feat: [CDE-174]: Adding logic to restart gitspaces. (#2239)

* feat: [CDE-174]: Linting
* feat: [CDE-174]: Updating the entrypoint to trap SIGTERM.
* feat: [CDE-174]: Adding logic to restart gitspaces.
unified-ui
Dhruv Dhruv 2024-07-17 09:28:29 +00:00 committed by Harness
parent a00265b22b
commit 1af6be80e9
5 changed files with 315 additions and 171 deletions

View File

@ -89,9 +89,13 @@ func eventsMessageMapping() map[enum.GitspaceEventType]string {
gitspaceConfigsMap[enum.GitspaceEventTypeInfraProvisioningCompleted] = "Provisioning Infrastructure Completed" gitspaceConfigsMap[enum.GitspaceEventTypeInfraProvisioningCompleted] = "Provisioning Infrastructure Completed"
gitspaceConfigsMap[enum.GitspaceEventTypeInfraProvisioningFailed] = "Provisioning Infrastructure Failed" gitspaceConfigsMap[enum.GitspaceEventTypeInfraProvisioningFailed] = "Provisioning Infrastructure Failed"
gitspaceConfigsMap[enum.GitspaceEventTypeInfraUnprovisioningStart] = "Unprovisioning Infrastructure..." gitspaceConfigsMap[enum.GitspaceEventTypeInfraStopStart] = "Stopping Infrastructure..."
gitspaceConfigsMap[enum.GitspaceEventTypeInfraUnprovisioningCompleted] = "Unprovisioning Infrastructure Completed" gitspaceConfigsMap[enum.GitspaceEventTypeInfraStopCompleted] = "Stopping Infrastructure Completed"
gitspaceConfigsMap[enum.GitspaceEventTypeInfraUnprovisioningFailed] = "Unprovisioning Infrastructure Failed" gitspaceConfigsMap[enum.GitspaceEventTypeInfraStopFailed] = "Stopping Infrastructure Failed"
gitspaceConfigsMap[enum.GitspaceEventTypeInfraDeprovisioningStart] = "Deprovisioning Infrastructure..."
gitspaceConfigsMap[enum.GitspaceEventTypeInfraDeprovisioningCompleted] = "Deprovisioning Infrastructure Completed"
gitspaceConfigsMap[enum.GitspaceEventTypeInfraDeprovisioningFailed] = "Deprovisioning Infrastructure Failed"
gitspaceConfigsMap[enum.GitspaceEventTypeAgentConnectStart] = "Connecting to the gitspace agent..." gitspaceConfigsMap[enum.GitspaceEventTypeAgentConnectStart] = "Connecting to the gitspace agent..."
gitspaceConfigsMap[enum.GitspaceEventTypeAgentConnectCompleted] = "Connected to the gitspace agent" gitspaceConfigsMap[enum.GitspaceEventTypeAgentConnectCompleted] = "Connected to the gitspace agent"
@ -101,6 +105,10 @@ func eventsMessageMapping() map[enum.GitspaceEventType]string {
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceCreationCompleted] = "Successfully setup the gitspace" gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceCreationCompleted] = "Successfully setup the gitspace"
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceCreationFailed] = "Failed to setup the gitspace" gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceCreationFailed] = "Failed to setup the gitspace"
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceStopStart] = "Stopping the gitspace..."
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceStopCompleted] = "Successfully stopped the gitspace"
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceStopFailed] = "Failed to stop the gitspace"
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceDeletionStart] = "Removing the gitspace..." gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceDeletionStart] = "Removing the gitspace..."
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceDeletionCompleted] = "Successfully removed the gitspace" gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceDeletionCompleted] = "Successfully removed the gitspace"
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceDeletionFailed] = "Failed to remove the gitspace" gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceDeletionFailed] = "Failed to remove the gitspace"

View File

@ -22,9 +22,10 @@ import (
) )
type Orchestrator interface { type Orchestrator interface {
// StartGitspace starts the gitspace container using the specified image or default image, clones the code, // CreateAndStartGitspace starts an exited container and starts a new container if the container is removed.
// runs SSH server and installs the IDE inside the container. It returns a map of the ports used by the Gitspace. // If the container is newly created, it clones the code, sets up the IDE and executes the postCreateCommand.
StartGitspace( // It returns the container ID, name and ports used.
CreateAndStartGitspace(
ctx context.Context, ctx context.Context,
gitspaceConfig *types.GitspaceConfig, gitspaceConfig *types.GitspaceConfig,
devcontainerConfig *types.DevcontainerConfig, devcontainerConfig *types.DevcontainerConfig,
@ -32,9 +33,12 @@ type Orchestrator interface {
repoName string, repoName string,
) (*StartResponse, error) ) (*StartResponse, error)
// StopGitspace stops and removes the gitspace container. // StopGitspace stops the gitspace container.
StopGitspace(ctx context.Context, gitspaceConfig *types.GitspaceConfig, infra *infraprovider.Infrastructure) error StopGitspace(ctx context.Context, config *types.GitspaceConfig, infra *infraprovider.Infrastructure) error
// Status checks if the infra is reachable and ready to begin container creation. // StopAndRemoveGitspace stops and removes the gitspace container.
StopAndRemoveGitspace(ctx context.Context, config *types.GitspaceConfig, infra *infraprovider.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 *infraprovider.Infrastructure) error
} }

View File

@ -28,7 +28,6 @@ import (
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
@ -42,6 +41,7 @@ const (
catchAllPort = "0" catchAllPort = "0"
containerStateRunning = "running" containerStateRunning = "running"
containerStateRemoved = "removed" containerStateRemoved = "removed"
containerStateStopped = "exited"
templateCloneGit = "clone_git.sh" templateCloneGit = "clone_git.sh"
templateSetupSSHServer = "setup_ssh_server.sh" templateSetupSSHServer = "setup_ssh_server.sh"
) )
@ -74,12 +74,11 @@ func NewEmbeddedDockerOrchestrator(
} }
} }
// StartGitspace checks if the Gitspace is already running by checking its entry in a map. If is it running, // CreateAndStartGitspace starts an exited container and starts a new container if the container is removed.
// it returns, else, it creates a new Gitspace container by using the provided image. If the provided image is // If the container is newly created, it clones the code, sets up the IDE and executes the postCreateCommand.
// nil, it uses a default image read from Gitness config. Post creation it runs the postCreate command and clones // It returns the container ID, name and ports used.
// the code inside the container. It uses the IDE service to setup the relevant IDE and install the SSH server // It returns an error if the container is not running, exited or removed.
// inside the container. func (e *EmbeddedDockerOrchestrator) CreateAndStartGitspace(
func (e *EmbeddedDockerOrchestrator) StartGitspace(
ctx context.Context, ctx context.Context,
gitspaceConfig *types.GitspaceConfig, gitspaceConfig *types.GitspaceConfig,
devcontainerConfig *types.DevcontainerConfig, devcontainerConfig *types.DevcontainerConfig,
@ -108,32 +107,17 @@ func (e *EmbeddedDockerOrchestrator) StartGitspace(
return nil, err return nil, err
} }
var usedPorts map[enum.IDEType]string ideService, err := e.getIDEService(gitspaceConfig)
var containerID string if err != nil {
return nil, err
}
switch state { switch state {
case containerStateRunning: case containerStateRunning:
log.Debug().Msg("gitspace is already running") log.Debug().Msg("gitspace is already running")
ideService, startErr := e.getIDEService(gitspaceConfig) case containerStateStopped:
if startErr != nil { log.Debug().Msg("gitspace is stopped, starting it")
return nil, startErr
}
id, ports, startErr := e.getContainerInfo(ctx, containerName, dockerClient, ideService)
if startErr != nil {
return nil, startErr
}
usedPorts = ports
containerID = id
case containerStateRemoved:
log.Debug().Msg("gitspace is not running, starting it...")
ideService, startErr := e.getIDEService(gitspaceConfig)
if startErr != nil {
return nil, startErr
}
logStreamInstance, loggerErr := e.statefulLogger.CreateLogStream(ctx, gitspaceConfig.ID) logStreamInstance, loggerErr := e.statefulLogger.CreateLogStream(ctx, gitspaceConfig.ID)
if loggerErr != nil { if loggerErr != nil {
@ -146,8 +130,33 @@ func (e *EmbeddedDockerOrchestrator) StartGitspace(
log.Warn().Err(loggerErr).Msgf("failed to flush log stream for gitspace ID %d", gitspaceConfig.ID) log.Warn().Err(loggerErr).Msgf("failed to flush log stream for gitspace ID %d", gitspaceConfig.ID)
} }
}() }()
startErr := e.startContainer(ctx, dockerClient, containerName, logStreamInstance)
if startErr != nil {
return nil, startErr
}
// TODO: Add gitspace status reporting.
log.Debug().Msg("started gitspace")
case containerStateRemoved:
log.Debug().Msg("gitspace is removed, creating it...")
logStreamInstance, loggerErr := e.statefulLogger.CreateLogStream(ctx, gitspaceConfig.ID)
if loggerErr != nil {
return nil, fmt.Errorf("error getting log stream for gitspace ID %d: %w", gitspaceConfig.ID, loggerErr)
}
defer func() {
loggerErr = logStreamInstance.Flush()
if loggerErr != nil {
log.Warn().Err(loggerErr).Msgf("failed to flush log stream for gitspace ID %d", gitspaceConfig.ID)
}
}()
workingDirectory := "/" + repoName workingDirectory := "/" + repoName
startErr = e.startGitspace(
startErr := e.startGitspace(
ctx, ctx,
gitspaceConfig, gitspaceConfig,
devcontainerConfig, devcontainerConfig,
@ -161,13 +170,6 @@ func (e *EmbeddedDockerOrchestrator) StartGitspace(
if startErr != nil { if startErr != nil {
return nil, fmt.Errorf("failed to start gitspace %s: %w", containerName, startErr) return nil, fmt.Errorf("failed to start gitspace %s: %w", containerName, startErr)
} }
id, ports, startErr := e.getContainerInfo(ctx, containerName, dockerClient, ideService)
if startErr != nil {
return nil, startErr
}
containerID = id
usedPorts = ports
// TODO: Add gitspace status reporting. // TODO: Add gitspace status reporting.
log.Debug().Msg("started gitspace") log.Debug().Msg("started gitspace")
@ -176,10 +178,15 @@ func (e *EmbeddedDockerOrchestrator) StartGitspace(
return nil, fmt.Errorf("gitspace %s is in a bad state: %s", containerName, state) return nil, fmt.Errorf("gitspace %s is in a bad state: %s", containerName, state)
} }
id, ports, startErr := e.getContainerInfo(ctx, containerName, dockerClient, ideService)
if startErr != nil {
return nil, startErr
}
return &StartResponse{ return &StartResponse{
ContainerID: containerID, ContainerID: id,
ContainerName: containerName, ContainerName: containerName,
PortsUsed: usedPorts, PortsUsed: ports,
}, nil }, nil
} }
@ -218,6 +225,11 @@ func (e *EmbeddedDockerOrchestrator) startGitspace(
return err return err
} }
err = e.startContainer(ctx, dockerClient, containerName, logStreamInstance)
if err != nil {
return err
}
var devcontainer = &Devcontainer{ var devcontainer = &Devcontainer{
ContainerName: containerName, ContainerName: containerName,
DockerClient: dockerClient, DockerClient: dockerClient,
@ -417,6 +429,38 @@ func (e *EmbeddedDockerOrchestrator) executePostCreateCommand(
return nil return nil
} }
func (e *EmbeddedDockerOrchestrator) startContainer(
ctx context.Context,
dockerClient *client.Client,
containerName string,
logStreamInstance *logutil.LogStreamInstance,
) error {
loggingErr := logStreamInstance.Write("Starting container: " + containerName)
if loggingErr != nil {
return fmt.Errorf("logging error: %w", loggingErr)
}
err := dockerClient.ContainerStart(ctx, containerName, dockerTypes.ContainerStartOptions{})
if err != nil {
loggingErr = logStreamInstance.Write("Error while creating container: " + err.Error())
err = fmt.Errorf("could not start container %s: %w", containerName, err)
if loggingErr != nil {
err = fmt.Errorf("original error: %w; logging error: %w", err, loggingErr)
}
return err
}
loggingErr = logStreamInstance.Write("Successfully started container")
if loggingErr != nil {
return fmt.Errorf("logging error: %w", loggingErr)
}
return nil
}
func (e *EmbeddedDockerOrchestrator) createContainer( func (e *EmbeddedDockerOrchestrator) createContainer(
ctx context.Context, ctx context.Context,
dockerClient *client.Client, dockerClient *client.Client,
@ -445,21 +489,16 @@ func (e *EmbeddedDockerOrchestrator) createContainer(
portBindings[natPort] = hostPortBindings portBindings[natPort] = hostPortBindings
} }
entryPoint := make(strslice.StrSlice, 0) entryPoint := []string{"/bin/bash", "-c", `trap "exit 0" 15; sleep infinity`}
entryPoint = append(entryPoint, "sleep")
commands := make(strslice.StrSlice, 0)
commands = append(commands, "infinity")
loggingErr := logStreamInstance.Write("Creating container: " + containerName) loggingErr := logStreamInstance.Write("Creating container: " + containerName)
if loggingErr != nil { if loggingErr != nil {
return fmt.Errorf("logging error: %w", loggingErr) return fmt.Errorf("logging error: %w", loggingErr)
} }
resp2, err := dockerClient.ContainerCreate(ctx, &container.Config{ _, err := dockerClient.ContainerCreate(ctx, &container.Config{
Image: imageName, Image: imageName,
Entrypoint: entryPoint, Entrypoint: entryPoint,
Cmd: commands,
ExposedPorts: exposedPorts, ExposedPorts: exposedPorts,
}, &container.HostConfig{ }, &container.HostConfig{
PortBindings: portBindings, PortBindings: portBindings,
@ -483,34 +522,6 @@ func (e *EmbeddedDockerOrchestrator) createContainer(
return err return err
} }
loggingErr = logStreamInstance.Write("Successfully created container")
if loggingErr != nil {
return fmt.Errorf("logging error: %w", loggingErr)
}
loggingErr = logStreamInstance.Write("Starting container: " + containerName)
if loggingErr != nil {
return fmt.Errorf("logging error: %w", loggingErr)
}
err = dockerClient.ContainerStart(ctx, resp2.ID, dockerTypes.ContainerStartOptions{})
if err != nil {
loggingErr = logStreamInstance.Write("Error while creating container: " + err.Error())
err = fmt.Errorf("could not start container %s: %w", containerName, err)
if loggingErr != nil {
err = fmt.Errorf("original error: %w; logging error: %w", err, loggingErr)
}
return err
}
loggingErr = logStreamInstance.Write("Successfully started container")
if loggingErr != nil {
return fmt.Errorf("logging error: %w", loggingErr)
}
return nil return nil
} }
@ -574,8 +585,7 @@ func (e *EmbeddedDockerOrchestrator) pullImage(
return nil return nil
} }
// StopGitspace checks if the Gitspace container is running. If yes, it stops and removes the container. // StopGitspace stops a container. If it is removed, it returns an error.
// Else it returns.
func (e EmbeddedDockerOrchestrator) StopGitspace( func (e EmbeddedDockerOrchestrator) StopGitspace(
ctx context.Context, ctx context.Context,
gitspaceConfig *types.GitspaceConfig, gitspaceConfig *types.GitspaceConfig,
@ -604,6 +614,10 @@ func (e EmbeddedDockerOrchestrator) StopGitspace(
} }
if state == containerStateRemoved { if state == containerStateRemoved {
return fmt.Errorf("gitspace %s is removed", containerName)
}
if state == containerStateStopped {
log.Debug().Msg("gitspace is already stopped") log.Debug().Msg("gitspace is already stopped")
return nil return nil
} }
@ -622,7 +636,7 @@ func (e EmbeddedDockerOrchestrator) StopGitspace(
} }
}() }()
err = e.stopGitspace(ctx, containerName, dockerClient, logStreamInstance) err = e.stopContainer(ctx, containerName, dockerClient, logStreamInstance)
if err != nil { if err != nil {
return fmt.Errorf("failed to stop gitspace %s: %w", containerName, err) return fmt.Errorf("failed to stop gitspace %s: %w", containerName, err)
} }
@ -632,7 +646,7 @@ func (e EmbeddedDockerOrchestrator) StopGitspace(
return nil return nil
} }
func (e EmbeddedDockerOrchestrator) stopGitspace( func (e EmbeddedDockerOrchestrator) stopContainer(
ctx context.Context, ctx context.Context,
containerName string, containerName string,
dockerClient *client.Client, dockerClient *client.Client,
@ -661,29 +675,6 @@ func (e EmbeddedDockerOrchestrator) stopGitspace(
return fmt.Errorf("logging error: %w", loggingErr) return fmt.Errorf("logging error: %w", loggingErr)
} }
loggingErr = logStreamInstance.Write("Removing container: " + containerName)
if loggingErr != nil {
return fmt.Errorf("logging error: %w", loggingErr)
}
err = dockerClient.ContainerRemove(ctx, containerName, dockerTypes.ContainerRemoveOptions{Force: true})
if err != nil {
loggingErr = logStreamInstance.Write("Error while removing container: " + err.Error())
err = fmt.Errorf("could not remove container %s: %w", containerName, err)
if loggingErr != nil {
err = fmt.Errorf("original error: %w; logging error: %w", err, loggingErr)
}
return err
}
loggingErr = logStreamInstance.Write("Successfully removed container")
if loggingErr != nil {
return fmt.Errorf("logging error: %w", loggingErr)
}
return nil return nil
} }
@ -715,3 +706,104 @@ func (e *EmbeddedDockerOrchestrator) containerState(
return containers[0].State, nil return containers[0].State, nil
} }
// StopAndRemoveGitspace stops the container if not stopped and removes it.
// If the container is already removed, it returns.
func (e *EmbeddedDockerOrchestrator) StopAndRemoveGitspace(
ctx context.Context,
gitspaceConfig *types.GitspaceConfig,
infra *infraprovider.Infrastructure,
) error {
containerName := getGitspaceContainerName(gitspaceConfig)
log := log.Ctx(ctx).With().Str(loggingKey, containerName).Logger()
dockerClient, err := e.dockerClientFactory.NewDockerClient(ctx, infra)
if err != nil {
return fmt.Errorf("error getting docker client from docker client factory: %w", err)
}
defer func() {
closingErr := dockerClient.Close()
if closingErr != nil {
log.Warn().Err(closingErr).Msg("failed to close docker client")
}
}()
log.Debug().Msg("checking current state of gitspace")
state, err := e.containerState(ctx, containerName, dockerClient)
if err != nil {
return err
}
if state == containerStateRemoved {
log.Debug().Msg("gitspace is already removed")
return nil
}
logStreamInstance, loggerErr := e.statefulLogger.CreateLogStream(ctx, gitspaceConfig.ID)
if loggerErr != nil {
return fmt.Errorf("error getting log stream for gitspace ID %d: %w", gitspaceConfig.ID, loggerErr)
}
defer func() {
loggerErr = logStreamInstance.Flush()
if loggerErr != nil {
log.Warn().Err(loggerErr).Msgf("failed to flush log stream for gitspace ID %d", gitspaceConfig.ID)
}
}()
if state != containerStateStopped {
log.Debug().Msg("stopping gitspace")
err = e.stopContainer(ctx, containerName, dockerClient, logStreamInstance)
if err != nil {
return fmt.Errorf("failed to stop gitspace %s: %w", containerName, err)
}
log.Debug().Msg("stopped gitspace")
}
log.Debug().Msg("removing gitspace")
err = e.removeContainer(ctx, containerName, dockerClient, logStreamInstance)
if err != nil {
return fmt.Errorf("failed to remove gitspace %s: %w", containerName, err)
}
log.Debug().Msg("removed gitspace")
return nil
}
func (e EmbeddedDockerOrchestrator) removeContainer(
ctx context.Context,
containerName string,
dockerClient *client.Client,
logStreamInstance *logutil.LogStreamInstance,
) error {
loggingErr := logStreamInstance.Write("Removing container: " + containerName)
if loggingErr != nil {
return fmt.Errorf("logging error: %w", loggingErr)
}
err := dockerClient.ContainerRemove(ctx, containerName, dockerTypes.ContainerRemoveOptions{Force: true})
if err != nil {
loggingErr = logStreamInstance.Write("Error while removing container: " + err.Error())
err = fmt.Errorf("could not remove container %s: %w", containerName, err)
if loggingErr != nil {
err = fmt.Errorf("original error: %w; logging error: %w", err, loggingErr)
}
return err
}
loggingErr = logStreamInstance.Write("Successfully removed container")
if loggingErr != nil {
return fmt.Errorf("logging error: %w", loggingErr)
}
return nil
}

View File

@ -26,6 +26,7 @@ import (
"github.com/harness/gitness/app/gitspace/orchestrator/container" "github.com/harness/gitness/app/gitspace/orchestrator/container"
"github.com/harness/gitness/app/gitspace/scm" "github.com/harness/gitness/app/gitspace/scm"
"github.com/harness/gitness/app/store" "github.com/harness/gitness/app/store"
"github.com/harness/gitness/infraprovider"
"github.com/harness/gitness/types" "github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum" "github.com/harness/gitness/types/enum"
@ -113,7 +114,8 @@ func (o orchestrator) StartGitspace(
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationStart) o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationStart)
startResponse, err := o.containerOrchestrator.StartGitspace(ctx, gitspaceConfig, devcontainerConfig, infra, repoName) startResponse, err := o.containerOrchestrator.CreateAndStartGitspace(
ctx, gitspaceConfig, devcontainerConfig, infra, repoName)
if err != nil { if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationFailed) o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationFailed)
@ -175,9 +177,67 @@ func (o orchestrator) StopGitspace(
return fmt.Errorf("cannot find the provisioned infra: %w", err) return fmt.Errorf("cannot find the provisioned infra: %w", err)
} }
err = o.stopGitspaceContainer(ctx, gitspaceConfig, infra)
if err != nil {
return err
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopStart)
_, err = o.infraProvisioner.Stop(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)
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraStopCompleted)
gitspaceInstance.State = enum.GitspaceInstanceStateDeleted
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeGitspaceActionStopCompleted)
return err
}
func (o orchestrator) stopGitspaceContainer(
ctx context.Context,
gitspaceConfig *types.GitspaceConfig,
infra *infraprovider.Infrastructure,
) error {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart) o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
err = o.containerOrchestrator.Status(ctx, infra) err := o.containerOrchestrator.Status(ctx, infra)
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.GitspaceEventTypeAgentGitspaceStopStart)
err = o.containerOrchestrator.StopGitspace(ctx, gitspaceConfig, infra)
if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceStopFailed)
return fmt.Errorf("error stopping the Gitspace container: %w", err)
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceStopCompleted)
return nil
}
func (o orchestrator) stopAndRemoveGitspaceContainer(
ctx context.Context,
gitspaceConfig *types.GitspaceConfig,
infra *infraprovider.Infrastructure,
) error {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
err := o.containerOrchestrator.Status(ctx, infra)
if err != nil { if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed) o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed)
@ -188,7 +248,7 @@ func (o orchestrator) StopGitspace(
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionStart) o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionStart)
err = o.containerOrchestrator.StopGitspace(ctx, gitspaceConfig, infra) err = o.containerOrchestrator.StopAndRemoveGitspace(ctx, gitspaceConfig, infra)
if err != nil { if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionFailed) o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionFailed)
@ -196,24 +256,7 @@ func (o orchestrator) StopGitspace(
} }
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionCompleted) o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionCompleted)
return nil
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraUnprovisioningStart)
_, err = o.infraProvisioner.Stop(ctx, infraProviderResource, gitspaceConfig)
if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraUnprovisioningFailed)
return fmt.Errorf(
"cannot stop provisioned infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraUnprovisioningCompleted)
gitspaceInstance.State = enum.GitspaceInstanceStateDeleted
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeGitspaceActionStopCompleted)
return err
} }
func (o orchestrator) DeleteGitspace( func (o orchestrator) DeleteGitspace(
@ -221,7 +264,6 @@ func (o orchestrator) DeleteGitspace(
gitspaceConfig *types.GitspaceConfig, gitspaceConfig *types.GitspaceConfig,
) (*types.GitspaceInstance, error) { ) (*types.GitspaceInstance, error) {
gitspaceInstance := gitspaceConfig.GitspaceInstance gitspaceInstance := gitspaceConfig.GitspaceInstance
currentState := gitspaceInstance.State
gitspaceInstance.State = enum.GitspaceInstanceStateError gitspaceInstance.State = enum.GitspaceInstanceStateError
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID) infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
@ -230,47 +272,27 @@ func (o orchestrator) DeleteGitspace(
"cannot get the infraProviderResource with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err) "cannot get the infraProviderResource with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
} }
if currentState == enum.GitspaceInstanceStateRunning || infra, err := o.infraProvisioner.Find(ctx, infraProviderResource, gitspaceConfig)
currentState == enum.GitspaceInstanceStateUnknown { if err != nil {
infra, err := o.infraProvisioner.Find(ctx, infraProviderResource, gitspaceConfig) return nil, fmt.Errorf("cannot find the provisioned infra: %w", err)
if err != nil {
return nil, fmt.Errorf("cannot find the provisioned infra: %w", err)
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectStart)
err = o.containerOrchestrator.Status(ctx, infra)
if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed)
return gitspaceConfig.GitspaceInstance, fmt.Errorf("couldn't call the agent health API: %w", err)
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectCompleted)
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionStart)
err = o.containerOrchestrator.StopGitspace(ctx, gitspaceConfig, infra)
if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionFailed)
return nil, fmt.Errorf("error stopping the Gitspace container: %w", err)
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionCompleted)
} }
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraUnprovisioningStart) err = o.stopAndRemoveGitspaceContainer(ctx, gitspaceConfig, infra)
if err != nil {
return nil, err
}
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningStart)
_, err = o.infraProvisioner.Deprovision(ctx, infraProviderResource, gitspaceConfig) _, err = o.infraProvisioner.Deprovision(ctx, infraProviderResource, gitspaceConfig)
if err != nil { if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraUnprovisioningFailed) o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningFailed)
return nil, fmt.Errorf( return nil, fmt.Errorf(
"cannot stop provisioned infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err) "cannot deprovision infrastructure with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
} }
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraUnprovisioningCompleted) o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraDeprovisioningCompleted)
gitspaceInstance.State = enum.GitspaceInstanceStateDeleted gitspaceInstance.State = enum.GitspaceInstanceStateDeleted

View File

@ -37,9 +37,13 @@ var gitspaceEventTypes = []GitspaceEventType{
GitspaceEventTypeInfraProvisioningCompleted, GitspaceEventTypeInfraProvisioningCompleted,
GitspaceEventTypeInfraProvisioningFailed, GitspaceEventTypeInfraProvisioningFailed,
GitspaceEventTypeInfraUnprovisioningStart, GitspaceEventTypeInfraStopStart,
GitspaceEventTypeInfraUnprovisioningCompleted, GitspaceEventTypeInfraStopCompleted,
GitspaceEventTypeInfraUnprovisioningFailed, GitspaceEventTypeInfraStopFailed,
GitspaceEventTypeInfraDeprovisioningStart,
GitspaceEventTypeInfraDeprovisioningCompleted,
GitspaceEventTypeInfraDeprovisioningFailed,
GitspaceEventTypeAgentConnectStart, GitspaceEventTypeAgentConnectStart,
GitspaceEventTypeAgentConnectCompleted, GitspaceEventTypeAgentConnectCompleted,
@ -49,6 +53,10 @@ var gitspaceEventTypes = []GitspaceEventType{
GitspaceEventTypeAgentGitspaceCreationCompleted, GitspaceEventTypeAgentGitspaceCreationCompleted,
GitspaceEventTypeAgentGitspaceCreationFailed, GitspaceEventTypeAgentGitspaceCreationFailed,
GitspaceEventTypeAgentGitspaceStopStart,
GitspaceEventTypeAgentGitspaceStopCompleted,
GitspaceEventTypeAgentGitspaceStopFailed,
GitspaceEventTypeAgentGitspaceDeletionStart, GitspaceEventTypeAgentGitspaceDeletionStart,
GitspaceEventTypeAgentGitspaceDeletionCompleted, GitspaceEventTypeAgentGitspaceDeletionCompleted,
GitspaceEventTypeAgentGitspaceDeletionFailed, GitspaceEventTypeAgentGitspaceDeletionFailed,
@ -80,10 +88,15 @@ const (
GitspaceEventTypeInfraProvisioningCompleted GitspaceEventType = "infra_provisioning_completed" GitspaceEventTypeInfraProvisioningCompleted GitspaceEventType = "infra_provisioning_completed"
GitspaceEventTypeInfraProvisioningFailed GitspaceEventType = "infra_provisioning_failed" GitspaceEventTypeInfraProvisioningFailed GitspaceEventType = "infra_provisioning_failed"
// Infra unprovisioning events. // Infra stop events.
GitspaceEventTypeInfraUnprovisioningStart GitspaceEventType = "infra_unprovisioning_start" GitspaceEventTypeInfraStopStart GitspaceEventType = "infra_stop_start"
GitspaceEventTypeInfraUnprovisioningCompleted GitspaceEventType = "infra_unprovisioning_completed" GitspaceEventTypeInfraStopCompleted GitspaceEventType = "infra_stop_completed"
GitspaceEventTypeInfraUnprovisioningFailed GitspaceEventType = "infra_unprovisioning_failed" GitspaceEventTypeInfraStopFailed GitspaceEventType = "infra_stop_failed"
// Infra deprovisioning events.
GitspaceEventTypeInfraDeprovisioningStart GitspaceEventType = "infra_deprovisioning_start"
GitspaceEventTypeInfraDeprovisioningCompleted GitspaceEventType = "infra_deprovisioning_completed"
GitspaceEventTypeInfraDeprovisioningFailed GitspaceEventType = "infra_deprovisioning_failed"
// Agent connection events. // Agent connection events.
GitspaceEventTypeAgentConnectStart GitspaceEventType = "agent_connect_start" GitspaceEventTypeAgentConnectStart GitspaceEventType = "agent_connect_start"
@ -95,6 +108,11 @@ const (
GitspaceEventTypeAgentGitspaceCreationCompleted GitspaceEventType = "agent_gitspace_creation_completed" GitspaceEventTypeAgentGitspaceCreationCompleted GitspaceEventType = "agent_gitspace_creation_completed"
GitspaceEventTypeAgentGitspaceCreationFailed GitspaceEventType = "agent_gitspace_creation_failed" GitspaceEventTypeAgentGitspaceCreationFailed GitspaceEventType = "agent_gitspace_creation_failed"
// Gitspace stop events.
GitspaceEventTypeAgentGitspaceStopStart GitspaceEventType = "agent_gitspace_stop_start"
GitspaceEventTypeAgentGitspaceStopCompleted GitspaceEventType = "agent_gitspace_stop_completed"
GitspaceEventTypeAgentGitspaceStopFailed GitspaceEventType = "agent_gitspace_stop_failed"
// Gitspace deletion events. // Gitspace deletion events.
GitspaceEventTypeAgentGitspaceDeletionStart GitspaceEventType = "agent_gitspace_deletion_start" GitspaceEventTypeAgentGitspaceDeletionStart GitspaceEventType = "agent_gitspace_deletion_start"
GitspaceEventTypeAgentGitspaceDeletionCompleted GitspaceEventType = "agent_gitspace_deletion_completed" GitspaceEventTypeAgentGitspaceDeletionCompleted GitspaceEventType = "agent_gitspace_deletion_completed"