No-op during Read if credentials are invalid (#194)
The `Image` resource already ignores errors during read but the `Index` resource was requiring the inspect call to always succeed. This will often fail due to https://github.com/pulumi/pulumi/issues/4981 (note however in this case credentials are stored with the resource instead of the provider). This changes our logic to instead emit a warning if the credentials are invalid. Fixes https://github.com/pulumi/pulumi-docker-build/issues/121.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -46,27 +46,27 @@ import pulumi_docker_build as docker_build
|
||||
ecr_repository = aws.ecr.Repository("ecr-repository")
|
||||
auth_token = aws.ecr.get_authorization_token_output(registry_id=ecr_repository.registry_id)
|
||||
my_image = docker_build.Image("my-image",
|
||||
cache_from=[docker_build.CacheFromArgs(
|
||||
registry=docker_build.CacheFromRegistryArgs(
|
||||
ref=ecr_repository.repository_url.apply(lambda repository_url: f"{repository_url}:cache"),
|
||||
),
|
||||
)],
|
||||
cache_to=[docker_build.CacheToArgs(
|
||||
registry=docker_build.CacheToRegistryArgs(
|
||||
image_manifest=True,
|
||||
oci_media_types=True,
|
||||
ref=ecr_repository.repository_url.apply(lambda repository_url: f"{repository_url}:cache"),
|
||||
),
|
||||
)],
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
cache_from=[{
|
||||
"registry": {
|
||||
"ref": ecr_repository.repository_url.apply(lambda repository_url: f"{repository_url}:cache"),
|
||||
},
|
||||
}],
|
||||
cache_to=[{
|
||||
"registry": {
|
||||
"image_manifest": True,
|
||||
"oci_media_types": True,
|
||||
"ref": ecr_repository.repository_url.apply(lambda repository_url: f"{repository_url}:cache"),
|
||||
},
|
||||
}],
|
||||
context={
|
||||
"location": "./app",
|
||||
},
|
||||
push=True,
|
||||
registries=[docker_build.RegistryArgs(
|
||||
address=ecr_repository.repository_url,
|
||||
password=auth_token.password,
|
||||
username=auth_token.user_name,
|
||||
)],
|
||||
registries=[{
|
||||
"address": ecr_repository.repository_url,
|
||||
"password": auth_token.password,
|
||||
"username": auth_token.user_name,
|
||||
}],
|
||||
tags=[ecr_repository.repository_url.apply(lambda repository_url: f"{repository_url}:latest")])
|
||||
pulumi.export("ref", my_image.ref)
|
||||
```
|
||||
@@ -277,7 +277,7 @@ public class App {
|
||||
.registryId(ecrRepository.registryId())
|
||||
.build());
|
||||
|
||||
var myImage = new Image("myImage", ImageArgs.builder()
|
||||
var myImage = new Image("myImage", ImageArgs.builder()
|
||||
.cacheFrom(CacheFromArgs.builder()
|
||||
.registry(CacheFromRegistryArgs.builder()
|
||||
.ref(ecrRepository.repositoryUrl().applyValue(repositoryUrl -> String.format("%s:cache", repositoryUrl)))
|
||||
@@ -330,9 +330,9 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
image = docker_build.Image("image",
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
),
|
||||
context={
|
||||
"location": "app",
|
||||
},
|
||||
platforms=[
|
||||
docker_build.Platform.PLAN9_AMD64,
|
||||
docker_build.Platform.PLAN9_386,
|
||||
@@ -428,7 +428,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("app")
|
||||
.build())
|
||||
@@ -468,15 +468,15 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
image = docker_build.Image("image",
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
),
|
||||
context={
|
||||
"location": "app",
|
||||
},
|
||||
push=True,
|
||||
registries=[docker_build.RegistryArgs(
|
||||
address="docker.io",
|
||||
password=docker_hub_password,
|
||||
username="pulumibot",
|
||||
)],
|
||||
registries=[{
|
||||
"address": "docker.io",
|
||||
"password": docker_hub_password,
|
||||
"username": "pulumibot",
|
||||
}],
|
||||
tags=["docker.io/pulumi/pulumi:3.107.0"])
|
||||
pulumi.export("ref", my_image["ref"])
|
||||
```
|
||||
@@ -594,7 +594,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("app")
|
||||
.build())
|
||||
@@ -642,20 +642,20 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
image = docker_build.Image("image",
|
||||
cache_from=[docker_build.CacheFromArgs(
|
||||
local=docker_build.CacheFromLocalArgs(
|
||||
src="tmp/cache",
|
||||
),
|
||||
)],
|
||||
cache_to=[docker_build.CacheToArgs(
|
||||
local=docker_build.CacheToLocalArgs(
|
||||
dest="tmp/cache",
|
||||
mode=docker_build.CacheMode.MAX,
|
||||
),
|
||||
)],
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
),
|
||||
cache_from=[{
|
||||
"local": {
|
||||
"src": "tmp/cache",
|
||||
},
|
||||
}],
|
||||
cache_to=[{
|
||||
"local": {
|
||||
"dest": "tmp/cache",
|
||||
"mode": docker_build.CacheMode.MAX,
|
||||
},
|
||||
}],
|
||||
context={
|
||||
"location": "app",
|
||||
},
|
||||
push=False)
|
||||
```
|
||||
```csharp
|
||||
@@ -782,7 +782,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.cacheFrom(CacheFromArgs.builder()
|
||||
.local(CacheFromLocalArgs.builder()
|
||||
.src("tmp/cache")
|
||||
@@ -827,12 +827,12 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
image = docker_build.Image("image",
|
||||
builder=docker_build.BuilderConfigArgs(
|
||||
name="cloud-builder-name",
|
||||
),
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
),
|
||||
builder={
|
||||
"name": "cloud-builder-name",
|
||||
},
|
||||
context={
|
||||
"location": "app",
|
||||
},
|
||||
exec_=True,
|
||||
push=False)
|
||||
```
|
||||
@@ -926,7 +926,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.builder(BuilderConfigArgs.builder()
|
||||
.name("cloud-builder-name")
|
||||
.build())
|
||||
@@ -966,9 +966,9 @@ image = docker_build.Image("image",
|
||||
build_args={
|
||||
"SET_ME_TO_TRUE": "true",
|
||||
},
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
),
|
||||
context={
|
||||
"location": "app",
|
||||
},
|
||||
push=False)
|
||||
```
|
||||
```csharp
|
||||
@@ -1057,7 +1057,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.buildArgs(Map.of("SET_ME_TO_TRUE", "true"))
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("app")
|
||||
@@ -1089,9 +1089,9 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
image = docker_build.Image("image",
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
),
|
||||
context={
|
||||
"location": "app",
|
||||
},
|
||||
push=False,
|
||||
target="build-me")
|
||||
```
|
||||
@@ -1175,7 +1175,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("app")
|
||||
.build())
|
||||
@@ -1211,14 +1211,14 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
image = docker_build.Image("image",
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
named={
|
||||
"golang:latest": docker_build.ContextArgs(
|
||||
location="docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984",
|
||||
),
|
||||
context={
|
||||
"location": "app",
|
||||
"named": {
|
||||
"golang_latest": {
|
||||
"location": "docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984",
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
push=False)
|
||||
```
|
||||
```csharp
|
||||
@@ -1313,7 +1313,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("app")
|
||||
.named(Map.of("golang:latest", Map.of("location", "docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984")))
|
||||
@@ -1344,9 +1344,9 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
image = docker_build.Image("image",
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile",
|
||||
),
|
||||
context={
|
||||
"location": "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile",
|
||||
},
|
||||
push=False)
|
||||
```
|
||||
```csharp
|
||||
@@ -1426,7 +1426,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile")
|
||||
.build())
|
||||
@@ -1461,14 +1461,14 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
image = docker_build.Image("image",
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
),
|
||||
dockerfile=docker_build.DockerfileArgs(
|
||||
inline="""FROM busybox
|
||||
context={
|
||||
"location": "app",
|
||||
},
|
||||
dockerfile={
|
||||
"inline": """FROM busybox
|
||||
COPY hello.c ./
|
||||
""",
|
||||
),
|
||||
},
|
||||
push=False)
|
||||
```
|
||||
```csharp
|
||||
@@ -1562,7 +1562,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("app")
|
||||
.build())
|
||||
@@ -1601,12 +1601,12 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
image = docker_build.Image("image",
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="https://github.com/docker-library/hello-world.git",
|
||||
),
|
||||
dockerfile=docker_build.DockerfileArgs(
|
||||
location="app/Dockerfile",
|
||||
),
|
||||
context={
|
||||
"location": "https://github.com/docker-library/hello-world.git",
|
||||
},
|
||||
dockerfile={
|
||||
"location": "app/Dockerfile",
|
||||
},
|
||||
push=False)
|
||||
```
|
||||
```csharp
|
||||
@@ -1696,7 +1696,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("https://github.com/docker-library/hello-world.git")
|
||||
.build())
|
||||
@@ -1734,14 +1734,14 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
image = docker_build.Image("image",
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
),
|
||||
exports=[docker_build.ExportArgs(
|
||||
docker=docker_build.ExportDockerArgs(
|
||||
tar=True,
|
||||
),
|
||||
)],
|
||||
context={
|
||||
"location": "app",
|
||||
},
|
||||
exports=[{
|
||||
"docker": {
|
||||
"tar": True,
|
||||
},
|
||||
}],
|
||||
push=False)
|
||||
```
|
||||
```csharp
|
||||
@@ -1843,7 +1843,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
var image = new Image("image", ImageArgs.builder()
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("app")
|
||||
.build())
|
||||
|
||||
@@ -57,37 +57,37 @@ import pulumi
|
||||
import pulumi_docker_build as docker_build
|
||||
|
||||
amd64 = docker_build.Image("amd64",
|
||||
cache_from=[docker_build.CacheFromArgs(
|
||||
registry=docker_build.CacheFromRegistryArgs(
|
||||
ref="docker.io/pulumi/pulumi:cache-amd64",
|
||||
),
|
||||
)],
|
||||
cache_to=[docker_build.CacheToArgs(
|
||||
registry=docker_build.CacheToRegistryArgs(
|
||||
mode=docker_build.CacheMode.MAX,
|
||||
ref="docker.io/pulumi/pulumi:cache-amd64",
|
||||
),
|
||||
)],
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
),
|
||||
cache_from=[{
|
||||
"registry": {
|
||||
"ref": "docker.io/pulumi/pulumi:cache-amd64",
|
||||
},
|
||||
}],
|
||||
cache_to=[{
|
||||
"registry": {
|
||||
"mode": docker_build.CacheMode.MAX,
|
||||
"ref": "docker.io/pulumi/pulumi:cache-amd64",
|
||||
},
|
||||
}],
|
||||
context={
|
||||
"location": "app",
|
||||
},
|
||||
platforms=[docker_build.Platform.LINUX_AMD64],
|
||||
tags=["docker.io/pulumi/pulumi:3.107.0-amd64"])
|
||||
arm64 = docker_build.Image("arm64",
|
||||
cache_from=[docker_build.CacheFromArgs(
|
||||
registry=docker_build.CacheFromRegistryArgs(
|
||||
ref="docker.io/pulumi/pulumi:cache-arm64",
|
||||
),
|
||||
)],
|
||||
cache_to=[docker_build.CacheToArgs(
|
||||
registry=docker_build.CacheToRegistryArgs(
|
||||
mode=docker_build.CacheMode.MAX,
|
||||
ref="docker.io/pulumi/pulumi:cache-arm64",
|
||||
),
|
||||
)],
|
||||
context=docker_build.BuildContextArgs(
|
||||
location="app",
|
||||
),
|
||||
cache_from=[{
|
||||
"registry": {
|
||||
"ref": "docker.io/pulumi/pulumi:cache-arm64",
|
||||
},
|
||||
}],
|
||||
cache_to=[{
|
||||
"registry": {
|
||||
"mode": docker_build.CacheMode.MAX,
|
||||
"ref": "docker.io/pulumi/pulumi:cache-arm64",
|
||||
},
|
||||
}],
|
||||
context={
|
||||
"location": "app",
|
||||
},
|
||||
platforms=[docker_build.Platform.LINUX_ARM64],
|
||||
tags=["docker.io/pulumi/pulumi:3.107.0-arm64"])
|
||||
index = docker_build.Index("index",
|
||||
@@ -355,7 +355,7 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var amd64 = new Image("amd64", ImageArgs.builder()
|
||||
var amd64 = new Image("amd64", ImageArgs.builder()
|
||||
.cacheFrom(CacheFromArgs.builder()
|
||||
.registry(CacheFromRegistryArgs.builder()
|
||||
.ref("docker.io/pulumi/pulumi:cache-amd64")
|
||||
@@ -374,7 +374,7 @@ public class App {
|
||||
.tags("docker.io/pulumi/pulumi:3.107.0-amd64")
|
||||
.build());
|
||||
|
||||
var arm64 = new Image("arm64", ImageArgs.builder()
|
||||
var arm64 = new Image("arm64", ImageArgs.builder()
|
||||
.cacheFrom(CacheFromArgs.builder()
|
||||
.registry(CacheFromRegistryArgs.builder()
|
||||
.ref("docker.io/pulumi/pulumi:cache-arm64")
|
||||
@@ -393,7 +393,7 @@ public class App {
|
||||
.tags("docker.io/pulumi/pulumi:3.107.0-arm64")
|
||||
.build());
|
||||
|
||||
var index = new Index("index", IndexArgs.builder()
|
||||
var index = new Index("index", IndexArgs.builder()
|
||||
.sources(
|
||||
amd64.ref(),
|
||||
arm64.ref())
|
||||
|
||||
@@ -802,6 +802,7 @@ func (i *Image) Read(
|
||||
continue
|
||||
}
|
||||
|
||||
//nolint:gocritic // Bytes aren't copied in a hot path.
|
||||
for _, d := range descriptors {
|
||||
if d.Platform != nil && d.Platform.Architecture == "unknown" {
|
||||
// Ignore cache manifests.
|
||||
|
||||
@@ -16,6 +16,7 @@ package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -23,6 +24,8 @@ import (
|
||||
// For examples/docs.
|
||||
_ "embed"
|
||||
|
||||
"github.com/regclient/regclient/types/errs"
|
||||
|
||||
provider "github.com/pulumi/pulumi-go-provider"
|
||||
"github.com/pulumi/pulumi-go-provider/infer"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
||||
@@ -194,12 +197,12 @@ func (i *Index) Read(
|
||||
provider.GetLogger(ctx).Debug("reading index with tag " + input.Tag)
|
||||
|
||||
digest, err := cli.ManifestInspect(ctx, input.Tag)
|
||||
if err != nil && strings.Contains(err.Error(), "No such manifest:") && input.isPushed() {
|
||||
if errors.Is(err, errs.ErrNotFound) {
|
||||
// A remote tag was expected but isn't there -- delete the resource.
|
||||
return "", input, state, err
|
||||
return "", input, state, nil
|
||||
}
|
||||
if err != nil && strings.Contains(err.Error(), "No such manifest:") && !input.isPushed() {
|
||||
// Nothing was pushed, so just use the tag without digest..
|
||||
if errors.Is(err, errs.ErrHTTPUnauthorized) {
|
||||
provider.GetLogger(ctx).Warning("invalid credentials, skipping")
|
||||
return name, input, state, nil
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
@@ -18,8 +18,10 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/regclient/regclient/types/errs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
|
||||
provider "github.com/pulumi/pulumi-go-provider"
|
||||
"github.com/pulumi/pulumi-go-provider/integration"
|
||||
@@ -84,6 +86,40 @@ func TestIndexLifecycle(t *testing.T) {
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "expired credentials",
|
||||
client: func(t *testing.T) Client {
|
||||
ctrl := gomock.NewController(t)
|
||||
c := NewMockClient(ctrl)
|
||||
c.EXPECT().ManifestCreate(gomock.Any(), true, gomock.Any(), gomock.Any())
|
||||
c.EXPECT().ManifestInspect(gomock.Any(), gomock.Any()).Return("", errs.ErrHTTPUnauthorized)
|
||||
c.EXPECT().ManifestDelete(gomock.Any(), gomock.Any()).Return(nil)
|
||||
return c
|
||||
},
|
||||
op: func(t *testing.T) integration.Operation {
|
||||
return integration.Operation{
|
||||
Inputs: resource.PropertyMap{
|
||||
"tag": resource.NewStringProperty(
|
||||
"docker.io/pulumibot/buildkit-e2e:manifest",
|
||||
),
|
||||
"sources": resource.NewArrayProperty([]resource.PropertyValue{
|
||||
resource.NewStringProperty("docker.io/pulumibot/buildkit-e2e:arm64"),
|
||||
resource.NewStringProperty("docker.io/pulumibot/buildkit-e2e:amd64"),
|
||||
}),
|
||||
"push": resource.NewBoolProperty(true),
|
||||
"registry": resource.NewObjectProperty(resource.PropertyMap{
|
||||
"address": resource.NewStringProperty("docker.io"),
|
||||
"username": resource.NewStringProperty("pulumibot"),
|
||||
"password": resource.NewSecretProperty(&resource.Secret{
|
||||
Element: resource.NewStringProperty(
|
||||
os.Getenv("DOCKER_HUB_PASSWORD"),
|
||||
),
|
||||
}),
|
||||
}),
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
Reference in New Issue
Block a user