0be6a4066e
Signed-off-by: Sam Alba <samalba@users.noreply.github.com>
90 lines
1.9 KiB
Go
90 lines
1.9 KiB
Go
package task
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/docker/distribution/reference"
|
|
"github.com/moby/buildkit/client/llb"
|
|
"go.dagger.io/dagger/compiler"
|
|
"go.dagger.io/dagger/plancontext"
|
|
"go.dagger.io/dagger/solver"
|
|
)
|
|
|
|
func init() {
|
|
Register("Pull", func() Task { return &pullTask{} })
|
|
}
|
|
|
|
type pullTask struct {
|
|
}
|
|
|
|
type authValue struct {
|
|
Target string
|
|
Username string
|
|
// FIXME: handle secrets
|
|
Secret string
|
|
}
|
|
|
|
func (c *pullTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) {
|
|
// FIXME: handle auth
|
|
rawRef, err := v.Lookup("source").String()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ref, err := reference.ParseNormalizedNamed(rawRef)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse ref %s: %w", rawRef, err)
|
|
}
|
|
// Add the default tag "latest" to a reference if it only has a repo name.
|
|
ref = reference.TagNameOnly(ref)
|
|
|
|
st := llb.Image(
|
|
ref.String(),
|
|
withCustomName(v, "Pull %s", rawRef),
|
|
)
|
|
|
|
// Load image metadata and convert to to LLB.
|
|
platform := pctx.Platform.Get()
|
|
image, digest, err := s.ResolveImageConfig(ctx, ref.String(), llb.ResolveImageConfigOpt{
|
|
LogName: vertexNamef(v, "load metadata for %s", ref.String()),
|
|
Platform: &platform,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
imageJSON, err := json.Marshal(image)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Apply Image Config on top of LLB instructions
|
|
st, err = st.WithImageConfig(imageJSON)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
auth := []authValue{}
|
|
|
|
// Read auth data
|
|
if err := v.Lookup("auth").Decode(&auth); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, a := range auth {
|
|
s.AddCredentials(a.Target, a.Username, a.Secret)
|
|
}
|
|
|
|
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(),
|
|
"digest": digest,
|
|
"config": image.Config,
|
|
})
|
|
}
|