Merge pull request #1534 from grouville/reconcile-auth
Reconcile docker.#Push.auth and engine.#Push.auth
This commit is contained in:
commit
946629d1fa
@ -14,11 +14,10 @@ package engine
|
|||||||
config: #ImageConfig
|
config: #ImageConfig
|
||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
auth: [...{
|
auth?: {
|
||||||
target: string
|
|
||||||
username: string
|
username: string
|
||||||
secret: string | #Secret
|
secret: #Secret
|
||||||
}]
|
}
|
||||||
|
|
||||||
// Complete ref of the pushed image, including digest
|
// Complete ref of the pushed image, including digest
|
||||||
result: #Ref
|
result: #Ref
|
||||||
@ -68,11 +67,10 @@ package engine
|
|||||||
source: #Ref
|
source: #Ref
|
||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
auth: [...{
|
auth?: {
|
||||||
target: string
|
|
||||||
username: string
|
username: string
|
||||||
secret: string | #Secret
|
secret: #Secret
|
||||||
}]
|
}
|
||||||
|
|
||||||
// Root filesystem of downloaded image
|
// Root filesystem of downloaded image
|
||||||
output: #FS
|
output: #FS
|
||||||
@ -98,11 +96,10 @@ package engine
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
auth: [...{
|
auth: [registry=string]: {
|
||||||
target: string
|
|
||||||
username: string
|
username: string
|
||||||
secret: string | #Secret
|
secret: #Secret
|
||||||
}]
|
}
|
||||||
|
|
||||||
platforms?: [...string]
|
platforms?: [...string]
|
||||||
target?: string
|
target?: string
|
||||||
|
@ -12,18 +12,16 @@ import (
|
|||||||
source: #Ref
|
source: #Ref
|
||||||
|
|
||||||
// Registry authentication
|
// Registry authentication
|
||||||
// Key must be registry address, for example "index.docker.io"
|
auth?: {
|
||||||
auth: [registry=string]: {
|
|
||||||
username: string
|
username: string
|
||||||
secret: dagger.#Secret
|
secret: dagger.#Secret
|
||||||
}
|
}
|
||||||
|
|
||||||
_op: engine.#Pull & {
|
_op: engine.#Pull & {
|
||||||
"source": source
|
"source": source
|
||||||
"auth": [ for target, creds in auth {
|
if auth != _|_ {
|
||||||
"target": target
|
"auth": auth
|
||||||
creds
|
}
|
||||||
}]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Downloaded image
|
// Downloaded image
|
||||||
|
@ -14,8 +14,7 @@ import (
|
|||||||
result: #Ref & _push.result
|
result: #Ref & _push.result
|
||||||
|
|
||||||
// Registry authentication
|
// Registry authentication
|
||||||
// Key must be registry address
|
auth?: {
|
||||||
auth: [registry=string]: {
|
|
||||||
username: string
|
username: string
|
||||||
secret: dagger.#Secret
|
secret: dagger.#Secret
|
||||||
}
|
}
|
||||||
@ -25,10 +24,9 @@ import (
|
|||||||
|
|
||||||
_push: engine.#Push & {
|
_push: engine.#Push & {
|
||||||
"dest": dest
|
"dest": dest
|
||||||
"auth": [ for target, creds in auth {
|
if auth != _|_ {
|
||||||
"target": target
|
"auth": auth
|
||||||
creds
|
}
|
||||||
}]
|
|
||||||
input: image.rootfs
|
input: image.rootfs
|
||||||
config: image.config
|
config: image.config
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type authValue struct {
|
type authValue struct {
|
||||||
Target string
|
|
||||||
Username string
|
Username string
|
||||||
Secret *plancontext.Secret
|
Secret *plancontext.Secret
|
||||||
}
|
}
|
||||||
@ -14,41 +13,23 @@ type authValue struct {
|
|||||||
// Decodes an auth field value
|
// Decodes an auth field value
|
||||||
//
|
//
|
||||||
// Cue format:
|
// Cue format:
|
||||||
// auth: [...{
|
// auth: {
|
||||||
// target: string
|
|
||||||
// username: string
|
// username: string
|
||||||
// secret: string | #Secret
|
// secret: string | #Secret
|
||||||
// }]
|
// }
|
||||||
func decodeAuthValue(pctx *plancontext.Context, v *compiler.Value) ([]*authValue, error) {
|
func decodeAuthValue(pctx *plancontext.Context, v *compiler.Value) (*authValue, error) {
|
||||||
vals, err := v.List()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
authVals := []*authValue{}
|
|
||||||
for _, val := range vals {
|
|
||||||
authVal := authValue{}
|
authVal := authValue{}
|
||||||
|
username, err := v.Lookup("username").String()
|
||||||
target, err := val.Lookup("target").String()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
authVal.Target = target
|
|
||||||
|
|
||||||
username, err := val.Lookup("username").String()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
authVal.Username = username
|
authVal.Username = username
|
||||||
|
|
||||||
secret, err := pctx.Secrets.FromValue(val.Lookup("secret"))
|
secret, err := pctx.Secrets.FromValue(v.Lookup("secret"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
authVal.Secret = secret
|
authVal.Secret = secret
|
||||||
|
|
||||||
authVals = append(authVals, &authVal)
|
return &authVal, nil
|
||||||
}
|
|
||||||
|
|
||||||
return authVals, nil
|
|
||||||
}
|
}
|
||||||
|
@ -30,15 +30,24 @@ type dockerfileTask struct {
|
|||||||
|
|
||||||
func (t *dockerfileTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) {
|
func (t *dockerfileTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.Solver, v *compiler.Value) (*compiler.Value, error) {
|
||||||
lg := log.Ctx(ctx)
|
lg := log.Ctx(ctx)
|
||||||
|
auths, err := v.Lookup("auth").Fields()
|
||||||
// Read auth info
|
|
||||||
auth, err := decodeAuthValue(pctx, v.Lookup("auth"))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, a := range auth {
|
|
||||||
s.AddCredentials(a.Target, a.Username, a.Secret.PlainText())
|
for _, auth := range auths {
|
||||||
lg.Debug().Str("target", a.Target).Msg("add target credentials")
|
// Read auth info
|
||||||
|
a, err := decodeAuthValue(pctx, auth.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Extract registry target from dest
|
||||||
|
target, err := solver.ParseAuthHost(auth.Label())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.AddCredentials(target, a.Username, a.Secret.PlainText())
|
||||||
|
lg.Debug().Str("target", target).Msg("add target credentials")
|
||||||
}
|
}
|
||||||
|
|
||||||
source, err := pctx.FS.FromValue(v.Lookup("source"))
|
source, err := pctx.FS.FromValue(v.Lookup("source"))
|
||||||
|
@ -28,13 +28,18 @@ func (c *pullTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read auth info
|
// Read auth info
|
||||||
auth, err := decodeAuthValue(pctx, v.Lookup("auth"))
|
if auth := v.Lookup("auth"); auth.Exists() {
|
||||||
|
a, err := decodeAuthValue(pctx, auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, a := range auth {
|
// Extract registry target from source
|
||||||
s.AddCredentials(a.Target, a.Username, a.Secret.PlainText())
|
target, err := solver.ParseAuthHost(rawRef)
|
||||||
lg.Debug().Str("target", a.Target).Msg("add target credentials")
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.AddCredentials(target, a.Username, a.Secret.PlainText())
|
||||||
|
lg.Debug().Str("target", target).Msg("add target credentials")
|
||||||
}
|
}
|
||||||
|
|
||||||
ref, err := reference.ParseNormalizedNamed(rawRef)
|
ref, err := reference.ParseNormalizedNamed(rawRef)
|
||||||
|
@ -36,13 +36,19 @@ func (c *pushTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.
|
|||||||
dest = reference.TagNameOnly(dest)
|
dest = reference.TagNameOnly(dest)
|
||||||
|
|
||||||
// Read auth info
|
// Read auth info
|
||||||
auth, err := decodeAuthValue(pctx, v.Lookup("auth"))
|
if auth := v.Lookup("auth"); auth.Exists() {
|
||||||
|
// Read auth info
|
||||||
|
a, err := decodeAuthValue(pctx, auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, a := range auth {
|
// Extract registry target from dest
|
||||||
s.AddCredentials(a.Target, a.Username, a.Secret.PlainText())
|
target, err := solver.ParseAuthHost(rawDest)
|
||||||
lg.Debug().Str("target", a.Target).Msg("add target credentials")
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.AddCredentials(target, a.Username, a.Secret.PlainText())
|
||||||
|
lg.Debug().Str("target", target).Msg("add target credentials")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get input state
|
// Get input state
|
||||||
|
@ -51,7 +51,7 @@ func (a *RegistryAuthProvider) Credentials(ctx context.Context, req *bkauth.Cred
|
|||||||
defer a.m.RUnlock()
|
defer a.m.RUnlock()
|
||||||
|
|
||||||
for authHost, auth := range a.credentials {
|
for authHost, auth := range a.credentials {
|
||||||
u, err := parseAuthHost(authHost)
|
u, err := ParseAuthHost(authHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ func (a *RegistryAuthProvider) Credentials(ctx context.Context, req *bkauth.Cred
|
|||||||
|
|
||||||
// Parsing function based on splitReposSearchTerm
|
// Parsing function based on splitReposSearchTerm
|
||||||
// "github.com/docker/docker/registry"
|
// "github.com/docker/docker/registry"
|
||||||
func parseAuthHost(host string) (string, error) {
|
func ParseAuthHost(host string) (string, error) {
|
||||||
host = strings.TrimPrefix(host, "http://")
|
host = strings.TrimPrefix(host, "http://")
|
||||||
host = strings.TrimPrefix(host, "https://")
|
host = strings.TrimPrefix(host, "https://")
|
||||||
host = strings.TrimSuffix(host, "/")
|
host = strings.TrimSuffix(host, "/")
|
||||||
|
@ -257,7 +257,7 @@ func TestParseAuthHost(t *testing.T) {
|
|||||||
|
|
||||||
successRefs := []output{}
|
successRefs := []output{}
|
||||||
for _, scase := range scases {
|
for _, scase := range scases {
|
||||||
named, err := parseAuthHost(scase.Host)
|
named, err := ParseAuthHost(scase.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Invalid normalized reference for [%q]. Got %q", scase, err)
|
t.Fatalf("Invalid normalized reference for [%q]. Got %q", scase, err)
|
||||||
}
|
}
|
||||||
@ -273,7 +273,7 @@ func TestParseAuthHost(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, fcase := range fcases {
|
for _, fcase := range fcases {
|
||||||
named, err := parseAuthHost(fcase.Host)
|
named, err := ParseAuthHost(fcase.Host)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("Invalid normalized reference for [%q]. Expected failure for %q", fcase, named)
|
t.Fatalf("Invalid normalized reference for [%q]. Expected failure for %q", fcase, named)
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,10 @@ engine.#Plan & {
|
|||||||
|
|
||||||
build: engine.#Dockerfile & {
|
build: engine.#Dockerfile & {
|
||||||
source: inputs.directories.testdata.contents
|
source: inputs.directories.testdata.contents
|
||||||
auth: [{
|
auth: "daggerio/ci-test:private-pull": {
|
||||||
target: "daggerio/ci-test:private-pull"
|
|
||||||
username: "daggertest"
|
username: "daggertest"
|
||||||
|
|
||||||
secret: sopsSecrets.output.DOCKERHUB_TOKEN.contents
|
secret: sopsSecrets.output.DOCKERHUB_TOKEN.contents
|
||||||
}]
|
}
|
||||||
dockerfile: contents: """
|
dockerfile: contents: """
|
||||||
FROM daggerio/ci-test:private-pull@sha256:c74f1b1166784193ea6c8f9440263b9be6cae07dfe35e32a5df7a31358ac2060
|
FROM daggerio/ci-test:private-pull@sha256:c74f1b1166784193ea6c8f9440263b9be6cae07dfe35e32a5df7a31358ac2060
|
||||||
"""
|
"""
|
||||||
|
@ -19,11 +19,10 @@ engine.#Plan & {
|
|||||||
|
|
||||||
pull: engine.#Pull & {
|
pull: engine.#Pull & {
|
||||||
source: "daggerio/ci-test:private-pull@sha256:c74f1b1166784193ea6c8f9440263b9be6cae07dfe35e32a5df7a31358ac2060"
|
source: "daggerio/ci-test:private-pull@sha256:c74f1b1166784193ea6c8f9440263b9be6cae07dfe35e32a5df7a31358ac2060"
|
||||||
auth: [{
|
auth: {
|
||||||
target: "daggerio/ci-test:private-pull"
|
|
||||||
username: "daggertest"
|
username: "daggertest"
|
||||||
secret: sopsSecrets.output.DOCKERHUB_TOKEN.contents
|
secret: sopsSecrets.output.DOCKERHUB_TOKEN.contents
|
||||||
}]
|
}
|
||||||
} & {
|
} & {
|
||||||
// assert result
|
// assert result
|
||||||
digest: "sha256:c74f1b1166784193ea6c8f9440263b9be6cae07dfe35e32a5df7a31358ac2060"
|
digest: "sha256:c74f1b1166784193ea6c8f9440263b9be6cae07dfe35e32a5df7a31358ac2060"
|
||||||
|
@ -12,11 +12,10 @@ engine.#Plan & {
|
|||||||
args: ["-d", "../../secrets_sops.yaml"]
|
args: ["-d", "../../secrets_sops.yaml"]
|
||||||
}
|
}
|
||||||
|
|
||||||
#auth: [{
|
#auth: {
|
||||||
target: "daggerio/ci-test:private-pull"
|
|
||||||
username: "daggertest"
|
username: "daggertest"
|
||||||
secret: actions.sopsSecrets.output.DOCKERHUB_TOKEN.contents
|
secret: actions.sopsSecrets.output.DOCKERHUB_TOKEN.contents
|
||||||
}]
|
}
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user