Fix auth again
This commit is contained in:
1
examples/tests/dockerhub/.dockerignore
Normal file
1
examples/tests/dockerhub/.dockerignore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*
|
||||||
34
examples/tests/dockerhub/Pulumi.yaml
Normal file
34
examples/tests/dockerhub/Pulumi.yaml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
name: dockerhub
|
||||||
|
description: Push to DockerHub with caching
|
||||||
|
runtime: yaml
|
||||||
|
plugins:
|
||||||
|
providers:
|
||||||
|
- name: docker-build
|
||||||
|
path: ../../../bin
|
||||||
|
outputs:
|
||||||
|
ref: ${my-image.ref}
|
||||||
|
resources:
|
||||||
|
my-image:
|
||||||
|
type: docker-build:Image
|
||||||
|
properties:
|
||||||
|
tags:
|
||||||
|
- docker.io/pulumibot/buildkit-e2e
|
||||||
|
push: true
|
||||||
|
context:
|
||||||
|
location: .
|
||||||
|
dockerfile:
|
||||||
|
inline: FROM alpine
|
||||||
|
cacheFrom:
|
||||||
|
- registry:
|
||||||
|
ref: docker.io/pulumibot/buildkit-e2e:cache
|
||||||
|
cacheTo:
|
||||||
|
- registry:
|
||||||
|
ref: docker.io/pulumibot/buildkit-e2e:cache
|
||||||
|
registries:
|
||||||
|
- username: pulumibot
|
||||||
|
address: docker.io
|
||||||
|
password: ${dockerHubPassword}
|
||||||
|
config:
|
||||||
|
dockerHubPassword:
|
||||||
|
type: string
|
||||||
|
secret: true
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
name: ecr
|
name: ecr
|
||||||
description: Push to AWS ECR with caching
|
description: Push to AWS ECR with caching
|
||||||
|
runtime: yaml
|
||||||
|
plugins:
|
||||||
|
providers:
|
||||||
|
- name: docker-build
|
||||||
|
path: ../../../bin
|
||||||
outputs:
|
outputs:
|
||||||
ref: ${my-image.ref}
|
ref: ${my-image.ref}
|
||||||
resources:
|
resources:
|
||||||
@@ -8,10 +13,10 @@ resources:
|
|||||||
properties:
|
properties:
|
||||||
forceDelete: true
|
forceDelete: true
|
||||||
my-image:
|
my-image:
|
||||||
type: dockerbuild:Image
|
type: docker-build:Image
|
||||||
properties:
|
properties:
|
||||||
tags:
|
tags:
|
||||||
- ${ecr-repository.repositoryUrl}:tag-name
|
- ${ecr-repository.repositoryUrl}:latest
|
||||||
push: true
|
push: true
|
||||||
context:
|
context:
|
||||||
location: .
|
location: .
|
||||||
@@ -29,7 +34,6 @@ resources:
|
|||||||
- username: ${auth-token.userName}
|
- username: ${auth-token.userName}
|
||||||
password: ${auth-token.password}
|
password: ${auth-token.password}
|
||||||
address: ${ecr-repository.repositoryUrl}
|
address: ${ecr-repository.repositoryUrl}
|
||||||
runtime: yaml
|
|
||||||
variables:
|
variables:
|
||||||
auth-token:
|
auth-token:
|
||||||
fn::aws:ecr:getAuthorizationToken:
|
fn::aws:ecr:getAuthorizationToken:
|
||||||
|
|||||||
@@ -40,3 +40,21 @@ func TestECR(t *testing.T) {
|
|||||||
|
|
||||||
integration.ProgramTest(t, &test)
|
integration.ProgramTest(t, &test)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDockerHub(t *testing.T) {
|
||||||
|
if os.Getenv("DOCKER_HUB_PASSWORD") == "" {
|
||||||
|
t.Skip("Missing DockerHub credentials")
|
||||||
|
}
|
||||||
|
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
test := integration.ProgramTestOptions{
|
||||||
|
Dir: path.Join(cwd, "tests/dockerhub"),
|
||||||
|
Secrets: map[string]string{
|
||||||
|
"dockerHubPassword": os.Getenv("DOCKER_HUB_PASSWORD"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
integration.ProgramTest(t, &test)
|
||||||
|
}
|
||||||
|
|||||||
@@ -347,7 +347,8 @@ type CacheWithMode struct {
|
|||||||
|
|
||||||
// Annotate sets docstrings and defaults on CacheWithMode.
|
// Annotate sets docstrings and defaults on CacheWithMode.
|
||||||
func (c *CacheWithMode) Annotate(a infer.Annotator) {
|
func (c *CacheWithMode) Annotate(a infer.Annotator) {
|
||||||
a.SetDefault(&c.Mode, Min)
|
m := Min
|
||||||
|
a.SetDefault(&c.Mode, &m)
|
||||||
a.Describe(&c.Mode, dedent(`
|
a.Describe(&c.Mode, dedent(`
|
||||||
The cache mode to use. Defaults to "min".
|
The cache mode to use. Defaults to "min".
|
||||||
`))
|
`))
|
||||||
@@ -559,7 +560,8 @@ type CacheWithCompression struct {
|
|||||||
|
|
||||||
// Annotate sets docstrings and defaults on CacheWithCompression.
|
// Annotate sets docstrings and defaults on CacheWithCompression.
|
||||||
func (c *CacheWithCompression) Annotate(a infer.Annotator) {
|
func (c *CacheWithCompression) Annotate(a infer.Annotator) {
|
||||||
a.SetDefault(&c.Compression, Gzip)
|
gz := Gzip
|
||||||
|
a.SetDefault(&c.Compression, &gz)
|
||||||
a.SetDefault(&c.CompressionLevel, 0)
|
a.SetDefault(&c.CompressionLevel, 0)
|
||||||
a.SetDefault(&c.ForceCompression, false)
|
a.SetDefault(&c.ForceCompression, false)
|
||||||
|
|
||||||
|
|||||||
@@ -79,21 +79,27 @@ func wrap(host *host, registries ...Registry) (*cli, error) {
|
|||||||
|
|
||||||
auths := map[string]cfgtypes.AuthConfig{}
|
auths := map[string]cfgtypes.AuthConfig{}
|
||||||
for k, v := range host.auths {
|
for k, v := range host.auths {
|
||||||
auths[k] = v
|
auths[k] = cfgtypes.AuthConfig{
|
||||||
|
ServerAddress: v.ServerAddress,
|
||||||
|
Username: v.Username,
|
||||||
|
Password: v.Password,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range registries {
|
for _, r := range registries {
|
||||||
// Special handling for legacy DockerHub domains. The OCI-compliant
|
// HostNewName takes care of DockerHub's special-casing for us.
|
||||||
// registry is registry-1.docker.io but this is stored in config under the
|
h := config.HostNewName(credentials.ConvertToHostname(r.Address))
|
||||||
// legacy name.
|
key := h.CredHost
|
||||||
// https://github.com/docker/cli/issues/3793#issuecomment-1269051403
|
if key == "" {
|
||||||
key := credentials.ConvertToHostname(r.Address)
|
key = h.Hostname
|
||||||
if key == "registry-1.docker.io" || key == "index.docker.io" || key == "docker.io" {
|
}
|
||||||
key = "https://index.docker.io/v1/"
|
// Add a scheme if it's missing.
|
||||||
|
if !strings.Contains(key, "://") {
|
||||||
|
key = "https://" + key
|
||||||
}
|
}
|
||||||
|
|
||||||
auths[key] = cfgtypes.AuthConfig{
|
auths[key] = cfgtypes.AuthConfig{
|
||||||
ServerAddress: r.Address,
|
ServerAddress: h.Hostname,
|
||||||
Username: r.Username,
|
Username: r.Username,
|
||||||
Password: r.Password,
|
Password: r.Password,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -252,8 +252,6 @@ func (c *cli) BuildKitEnabled() (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *cli) ManifestCreate(ctx provider.Context, push bool, target string, refs ...string) error {
|
func (c *cli) ManifestCreate(ctx provider.Context, push bool, target string, refs ...string) error {
|
||||||
// TODO: Create this manifest with regclient or imagetools.
|
|
||||||
|
|
||||||
go c.tail(ctx)
|
go c.tail(ctx)
|
||||||
defer contract.IgnoreClose(c)
|
defer contract.IgnoreClose(c)
|
||||||
|
|
||||||
@@ -261,6 +259,7 @@ func (c *cli) ManifestCreate(ctx provider.Context, push bool, target string, ref
|
|||||||
// "buildx",
|
// "buildx",
|
||||||
"imagetools",
|
"imagetools",
|
||||||
"create",
|
"create",
|
||||||
|
"--progress=plain",
|
||||||
"--tag", target,
|
"--tag", target,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,10 +272,13 @@ func (c *cli) ManifestCreate(ctx provider.Context, push bool, target string, ref
|
|||||||
cmd := commands.NewRootCmd(os.Args[0], false, c)
|
cmd := commands.NewRootCmd(os.Args[0], false, c)
|
||||||
|
|
||||||
cmd.SetArgs(args)
|
cmd.SetArgs(args)
|
||||||
|
|
||||||
|
ctx.Log(diag.Debug, fmt.Sprint("creating manifest with args", args))
|
||||||
return cmd.ExecuteContext(ctx)
|
return cmd.ExecuteContext(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cli) ManifestInspect(ctx provider.Context, target string) (string, error) {
|
func (c *cli) ManifestInspect(ctx provider.Context, target string) (string, error) {
|
||||||
|
ctx.LogStatus(diag.Info, "inspecting manifest")
|
||||||
rc := c.rc()
|
rc := c.rc()
|
||||||
|
|
||||||
ref, err := ref.New(target)
|
ref, err := ref.New(target)
|
||||||
@@ -286,7 +288,7 @@ func (c *cli) ManifestInspect(ctx provider.Context, target string) (string, erro
|
|||||||
|
|
||||||
m, err := rc.ManifestHead(ctx, ref)
|
m, err := rc.ManifestHead(ctx, ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("fetching head: %w", err)
|
return "", fmt.Errorf("fetching %q: %w", ref, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(m.GetDescriptor().Digest), nil
|
return string(m.GetDescriptor().Digest), nil
|
||||||
|
|||||||
@@ -393,7 +393,8 @@ type ExportWithCompression struct {
|
|||||||
|
|
||||||
// Annotate sets docstrings and defaults on ExportWithCompression.
|
// Annotate sets docstrings and defaults on ExportWithCompression.
|
||||||
func (e *ExportWithCompression) Annotate(a infer.Annotator) {
|
func (e *ExportWithCompression) Annotate(a infer.Annotator) {
|
||||||
a.SetDefault(&e.Compression, Gzip)
|
gzip := Gzip
|
||||||
|
a.SetDefault(&e.Compression, &gzip)
|
||||||
a.SetDefault(&e.CompressionLevel, 0)
|
a.SetDefault(&e.CompressionLevel, 0)
|
||||||
a.SetDefault(&e.ForceCompression, false)
|
a.SetDefault(&e.ForceCompression, false)
|
||||||
|
|
||||||
|
|||||||
@@ -287,7 +287,8 @@ func (ia *ImageArgs) Annotate(a infer.Annotator) {
|
|||||||
"docker-buildx" binary.
|
"docker-buildx" binary.
|
||||||
`))
|
`))
|
||||||
|
|
||||||
a.SetDefault(&ia.Network, Default)
|
d := Default
|
||||||
|
a.SetDefault(&ia.Network, &d)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageState is serialized to the program's state file.
|
// ImageState is serialized to the program's state file.
|
||||||
@@ -350,7 +351,7 @@ func (i *Image) client(pctx provider.Context, state ImageState, args ImageArgs)
|
|||||||
// We prefer auth from args, the provider, and state in that order. We
|
// We prefer auth from args, the provider, and state in that order. We
|
||||||
// build a slice in reverse order because wrap() will overwrite earlier
|
// build a slice in reverse order because wrap() will overwrite earlier
|
||||||
// entries with later ones.
|
// entries with later ones.
|
||||||
auths := state.Registries
|
auths := []Registry{}
|
||||||
auths = append(auths, cfg.Registries...)
|
auths = append(auths, cfg.Registries...)
|
||||||
auths = append(auths, args.Registries...)
|
auths = append(auths, args.Registries...)
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
|
|
||||||
provider "github.com/pulumi/pulumi-go-provider"
|
provider "github.com/pulumi/pulumi-go-provider"
|
||||||
"github.com/pulumi/pulumi-go-provider/infer"
|
"github.com/pulumi/pulumi-go-provider/infer"
|
||||||
|
"github.com/pulumi/pulumi/sdk/v3/go/common/diag"
|
||||||
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -138,6 +139,8 @@ func (i *Index) Update(
|
|||||||
return state, nil
|
return state, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.Log(diag.Info, fmt.Sprintf("creating index with tag %s and sources %s", input.Tag, input.Sources))
|
||||||
|
|
||||||
err = cli.ManifestCreate(ctx, input.Push, input.Tag, input.Sources...)
|
err = cli.ManifestCreate(ctx, input.Push, input.Tag, input.Sources...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return state, fmt.Errorf("creating: %w", err)
|
return state, fmt.Errorf("creating: %w", err)
|
||||||
@@ -160,6 +163,7 @@ func (i *Index) Read(
|
|||||||
state.Ref = input.Tag
|
state.Ref = input.Tag
|
||||||
|
|
||||||
if !input.Push {
|
if !input.Push {
|
||||||
|
ctx.Log(diag.Debug, "skipping read because index was not pushed")
|
||||||
return name, input, state, nil // Nothing to read.
|
return name, input, state, nil // Nothing to read.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +172,8 @@ func (i *Index) Read(
|
|||||||
return name, input, state, err
|
return name, input, state, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.Log(diag.Debug, fmt.Sprintf("reading index with tag %s", input.Tag))
|
||||||
|
|
||||||
digest, err := cli.ManifestInspect(ctx, input.Tag)
|
digest, err := cli.ManifestInspect(ctx, input.Tag)
|
||||||
if err != nil && strings.Contains(err.Error(), "No such manifest:") && input.Push {
|
if err != nil && strings.Contains(err.Error(), "No such manifest:") && input.Push {
|
||||||
// A remote tag was expected but isn't there -- delete the resource.
|
// A remote tag was expected but isn't there -- delete the resource.
|
||||||
@@ -175,7 +181,7 @@ func (i *Index) Read(
|
|||||||
}
|
}
|
||||||
if err != nil && strings.Contains(err.Error(), "No such manifest:") && !input.Push {
|
if err != nil && strings.Contains(err.Error(), "No such manifest:") && !input.Push {
|
||||||
// Nothing was pushed, so just use the tag without digest..
|
// Nothing was pushed, so just use the tag without digest..
|
||||||
return name, input, state, err
|
return name, input, state, nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return name, input, state, err
|
return name, input, state, err
|
||||||
@@ -295,7 +301,7 @@ func (i *Index) Diff(
|
|||||||
// of any host-level credentials.
|
// of any host-level credentials.
|
||||||
func (i *Index) client(
|
func (i *Index) client(
|
||||||
ctx provider.Context,
|
ctx provider.Context,
|
||||||
state IndexState,
|
_ IndexState,
|
||||||
args IndexArgs,
|
args IndexArgs,
|
||||||
) (Client, error) {
|
) (Client, error) {
|
||||||
cfg := infer.GetConfig[Config](ctx)
|
cfg := infer.GetConfig[Config](ctx)
|
||||||
@@ -308,9 +314,6 @@ func (i *Index) client(
|
|||||||
// build a slice in reverse order because wrap() will overwrite earlier
|
// build a slice in reverse order because wrap() will overwrite earlier
|
||||||
// entries with later ones.
|
// entries with later ones.
|
||||||
auths := []Registry{}
|
auths := []Registry{}
|
||||||
if state.Registry != nil {
|
|
||||||
auths = append(auths, *state.Registry)
|
|
||||||
}
|
|
||||||
auths = append(auths, cfg.Registries...)
|
auths = append(auths, cfg.Registries...)
|
||||||
if args.Registry != nil {
|
if args.Registry != nil {
|
||||||
auths = append(auths, *args.Registry)
|
auths = append(auths, *args.Registry)
|
||||||
|
|||||||
1
sdk/go/dockerbuild/config/config.go
generated
1
sdk/go/dockerbuild/config/config.go
generated
@@ -4,7 +4,6 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
dockerbuild "github.com/pulumi/pulumi-docker-build/sdk/go/dockerbuild"
|
|
||||||
"github.com/pulumi/pulumi-docker-build/sdk/go/dockerbuild/internal"
|
"github.com/pulumi/pulumi-docker-build/sdk/go/dockerbuild/internal"
|
||||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
|
||||||
|
|||||||
1
sdk/go/dockerbuild/x/config/config.go
generated
1
sdk/go/dockerbuild/x/config/config.go
generated
@@ -4,7 +4,6 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
dockerbuild "github.com/pulumi/pulumi-docker-build/sdk/go/dockerbuild"
|
|
||||||
"github.com/pulumi/pulumi-docker-build/sdk/go/dockerbuild/internal"
|
"github.com/pulumi/pulumi-docker-build/sdk/go/dockerbuild/internal"
|
||||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
|
||||||
|
|||||||
Reference in New Issue
Block a user