mirror of https://github.com/harness/drone.git
feat: [CDE-475]: Adding support for runArgs. (#3031)
* Rebasing * feat: [CDE-475]: Adding support for runArgs. * WIP * WIPpull/3597/head
parent
1299db775e
commit
7c358528ef
|
@ -7,7 +7,7 @@ GITNESS_METRIC_ENABLED=false
|
|||
GITNESS_HTTP_HOST=localhost
|
||||
GITNESS_GITSPACE_ENABLE=true
|
||||
GITNESS_DEBUG=true
|
||||
GITNESS_DOCKER_API_VERSION=1.41
|
||||
GITNESS_DOCKER_API_VERSION=1.45
|
||||
GITNESS_SSH_ENABLE=true
|
||||
GITNESS_SSH_HOST=localhost
|
||||
GITNESS_SSH_PORT=2222
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
// 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 container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
|
||||
"github.com/harness/gitness/types"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func ExtractRunArgs(
|
||||
ctx context.Context,
|
||||
spaceID int64,
|
||||
runArgProvider runarg.Provider,
|
||||
runArgsRaw []string,
|
||||
) (map[types.RunArg]*types.RunArgValue, error) {
|
||||
supportedRunArgsMap, err := runArgProvider.ProvideSupportedRunArgs(ctx, spaceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var runArgsMap = make(map[types.RunArg]*types.RunArgValue)
|
||||
primaryLoopCounter := 0
|
||||
for primaryLoopCounter < len(runArgsRaw) {
|
||||
currentArg := runArgsRaw[primaryLoopCounter]
|
||||
if currentArg == "" || !isArg(currentArg) {
|
||||
primaryLoopCounter++
|
||||
continue
|
||||
}
|
||||
|
||||
argParts := strings.SplitN(currentArg, "=", 2)
|
||||
argKey := argParts[0]
|
||||
|
||||
currentRunArgDefinition, isSupportedArg := supportedRunArgsMap[types.RunArg(argKey)]
|
||||
if !isSupportedArg {
|
||||
primaryLoopCounter++
|
||||
continue
|
||||
}
|
||||
updatedPrimaryLoopCounter, allowedValues, isAnyValueBlocked := getValues(runArgsRaw, argParts,
|
||||
primaryLoopCounter, currentRunArgDefinition)
|
||||
|
||||
primaryLoopCounter = updatedPrimaryLoopCounter
|
||||
|
||||
if isAnyValueBlocked && len(allowedValues) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
currentRunArgValue := types.RunArgValue{
|
||||
Name: currentRunArgDefinition.Name,
|
||||
Values: allowedValues,
|
||||
}
|
||||
|
||||
existingRunArgValue, isAlreadyPresent := runArgsMap[currentRunArgDefinition.Name]
|
||||
if isAlreadyPresent && currentRunArgDefinition.AllowMultipleOccurences {
|
||||
existingRunArgValue.Values = append(existingRunArgValue.Values, currentRunArgValue.Values...)
|
||||
} else {
|
||||
runArgsMap[currentRunArgDefinition.Name] = ¤tRunArgValue
|
||||
}
|
||||
}
|
||||
|
||||
return runArgsMap, nil
|
||||
}
|
||||
|
||||
func getValues(
|
||||
runArgs []string,
|
||||
argParts []string,
|
||||
primaryLoopCounter int,
|
||||
currentRunArgDefinition types.RunArgDefinition,
|
||||
) (int, []string, bool) {
|
||||
values := make([]string, 0)
|
||||
if len(argParts) > 1 {
|
||||
values = append(values, argParts[1])
|
||||
primaryLoopCounter++
|
||||
} else {
|
||||
var secondaryLoopCounter = primaryLoopCounter + 1
|
||||
for secondaryLoopCounter < len(runArgs) {
|
||||
currentValue := runArgs[secondaryLoopCounter]
|
||||
if isArg(currentValue) {
|
||||
break
|
||||
}
|
||||
values = append(values, currentValue)
|
||||
secondaryLoopCounter++
|
||||
}
|
||||
primaryLoopCounter = secondaryLoopCounter
|
||||
}
|
||||
allowedValues, isAnyValueBlocked := filterAllowedValues(values, currentRunArgDefinition)
|
||||
return primaryLoopCounter, allowedValues, isAnyValueBlocked
|
||||
}
|
||||
|
||||
func filterAllowedValues(values []string, currentRunArgDefinition types.RunArgDefinition) ([]string, bool) {
|
||||
isAnyValueBlocked := false
|
||||
allowedValues := make([]string, 0)
|
||||
for _, v := range values {
|
||||
switch {
|
||||
case len(currentRunArgDefinition.AllowedValues) > 0:
|
||||
if _, ok := currentRunArgDefinition.AllowedValues[v]; ok {
|
||||
allowedValues = append(allowedValues, v)
|
||||
} else {
|
||||
isAnyValueBlocked = true
|
||||
}
|
||||
case len(currentRunArgDefinition.BlockedValues) > 0:
|
||||
if _, ok := currentRunArgDefinition.BlockedValues[v]; !ok {
|
||||
allowedValues = append(allowedValues, v)
|
||||
} else {
|
||||
isAnyValueBlocked = true
|
||||
}
|
||||
default:
|
||||
allowedValues = append(allowedValues, v)
|
||||
}
|
||||
}
|
||||
return allowedValues, isAnyValueBlocked
|
||||
}
|
||||
|
||||
func isArg(str string) bool {
|
||||
return strings.HasPrefix(str, "--") || strings.HasPrefix(str, "-")
|
||||
}
|
||||
|
||||
func ExtractEnv(devcontainerConfig types.DevcontainerConfig, runArgsMap map[types.RunArg]*types.RunArgValue) []string {
|
||||
var env []string
|
||||
for key, value := range devcontainerConfig.ContainerEnv {
|
||||
env = append(env, fmt.Sprintf("%s=%s", key, value))
|
||||
}
|
||||
envFromRunArgs := getEnv(runArgsMap)
|
||||
env = append(env, envFromRunArgs...)
|
||||
return env
|
||||
}
|
||||
|
||||
func ExtractForwardPorts(devcontainerConfig types.DevcontainerConfig) []int {
|
||||
var ports []int
|
||||
for _, strPort := range devcontainerConfig.ForwardPorts {
|
||||
portAsInt, err := strPort.Int64() // Using Atoi to convert string to int
|
||||
if err != nil {
|
||||
log.Warn().Msgf("Error converting port string '%s' to int: %v", strPort, err)
|
||||
continue // Skip the invalid port
|
||||
}
|
||||
ports = append(ports, int(portAsInt))
|
||||
}
|
||||
return ports
|
||||
}
|
||||
|
||||
func ExtractLifecycleCommands(actionType PostAction, devcontainerConfig types.DevcontainerConfig) []string {
|
||||
switch actionType {
|
||||
case PostCreateAction:
|
||||
return devcontainerConfig.PostCreateCommand.ToCommandArray()
|
||||
case PostStartAction:
|
||||
return devcontainerConfig.PostStartCommand.ToCommandArray()
|
||||
default:
|
||||
return []string{} // Return empty string if actionType is not recognized
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/runarg"
|
||||
gitspaceTypes "github.com/harness/gitness/app/gitspace/types"
|
||||
"github.com/harness/gitness/types"
|
||||
|
||||
|
@ -31,6 +32,7 @@ import (
|
|||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
@ -131,22 +133,50 @@ func CreateContainer(
|
|||
mountType mount.Type,
|
||||
portMappings map[int]*types.PortMapping,
|
||||
env []string,
|
||||
runArgsMap map[types.RunArg]*types.RunArgValue,
|
||||
) error {
|
||||
exposedPorts, portBindings := applyPortMappings(portMappings)
|
||||
|
||||
gitspaceLogger.Info("Creating container: " + containerName)
|
||||
|
||||
hostConfig := prepareHostConfig(bindMountSource, bindMountTarget, mountType, portBindings)
|
||||
hostConfig, err := prepareHostConfig(bindMountSource, bindMountTarget, mountType, portBindings, runArgsMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
healthCheckConfig, err := getHealthCheckConfig(runArgsMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stopTimeout, err := getStopTimeout(runArgsMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
entrypoint := getEntrypoint(runArgsMap)
|
||||
var cmd strslice.StrSlice
|
||||
if len(entrypoint) == 0 {
|
||||
entrypoint = []string{"/bin/sh"}
|
||||
cmd = []string{"-c", "trap 'exit 0' 15; sleep infinity & wait $!"}
|
||||
}
|
||||
|
||||
// Create the container
|
||||
containerConfig := &container.Config{
|
||||
Hostname: getHostname(runArgsMap),
|
||||
Domainname: getDomainname(runArgsMap),
|
||||
Image: imageName,
|
||||
Env: env,
|
||||
Entrypoint: []string{"/bin/sh"},
|
||||
Cmd: []string{"-c", "trap 'exit 0' 15; sleep infinity & wait $!"},
|
||||
Entrypoint: entrypoint,
|
||||
Cmd: cmd,
|
||||
ExposedPorts: exposedPorts,
|
||||
Labels: getLabels(runArgsMap),
|
||||
Healthcheck: healthCheckConfig,
|
||||
MacAddress: getMACAddress(runArgsMap),
|
||||
StopSignal: getStopSignal(runArgsMap),
|
||||
StopTimeout: stopTimeout,
|
||||
User: getUser(runArgsMap),
|
||||
}
|
||||
_, err := dockerClient.ContainerCreate(ctx, containerConfig, hostConfig, nil, nil, containerName)
|
||||
|
||||
_, err = dockerClient.ContainerCreate(ctx, containerConfig, hostConfig, nil, nil, containerName)
|
||||
if err != nil {
|
||||
return logStreamWrapError(gitspaceLogger, "Error while creating container", err)
|
||||
}
|
||||
|
@ -178,7 +208,33 @@ func prepareHostConfig(
|
|||
bindMountTarget string,
|
||||
mountType mount.Type,
|
||||
portBindings nat.PortMap,
|
||||
) *container.HostConfig {
|
||||
runArgsMap map[types.RunArg]*types.RunArgValue,
|
||||
) (*container.HostConfig, error) {
|
||||
hostResources, err := getHostResources(runArgsMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
extraHosts := getExtraHosts(runArgsMap)
|
||||
if goruntime.GOOS == "linux" {
|
||||
extraHosts = append(extraHosts, "host.docker.internal:host-gateway")
|
||||
}
|
||||
|
||||
restartPolicy, err := getRestartPolicy(runArgsMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oomScoreAdj, err := getOomScoreAdj(runArgsMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
shmSize, err := getSHMSize(runArgsMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hostConfig := &container.HostConfig{
|
||||
PortBindings: portBindings,
|
||||
Mounts: []mount.Mount{
|
||||
|
@ -188,14 +244,33 @@ func prepareHostConfig(
|
|||
Target: bindMountTarget,
|
||||
},
|
||||
},
|
||||
Resources: hostResources,
|
||||
Annotations: getAnnotations(runArgsMap),
|
||||
ExtraHosts: extraHosts,
|
||||
NetworkMode: getNetworkMode(runArgsMap),
|
||||
RestartPolicy: restartPolicy,
|
||||
AutoRemove: getAutoRemove(runArgsMap),
|
||||
CapDrop: getCapDrop(runArgsMap),
|
||||
CgroupnsMode: getCgroupNSMode(runArgsMap),
|
||||
DNS: getDNS(runArgsMap),
|
||||
DNSOptions: getDNSOptions(runArgsMap),
|
||||
DNSSearch: getDNSSearch(runArgsMap),
|
||||
IpcMode: getIPCMode(runArgsMap),
|
||||
Isolation: getIsolation(runArgsMap),
|
||||
Init: getInit(runArgsMap),
|
||||
Links: getLinks(runArgsMap),
|
||||
OomScoreAdj: oomScoreAdj,
|
||||
PidMode: getPIDMode(runArgsMap),
|
||||
Runtime: getRuntime(runArgsMap),
|
||||
SecurityOpt: getSecurityOpt(runArgsMap),
|
||||
StorageOpt: getStorageOpt(runArgsMap),
|
||||
ShmSize: shmSize,
|
||||
Sysctls: getSysctls(runArgsMap),
|
||||
}
|
||||
|
||||
if goruntime.GOOS == "linux" {
|
||||
hostConfig.ExtraHosts = []string{"host.docker.internal:host-gateway"}
|
||||
}
|
||||
|
||||
return hostConfig
|
||||
return hostConfig, nil
|
||||
}
|
||||
|
||||
func GetContainerInfo(
|
||||
ctx context.Context,
|
||||
containerName string,
|
||||
|
@ -227,10 +302,46 @@ func PullImage(
|
|||
ctx context.Context,
|
||||
imageName string,
|
||||
dockerClient *client.Client,
|
||||
runArgsMap map[types.RunArg]*types.RunArgValue,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
imagePullRunArg := getImagePullPolicy(runArgsMap)
|
||||
gitspaceLogger.Info("Image pull policy is: " + imagePullRunArg)
|
||||
if imagePullRunArg == "never" {
|
||||
return nil
|
||||
}
|
||||
if imagePullRunArg == "missing" {
|
||||
gitspaceLogger.Info("Checking if image " + imageName + " is present locally")
|
||||
|
||||
filterArgs := filters.NewArgs()
|
||||
filterArgs.Add("reference", imageName)
|
||||
|
||||
images, err := dockerClient.ImageList(ctx, image.ListOptions{Filters: filterArgs})
|
||||
if err != nil {
|
||||
gitspaceLogger.Error("Error listing images locally", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if len(images) > 0 {
|
||||
gitspaceLogger.Info("Image " + imageName + " is present locally")
|
||||
return nil
|
||||
}
|
||||
gitspaceLogger.Info("Image " + imageName + " is not present locally")
|
||||
}
|
||||
|
||||
gitspaceLogger.Info("Pulling image: " + imageName)
|
||||
pullResponse, err := dockerClient.ImagePull(ctx, imageName, image.PullOptions{})
|
||||
|
||||
pullResponse, err := dockerClient.ImagePull(ctx, imageName, image.PullOptions{Platform: getPlatform(runArgsMap)})
|
||||
defer func() {
|
||||
if pullResponse == nil {
|
||||
return
|
||||
}
|
||||
closingErr := pullResponse.Close()
|
||||
if closingErr != nil {
|
||||
log.Warn().Err(closingErr).Msg("failed to close image pull response")
|
||||
}
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
return logStreamWrapError(gitspaceLogger, "Error while pulling image", err)
|
||||
}
|
||||
|
@ -271,6 +382,28 @@ func PullImage(
|
|||
return nil
|
||||
}
|
||||
|
||||
func ExtractRunArgsWithLogging(
|
||||
ctx context.Context,
|
||||
spaceID int64,
|
||||
runArgProvider runarg.Provider,
|
||||
runArgsRaw []string,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) (map[types.RunArg]*types.RunArgValue, error) {
|
||||
gitspaceLogger.Info("Extracting runsArgs")
|
||||
runArgsMap, err := ExtractRunArgs(ctx, spaceID, runArgProvider, runArgsRaw)
|
||||
if err != nil {
|
||||
return nil, logStreamWrapError(gitspaceLogger, "Error while extracting runArgs", err)
|
||||
}
|
||||
if len(runArgsMap) > 0 {
|
||||
st := ""
|
||||
for key, value := range runArgsMap {
|
||||
st = fmt.Sprintf("%s%s: %s\n", st, key, value)
|
||||
}
|
||||
gitspaceLogger.Info(fmt.Sprintf("Extracted following runArgs\n%v", st))
|
||||
}
|
||||
return runArgsMap, nil
|
||||
}
|
||||
|
||||
// getContainerResponse retrieves container information and prepares the start response.
|
||||
func GetContainerResponse(
|
||||
ctx context.Context,
|
|
@ -17,7 +17,6 @@ package container
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/common"
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
|
||||
|
@ -26,178 +25,9 @@ import (
|
|||
"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/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
// buildSetupSteps constructs the steps to be executed in the setup process.
|
||||
func (e *EmbeddedDockerOrchestrator) buildSetupSteps(
|
||||
_ context.Context,
|
||||
ideService ide.IDE,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
resolvedRepoDetails scm.ResolvedDetails,
|
||||
defaultBaseImage string,
|
||||
environment []string,
|
||||
devcontainerConfig types.DevcontainerConfig,
|
||||
codeRepoDir string,
|
||||
) []gitspaceTypes.Step {
|
||||
return []gitspaceTypes.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)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Set environment",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return SetEnv(ctx, exec, gitspaceLogger, environment)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Install Tools",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return InstallTools(ctx, exec, gitspaceLogger, gitspaceConfig.IDE)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Setup IDE",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return SetupIDE(ctx, exec, ideService, gitspaceLogger)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Run IDE",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return RunIDE(ctx, exec, ideService, gitspaceLogger)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Install Git",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return InstallGit(ctx, exec, e.gitService, gitspaceLogger)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Setup Git Credentials",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
if resolvedRepoDetails.ResolvedCredentials.Credentials != nil {
|
||||
return SetupGitCredentials(ctx, exec, resolvedRepoDetails, e.gitService, gitspaceLogger)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Clone Code",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return CloneCode(ctx, exec, defaultBaseImage, resolvedRepoDetails, e.gitService, gitspaceLogger)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
// Post-create and Post-start steps
|
||||
{
|
||||
Name: "Execute PostCreate Command",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
command := ExtractLifecycleCommands(PostCreateAction, devcontainerConfig)
|
||||
return ExecuteCommands(ctx, exec, codeRepoDir, gitspaceLogger, command, PostCreateAction)
|
||||
},
|
||||
StopOnFailure: false,
|
||||
},
|
||||
{
|
||||
Name: "Execute PostStart Command",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
command := ExtractLifecycleCommands(PostStartAction, devcontainerConfig)
|
||||
return ExecuteCommands(ctx, exec, codeRepoDir, gitspaceLogger, command, PostStartAction)
|
||||
},
|
||||
StopOnFailure: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// setupGitspaceAndIDE initializes Gitspace and IDE by registering and executing the setup steps.
|
||||
func (e *EmbeddedDockerOrchestrator) setupGitspaceAndIDE(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
ideService ide.IDE,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
resolvedRepoDetails scm.ResolvedDetails,
|
||||
defaultBaseImage string,
|
||||
environment []string,
|
||||
) error {
|
||||
homeDir := GetUserHomeDir(gitspaceConfig.GitspaceUser.Identifier)
|
||||
devcontainerConfig := resolvedRepoDetails.DevcontainerConfig
|
||||
codeRepoDir := filepath.Join(homeDir, resolvedRepoDetails.RepoName)
|
||||
|
||||
steps := e.buildSetupSteps(
|
||||
ctx,
|
||||
ideService,
|
||||
gitspaceConfig,
|
||||
resolvedRepoDetails,
|
||||
defaultBaseImage,
|
||||
environment,
|
||||
devcontainerConfig,
|
||||
codeRepoDir)
|
||||
|
||||
// Execute the registered steps
|
||||
if err := e.ExecuteSteps(ctx, exec, gitspaceLogger, steps); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func InstallTools(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
|
@ -13,43 +13,3 @@
|
|||
// limitations under the License.
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func ExtractEnv(devcontainerConfig types.DevcontainerConfig) []string {
|
||||
var env []string
|
||||
for key, value := range devcontainerConfig.ContainerEnv {
|
||||
env = append(env, fmt.Sprintf("%s=%s", key, value))
|
||||
}
|
||||
return env
|
||||
}
|
||||
|
||||
func ExtractForwardPorts(devcontainerConfig types.DevcontainerConfig) []int {
|
||||
var ports []int
|
||||
for _, strPort := range devcontainerConfig.ForwardPorts {
|
||||
portAsInt, err := strPort.Int64() // Using Atoi to convert string to int
|
||||
if err != nil {
|
||||
log.Warn().Msgf("Error converting port string '%s' to int: %v", strPort, err)
|
||||
continue // Skip the invalid port
|
||||
}
|
||||
ports = append(ports, int(portAsInt))
|
||||
}
|
||||
return ports
|
||||
}
|
||||
|
||||
func ExtractLifecycleCommands(actionType PostAction, devcontainerConfig types.DevcontainerConfig) []string {
|
||||
switch actionType {
|
||||
case PostCreateAction:
|
||||
return devcontainerConfig.PostCreateCommand.ToCommandArray()
|
||||
case PostStartAction:
|
||||
return devcontainerConfig.PostStartCommand.ToCommandArray()
|
||||
default:
|
||||
return []string{} // Return empty string if actionType is not recognized
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"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"
|
||||
|
@ -45,6 +46,7 @@ type EmbeddedDockerOrchestrator struct {
|
|||
statefulLogger *logutil.StatefulLogger
|
||||
gitService git.Service
|
||||
userService user.Service
|
||||
runArgProvider runarg.Provider
|
||||
}
|
||||
|
||||
// ExecuteSteps executes all registered steps in sequence, respecting stopOnFailure flag.
|
||||
|
@ -73,12 +75,14 @@ func NewEmbeddedDockerOrchestrator(
|
|||
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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,8 +379,14 @@ func (e *EmbeddedDockerOrchestrator) runGitspaceSetupSteps(
|
|||
imageName = defaultBaseImage
|
||||
}
|
||||
|
||||
runArgsMap, err := ExtractRunArgsWithLogging(ctx, gitspaceConfig.SpaceID, e.runArgProvider,
|
||||
devcontainerConfig.RunArgs, gitspaceLogger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Pull the required image
|
||||
if err := PullImage(ctx, imageName, dockerClient, gitspaceLogger); err != nil {
|
||||
if err := PullImage(ctx, imageName, dockerClient, runArgsMap, gitspaceLogger); err != nil {
|
||||
return err
|
||||
}
|
||||
portMappings := infrastructure.GitspacePortMappings
|
||||
|
@ -392,12 +402,12 @@ func (e *EmbeddedDockerOrchestrator) runGitspaceSetupSteps(
|
|||
}
|
||||
|
||||
storage := infrastructure.Storage
|
||||
environment := ExtractEnv(devcontainerConfig)
|
||||
environment := ExtractEnv(devcontainerConfig, runArgsMap)
|
||||
if len(environment) > 0 {
|
||||
gitspaceLogger.Info(fmt.Sprintf("Setting Environment : %v", environment))
|
||||
}
|
||||
// Create the container
|
||||
err := CreateContainer(
|
||||
err = CreateContainer(
|
||||
ctx,
|
||||
dockerClient,
|
||||
imageName,
|
||||
|
@ -408,6 +418,7 @@ func (e *EmbeddedDockerOrchestrator) runGitspaceSetupSteps(
|
|||
mount.TypeVolume,
|
||||
portMappings,
|
||||
environment,
|
||||
runArgsMap,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -444,6 +455,174 @@ func (e *EmbeddedDockerOrchestrator) runGitspaceSetupSteps(
|
|||
return nil
|
||||
}
|
||||
|
||||
// buildSetupSteps constructs the steps to be executed in the setup process.
|
||||
func (e *EmbeddedDockerOrchestrator) buildSetupSteps(
|
||||
_ context.Context,
|
||||
ideService ide.IDE,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
resolvedRepoDetails scm.ResolvedDetails,
|
||||
defaultBaseImage string,
|
||||
environment []string,
|
||||
devcontainerConfig types.DevcontainerConfig,
|
||||
codeRepoDir string,
|
||||
) []gitspaceTypes.Step {
|
||||
return []gitspaceTypes.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)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Set environment",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return SetEnv(ctx, exec, gitspaceLogger, environment)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Install Tools",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return InstallTools(ctx, exec, gitspaceLogger, gitspaceConfig.IDE)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Setup IDE",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return SetupIDE(ctx, exec, ideService, gitspaceLogger)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Run IDE",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return RunIDE(ctx, exec, ideService, gitspaceLogger)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Install Git",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return InstallGit(ctx, exec, e.gitService, gitspaceLogger)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Setup Git Credentials",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
if resolvedRepoDetails.ResolvedCredentials.Credentials != nil {
|
||||
return SetupGitCredentials(ctx, exec, resolvedRepoDetails, e.gitService, gitspaceLogger)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
{
|
||||
Name: "Clone Code",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
return CloneCode(ctx, exec, defaultBaseImage, resolvedRepoDetails, e.gitService, gitspaceLogger)
|
||||
},
|
||||
StopOnFailure: true,
|
||||
},
|
||||
// Post-create and Post-start steps
|
||||
{
|
||||
Name: "Execute PostCreate Command",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
command := ExtractLifecycleCommands(PostCreateAction, devcontainerConfig)
|
||||
return ExecuteCommands(ctx, exec, codeRepoDir, gitspaceLogger, command, PostCreateAction)
|
||||
},
|
||||
StopOnFailure: false,
|
||||
},
|
||||
{
|
||||
Name: "Execute PostStart Command",
|
||||
Execute: func(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
) error {
|
||||
command := ExtractLifecycleCommands(PostStartAction, devcontainerConfig)
|
||||
return ExecuteCommands(ctx, exec, codeRepoDir, gitspaceLogger, command, PostStartAction)
|
||||
},
|
||||
StopOnFailure: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// setupGitspaceAndIDE initializes Gitspace and IDE by registering and executing the setup steps.
|
||||
func (e *EmbeddedDockerOrchestrator) setupGitspaceAndIDE(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
ideService ide.IDE,
|
||||
gitspaceConfig types.GitspaceConfig,
|
||||
resolvedRepoDetails scm.ResolvedDetails,
|
||||
defaultBaseImage string,
|
||||
environment []string,
|
||||
) error {
|
||||
homeDir := GetUserHomeDir(gitspaceConfig.GitspaceUser.Identifier)
|
||||
devcontainerConfig := resolvedRepoDetails.DevcontainerConfig
|
||||
codeRepoDir := filepath.Join(homeDir, resolvedRepoDetails.RepoName)
|
||||
|
||||
steps := e.buildSetupSteps(
|
||||
ctx,
|
||||
ideService,
|
||||
gitspaceConfig,
|
||||
resolvedRepoDetails,
|
||||
defaultBaseImage,
|
||||
environment,
|
||||
devcontainerConfig,
|
||||
codeRepoDir)
|
||||
|
||||
// Execute the registered steps
|
||||
if err := e.ExecuteSteps(ctx, exec, gitspaceLogger, steps); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getDockerClient creates and returns a new Docker client using the factory.
|
||||
func (e *EmbeddedDockerOrchestrator) getDockerClient(
|
||||
ctx context.Context,
|
|
@ -0,0 +1,541 @@
|
|||
// 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 container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func getHostResources(runArgsMap map[types.RunArg]*types.RunArgValue) (container.Resources, error) { // nolint: gocognit
|
||||
var resources = container.Resources{}
|
||||
blkioWeight, err := getArgValueUint16(runArgsMap, types.RunArgBlkioWeight)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.BlkioWeight = blkioWeight
|
||||
|
||||
cpuShares, err := getArgValueInt64(runArgsMap, types.RunArgCPUShares)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.CPUShares = cpuShares
|
||||
|
||||
memory, err := getArgValueMemoryBytes(runArgsMap, types.RunArgMemory)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.Memory = memory
|
||||
|
||||
cpus, err := getCPUs(runArgsMap, types.RunArgCpus)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.NanoCPUs = cpus
|
||||
|
||||
resources.CgroupParent = getArgValueString(runArgsMap, types.RunArgCgroupParent)
|
||||
|
||||
cpuPeriod, err := getArgValueInt64(runArgsMap, types.RunArgCPUPeriod)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.CPUPeriod = cpuPeriod
|
||||
|
||||
cpuQuota, err := getArgValueInt64(runArgsMap, types.RunArgCPUQuota)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.CPUQuota = cpuQuota
|
||||
|
||||
cpuRTPeriod, err := getArgValueInt64(runArgsMap, types.RunArgCPURtPeriod)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.CPURealtimePeriod = cpuRTPeriod
|
||||
|
||||
cpuRTRuntime, err := getArgValueInt64(runArgsMap, types.RunArgCPURtRuntime)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.CPURealtimeRuntime = cpuRTRuntime
|
||||
|
||||
resources.CpusetCpus = getArgValueString(runArgsMap, types.RunArgCpusetCpus)
|
||||
|
||||
resources.CpusetMems = getArgValueString(runArgsMap, types.RunArgCpusetMems)
|
||||
|
||||
cpuCount, err := getArgValueInt64(runArgsMap, types.RunArgCPUCount)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.CPUCount = cpuCount
|
||||
|
||||
cpuPercent, err := getArgValueInt64(runArgsMap, types.RunArgCPUPercent)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.CPUPercent = cpuPercent
|
||||
|
||||
kernelMemory, err := getArgValueMemoryBytes(runArgsMap, types.RunArgKernelMemory)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.KernelMemory = kernelMemory
|
||||
|
||||
memoryReservation, err := getArgValueMemoryBytes(runArgsMap, types.RunArgMemoryReservation)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.MemoryReservation = memoryReservation
|
||||
|
||||
memorySwappiness, err := getArgValueInt64Ptr(runArgsMap, types.RunArgMemorySwappiness)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.MemorySwappiness = memorySwappiness
|
||||
|
||||
memorySwap, err := getArgValueMemorySwapBytes(runArgsMap, types.RunArgMemorySwap)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.MemorySwap = memorySwap
|
||||
|
||||
resources.OomKillDisable = getArgValueBoolPtr(runArgsMap, types.RunArgOomKillDisable)
|
||||
|
||||
pidsLimit, err := getArgValueInt64Ptr(runArgsMap, types.RunArgPidsLimit)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.PidsLimit = pidsLimit
|
||||
|
||||
ioMaxiops, err := getArgValueUint64(runArgsMap, types.RunArgIoMaxiops)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.IOMaximumIOps = ioMaxiops
|
||||
|
||||
ioMaxbandwidth, err := getArgValueMemoryBytes(runArgsMap, types.RunArgIoMaxbandwidth)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
resources.IOMaximumBandwidth = uint64(ioMaxbandwidth)
|
||||
|
||||
if arg, ok := runArgsMap[types.RunArgUlimit]; ok {
|
||||
ulimits := []*container.Ulimit{}
|
||||
for _, v := range arg.Values {
|
||||
ulimit, err := units.ParseUlimit(v)
|
||||
if err != nil {
|
||||
return resources, err
|
||||
}
|
||||
ulimits = append(ulimits, ulimit)
|
||||
}
|
||||
resources.Ulimits = ulimits
|
||||
}
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
func getNetworkMode(runArgsMap map[types.RunArg]*types.RunArgValue) container.NetworkMode {
|
||||
return container.NetworkMode(getArgValueString(runArgsMap, types.RunArgNetwork))
|
||||
}
|
||||
|
||||
func getCapDrop(runArgsMap map[types.RunArg]*types.RunArgValue) strslice.StrSlice {
|
||||
return getArgValueStringSlice(runArgsMap, types.RunArgCapDrop)
|
||||
}
|
||||
|
||||
func getSHMSize(runArgsMap map[types.RunArg]*types.RunArgValue) (int64, error) {
|
||||
return getArgValueMemoryBytes(runArgsMap, types.RunArgShmSize)
|
||||
}
|
||||
|
||||
func getArgValueMemorySwapBytes(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) (int64, error) {
|
||||
value := getArgValueString(runArgsMap, argName)
|
||||
if value == "" {
|
||||
return 0, nil
|
||||
}
|
||||
if value == "-1" {
|
||||
return -1, nil
|
||||
}
|
||||
memorySwapBytes, err := units.RAMInBytes(value)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return memorySwapBytes, nil
|
||||
}
|
||||
|
||||
func getSysctls(runArgsMap map[types.RunArg]*types.RunArgValue) map[string]string {
|
||||
values := getArgValueStringSlice(runArgsMap, types.RunArgSysctl)
|
||||
var opt = map[string]string{}
|
||||
for _, value := range values {
|
||||
parts := strings.SplitN(value, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
parts = append(parts, "")
|
||||
}
|
||||
opt[parts[0]] = parts[1]
|
||||
}
|
||||
return opt
|
||||
}
|
||||
|
||||
func getDNS(runArgsMap map[types.RunArg]*types.RunArgValue) []string {
|
||||
return getArgValueStringSlice(runArgsMap, types.RunArgDNS)
|
||||
}
|
||||
|
||||
func getDNSOptions(runArgsMap map[types.RunArg]*types.RunArgValue) []string {
|
||||
return getArgValueStringSlice(runArgsMap, types.RunArgDNSOption)
|
||||
}
|
||||
|
||||
func getDNSSearch(runArgsMap map[types.RunArg]*types.RunArgValue) []string {
|
||||
return getArgValueStringSlice(runArgsMap, types.RunArgDNSSearch)
|
||||
}
|
||||
|
||||
func getCgroupNSMode(runArgsMap map[types.RunArg]*types.RunArgValue) container.CgroupnsMode {
|
||||
value := getArgValueString(runArgsMap, types.RunArgCgroupns)
|
||||
return container.CgroupnsMode(value)
|
||||
}
|
||||
|
||||
func getIPCMode(runArgsMap map[types.RunArg]*types.RunArgValue) container.IpcMode {
|
||||
return container.IpcMode(getArgValueString(runArgsMap, types.RunArgIpc))
|
||||
}
|
||||
|
||||
func getIsolation(runArgsMap map[types.RunArg]*types.RunArgValue) container.Isolation {
|
||||
return container.Isolation(getArgValueString(runArgsMap, types.RunArgIsolation))
|
||||
}
|
||||
|
||||
func getRuntime(runArgsMap map[types.RunArg]*types.RunArgValue) string {
|
||||
return getArgValueString(runArgsMap, types.RunArgRuntime)
|
||||
}
|
||||
|
||||
func getPlatform(runArgsMap map[types.RunArg]*types.RunArgValue) string {
|
||||
return getArgValueString(runArgsMap, types.RunArgPlatform)
|
||||
}
|
||||
|
||||
func getPIDMode(runArgsMap map[types.RunArg]*types.RunArgValue) container.PidMode {
|
||||
return container.PidMode(getArgValueString(runArgsMap, types.RunArgPid))
|
||||
}
|
||||
|
||||
func getSecurityOpt(runArgsMap map[types.RunArg]*types.RunArgValue) []string {
|
||||
return getArgValueStringSlice(runArgsMap, types.RunArgSecurityOpt)
|
||||
}
|
||||
|
||||
func getStorageOpt(runArgsMap map[types.RunArg]*types.RunArgValue) map[string]string {
|
||||
values := getArgValueStringSlice(runArgsMap, types.RunArgStorageOpt)
|
||||
var opt = map[string]string{}
|
||||
for _, value := range values {
|
||||
parts := strings.SplitN(value, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
parts = append(parts, "")
|
||||
}
|
||||
opt[parts[0]] = parts[1]
|
||||
}
|
||||
return opt
|
||||
}
|
||||
|
||||
func getAutoRemove(runArgsMap map[types.RunArg]*types.RunArgValue) bool {
|
||||
return getArgValueBool(runArgsMap, types.RunArgRm)
|
||||
}
|
||||
|
||||
func getInit(runArgsMap map[types.RunArg]*types.RunArgValue) *bool {
|
||||
return getArgValueBoolPtr(runArgsMap, types.RunArgInit)
|
||||
}
|
||||
|
||||
func getEnv(runArgsMap map[types.RunArg]*types.RunArgValue) []string {
|
||||
return getArgValueStringSlice(runArgsMap, types.RunArgEnv)
|
||||
}
|
||||
|
||||
func getLinks(runArgsMap map[types.RunArg]*types.RunArgValue) []string {
|
||||
return getArgValueStringSlice(runArgsMap, types.RunArgLink)
|
||||
}
|
||||
|
||||
func getOomScoreAdj(runArgsMap map[types.RunArg]*types.RunArgValue) (int, error) {
|
||||
return getArgValueInt(runArgsMap, types.RunArgOomScoreAdj)
|
||||
}
|
||||
|
||||
func getRestartPolicy(runArgsMap map[types.RunArg]*types.RunArgValue) (container.RestartPolicy, error) {
|
||||
value := getArgValueString(runArgsMap, types.RunArgRestart)
|
||||
if len(value) == 0 {
|
||||
return container.RestartPolicy{}, nil
|
||||
}
|
||||
parts := strings.SplitN(value, ":", 2)
|
||||
maxCount := 0
|
||||
if container.RestartPolicyMode(parts[0]) == container.RestartPolicyOnFailure && len(parts) == 2 {
|
||||
count, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return container.RestartPolicy{}, err
|
||||
}
|
||||
maxCount = count
|
||||
}
|
||||
return container.RestartPolicy{
|
||||
Name: container.RestartPolicyMode(parts[0]),
|
||||
MaximumRetryCount: maxCount,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getExtraHosts(runArgsMap map[types.RunArg]*types.RunArgValue) []string {
|
||||
return getArgValueStringSlice(runArgsMap, types.RunArgAddHost)
|
||||
}
|
||||
|
||||
func getHostname(runArgsMap map[types.RunArg]*types.RunArgValue) string {
|
||||
return getArgValueString(runArgsMap, types.RunArgHostname)
|
||||
}
|
||||
|
||||
func getDomainname(runArgsMap map[types.RunArg]*types.RunArgValue) string {
|
||||
return getArgValueString(runArgsMap, types.RunArgDomainname)
|
||||
}
|
||||
|
||||
func getMACAddress(runArgsMap map[types.RunArg]*types.RunArgValue) string {
|
||||
return getArgValueString(runArgsMap, types.RunArgMacAddress)
|
||||
}
|
||||
|
||||
func getStopSignal(runArgsMap map[types.RunArg]*types.RunArgValue) string {
|
||||
return getArgValueString(runArgsMap, types.RunArgStopSignal)
|
||||
}
|
||||
|
||||
func getStopTimeout(runArgsMap map[types.RunArg]*types.RunArgValue) (*int, error) {
|
||||
return getArgValueIntPtr(runArgsMap, types.RunArgStopTimeout)
|
||||
}
|
||||
|
||||
func getImagePullPolicy(runArgsMap map[types.RunArg]*types.RunArgValue) string {
|
||||
policy := getArgValueString(runArgsMap, types.RunArgPull)
|
||||
if policy == "" {
|
||||
policy = "missing"
|
||||
}
|
||||
return policy
|
||||
}
|
||||
|
||||
func getUser(runArgsMap map[types.RunArg]*types.RunArgValue) string {
|
||||
return getArgValueString(runArgsMap, types.RunArgUser)
|
||||
}
|
||||
|
||||
func getEntrypoint(runArgsMap map[types.RunArg]*types.RunArgValue) []string {
|
||||
return getArgValueStringSlice(runArgsMap, types.RunArgEntrypoint)
|
||||
}
|
||||
|
||||
func getHealthCheckConfig(runArgsMap map[types.RunArg]*types.RunArgValue) (*container.HealthConfig, error) {
|
||||
var healthConfig = &container.HealthConfig{}
|
||||
|
||||
retries, err := getArgValueInt(runArgsMap, types.RunArgHealthRetries)
|
||||
if err != nil {
|
||||
return healthConfig, err
|
||||
}
|
||||
healthConfig.Retries = retries
|
||||
|
||||
interval, err := getArgValueDuration(runArgsMap, types.RunArgHealthInterval)
|
||||
if err != nil {
|
||||
return healthConfig, err
|
||||
}
|
||||
healthConfig.Interval = interval
|
||||
|
||||
timeout, err := getArgValueDuration(runArgsMap, types.RunArgHealthTimeout)
|
||||
if err != nil {
|
||||
return healthConfig, err
|
||||
}
|
||||
healthConfig.Timeout = timeout
|
||||
|
||||
startPeriod, err := getArgValueDuration(runArgsMap, types.RunArgHealthStartPeriod)
|
||||
if err != nil {
|
||||
return healthConfig, err
|
||||
}
|
||||
healthConfig.StartPeriod = startPeriod
|
||||
|
||||
startInterval, err := getArgValueDuration(runArgsMap, types.RunArgHealthStartInterval)
|
||||
if err != nil {
|
||||
return healthConfig, err
|
||||
}
|
||||
healthConfig.StartInterval = startInterval
|
||||
|
||||
if _, ok := runArgsMap[types.RunArgNoHealthcheck]; ok {
|
||||
healthConfig.Test = []string{"NONE"}
|
||||
} else if arg, healthCmdOK := runArgsMap[types.RunArgHealthCmd]; healthCmdOK {
|
||||
healthConfig.Test = arg.Values
|
||||
}
|
||||
|
||||
return healthConfig, nil
|
||||
}
|
||||
|
||||
func getLabels(runArgsMap map[types.RunArg]*types.RunArgValue) map[string]string {
|
||||
arg, ok := runArgsMap[types.RunArgLabel]
|
||||
labelsMap := make(map[string]string)
|
||||
if ok {
|
||||
labels := arg.Values
|
||||
for _, v := range labels {
|
||||
parts := strings.SplitN(v, "=", 2)
|
||||
if len(parts) < 2 {
|
||||
labelsMap[parts[0]] = ""
|
||||
} else {
|
||||
labelsMap[parts[0]] = parts[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return labelsMap
|
||||
}
|
||||
|
||||
func getAnnotations(runArgsMap map[types.RunArg]*types.RunArgValue) map[string]string {
|
||||
arg, ok := runArgsMap[types.RunArgAnnotation]
|
||||
annotationsMap := make(map[string]string)
|
||||
if ok {
|
||||
annotations := arg.Values
|
||||
for _, v := range annotations {
|
||||
annotationParts := strings.SplitN(v, "=", 2)
|
||||
if len(annotationParts) != 2 {
|
||||
log.Warn().Msgf("invalid annotation: %s", v)
|
||||
} else {
|
||||
annotationsMap[annotationParts[0]] = annotationParts[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return annotationsMap
|
||||
}
|
||||
|
||||
func getArgValueMemoryBytes(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) (int64, error) {
|
||||
value := getArgValueString(runArgsMap, argName)
|
||||
if value == "" {
|
||||
return 0, nil
|
||||
}
|
||||
memoryBytes, err := units.RAMInBytes(value)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return memoryBytes, nil
|
||||
}
|
||||
|
||||
func getArgValueString(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) string {
|
||||
if arg, ok := runArgsMap[argName]; ok {
|
||||
return arg.Values[0]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getArgValueStringSlice(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) []string {
|
||||
if arg, ok := runArgsMap[argName]; ok {
|
||||
return arg.Values
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func getArgValueInt(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) (int, error) {
|
||||
value, err := getArgValueIntPtr(runArgsMap, argName)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if value == nil {
|
||||
return 0, nil
|
||||
}
|
||||
return *value, nil
|
||||
}
|
||||
|
||||
func getArgValueIntPtr(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) (*int, error) {
|
||||
if arg, ok := runArgsMap[argName]; ok {
|
||||
value, err := strconv.Atoi(arg.Values[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &value, nil
|
||||
}
|
||||
return nil, nil // nolint: nilnil
|
||||
}
|
||||
|
||||
func getArgValueUint16(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) (uint16, error) {
|
||||
if arg, ok := runArgsMap[argName]; ok {
|
||||
value, err := strconv.ParseUint(arg.Values[0], 10, 16)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint16(value), nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func getArgValueUint64(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) (uint64, error) {
|
||||
if arg, ok := runArgsMap[argName]; ok {
|
||||
value, err := strconv.ParseUint(arg.Values[0], 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func getCPUs(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) (int64, error) {
|
||||
if arg, ok := runArgsMap[argName]; ok {
|
||||
value := arg.Values[0]
|
||||
cpu, ok1 := new(big.Rat).SetString(value) // nolint: gosec
|
||||
if !ok1 {
|
||||
return 0, fmt.Errorf("failed to parse %v as a rational number", value)
|
||||
}
|
||||
nano := cpu.Mul(cpu, big.NewRat(1e9, 1))
|
||||
if !nano.IsInt() {
|
||||
return 0, fmt.Errorf("value is too precise")
|
||||
}
|
||||
return nano.Num().Int64(), nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func getArgValueInt64(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) (int64, error) {
|
||||
value, err := getArgValueInt64Ptr(runArgsMap, argName)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if value == nil {
|
||||
return 0, nil
|
||||
}
|
||||
return *value, nil
|
||||
}
|
||||
|
||||
func getArgValueInt64Ptr(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) (*int64, error) {
|
||||
if arg, ok := runArgsMap[argName]; ok {
|
||||
value, err := strconv.ParseInt(arg.Values[0], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &value, nil
|
||||
}
|
||||
return nil, nil // nolint: nilnil
|
||||
}
|
||||
|
||||
func getArgValueDuration(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) (time.Duration, error) {
|
||||
defaultDur := time.Second * 0
|
||||
if arg, ok := runArgsMap[argName]; ok {
|
||||
dur, err := time.ParseDuration(arg.Values[0])
|
||||
if err != nil {
|
||||
return defaultDur, err
|
||||
}
|
||||
return dur, nil
|
||||
}
|
||||
return defaultDur, nil
|
||||
}
|
||||
|
||||
func getArgValueBool(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) bool {
|
||||
value := getArgValueBoolPtr(runArgsMap, argName)
|
||||
if value == nil {
|
||||
return false
|
||||
}
|
||||
return *value
|
||||
}
|
||||
func getArgValueBoolPtr(runArgsMap map[types.RunArg]*types.RunArgValue, argName types.RunArg) *bool {
|
||||
_, ok := runArgsMap[argName]
|
||||
if ok {
|
||||
return &ok
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -17,6 +17,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"
|
||||
|
||||
|
@ -32,11 +33,13 @@ func ProvideEmbeddedDockerOrchestrator(
|
|||
statefulLogger *logutil.StatefulLogger,
|
||||
gitService git.Service,
|
||||
userService user.Service,
|
||||
runArgProvdier runarg.Provider,
|
||||
) Orchestrator {
|
||||
return NewEmbeddedDockerOrchestrator(
|
||||
dockerClientFactory,
|
||||
statefulLogger,
|
||||
gitService,
|
||||
userService,
|
||||
runArgProvdier,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// 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 runarg
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
)
|
||||
|
||||
type Provider interface {
|
||||
// ProvideSupportedRunArgs returns a map of the run arg definitions for all the supported arg applicable for the
|
||||
// given gitspace spaceID.
|
||||
ProvideSupportedRunArgs(ctx context.Context, spaceID int64) (map[types.RunArg]types.RunArgDefinition, error)
|
||||
}
|
|
@ -0,0 +1,727 @@
|
|||
---
|
||||
- name: --add-host
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: {}
|
||||
allowed_values: {}
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --annotation
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: {}
|
||||
allowed_values: {}
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --attach
|
||||
short_hand: -a
|
||||
supported: false
|
||||
blocked_values: {}
|
||||
allowed_values: {}
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --blkio-weight
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: {}
|
||||
allowed_values: {}
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --blkio-weight-device
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: {}
|
||||
allowed_values: {}
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --cap-add
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --cap-drop
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --cgroup-parent
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cgroupns
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cidfile
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --cpu-count
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cpu-percent
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cpu-period
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cpu-quota
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cpu-rt-period
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cpu-rt-runtime
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cpu-shares
|
||||
short_hand: -c
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cpus
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cpuset-cpus
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --cpuset-mems
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --detach
|
||||
short_hand: -d
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --detach-keys
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --device
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --device-cgroup-rule
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --device-read-bps
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --device-read-iops
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --device-write-bps
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --device-write-iops
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --disable-content-trust
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --dns
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --dns-option
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --dns-search
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --domainname
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --entrypoint
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --env
|
||||
short_hand: -e
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --env-file
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --expose
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --gpus
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --group-add
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --health-cmd
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --health-interval
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --health-retries
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --health-start-interval
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --health-start-period
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --health-timeout
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --help
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --hostname
|
||||
short_hand: -h
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --init
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --interactive
|
||||
short_hand: -i
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --io-maxbandwidth
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --io-maxiops
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --ip
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --ip6
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --ipc
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --isolation
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --kernel-memory
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --label
|
||||
short_hand: -l
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --label-file
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: {}
|
||||
allowed_values: {}
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --link
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --link-local-ip
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --log-driver
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --log-opt
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --mac-address
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --memory
|
||||
short_hand: -m
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --memory-reservation
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --memory-swap
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --memory-swappiness
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --mount
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --name
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --network
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values:
|
||||
host: true
|
||||
none: true
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --network-alias
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --no-healthcheck
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --oom-kill-disable
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --oom-score-adj
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --pid
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --pids-limit
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --platform
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --privileged
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --publish
|
||||
short_hand: -p
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --publish-all
|
||||
short_hand: -P
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --pull
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --quiet
|
||||
short_hand: -q
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --read-only
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --restart
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --rm
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
|
||||
- name: --runtime
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --security-opt
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --shm-size
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --sig-proxy
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --stop-signal
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --stop-timeout
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
- name: --storage-opt
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --sysctl
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --tmpfs
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --tty
|
||||
short_hand: -t
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --ulimit
|
||||
short_hand:
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
|
||||
- name: --user
|
||||
short_hand: -u
|
||||
supported: true
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: false
|
||||
|
||||
|
||||
- name: --userns
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
|
||||
- name: --uts
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --volume
|
||||
short_hand: -v
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --volume-driver
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --volumes-from
|
||||
short_hand:
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
||||
|
||||
- name: --workdir
|
||||
short_hand: -w
|
||||
supported: false
|
||||
blocked_values: { }
|
||||
allowed_values: { }
|
||||
allow_multiple_occurrences: true
|
|
@ -0,0 +1,61 @@
|
|||
// 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 runarg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/types"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
var _ Provider = (*StaticProvider)(nil)
|
||||
|
||||
//go:embed runArgs.yaml
|
||||
var supportedRunArgsRaw []byte
|
||||
|
||||
type StaticProvider struct {
|
||||
supportedRunArgsMap map[types.RunArg]types.RunArgDefinition
|
||||
}
|
||||
|
||||
func NewStaticProvider() (Provider, error) {
|
||||
allRunArgs := make([]types.RunArgDefinition, 0)
|
||||
err := yaml.Unmarshal(supportedRunArgsRaw, &allRunArgs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal runArgs.yaml: %w", err)
|
||||
}
|
||||
argsMap := make(map[types.RunArg]types.RunArgDefinition)
|
||||
for _, arg := range allRunArgs {
|
||||
if arg.Supported {
|
||||
argsMap[arg.Name] = arg
|
||||
if arg.ShortHand != "" {
|
||||
argsMap[arg.ShortHand] = arg
|
||||
}
|
||||
}
|
||||
}
|
||||
return &StaticProvider{supportedRunArgsMap: argsMap}, nil
|
||||
}
|
||||
|
||||
// ProvideSupportedRunArgs provides a static map of supported run args.
|
||||
func (s *StaticProvider) ProvideSupportedRunArgs(
|
||||
_ context.Context,
|
||||
_ int64,
|
||||
) (map[types.RunArg]types.RunArgDefinition, error) {
|
||||
return s.supportedRunArgsMap, nil
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// 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 runarg
|
||||
|
||||
import (
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
var WireSet = wire.NewSet(
|
||||
ProvideStaticProvider,
|
||||
)
|
||||
|
||||
func ProvideStaticProvider() (Provider, error) {
|
||||
return NewStaticProvider()
|
||||
}
|
|
@ -66,6 +66,7 @@ import (
|
|||
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"
|
||||
|
@ -281,6 +282,7 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
|
|||
containerGit.WireSet,
|
||||
containerUser.WireSet,
|
||||
messagingservice.WireSet,
|
||||
runarg.WireSet,
|
||||
)
|
||||
return &cliserver.System{}, nil
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ import (
|
|||
"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"
|
||||
|
@ -318,7 +319,11 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||
statefulLogger := logutil.ProvideStatefulLogger(logStream)
|
||||
gitService := git2.ProvideGitServiceImpl()
|
||||
userService := user2.ProvideUserServiceImpl()
|
||||
containerOrchestrator := container.ProvideEmbeddedDockerOrchestrator(dockerClientFactory, statefulLogger, gitService, userService)
|
||||
runargProvider, err := runarg.ProvideStaticProvider()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
containerOrchestrator := container.ProvideEmbeddedDockerOrchestrator(dockerClientFactory, statefulLogger, gitService, userService, runargProvider)
|
||||
orchestratorConfig := server.ProvideGitspaceOrchestratorConfig(config)
|
||||
vsCodeConfig := server.ProvideIDEVSCodeConfig(config)
|
||||
vsCode := ide.ProvideVSCodeService(vsCodeConfig)
|
||||
|
|
|
@ -27,6 +27,7 @@ type DevcontainerConfig struct {
|
|||
ForwardPorts []json.Number `json:"forwardPorts"` //nolint:tagliatelle
|
||||
ContainerEnv map[string]string `json:"containerEnv"` //nolint:tagliatelle
|
||||
Customizations DevContainerConfigCustomizations `json:"customizations"`
|
||||
RunArgs []string `json:"runArgs"` //nolint:tagliatelle
|
||||
}
|
||||
|
||||
// LifecycleCommand supports multiple formats for lifecycle commands.
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
// 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 (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RunArg string
|
||||
|
||||
const (
|
||||
RunArgAddHost = RunArg("--add-host")
|
||||
RunArgAnnotation = RunArg("--annotation")
|
||||
RunArgBlkioWeight = RunArg("--blkio-weight")
|
||||
RunArgCapDrop = RunArg("--cap-drop")
|
||||
RunArgCgroupParent = RunArg("--cgroup-parent")
|
||||
RunArgCgroupns = RunArg("--cgroupns")
|
||||
RunArgCPUCount = RunArg("--cpu-count")
|
||||
RunArgCPUPercent = RunArg("--cpu-percent")
|
||||
RunArgCPUPeriod = RunArg("--cpu-period")
|
||||
RunArgCPUQuota = RunArg("--cpu-quota")
|
||||
RunArgCPURtPeriod = RunArg("--cpu-rt-period")
|
||||
RunArgCPURtRuntime = RunArg("--cpu-rt-runtime")
|
||||
RunArgCPUShares = RunArg("--cpu-shares")
|
||||
RunArgCpus = RunArg("--cpus")
|
||||
RunArgCpusetCpus = RunArg("--cpuset-cpus")
|
||||
RunArgCpusetMems = RunArg("--cpuset-mems")
|
||||
RunArgDNS = RunArg("--dns")
|
||||
RunArgDNSOption = RunArg("--dns-option")
|
||||
RunArgDNSSearch = RunArg("--dns-search")
|
||||
RunArgDomainname = RunArg("--domainname")
|
||||
RunArgEntrypoint = RunArg("--entrypoint")
|
||||
RunArgEnv = RunArg("--env")
|
||||
RunArgHealthCmd = RunArg("--health-cmd")
|
||||
RunArgHealthInterval = RunArg("--health-interval")
|
||||
RunArgHealthRetries = RunArg("--health-retries")
|
||||
RunArgHealthStartInterval = RunArg("--health-start-interval")
|
||||
RunArgHealthStartPeriod = RunArg("--health-start-period")
|
||||
RunArgHealthTimeout = RunArg("--health-timeout")
|
||||
RunArgHostname = RunArg("--hostname")
|
||||
RunArgInit = RunArg("--init")
|
||||
RunArgIoMaxbandwidth = RunArg("--io-maxbandwidth")
|
||||
RunArgIoMaxiops = RunArg("--io-maxiops")
|
||||
RunArgIpc = RunArg("--ipc")
|
||||
RunArgIsolation = RunArg("--isolation")
|
||||
RunArgKernelMemory = RunArg("--kernel-memory")
|
||||
RunArgLabel = RunArg("--label")
|
||||
RunArgLink = RunArg("--link")
|
||||
RunArgMacAddress = RunArg("--mac-address")
|
||||
RunArgMemory = RunArg("--memory")
|
||||
RunArgMemoryReservation = RunArg("--memory-reservation")
|
||||
RunArgMemorySwap = RunArg("--memory-swap")
|
||||
RunArgMemorySwappiness = RunArg("--memory-swappiness")
|
||||
RunArgNetwork = RunArg("--network")
|
||||
RunArgNoHealthcheck = RunArg("--no-healthcheck")
|
||||
RunArgOomKillDisable = RunArg("--oom-kill-disable")
|
||||
RunArgOomScoreAdj = RunArg("--oom-score-adj")
|
||||
RunArgPid = RunArg("--pid")
|
||||
RunArgPidsLimit = RunArg("--pids-limit")
|
||||
RunArgPlatform = RunArg("--platform")
|
||||
RunArgPull = RunArg("--pull")
|
||||
RunArgRestart = RunArg("--restart")
|
||||
RunArgRm = RunArg("--rm")
|
||||
RunArgRuntime = RunArg("--runtime")
|
||||
RunArgSecurityOpt = RunArg("--security-opt")
|
||||
RunArgShmSize = RunArg("--shm-size")
|
||||
RunArgStopSignal = RunArg("--stop-signal")
|
||||
RunArgStopTimeout = RunArg("--stop-timeout")
|
||||
RunArgStorageOpt = RunArg("--storage-opt")
|
||||
RunArgSysctl = RunArg("--sysctl")
|
||||
RunArgUlimit = RunArg("--ulimit")
|
||||
RunArgUser = RunArg("--user")
|
||||
)
|
||||
|
||||
type RunArgDefinition struct {
|
||||
Name RunArg `yaml:"name"`
|
||||
ShortHand RunArg `yaml:"short_hand"`
|
||||
Supported bool `yaml:"supported"`
|
||||
BlockedValues map[string]bool `yaml:"blocked_values"`
|
||||
AllowedValues map[string]bool `yaml:"allowed_values"`
|
||||
AllowMultipleOccurences bool `yaml:"allow_multiple_occurrences"`
|
||||
}
|
||||
|
||||
type RunArgValue struct {
|
||||
Name RunArg
|
||||
Values []string
|
||||
}
|
||||
|
||||
func (c *RunArgValue) String() string {
|
||||
return strings.Join(c.Values, ", ")
|
||||
}
|
Loading…
Reference in New Issue