feat: [CDE-573]: refactor to reduce number of abstractions and modules. (#3199)

* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
* feat: [CDE-573]: refactor to reduce number of abstractions and modules.
This commit is contained in:
Ansuman Satapathy 2024-12-26 05:11:54 +00:00 committed by Harness
parent 0a042b66e5
commit d89825d317
39 changed files with 462 additions and 732 deletions

View File

@ -1,26 +0,0 @@
// 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 common
import (
_ "embed"
)
//go:embed script/os_info.sh
var osDetectScript string
func GetOSInfoScript() (script string) {
return osDetectScript
}

View File

@ -1,209 +0,0 @@
// 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 common
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/orchestrator/template"
"github.com/harness/gitness/app/gitspace/types"
"github.com/harness/gitness/types/enum"
)
const templateSupportedOSDistribution = "supported_os_distribution.sh"
const templateVsCodeWebToolsInstallation = "install_tools_vs_code_web.sh"
const templateVsCodeToolsInstallation = "install_tools_vs_code.sh"
const templateSetEnv = "set_env.sh"
func ValidateSupportedOS(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger types.GitspaceLogger,
) error {
// TODO: Currently not supporting arch, freebsd and alpine.
// For alpine wee need to install multiple things from
// https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites
script, err := template.GenerateScriptFromTemplate(
templateSupportedOSDistribution, &template.SupportedOSDistributionPayload{
OSInfoScript: osDetectScript,
})
if err != nil {
return fmt.Errorf("failed to generate scipt to validate supported os distribution from template %s: %w",
templateSupportedOSDistribution, err)
}
gitspaceLogger.Info("Validate supported OSes...")
err = ExecuteCommandInHomeDirAndLog(ctx, exec, script, true, gitspaceLogger, false)
if err != nil {
return fmt.Errorf("error while detecting os distribution: %w", err)
}
return nil
}
func InstallTools(
ctx context.Context,
exec *devcontainer.Exec,
ideType enum.IDEType,
gitspaceLogger types.GitspaceLogger,
) error {
switch ideType {
case enum.IDETypeVSCodeWeb:
err := InstallToolsForVsCodeWeb(ctx, exec, gitspaceLogger)
if err != nil {
return err
}
return nil
case enum.IDETypeVSCode:
err := InstallToolsForVsCode(ctx, exec, gitspaceLogger)
if err != nil {
return err
}
return nil
case enum.IDETypeIntellij:
// not installing any tools for intellij
return nil
}
return nil
}
func InstallToolsForVsCodeWeb(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger types.GitspaceLogger,
) error {
script, err := template.GenerateScriptFromTemplate(
templateVsCodeWebToolsInstallation, &template.InstallToolsPayload{
OSInfoScript: osDetectScript,
})
if err != nil {
return fmt.Errorf(
"failed to generate scipt to install tools for vs code web from template %s: %w",
templateVsCodeWebToolsInstallation, err)
}
gitspaceLogger.Info("Installing tools for vs code web inside container")
gitspaceLogger.Info("Tools installation output...")
err = ExecuteCommandInHomeDirAndLog(ctx, exec, script, true, gitspaceLogger, false)
if err != nil {
return fmt.Errorf("failed to install tools for vs code web: %w", err)
}
gitspaceLogger.Info("Successfully installed tools for vs code web")
return nil
}
func InstallToolsForVsCode(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger types.GitspaceLogger,
) error {
script, err := template.GenerateScriptFromTemplate(
templateVsCodeToolsInstallation, &template.InstallToolsPayload{
OSInfoScript: osDetectScript,
})
if err != nil {
return fmt.Errorf(
"failed to generate scipt to install tools for vs code from template %s: %w",
templateVsCodeToolsInstallation, err)
}
gitspaceLogger.Info("Installing tools for vs code in container")
err = ExecuteCommandInHomeDirAndLog(ctx, exec, script, true, gitspaceLogger, false)
if err != nil {
return fmt.Errorf("failed to install tools for vs code: %w", err)
}
gitspaceLogger.Info("Successfully installed tools for vs code")
return nil
}
func SetEnv(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger types.GitspaceLogger,
environment []string,
) error {
script, err := template.GenerateScriptFromTemplate(
templateSetEnv, &template.SetEnvPayload{
EnvVariables: environment,
})
if err != nil {
return fmt.Errorf("failed to generate scipt to set env from template %s: %w",
templateSetEnv, err)
}
gitspaceLogger.Info("Setting env...")
err = ExecuteCommandInHomeDirAndLog(ctx, exec, script, true, gitspaceLogger, true)
if err != nil {
return fmt.Errorf("error while setting env vars: %w", err)
}
return nil
}
func ExecuteCommandInHomeDirAndLog(
ctx context.Context,
exec *devcontainer.Exec,
script string,
root bool,
gitspaceLogger types.GitspaceLogger,
verbose bool,
) error {
// Buffer upto a thousand messages
outputCh := make(chan []byte, 1000)
err := exec.ExecuteCmdInHomeDirectoryAsyncStream(ctx, script, root, false, outputCh)
if err != nil {
return err
}
// Use select to wait for the output and exit status
for {
select {
case output := <-outputCh:
done, chErr := handleOutputChannel(output, verbose, gitspaceLogger)
if done {
return chErr
}
case <-ctx.Done():
// Handle context cancellation or timeout
return ctx.Err()
}
}
}
func handleOutputChannel(output []byte, verbose bool, gitspaceLogger types.GitspaceLogger) (bool, error) {
// Handle the exit status first
if strings.HasPrefix(string(output), devcontainer.ChannelExitStatus) {
// Extract the exit code from the message
exitCodeStr := strings.TrimPrefix(string(output), devcontainer.ChannelExitStatus)
exitCode, err := strconv.Atoi(exitCodeStr)
if err != nil {
return true, fmt.Errorf("invalid exit status format: %w", err)
}
if exitCode != 0 {
gitspaceLogger.Info("Process Exited with status " + exitCodeStr)
return true, fmt.Errorf("command exited with non-zero status: %d", exitCode)
}
// If exit status is zero, just continue processing
return true, nil
}
// Handle regular command output
msg := string(output)
if len(output) > 0 {
// Log output if verbose or if it's an error
if verbose || strings.HasPrefix(msg, devcontainer.LoggerErrorPrefix) {
gitspaceLogger.Info(msg)
}
}
return false, nil
}

View File

@ -19,11 +19,9 @@ import (
"fmt"
"sync"
"github.com/harness/gitness/app/gitspace/orchestrator/common"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/orchestrator/git"
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
"github.com/harness/gitness/app/gitspace/orchestrator/user"
"github.com/harness/gitness/app/gitspace/orchestrator/utils"
"github.com/harness/gitness/app/gitspace/scm"
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
"github.com/harness/gitness/types/enum"
@ -35,7 +33,7 @@ func InstallTools(
gitspaceLogger gitspaceTypes.GitspaceLogger,
ideType enum.IDEType,
) error {
err := common.InstallTools(ctx, exec, ideType, gitspaceLogger)
err := utils.InstallTools(ctx, exec, ideType, gitspaceLogger)
if err != nil {
return logStreamWrapError(gitspaceLogger, "Error while installing tools inside container", err)
}
@ -47,7 +45,7 @@ func ValidateSupportedOS(
exec *devcontainer.Exec,
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
err := common.ValidateSupportedOS(ctx, exec, gitspaceLogger)
err := utils.ValidateSupportedOS(ctx, exec, gitspaceLogger)
if err != nil {
return logStreamWrapError(gitspaceLogger, "Error while detecting OS inside container", err)
}
@ -89,7 +87,7 @@ func ExecuteLifecycleCommands(
// Log command execution details.
gitspaceLogger.Info(fmt.Sprintf("%sExecuting %s command: %s", logPrefix, actionType, command))
exec.DefaultWorkingDir = codeRepoDir
err := common.ExecuteCommandInHomeDirAndLog(ctx, &exec, command, false, gitspaceLogger, true)
err := exec.ExecuteCommandInHomeDirAndLog(ctx, command, false, gitspaceLogger, true)
if err != nil {
// Log the error if there is any issue with executing the command.
_ = logStreamWrapError(gitspaceLogger, fmt.Sprintf("%sError while executing %s command: %s",
@ -114,10 +112,9 @@ func CloneCode(
exec *devcontainer.Exec,
defaultBaseImage string,
resolvedRepoDetails scm.ResolvedDetails,
gitService git.Service,
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
err := gitService.CloneCode(ctx, exec, resolvedRepoDetails, defaultBaseImage, gitspaceLogger)
err := utils.CloneCode(ctx, exec, resolvedRepoDetails, defaultBaseImage, gitspaceLogger)
if err != nil {
return logStreamWrapError(gitspaceLogger, "Error while cloning code inside container", err)
}
@ -127,10 +124,9 @@ func CloneCode(
func InstallGit(
ctx context.Context,
exec *devcontainer.Exec,
gitService git.Service,
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
err := gitService.Install(ctx, exec, gitspaceLogger)
err := utils.InstallGit(ctx, exec, gitspaceLogger)
if err != nil {
return logStreamWrapError(gitspaceLogger, "Error while installing git inside container", err)
}
@ -141,10 +137,9 @@ func SetupGitCredentials(
ctx context.Context,
exec *devcontainer.Exec,
resolvedRepoDetails scm.ResolvedDetails,
gitService git.Service,
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
err := gitService.SetupCredentials(ctx, exec, resolvedRepoDetails, gitspaceLogger)
err := utils.SetupGitCredentials(ctx, exec, resolvedRepoDetails, gitspaceLogger)
if err != nil {
return logStreamWrapError(
gitspaceLogger, "Error while setting up git credentials inside container", err)
@ -155,10 +150,9 @@ func SetupGitCredentials(
func ManageUser(
ctx context.Context,
exec *devcontainer.Exec,
userService user.Service,
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
err := userService.Manage(ctx, exec, gitspaceLogger)
err := utils.ManageUser(ctx, exec, gitspaceLogger)
if err != nil {
return logStreamWrapError(gitspaceLogger, "Error while creating user inside container", err)
}
@ -202,7 +196,7 @@ func SetEnv(
environment []string,
) error {
if len(environment) > 0 {
err := common.SetEnv(ctx, exec, gitspaceLogger, environment)
err := utils.SetEnv(ctx, exec, gitspaceLogger, environment)
if err != nil {
return logStreamWrapError(gitspaceLogger, "Error while installing tools inside container", err)
}

View File

@ -21,10 +21,8 @@ import (
"github.com/harness/gitness/app/gitspace/logutil"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/orchestrator/git"
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
"github.com/harness/gitness/app/gitspace/orchestrator/user"
"github.com/harness/gitness/app/gitspace/scm"
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
"github.com/harness/gitness/infraprovider"
@ -44,17 +42,22 @@ const (
type EmbeddedDockerOrchestrator struct {
dockerClientFactory *infraprovider.DockerClientFactory
statefulLogger *logutil.StatefulLogger
gitService git.Service
userService user.Service
runArgProvider runarg.Provider
}
// Step represents a single setup action.
type step struct {
Name string
Execute func(ctx context.Context, exec *devcontainer.Exec, gitspaceLogger gitspaceTypes.GitspaceLogger) error
StopOnFailure bool // Flag to control whether execution should stop on failure
}
// ExecuteSteps executes all registered steps in sequence, respecting stopOnFailure flag.
func (e *EmbeddedDockerOrchestrator) ExecuteSteps(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger gitspaceTypes.GitspaceLogger,
steps []gitspaceTypes.Step,
steps []step,
) error {
for _, step := range steps {
// Execute the step
@ -73,15 +76,11 @@ func (e *EmbeddedDockerOrchestrator) ExecuteSteps(
func NewEmbeddedDockerOrchestrator(
dockerClientFactory *infraprovider.DockerClientFactory,
statefulLogger *logutil.StatefulLogger,
gitService git.Service,
userService user.Service,
runArgProvider runarg.Provider,
) Orchestrator {
return &EmbeddedDockerOrchestrator{
dockerClientFactory: dockerClientFactory,
statefulLogger: statefulLogger,
gitService: gitService,
userService: userService,
runArgProvider: runArgProvider,
}
}
@ -207,7 +206,7 @@ func (e *EmbeddedDockerOrchestrator) startStoppedGitspace(
// Set up git credentials if needed
if resolvedRepoDetails.Credentials != nil {
if err := SetupGitCredentials(ctx, exec, resolvedRepoDetails, e.gitService, logStreamInstance); err != nil {
if err := SetupGitCredentials(ctx, exec, resolvedRepoDetails, logStreamInstance); err != nil {
return err
}
}
@ -488,22 +487,16 @@ func (e *EmbeddedDockerOrchestrator) buildSetupSteps(
environment []string,
devcontainerConfig types.DevcontainerConfig,
codeRepoDir string,
) []gitspaceTypes.Step {
return []gitspaceTypes.Step{
) []step {
return []step{
{
Name: "Validate Supported OS",
Execute: ValidateSupportedOS,
StopOnFailure: true,
},
{
Name: "Manage User",
Execute: func(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
return ManageUser(ctx, exec, e.userService, gitspaceLogger)
},
Name: "Manage User",
Execute: ManageUser,
StopOnFailure: true,
},
{
@ -529,14 +522,8 @@ func (e *EmbeddedDockerOrchestrator) buildSetupSteps(
StopOnFailure: true,
},
{
Name: "Install Git",
Execute: func(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
return InstallGit(ctx, exec, e.gitService, gitspaceLogger)
},
Name: "Install Git",
Execute: InstallGit,
StopOnFailure: true,
},
{
@ -547,7 +534,7 @@ func (e *EmbeddedDockerOrchestrator) buildSetupSteps(
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
if resolvedRepoDetails.ResolvedCredentials.Credentials != nil {
return SetupGitCredentials(ctx, exec, resolvedRepoDetails, e.gitService, gitspaceLogger)
return SetupGitCredentials(ctx, exec, resolvedRepoDetails, gitspaceLogger)
}
return nil
},
@ -560,7 +547,7 @@ func (e *EmbeddedDockerOrchestrator) buildSetupSteps(
exec *devcontainer.Exec,
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
return CloneCode(ctx, exec, defaultBaseImage, resolvedRepoDetails, e.gitService, gitspaceLogger)
return CloneCode(ctx, exec, defaultBaseImage, resolvedRepoDetails, gitspaceLogger)
},
StopOnFailure: true,
},

View File

@ -16,9 +16,7 @@ package container
import (
"github.com/harness/gitness/app/gitspace/logutil"
"github.com/harness/gitness/app/gitspace/orchestrator/git"
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
"github.com/harness/gitness/app/gitspace/orchestrator/user"
"github.com/harness/gitness/infraprovider"
"github.com/google/wire"
@ -31,15 +29,11 @@ var WireSet = wire.NewSet(
func ProvideEmbeddedDockerOrchestrator(
dockerClientFactory *infraprovider.DockerClientFactory,
statefulLogger *logutil.StatefulLogger,
gitService git.Service,
userService user.Service,
runArgProvdier runarg.Provider,
) Orchestrator {
return NewEmbeddedDockerOrchestrator(
dockerClientFactory,
statefulLogger,
gitService,
userService,
runArgProvdier,
)
}

View File

@ -20,9 +20,11 @@ import (
"context"
"fmt"
"io"
"strconv"
"strings"
"sync"
"github.com/harness/gitness/app/gitspace/types"
"github.com/harness/gitness/types/enum"
dockerTypes "github.com/docker/docker/api/types"
@ -91,6 +93,34 @@ func (e *Exec) ExecuteCommand(
return stdoutBuf.String(), nil
}
func (e *Exec) ExecuteCommandInHomeDirAndLog(
ctx context.Context,
script string,
root bool,
gitspaceLogger types.GitspaceLogger,
verbose bool,
) error {
// Buffer upto a thousand messages
outputCh := make(chan []byte, 1000)
err := e.executeCmdInHomeDirectoryAsyncStream(ctx, script, root, false, outputCh)
if err != nil {
return err
}
// Use select to wait for the output and exit status
for {
select {
case output := <-outputCh:
done, chErr := handleOutputChannel(output, verbose, gitspaceLogger)
if done {
return chErr
}
case <-ctx.Done():
// Handle context cancellation or timeout
return ctx.Err()
}
}
}
func (e *Exec) createExecution(
ctx context.Context,
command string,
@ -148,7 +178,7 @@ func (e *Exec) executeCmdAsyncStream(
return nil
}
func (e *Exec) ExecuteCmdInHomeDirectoryAsyncStream(
func (e *Exec) executeCmdInHomeDirectoryAsyncStream(
ctx context.Context,
command string,
root bool,
@ -270,3 +300,30 @@ func (e *Exec) streamStdErr(stderr io.Reader, outputCh chan []byte, wg *sync.Wai
log.Error().Err(err).Msg("Error reading stderr " + err.Error())
}
}
func handleOutputChannel(output []byte, verbose bool, gitspaceLogger types.GitspaceLogger) (bool, error) {
// Handle the exit status first
if strings.HasPrefix(string(output), ChannelExitStatus) {
// Extract the exit code from the message
exitCodeStr := strings.TrimPrefix(string(output), ChannelExitStatus)
exitCode, err := strconv.Atoi(exitCodeStr)
if err != nil {
return true, fmt.Errorf("invalid exit status format: %w", err)
}
if exitCode != 0 {
gitspaceLogger.Info("Process Exited with status " + exitCodeStr)
return true, fmt.Errorf("command exited with non-zero status: %d", exitCode)
}
// If exit status is zero, just continue processing
return true, nil
}
// Handle regular command output
msg := string(output)
if len(output) > 0 {
// Log output if verbose or if it's an error
if verbose || strings.HasPrefix(msg, LoggerErrorPrefix) {
gitspaceLogger.Info(msg)
}
}
return false, nil
}

View File

@ -1,48 +0,0 @@
// 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 git
import (
"context"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/scm"
"github.com/harness/gitness/app/gitspace/types"
)
type Service interface {
// Install ensures git is installed in the container.
Install(ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger types.GitspaceLogger,
) error
// SetupCredentials sets the user's git credentials inside the container.
SetupCredentials(
ctx context.Context,
exec *devcontainer.Exec,
resolvedRepoDetails scm.ResolvedDetails,
gitspaceLogger types.GitspaceLogger,
) error
// CloneCode clones the code and ensures devcontainer file is present.
CloneCode(
ctx context.Context,
exec *devcontainer.Exec,
resolvedRepoDetails scm.ResolvedDetails,
defaultBaseImage string,
gitspaceLogger types.GitspaceLogger,
) error
}

View File

@ -1,27 +0,0 @@
// 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 git
import (
"github.com/google/wire"
)
var WireSet = wire.NewSet(
ProvideGitServiceImpl,
)
func ProvideGitServiceImpl() Service {
return NewGitServiceImpl()
}

View File

@ -20,9 +20,8 @@ import (
"fmt"
"strconv"
"github.com/harness/gitness/app/gitspace/orchestrator/common"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/orchestrator/template"
"github.com/harness/gitness/app/gitspace/orchestrator/utils"
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
@ -81,19 +80,19 @@ func (v *VSCode) setupSSHServer(
exec *devcontainer.Exec,
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
osInfoScript := common.GetOSInfoScript()
payload := template.SetupSSHServerPayload{
osInfoScript := utils.GetOSInfoScript()
payload := gitspaceTypes.SetupSSHServerPayload{
Username: exec.RemoteUser,
AccessType: exec.AccessType,
OSInfoScript: osInfoScript,
}
sshServerScript, err := template.GenerateScriptFromTemplate(
sshServerScript, err := utils.GenerateScriptFromTemplate(
templateSetupSSHServer, &payload)
if err != nil {
return fmt.Errorf(
"failed to generate scipt to setup ssh server from template %s: %w", templateSetupSSHServer, err)
}
err = common.ExecuteCommandInHomeDirAndLog(ctx, exec, sshServerScript, true, gitspaceLogger, false)
err = exec.ExecuteCommandInHomeDirAndLog(ctx, sshServerScript, true, gitspaceLogger, false)
if err != nil {
return fmt.Errorf("failed to setup SSH serverr: %w", err)
}
@ -107,14 +106,14 @@ func (v *VSCode) setupVSCodeExtensions(
args map[gitspaceTypes.IDEArg]interface{},
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
payload := template.SetupVSCodeExtensionsPayload{
payload := gitspaceTypes.SetupVSCodeExtensionsPayload{
Username: exec.RemoteUser,
}
if err := v.updateVSCodeSetupPayload(args, gitspaceLogger, &payload); err != nil {
return err
}
vscodeExtensionsScript, err := template.GenerateScriptFromTemplate(
vscodeExtensionsScript, err := utils.GenerateScriptFromTemplate(
templateSetupVSCodeExtensions, &payload)
if err != nil {
return fmt.Errorf(
@ -124,7 +123,7 @@ func (v *VSCode) setupVSCodeExtensions(
)
}
err = common.ExecuteCommandInHomeDirAndLog(ctx, exec, vscodeExtensionsScript,
err = exec.ExecuteCommandInHomeDirAndLog(ctx, vscodeExtensionsScript,
true, gitspaceLogger, false)
if err != nil {
return fmt.Errorf("failed to setup vs-code extensions: %w", err)
@ -140,17 +139,17 @@ func (v *VSCode) Run(
_ map[gitspaceTypes.IDEArg]interface{},
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
payload := template.RunSSHServerPayload{
payload := gitspaceTypes.RunSSHServerPayload{
Port: strconv.Itoa(v.config.Port),
}
runSSHScript, err := template.GenerateScriptFromTemplate(
runSSHScript, err := utils.GenerateScriptFromTemplate(
templateRunSSHServer, &payload)
if err != nil {
return fmt.Errorf(
"failed to generate scipt to run ssh server from template %s: %w", templateRunSSHServer, err)
}
gitspaceLogger.Info("SSH server run output...")
err = common.ExecuteCommandInHomeDirAndLog(ctx, exec, runSSHScript, true, gitspaceLogger, true)
err = exec.ExecuteCommandInHomeDirAndLog(ctx, runSSHScript, true, gitspaceLogger, true)
if err != nil {
return fmt.Errorf("failed to run SSH server: %w", err)
}
@ -174,7 +173,7 @@ func (v *VSCode) Type() enum.IDEType {
func (v *VSCode) updateVSCodeSetupPayload(
args map[gitspaceTypes.IDEArg]interface{},
gitspaceLogger gitspaceTypes.GitspaceLogger,
payload *template.SetupVSCodeExtensionsPayload,
payload *gitspaceTypes.SetupVSCodeExtensionsPayload,
) error {
if args == nil {
return nil
@ -184,16 +183,22 @@ func (v *VSCode) updateVSCodeSetupPayload(
return err
}
// Handle Repository Name
if err := v.handleRepoName(args, payload); err != nil {
return err
repoName, exists := args[gitspaceTypes.IDERepoNameArg]
if !exists {
return nil // No repo name found, nothing to do
}
repoNameStr, ok := repoName.(string)
if !ok {
return fmt.Errorf("repo name is not of type string")
}
payload.RepoName = repoNameStr
return nil
}
func (v *VSCode) handleVSCodeCustomization(
args map[gitspaceTypes.IDEArg]interface{},
gitspaceLogger gitspaceTypes.GitspaceLogger,
payload *template.SetupVSCodeExtensionsPayload,
payload *gitspaceTypes.SetupVSCodeExtensionsPayload,
) error {
customization, exists := args[gitspaceTypes.VSCodeCustomizationArg]
if !exists {
@ -220,21 +225,3 @@ func (v *VSCode) handleVSCodeCustomization(
return nil
}
func (v *VSCode) handleRepoName(
args map[gitspaceTypes.IDEArg]interface{},
payload *template.SetupVSCodeExtensionsPayload,
) error {
repoName, exists := args[gitspaceTypes.IDERepoNameArg]
if !exists {
return nil // No repo name found, nothing to do
}
repoNameStr, ok := repoName.(string)
if !ok {
return fmt.Errorf("repo name is not of type string")
}
payload.RepoName = repoNameStr
return nil
}

View File

@ -25,9 +25,8 @@ import (
"strconv"
"strings"
"github.com/harness/gitness/app/gitspace/orchestrator/common"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/orchestrator/template"
"github.com/harness/gitness/app/gitspace/orchestrator/utils"
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
@ -68,13 +67,13 @@ func (v *VSCodeWeb) Setup(
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
gitspaceLogger.Info("Installing VSCode Web inside container...")
payload := &template.SetupVSCodeWebPayload{}
payload := &gitspaceTypes.SetupVSCodeWebPayload{}
if args != nil {
if err := updateSetupPayloadFromArgs(args, payload, gitspaceLogger); err != nil {
return err
}
}
setupScript, err := template.GenerateScriptFromTemplate(templateSetupVSCodeWeb, payload)
setupScript, err := utils.GenerateScriptFromTemplate(templateSetupVSCodeWeb, payload)
if err != nil {
return fmt.Errorf(
"failed to generate script to setup VSCode Web from template %s: %w",
@ -82,7 +81,7 @@ func (v *VSCodeWeb) Setup(
err,
)
}
err = common.ExecuteCommandInHomeDirAndLog(ctx, exec, setupScript, false, gitspaceLogger, false)
err = exec.ExecuteCommandInHomeDirAndLog(ctx, setupScript, false, gitspaceLogger, false)
if err != nil {
return fmt.Errorf("failed to install VSCode Web: %w", err)
}
@ -124,17 +123,21 @@ func (v *VSCodeWeb) Run(
args map[gitspaceTypes.IDEArg]interface{},
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
payload := &template.RunVSCodeWebPayload{
payload := gitspaceTypes.RunVSCodeWebPayload{
Port: strconv.Itoa(v.config.Port),
}
if args != nil {
err := updateRunPayloadFromArgs(args, payload, gitspaceLogger)
if err != nil {
return err
if proxyURI, exists := args[gitspaceTypes.VSCodeProxyURIArg]; exists {
// Perform a type assertion to ensure proxyURI is a string
proxyURIStr, ok := proxyURI.(string)
if !ok {
return fmt.Errorf("%s is not a string", gitspaceTypes.VSCodeProxyURIArg)
}
payload.ProxyURI = proxyURIStr
}
}
runScript, err := template.GenerateScriptFromTemplate(templateRunVSCodeWeb, payload)
runScript, err := utils.GenerateScriptFromTemplate(templateRunVSCodeWeb, payload)
if err != nil {
return fmt.Errorf(
"failed to generate script to run VSCode Web from template %s: %w",
@ -144,32 +147,16 @@ func (v *VSCodeWeb) Run(
}
gitspaceLogger.Info("Starting IDE ...")
// Execute the script in the home directory
err = common.ExecuteCommandInHomeDirAndLog(ctx, exec, runScript, false, gitspaceLogger, true)
err = exec.ExecuteCommandInHomeDirAndLog(ctx, runScript, false, gitspaceLogger, true)
if err != nil {
return fmt.Errorf("failed to run VSCode Web: %w", err)
}
return nil
}
func updateRunPayloadFromArgs(
args map[gitspaceTypes.IDEArg]interface{},
payload *template.RunVSCodeWebPayload,
_ gitspaceTypes.GitspaceLogger,
) error {
if proxyURI, exists := args[gitspaceTypes.VSCodeProxyURIArg]; exists {
// Perform a type assertion to ensure proxyURI is a string
proxyURIStr, ok := proxyURI.(string)
if !ok {
return fmt.Errorf("%s is not a string", gitspaceTypes.VSCodeProxyURIArg)
}
payload.ProxyURI = proxyURIStr
}
return nil
}
func updateSetupPayloadFromArgs(
args map[gitspaceTypes.IDEArg]interface{},
payload *template.SetupVSCodeWebPayload,
payload *gitspaceTypes.SetupVSCodeWebPayload,
gitspaceLogger gitspaceTypes.GitspaceLogger,
) error {
if customization, exists := args[gitspaceTypes.VSCodeCustomizationArg]; exists {

View File

@ -1,76 +0,0 @@
// 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 orchestrator
import (
"context"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
)
const (
vscodeURLScheme = "vscode-remote"
intellijURLScheme = "jetbrains-gateway"
)
type Orchestrator interface {
// TriggerStartGitspace fetches the infra resources configured for the gitspace and triggers the infra provisioning.
TriggerStartGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) *types.GitspaceError
// 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, *types.GitspaceError)
// TriggerStopGitspace stops the Gitspace container and triggers infra deprovisioning to deprovision
// all the infra resources which are not required to restart the Gitspace.
TriggerStopGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig) *types.GitspaceError
// ResumeStopGitspace saves the deprovisioned infra details.
ResumeStopGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
stoppedInfra types.Infrastructure,
) (enum.GitspaceInstanceStateType, *types.GitspaceError)
// TriggerCleanupInstanceResources cleans up all the resources exclusive to gitspace instance.
TriggerCleanupInstanceResources(ctx context.Context, gitspaceConfig types.GitspaceConfig) error
// ResumeCleanupInstanceResources saves the cleaned up infra details.
ResumeCleanupInstanceResources(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
cleanedUpInfra types.Infrastructure,
) (enum.GitspaceInstanceStateType, error)
// TriggerDeleteGitspace removes the Gitspace container and triggers infra deprovisioning to deprovision
// the infra resources.
// canDeleteUserData = false -> trigger deprovision of all resources except storage associated to user data.
// canDeleteUserData = true -> trigger deprovision of all resources.
TriggerDeleteGitspace(ctx context.Context, gitspaceConfig types.GitspaceConfig, canDeleteUserData bool) error
// ResumeDeleteGitspace saves the deprovisioned infra details.
ResumeDeleteGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
deprovisionedInfra types.Infrastructure,
) (enum.GitspaceInstanceStateType, error)
// GetGitspaceLogs fetches gitspace's start/stop logs.
GetGitspaceLogs(ctx context.Context, gitspaceConfig types.GitspaceConfig) (string, error)
}

View File

@ -26,6 +26,7 @@ import (
"github.com/harness/gitness/app/gitspace/orchestrator/container"
"github.com/harness/gitness/app/gitspace/secret"
secretenum "github.com/harness/gitness/app/gitspace/secret/enum"
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
"github.com/harness/gitness/app/paths"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
@ -34,7 +35,8 @@ import (
"github.com/rs/zerolog/log"
)
func (o orchestrator) ResumeStartGitspace(
// ResumeStartGitspace saves the provisioned infra, resolves the code repo details & creates the Gitspace container.
func (o Orchestrator) ResumeStartGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
provisionedInfra types.Infrastructure,
@ -217,7 +219,7 @@ func generateIDEURL(
case enum.IDETypeVSCode:
// TODO: the following userID is hard coded and should be changed.
ideURL = url.URL{
Scheme: vscodeURLScheme,
Scheme: gitspaceTypes.VSCodeURLScheme,
Host: "", // Empty since we include the host and port in the path
Path: fmt.Sprintf(
"ssh-remote+%s@%s:%s",
@ -229,7 +231,7 @@ func generateIDEURL(
case enum.IDETypeIntellij:
idePath := relativeRepoPath + "/.cache"
ideURL = url.URL{
Scheme: intellijURLScheme,
Scheme: gitspaceTypes.IntellijURLScheme,
Host: "", // Empty since we include the host and port in the path
Path: "connect",
Fragment: fmt.Sprintf("idePath=%s&projectPath=%s&host=%s&port=%s&user=%s&type=%s&deploy=%s",
@ -248,7 +250,7 @@ func generateIDEURL(
return ideURLString
}
func (o orchestrator) getSecretResolver(accessType enum.GitspaceAccessType) (secret.Resolver, error) {
func (o Orchestrator) getSecretResolver(accessType enum.GitspaceAccessType) (secret.Resolver, error) {
secretType := secretenum.PasswordSecretType
switch accessType {
case enum.GitspaceAccessTypeUserCredentials:
@ -261,7 +263,8 @@ func (o orchestrator) getSecretResolver(accessType enum.GitspaceAccessType) (sec
return o.secretResolverFactory.GetSecretResolver(secretType)
}
func (o orchestrator) ResumeStopGitspace(
// ResumeStopGitspace saves the deprovisioned infra details.
func (o Orchestrator) ResumeStopGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
stoppedInfra types.Infrastructure,
@ -302,7 +305,8 @@ func (o orchestrator) ResumeStopGitspace(
return instanceState, nil
}
func (o orchestrator) ResumeDeleteGitspace(
// ResumeDeleteGitspace saves the deprovisioned infra details.
func (o Orchestrator) ResumeDeleteGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
deprovisionedInfra types.Infrastructure,
@ -334,7 +338,8 @@ func (o orchestrator) ResumeDeleteGitspace(
return instanceState, nil
}
func (o orchestrator) ResumeCleanupInstanceResources(
// ResumeCleanupInstanceResources saves the cleaned up infra details.
func (o Orchestrator) ResumeCleanupInstanceResources(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
cleanedUpInfra types.Infrastructure,

View File

@ -26,7 +26,6 @@ import (
"github.com/harness/gitness/app/gitspace/platformconnector"
"github.com/harness/gitness/app/gitspace/scm"
"github.com/harness/gitness/app/gitspace/secret"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
@ -41,24 +40,20 @@ type Config struct {
DefaultBaseImage string
}
type orchestrator struct {
scm *scm.SCM
platformConnector platformconnector.PlatformConnector
infraProviderResourceStore store.InfraProviderResourceStore
infraProvisioner infrastructure.InfraProvisioner
containerOrchestrator container.Orchestrator
eventReporter *events.Reporter
config *Config
ideFactory ide.Factory
secretResolverFactory *secret.ResolverFactory
type Orchestrator struct {
scm *scm.SCM
platformConnector platformconnector.PlatformConnector
infraProvisioner infrastructure.InfraProvisioner
containerOrchestrator container.Orchestrator
eventReporter *events.Reporter
config *Config
ideFactory ide.Factory
secretResolverFactory *secret.ResolverFactory
}
var _ Orchestrator = (*orchestrator)(nil)
func NewOrchestrator(
scm *scm.SCM,
platformConnector platformconnector.PlatformConnector,
infraProviderResourceStore store.InfraProviderResourceStore,
infraProvisioner infrastructure.InfraProvisioner,
containerOrchestrator container.Orchestrator,
eventReporter *events.Reporter,
@ -66,20 +61,20 @@ func NewOrchestrator(
ideFactory ide.Factory,
secretResolverFactory *secret.ResolverFactory,
) Orchestrator {
return orchestrator{
scm: scm,
platformConnector: platformConnector,
infraProviderResourceStore: infraProviderResourceStore,
infraProvisioner: infraProvisioner,
containerOrchestrator: containerOrchestrator,
eventReporter: eventReporter,
config: config,
ideFactory: ideFactory,
secretResolverFactory: secretResolverFactory,
return Orchestrator{
scm: scm,
platformConnector: platformConnector,
infraProvisioner: infraProvisioner,
containerOrchestrator: containerOrchestrator,
eventReporter: eventReporter,
config: config,
ideFactory: ideFactory,
secretResolverFactory: secretResolverFactory,
}
}
func (o orchestrator) TriggerStartGitspace(
// TriggerStartGitspace fetches the infra resources configured for the gitspace and triggers the infra provisioning.
func (o Orchestrator) TriggerStartGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
) *types.GitspaceError {
@ -142,7 +137,9 @@ func (o orchestrator) TriggerStartGitspace(
return nil
}
func (o orchestrator) TriggerStopGitspace(
// TriggerStopGitspace stops the Gitspace container and triggers infra deprovisioning to deprovision
// all the infra resources which are not required to restart the Gitspace.
func (o Orchestrator) TriggerStopGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
) *types.GitspaceError {
@ -183,7 +180,7 @@ func (o orchestrator) TriggerStopGitspace(
return nil
}
func (o orchestrator) stopGitspaceContainer(
func (o Orchestrator) stopGitspaceContainer(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
infra types.Infrastructure,
@ -215,7 +212,7 @@ func (o orchestrator) stopGitspaceContainer(
return nil
}
func (o orchestrator) stopAndRemoveGitspaceContainer(
func (o Orchestrator) stopAndRemoveGitspaceContainer(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
infra types.Infrastructure,
@ -246,7 +243,8 @@ func (o orchestrator) stopAndRemoveGitspaceContainer(
return nil
}
func (o orchestrator) TriggerCleanupInstanceResources(ctx context.Context, gitspaceConfig types.GitspaceConfig) error {
// TriggerCleanupInstanceResources cleans up all the resources exclusive to gitspace instance.
func (o Orchestrator) TriggerCleanupInstanceResources(ctx context.Context, gitspaceConfig types.GitspaceConfig) error {
infra, err := o.getProvisionedInfra(ctx, gitspaceConfig,
[]enum.InfraStatus{
enum.InfraStatusProvisioned,
@ -281,7 +279,11 @@ func (o orchestrator) TriggerCleanupInstanceResources(ctx context.Context, gitsp
return nil
}
func (o orchestrator) TriggerDeleteGitspace(
// TriggerDeleteGitspace removes the Gitspace container and triggers infra deprovisioning to deprovision
// the infra resources.
// canDeleteUserData = false -> trigger deprovision of all resources except storage associated to user data.
// canDeleteUserData = true -> trigger deprovision of all resources.
func (o Orchestrator) TriggerDeleteGitspace(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
canDeleteUserData bool,
@ -324,7 +326,7 @@ func (o orchestrator) TriggerDeleteGitspace(
return nil
}
func (o orchestrator) emitGitspaceEvent(
func (o Orchestrator) emitGitspaceEvent(
ctx context.Context,
config types.GitspaceConfig,
eventType enum.GitspaceEventType,
@ -341,7 +343,7 @@ func (o orchestrator) emitGitspaceEvent(
})
}
func (o orchestrator) getPortsRequiredForGitspace(
func (o Orchestrator) getPortsRequiredForGitspace(
gitspaceConfig types.GitspaceConfig,
devcontainerConfig types.DevcontainerConfig,
) ([]types.GitspacePort, error) {
@ -363,7 +365,8 @@ func (o orchestrator) getPortsRequiredForGitspace(
return gitspacePorts, nil
}
func (o orchestrator) GetGitspaceLogs(ctx context.Context, gitspaceConfig types.GitspaceConfig) (string, error) {
// GetGitspaceLogs fetches gitspace's start/stop logs.
func (o Orchestrator) GetGitspaceLogs(ctx context.Context, gitspaceConfig types.GitspaceConfig) (string, error) {
if gitspaceConfig.GitspaceInstance == nil {
return "", fmt.Errorf("gitspace %s is not setup yet, please try later", gitspaceConfig.Identifier)
}
@ -384,7 +387,7 @@ func (o orchestrator) GetGitspaceLogs(ctx context.Context, gitspaceConfig types.
return logs, nil
}
func (o orchestrator) getProvisionedInfra(
func (o Orchestrator) getProvisionedInfra(
ctx context.Context,
gitspaceConfig types.GitspaceConfig,
expectedStatus []enum.InfraStatus,

View File

@ -1,27 +0,0 @@
// 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 user
import (
"context"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/types"
)
type Service interface {
// Manage manager the linux user in the container.
Manage(ctx context.Context, exec *devcontainer.Exec, gitspaceLogger types.GitspaceLogger) error
}

View File

@ -1,27 +0,0 @@
// 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 user
import (
"github.com/google/wire"
)
var WireSet = wire.NewSet(
ProvideUserServiceImpl,
)
func ProvideUserServiceImpl() Service {
return NewUserServiceImpl()
}

View File

@ -0,0 +1,89 @@
// 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 utils
import (
"context"
"fmt"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/types"
_ "embed"
)
const (
templateSupportedOSDistribution = "supported_os_distribution.sh"
templateVsCodeWebToolsInstallation = "install_tools_vs_code_web.sh"
templateVsCodeToolsInstallation = "install_tools_vs_code.sh"
templateSetEnv = "set_env.sh"
templateGitInstallScript string = "install_git.sh"
templateSetupGitCredentials = "setup_git_credentials.sh" // nolint:gosec
templateCloneCode = "clone_code.sh"
templateManagerUser = "manage_user.sh"
)
//go:embed script/os_info.sh
var osDetectScript string
func GetOSInfoScript() (script string) {
return osDetectScript
}
func ValidateSupportedOS(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger types.GitspaceLogger,
) error {
// TODO: Currently not supporting arch, freebsd and alpine.
// For alpine wee need to install multiple things from
// https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites
script, err := GenerateScriptFromTemplate(
templateSupportedOSDistribution, &types.SupportedOSDistributionPayload{
OSInfoScript: osDetectScript,
})
if err != nil {
return fmt.Errorf("failed to generate scipt to validate supported os distribution from template %s: %w",
templateSupportedOSDistribution, err)
}
gitspaceLogger.Info("Validate supported OSes...")
err = exec.ExecuteCommandInHomeDirAndLog(ctx, script, true, gitspaceLogger, false)
if err != nil {
return fmt.Errorf("error while detecting os distribution: %w", err)
}
return nil
}
func SetEnv(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger types.GitspaceLogger,
environment []string,
) error {
script, err := GenerateScriptFromTemplate(
templateSetEnv, &types.SetEnvPayload{
EnvVariables: environment,
})
if err != nil {
return fmt.Errorf("failed to generate scipt to set env from template %s: %w",
templateSetEnv, err)
}
gitspaceLogger.Info("Setting env...")
err = exec.ExecuteCommandInHomeDirAndLog(ctx, script, true, gitspaceLogger, true)
if err != nil {
return fmt.Errorf("error while setting env vars: %w", err)
}
return nil
}

View File

@ -12,41 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package git
package utils
import (
"context"
"fmt"
"net/url"
"github.com/harness/gitness/app/gitspace/orchestrator/common"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/orchestrator/template"
"github.com/harness/gitness/app/gitspace/scm"
"github.com/harness/gitness/app/gitspace/types"
)
var _ Service = (*ServiceImpl)(nil)
const templateGitInstallScript string = "install_git.sh"
const templateSetupGitCredentials = "setup_git_credentials.sh" // nolint:gosec
const templateCloneCode = "clone_code.sh"
type ServiceImpl struct {
}
func NewGitServiceImpl() Service {
return &ServiceImpl{}
}
func (g *ServiceImpl) Install(
func InstallGit(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger types.GitspaceLogger,
) error {
script, err := template.GenerateScriptFromTemplate(
templateGitInstallScript, &template.SetupGitInstallPayload{
OSInfoScript: common.GetOSInfoScript(),
script, err := GenerateScriptFromTemplate(
templateGitInstallScript, &types.SetupGitInstallPayload{
OSInfoScript: GetOSInfoScript(),
})
if err != nil {
return fmt.Errorf(
@ -54,7 +39,7 @@ func (g *ServiceImpl) Install(
}
gitspaceLogger.Info("Install git output...")
gitspaceLogger.Info("Setting up git inside container")
err = common.ExecuteCommandInHomeDirAndLog(ctx, exec, script, true, gitspaceLogger, false)
err = exec.ExecuteCommandInHomeDirAndLog(ctx, script, true, gitspaceLogger, false)
if err != nil {
return fmt.Errorf("failed to setup git: %w", err)
}
@ -63,14 +48,14 @@ func (g *ServiceImpl) Install(
return nil
}
func (g *ServiceImpl) SetupCredentials(
func SetupGitCredentials(
ctx context.Context,
exec *devcontainer.Exec,
resolvedRepoDetails scm.ResolvedDetails,
gitspaceLogger types.GitspaceLogger,
) error {
script, err := template.GenerateScriptFromTemplate(
templateSetupGitCredentials, &template.SetupGitCredentialsPayload{
script, err := GenerateScriptFromTemplate(
templateSetupGitCredentials, &types.SetupGitCredentialsPayload{
CloneURLWithCreds: resolvedRepoDetails.CloneURL.Value(),
})
if err != nil {
@ -79,7 +64,7 @@ func (g *ServiceImpl) SetupCredentials(
}
gitspaceLogger.Info("Setting up git credentials output...")
gitspaceLogger.Info("Setting up git credentials inside container")
err = common.ExecuteCommandInHomeDirAndLog(ctx, exec, script, false, gitspaceLogger, true)
err = exec.ExecuteCommandInHomeDirAndLog(ctx, script, false, gitspaceLogger, true)
if err != nil {
return fmt.Errorf("failed to setup git credentials: %w", err)
}
@ -87,7 +72,7 @@ func (g *ServiceImpl) SetupCredentials(
return nil
}
func (g *ServiceImpl) CloneCode(
func CloneCode(
ctx context.Context,
exec *devcontainer.Exec,
resolvedRepoDetails scm.ResolvedDetails,
@ -100,7 +85,7 @@ func (g *ServiceImpl) CloneCode(
"failed to parse clone url %s: %w", resolvedRepoDetails.CloneURL, err)
}
cloneURL.User = nil
data := &template.CloneCodePayload{
data := &types.CloneCodePayload{
RepoURL: cloneURL.String(),
Image: defaultBaseImage,
Branch: resolvedRepoDetails.Branch,
@ -110,14 +95,14 @@ func (g *ServiceImpl) CloneCode(
data.Email = resolvedRepoDetails.Credentials.Email
data.Name = resolvedRepoDetails.Credentials.Name.Value()
}
script, err := template.GenerateScriptFromTemplate(
script, err := GenerateScriptFromTemplate(
templateCloneCode, data)
if err != nil {
return fmt.Errorf(
"failed to generate scipt to clone code from template %s: %w", templateCloneCode, err)
}
gitspaceLogger.Info("Cloning code inside container")
err = common.ExecuteCommandInHomeDirAndLog(ctx, exec, script, false, gitspaceLogger, true)
err = exec.ExecuteCommandInHomeDirAndLog(ctx, script, false, gitspaceLogger, true)
if err != nil {
return fmt.Errorf("failed to clone code: %w", err)
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package template
package utils
import (
"bytes"
@ -21,8 +21,6 @@ import (
"io/fs"
"path"
"text/template"
"github.com/harness/gitness/types/enum"
)
const (
@ -35,68 +33,6 @@ var (
scriptTemplates map[string]*template.Template
)
type CloneCodePayload struct {
RepoURL string
Image string
Branch string
RepoName string
Name string
Email string
}
type SetupGitInstallPayload struct {
OSInfoScript string
}
type SetupGitCredentialsPayload struct {
CloneURLWithCreds string
}
type RunVSCodeWebPayload struct {
Port string
Arguments string
ProxyURI string
}
type SetupVSCodeWebPayload struct {
Extensions []string
}
type SetupUserPayload struct {
Username string
AccessKey string
AccessType enum.GitspaceAccessType
HomeDir string
}
type SetupSSHServerPayload struct {
Username string
AccessType enum.GitspaceAccessType
OSInfoScript string
}
type SetupVSCodeExtensionsPayload struct {
Username string
Extensions string
RepoName string
}
type RunSSHServerPayload struct {
Port string
}
type InstallToolsPayload struct {
OSInfoScript string
}
type SupportedOSDistributionPayload struct {
OSInfoScript string
}
type SetEnvPayload struct {
EnvVariables []string
}
func init() {
err := LoadTemplates()
if err != nil {

View File

@ -0,0 +1,99 @@
// 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 utils
import (
"context"
"fmt"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/types"
"github.com/harness/gitness/types/enum"
)
func InstallTools(
ctx context.Context,
exec *devcontainer.Exec,
ideType enum.IDEType,
gitspaceLogger types.GitspaceLogger,
) error {
switch ideType {
case enum.IDETypeVSCodeWeb:
err := InstallToolsForVsCodeWeb(ctx, exec, gitspaceLogger)
if err != nil {
return err
}
return nil
case enum.IDETypeVSCode:
err := InstallToolsForVsCode(ctx, exec, gitspaceLogger)
if err != nil {
return err
}
return nil
case enum.IDETypeIntellij:
// not installing any tools for intellij
return nil
}
return nil
}
func InstallToolsForVsCodeWeb(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger types.GitspaceLogger,
) error {
script, err := GenerateScriptFromTemplate(
templateVsCodeWebToolsInstallation, &types.InstallToolsPayload{
OSInfoScript: osDetectScript,
})
if err != nil {
return fmt.Errorf(
"failed to generate scipt to install tools for vs code web from template %s: %w",
templateVsCodeWebToolsInstallation, err)
}
gitspaceLogger.Info("Installing tools for vs code web inside container")
gitspaceLogger.Info("Tools installation output...")
err = exec.ExecuteCommandInHomeDirAndLog(ctx, script, true, gitspaceLogger, false)
if err != nil {
return fmt.Errorf("failed to install tools for vs code web: %w", err)
}
gitspaceLogger.Info("Successfully installed tools for vs code web")
return nil
}
func InstallToolsForVsCode(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger types.GitspaceLogger,
) error {
script, err := GenerateScriptFromTemplate(
templateVsCodeToolsInstallation, &types.InstallToolsPayload{
OSInfoScript: osDetectScript,
})
if err != nil {
return fmt.Errorf(
"failed to generate scipt to install tools for vs code from template %s: %w",
templateVsCodeToolsInstallation, err)
}
gitspaceLogger.Info("Installing tools for vs code in container")
err = exec.ExecuteCommandInHomeDirAndLog(ctx, script, true, gitspaceLogger, false)
if err != nil {
return fmt.Errorf("failed to install tools for vs code: %w", err)
}
gitspaceLogger.Info("Successfully installed tools for vs code")
return nil
}

View File

@ -12,36 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package user
package utils
import (
"context"
"fmt"
"github.com/harness/gitness/app/gitspace/orchestrator/common"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/app/gitspace/orchestrator/template"
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
"github.com/harness/gitness/app/gitspace/types"
)
var _ Service = (*ServiceImpl)(nil)
const templateManagerUser = "manage_user.sh"
type ServiceImpl struct {
}
func NewUserServiceImpl() Service {
return &ServiceImpl{}
}
func (u *ServiceImpl) Manage(
func ManageUser(
ctx context.Context,
exec *devcontainer.Exec,
gitspaceLogger gitspaceTypes.GitspaceLogger,
gitspaceLogger types.GitspaceLogger,
) error {
script, err := template.GenerateScriptFromTemplate(
templateManagerUser, &template.SetupUserPayload{
script, err := GenerateScriptFromTemplate(
templateManagerUser, &types.SetupUserPayload{
Username: exec.RemoteUser,
AccessKey: exec.AccessKey,
AccessType: exec.AccessType,
@ -53,7 +40,7 @@ func (u *ServiceImpl) Manage(
}
gitspaceLogger.Info("Configuring user directory and credentials inside container")
err = common.ExecuteCommandInHomeDirAndLog(ctx, exec, script, true, gitspaceLogger, true)
err = exec.ExecuteCommandInHomeDirAndLog(ctx, script, true, gitspaceLogger, true)
if err != nil {
return fmt.Errorf("failed to setup user: %w", err)
}

View File

@ -22,7 +22,6 @@ import (
"github.com/harness/gitness/app/gitspace/platformconnector"
"github.com/harness/gitness/app/gitspace/scm"
"github.com/harness/gitness/app/gitspace/secret"
"github.com/harness/gitness/app/store"
"github.com/google/wire"
)
@ -35,7 +34,6 @@ var WireSet = wire.NewSet(
func ProvideOrchestrator(
scm *scm.SCM,
platformConnector platformconnector.PlatformConnector,
infraProviderResourceStore store.InfraProviderResourceStore,
infraProvisioner infrastructure.InfraProvisioner,
containerOrchestrator container.Orchestrator,
reporter *events.Reporter,
@ -46,7 +44,6 @@ func ProvideOrchestrator(
return NewOrchestrator(
scm,
platformConnector,
infraProviderResourceStore,
infraProvisioner,
containerOrchestrator,
reporter,

View File

@ -0,0 +1,79 @@
// 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 types
import "github.com/harness/gitness/types/enum"
type CloneCodePayload struct {
RepoURL string
Image string
Branch string
RepoName string
Name string
Email string
}
type SetupGitInstallPayload struct {
OSInfoScript string
}
type SetupGitCredentialsPayload struct {
CloneURLWithCreds string
}
type RunVSCodeWebPayload struct {
Port string
Arguments string
ProxyURI string
}
type SetupVSCodeWebPayload struct {
Extensions []string
}
type SetupUserPayload struct {
Username string
AccessKey string
AccessType enum.GitspaceAccessType
HomeDir string
}
type SetupSSHServerPayload struct {
Username string
AccessType enum.GitspaceAccessType
OSInfoScript string
}
type SetupVSCodeExtensionsPayload struct {
Username string
Extensions string
RepoName string
}
type RunSSHServerPayload struct {
Port string
}
type InstallToolsPayload struct {
OSInfoScript string
}
type SupportedOSDistributionPayload struct {
OSInfoScript string
}
type SetEnvPayload struct {
EnvVariables []string
}

View File

@ -15,9 +15,6 @@
package types
import (
"context"
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
"github.com/harness/gitness/types"
"github.com/rs/zerolog"
@ -29,6 +26,8 @@ const (
VSCodeCustomizationArg IDEArg = "VSCODE_CUSTOMIZATION"
VSCodeProxyURIArg IDEArg = "VSCODE_PROXY_URI"
IDERepoNameArg IDEArg = "IDE_REPO_NAME"
VSCodeURLScheme = "vscode-remote"
IntellijURLScheme = "jetbrains-gateway"
)
type GitspaceLogger interface {
@ -38,13 +37,6 @@ type GitspaceLogger interface {
Error(msg string, err error)
}
// Step represents a single setup action.
type Step struct {
Name string
Execute func(ctx context.Context, exec *devcontainer.Exec, gitspaceLogger GitspaceLogger) error
StopOnFailure bool // Flag to control whether execution should stop on failure
}
type ZerologAdapter struct {
logger *zerolog.Logger
}

View File

@ -64,10 +64,8 @@ import (
"github.com/harness/gitness/app/gitspace/logutil"
"github.com/harness/gitness/app/gitspace/orchestrator"
containerorchestrator "github.com/harness/gitness/app/gitspace/orchestrator/container"
containerGit "github.com/harness/gitness/app/gitspace/orchestrator/git"
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
containerUser "github.com/harness/gitness/app/gitspace/orchestrator/user"
"github.com/harness/gitness/app/gitspace/platformconnector"
"github.com/harness/gitness/app/gitspace/scm"
gitspacesecret "github.com/harness/gitness/app/gitspace/secret"
@ -282,8 +280,6 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
capabilitiesservice.WireSet,
docker.ProvideReporter,
secretservice.WireSet,
containerGit.WireSet,
containerUser.WireSet,
messagingservice.WireSet,
runarg.WireSet,
usage.WireSet,

View File

@ -53,10 +53,8 @@ import (
"github.com/harness/gitness/app/gitspace/logutil"
"github.com/harness/gitness/app/gitspace/orchestrator"
"github.com/harness/gitness/app/gitspace/orchestrator/container"
git2 "github.com/harness/gitness/app/gitspace/orchestrator/git"
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
user2 "github.com/harness/gitness/app/gitspace/orchestrator/user"
"github.com/harness/gitness/app/gitspace/platformconnector"
"github.com/harness/gitness/app/gitspace/scm"
"github.com/harness/gitness/app/gitspace/secret"
@ -321,8 +319,6 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
infrastructureConfig := server.ProvideGitspaceInfraProvisionerConfig(config)
infraProvisioner := infrastructure.ProvideInfraProvisionerService(infraProviderConfigStore, infraProviderResourceStore, factory, infraProviderTemplateStore, infraProvisionedStore, infrastructureConfig)
statefulLogger := logutil.ProvideStatefulLogger(logStream)
gitService := git2.ProvideGitServiceImpl()
userService := user2.ProvideUserServiceImpl()
runargResolver, err := runarg.ProvideResolver()
if err != nil {
return nil, err
@ -331,7 +327,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
if err != nil {
return nil, err
}
containerOrchestrator := container.ProvideEmbeddedDockerOrchestrator(dockerClientFactory, statefulLogger, gitService, userService, runargProvider)
containerOrchestrator := container.ProvideEmbeddedDockerOrchestrator(dockerClientFactory, statefulLogger, runargProvider)
orchestratorConfig := server.ProvideGitspaceOrchestratorConfig(config)
vsCodeConfig := server.ProvideIDEVSCodeConfig(config)
vsCode := ide.ProvideVSCodeService(vsCodeConfig)
@ -340,7 +336,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
ideFactory := ide.ProvideIDEFactory(vsCode, vsCodeWeb)
passwordResolver := secret.ProvidePasswordResolver()
resolverFactory := secret.ProvideResolverFactory(passwordResolver)
orchestratorOrchestrator := orchestrator.ProvideOrchestrator(scmSCM, platformConnector, infraProviderResourceStore, infraProvisioner, containerOrchestrator, eventsReporter, orchestratorConfig, ideFactory, resolverFactory)
orchestratorOrchestrator := orchestrator.ProvideOrchestrator(scmSCM, platformConnector, infraProvisioner, containerOrchestrator, eventsReporter, orchestratorConfig, ideFactory, resolverFactory)
gitspaceService := gitspace.ProvideGitspace(transactor, gitspaceConfigStore, gitspaceInstanceStore, eventsReporter, gitspaceEventStore, spaceStore, infraproviderService, orchestratorOrchestrator, scmSCM, config)
usageMetricStore := database.ProvideUsageMetricStore(db)
spaceController := space.ProvideController(config, transactor, provider, streamer, spaceIdentifier, authorizer, spacePathStore, pipelineStore, secretStore, connectorStore, templateStore, spaceStore, repoStore, principalStore, repoController, membershipStore, listService, spaceCache, repository, exporterRepository, resourceLimiter, publicaccessService, auditService, gitspaceService, labelService, instrumentService, executionStore, rulesService, usageMetricStore)