feat: [CDE-666]: Changes for suspend/resume flow (#3644)

* feat: [CDE-666]: fix lint
* feat: [CDE-666]: Changes for suspend/resume flow
This commit is contained in:
Vikyath Harekal 2025-04-08 13:32:36 +00:00 committed by Harness
parent 4e9ce9d81a
commit c0e68605f4
8 changed files with 95 additions and 8 deletions

View File

@ -169,6 +169,25 @@ func (i InfraProvisioner) GetInfraFromStoredInfo(
return &infra, nil
}
func (i InfraProvisioner) GetStoppedInfraFromStoredInfo(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
) (*types.Infrastructure, error) {
infraProvisioned, err := i.infraProvisionedStore.FindStoppedInfraForGitspaceConfigIdentifier(
ctx,
gitspaceConfig.Identifier,
)
if err != nil {
return nil, fmt.Errorf("failed to find infraProvisioned: %w", err)
}
var infra types.Infrastructure
err = json.Unmarshal([]byte(*infraProvisioned.ResponseMetadata), &infra)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal response metadata: %w", err)
}
return &infra, nil
}
// Methods to find infra provider resources.
func (i InfraProvisioner) getConfigFromResource(
ctx context.Context,

View File

@ -89,6 +89,7 @@ func (i InfraProvisioner) TriggerInfraEventWithOpts(
infra *types.Infrastructure,
opts InfraEventOpts,
) error {
logger := log.Logger.With().Logger()
infraProviderEntity, err := i.getConfigFromResource(ctx, gitspaceConfig.InfraProviderResource)
if err != nil {
return err
@ -106,11 +107,33 @@ func (i InfraProvisioner) TriggerInfraEventWithOpts(
switch eventType {
case enum.InfraEventProvision:
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew {
return i.provisionNewInfrastructure(ctx, infraProvider, infraProviderEntity.Type,
gitspaceConfig, opts.RequiredGitspacePorts)
var stoppedInfra *types.Infrastructure
stoppedInfra, err = i.GetStoppedInfraFromStoredInfo(ctx, gitspaceConfig)
if err != nil {
logger.Info().
Str("error", err.Error()).
Msgf(
"could not find stopped infra provisioned entity for instance %s",
gitspaceConfig.Identifier,
)
}
return i.provisionExistingInfrastructure(ctx, infraProvider, gitspaceConfig, opts.RequiredGitspacePorts)
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew {
return i.provisionNewInfrastructure(
ctx,
infraProvider,
infraProviderEntity.Type,
gitspaceConfig,
opts.RequiredGitspacePorts,
stoppedInfra,
)
}
return i.provisionExistingInfrastructure(
ctx,
infraProvider,
gitspaceConfig,
opts.RequiredGitspacePorts,
stoppedInfra,
)
case enum.InfraEventDeprovision:
if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew {
@ -142,6 +165,7 @@ func (i InfraProvisioner) provisionNewInfrastructure(
infraProviderType enum.InfraProviderType,
gitspaceConfig types.GitspaceConfig,
requiredGitspacePorts []types.GitspacePort,
stoppedInfra *types.Infrastructure,
) error {
// Logic for new provisioning...
infraProvisionedLatest, _ := i.infraProvisionedStore.FindLatestByGitspaceInstanceID(
@ -181,11 +205,13 @@ func (i InfraProvisioner) provisionNewInfrastructure(
SpacePath: gitspaceConfig.SpacePath,
GitspaceConfigIdentifier: gitspaceConfig.Identifier,
GitspaceInstanceIdentifier: gitspaceConfig.GitspaceInstance.Identifier,
GitspaceInstanceID: gitspaceConfig.GitspaceInstance.ID,
ProviderType: infraProviderType,
InputParameters: allParams,
ConfigMetadata: configMetadata,
}
if stoppedInfra != nil {
infrastructure.InstanceInfo = stoppedInfra.InstanceInfo
}
responseMetadata, err := json.Marshal(infrastructure)
if err != nil {
return fmt.Errorf("unable to marshal infra object %+v: %w", responseMetadata, err)
@ -222,6 +248,7 @@ func (i InfraProvisioner) provisionNewInfrastructure(
requiredGitspacePorts,
allParams,
configMetadata,
infrastructure,
)
if err != nil {
infraProvisioned.InfraStatus = enum.InfraStatusUnknown
@ -246,6 +273,7 @@ func (i InfraProvisioner) provisionExistingInfrastructure(
infraProvider infraprovider.InfraProvider,
gitspaceConfig types.GitspaceConfig,
requiredGitspacePorts []types.GitspacePort,
stoppedInfra *types.Infrastructure,
) error {
allParams, configMetadata, err := i.getAllParamsFromDB(ctx, gitspaceConfig.InfraProviderResource, infraProvider)
if err != nil {
@ -268,6 +296,7 @@ func (i InfraProvisioner) provisionExistingInfrastructure(
requiredGitspacePorts,
allParams,
configMetadata,
*stoppedInfra,
)
if err != nil {
return fmt.Errorf(

View File

@ -1326,6 +1326,10 @@ type (
spaceID int64,
gitspaceInstanceIdentifier string,
) (*types.InfraProvisioned, error)
FindStoppedInfraForGitspaceConfigIdentifier(
ctc context.Context,
gitspaceConfigIdentifier string,
) (*types.InfraProvisioned, error)
Create(ctx context.Context, infraProvisioned *types.InfraProvisioned) error
Delete(ctx context.Context, id int64) error
Update(ctx context.Context, infraProvisioned *types.InfraProvisioned) error

View File

@ -206,6 +206,40 @@ func (i infraProvisionedStore) FindLatestByGitspaceInstanceIdentifier(
return entity.toDTO(), nil
}
func (i infraProvisionedStore) FindStoppedInfraForGitspaceConfigIdentifier(
ctx context.Context,
gitspaceConfigIdentifier string,
) (*types.InfraProvisioned, error) {
gitsSubQuery := fmt.Sprintf(`
SELECT gits.gits_id
FROM %s gits
JOIN %s conf ON gits.gits_gitspace_config_id = conf.gconf_id
WHERE conf.gconf_uid = '%s' AND gits.gits_state = 'starting'
LIMIT 1`,
gitspaceInstanceTable, gitspaceConfigsTable, gitspaceConfigIdentifier)
// Build the main query
stmt := database.Builder.
Select(infraProvisionedSelectColumns).
From(infraProvisionedTable).
Where("iprov_infra_status = ?", enum.InfraStatusStopped).
Join(fmt.Sprintf("(%s) AS gits ON iprov_gitspace_id = gits.gits_id", gitsSubQuery))
sql, args, err := stmt.ToSql()
if err != nil {
return nil, errors.Wrap(err, "Failed to convert squirrel builder to sql")
}
entity := new(infraProvisioned)
db := dbtx.GetAccessor(ctx, i.db)
if err := db.GetContext(ctx, entity, sql, args...); err != nil {
return nil, database.ProcessSQLErrorf(
ctx, err, "Failed to find last stopped infraprovisioned for config %s", gitspaceConfigIdentifier)
}
return entity.toDTO(), nil
}
func (i infraProvisionedStore) Create(ctx context.Context, infraProvisioned *types.InfraProvisioned) error {
stmt := database.Builder.
Insert(infraProvisionedTable).

View File

@ -61,6 +61,7 @@ func (d DockerProvider) Provision(
requiredGitspacePorts []types.GitspacePort,
inputParameters []types.InfraProviderParameter,
_ map[string]any,
_ types.Infrastructure,
) error {
dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, types.Infrastructure{
ProviderType: enum.InfraProviderTypeDocker,

View File

@ -34,6 +34,7 @@ type InfraProvider interface {
requiredGitspacePorts []types.GitspacePort,
inputParameters []types.InfraProviderParameter,
configMetadata map[string]any,
infrastructure types.Infrastructure,
) error
// Find finds infrastructure provisioned against a gitspace.

View File

@ -37,6 +37,7 @@ const (
GitspaceInstanceStateUninitialized GitspaceInstanceStateType = "uninitialized"
GitspaceInstanceStateUnknown GitspaceInstanceStateType = "unknown"
GitspaceInstanceStateError GitspaceInstanceStateType = "error"
GitspaceInstanceStateStopped GitspaceInstanceStateType = "stopped"
GitspaceInstanceStateDeleted GitspaceInstanceStateType = "deleted"
GitspaceInstanceStateCleaned GitspaceInstanceStateType = "cleaned"

View File

@ -116,7 +116,7 @@ func (g *GitspaceInstance) GetGitspaceState() (enum.GitspaceStateType, error) {
switch instanceState {
case enum.GitspaceInstanceStateRunning:
return enum.GitspaceStateRunning, nil
case enum.GitspaceInstanceStateDeleted:
case enum.GitspaceInstanceStateStopped, enum.GitspaceInstanceStateDeleted, enum.GitspaceInstanceStateCleaned:
return enum.GitspaceStateStopped, nil
case emptyGitspaceInstanceState, enum.GitspaceInstanceStateUninitialized:
return enum.GitspaceStateUninitialized, nil
@ -128,8 +128,6 @@ func (g *GitspaceInstance) GetGitspaceState() (enum.GitspaceStateType, error) {
case enum.GitspaceInstanceStateStopping,
enum.GitSpaceInstanceStateCleaning:
return enum.GitspaceStateStopping, nil
case enum.GitspaceInstanceStateCleaned:
return enum.GitspaceStateStopped, nil
default:
return enum.GitspaceStateError, fmt.Errorf("unsupported gitspace instance state %s", string(instanceState))
}