Skip to content

Commit 4484461

Browse files
authored
Merge pull request #29 from antoinetran/fix_envfile_issue27
added alessio/shellescape and changed prepareEnvs to use envfile
2 parents 4e6cd8d + 9ab0b5b commit 4484461

File tree

4 files changed

+66
-19
lines changed

4 files changed

+66
-19
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.22
55
toolchain go1.22.4
66

77
require (
8+
al.essio.dev/pkg/shellescape v1.5.0
89
github.com/alexellis/go-execute v0.6.0
910
github.com/containerd/containerd v1.7.6
1011
github.com/intertwin-eu/interlink v0.0.0-20240829090340-24c45973f3ec

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
al.essio.dev/pkg/shellescape v1.5.0 h1:7oTvSsQ5kg9WksA9O58y9wjYnY4jP0CL82/Q8WLUGKk=
2+
al.essio.dev/pkg/shellescape v1.5.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
13
github.com/alexellis/go-execute v0.6.0 h1:FVGoudJnWSObwf9qmehbvVuvhK6g1UpKOCBjS+OUXEA=
24
github.com/alexellis/go-execute v0.6.0/go.mod h1:nlg2F6XdYydUm1xXQMMiuibQCV1mveybBkNWfdNznjk=
35
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=

pkg/slurm/Create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func (h *SidecarHandler) SubmitHandler(w http.ResponseWriter, r *http.Request) {
8181

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

84-
envs := prepareEnvs(spanCtx, container)
84+
envs := prepareEnvs(spanCtx, h.Config, data, container)
8585
image := ""
8686

8787
CPULimit, _ := container.Resources.Limits.Cpu().AsInt64()

pkg/slurm/prepare.go

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"strings"
1616
"time"
1717

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

187-
// prepareEnvs reads all Environment variables from a container and append them to a slice of strings.
188-
// It returns the slice containing all envs in the form of key=value.
189-
func prepareEnvs(Ctx context.Context, container v1.Container) []string {
188+
func createEnvFile(Ctx context.Context, config SlurmConfig, podData commonIL.RetrievedPodData, container v1.Container) ([]string, []string, error) {
189+
envs := []string{}
190+
// For debugging purpose only
191+
envs_data := []string{}
192+
193+
envfilePath := (config.DataRootFolder + podData.Pod.Namespace + "-" + string(podData.Pod.UID) + "/" + "envfile.properties")
194+
log.G(Ctx).Info("-- Appending envs using envfile " + envfilePath)
195+
envs = append(envs, "--env-file")
196+
envs = append(envs, envfilePath)
197+
198+
envfile, err := os.Create(envfilePath)
199+
if err != nil {
200+
log.G(Ctx).Error(err)
201+
return nil, nil, err
202+
}
203+
defer envfile.Close()
204+
205+
for _, envVar := range container.Env {
206+
// The environment variable values can contains all sort of simple/double quote and space and any arbitrary values.
207+
// singularity reads the env-file and parse it like a bash string, so shellescape will escape any quote properly.
208+
tmpValue := shellescape.Quote(envVar.Value)
209+
tmp := (envVar.Name + "=" + tmpValue)
210+
211+
envs_data = append(envs_data, tmp)
212+
213+
_, err := envfile.WriteString(tmp + "\n")
214+
if err != nil {
215+
log.G(Ctx).Error(err)
216+
return nil, nil, err
217+
} else {
218+
log.G(Ctx).Debug("---- Written envfile file " + envfilePath + " key " + envVar.Name + " value " + tmpValue)
219+
}
220+
}
221+
222+
// All env variables are written, we flush it now.
223+
err = envfile.Sync()
224+
if err != nil {
225+
log.G(Ctx).Error(err)
226+
return nil, nil, err
227+
}
228+
229+
// Calling Close() in case of error. If not error, the defer will close it again but it should be idempotent.
230+
envfile.Close()
231+
232+
return envs, envs_data, nil
233+
}
234+
235+
// prepareEnvs reads all Environment variables from a container and append them to a envfile.properties. The values are bash-escaped.
236+
// It returns the slice containing, if there are Environment variables, the arguments for envfile and its path, or else an empty array.
237+
func prepareEnvs(Ctx context.Context, config SlurmConfig, podData commonIL.RetrievedPodData, container v1.Container) []string {
190238
start := time.Now().UnixMicro()
191239
span := trace.SpanFromContext(Ctx)
192240
span.AddEvent("Preparing ENVs for container " + container.Name)
193-
var envs []string
241+
var envs []string = []string{}
242+
// For debugging purpose only
243+
envs_data := []string{}
244+
var err error
194245

195246
if len(container.Env) > 0 {
196-
log.G(Ctx).Info("-- Appending envs")
197-
envs = append(envs, "--env")
198-
env_data := ""
199-
for _, envVar := range container.Env {
200-
tmp := (envVar.Name + "=" + envVar.Value + ",")
201-
env_data += tmp
202-
}
203-
if last := len(env_data) - 1; last >= 0 && env_data[last] == ',' {
204-
env_data = env_data[:last]
205-
}
206-
if env_data == "" {
207-
envs = []string{}
247+
envs, envs_data, err = createEnvFile(Ctx, config, podData, container)
248+
if err != nil {
249+
log.G(Ctx).Error(err)
250+
return nil
208251
}
209-
envs = append(envs, env_data)
210252
}
211253

212254
duration := time.Now().UnixMicro() - start
213255
span.AddEvent("Prepared ENVs for container "+container.Name, trace.WithAttributes(
214256
attribute.String("prepareenvs.container.name", container.Name),
215257
attribute.Int64("prepareenvs.duration", duration),
216-
attribute.StringSlice("prepareenvs.container.envs", envs)))
258+
attribute.StringSlice("prepareenvs.container.envs", envs),
259+
attribute.StringSlice("prepareenvs.container.envs_data", envs_data)))
260+
217261
return envs
218262
}
219263

0 commit comments

Comments
 (0)