Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added alessio/shellescape and changed prepareEnvs to use envfile #29

Merged
merged 1 commit into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22
toolchain go1.22.4

require (
al.essio.dev/pkg/shellescape v1.5.0
github.com/alexellis/go-execute v0.6.0
github.com/containerd/containerd v1.7.6
github.com/intertwin-eu/interlink v0.0.0-20240829090340-24c45973f3ec
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
al.essio.dev/pkg/shellescape v1.5.0 h1:7oTvSsQ5kg9WksA9O58y9wjYnY4jP0CL82/Q8WLUGKk=
al.essio.dev/pkg/shellescape v1.5.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
github.com/alexellis/go-execute v0.6.0 h1:FVGoudJnWSObwf9qmehbvVuvhK6g1UpKOCBjS+OUXEA=
github.com/alexellis/go-execute v0.6.0/go.mod h1:nlg2F6XdYydUm1xXQMMiuibQCV1mveybBkNWfdNznjk=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
Expand Down
2 changes: 1 addition & 1 deletion pkg/slurm/Create.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (h *SidecarHandler) SubmitHandler(w http.ResponseWriter, r *http.Request) {

commstr1 := []string{"singularity", "exec", "--containall", "--nv", singularityMounts, singularityOptions}

envs := prepareEnvs(spanCtx, container)
envs := prepareEnvs(spanCtx, h.Config, data, container)
image := ""

CPULimit, _ := container.Resources.Limits.Cpu().AsInt64()
Expand Down
80 changes: 62 additions & 18 deletions pkg/slurm/prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"strings"
"time"

"al.essio.dev/pkg/shellescape"
exec2 "github.com/alexellis/go-execute/pkg/v1"
"github.com/containerd/containerd/log"
v1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -184,36 +185,79 @@ func (h *SidecarHandler) LoadJIDs() error {
return nil
}

// prepareEnvs reads all Environment variables from a container and append them to a slice of strings.
// It returns the slice containing all envs in the form of key=value.
func prepareEnvs(Ctx context.Context, container v1.Container) []string {
func createEnvFile(Ctx context.Context, config SlurmConfig, podData commonIL.RetrievedPodData, container v1.Container) ([]string, []string, error) {
envs := []string{}
// For debugging purpose only
envs_data := []string{}

envfilePath := (config.DataRootFolder + podData.Pod.Namespace + "-" + string(podData.Pod.UID) + "/" + "envfile.properties")
log.G(Ctx).Info("-- Appending envs using envfile " + envfilePath)
envs = append(envs, "--env-file")
envs = append(envs, envfilePath)

envfile, err := os.Create(envfilePath)
if err != nil {
log.G(Ctx).Error(err)
return nil, nil, err
}
defer envfile.Close()

for _, envVar := range container.Env {
// The environment variable values can contains all sort of simple/double quote and space and any arbitrary values.
// singularity reads the env-file and parse it like a bash string, so shellescape will escape any quote properly.
tmpValue := shellescape.Quote(envVar.Value)
tmp := (envVar.Name + "=" + tmpValue)

envs_data = append(envs_data, tmp)

_, err := envfile.WriteString(tmp + "\n")
if err != nil {
log.G(Ctx).Error(err)
return nil, nil, err
} else {
log.G(Ctx).Debug("---- Written envfile file " + envfilePath + " key " + envVar.Name + " value " + tmpValue)
}
}

// All env variables are written, we flush it now.
err = envfile.Sync()
if err != nil {
log.G(Ctx).Error(err)
return nil, nil, err
}

// Calling Close() in case of error. If not error, the defer will close it again but it should be idempotent.
envfile.Close()

return envs, envs_data, nil
}

// prepareEnvs reads all Environment variables from a container and append them to a envfile.properties. The values are bash-escaped.
// It returns the slice containing, if there are Environment variables, the arguments for envfile and its path, or else an empty array.
func prepareEnvs(Ctx context.Context, config SlurmConfig, podData commonIL.RetrievedPodData, container v1.Container) []string {
start := time.Now().UnixMicro()
span := trace.SpanFromContext(Ctx)
span.AddEvent("Preparing ENVs for container " + container.Name)
var envs []string
var envs []string = []string{}
// For debugging purpose only
envs_data := []string{}
var err error

if len(container.Env) > 0 {
log.G(Ctx).Info("-- Appending envs")
envs = append(envs, "--env")
env_data := ""
for _, envVar := range container.Env {
tmp := (envVar.Name + "=" + envVar.Value + ",")
env_data += tmp
}
if last := len(env_data) - 1; last >= 0 && env_data[last] == ',' {
env_data = env_data[:last]
}
if env_data == "" {
envs = []string{}
envs, envs_data, err = createEnvFile(Ctx, config, podData, container)
if err != nil {
log.G(Ctx).Error(err)
return nil
}
envs = append(envs, env_data)
}

duration := time.Now().UnixMicro() - start
span.AddEvent("Prepared ENVs for container "+container.Name, trace.WithAttributes(
attribute.String("prepareenvs.container.name", container.Name),
attribute.Int64("prepareenvs.duration", duration),
attribute.StringSlice("prepareenvs.container.envs", envs)))
attribute.StringSlice("prepareenvs.container.envs", envs),
attribute.StringSlice("prepareenvs.container.envs_data", envs_data)))

return envs
}

Expand Down