diff --git a/plan/task/service.go b/plan/task/service.go new file mode 100644 index 00000000..4c2d152b --- /dev/null +++ b/plan/task/service.go @@ -0,0 +1,58 @@ +package task + +import ( + "context" + "errors" + + "cuelang.org/go/cue" + "github.com/rs/zerolog/log" + "go.dagger.io/dagger/compiler" + "go.dagger.io/dagger/plancontext" + "go.dagger.io/dagger/solver" +) + +func init() { + Register("Service", func() Task { return &serviceTask{} }) +} + +type serviceTask struct { +} + +func (c serviceTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) { + var unix, npipe string + var stringErr error + + unixV := v.Lookup("unix") + npipeV := v.Lookup("npipe") + + if unixV.Exists() && unixV.IsConcrete() { + unix, stringErr = unixV.String() + } + + if npipeV.Exists() && npipeV.IsConcrete() { + npipe, stringErr = npipeV.String() + } + + if stringErr != nil { + return nil, stringErr + } + + if unix == "" && npipe == "" { + return nil, errors.New("invalid service") + } + + lg := log.Ctx(ctx) + + if unix != "" { + lg.Debug().Str("unix", unix).Msg("loading service") + } else if npipe != "" { + lg.Debug().Str("npipe", npipe).Msg("loading service") + } + + service := pctx.Services.New(unix, npipe) + out := compiler.NewValue() + if err := out.FillPath(cue.ParsePath("service"), service.MarshalCUE()); err != nil { + return nil, err + } + return out, nil +} diff --git a/stdlib/europa/dagger/engine/plan.cue b/stdlib/europa/dagger/engine/plan.cue index 1d9b776e..a5ac386a 100644 --- a/stdlib/europa/dagger/engine/plan.cue +++ b/stdlib/europa/dagger/engine/plan.cue @@ -38,4 +38,14 @@ package engine envvar: string } } + + services: [string]: { + service: #Service + _type: "Service" + { + unix: string + } | { + npipe: string + } + } } diff --git a/tests/plan.bats b/tests/plan.bats index d2c16fd6..f99567ef 100644 --- a/tests/plan.bats +++ b/tests/plan.bats @@ -4,9 +4,37 @@ setup() { common_setup } -@test "plan: hello" { +@test "plan/hello" { # Europa loader handles the cwd differently, therefore we need to CD into the tree at or below the parent of cue.mod cd "$TESTDIR" - run "$DAGGER" --europa up ./plan/hello-europa - assert_success + "$DAGGER" --europa up ./plan/hello-europa +} + +@test "plan/context/services invalid schema" { + cd "$TESTDIR" + run "$DAGGER" --europa up ./plan/context/services/invalid_schema.cue + assert_failure +} + +@test "plan/context/services invalid value" { + cd "$TESTDIR" + run "$DAGGER" --europa up ./plan/context/services/invalid_value.cue + assert_failure +} + +@test "plan/context/services incomplete unix" { + cd "$TESTDIR" + run "$DAGGER" --europa up ./plan/context/services/incomplete_unix.cue + assert_failure +} + +@test "plan/context/services incomplete service" { + cd "$TESTDIR" + run "$DAGGER" --europa up ./plan/context/services/incomplete_service.cue + assert_output --partial "pipeline was partially executed because of missing inputs" +} + +@test "plan/context/services unix" { + cd "$TESTDIR" + "$DAGGER" --europa up ./plan/context/services/unix.cue } \ No newline at end of file diff --git a/tests/plan/context/services/incomplete_service.cue b/tests/plan/context/services/incomplete_service.cue new file mode 100644 index 00000000..33adbc79 --- /dev/null +++ b/tests/plan/context/services/incomplete_service.cue @@ -0,0 +1,26 @@ +package main + +import ( + "alpha.dagger.io/europa/dagger/engine" + "alpha.dagger.io/dagger/op" + "alpha.dagger.io/alpine" +) + +engine.#Plan & { + // should fail + context: services: dockerSocket: {} + + actions: test: #up: [ + op.#Load & { + from: alpine.#Image & { + package: "docker-cli": true + } + }, + + op.#Exec & { + always: true + mount: "/var/run/docker.sock": stream: context.services.dockerSocket.service + args: ["docker", "info"] + }, + ] +} diff --git a/tests/plan/context/services/incomplete_unix.cue b/tests/plan/context/services/incomplete_unix.cue new file mode 100644 index 00000000..379dc8bc --- /dev/null +++ b/tests/plan/context/services/incomplete_unix.cue @@ -0,0 +1,26 @@ +package main + +import ( + "alpha.dagger.io/europa/dagger/engine" + "alpha.dagger.io/dagger/op" + "alpha.dagger.io/alpine" +) + +engine.#Plan & { + // should succeed + context: services: dockerSocket: unix: string + + actions: test: #up: [ + op.#Load & { + from: alpine.#Image & { + package: "docker-cli": true + } + }, + + op.#Exec & { + always: true + mount: "/var/run/docker.sock": stream: context.services.dockerSocket.service + args: ["docker", "info"] + }, + ] +} diff --git a/tests/plan/context/services/invalid_schema.cue b/tests/plan/context/services/invalid_schema.cue new file mode 100644 index 00000000..bf19f9d2 --- /dev/null +++ b/tests/plan/context/services/invalid_schema.cue @@ -0,0 +1,26 @@ +package main + +import ( + "alpha.dagger.io/europa/dagger/engine" + "alpha.dagger.io/dagger/op" + "alpha.dagger.io/alpine" +) + +engine.#Plan & { + // should fail because of misspelled key + context: services: dockerSocket: unx: "/var/run/docker.soc" + + actions: test: #up: [ + op.#Load & { + from: alpine.#Image & { + package: "docker-cli": true + } + }, + + op.#Exec & { + always: true + mount: "/var/run/docker.sock": stream: context.services.dockerSocket.service + args: ["docker", "info"] + }, + ] +} diff --git a/tests/plan/context/services/invalid_value.cue b/tests/plan/context/services/invalid_value.cue new file mode 100644 index 00000000..1dcba88c --- /dev/null +++ b/tests/plan/context/services/invalid_value.cue @@ -0,0 +1,26 @@ +package main + +import ( + "alpha.dagger.io/europa/dagger/engine" + "alpha.dagger.io/dagger/op" + "alpha.dagger.io/alpine" +) + +engine.#Plan & { + // should fail because of misspelled value + context: services: dockerSocket: unix: "/var/run/docker.soc" + + actions: test: #up: [ + op.#Load & { + from: alpine.#Image & { + package: "docker-cli": true + } + }, + + op.#Exec & { + always: true + mount: "/var/run/docker.sock": stream: context.services.dockerSocket.service + args: ["docker", "info"] + }, + ] +} diff --git a/tests/plan/context/services/unix.cue b/tests/plan/context/services/unix.cue new file mode 100644 index 00000000..3e1fc723 --- /dev/null +++ b/tests/plan/context/services/unix.cue @@ -0,0 +1,26 @@ +package main + +import ( + "alpha.dagger.io/europa/dagger/engine" + "alpha.dagger.io/dagger/op" + "alpha.dagger.io/alpine" +) + +engine.#Plan & { + // should succeed + context: services: dockerSocket: unix: "/var/run/docker.sock" + + actions: test: #up: [ + op.#Load & { + from: alpine.#Image & { + package: "docker-cli": true + } + }, + + op.#Exec & { + always: true + mount: "/var/run/docker.sock": stream: context.services.dockerSocket.service + args: ["docker", "info"] + }, + ] +}