diff --git a/plan/task/httpfetch.go b/plan/task/httpfetch.go new file mode 100644 index 00000000..d70caffe --- /dev/null +++ b/plan/task/httpfetch.go @@ -0,0 +1,79 @@ +package task + +import ( + "context" + "fmt" + "io/fs" + "net/url" + + "github.com/moby/buildkit/client/llb" + "github.com/opencontainers/go-digest" + "github.com/rs/zerolog/log" + "go.dagger.io/dagger/compiler" + "go.dagger.io/dagger/plancontext" + "go.dagger.io/dagger/solver" +) + +func init() { + Register("HTTPFetch", func() Task { return &httpFetchTask{} }) +} + +type httpFetchTask struct { +} + +func (c httpFetchTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) { + var httpFetch struct { + Source string + Checksum string + Dest string + Permissions int + UID int + GID int + } + + if err := v.Decode(&httpFetch); err != nil { + return nil, err + } + + linkRedacted := httpFetch.Source + if u, err := url.Parse(httpFetch.Source); err == nil { + linkRedacted = u.Redacted() + } + + httpOpts := []llb.HTTPOption{} + lg := log.Ctx(ctx) + if httpFetch.Checksum != "" { + lg.Debug().Str("checksum", httpFetch.Checksum).Msg("adding http option") + dgst, err := digest.Parse(httpFetch.Checksum) + if err != nil { + return nil, err + } + httpOpts = append(httpOpts, llb.Checksum(dgst)) + } + if httpFetch.Dest != "" { + lg.Debug().Str("dest", httpFetch.Dest).Msg("adding http option") + httpOpts = append(httpOpts, llb.Filename(httpFetch.Dest)) + } + if httpFetch.Permissions != 0 { + lg.Debug().Str("permissions", fmt.Sprint(httpFetch.Permissions)).Msg("adding http option") + httpOpts = append(httpOpts, llb.Chmod(fs.FileMode(httpFetch.Permissions))) + } + if httpFetch.UID != 0 && httpFetch.GID != 0 { + lg.Debug().Str("uid", fmt.Sprint(httpFetch.UID)).Str("gid", fmt.Sprint(httpFetch.GID)).Msg("adding http option") + httpOpts = append(httpOpts, llb.Chown(httpFetch.UID, httpFetch.GID)) + } + + httpOpts = append(httpOpts, withCustomName(v, "FetchHTTP %s", linkRedacted)) + + st := llb.HTTP(httpFetch.Source, httpOpts...) + + result, err := s.Solve(ctx, st, pctx.Platform.Get()) + if err != nil { + return nil, err + } + + fs := pctx.FS.New(result) + return compiler.NewValue().FillFields(map[string]interface{}{ + "output": fs.MarshalCUE(), + }) +} diff --git a/stdlib/europa/dagger/engine/http.cue b/stdlib/europa/dagger/engine/http.cue index d5f9a56f..b65cf7d7 100644 --- a/stdlib/europa/dagger/engine/http.cue +++ b/stdlib/europa/dagger/engine/http.cue @@ -18,7 +18,6 @@ package engine // Fetch a file over HTTP #HTTPFetch: { - @dagger(notimplemented) $dagger: task: _name: "HTTPFetch" // Source url diff --git a/tests/tasks.bats b/tests/tasks.bats index d17593fb..97ed97e2 100644 --- a/tests/tasks.bats +++ b/tests/tasks.bats @@ -105,6 +105,11 @@ setup() { assert_failure run "$DAGGER" --europa up ./tasks/gitPull/bad_ref.cue assert_failure - - +} + +@test "task: #HTTPFetch" { + cd "$TESTDIR" + "$DAGGER" --europa up ./tasks/httpfetch/exist.cue + run "$DAGGER" --europa up ./tasks/httpfetch/not_exist.cue + assert_failure } diff --git a/tests/tasks/httpfetch/exist.cue b/tests/tasks/httpfetch/exist.cue new file mode 100644 index 00000000..aa2aaa81 --- /dev/null +++ b/tests/tasks/httpfetch/exist.cue @@ -0,0 +1,10 @@ +package main + +import "alpha.dagger.io/europa/dagger/engine" + +engine.#Plan & { + actions: fetch: engine.#HTTPFetch & { + source: "https://releases.dagger.io/dagger/latest_version" + dest: "/latest.html" + } +} diff --git a/tests/tasks/httpfetch/not_exist.cue b/tests/tasks/httpfetch/not_exist.cue new file mode 100644 index 00000000..2ee9097c --- /dev/null +++ b/tests/tasks/httpfetch/not_exist.cue @@ -0,0 +1,10 @@ +package main + +import "alpha.dagger.io/europa/dagger/engine" + +engine.#Plan & { + actions: fetch: engine.#HTTPFetch & { + source: "https://releases.dagger.io/dagger/asfgdsfg" + dest: "/latest.html" + } +}