Skip to content

Commit

Permalink
feat: [CDE-94]: Adding events for gitspace transitions. (harness#2195)
Browse files Browse the repository at this point in the history
* feat: [CDE-94]: Fixing gitspace url.
* feat: [CDE-94]: Linting
* feat: [CDE-94]: Adding events for gitspace transitions.
  • Loading branch information
dhruv-harness authored and Harness committed Jul 10, 2024
1 parent 61f1bc5 commit e712903
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 8 deletions.
3 changes: 2 additions & 1 deletion app/api/controller/gitspace/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ func (c *Controller) sanitizeActionInput(in *ActionInput) error {
func (c *Controller) emitGitspaceConfigEvent(
ctx context.Context,
config *types.GitspaceConfig,
eventType enum.GitspaceEventType) {
eventType enum.GitspaceEventType,
) {
c.eventReporter.EmitGitspaceEvent(ctx, events.GitspaceEvent, &events.GitspaceEventPayload{
QueryKey: config.Identifier,
EntityID: config.ID,
Expand Down
8 changes: 8 additions & 0 deletions app/api/controller/gitspace/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ func eventsMessageMapping() map[enum.GitspaceEventType]string {
gitspaceConfigsMap[enum.GitspaceEventTypeGitspaceActionStopCompleted] = "Stopped Gitspace"
gitspaceConfigsMap[enum.GitspaceEventTypeGitspaceActionStopFailed] = "Stopping Gitspace Failed"

gitspaceConfigsMap[enum.GitspaceEventTypeFetchDevcontainerStart] = "Fetching devcontainer config..."
gitspaceConfigsMap[enum.GitspaceEventTypeFetchDevcontainerCompleted] = "Fetched devcontainer config"
gitspaceConfigsMap[enum.GitspaceEventTypeFetchDevcontainerFailed] = "Fetching devcontainer config failed"

gitspaceConfigsMap[enum.GitspaceEventTypeInfraProvisioningStart] = "Provisioning Infrastructure..."
gitspaceConfigsMap[enum.GitspaceEventTypeInfraProvisioningCompleted] = "Provisioning Infrastructure Completed"
gitspaceConfigsMap[enum.GitspaceEventTypeInfraProvisioningFailed] = "Provisioning Infrastructure Failed"
Expand All @@ -97,6 +101,10 @@ func eventsMessageMapping() map[enum.GitspaceEventType]string {
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceCreationCompleted] = "Successfully setup the gitspace"
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceCreationFailed] = "Failed to setup the gitspace"

gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceDeletionStart] = "Removing the gitspace..."
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceDeletionCompleted] = "Successfully removed the gitspace"
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceDeletionFailed] = "Failed to remove the gitspace"

gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceStateReportRunning] = "Gitspace is running"
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceStateReportStopped] = "Gitspace is stopped"
gitspaceConfigsMap[enum.GitspaceEventTypeAgentGitspaceStateReportUnknown] = "Gitspace is in unknown state"
Expand Down
119 changes: 114 additions & 5 deletions app/gitspace/orchestrator/orchestrator_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"net/url"
"time"

events "github.com/harness/gitness/app/events/gitspace"
"github.com/harness/gitness/app/gitspace/infrastructure"
"github.com/harness/gitness/app/gitspace/orchestrator/container"
"github.com/harness/gitness/app/gitspace/scm"
Expand All @@ -35,6 +36,7 @@ type orchestrator struct {
infraProviderResourceStore store.InfraProviderResourceStore
infraProvisioner infrastructure.InfraProvisioner
containerOrchestrator container.Orchestrator
eventReporter *events.Reporter
}

var _ Orchestrator = (*orchestrator)(nil)
Expand All @@ -44,12 +46,14 @@ func NewOrchestrator(
infraProviderResourceStore store.InfraProviderResourceStore,
infraProvisioner infrastructure.InfraProvisioner,
containerOrchestrator container.Orchestrator,
eventReporter *events.Reporter,
) Orchestrator {
return orchestrator{
scm: scm,
infraProviderResourceStore: infraProviderResourceStore,
infraProvisioner: infraProvisioner,
containerOrchestrator: containerOrchestrator,
eventReporter: eventReporter,
}
}

Expand All @@ -59,8 +63,13 @@ func (o orchestrator) StartGitspace(
) (*types.GitspaceInstance, error) {
gitspaceInstance := gitspaceConfig.GitspaceInstance
gitspaceInstance.State = enum.GitspaceInstanceStateError

o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeFetchDevcontainerStart)

devcontainerConfig, err := o.scm.DevcontainerConfig(ctx, gitspaceConfig)
if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeFetchDevcontainerFailed)

log.Warn().Err(err).Msg("devcontainerConfig fetch failed.")
}

Expand All @@ -69,26 +78,49 @@ func (o orchestrator) StartGitspace(
devcontainerConfig = &types.DevcontainerConfig{}
}

o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeFetchDevcontainerCompleted)

infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
if err != nil {
return gitspaceInstance, fmt.Errorf("cannot get the infraProviderResource for ID %d: %w",
gitspaceConfig.InfraProviderResourceID, err)
}

o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningStart)

infra, err := o.infraProvisioner.Provision(ctx, infraProviderResource, gitspaceConfig)
if err != nil {
return gitspaceInstance, fmt.Errorf("cannot provision infrastructure for ID %d: %w",
gitspaceConfig.InfraProviderResourceID, err)
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.GitspaceEventTypeAgentConnectStart)

err = o.containerOrchestrator.Status(ctx, infra)
gitspaceInstance.State = enum.GitspaceInstanceStateError
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.StartGitspace(ctx, gitspaceConfig, devcontainerConfig, infra)
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)

repoName, err := o.scm.RepositoryName(ctx, gitspaceConfig)
if err != nil {
log.Warn().Err(err).Msg("failed to fetch repository name.")
Expand All @@ -99,16 +131,16 @@ func (o orchestrator) StartGitspace(
var ideURL url.URL

if infra.Host == "" {
// TODO: This fix does not cover all use-cases. Ideally, we need to read the host name on which this docker is
// running and set it as the infra.Host. Remove once that change is done.
// TODO: This fix does not cover all use-cases. Ideally, we need to read the host name
// on which this docker is running and set it as the infra.Host. Remove once that change is done.
infra.Host = "localhost"
}

if gitspaceConfig.IDE == enum.IDETypeVSCodeWeb {
ideURL = url.URL{
Scheme: "http",
Host: infra.Host + ":" + port,
RawQuery: "folder=/" + startResponse.WorkingDirectory + "/" + repoName,
RawQuery: "folder=" + startResponse.WorkingDirectory + "/" + repoName,
}
} else if gitspaceConfig.IDE == enum.IDETypeVSCode {
// TODO: the following user ID is hard coded and should be changed.
Expand All @@ -131,6 +163,8 @@ func (o orchestrator) StartGitspace(
gitspaceInstance.LastUsed = time.Now().UnixMilli()
gitspaceInstance.State = enum.GitspaceInstanceStateRunning

o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeGitspaceActionStartCompleted)

return gitspaceInstance, nil
}

Expand All @@ -140,6 +174,7 @@ func (o orchestrator) StopGitspace(
) (*types.GitspaceInstance, error) {
gitspaceInstance := gitspaceConfig.GitspaceInstance
gitspaceInstance.State = enum.GitspaceInstanceStateError

infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
if err != nil {
return nil, fmt.Errorf(
Expand All @@ -151,17 +186,44 @@ func (o orchestrator) StopGitspace(
return gitspaceInstance, 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 gitspaceInstance, fmt.Errorf("error stopping the Gitspace container: %w", err)
}

o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceDeletionCompleted)

o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraUnprovisioningStart)

_, err = o.infraProvisioner.Stop(ctx, infraProviderResource, gitspaceConfig)
if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraUnprovisioningFailed)

return gitspaceInstance, 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 gitspaceInstance, err
}

Expand All @@ -172,28 +234,75 @@ func (o orchestrator) DeleteGitspace(
gitspaceInstance := gitspaceConfig.GitspaceInstance
currentState := gitspaceInstance.State
gitspaceInstance.State = enum.GitspaceInstanceStateError

infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
if err != nil {
return nil, fmt.Errorf(
"cannot get the infraProviderResource with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
}

if currentState == enum.GitspaceInstanceStateRunning ||
currentState == enum.GitspaceInstanceStateUnknown {
infra, err := o.infraProvisioner.Find(ctx, infraProviderResource, gitspaceConfig)
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.infraProvisioner.Unprovision(ctx, infraProviderResource, gitspaceConfig)
if err != nil {
o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraUnprovisioningFailed)

return nil, 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 gitspaceInstance, nil
}

func (o orchestrator) emitGitspaceEvent(
ctx context.Context,
config *types.GitspaceConfig,
eventType enum.GitspaceEventType,
) {
o.eventReporter.EmitGitspaceEvent(
ctx,
events.GitspaceEvent,
&events.GitspaceEventPayload{
QueryKey: config.Identifier,
EntityID: config.GitspaceInstance.ID,
EntityType: enum.GitspaceEntityTypeGitspaceInstance,
EventType: eventType,
Created: time.Now().UnixMilli(),
})
}
4 changes: 3 additions & 1 deletion app/gitspace/orchestrator/wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package orchestrator

import (
events "github.com/harness/gitness/app/events/gitspace"
"github.com/harness/gitness/app/gitspace/infrastructure"
"github.com/harness/gitness/app/gitspace/orchestrator/container"
"github.com/harness/gitness/app/gitspace/scm"
Expand All @@ -33,6 +34,7 @@ func ProvideOrchestrator(
infraProviderResourceStore store.InfraProviderResourceStore,
infraProvisioner infrastructure.InfraProvisioner,
containerOrchestrator container.Orchestrator,
reporter *events.Reporter,
) Orchestrator {
return NewOrchestrator(scm, infraProviderResourceStore, infraProvisioner, containerOrchestrator)
return NewOrchestrator(scm, infraProviderResourceStore, infraProvisioner, containerOrchestrator, reporter)
}
4 changes: 4 additions & 0 deletions app/gitspace/scm/scm.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,21 @@ func (s scm) DevcontainerConfig(
gitspaceConfig *types.GitspaceConfig,
) (*types.DevcontainerConfig, error) {
gitWorkingDirectory := "/tmp/git/"

cloneDir := gitWorkingDirectory + uuid.New().String()

err := os.MkdirAll(cloneDir, os.ModePerm)
if err != nil {
return nil, fmt.Errorf("error creating directory %s: %w", cloneDir, err)
}

defer func() {
err = os.RemoveAll(cloneDir)
if err != nil {
log.Ctx(ctx).Warn().Err(err).Msg("Unable to remove working directory")
}
}()

filePath := ".devcontainer/devcontainer.json"
err = validateArgs(gitspaceConfig)
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions app/store/database/gitspace_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ func (g gitspaceEventStore) List(

queryStmt = g.setQueryFilter(queryStmt, filter)

queryStmt = g.setSortFilter(queryStmt, filter)

queryStmt = g.setPaginationFilter(queryStmt, filter)

sql, args, err := queryStmt.ToSql()
Expand Down Expand Up @@ -171,6 +173,13 @@ func (g gitspaceEventStore) setQueryFilter(
return stmt
}

func (g gitspaceEventStore) setSortFilter(
stmt squirrel.SelectBuilder,
_ *types.GitspaceEventFilter,
) squirrel.SelectBuilder {
return stmt.OrderBy("geven_created ASC")
}

func (g gitspaceEventStore) setPaginationFilter(
stmt squirrel.SelectBuilder,
filter *types.GitspaceEventFilter,
Expand Down
2 changes: 1 addition & 1 deletion cmd/gitness/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit e712903

Please sign in to comment.