mirror of https://github.com/harness/drone.git
feat: [CDE-203]: Making infra processing async. (#2325)
* Cleaning the flow around gitspace instance update. * Renaming params and param schema types. * Correcting comments. * feat: [CDE-203]: Making infra processing async. * feat: [CDE-203]: Making infra processing async. * feat: [CDE-203]: Making infra processing async.pull/3545/head
parent
bd9cfce3ab
commit
9d5071b45c
|
@ -34,7 +34,7 @@ import (
|
|||
|
||||
const defaultAccessKey = "Harness@123"
|
||||
const defaultMachineUser = "harness"
|
||||
const gitspaceTimedOutInMintues = 10
|
||||
const gitspaceTimedOutInMintues = 5
|
||||
|
||||
type ActionInput struct {
|
||||
Action enum.GitspaceActionType `json:"action"`
|
||||
|
@ -135,21 +135,28 @@ func (c *Controller) startGitspaceAction(
|
|||
|
||||
func (c *Controller) asyncOperation(
|
||||
ctxWithTimedOut context.Context,
|
||||
config *types.GitspaceConfig,
|
||||
config types.GitspaceConfig,
|
||||
action enum.GitspaceActionType,
|
||||
stateChannel chan enum.GitspaceInstanceStateType,
|
||||
errChannel chan error,
|
||||
) {
|
||||
defer close(stateChannel)
|
||||
defer close(errChannel)
|
||||
|
||||
var orchestrateErr error
|
||||
var instanceState enum.GitspaceInstanceStateType
|
||||
|
||||
switch action {
|
||||
case enum.GitspaceActionTypeStart:
|
||||
orchestrateErr = c.orchestrator.StartGitspace(ctxWithTimedOut, config)
|
||||
instanceState, orchestrateErr = c.orchestrator.TriggerStartGitspace(ctxWithTimedOut, config)
|
||||
case enum.GitspaceActionTypeStop:
|
||||
orchestrateErr = c.orchestrator.StopGitspace(ctxWithTimedOut, config)
|
||||
instanceState, orchestrateErr = c.orchestrator.TriggerStopGitspace(ctxWithTimedOut, config)
|
||||
}
|
||||
|
||||
if orchestrateErr != nil {
|
||||
errChannel <- fmt.Errorf("failed to find start/stop gitspace : %s %w", config.Identifier, orchestrateErr)
|
||||
errChannel <- fmt.Errorf("failed to start/stop gitspace: %s %w", config.Identifier, orchestrateErr)
|
||||
}
|
||||
close(errChannel)
|
||||
stateChannel <- instanceState
|
||||
}
|
||||
|
||||
func (c *Controller) submitAsyncOps(
|
||||
|
@ -157,21 +164,25 @@ func (c *Controller) submitAsyncOps(
|
|||
config *types.GitspaceConfig,
|
||||
action enum.GitspaceActionType,
|
||||
) {
|
||||
errChannel := make(chan error)
|
||||
stateChannel := make(chan enum.GitspaceInstanceStateType)
|
||||
|
||||
submitCtx := context.WithoutCancel(ctx)
|
||||
ttlExecuteContext, cancel := context.WithTimeout(submitCtx, gitspaceTimedOutInMintues*time.Minute)
|
||||
// submit an async task with a TTL
|
||||
errChannel := make(chan error)
|
||||
go c.asyncOperation(ttlExecuteContext, config, action, errChannel)
|
||||
// wait execution completion for the specified time or mark it as an error
|
||||
|
||||
go c.asyncOperation(ttlExecuteContext, *config, action, stateChannel, errChannel)
|
||||
|
||||
var err error
|
||||
var instanceState enum.GitspaceInstanceStateType
|
||||
|
||||
go func() {
|
||||
defer c.updateGitspaceInstance(submitCtx, config)
|
||||
select {
|
||||
case <-ttlExecuteContext.Done():
|
||||
if ttlExecuteContext.Err() != nil {
|
||||
err = ttlExecuteContext.Err()
|
||||
}
|
||||
case err = <-errChannel:
|
||||
case instanceState = <-stateChannel:
|
||||
}
|
||||
if err != nil {
|
||||
log.Err(err).Msgf("error during async execution for %s", config.GitspaceInstance.Identifier)
|
||||
|
@ -182,6 +193,15 @@ func (c *Controller) submitAsyncOps(
|
|||
c.emitGitspaceConfigEvent(ttlExecuteContext, config, enum.GitspaceEventTypeGitspaceActionStopFailed)
|
||||
}
|
||||
}
|
||||
|
||||
if instanceState == "" {
|
||||
instanceState = enum.GitspaceInstanceStateError
|
||||
}
|
||||
|
||||
config.GitspaceInstance.State = instanceState
|
||||
|
||||
c.updateGitspaceInstance(submitCtx, config.GitspaceInstance)
|
||||
|
||||
cancel()
|
||||
}()
|
||||
}
|
||||
|
@ -286,11 +306,11 @@ func (c *Controller) emitGitspaceConfigEvent(
|
|||
|
||||
func (c *Controller) updateGitspaceInstance(
|
||||
ctx context.Context,
|
||||
config *types.GitspaceConfig,
|
||||
instance *types.GitspaceInstance,
|
||||
) {
|
||||
err := c.gitspaceInstanceStore.Update(ctx, config.GitspaceInstance)
|
||||
err := c.gitspaceInstanceStore.Update(ctx, instance)
|
||||
if err != nil {
|
||||
log.Err(err).Msgf(
|
||||
"failed to update gitspace instance during exec %q", config.GitspaceInstance.Identifier)
|
||||
"failed to update gitspace instance during exec %q", instance.Identifier)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/harness/gitness/app/gitspace/logutil"
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator"
|
||||
"github.com/harness/gitness/app/gitspace/scm"
|
||||
"github.com/harness/gitness/app/services/gitspace"
|
||||
"github.com/harness/gitness/app/services/infraprovider"
|
||||
"github.com/harness/gitness/app/store"
|
||||
"github.com/harness/gitness/store/database/dbtx"
|
||||
|
@ -38,6 +39,7 @@ type Controller struct {
|
|||
statefulLogger *logutil.StatefulLogger
|
||||
scm scm.SCM
|
||||
repoStore store.RepoStore
|
||||
gitspaceSvc *gitspace.Service
|
||||
}
|
||||
|
||||
func NewController(
|
||||
|
@ -53,6 +55,7 @@ func NewController(
|
|||
statefulLogger *logutil.StatefulLogger,
|
||||
scm scm.SCM,
|
||||
repoStore store.RepoStore,
|
||||
gitspaceSvc *gitspace.Service,
|
||||
) *Controller {
|
||||
return &Controller{
|
||||
tx: tx,
|
||||
|
@ -67,5 +70,6 @@ func NewController(
|
|||
statefulLogger: statefulLogger,
|
||||
scm: scm,
|
||||
repoStore: repoStore,
|
||||
gitspaceSvc: gitspaceSvc,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
apiauth "github.com/harness/gitness/app/api/auth"
|
||||
"github.com/harness/gitness/app/api/usererror"
|
||||
"github.com/harness/gitness/app/auth"
|
||||
infraproviderenum "github.com/harness/gitness/infraprovider/enum"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/check"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
@ -189,7 +188,7 @@ func (c *Controller) autoCreateDefaultResource(ctx context.Context, parentSpace
|
|||
infraProviderConfig := &types.InfraProviderConfig{
|
||||
Identifier: defaultResourceIdentifier,
|
||||
Name: "default docker infrastructure",
|
||||
Type: infraproviderenum.InfraProviderTypeDocker,
|
||||
Type: enum.InfraProviderTypeDocker,
|
||||
SpaceID: parentSpace.ID,
|
||||
SpacePath: parentSpace.Path,
|
||||
Created: now,
|
||||
|
@ -199,7 +198,7 @@ func (c *Controller) autoCreateDefaultResource(ctx context.Context, parentSpace
|
|||
Identifier: defaultResourceIdentifier,
|
||||
Name: "Standard Docker Resource",
|
||||
InfraProviderConfigIdentifier: infraProviderConfig.Identifier,
|
||||
InfraProviderType: infraproviderenum.InfraProviderTypeDocker,
|
||||
InfraProviderType: enum.InfraProviderTypeDocker,
|
||||
CPU: wrapString("any"),
|
||||
Memory: wrapString("any"),
|
||||
Disk: wrapString("any"),
|
||||
|
|
|
@ -51,26 +51,34 @@ func (c *Controller) Delete(
|
|||
instance, _ := c.gitspaceInstanceStore.FindLatestByGitspaceConfigID(ctx, gitspaceConfig.ID, gitspaceConfig.SpaceID)
|
||||
gitspaceConfig.GitspaceInstance = instance
|
||||
gitspaceConfig.SpacePath = space.Path
|
||||
if instance != nil {
|
||||
if stopErr := c.stopRunningGitspace(ctx, gitspaceConfig); stopErr != nil {
|
||||
if instance == nil {
|
||||
gitspaceConfig.IsDeleted = true
|
||||
err = c.gitspaceConfigStore.Update(ctx, gitspaceConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to mark gitspace config as deleted: %w", err)
|
||||
}
|
||||
} else {
|
||||
instanceState, stopErr := c.stopRunningGitspace(ctx, *gitspaceConfig)
|
||||
if stopErr != nil {
|
||||
return stopErr
|
||||
}
|
||||
}
|
||||
gitspaceConfig.IsDeleted = true
|
||||
if err = c.gitspaceConfigStore.Update(ctx, gitspaceConfig); err != nil {
|
||||
return fmt.Errorf("failed to delete gitspace config with ID: %s %w", gitspaceConfig.Identifier, err)
|
||||
|
||||
instance.State = instanceState
|
||||
err = c.gitspaceInstanceStore.Update(ctx, instance)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update instance: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) stopRunningGitspace(
|
||||
ctx context.Context,
|
||||
config *types.GitspaceConfig,
|
||||
) error {
|
||||
if instanceUpdated, err := c.orchestrator.DeleteGitspace(ctx, config); err != nil {
|
||||
return err
|
||||
} else if err = c.gitspaceInstanceStore.Update(ctx, instanceUpdated); err != nil {
|
||||
return err
|
||||
config types.GitspaceConfig,
|
||||
) (enum.GitspaceInstanceStateType, error) {
|
||||
instanceState, err := c.orchestrator.TriggerDeleteGitspace(ctx, config)
|
||||
if err != nil {
|
||||
return instanceState, err
|
||||
}
|
||||
return nil
|
||||
return instanceState, nil
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
|
||||
apiauth "github.com/harness/gitness/app/api/auth"
|
||||
"github.com/harness/gitness/app/auth"
|
||||
"github.com/harness/gitness/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
@ -32,45 +31,18 @@ func (c *Controller) Find(
|
|||
identifier string,
|
||||
) (*types.GitspaceConfig, error) {
|
||||
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
||||
const resourceNotFoundErr = "Failed to find gitspace: resource not found"
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find space: %w", err)
|
||||
}
|
||||
|
||||
err = apiauth.CheckGitspace(ctx, c.authorizer, session, space.Path, identifier, enum.PermissionGitspaceView)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to authorize: %w", err)
|
||||
}
|
||||
var gitspaceConfig *types.GitspaceConfig
|
||||
err = c.tx.WithTx(ctx, func(ctx context.Context) error {
|
||||
gitspaceConfig, err = c.gitspaceConfigStore.FindByIdentifier(ctx, space.ID, identifier)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find gitspace config: %w", err)
|
||||
}
|
||||
infraProviderResource, err := c.infraProviderSvc.FindResource(ctx, gitspaceConfig.InfraProviderResourceID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find infra provider resource for gitspace config: %w", err)
|
||||
}
|
||||
gitspaceConfig.SpacePath = space.Path
|
||||
gitspaceConfig.InfraProviderResourceIdentifier = infraProviderResource.Identifier
|
||||
instance, err := c.gitspaceInstanceStore.FindLatestByGitspaceConfigID(ctx, gitspaceConfig.ID, gitspaceConfig.SpaceID)
|
||||
if err != nil && err.Error() != resourceNotFoundErr { // TODO fix this
|
||||
return fmt.Errorf("failed to find gitspace instance for config ID : %s %w", gitspaceConfig.Identifier, err)
|
||||
}
|
||||
if instance != nil {
|
||||
gitspaceConfig.GitspaceInstance = instance
|
||||
instance.SpacePath = gitspaceConfig.SpacePath
|
||||
gitspaceStateType, err := enum.GetGitspaceStateFromInstance(instance.State)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gitspaceConfig.State = gitspaceStateType
|
||||
} else {
|
||||
gitspaceConfig.State = enum.GitspaceStateUninitialized
|
||||
}
|
||||
return nil
|
||||
}, dbtx.TxDefaultReadOnly)
|
||||
|
||||
res, err := c.gitspaceSvc.Find(ctx, space.ID, space.Path, identifier)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("failed to find gitspace: %w", err)
|
||||
}
|
||||
return gitspaceConfig, nil
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/harness/gitness/app/gitspace/logutil"
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator"
|
||||
"github.com/harness/gitness/app/gitspace/scm"
|
||||
"github.com/harness/gitness/app/services/gitspace"
|
||||
"github.com/harness/gitness/app/services/infraprovider"
|
||||
"github.com/harness/gitness/app/store"
|
||||
"github.com/harness/gitness/store/database/dbtx"
|
||||
|
@ -45,6 +46,7 @@ func ProvideController(
|
|||
statefulLogger *logutil.StatefulLogger,
|
||||
scm scm.SCM,
|
||||
repoStore store.RepoStore,
|
||||
gitspaceSvc *gitspace.Service,
|
||||
) *Controller {
|
||||
return NewController(
|
||||
tx,
|
||||
|
@ -59,5 +61,6 @@ func ProvideController(
|
|||
statefulLogger,
|
||||
scm,
|
||||
repoStore,
|
||||
gitspaceSvc,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -22,34 +22,33 @@ import (
|
|||
|
||||
apiauth "github.com/harness/gitness/app/api/auth"
|
||||
"github.com/harness/gitness/app/auth"
|
||||
infraproviderenum "github.com/harness/gitness/infraprovider/enum"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/check"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
type CreateInput struct {
|
||||
Identifier string `json:"identifier"`
|
||||
SpaceRef string `json:"space_ref"` // Ref of the parent space
|
||||
Name string `json:"name"`
|
||||
Type infraproviderenum.InfraProviderType `json:"type"`
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
Resources []ResourceInput `json:"resources"`
|
||||
Identifier string `json:"identifier"`
|
||||
SpaceRef string `json:"space_ref"` // Ref of the parent space
|
||||
Name string `json:"name"`
|
||||
Type enum.InfraProviderType `json:"type"`
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
Resources []ResourceInput `json:"resources"`
|
||||
}
|
||||
|
||||
type ResourceInput struct {
|
||||
Identifier string `json:"identifier"`
|
||||
Name string `json:"name"`
|
||||
InfraProviderType infraproviderenum.InfraProviderType `json:"infra_provider_type"`
|
||||
CPU *string `json:"cpu"`
|
||||
Memory *string `json:"memory"`
|
||||
Disk *string `json:"disk"`
|
||||
Network *string `json:"network"`
|
||||
Region []string `json:"region"`
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
GatewayHost *string `json:"gateway_host"`
|
||||
GatewayPort *string `json:"gateway_port"`
|
||||
TemplateIdentifier *string `json:"template_identifier"`
|
||||
Identifier string `json:"identifier"`
|
||||
Name string `json:"name"`
|
||||
InfraProviderType enum.InfraProviderType `json:"infra_provider_type"`
|
||||
CPU *string `json:"cpu"`
|
||||
Memory *string `json:"memory"`
|
||||
Disk *string `json:"disk"`
|
||||
Network *string `json:"network"`
|
||||
Region []string `json:"region"`
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
GatewayHost *string `json:"gateway_host"`
|
||||
GatewayPort *string `json:"gateway_port"`
|
||||
TemplateIdentifier *string `json:"template_identifier"`
|
||||
}
|
||||
|
||||
// Create creates a new infraprovider config.
|
||||
|
|
|
@ -12,12 +12,9 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package enum
|
||||
package events
|
||||
|
||||
func toInterfaceSlice[T interface{}](vals []T) []interface{} {
|
||||
res := make([]interface{}, len(vals))
|
||||
for i := range vals {
|
||||
res[i] = vals[i]
|
||||
}
|
||||
return res
|
||||
}
|
||||
const (
|
||||
// category defines the event category used for this package.
|
||||
category = "gitspace_infra"
|
||||
)
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package events
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/events"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const (
|
||||
// List all Gitspace Infra events below.
|
||||
|
||||
GitspaceInfraEvent events.EventType = "gitspace_infra_event"
|
||||
)
|
||||
|
||||
type (
|
||||
GitspaceInfraEventPayload struct {
|
||||
Infra *types.Infrastructure `json:"infra,omitempty"`
|
||||
Type enum.InfraEvent `json:"type"`
|
||||
}
|
||||
)
|
||||
|
||||
func (r *Reporter) EmitGitspaceInfraEvent(
|
||||
ctx context.Context,
|
||||
event events.EventType,
|
||||
payload *GitspaceInfraEventPayload,
|
||||
) {
|
||||
if payload == nil {
|
||||
return
|
||||
}
|
||||
eventID, err := events.ReporterSendEvent(r.innerReporter, ctx, event, payload)
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Err(err).Msgf("failed to send %v event", event)
|
||||
return
|
||||
}
|
||||
|
||||
log.Ctx(ctx).Debug().Msgf("reported %v event with id '%s'", event, eventID)
|
||||
}
|
||||
|
||||
func (r *Reader) RegisterGitspaceInfraEvent(
|
||||
fn events.HandlerFunc[*GitspaceInfraEventPayload],
|
||||
opts ...events.HandlerOption,
|
||||
) error {
|
||||
return events.ReaderRegisterEvent(r.innerReader, GitspaceInfraEvent, fn, opts...)
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package events
|
||||
|
||||
import (
|
||||
"github.com/harness/gitness/events"
|
||||
)
|
||||
|
||||
func NewReaderFactory(eventsSystem *events.System) (*events.ReaderFactory[*Reader], error) {
|
||||
readerFactoryFunc := func(innerReader *events.GenericReader) (*Reader, error) {
|
||||
return &Reader{
|
||||
innerReader: innerReader,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return events.NewReaderFactory(eventsSystem, category, readerFactoryFunc)
|
||||
}
|
||||
|
||||
// Reader is the event reader for this package.
|
||||
type Reader struct {
|
||||
innerReader *events.GenericReader
|
||||
}
|
||||
|
||||
func (r *Reader) Configure(opts ...events.ReaderOption) {
|
||||
r.innerReader.Configure(opts...)
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package events
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/harness/gitness/events"
|
||||
)
|
||||
|
||||
// Reporter is the event reporter for this package.
|
||||
type Reporter struct {
|
||||
innerReporter *events.GenericReporter
|
||||
}
|
||||
|
||||
func NewReporter(eventsSystem *events.System) (*Reporter, error) {
|
||||
innerReporter, err := events.NewReporter(eventsSystem, category)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to create new GenericReporter from event system")
|
||||
}
|
||||
|
||||
return &Reporter{
|
||||
innerReporter: innerReporter,
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package events
|
||||
|
||||
import (
|
||||
"github.com/harness/gitness/events"
|
||||
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
// WireSet provides a wire set for this package.
|
||||
var WireSet = wire.NewSet(
|
||||
ProvideReaderFactory,
|
||||
ProvideReporter,
|
||||
)
|
||||
|
||||
func ProvideReaderFactory(eventsSystem *events.System) (*events.ReaderFactory[*Reader], error) {
|
||||
return NewReaderFactory(eventsSystem)
|
||||
}
|
||||
|
||||
func ProvideReporter(eventsSystem *events.System) (*Reporter, error) {
|
||||
return NewReporter(eventsSystem)
|
||||
}
|
|
@ -17,40 +17,64 @@ package infrastructure
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/infraprovider"
|
||||
"github.com/harness/gitness/types"
|
||||
)
|
||||
|
||||
// TODO Check if the interface can be discarded
|
||||
|
||||
type InfraProvisioner interface {
|
||||
// Provision provisions infra resources using the infraProviderResource with different infra providers and
|
||||
// stores the details in the db depending on the provisioning type.
|
||||
Provision(
|
||||
// TriggerProvision triggers the provisionining of infra resources using the infraProviderResource with different
|
||||
// infra providers.
|
||||
TriggerProvision(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
requiredPorts []int,
|
||||
) (*infraprovider.Infrastructure, error)
|
||||
) error
|
||||
|
||||
// Stop unprovisions those resources which can be stopped without losing the gitspace data.
|
||||
Stop(
|
||||
// ResumeProvision stores the provisioned infra details in the db depending on the provisioning type.
|
||||
ResumeProvision(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
) (*infraprovider.Infrastructure, error)
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
requiredPorts []int,
|
||||
provisionedInfra *types.Infrastructure,
|
||||
) (*types.Infrastructure, error)
|
||||
|
||||
// Deprovision removes all the resources created for the gitspace.
|
||||
Deprovision(
|
||||
// TriggerStop triggers deprovisioning of those resources which can be stopped without losing the Gitspace data.
|
||||
TriggerStop(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
) (*infraprovider.Infrastructure, error)
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) error
|
||||
|
||||
// ResumeStop stores the deprovisioned infra details in the db depending on the provisioning type.
|
||||
ResumeStop(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
deprovisionedInfra *types.Infrastructure,
|
||||
) (*types.Infrastructure, error)
|
||||
|
||||
// TriggerDeprovision triggers deprovisionign of all the resources created for the Gitspace.
|
||||
TriggerDeprovision(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) error
|
||||
|
||||
// ResumeDeprovision stores the deprovisioned infra details in the db depending on the provisioning type.
|
||||
ResumeDeprovision(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
deprovisionedInfra *types.Infrastructure,
|
||||
) (*types.Infrastructure, error)
|
||||
|
||||
// Find finds the provisioned infra resources for the gitspace instance.
|
||||
Find(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
) (*infraprovider.Infrastructure, error)
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) (*types.Infrastructure, error)
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ import (
|
|||
|
||||
"github.com/harness/gitness/app/store"
|
||||
"github.com/harness/gitness/infraprovider"
|
||||
"github.com/harness/gitness/infraprovider/enum"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
var _ InfraProvisioner = (*infraProvisioner)(nil)
|
||||
|
@ -44,31 +44,31 @@ func NewInfraProvisionerService(
|
|||
}
|
||||
}
|
||||
|
||||
func (i infraProvisioner) Provision(
|
||||
func (i infraProvisioner) TriggerProvision(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
requiredPorts []int,
|
||||
) (*infraprovider.Infrastructure, error) {
|
||||
) error {
|
||||
infraProviderEntity, err := i.getConfigFromResource(ctx, infraProviderResource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
infraProvider, err := i.getInfraProvider(infraProviderEntity)
|
||||
infraProvider, err := i.getInfraProvider(infraProviderEntity.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive,staticcheck
|
||||
// TODO: Check if any existing infra is provisioned, its status and create new infraProvisioned record
|
||||
}
|
||||
|
||||
var allParams []infraprovider.Parameter
|
||||
var allParams []types.InfraProviderParameter
|
||||
|
||||
templateParams, err := i.getTemplateParams(infraProvider, infraProviderResource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
allParams = append(allParams, templateParams...)
|
||||
|
@ -79,47 +79,44 @@ func (i infraProvisioner) Provision(
|
|||
|
||||
err = infraProvider.ValidateParams(allParams)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid provisioning params %v: %w", infraProviderResource.Metadata, err)
|
||||
return fmt.Errorf("invalid provisioning params %v: %w", infraProviderResource.Metadata, err)
|
||||
}
|
||||
|
||||
provisionedInfra, err := infraProvider.Provision(
|
||||
err = infraProvider.Provision(
|
||||
ctx,
|
||||
gitspaceConfig.SpaceID,
|
||||
gitspaceConfig.SpacePath,
|
||||
gitspaceConfig.Identifier,
|
||||
requiredPorts,
|
||||
allParams,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"unable to provision infrastructure for gitspaceConfigIdentifier %v: %w",
|
||||
return fmt.Errorf(
|
||||
"unable to trigger provision infrastructure for gitspaceConfigIdentifier %v: %w",
|
||||
gitspaceConfig.Identifier,
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive,staticcheck
|
||||
// TODO: Update the infraProvisioned record
|
||||
}
|
||||
|
||||
return provisionedInfra, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i infraProvisioner) Stop(
|
||||
func (i infraProvisioner) TriggerStop(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
) (*infraprovider.Infrastructure, error) {
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) error {
|
||||
infraProviderEntity, err := i.getConfigFromResource(ctx, infraProviderResource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
infraProvider, err := i.getInfraProvider(infraProviderEntity)
|
||||
infraProvider, err := i.getInfraProvider(infraProviderEntity.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
var allParams []infraprovider.Parameter
|
||||
var allParams []types.InfraProviderParameter
|
||||
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive
|
||||
// TODO: Fetch and check existing infraProvisioned record
|
||||
|
@ -127,7 +124,7 @@ func (i infraProvisioner) Stop(
|
|||
} else {
|
||||
templateParams, err2 := i.getTemplateParams(infraProvider, infraProviderResource)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
return err2
|
||||
}
|
||||
allParams = append(allParams, templateParams...)
|
||||
|
||||
|
@ -138,48 +135,46 @@ func (i infraProvisioner) Stop(
|
|||
|
||||
err = infraProvider.ValidateParams(allParams)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid provisioning params %+v: %w", infraProviderResource.Metadata, err)
|
||||
return fmt.Errorf("invalid provisioning params %+v: %w", infraProviderResource.Metadata, err)
|
||||
}
|
||||
|
||||
var provisionedInfra *infraprovider.Infrastructure
|
||||
var provisionedInfra *types.Infrastructure
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive
|
||||
// TODO: Fetch and check existing infraProvisioned record
|
||||
} else {
|
||||
provisionedInfra = &infraprovider.Infrastructure{
|
||||
provisionedInfra = &types.Infrastructure{
|
||||
SpaceID: gitspaceConfig.SpaceID,
|
||||
SpacePath: gitspaceConfig.SpacePath,
|
||||
ResourceKey: gitspaceConfig.Identifier,
|
||||
ProviderType: infraProviderEntity.Type,
|
||||
Parameters: allParams,
|
||||
}
|
||||
}
|
||||
|
||||
stoppedInfra, err := infraProvider.Stop(ctx, provisionedInfra)
|
||||
err = infraProvider.Stop(ctx, provisionedInfra)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to stop provisioned infra %+v: %w", provisionedInfra, err)
|
||||
return fmt.Errorf("unable to trigger stop infra %+v: %w", provisionedInfra, err)
|
||||
}
|
||||
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive,staticcheck
|
||||
// TODO: Update existing infraProvisioned record
|
||||
}
|
||||
|
||||
return stoppedInfra, err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i infraProvisioner) Deprovision(
|
||||
func (i infraProvisioner) TriggerDeprovision(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
) (*infraprovider.Infrastructure, error) {
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) error {
|
||||
infraProviderEntity, err := i.getConfigFromResource(ctx, infraProviderResource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
infraProvider, err := i.getInfraProvider(infraProviderEntity)
|
||||
infraProvider, err := i.getInfraProvider(infraProviderEntity.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
var allParams []infraprovider.Parameter
|
||||
var allParams []types.InfraProviderParameter
|
||||
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive
|
||||
// TODO: Fetch and check existing infraProvisioned record
|
||||
|
@ -187,7 +182,7 @@ func (i infraProvisioner) Deprovision(
|
|||
} else {
|
||||
templateParams, err2 := i.getTemplateParams(infraProvider, infraProviderResource)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
return err2
|
||||
}
|
||||
allParams = append(allParams, templateParams...)
|
||||
|
||||
|
@ -198,51 +193,48 @@ func (i infraProvisioner) Deprovision(
|
|||
|
||||
err = infraProvider.ValidateParams(allParams)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid provisioning params %+v: %w", infraProviderResource.Metadata, err)
|
||||
return fmt.Errorf("invalid provisioning params %+v: %w", infraProviderResource.Metadata, err)
|
||||
}
|
||||
|
||||
var provisionedInfra *infraprovider.Infrastructure
|
||||
var provisionedInfra *types.Infrastructure
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive
|
||||
// TODO: Fetch and check existing infraProvisioned record
|
||||
} else {
|
||||
provisionedInfra, err = infraProvider.Find(ctx, gitspaceConfig.SpacePath, gitspaceConfig.Identifier, allParams)
|
||||
provisionedInfra, err = infraProvider.Find(
|
||||
ctx, gitspaceConfig.SpaceID, gitspaceConfig.SpacePath, gitspaceConfig.Identifier, allParams)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find provisioned infra for gitspace %s: %w",
|
||||
return fmt.Errorf("unable to find provisioned infra for gitspace %s: %w",
|
||||
gitspaceConfig.Identifier, err)
|
||||
}
|
||||
}
|
||||
destroyedInfra, err := infraProvider.Deprovision(ctx, provisionedInfra)
|
||||
err = infraProvider.Deprovision(ctx, provisionedInfra)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to stop provisioned infra %+v: %w", provisionedInfra, err)
|
||||
return fmt.Errorf("unable to trigger deprovision infra %+v: %w", provisionedInfra, err)
|
||||
}
|
||||
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive,staticcheck
|
||||
// TODO: Update existing infraProvisioned record
|
||||
}
|
||||
|
||||
return destroyedInfra, err
|
||||
return err
|
||||
}
|
||||
|
||||
func (i infraProvisioner) Find(
|
||||
ctx context.Context,
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
_ *types.GitspaceConfig,
|
||||
) (*infraprovider.Infrastructure, error) {
|
||||
_ types.GitspaceConfig,
|
||||
) (*types.Infrastructure, error) {
|
||||
infraProviderEntity, err := i.getConfigFromResource(ctx, infraProviderResource)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
infraProvider, err := i.getInfraProvider(infraProviderEntity)
|
||||
infraProvider, err := i.getInfraProvider(infraProviderEntity.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var infra infraprovider.Infrastructure
|
||||
var infra types.Infrastructure
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive
|
||||
// TODO: Fetch existing infraProvisioned record and map to &infraprovider.Infrastructure
|
||||
} else {
|
||||
var allParams []infraprovider.Parameter
|
||||
var allParams []types.InfraProviderParameter
|
||||
|
||||
templateParams, err2 := i.getTemplateParams(infraProvider, infraProviderResource)
|
||||
if err2 != nil {
|
||||
|
@ -254,7 +246,7 @@ func (i infraProvisioner) Find(
|
|||
|
||||
allParams = append(allParams, params...)
|
||||
|
||||
infra = infraprovider.Infrastructure{
|
||||
infra = types.Infrastructure{
|
||||
ProviderType: infraProviderEntity.Type,
|
||||
Parameters: allParams,
|
||||
Status: enum.InfraStatusProvisioned,
|
||||
|
@ -277,11 +269,11 @@ func (i infraProvisioner) getConfigFromResource(
|
|||
}
|
||||
|
||||
func (i infraProvisioner) getInfraProvider(
|
||||
infraProviderEntity *types.InfraProviderConfig,
|
||||
infraProviderType enum.InfraProviderType,
|
||||
) (infraprovider.InfraProvider, error) {
|
||||
infraProvider, err := i.providerFactory.GetInfraProvider(infraProviderEntity.Type)
|
||||
infraProvider, err := i.providerFactory.GetInfraProvider(infraProviderType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get infra provider of type %v: %w", infraProviderEntity.Type, err)
|
||||
return nil, fmt.Errorf("unable to get infra provider of type %v: %w", infraProviderType, err)
|
||||
}
|
||||
return infraProvider, nil
|
||||
}
|
||||
|
@ -289,7 +281,7 @@ func (i infraProvisioner) getInfraProvider(
|
|||
func (i infraProvisioner) getTemplateParams(
|
||||
infraProvider infraprovider.InfraProvider,
|
||||
_ *types.InfraProviderResource,
|
||||
) ([]infraprovider.Parameter, error) { //nolint:unparam
|
||||
) ([]types.InfraProviderParameter, error) { //nolint:unparam
|
||||
templateParams := infraProvider.TemplateParams()
|
||||
if len(templateParams) > 0 { //nolint:revive,staticcheck
|
||||
// TODO: Fetch templates and convert into []Parameters
|
||||
|
@ -299,14 +291,14 @@ func (i infraProvisioner) getTemplateParams(
|
|||
|
||||
func (i infraProvisioner) paramsFromResource(
|
||||
infraProviderResource *types.InfraProviderResource,
|
||||
) []infraprovider.Parameter {
|
||||
params := make([]infraprovider.Parameter, len(infraProviderResource.Metadata))
|
||||
) []types.InfraProviderParameter {
|
||||
params := make([]types.InfraProviderParameter, len(infraProviderResource.Metadata))
|
||||
counter := 0
|
||||
for key, value := range infraProviderResource.Metadata {
|
||||
if key == "" || value == "" {
|
||||
continue
|
||||
}
|
||||
params[counter] = infraprovider.Parameter{
|
||||
params[counter] = types.InfraProviderParameter{
|
||||
Name: key,
|
||||
Value: value,
|
||||
}
|
||||
|
@ -314,3 +306,58 @@ func (i infraProvisioner) paramsFromResource(
|
|||
}
|
||||
return params
|
||||
}
|
||||
|
||||
func (i infraProvisioner) ResumeProvision(
|
||||
_ context.Context,
|
||||
_ *types.InfraProviderResource,
|
||||
_ types.GitspaceConfig,
|
||||
_ []int,
|
||||
provisionedInfra *types.Infrastructure,
|
||||
) (*types.Infrastructure, error) {
|
||||
infraProvider, err := i.getInfraProvider(provisionedInfra.ProviderType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive,staticcheck
|
||||
// TODO: Update the infraProvisioned record
|
||||
}
|
||||
|
||||
return provisionedInfra, nil
|
||||
}
|
||||
|
||||
func (i infraProvisioner) ResumeStop(
|
||||
_ context.Context,
|
||||
_ *types.InfraProviderResource,
|
||||
_ types.GitspaceConfig,
|
||||
stoppedInfra *types.Infrastructure,
|
||||
) (*types.Infrastructure, error) {
|
||||
infraProvider, err := i.getInfraProvider(stoppedInfra.ProviderType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive,staticcheck
|
||||
// TODO: Update existing infraProvisioned record
|
||||
}
|
||||
|
||||
return stoppedInfra, err
|
||||
}
|
||||
|
||||
func (i infraProvisioner) ResumeDeprovision(
|
||||
_ context.Context,
|
||||
_ *types.InfraProviderResource,
|
||||
_ types.GitspaceConfig,
|
||||
deprovisionedInfra *types.Infrastructure,
|
||||
) (*types.Infrastructure, error) {
|
||||
infraProvider, err := i.getInfraProvider(deprovisionedInfra.ProviderType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { //nolint:revive,staticcheck
|
||||
// TODO: Update existing infraProvisioned record
|
||||
}
|
||||
|
||||
return deprovisionedInfra, err
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
|
||||
"github.com/harness/gitness/app/gitspace/scm"
|
||||
"github.com/harness/gitness/infraprovider"
|
||||
"github.com/harness/gitness/types"
|
||||
)
|
||||
|
||||
|
@ -29,19 +28,19 @@ type Orchestrator interface {
|
|||
// It returns the container ID, name and ports used.
|
||||
CreateAndStartGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
infra *infraprovider.Infrastructure,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
infra *types.Infrastructure,
|
||||
resolvedDetails *scm.ResolvedDetails,
|
||||
defaultBaseImage string,
|
||||
ideService ide.IDE,
|
||||
) (*StartResponse, error)
|
||||
|
||||
// StopGitspace stops the gitspace container.
|
||||
StopGitspace(ctx context.Context, config *types.GitspaceConfig, infra *infraprovider.Infrastructure) error
|
||||
StopGitspace(ctx context.Context, config types.GitspaceConfig, infra *types.Infrastructure) error
|
||||
|
||||
// StopAndRemoveGitspace stops and removes the gitspace container.
|
||||
StopAndRemoveGitspace(ctx context.Context, config *types.GitspaceConfig, infra *infraprovider.Infrastructure) error
|
||||
StopAndRemoveGitspace(ctx context.Context, config types.GitspaceConfig, infra *types.Infrastructure) error
|
||||
|
||||
// Status checks if the infra is reachable and ready to orchestrate containers.
|
||||
Status(ctx context.Context, infra *infraprovider.Infrastructure) error
|
||||
Status(ctx context.Context, infra *types.Infrastructure) error
|
||||
}
|
||||
|
|
|
@ -73,8 +73,8 @@ func NewEmbeddedDockerOrchestrator(
|
|||
// It returns an error if the container is not running, exited or removed.
|
||||
func (e *EmbeddedDockerOrchestrator) CreateAndStartGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
infra *infraprovider.Infrastructure,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
infra *types.Infrastructure,
|
||||
resolvedRepoDetails *scm.ResolvedDetails,
|
||||
defaultBaseImage string,
|
||||
ideService ide.IDE,
|
||||
|
@ -202,7 +202,7 @@ func (e *EmbeddedDockerOrchestrator) getWorkingDir(repoName string) string {
|
|||
|
||||
func (e *EmbeddedDockerOrchestrator) startGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
containerName string,
|
||||
dockerClient *client.Client,
|
||||
ideService ide.IDE,
|
||||
|
@ -210,7 +210,7 @@ func (e *EmbeddedDockerOrchestrator) startGitspace(
|
|||
volumeName string,
|
||||
workingDirectory string,
|
||||
resolvedRepoDetails *scm.ResolvedDetails,
|
||||
portMappings map[int]*infraprovider.PortMapping,
|
||||
portMappings map[int]*types.PortMapping,
|
||||
defaultBaseImage string,
|
||||
) error {
|
||||
var imageName = resolvedRepoDetails.DevcontainerConfig.Image
|
||||
|
@ -357,7 +357,7 @@ func (e *EmbeddedDockerOrchestrator) getContainerInfo(
|
|||
ctx context.Context,
|
||||
containerName string,
|
||||
dockerClient *client.Client,
|
||||
portMappings map[int]*infraprovider.PortMapping,
|
||||
portMappings map[int]*types.PortMapping,
|
||||
) (string, map[int]string, error) {
|
||||
inspectResp, err := dockerClient.ContainerInspect(ctx, containerName)
|
||||
if err != nil {
|
||||
|
@ -592,7 +592,7 @@ func (e *EmbeddedDockerOrchestrator) createContainer(
|
|||
logStreamInstance *logutil.LogStreamInstance,
|
||||
volumeName string,
|
||||
workingDirectory string,
|
||||
portMappings map[int]*infraprovider.PortMapping,
|
||||
portMappings map[int]*types.PortMapping,
|
||||
) error {
|
||||
exposedPorts := nat.PortSet{}
|
||||
portBindings := nat.PortMap{}
|
||||
|
@ -707,8 +707,8 @@ func (e *EmbeddedDockerOrchestrator) pullImage(
|
|||
// StopGitspace stops a container. If it is removed, it returns an error.
|
||||
func (e EmbeddedDockerOrchestrator) StopGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
infra *infraprovider.Infrastructure,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
infra *types.Infrastructure,
|
||||
) error {
|
||||
containerName := getGitspaceContainerName(gitspaceConfig)
|
||||
|
||||
|
@ -797,12 +797,12 @@ func (e EmbeddedDockerOrchestrator) stopContainer(
|
|||
return nil
|
||||
}
|
||||
|
||||
func getGitspaceContainerName(config *types.GitspaceConfig) string {
|
||||
func getGitspaceContainerName(config types.GitspaceConfig) string {
|
||||
return "gitspace-" + config.UserID + "-" + config.Identifier
|
||||
}
|
||||
|
||||
// Status is NOOP for EmbeddedDockerOrchestrator as the docker host is verified by the infra provisioner.
|
||||
func (e *EmbeddedDockerOrchestrator) Status(_ context.Context, _ *infraprovider.Infrastructure) error {
|
||||
func (e *EmbeddedDockerOrchestrator) Status(_ context.Context, _ *types.Infrastructure) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -830,8 +830,8 @@ func (e *EmbeddedDockerOrchestrator) containerState(
|
|||
// If the container is already removed, it returns.
|
||||
func (e *EmbeddedDockerOrchestrator) StopAndRemoveGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
infra *infraprovider.Infrastructure,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
infra *types.Infrastructure,
|
||||
) error {
|
||||
containerName := getGitspaceContainerName(gitspaceConfig)
|
||||
|
||||
|
|
|
@ -18,19 +18,39 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
type Orchestrator interface {
|
||||
// StartGitspace is responsible for all the operations necessary to create the Gitspace container. It fetches the
|
||||
// devcontainer.json from the code repo, provisions infra using the infra provisioner and setting up the Gitspace
|
||||
// through the container orchestrator.
|
||||
StartGitspace(ctx context.Context, gitspaceConfig *types.GitspaceConfig) error
|
||||
// TriggerStartGitspace fetches the infra resources configured for the gitspace and triggers the infra provisioning.
|
||||
TriggerStartGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) (enum.GitspaceInstanceStateType, error)
|
||||
|
||||
// StopGitspace is responsible for stopping a running Gitspace. It stops the Gitspace container and unprovisions
|
||||
// ResumeStartGitspace saves the provisioned infra, resolves the code repo details & creates the Gitspace container.
|
||||
ResumeStartGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
provisionedInfra *types.Infrastructure,
|
||||
) (types.GitspaceInstance, error)
|
||||
|
||||
// TriggerStopGitspace stops the Gitspace container and triggers infra deprovisioning to deprovision
|
||||
// all the infra resources which are not required to restart the Gitspace.
|
||||
StopGitspace(ctx context.Context, gitspaceConfig *types.GitspaceConfig) error
|
||||
TriggerStopGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) (enum.GitspaceInstanceStateType, error)
|
||||
|
||||
// DeleteGitspace is responsible for deleting a Gitspace. It stops the Gitspace container and unprovisions
|
||||
// ResumeStopGitspace saves the deprovisioned infra details.
|
||||
ResumeStopGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
stoppedInfra *types.Infrastructure,
|
||||
) (enum.GitspaceInstanceStateType, error)
|
||||
|
||||
// TriggerDeleteGitspace removes the Gitspace container and triggers infra deprovisioning to deprovision
|
||||
// all the infra resources.
|
||||
DeleteGitspace(ctx context.Context, gitspaceConfig *types.GitspaceConfig) (*types.GitspaceInstance, error)
|
||||
TriggerDeleteGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) (enum.GitspaceInstanceStateType, error)
|
||||
|
||||
// ResumeDeleteGitspace saves the deprovisioned infra details.
|
||||
ResumeDeleteGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
deprovisionedInfra *types.Infrastructure,
|
||||
) (enum.GitspaceInstanceStateType, error)
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import (
|
|||
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
|
||||
"github.com/harness/gitness/app/gitspace/scm"
|
||||
"github.com/harness/gitness/app/store"
|
||||
"github.com/harness/gitness/infraprovider"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
|
@ -74,166 +73,80 @@ func NewOrchestrator(
|
|||
}
|
||||
}
|
||||
|
||||
func (o orchestrator) StartGitspace(
|
||||
func (o orchestrator) TriggerStartGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
) error {
|
||||
gitspaceInstance := gitspaceConfig.GitspaceInstance
|
||||
gitspaceInstance.State = enum.GitspaceInstanceStateError
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeFetchDevcontainerStart)
|
||||
|
||||
scmResolvedDetails, err := o.scm.GetSCMRepoDetails(ctx, gitspaceConfig)
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeFetchDevcontainerFailed)
|
||||
|
||||
return fmt.Errorf("failed to fetch code repo details for gitspace config ID %w %d", err, gitspaceConfig.ID)
|
||||
}
|
||||
devcontainerConfig := scmResolvedDetails.DevcontainerConfig
|
||||
repoName := scmResolvedDetails.RepoName
|
||||
|
||||
if devcontainerConfig == nil {
|
||||
log.Warn().Err(err).Msg("devcontainer config is nil, using empty config")
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeFetchDevcontainerCompleted)
|
||||
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) (enum.GitspaceInstanceStateType, error) {
|
||||
instanceState := enum.GitspaceInstanceStateError
|
||||
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot get the infraprovider resource for ID %d: %w",
|
||||
return instanceState, fmt.Errorf("cannot get the infraprovider resource for ID %d: %w",
|
||||
gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
ideSvc, err := o.getIDEService(gitspaceConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
return instanceState, err
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningStart)
|
||||
|
||||
idePort := ideSvc.Port()
|
||||
|
||||
infra, err := o.infraProvisioner.Provision(ctx, infraProviderResource, gitspaceConfig, []int{idePort})
|
||||
err = o.infraProvisioner.TriggerProvision(ctx, infraProviderResource, gitspaceConfig, []int{idePort})
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningFailed)
|
||||
|
||||
return fmt.Errorf(
|
||||
"cannot provision infrastructure for ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
return instanceState, fmt.Errorf(
|
||||
"cannot trigger provision infrastructure for ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningCompleted)
|
||||
instanceState = enum.GitspaceInstanceStateStarting
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
|
||||
|
||||
err = o.containerOrchestrator.Status(ctx, infra)
|
||||
gitspaceInstance.State = enum.GitspaceInstanceStateError
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed)
|
||||
|
||||
return fmt.Errorf("couldn't call the agent health API: %w", err)
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectCompleted)
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationStart)
|
||||
|
||||
startResponse, err := o.containerOrchestrator.CreateAndStartGitspace(
|
||||
ctx, gitspaceConfig, infra, scmResolvedDetails, o.config.DefaultBaseImage, ideSvc)
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationFailed)
|
||||
|
||||
return fmt.Errorf("couldn't call the agent start API: %w", err)
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationCompleted)
|
||||
|
||||
var ideURL url.URL
|
||||
|
||||
var forwardedPort string
|
||||
|
||||
if infra.PortMappings[idePort].PublishedPort == 0 {
|
||||
forwardedPort = startResponse.PublishedPorts[idePort]
|
||||
} else {
|
||||
forwardedPort = strconv.Itoa(infra.PortMappings[idePort].ForwardedPort)
|
||||
}
|
||||
|
||||
if gitspaceConfig.IDE == enum.IDETypeVSCodeWeb {
|
||||
ideURL = url.URL{
|
||||
Scheme: "http",
|
||||
Host: infra.Host + ":" + forwardedPort,
|
||||
RawQuery: filepath.Join("folder=", repoName),
|
||||
}
|
||||
} else if gitspaceConfig.IDE == enum.IDETypeVSCode {
|
||||
// TODO: the following userID is hard coded and should be changed.
|
||||
userID := "harness"
|
||||
ideURL = url.URL{
|
||||
Scheme: "vscode-remote",
|
||||
Host: "", // Empty since we include the host and port in the path
|
||||
Path: fmt.Sprintf(
|
||||
"ssh-remote+%s@%s:%s",
|
||||
userID,
|
||||
infra.Host,
|
||||
filepath.Join(forwardedPort, repoName),
|
||||
),
|
||||
}
|
||||
}
|
||||
ideURLString := ideURL.String()
|
||||
gitspaceInstance.URL = &ideURLString
|
||||
|
||||
gitspaceInstance.LastUsed = time.Now().UnixMilli()
|
||||
gitspaceInstance.State = enum.GitspaceInstanceStateRunning
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeGitspaceActionStartCompleted)
|
||||
|
||||
return nil
|
||||
return instanceState, nil
|
||||
}
|
||||
|
||||
func (o orchestrator) StopGitspace(
|
||||
func (o orchestrator) TriggerStopGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
) error {
|
||||
gitspaceInstance := gitspaceConfig.GitspaceInstance
|
||||
gitspaceInstance.State = enum.GitspaceInstanceStateError
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) (enum.GitspaceInstanceStateType, error) {
|
||||
instanceState := enum.GitspaceInstanceStateError
|
||||
|
||||
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
return instanceState, fmt.Errorf(
|
||||
"cannot get the infraProviderResource with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
infra, err := o.infraProvisioner.Find(ctx, infraProviderResource, gitspaceConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot find the provisioned infra: %w", err)
|
||||
return instanceState, fmt.Errorf("cannot find the provisioned infra: %w", err)
|
||||
}
|
||||
|
||||
err = o.stopGitspaceContainer(ctx, gitspaceConfig, infra)
|
||||
if err != nil {
|
||||
return err
|
||||
return instanceState, err
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopStart)
|
||||
|
||||
_, err = o.infraProvisioner.Stop(ctx, infraProviderResource, gitspaceConfig)
|
||||
err = o.infraProvisioner.TriggerStop(ctx, infraProviderResource, gitspaceConfig)
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopFailed)
|
||||
|
||||
return fmt.Errorf(
|
||||
"cannot stop provisioned infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
return instanceState, fmt.Errorf(
|
||||
"cannot trigger stop infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopCompleted)
|
||||
instanceState = enum.GitspaceInstanceStateStopping
|
||||
|
||||
gitspaceInstance.State = enum.GitspaceInstanceStateDeleted
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeGitspaceActionStopCompleted)
|
||||
|
||||
return err
|
||||
return instanceState, nil
|
||||
}
|
||||
|
||||
func (o orchestrator) stopGitspaceContainer(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
infra *infraprovider.Infrastructure,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
infra *types.Infrastructure,
|
||||
) error {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
|
||||
|
||||
|
@ -261,8 +174,8 @@ func (o orchestrator) stopGitspaceContainer(
|
|||
|
||||
func (o orchestrator) stopAndRemoveGitspaceContainer(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
infra *infraprovider.Infrastructure,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
infra *types.Infrastructure,
|
||||
) error {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
|
||||
|
||||
|
@ -288,51 +201,45 @@ func (o orchestrator) stopAndRemoveGitspaceContainer(
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o orchestrator) DeleteGitspace(
|
||||
func (o orchestrator) TriggerDeleteGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
) (*types.GitspaceInstance, error) {
|
||||
gitspaceInstance := gitspaceConfig.GitspaceInstance
|
||||
gitspaceInstance.State = enum.GitspaceInstanceStateError
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) (enum.GitspaceInstanceStateType, error) {
|
||||
instanceState := enum.GitspaceInstanceStateError
|
||||
|
||||
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
return instanceState, fmt.Errorf(
|
||||
"cannot get the infraProviderResource with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
infra, err := o.infraProvisioner.Find(ctx, infraProviderResource, gitspaceConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot find the provisioned infra: %w", err)
|
||||
return instanceState, fmt.Errorf("cannot find the provisioned infra: %w", err)
|
||||
}
|
||||
|
||||
err = o.stopAndRemoveGitspaceContainer(ctx, gitspaceConfig, infra)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return instanceState, err
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningStart)
|
||||
|
||||
_, err = o.infraProvisioner.Deprovision(ctx, infraProviderResource, gitspaceConfig)
|
||||
err = o.infraProvisioner.TriggerDeprovision(ctx, infraProviderResource, gitspaceConfig)
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningFailed)
|
||||
|
||||
return nil, fmt.Errorf(
|
||||
"cannot deprovision infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
return instanceState, fmt.Errorf(
|
||||
"cannot trigger deprovision infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
instanceState = enum.GitspaceInstanceStateStopping
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningCompleted)
|
||||
|
||||
gitspaceInstance.State = enum.GitspaceInstanceStateDeleted
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeGitspaceActionStopCompleted)
|
||||
|
||||
return gitspaceInstance, nil
|
||||
return instanceState, nil
|
||||
}
|
||||
|
||||
func (o orchestrator) emitGitspaceEvent(
|
||||
ctx context.Context,
|
||||
config *types.GitspaceConfig,
|
||||
config types.GitspaceConfig,
|
||||
eventType enum.GitspaceEventType,
|
||||
) {
|
||||
o.eventReporter.EmitGitspaceEvent(
|
||||
|
@ -347,7 +254,7 @@ func (o orchestrator) emitGitspaceEvent(
|
|||
})
|
||||
}
|
||||
|
||||
func (o orchestrator) getIDEService(gitspaceConfig *types.GitspaceConfig) (ide.IDE, error) {
|
||||
func (o orchestrator) getIDEService(gitspaceConfig types.GitspaceConfig) (ide.IDE, error) {
|
||||
var ideService ide.IDE
|
||||
|
||||
switch gitspaceConfig.IDE {
|
||||
|
@ -361,3 +268,180 @@ func (o orchestrator) getIDEService(gitspaceConfig *types.GitspaceConfig) (ide.I
|
|||
|
||||
return ideService, nil
|
||||
}
|
||||
|
||||
func (o orchestrator) ResumeStartGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
provisionedInfra *types.Infrastructure,
|
||||
) (types.GitspaceInstance, error) {
|
||||
gitspaceInstance := *gitspaceConfig.GitspaceInstance
|
||||
gitspaceInstance.State = enum.GitspaceInstanceStateError
|
||||
|
||||
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
|
||||
if err != nil {
|
||||
return gitspaceInstance, fmt.Errorf("cannot get the infraprovider resource for ID %d: %w",
|
||||
gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
ideSvc, err := o.getIDEService(gitspaceConfig)
|
||||
if err != nil {
|
||||
return gitspaceInstance, err
|
||||
}
|
||||
|
||||
idePort := ideSvc.Port()
|
||||
|
||||
provisionedInfra, err = o.infraProvisioner.ResumeProvision(
|
||||
ctx, infraProviderResource, gitspaceConfig, []int{idePort}, provisionedInfra)
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningFailed)
|
||||
|
||||
return gitspaceInstance, fmt.Errorf(
|
||||
"cannot provision infrastructure for ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningCompleted)
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeFetchDevcontainerStart)
|
||||
|
||||
scmResolvedDetails, err := o.scm.GetSCMRepoDetails(ctx, gitspaceConfig)
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeFetchDevcontainerFailed)
|
||||
|
||||
return gitspaceInstance, fmt.Errorf(
|
||||
"failed to fetch code repo details for gitspace config ID %w %d", err, gitspaceConfig.ID)
|
||||
}
|
||||
devcontainerConfig := scmResolvedDetails.DevcontainerConfig
|
||||
repoName := scmResolvedDetails.RepoName
|
||||
|
||||
if devcontainerConfig == nil {
|
||||
log.Warn().Err(err).Msg("devcontainer config is nil, using empty config")
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeFetchDevcontainerCompleted)
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
|
||||
|
||||
err = o.containerOrchestrator.Status(ctx, provisionedInfra)
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed)
|
||||
|
||||
return gitspaceInstance, fmt.Errorf("couldn't call the agent health API: %w", err)
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectCompleted)
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationStart)
|
||||
|
||||
startResponse, err := o.containerOrchestrator.CreateAndStartGitspace(
|
||||
ctx, gitspaceConfig, provisionedInfra, scmResolvedDetails, o.config.DefaultBaseImage, ideSvc)
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationFailed)
|
||||
|
||||
return gitspaceInstance, fmt.Errorf("couldn't call the agent start API: %w", err)
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationCompleted)
|
||||
|
||||
var ideURL url.URL
|
||||
|
||||
var forwardedPort string
|
||||
|
||||
if provisionedInfra.PortMappings[idePort].PublishedPort == 0 {
|
||||
forwardedPort = startResponse.PublishedPorts[idePort]
|
||||
} else {
|
||||
forwardedPort = strconv.Itoa(provisionedInfra.PortMappings[idePort].ForwardedPort)
|
||||
}
|
||||
|
||||
host := provisionedInfra.Host
|
||||
if provisionedInfra.ProxyHost != "" {
|
||||
host = provisionedInfra.ProxyHost
|
||||
}
|
||||
|
||||
if gitspaceConfig.IDE == enum.IDETypeVSCodeWeb {
|
||||
ideURL = url.URL{
|
||||
Scheme: "http",
|
||||
Host: host + ":" + forwardedPort,
|
||||
RawQuery: filepath.Join("folder=", repoName),
|
||||
}
|
||||
} else if gitspaceConfig.IDE == enum.IDETypeVSCode {
|
||||
// TODO: the following userID is hard coded and should be changed.
|
||||
userID := "harness"
|
||||
ideURL = url.URL{
|
||||
Scheme: "vscode-remote",
|
||||
Host: "", // Empty since we include the host and port in the path
|
||||
Path: fmt.Sprintf(
|
||||
"ssh-remote+%s@%s:%s",
|
||||
userID,
|
||||
host,
|
||||
filepath.Join(forwardedPort, repoName),
|
||||
),
|
||||
}
|
||||
}
|
||||
ideURLString := ideURL.String()
|
||||
gitspaceInstance.URL = &ideURLString
|
||||
|
||||
gitspaceInstance.LastUsed = time.Now().UnixMilli()
|
||||
gitspaceInstance.State = enum.GitspaceInstanceStateRunning
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeGitspaceActionStartCompleted)
|
||||
|
||||
return gitspaceInstance, nil
|
||||
}
|
||||
|
||||
func (o orchestrator) ResumeStopGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
stoppedInfra *types.Infrastructure,
|
||||
) (enum.GitspaceInstanceStateType, error) {
|
||||
instanceState := enum.GitspaceInstanceStateError
|
||||
|
||||
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
|
||||
if err != nil {
|
||||
return instanceState, fmt.Errorf(
|
||||
"cannot get the infraProviderResource with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
_, err = o.infraProvisioner.ResumeStop(ctx, infraProviderResource, gitspaceConfig, stoppedInfra)
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopFailed)
|
||||
|
||||
return instanceState, fmt.Errorf(
|
||||
"cannot stop provisioned infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopCompleted)
|
||||
|
||||
instanceState = enum.GitspaceInstanceStateDeleted
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeGitspaceActionStopCompleted)
|
||||
|
||||
return instanceState, nil
|
||||
}
|
||||
|
||||
func (o orchestrator) ResumeDeleteGitspace(
|
||||
ctx context.Context,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
deprovisionedInfra *types.Infrastructure,
|
||||
) (enum.GitspaceInstanceStateType, error) {
|
||||
instanceState := enum.GitspaceInstanceStateError
|
||||
|
||||
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
|
||||
if err != nil {
|
||||
return instanceState, fmt.Errorf(
|
||||
"cannot get the infraProviderResource with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
_, err = o.infraProvisioner.ResumeDeprovision(ctx, infraProviderResource, gitspaceConfig, deprovisionedInfra)
|
||||
if err != nil {
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningFailed)
|
||||
return instanceState, fmt.Errorf(
|
||||
"cannot deprovision infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
|
||||
}
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningCompleted)
|
||||
|
||||
instanceState = enum.GitspaceInstanceStateDeleted
|
||||
|
||||
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeGitspaceActionStopCompleted)
|
||||
return instanceState, nil
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ func NewGitnessSCM(repoStore store.RepoStore, git git.Interface,
|
|||
|
||||
func (s GitnessSCM) ResolveCredentials(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) (*ResolvedCredentials, error) {
|
||||
repoURL, err := url.Parse(gitspaceConfig.CodeRepoURL)
|
||||
if err != nil {
|
||||
|
@ -116,7 +116,7 @@ func (s GitnessSCM) ResolveCredentials(
|
|||
}
|
||||
|
||||
func (s GitnessSCM) GetFileContent(ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
filePath string,
|
||||
) ([]byte, error) {
|
||||
repo, err := s.repoStore.FindByRef(ctx, *gitspaceConfig.CodeRepoRef)
|
||||
|
|
|
@ -39,7 +39,7 @@ func NewGenericSCM() *GenericSCM {
|
|||
}
|
||||
|
||||
func (s GenericSCM) GetFileContent(ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
filePath string,
|
||||
) ([]byte, error) {
|
||||
gitWorkingDirectory := "/tmp/git/"
|
||||
|
@ -102,7 +102,7 @@ func (s GenericSCM) GetFileContent(ctx context.Context,
|
|||
|
||||
func (s GenericSCM) ResolveCredentials(
|
||||
_ context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) (*ResolvedCredentials, error) {
|
||||
var resolvedCredentials = &ResolvedCredentials{
|
||||
Branch: gitspaceConfig.Branch,
|
||||
|
|
|
@ -41,7 +41,7 @@ type SCM interface {
|
|||
// GetSCMRepoDetails fetches repository name, credentials & devcontainer config file from the given repo and branch.
|
||||
GetSCMRepoDetails(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) (*ResolvedDetails, error)
|
||||
|
||||
// CheckValidCodeRepo checks if the current URL is a valid and accessible code repo,
|
||||
|
@ -86,7 +86,7 @@ func (s scm) CheckValidCodeRepo(
|
|||
|
||||
func (s scm) GetSCMRepoDetails(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
) (*ResolvedDetails, error) {
|
||||
filePath := devcontainerDefaultPath
|
||||
if gitspaceConfig.CodeRepoType == "" {
|
||||
|
|
|
@ -23,10 +23,10 @@ import (
|
|||
)
|
||||
|
||||
type Provider interface {
|
||||
ResolveCredentials(ctx context.Context, gitspaceConfig *types.GitspaceConfig) (*ResolvedCredentials, error)
|
||||
ResolveCredentials(ctx context.Context, gitspaceConfig types.GitspaceConfig) (*ResolvedCredentials, error)
|
||||
GetFileContent(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
filePath string,
|
||||
) ([]byte, error)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitspace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
const resourceNotFoundErr = "Failed to find gitspace: resource not found"
|
||||
|
||||
func (c *Service) Find(
|
||||
ctx context.Context,
|
||||
spaceID int64,
|
||||
spacePath string,
|
||||
identifier string,
|
||||
) (*types.GitspaceConfig, error) {
|
||||
var gitspaceConfigResult *types.GitspaceConfig
|
||||
txErr := c.tx.WithTx(ctx, func(ctx context.Context) error {
|
||||
gitspaceConfig, err := c.gitspaceConfigStore.FindByIdentifier(ctx, spaceID, identifier)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find gitspace config: %w", err)
|
||||
}
|
||||
infraProviderResource, err := c.infraProviderSvc.FindResource(ctx, gitspaceConfig.InfraProviderResourceID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find infra provider resource for gitspace config: %w", err)
|
||||
}
|
||||
gitspaceConfig.SpacePath = spacePath
|
||||
gitspaceConfig.InfraProviderResourceIdentifier = infraProviderResource.Identifier
|
||||
instance, err := c.gitspaceInstanceStore.FindLatestByGitspaceConfigID(ctx, gitspaceConfig.ID, gitspaceConfig.SpaceID)
|
||||
if err != nil && err.Error() != resourceNotFoundErr { // TODO fix this
|
||||
return fmt.Errorf("failed to find gitspace instance for config ID : %s %w", gitspaceConfig.Identifier, err)
|
||||
}
|
||||
if instance != nil {
|
||||
gitspaceConfig.GitspaceInstance = instance
|
||||
instance.SpacePath = gitspaceConfig.SpacePath
|
||||
gitspaceStateType, err := enum.GetGitspaceStateFromInstance(instance.State)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gitspaceConfig.State = gitspaceStateType
|
||||
} else {
|
||||
gitspaceConfig.State = enum.GitspaceStateUninitialized
|
||||
}
|
||||
gitspaceConfigResult = gitspaceConfig
|
||||
return nil
|
||||
}, dbtx.TxDefaultReadOnly)
|
||||
if txErr != nil {
|
||||
return nil, txErr
|
||||
}
|
||||
return gitspaceConfigResult, nil
|
||||
}
|
|
@ -18,6 +18,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/app/services/infraprovider"
|
||||
"github.com/harness/gitness/app/store"
|
||||
"github.com/harness/gitness/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
|
@ -29,12 +30,14 @@ func NewService(
|
|||
gitspaceStore store.GitspaceConfigStore,
|
||||
gitspaceInstanceStore store.GitspaceInstanceStore,
|
||||
spaceStore store.SpaceStore,
|
||||
infraProviderSvc *infraprovider.Service,
|
||||
) *Service {
|
||||
return &Service{
|
||||
tx: tx,
|
||||
gitspaceConfigStore: gitspaceStore,
|
||||
gitspaceInstanceStore: gitspaceInstanceStore,
|
||||
spaceStore: spaceStore,
|
||||
infraProviderSvc: infraProviderSvc,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,6 +46,7 @@ type Service struct {
|
|||
gitspaceInstanceStore store.GitspaceInstanceStore
|
||||
spaceStore store.SpaceStore
|
||||
tx dbtx.Transactor
|
||||
infraProviderSvc *infraprovider.Service
|
||||
}
|
||||
|
||||
func (c *Service) ListGitspacesForSpace(
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitspace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
)
|
||||
|
||||
func (c *Service) UpdateConfig(
|
||||
ctx context.Context,
|
||||
gitspaceConfig *types.GitspaceConfig,
|
||||
) error {
|
||||
err := c.gitspaceConfigStore.Update(ctx, gitspaceConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update gitspace config: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitspace
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
)
|
||||
|
||||
func (c *Service) UpdateInstance(
|
||||
ctx context.Context,
|
||||
gitspaceInstance *types.GitspaceInstance,
|
||||
) error {
|
||||
err := c.gitspaceInstanceStore.Update(ctx, gitspaceInstance)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update gitspace instance: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
package gitspace
|
||||
|
||||
import (
|
||||
"github.com/harness/gitness/app/services/infraprovider"
|
||||
"github.com/harness/gitness/app/store"
|
||||
"github.com/harness/gitness/store/database/dbtx"
|
||||
|
||||
|
@ -30,6 +31,7 @@ func ProvideGitspace(
|
|||
gitspaceStore store.GitspaceConfigStore,
|
||||
gitspaceInstanceStore store.GitspaceInstanceStore,
|
||||
spaceStore store.SpaceStore,
|
||||
infraProviderSvc *infraprovider.Service,
|
||||
) *Service {
|
||||
return NewService(tx, gitspaceStore, gitspaceInstanceStore, spaceStore)
|
||||
return NewService(tx, gitspaceStore, gitspaceInstanceStore, spaceStore, infraProviderSvc)
|
||||
}
|
||||
|
|
|
@ -51,13 +51,13 @@ func (c *Config) Sanitize() error {
|
|||
}
|
||||
|
||||
type Service struct {
|
||||
config Config
|
||||
config *Config
|
||||
gitspaceEventStore store.GitspaceEventStore
|
||||
}
|
||||
|
||||
func NewService(
|
||||
ctx context.Context,
|
||||
config Config,
|
||||
config *Config,
|
||||
gitspaceEventReaderFactory *events.ReaderFactory[*gitspaceevents.Reader],
|
||||
gitspaceEventStore store.GitspaceEventStore,
|
||||
) (*Service, error) {
|
||||
|
|
|
@ -30,7 +30,7 @@ var WireSet = wire.NewSet(
|
|||
)
|
||||
|
||||
func ProvideService(ctx context.Context,
|
||||
config Config,
|
||||
config *Config,
|
||||
gitspaceEventReaderFactory *events.ReaderFactory[*gitspaceevents.Reader],
|
||||
gitspaceEventStore store.GitspaceEventStore,
|
||||
) (*Service, error) {
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitspaceinfraevent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
gitspaceEvents "github.com/harness/gitness/app/events/gitspace"
|
||||
gitspaceInfraEvents "github.com/harness/gitness/app/events/gitspaceinfra"
|
||||
"github.com/harness/gitness/events"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
func (s *Service) handleGitspaceInfraEvent(
|
||||
ctx context.Context,
|
||||
event *events.Event[*gitspaceInfraEvents.GitspaceInfraEventPayload],
|
||||
) error {
|
||||
payload := event.Payload
|
||||
|
||||
config, fetchErr := s.getConfig(ctx, payload.Infra.SpaceID, payload.Infra.SpacePath, payload.Infra.ResourceKey)
|
||||
if fetchErr != nil {
|
||||
return fetchErr
|
||||
}
|
||||
|
||||
var instance = config.GitspaceInstance
|
||||
var err error
|
||||
|
||||
switch payload.Type {
|
||||
case enum.InfraEventProvision:
|
||||
updatedInstance, err := s.orchestrator.ResumeStartGitspace(ctx, *config, payload.Infra)
|
||||
if err != nil {
|
||||
s.emitGitspaceConfigEvent(ctx, config, enum.GitspaceEventTypeGitspaceActionStartFailed)
|
||||
|
||||
return fmt.Errorf("failed to resume start gitspace: %w", err)
|
||||
}
|
||||
|
||||
instance = &updatedInstance
|
||||
|
||||
case enum.InfraEventStop:
|
||||
instanceState, err := s.orchestrator.ResumeStopGitspace(ctx, *config, payload.Infra)
|
||||
if err != nil {
|
||||
s.emitGitspaceConfigEvent(ctx, config, enum.GitspaceEventTypeGitspaceActionStopFailed)
|
||||
|
||||
return fmt.Errorf("failed to resume stop gitspace: %w", err)
|
||||
}
|
||||
|
||||
instance.State = instanceState
|
||||
|
||||
case enum.InfraEventDeprovision:
|
||||
instanceState, err := s.orchestrator.ResumeDeleteGitspace(ctx, *config, payload.Infra)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resume delete gitspace: %w", err)
|
||||
}
|
||||
|
||||
instance.State = instanceState
|
||||
|
||||
config.IsDeleted = true
|
||||
if err = s.gitspaceSvc.UpdateConfig(ctx, config); err != nil {
|
||||
return fmt.Errorf("failed to delete gitspace config with ID: %s %w", config.Identifier, err)
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown event type: %s", event.Payload.Type)
|
||||
}
|
||||
|
||||
err = s.gitspaceSvc.UpdateInstance(ctx, instance)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update gitspace instance: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) getConfig(
|
||||
ctx context.Context,
|
||||
spaceID int64,
|
||||
spacePath string,
|
||||
identifier string,
|
||||
) (*types.GitspaceConfig, error) {
|
||||
config, err := s.gitspaceSvc.Find(ctx, spaceID, spacePath, identifier)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"failed to find gitspace config during infra event handling, identifier %s: %w", identifier, err)
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func (s *Service) emitGitspaceConfigEvent(ctx context.Context,
|
||||
config *types.GitspaceConfig,
|
||||
eventType enum.GitspaceEventType,
|
||||
) {
|
||||
s.eventReporter.EmitGitspaceEvent(ctx, gitspaceEvents.GitspaceEvent, &gitspaceEvents.GitspaceEventPayload{
|
||||
QueryKey: config.Identifier,
|
||||
EntityID: config.ID,
|
||||
EntityType: enum.GitspaceEntityTypeGitspaceConfig,
|
||||
EventType: eventType,
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
})
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitspaceinfraevent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
gitspaceevents "github.com/harness/gitness/app/events/gitspace"
|
||||
gitspaceinfraevents "github.com/harness/gitness/app/events/gitspaceinfra"
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator"
|
||||
"github.com/harness/gitness/app/services/gitspace"
|
||||
"github.com/harness/gitness/app/services/gitspaceevent"
|
||||
"github.com/harness/gitness/events"
|
||||
"github.com/harness/gitness/stream"
|
||||
)
|
||||
|
||||
const groupGitspaceInfraEvents = "gitness:gitspaceinfra"
|
||||
|
||||
type Service struct {
|
||||
config *gitspaceevent.Config
|
||||
orchestrator orchestrator.Orchestrator
|
||||
gitspaceSvc *gitspace.Service
|
||||
eventReporter *gitspaceevents.Reporter
|
||||
}
|
||||
|
||||
func NewService(
|
||||
ctx context.Context,
|
||||
config *gitspaceevent.Config,
|
||||
gitspaceInfraEventReaderFactory *events.ReaderFactory[*gitspaceinfraevents.Reader],
|
||||
orchestrator orchestrator.Orchestrator,
|
||||
gitspaceSvc *gitspace.Service,
|
||||
eventReporter *gitspaceevents.Reporter,
|
||||
) (*Service, error) {
|
||||
if err := config.Sanitize(); err != nil {
|
||||
return nil, fmt.Errorf("provided gitspace infra event service config is invalid: %w", err)
|
||||
}
|
||||
service := &Service{
|
||||
config: config,
|
||||
orchestrator: orchestrator,
|
||||
gitspaceSvc: gitspaceSvc,
|
||||
eventReporter: eventReporter,
|
||||
}
|
||||
|
||||
_, err := gitspaceInfraEventReaderFactory.Launch(ctx, groupGitspaceInfraEvents, config.EventReaderName,
|
||||
func(r *gitspaceinfraevents.Reader) error {
|
||||
const idleTimeout = 1 * time.Minute
|
||||
r.Configure(
|
||||
stream.WithConcurrency(config.Concurrency),
|
||||
stream.WithHandlerOptions(
|
||||
stream.WithIdleTimeout(idleTimeout),
|
||||
stream.WithMaxRetries(config.MaxRetries),
|
||||
))
|
||||
|
||||
_ = r.RegisterGitspaceInfraEvent(service.handleGitspaceInfraEvent)
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to launch gitspace infra event reader: %w", err)
|
||||
}
|
||||
|
||||
return service, nil
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitspaceinfraevent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
gitspaceevents "github.com/harness/gitness/app/events/gitspace"
|
||||
gitspaceinfraevents "github.com/harness/gitness/app/events/gitspaceinfra"
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator"
|
||||
"github.com/harness/gitness/app/services/gitspace"
|
||||
"github.com/harness/gitness/app/services/gitspaceevent"
|
||||
"github.com/harness/gitness/events"
|
||||
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
// WireSet provides a wire set for this package.
|
||||
var WireSet = wire.NewSet(
|
||||
ProvideService,
|
||||
)
|
||||
|
||||
func ProvideService(
|
||||
ctx context.Context,
|
||||
config *gitspaceevent.Config,
|
||||
gitspaceInfraEventReaderFactory *events.ReaderFactory[*gitspaceinfraevents.Reader],
|
||||
orchestrator orchestrator.Orchestrator,
|
||||
gitspaceSvc *gitspace.Service,
|
||||
eventReporter *gitspaceevents.Reporter,
|
||||
) (*Service, error) {
|
||||
return NewService(
|
||||
ctx,
|
||||
config,
|
||||
gitspaceInfraEventReaderFactory,
|
||||
orchestrator,
|
||||
gitspaceSvc,
|
||||
eventReporter,
|
||||
)
|
||||
}
|
|
@ -93,7 +93,7 @@ func (c *Service) CreateInfraProvider(
|
|||
if len(infraProvider.TemplateParams()) > 0 {
|
||||
return fmt.Errorf("failed to fetch templates") // TODO Implement
|
||||
}
|
||||
parameters := []infraprovider.Parameter{}
|
||||
parameters := []types.InfraProviderParameter{}
|
||||
// TODO logic to populate paramteters as per the provider type
|
||||
err = infraProvider.ValidateParams(parameters)
|
||||
if err != nil {
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/harness/gitness/app/services/cleanup"
|
||||
"github.com/harness/gitness/app/services/gitspace"
|
||||
"github.com/harness/gitness/app/services/gitspaceevent"
|
||||
"github.com/harness/gitness/app/services/gitspaceinfraevent"
|
||||
"github.com/harness/gitness/app/services/infraprovider"
|
||||
"github.com/harness/gitness/app/services/keywordsearch"
|
||||
"github.com/harness/gitness/app/services/metric"
|
||||
|
@ -36,19 +37,20 @@ var WireSet = wire.NewSet(
|
|||
)
|
||||
|
||||
type Services struct {
|
||||
Webhook *webhook.Service
|
||||
PullReq *pullreq.Service
|
||||
Trigger *trigger.Service
|
||||
JobScheduler *job.Scheduler
|
||||
MetricCollector *metric.Collector
|
||||
RepoSizeCalculator *repo.SizeCalculator
|
||||
Repo *repo.Service
|
||||
Cleanup *cleanup.Service
|
||||
Notification *notification.Service
|
||||
Keywordsearch *keywordsearch.Service
|
||||
GitspaceEvent *gitspaceevent.Service
|
||||
infraProvider *infraprovider.Service
|
||||
gitspace *gitspace.Service
|
||||
Webhook *webhook.Service
|
||||
PullReq *pullreq.Service
|
||||
Trigger *trigger.Service
|
||||
JobScheduler *job.Scheduler
|
||||
MetricCollector *metric.Collector
|
||||
RepoSizeCalculator *repo.SizeCalculator
|
||||
Repo *repo.Service
|
||||
Cleanup *cleanup.Service
|
||||
Notification *notification.Service
|
||||
Keywordsearch *keywordsearch.Service
|
||||
GitspaceEvent *gitspaceevent.Service
|
||||
infraProvider *infraprovider.Service
|
||||
gitspace *gitspace.Service
|
||||
gitspaceInfraEventSvc *gitspaceinfraevent.Service
|
||||
}
|
||||
|
||||
func ProvideServices(
|
||||
|
@ -65,20 +67,22 @@ func ProvideServices(
|
|||
gitspaceEventSvc *gitspaceevent.Service,
|
||||
infraProviderSvc *infraprovider.Service,
|
||||
gitspaceSvc *gitspace.Service,
|
||||
gitspaceInfraEventSvc *gitspaceinfraevent.Service,
|
||||
) Services {
|
||||
return Services{
|
||||
Webhook: webhooksSvc,
|
||||
PullReq: pullReqSvc,
|
||||
Trigger: triggerSvc,
|
||||
JobScheduler: jobScheduler,
|
||||
MetricCollector: metricCollector,
|
||||
RepoSizeCalculator: repoSizeCalculator,
|
||||
Repo: repo,
|
||||
Cleanup: cleanupSvc,
|
||||
Notification: notificationSvc,
|
||||
Keywordsearch: keywordsearchSvc,
|
||||
GitspaceEvent: gitspaceEventSvc,
|
||||
infraProvider: infraProviderSvc,
|
||||
gitspace: gitspaceSvc,
|
||||
Webhook: webhooksSvc,
|
||||
PullReq: pullReqSvc,
|
||||
Trigger: triggerSvc,
|
||||
JobScheduler: jobScheduler,
|
||||
MetricCollector: metricCollector,
|
||||
RepoSizeCalculator: repoSizeCalculator,
|
||||
Repo: repo,
|
||||
Cleanup: cleanupSvc,
|
||||
Notification: notificationSvc,
|
||||
Keywordsearch: keywordsearchSvc,
|
||||
GitspaceEvent: gitspaceEventSvc,
|
||||
infraProvider: infraProviderSvc,
|
||||
gitspace: gitspaceSvc,
|
||||
gitspaceInfraEventSvc: gitspaceInfraEventSvc,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,10 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/harness/gitness/app/store"
|
||||
"github.com/harness/gitness/infraprovider/enum"
|
||||
"github.com/harness/gitness/store/database"
|
||||
"github.com/harness/gitness/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/pkg/errors"
|
||||
|
|
|
@ -19,10 +19,10 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
"github.com/harness/gitness/app/store"
|
||||
"github.com/harness/gitness/infraprovider/enum"
|
||||
"github.com/harness/gitness/store/database"
|
||||
"github.com/harness/gitness/store/database/dbtx"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
"github.com/guregu/null"
|
||||
"github.com/jmoiron/sqlx"
|
||||
|
|
|
@ -413,8 +413,8 @@ func ProvideGitspaceOrchestratorConfig(config *types.Config) *orchestrator.Confi
|
|||
}
|
||||
|
||||
// ProvideGitspaceEventConfig loads the gitspace event service config from the main config.
|
||||
func ProvideGitspaceEventConfig(config *types.Config) gitspaceevent.Config {
|
||||
return gitspaceevent.Config{
|
||||
func ProvideGitspaceEventConfig(config *types.Config) *gitspaceevent.Config {
|
||||
return &gitspaceevent.Config{
|
||||
EventReaderName: config.InstanceID,
|
||||
Concurrency: config.Gitspace.Events.Concurrency,
|
||||
MaxRetries: config.Gitspace.Events.MaxRetries,
|
||||
|
|
|
@ -42,6 +42,7 @@ import (
|
|||
"github.com/harness/gitness/app/bootstrap"
|
||||
gitevents "github.com/harness/gitness/app/events/git"
|
||||
gitspaceevents "github.com/harness/gitness/app/events/gitspace"
|
||||
gitspaceinfraevents "github.com/harness/gitness/app/events/gitspaceinfra"
|
||||
pullreqevents "github.com/harness/gitness/app/events/pullreq"
|
||||
repoevents "github.com/harness/gitness/app/events/repo"
|
||||
infrastructure "github.com/harness/gitness/app/gitspace/infrastructure"
|
||||
|
@ -68,6 +69,7 @@ import (
|
|||
"github.com/harness/gitness/app/services/exporter"
|
||||
gitspaceSvc "github.com/harness/gitness/app/services/gitspace"
|
||||
"github.com/harness/gitness/app/services/gitspaceevent"
|
||||
gitspaceInfraEventSvc "github.com/harness/gitness/app/services/gitspaceinfraevent"
|
||||
"github.com/harness/gitness/app/services/importer"
|
||||
infraproviderSvc "github.com/harness/gitness/app/services/infraprovider"
|
||||
"github.com/harness/gitness/app/services/keywordsearch"
|
||||
|
@ -153,6 +155,7 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
|
|||
gitspaceCtrl.WireSet,
|
||||
infraproviderSvc.WireSet,
|
||||
gitspaceSvc.WireSet,
|
||||
gitspaceInfraEventSvc.WireSet,
|
||||
gitevents.WireSet,
|
||||
pullreqevents.WireSet,
|
||||
repoevents.WireSet,
|
||||
|
@ -231,6 +234,7 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
|
|||
logutil.WireSet,
|
||||
cliserver.ProvideGitspaceOrchestratorConfig,
|
||||
ide.WireSet,
|
||||
gitspaceinfraevents.WireSet,
|
||||
)
|
||||
return &cliserver.System{}, nil
|
||||
}
|
||||
|
|
|
@ -39,9 +39,10 @@ import (
|
|||
"github.com/harness/gitness/app/auth/authn"
|
||||
"github.com/harness/gitness/app/auth/authz"
|
||||
"github.com/harness/gitness/app/bootstrap"
|
||||
events4 "github.com/harness/gitness/app/events/git"
|
||||
events5 "github.com/harness/gitness/app/events/gitspace"
|
||||
events3 "github.com/harness/gitness/app/events/pullreq"
|
||||
events5 "github.com/harness/gitness/app/events/git"
|
||||
events6 "github.com/harness/gitness/app/events/gitspace"
|
||||
events3 "github.com/harness/gitness/app/events/gitspaceinfra"
|
||||
events4 "github.com/harness/gitness/app/events/pullreq"
|
||||
events2 "github.com/harness/gitness/app/events/repo"
|
||||
"github.com/harness/gitness/app/gitspace/infrastructure"
|
||||
"github.com/harness/gitness/app/gitspace/logutil"
|
||||
|
@ -67,6 +68,7 @@ import (
|
|||
"github.com/harness/gitness/app/services/exporter"
|
||||
"github.com/harness/gitness/app/services/gitspace"
|
||||
"github.com/harness/gitness/app/services/gitspaceevent"
|
||||
"github.com/harness/gitness/app/services/gitspaceinfraevent"
|
||||
"github.com/harness/gitness/app/services/importer"
|
||||
infraprovider2 "github.com/harness/gitness/app/services/infraprovider"
|
||||
"github.com/harness/gitness/app/services/keywordsearch"
|
||||
|
@ -252,7 +254,21 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
}
|
||||
gitspaceConfigStore := database.ProvideGitspaceConfigStore(db)
|
||||
gitspaceInstanceStore := database.ProvideGitspaceInstanceStore(db)
|
||||
gitspaceService := gitspace.ProvideGitspace(transactor, gitspaceConfigStore, gitspaceInstanceStore, spaceStore)
|
||||
infraProviderResourceStore := database.ProvideInfraProviderResourceStore(db)
|
||||
infraProviderConfigStore := database.ProvideInfraProviderConfigStore(db)
|
||||
dockerConfig, err := server.ProvideDockerConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dockerClientFactory := infraprovider.ProvideDockerClientFactory(dockerConfig)
|
||||
eventsReporter, err := events3.ProvideReporter(eventsSystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dockerProvider := infraprovider.ProvideDockerProvider(dockerConfig, dockerClientFactory, eventsReporter)
|
||||
factory := infraprovider.ProvideFactory(dockerProvider)
|
||||
infraproviderService := infraprovider2.ProvideInfraProvider(transactor, infraProviderResourceStore, infraProviderConfigStore, factory, spaceStore)
|
||||
gitspaceService := gitspace.ProvideGitspace(transactor, gitspaceConfigStore, gitspaceInstanceStore, spaceStore, infraproviderService)
|
||||
spaceController := space.ProvideController(config, transactor, provider, streamer, spaceIdentifier, authorizer, spacePathStore, pipelineStore, secretStore, connectorStore, templateStore, spaceStore, repoStore, principalStore, repoController, membershipStore, repository, exporterRepository, resourceLimiter, publicaccessService, auditService, gitspaceService, gitspaceConfigStore, gitspaceInstanceStore, labelService)
|
||||
pipelineController := pipeline.ProvideController(repoStore, triggerStore, authorizer, pipelineStore)
|
||||
secretController := secret.ProvideController(encrypter, secretStore, authorizer, spaceStore)
|
||||
|
@ -266,27 +282,27 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
pullReqReviewStore := database.ProvidePullReqReviewStore(db)
|
||||
pullReqReviewerStore := database.ProvidePullReqReviewerStore(db, principalInfoCache)
|
||||
pullReqFileViewStore := database.ProvidePullReqFileViewStore(db)
|
||||
eventsReporter, err := events3.ProvideReporter(eventsSystem)
|
||||
reporter2, err := events4.ProvideReporter(eventsSystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
migrator := codecomments.ProvideMigrator(gitInterface)
|
||||
readerFactory, err := events4.ProvideReaderFactory(eventsSystem)
|
||||
readerFactory, err := events5.ProvideReaderFactory(eventsSystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
eventsReaderFactory, err := events3.ProvideReaderFactory(eventsSystem)
|
||||
eventsReaderFactory, err := events4.ProvideReaderFactory(eventsSystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repoGitInfoView := database.ProvideRepoGitInfoView(db)
|
||||
repoGitInfoCache := cache.ProvideRepoGitInfoCache(repoGitInfoView)
|
||||
pullreqService, err := pullreq.ProvideService(ctx, config, readerFactory, eventsReaderFactory, eventsReporter, gitInterface, repoGitInfoCache, repoStore, pullReqStore, pullReqActivityStore, codeCommentView, migrator, pullReqFileViewStore, pubSub, provider, streamer)
|
||||
pullreqService, err := pullreq.ProvideService(ctx, config, readerFactory, eventsReaderFactory, reporter2, gitInterface, repoGitInfoCache, repoStore, pullReqStore, pullReqActivityStore, codeCommentView, migrator, pullReqFileViewStore, pubSub, provider, streamer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pullReq := importer.ProvidePullReqImporter(provider, gitInterface, principalStore, repoStore, pullReqStore, pullReqActivityStore, transactor)
|
||||
pullreqController := pullreq2.ProvideController(transactor, provider, authorizer, pullReqStore, pullReqActivityStore, codeCommentView, pullReqReviewStore, pullReqReviewerStore, repoStore, principalStore, principalInfoCache, pullReqFileViewStore, membershipStore, checkStore, gitInterface, eventsReporter, migrator, pullreqService, protectionManager, streamer, codeownersService, lockerLocker, pullReq, labelService)
|
||||
pullreqController := pullreq2.ProvideController(transactor, provider, authorizer, pullReqStore, pullReqActivityStore, codeCommentView, pullReqReviewStore, pullReqReviewerStore, repoStore, principalStore, principalInfoCache, pullReqFileViewStore, membershipStore, checkStore, gitInterface, reporter2, migrator, pullreqService, protectionManager, streamer, codeownersService, lockerLocker, pullReq, labelService)
|
||||
webhookConfig := server.ProvideWebhookConfig(config)
|
||||
webhookStore := database.ProvideWebhookStore(db)
|
||||
webhookExecutionStore := database.ProvideWebhookExecutionStore(db)
|
||||
|
@ -295,7 +311,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
return nil, err
|
||||
}
|
||||
webhookController := webhook2.ProvideController(webhookConfig, authorizer, webhookStore, webhookExecutionStore, repoStore, webhookService, encrypter)
|
||||
reporter2, err := events4.ProvideReporter(eventsSystem)
|
||||
reporter3, err := events5.ProvideReporter(eventsSystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -311,7 +327,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
githookController := githook.ProvideController(authorizer, principalStore, repoStore, reporter2, reporter, gitInterface, pullReqStore, provider, protectionManager, clientFactory, resourceLimiter, settingsService, preReceiveExtender, updateExtender, postReceiveExtender)
|
||||
githookController := githook.ProvideController(authorizer, principalStore, repoStore, reporter3, reporter, gitInterface, pullReqStore, provider, protectionManager, clientFactory, resourceLimiter, settingsService, preReceiveExtender, updateExtender, postReceiveExtender)
|
||||
serviceaccountController := serviceaccount.NewController(principalUID, authorizer, principalStore, spaceStore, repoStore, tokenStore)
|
||||
principalController := principal.ProvideController(principalStore, authorizer)
|
||||
v := check2.ProvideCheckSanitizers()
|
||||
|
@ -328,18 +344,8 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
uploadController := upload.ProvideController(authorizer, repoStore, blobStore)
|
||||
searcher := keywordsearch.ProvideSearcher(localIndexSearcher)
|
||||
keywordsearchController := keywordsearch2.ProvideController(authorizer, searcher, repoController, spaceController)
|
||||
infraProviderResourceStore := database.ProvideInfraProviderResourceStore(db)
|
||||
infraProviderConfigStore := database.ProvideInfraProviderConfigStore(db)
|
||||
dockerConfig, err := server.ProvideDockerConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dockerClientFactory := infraprovider.ProvideDockerClientFactory(dockerConfig)
|
||||
dockerProvider := infraprovider.ProvideDockerProvider(dockerConfig, dockerClientFactory)
|
||||
factory := infraprovider.ProvideFactory(dockerProvider)
|
||||
infraproviderService := infraprovider2.ProvideInfraProvider(transactor, infraProviderResourceStore, infraProviderConfigStore, factory, spaceStore)
|
||||
infraproviderController := infraprovider3.ProvideController(authorizer, spaceStore, infraproviderService)
|
||||
reporter3, err := events5.ProvideReporter(eventsSystem)
|
||||
reporter4, err := events6.ProvideReporter(eventsSystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -354,9 +360,9 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
vsCode := ide.ProvideVSCodeService()
|
||||
vsCodeWebConfig := server.ProvideIDEVSCodeWebConfig(config)
|
||||
vsCodeWeb := ide.ProvideVSCodeWebService(vsCodeWebConfig)
|
||||
orchestratorOrchestrator := orchestrator.ProvideOrchestrator(scmSCM, infraProviderResourceStore, infraProvisioner, containerOrchestrator, reporter3, orchestratorConfig, vsCode, vsCodeWeb)
|
||||
orchestratorOrchestrator := orchestrator.ProvideOrchestrator(scmSCM, infraProviderResourceStore, infraProvisioner, containerOrchestrator, reporter4, orchestratorConfig, vsCode, vsCodeWeb)
|
||||
gitspaceEventStore := database.ProvideGitspaceEventStore(db)
|
||||
gitspaceController := gitspace2.ProvideController(transactor, authorizer, infraproviderService, gitspaceConfigStore, gitspaceInstanceStore, spaceStore, reporter3, orchestratorOrchestrator, gitspaceEventStore, statefulLogger, scmSCM, repoStore)
|
||||
gitspaceController := gitspace2.ProvideController(transactor, authorizer, infraproviderService, gitspaceConfigStore, gitspaceInstanceStore, spaceStore, reporter4, orchestratorOrchestrator, gitspaceEventStore, statefulLogger, scmSCM, repoStore, gitspaceService)
|
||||
migrateController := migrate.ProvideController(authorizer, principalStore)
|
||||
openapiService := openapi.ProvideOpenAPIService()
|
||||
routerRouter := router.ProvideRouter(ctx, config, authenticator, repoController, reposettingsController, executionController, logsController, spaceController, pipelineController, secretController, triggerController, connectorController, templateController, pluginController, pullreqController, webhookController, githookController, gitInterface, serviceaccountController, controller, principalController, checkController, systemController, uploadController, keywordsearchController, infraproviderController, gitspaceController, migrateController, provider, openapiService)
|
||||
|
@ -410,7 +416,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
return nil, err
|
||||
}
|
||||
gitspaceeventConfig := server.ProvideGitspaceEventConfig(config)
|
||||
readerFactory3, err := events5.ProvideReaderFactory(eventsSystem)
|
||||
readerFactory3, err := events6.ProvideReaderFactory(eventsSystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -418,7 +424,15 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
servicesServices := services.ProvideServices(webhookService, pullreqService, triggerService, jobScheduler, collector, sizeCalculator, repoService, cleanupService, notificationService, keywordsearchService, gitspaceeventService, infraproviderService, gitspaceService)
|
||||
readerFactory4, err := events3.ProvideReaderFactory(eventsSystem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gitspaceinfraeventService, err := gitspaceinfraevent.ProvideService(ctx, gitspaceeventConfig, readerFactory4, orchestratorOrchestrator, gitspaceService, reporter4)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
servicesServices := services.ProvideServices(webhookService, pullreqService, triggerService, jobScheduler, collector, sizeCalculator, repoService, cleanupService, notificationService, keywordsearchService, gitspaceeventService, infraproviderService, gitspaceService, gitspaceinfraeventService)
|
||||
serverSystem := server.NewSystem(bootstrapBootstrap, serverServer, sshServer, poller, resolverManager, servicesServices)
|
||||
return serverSystem, nil
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ import (
|
|||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/harness/gitness/infraprovider/enum"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
|
@ -37,7 +38,7 @@ func NewDockerClientFactory(config *DockerConfig) *DockerClientFactory {
|
|||
// NewDockerClient returns a new docker client created using the docker config and infra.
|
||||
func (d *DockerClientFactory) NewDockerClient(
|
||||
_ context.Context,
|
||||
infra *Infrastructure,
|
||||
infra *types.Infrastructure,
|
||||
) (*client.Client, error) {
|
||||
if infra.ProviderType != enum.InfraProviderTypeDocker {
|
||||
return nil, fmt.Errorf("infra provider type %s not supported", infra.ProviderType)
|
||||
|
@ -49,7 +50,7 @@ func (d *DockerClientFactory) NewDockerClient(
|
|||
return dockerClient, nil
|
||||
}
|
||||
|
||||
func (d *DockerClientFactory) getClient(_ []Parameter) (*client.Client, error) {
|
||||
func (d *DockerClientFactory) getClient(_ []types.InfraProviderParameter) (*client.Client, error) {
|
||||
var opts []client.Opt
|
||||
|
||||
opts = append(opts, client.WithHost(d.config.DockerHost))
|
||||
|
|
|
@ -19,7 +19,9 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/harness/gitness/infraprovider/enum"
|
||||
events "github.com/harness/gitness/app/events/gitspaceinfra"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
"github.com/docker/docker/api/types/volume"
|
||||
"github.com/docker/docker/client"
|
||||
|
@ -31,15 +33,18 @@ var _ InfraProvider = (*DockerProvider)(nil)
|
|||
type DockerProvider struct {
|
||||
config *DockerConfig
|
||||
dockerClientFactory *DockerClientFactory
|
||||
eventReporter *events.Reporter
|
||||
}
|
||||
|
||||
func NewDockerProvider(
|
||||
config *DockerConfig,
|
||||
dockerClientFactory *DockerClientFactory,
|
||||
eventReporter *events.Reporter,
|
||||
) *DockerProvider {
|
||||
return &DockerProvider{
|
||||
config: config,
|
||||
dockerClientFactory: dockerClientFactory,
|
||||
eventReporter: eventReporter,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,17 +52,18 @@ func NewDockerProvider(
|
|||
// It does not start docker engine. It creates a directory in the host machine using the given resource key.
|
||||
func (d DockerProvider) Provision(
|
||||
ctx context.Context,
|
||||
spaceID int64,
|
||||
spacePath string,
|
||||
resourceKey string,
|
||||
requiredPorts []int,
|
||||
params []Parameter,
|
||||
) (*Infrastructure, error) {
|
||||
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, &Infrastructure{
|
||||
params []types.InfraProviderParameter,
|
||||
) error {
|
||||
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, &types.Infrastructure{
|
||||
ProviderType: enum.InfraProviderTypeDocker,
|
||||
Parameters: params,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting docker client from docker client factory: %w", err)
|
||||
return fmt.Errorf("error getting docker client from docker client factory: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
|
@ -69,20 +75,24 @@ func (d DockerProvider) Provision(
|
|||
|
||||
infrastructure, err := d.dockerHostInfo(ctx, dockerClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
infrastructure.SpaceID = spaceID
|
||||
infrastructure.SpacePath = spacePath
|
||||
infrastructure.ResourceKey = resourceKey
|
||||
|
||||
storageName, err := d.createNamedVolume(ctx, spacePath, resourceKey, dockerClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
infrastructure.Storage = storageName
|
||||
|
||||
var portMappings = make(map[int]*PortMapping, len(requiredPorts))
|
||||
var portMappings = make(map[int]*types.PortMapping, len(requiredPorts))
|
||||
|
||||
for _, requiredPort := range requiredPorts {
|
||||
portMapping := &PortMapping{
|
||||
portMapping := &types.PortMapping{
|
||||
PublishedPort: 0,
|
||||
ForwardedPort: 0,
|
||||
}
|
||||
|
@ -92,55 +102,81 @@ func (d DockerProvider) Provision(
|
|||
|
||||
infrastructure.PortMappings = portMappings
|
||||
|
||||
return infrastructure, nil
|
||||
event := &events.GitspaceInfraEventPayload{
|
||||
Infra: infrastructure,
|
||||
Type: enum.InfraEventProvision,
|
||||
}
|
||||
|
||||
d.eventReporter.EmitGitspaceInfraEvent(ctx, events.GitspaceInfraEvent, event)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find fetches the infrastructure with the current state, the method has no side effects on the infra.
|
||||
func (d DockerProvider) Find(
|
||||
ctx context.Context,
|
||||
spaceID int64,
|
||||
spacePath string,
|
||||
resourceKey string,
|
||||
params []Parameter,
|
||||
) (*Infrastructure, error) {
|
||||
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, &Infrastructure{
|
||||
params []types.InfraProviderParameter,
|
||||
) (*types.Infrastructure, error) {
|
||||
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, &types.Infrastructure{
|
||||
ProviderType: enum.InfraProviderTypeDocker,
|
||||
Parameters: params,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting docker client from docker client factory: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
closingErr := dockerClient.Close()
|
||||
if closingErr != nil {
|
||||
log.Ctx(ctx).Warn().Err(closingErr).Msg("failed to close docker client")
|
||||
}
|
||||
}()
|
||||
|
||||
infrastructure, err := d.dockerHostInfo(ctx, dockerClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
infrastructure.SpaceID = spaceID
|
||||
infrastructure.SpacePath = spacePath
|
||||
infrastructure.ResourceKey = resourceKey
|
||||
|
||||
name := volumeName(spacePath, resourceKey)
|
||||
|
||||
volumeInspect, err := dockerClient.VolumeInspect(ctx, name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't find the volume for %s : %w", name, err)
|
||||
}
|
||||
|
||||
infrastructure.Storage = volumeInspect.Name
|
||||
|
||||
return infrastructure, nil
|
||||
}
|
||||
|
||||
// Stop is NOOP as this provider uses already running docker engine. It does not stop the docker engine.
|
||||
func (d DockerProvider) Stop(_ context.Context, infra *Infrastructure) (*Infrastructure, error) {
|
||||
return infra, nil
|
||||
func (d DockerProvider) Stop(ctx context.Context, infra *types.Infrastructure) error {
|
||||
event := &events.GitspaceInfraEventPayload{
|
||||
Infra: infra,
|
||||
Type: enum.InfraEventStop,
|
||||
}
|
||||
|
||||
d.eventReporter.EmitGitspaceInfraEvent(ctx, events.GitspaceInfraEvent, event)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deprovision deletes the host machine directory created by Provision. It does not stop the docker engine.
|
||||
func (d DockerProvider) Deprovision(ctx context.Context, infra *Infrastructure) (*Infrastructure, error) {
|
||||
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, &Infrastructure{
|
||||
// Deprovision deletes the volume created by Provision. It does not stop the docker engine.
|
||||
func (d DockerProvider) Deprovision(ctx context.Context, infra *types.Infrastructure) error {
|
||||
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, &types.Infrastructure{
|
||||
ProviderType: enum.InfraProviderTypeDocker,
|
||||
Parameters: infra.Parameters,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting docker client from docker client factory: %w", err)
|
||||
return fmt.Errorf("error getting docker client from docker client factory: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
closingErr := dockerClient.Close()
|
||||
|
@ -150,23 +186,31 @@ func (d DockerProvider) Deprovision(ctx context.Context, infra *Infrastructure)
|
|||
}()
|
||||
err = dockerClient.VolumeRemove(ctx, infra.Storage, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't delete volume for %s : %w", infra.Storage, err)
|
||||
return fmt.Errorf("couldn't delete volume for %s : %w", infra.Storage, err)
|
||||
}
|
||||
return infra, nil
|
||||
|
||||
event := &events.GitspaceInfraEventPayload{
|
||||
Infra: infra,
|
||||
Type: enum.InfraEventDeprovision,
|
||||
}
|
||||
|
||||
d.eventReporter.EmitGitspaceInfraEvent(ctx, events.GitspaceInfraEvent, event)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AvailableParams returns empty slice as no params are defined.
|
||||
func (d DockerProvider) AvailableParams() []ParameterSchema {
|
||||
return []ParameterSchema{}
|
||||
func (d DockerProvider) AvailableParams() []types.InfraProviderParameterSchema {
|
||||
return []types.InfraProviderParameterSchema{}
|
||||
}
|
||||
|
||||
// ValidateParams returns nil as no params are defined.
|
||||
func (d DockerProvider) ValidateParams(_ []Parameter) error {
|
||||
func (d DockerProvider) ValidateParams(_ []types.InfraProviderParameter) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TemplateParams returns nil as no template params are used.
|
||||
func (d DockerProvider) TemplateParams() []ParameterSchema {
|
||||
func (d DockerProvider) TemplateParams() []types.InfraProviderParameterSchema {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -175,12 +219,15 @@ func (d DockerProvider) ProvisioningType() enum.InfraProvisioningType {
|
|||
return enum.InfraProvisioningTypeExisting
|
||||
}
|
||||
|
||||
func (d DockerProvider) dockerHostInfo(ctx context.Context, dockerClient *client.Client) (*Infrastructure, error) {
|
||||
func (d DockerProvider) dockerHostInfo(
|
||||
ctx context.Context,
|
||||
dockerClient *client.Client,
|
||||
) (*types.Infrastructure, error) {
|
||||
info, err := dockerClient.Info(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to connect to docker engine: %w", err)
|
||||
}
|
||||
return &Infrastructure{
|
||||
return &types.Infrastructure{
|
||||
Identifier: info.ID,
|
||||
ProviderType: enum.InfraProviderTypeDocker,
|
||||
Status: enum.InfraStatusProvisioned,
|
||||
|
|
|
@ -17,30 +17,38 @@ package infraprovider
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/infraprovider/enum"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
type InfraProvider interface {
|
||||
// Provision provisions infrastructure against a resourceKey with the provided parameters.
|
||||
Provision(
|
||||
ctx context.Context,
|
||||
spaceID int64,
|
||||
spacePath string,
|
||||
resourceKey string,
|
||||
requiredPorts []int,
|
||||
parameters []Parameter,
|
||||
) (*Infrastructure, error)
|
||||
parameters []types.InfraProviderParameter,
|
||||
) error
|
||||
// Find finds infrastructure provisioned against a resourceKey.
|
||||
Find(ctx context.Context, spacePath string, resourceKey string, parameters []Parameter) (*Infrastructure, error)
|
||||
Find(
|
||||
ctx context.Context,
|
||||
spaceID int64,
|
||||
spacePath string,
|
||||
resourceKey string,
|
||||
parameters []types.InfraProviderParameter,
|
||||
) (*types.Infrastructure, error)
|
||||
// Stop frees up the resources allocated against a resourceKey, which can be freed.
|
||||
Stop(ctx context.Context, infra *Infrastructure) (*Infrastructure, error)
|
||||
Stop(ctx context.Context, infra *types.Infrastructure) error
|
||||
// Deprovision removes all infrastructure provisioned againest the resourceKey.
|
||||
Deprovision(ctx context.Context, infra *Infrastructure) (*Infrastructure, error)
|
||||
Deprovision(ctx context.Context, infra *types.Infrastructure) error
|
||||
// AvailableParams provides a schema to define the infrastructure.
|
||||
AvailableParams() []ParameterSchema
|
||||
AvailableParams() []types.InfraProviderParameterSchema
|
||||
// ValidateParams validates the supplied params before defining the infrastructure resource .
|
||||
ValidateParams(parameters []Parameter) error
|
||||
ValidateParams(parameters []types.InfraProviderParameter) error
|
||||
// TemplateParams provides a list of params which are of type template.
|
||||
TemplateParams() []ParameterSchema
|
||||
TemplateParams() []types.InfraProviderParameterSchema
|
||||
// ProvisioningType specifies whether the provider will provision new infra resources or it will reuse existing.
|
||||
ProvisioningType() enum.InfraProvisioningType
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ package infraprovider
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/infraprovider/enum"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
type Factory struct {
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
package infraprovider
|
||||
|
||||
import (
|
||||
events "github.com/harness/gitness/app/events/gitspaceinfra"
|
||||
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
|
@ -28,8 +30,9 @@ var WireSet = wire.NewSet(
|
|||
func ProvideDockerProvider(
|
||||
config *DockerConfig,
|
||||
dockerClientFactory *DockerClientFactory,
|
||||
eventReporter *events.Reporter,
|
||||
) *DockerProvider {
|
||||
return NewDockerProvider(config, dockerClientFactory)
|
||||
return NewDockerProvider(config, dockerClientFactory, eventReporter)
|
||||
}
|
||||
|
||||
func ProvideFactory(dockerProvider *DockerProvider) Factory {
|
||||
|
|
|
@ -41,7 +41,8 @@ const (
|
|||
)
|
||||
|
||||
func GetGitspaceStateFromInstance(
|
||||
instanceState GitspaceInstanceStateType) (GitspaceStateType, error) {
|
||||
instanceState GitspaceInstanceStateType,
|
||||
) (GitspaceStateType, error) {
|
||||
switch instanceState {
|
||||
case GitspaceInstanceStateRunning:
|
||||
return GitspaceStateRunning, nil
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package enum
|
||||
|
||||
type InfraEvent string
|
||||
|
||||
func (InfraEvent) Enum() []interface{} {
|
||||
return toInterfaceSlice(infraEvents)
|
||||
}
|
||||
|
||||
var infraEvents = []InfraEvent{
|
||||
InfraEventProvision, InfraEventStop, InfraEventDeprovision,
|
||||
}
|
||||
|
||||
const (
|
||||
InfraEventProvision InfraEvent = "provision"
|
||||
InfraEventStop InfraEvent = "stop"
|
||||
InfraEventDeprovision InfraEvent = "deprovision"
|
||||
)
|
|
@ -15,7 +15,7 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"github.com/harness/gitness/infraprovider/enum"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
type InfraProviderConfig struct {
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package infraprovider
|
||||
package types
|
||||
|
||||
import "github.com/harness/gitness/infraprovider/enum"
|
||||
import "github.com/harness/gitness/types/enum"
|
||||
|
||||
type ParameterSchema struct {
|
||||
type InfraProviderParameterSchema struct {
|
||||
Name string
|
||||
Description string
|
||||
DefaultValue string
|
||||
|
@ -25,7 +25,7 @@ type ParameterSchema struct {
|
|||
Editable bool
|
||||
}
|
||||
|
||||
type Parameter struct {
|
||||
type InfraProviderParameter struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
@ -49,13 +49,15 @@ type Infrastructure struct {
|
|||
// ProviderType specifies the type of the infra provider.
|
||||
ProviderType enum.InfraProviderType
|
||||
// Parameters which are required by the provider to provision the infra.
|
||||
Parameters []Parameter
|
||||
Parameters []InfraProviderParameter
|
||||
// Status of the infra.
|
||||
Status enum.InfraStatus
|
||||
// Host through which the infra can be accessed for all purposes.
|
||||
Host string
|
||||
// Port on which the infra can be accessed to orchestrate containers.
|
||||
Port int
|
||||
// Host through which the infra can be accessed.
|
||||
Host string
|
||||
ProxyHost string
|
||||
// AgentPort on which the agent can be accessed to orchestrate containers.
|
||||
AgentPort int
|
||||
ProxyPort int
|
||||
// Storage is the name of the volume or disk created for the resource.
|
||||
Storage string
|
||||
// PortMappings contains the ports assigned for every requested port.
|
Loading…
Reference in New Issue