Add #Secret type to Docker #Build args

Signed-off-by: Kevin Poirot <kevin@vazee.fr>
This commit is contained in:
Kevin Poirot 2021-09-15 16:32:43 +02:00
parent 541c8c078f
commit 51f96172bd
3 changed files with 32 additions and 24 deletions

View File

@ -658,6 +658,25 @@ func unmarshalAnything(data []byte, fn unmarshaller) (interface{}, error) {
return o, err return o, err
} }
// parseStringOrSecret retrieve secret as plain text or retrieve string
func parseStringOrSecret(ctx context.Context, ss solver.SecretsStore, v *compiler.Value) (string, error) {
// Check if the value is a string, return as is
if value, err := v.String(); err == nil {
return value, nil
}
// If we get here, it's a secret
id, err := getSecretID(v)
if err != nil {
return "", err
}
secretBytes, err := ss.GetSecret(ctx, id)
if err != nil {
return "", err
}
return string(secretBytes), nil
}
func (p *Pipeline) Load(ctx context.Context, op *compiler.Value, st llb.State) (llb.State, error) { func (p *Pipeline) Load(ctx context.Context, op *compiler.Value, st llb.State) (llb.State, error) {
// Execute 'from' in a tmp pipeline, and use the resulting fs // Execute 'from' in a tmp pipeline, and use the resulting fs
from := NewPipeline(op.Lookup("from"), p.s) from := NewPipeline(op.Lookup("from"), p.s)
@ -674,27 +693,13 @@ func (p *Pipeline) DockerLogin(ctx context.Context, op *compiler.Value, st llb.S
return st, err return st, err
} }
// Inject secret as plain text or retrieve string // FIXME If we could create secret directly in `cue`, we could avoid using
// FIXME If we could create secret directly in `cue`, we could clean up // that function
// that condition
// But currently it's not possible because ECR secret's is a string // But currently it's not possible because ECR secret's is a string
// so we need to handle both options (string & secret) // so we need to handle both options (string & secret)
secretValue, err := op.Lookup("secret").String() secretValue, err := parseStringOrSecret(ctx, p.s.GetOptions().SecretsStore, op.Lookup("secret"))
if err != nil { if err != nil {
// Retrieve secret return st, err
if secret := op.Lookup("secret"); secret.Exists() {
id, err := getSecretID(secret)
if err != nil {
return st, err
}
secretBytes, err := p.s.GetOptions().SecretsStore.GetSecret(ctx, id)
if err != nil {
return st, err
}
secretValue = string(secretBytes)
} else {
return st, err
}
} }
target, err := op.Lookup("target").String() target, err := op.Lookup("target").String()
@ -978,7 +983,7 @@ func (p *Pipeline) DockerBuild(ctx context.Context, op *compiler.Value, st llb.S
} }
} }
opts, err := dockerBuildOpts(op) opts, err := dockerBuildOpts(ctx, op, p.s.GetOptions().SecretsStore)
if err != nil { if err != nil {
return st, err return st, err
} }
@ -1017,7 +1022,7 @@ func (p *Pipeline) DockerBuild(ctx context.Context, op *compiler.Value, st llb.S
return applyImageToState(p.image, st), nil return applyImageToState(p.image, st), nil
} }
func dockerBuildOpts(op *compiler.Value) (map[string]string, error) { func dockerBuildOpts(ctx context.Context, op *compiler.Value, ss solver.SecretsStore) (map[string]string, error) {
opts := map[string]string{} opts := map[string]string{}
if dockerfilePath := op.Lookup("dockerfilePath"); dockerfilePath.Exists() { if dockerfilePath := op.Lookup("dockerfilePath"); dockerfilePath.Exists() {
@ -1060,7 +1065,7 @@ func dockerBuildOpts(op *compiler.Value) (map[string]string, error) {
return nil, err return nil, err
} }
for _, buildArg := range fields { for _, buildArg := range fields {
v, err := buildArg.Value.String() v, err := parseStringOrSecret(ctx, ss, buildArg.Value)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -116,8 +116,11 @@ package op
dockerfile?: string dockerfile?: string
platforms?: [...string] platforms?: [...string]
buildArg?: [string]: string buildArg?: {
label?: [string]: string // FIXME: should be `[string]: string | #Secret` (circular import)
[string]: string | _ @dagger(secret)
}
label?: [string]: string
target?: string target?: string
hosts?: [string]: string hosts?: [string]: string
} }

View File

@ -14,7 +14,7 @@ import (
// Dockerfile passed as a string // Dockerfile passed as a string
dockerfile: dagger.#Input & {*null | string} dockerfile: dagger.#Input & {*null | string}
args?: [string]: string args?: [string]: string | dagger.#Secret
#up: [ #up: [
op.#DockerBuild & { op.#DockerBuild & {