+5
-1
spindle/engine/engine.go
+5
-1
spindle/engine/engine.go
···
203
203
}()
204
204
205
205
for _, step := range steps {
206
+
envs := ConstructEnvs(step.Environment)
207
+
envs.AddEnv("HOME", workspaceDir)
208
+
e.l.Debug("envs for step", "step", step.Name, "envs", envs.Slice())
209
+
206
210
hostConfig := hostConfig(wid)
207
211
resp, err := e.docker.ContainerCreate(ctx, &container.Config{
208
212
Image: image,
···
210
214
WorkingDir: workspaceDir,
211
215
Tty: false,
212
216
Hostname: "spindle",
213
-
Env: []string{"HOME=" + workspaceDir},
217
+
Env: envs.Slice(),
214
218
}, hostConfig, nil, nil, "")
215
219
if err != nil {
216
220
return fmt.Errorf("creating container: %w", err)
+32
spindle/engine/envs.go
+32
spindle/engine/envs.go
···
1
+
package engine
2
+
3
+
import (
4
+
"fmt"
5
+
6
+
"tangled.sh/tangled.sh/core/api/tangled"
7
+
)
8
+
9
+
type EnvVars []string
10
+
11
+
// ConstructEnvs converts a tangled.Pipeline_Step_Environment_Elem.{Key,Value}
12
+
// representation into a docker-friendly []string{"KEY=value", ...} slice.
13
+
func ConstructEnvs(envs []*tangled.Pipeline_Step_Environment_Elem) EnvVars {
14
+
var dockerEnvs EnvVars
15
+
for _, env := range envs {
16
+
if env != nil {
17
+
ev := fmt.Sprintf("%s=%s", env.Key, env.Value)
18
+
dockerEnvs = append(dockerEnvs, ev)
19
+
}
20
+
}
21
+
return dockerEnvs
22
+
}
23
+
24
+
// Slice returns the EnvVar as a []string slice.
25
+
func (ev EnvVars) Slice() []string {
26
+
return ev
27
+
}
28
+
29
+
// AddEnv adds a key=value string to the EnvVar.
30
+
func (ev *EnvVars) AddEnv(key, value string) {
31
+
*ev = append(*ev, fmt.Sprintf("%s=%s", key, value))
32
+
}
+70
spindle/engine/envs_test.go
+70
spindle/engine/envs_test.go
···
1
+
package engine
2
+
3
+
import (
4
+
"reflect"
5
+
"testing"
6
+
7
+
"tangled.sh/tangled.sh/core/api/tangled"
8
+
)
9
+
10
+
func TestConstructEnvs(t *testing.T) {
11
+
tests := []struct {
12
+
name string
13
+
in []*tangled.Pipeline_Step_Environment_Elem
14
+
want EnvVars
15
+
}{
16
+
{
17
+
name: "empty input",
18
+
in: []*tangled.Pipeline_Step_Environment_Elem{},
19
+
want: EnvVars{},
20
+
},
21
+
{
22
+
name: "single env var",
23
+
in: []*tangled.Pipeline_Step_Environment_Elem{
24
+
{Key: "FOO", Value: "bar"},
25
+
},
26
+
want: EnvVars{"FOO=bar"},
27
+
},
28
+
{
29
+
name: "multiple env vars",
30
+
in: []*tangled.Pipeline_Step_Environment_Elem{
31
+
{Key: "FOO", Value: "bar"},
32
+
{Key: "BAZ", Value: "qux"},
33
+
},
34
+
want: EnvVars{"FOO=bar", "BAZ=qux"},
35
+
},
36
+
{
37
+
name: "nil entries are skipped",
38
+
in: []*tangled.Pipeline_Step_Environment_Elem{
39
+
nil,
40
+
{Key: "FOO", Value: "bar"},
41
+
},
42
+
want: EnvVars{"FOO=bar"},
43
+
},
44
+
}
45
+
46
+
for _, tt := range tests {
47
+
t.Run(tt.name, func(t *testing.T) {
48
+
got := ConstructEnvs(tt.in)
49
+
50
+
if got == nil {
51
+
got = EnvVars{}
52
+
}
53
+
54
+
if !reflect.DeepEqual(got, tt.want) {
55
+
t.Errorf("ConstructEnvs() = %v, want %v", got, tt.want)
56
+
}
57
+
})
58
+
}
59
+
}
60
+
61
+
func TestAddEnv(t *testing.T) {
62
+
ev := EnvVars{}
63
+
ev.AddEnv("FOO", "bar")
64
+
ev.AddEnv("BAZ", "qux")
65
+
66
+
want := EnvVars{"FOO=bar", "BAZ=qux"}
67
+
if !reflect.DeepEqual(ev, want) {
68
+
t.Errorf("AddEnv result = %v, want %v", ev, want)
69
+
}
70
+
}