From 43a75885f16ae80edcb84ac38382bbdeeeac1a41 Mon Sep 17 00:00:00 2001 From: Brandon Biggs Date: Sat, 21 Sep 2024 17:47:04 -0600 Subject: [PATCH] feat: adds ability to specify container options in process-compose.yml This introduces several new options in the configuration files. These options are ignored if `is_container` is not set to `true` or if `container_runtime` is not set to apptainer. This could be expanded to allow for other container tools like podman, singularity, docker, etc, but for right now it is just configured with apptainer in mind. The new options include: ``` is_container bool container_runtime string (apptainer, singularity, podman, etc) container_execution string (exec, run, etc) container_volumes []string (Each container runtime has a different way to define volumes, right now I'm only considering apptainer volumes which are defined with a -B/--bind container_image string (full path to .sif or OCI path) container_args []string (additional arguments to pass to the container runtime) ``` --- src/app/process.go | 10 ++++++++++ src/command/command.go | 13 +++++++++++++ src/types/process.go | 6 ++++++ 3 files changed, 29 insertions(+) diff --git a/src/app/process.go b/src/app/process.go index e939c31..a359440 100644 --- a/src/app/process.go +++ b/src/app/process.go @@ -222,6 +222,16 @@ func (p *Process) getCommander() command.Commander { p.procConf.Executable, p.mergeExtraArgs(), ) + } else if p.procConf.IsContainer && strings.ToLower(p.procConf.ContainerRuntime) == "apptainer" { + return command.BuildApptainerCommand( + p.procConf.ContainerRuntime, + p.procConf.ContainerExec, + p.procConf.ContainerVolumes, + p.procConf.ContainerArgs, + p.procConf.ContainerImage, + p.procConf.Executable, + p.mergeExtraArgs(), + ) } else { return command.BuildCommand( p.procConf.Executable, diff --git a/src/command/command.go b/src/command/command.go index c6e7f38..a29c1da 100644 --- a/src/command/command.go +++ b/src/command/command.go @@ -6,6 +6,7 @@ import ( "os" "os/exec" "runtime" + "strings" ) func BuildCommand(cmd string, args []string) *CmdWrapper { @@ -32,6 +33,18 @@ func BuildCommandShellArgContext(ctx context.Context, shell ShellConfig, cmd str } } +func BuildApptainerCommand(containerRuntime string, containerExecution string, containerVolumes []string, containerArgs []string, containerImage string, containerCmd string, cmdArgs []string) *CmdWrapper { + volumes := "-B " + strings.Join(containerVolumes, ",") + container_args := strings.Join(containerArgs, " ") + args_string := strings.Join(cmdArgs, " ") + + args := []string{containerExecution, volumes, container_args, containerImage, containerCmd, args_string} + + return &CmdWrapper{ + cmd: exec.Command(containerRuntime, args...), + } +} + func getRunnerShell() string { shell, ok := os.LookupEnv("COMPOSE_SHELL") if !ok { diff --git a/src/types/process.go b/src/types/process.go index b8b2de4..5c970d2 100644 --- a/src/types/process.go +++ b/src/types/process.go @@ -38,6 +38,12 @@ type ProcessConfig struct { IsForeground bool `yaml:"is_foreground"` IsTty bool `yaml:"is_tty"` IsElevated bool `yaml:"is_elevated"` + IsContainer bool `yaml:"is_container"` + ContainerRuntime string `yaml:"container_runtime"` + ContainerExec string `yaml:"container_execution"` + ContainerVolumes []string `yaml:"container_volumes"` + ContainerImage string `yaml:"container_image"` + ContainerArgs []string `yaml:"container_args"` ReplicaNum int ReplicaName string Executable string