From 8030fb86df36ad04ee4f93418f7a6f99eea4f86e Mon Sep 17 00:00:00 2001 From: Anirudh Oppiliappan Date: Mon, 16 Jun 2025 10:48:20 +0300 Subject: [PATCH] spindle/engine: helpers to convert step.Environment to []string{} and set them Change-Id: pmtpswykplzrymuttzwqllnumvuqvnoz Signed-off-by: Anirudh Oppiliappan --- spindle/engine/engine.go | 6 +++- spindle/engine/envs.go | 32 +++++++++++++++++ spindle/engine/envs_test.go | 70 +++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 spindle/engine/envs.go create mode 100644 spindle/engine/envs_test.go diff --git a/spindle/engine/engine.go b/spindle/engine/engine.go index 4ef6349..b3c04a9 100644 --- a/spindle/engine/engine.go +++ b/spindle/engine/engine.go @@ -203,6 +203,10 @@ func (e *Engine) StartSteps(ctx context.Context, steps []*tangled.Pipeline_Step, }() for _, step := range steps { + envs := ConstructEnvs(step.Environment) + envs.AddEnv("HOME", workspaceDir) + e.l.Debug("envs for step", "step", step.Name, "envs", envs.Slice()) + hostConfig := hostConfig(wid) resp, err := e.docker.ContainerCreate(ctx, &container.Config{ Image: image, @@ -210,7 +214,7 @@ func (e *Engine) StartSteps(ctx context.Context, steps []*tangled.Pipeline_Step, WorkingDir: workspaceDir, Tty: false, Hostname: "spindle", - Env: []string{"HOME=" + workspaceDir}, + Env: envs.Slice(), }, hostConfig, nil, nil, "") if err != nil { return fmt.Errorf("creating container: %w", err) diff --git a/spindle/engine/envs.go b/spindle/engine/envs.go new file mode 100644 index 0000000..bfe6886 --- /dev/null +++ b/spindle/engine/envs.go @@ -0,0 +1,32 @@ +package engine + +import ( + "fmt" + + "tangled.sh/tangled.sh/core/api/tangled" +) + +type EnvVars []string + +// ConstructEnvs converts a tangled.Pipeline_Step_Environment_Elem.{Key,Value} +// representation into a docker-friendly []string{"KEY=value", ...} slice. +func ConstructEnvs(envs []*tangled.Pipeline_Step_Environment_Elem) EnvVars { + var dockerEnvs EnvVars + for _, env := range envs { + if env != nil { + ev := fmt.Sprintf("%s=%s", env.Key, env.Value) + dockerEnvs = append(dockerEnvs, ev) + } + } + return dockerEnvs +} + +// Slice returns the EnvVar as a []string slice. +func (ev EnvVars) Slice() []string { + return ev +} + +// AddEnv adds a key=value string to the EnvVar. +func (ev *EnvVars) AddEnv(key, value string) { + *ev = append(*ev, fmt.Sprintf("%s=%s", key, value)) +} diff --git a/spindle/engine/envs_test.go b/spindle/engine/envs_test.go new file mode 100644 index 0000000..8554a1e --- /dev/null +++ b/spindle/engine/envs_test.go @@ -0,0 +1,70 @@ +package engine + +import ( + "reflect" + "testing" + + "tangled.sh/tangled.sh/core/api/tangled" +) + +func TestConstructEnvs(t *testing.T) { + tests := []struct { + name string + in []*tangled.Pipeline_Step_Environment_Elem + want EnvVars + }{ + { + name: "empty input", + in: []*tangled.Pipeline_Step_Environment_Elem{}, + want: EnvVars{}, + }, + { + name: "single env var", + in: []*tangled.Pipeline_Step_Environment_Elem{ + {Key: "FOO", Value: "bar"}, + }, + want: EnvVars{"FOO=bar"}, + }, + { + name: "multiple env vars", + in: []*tangled.Pipeline_Step_Environment_Elem{ + {Key: "FOO", Value: "bar"}, + {Key: "BAZ", Value: "qux"}, + }, + want: EnvVars{"FOO=bar", "BAZ=qux"}, + }, + { + name: "nil entries are skipped", + in: []*tangled.Pipeline_Step_Environment_Elem{ + nil, + {Key: "FOO", Value: "bar"}, + }, + want: EnvVars{"FOO=bar"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := ConstructEnvs(tt.in) + + if got == nil { + got = EnvVars{} + } + + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConstructEnvs() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestAddEnv(t *testing.T) { + ev := EnvVars{} + ev.AddEnv("FOO", "bar") + ev.AddEnv("BAZ", "qux") + + want := EnvVars{"FOO=bar", "BAZ=qux"} + if !reflect.DeepEqual(ev, want) { + t.Errorf("AddEnv result = %v, want %v", ev, want) + } +} -- 2.43.0