Skip to content

Commit

Permalink
Restore Image.repoDigest output
Browse files Browse the repository at this point in the history
The Image.repoDigest property was removed in v4 as part of the
transition to use the Docker SDK instead of the Docker CLI. Fortunately
the SDK exposes a method that makes it easy to construct the repo
digest.

Fix #507.

Co-authored-by: Aaron Friel <mayreply@aaronfriel.com>
  • Loading branch information
benesch and AaronFriel committed Mar 16, 2023
1 parent 930d965 commit bc43269
Show file tree
Hide file tree
Showing 14 changed files with 75 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/aws-container-registry/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ const image = new docker.Image("my-image", {

// Export the resulting image name
export const imageName = image.imageName;
export const imageRepoDigest = image.repoDigest;
1 change: 1 addition & 0 deletions examples/docker-container-registry/csharp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Program
return new Dictionary<string, object>
{
{ "imageName", image.ImageName },
{ "repoDigest", image.RepoDigest },
};
});
}
1 change: 1 addition & 0 deletions examples/docker-container-registry/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func main() {

// Export the resulting image name and tag.
ctx.Export("imageName", image.ImageName)
ctx.Export("repoDigest", image.RepoDigest)
return nil
})
}
1 change: 1 addition & 0 deletions examples/docker-container-registry/py/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ def get_registry_info(token):

# Export the resulting image name
pulumi.export('fullImageName', image.image_name)
pulumi.export('repoDigest', image.repo_digest)
1 change: 1 addition & 0 deletions examples/docker-container-registry/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ const image = new docker.Image("my-image", {

// Export the resulting image name
export const fullImageName = image.imageName;
export const repoDigest = image.repoDigest;
6 changes: 6 additions & 0 deletions examples/examples_nodejs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"testing"

"github.com/pulumi/pulumi/pkg/v3/testing/integration"
"github.com/stretchr/testify/assert"
)

func TestNginxTs(t *testing.T) {
Expand Down Expand Up @@ -70,6 +71,11 @@ func TestAwsContainerRegistry(t *testing.T) {
Config: map[string]string{
"aws:region": region,
},
ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
digest, ok := stack.Outputs["imageRepoDigest"].(string)
assert.True(t, ok)
assert.NotEmpty(t, digest)
},
})

integration.ProgramTest(t, &test)
Expand Down
4 changes: 4 additions & 0 deletions provider/cmd/pulumi-resource-docker/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4429,6 +4429,10 @@
"registryServer": {
"type": "string",
"description": "The name of the registry server hosting the image."
},
"repoDigest": {
"type": "string",
"description": "The digest of the manifest pushed to the registry, e.g.: repo[:tag]@\u003calgorithm\u003e:\u003chash\u003e"
}
},
"type": "object",
Expand Down
13 changes: 13 additions & 0 deletions provider/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,24 @@ func (p *dockerNativeProvider) dockerBuild(ctx context.Context,
}
}

dist, _, err := docker.ImageInspectWithRaw(ctx, img.Name)
if err != nil {
return "", nil, err
}

// The repoDigest should be populated after a push. Clients may choose to throw an error or coerce
// this to a non-optional value.
repoDigest := resource.NewNullProperty()
if len(dist.RepoDigests) > 0 {
repoDigest = resource.NewStringProperty(dist.RepoDigests[0])
}

outputs := map[string]interface{}{
"dockerfile": img.Build.Dockerfile,
"context": img.Build.Context,
"baseImageName": img.Name,
"registryServer": img.Registry.Server,
"repoDigest": repoDigest,
}
pbstruct, err := plugin.MarshalProperties(
resource.NewPropertyMapFromMap(outputs),
Expand Down
4 changes: 4 additions & 0 deletions provider/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ func Provider() tfbridge.ProviderInfo {
Description: "The fully qualified image name that was pushed to the registry.",
TypeSpec: schema.TypeSpec{Type: "string"},
},
"repoDigest": {
Description: "The digest of the manifest pushed to the registry, e.g.: repo[:tag]@<algorithm>:<hash>",
TypeSpec: schema.TypeSpec{Type: "string"},
},
},
},
IsComponent: false,
Expand Down
6 changes: 6 additions & 0 deletions sdk/dotnet/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ public partial class Image : global::Pulumi.CustomResource
[Output("registryServer")]
public Output<string?> RegistryServer { get; private set; } = null!;

/// <summary>
/// The digest of the manifest pushed to the registry, e.g.: repo[:tag]@&lt;algorithm&gt;:&lt;hash&gt;
/// </summary>
[Output("repoDigest")]
public Output<string?> RepoDigest { get; private set; } = null!;


/// <summary>
/// Create a Image resource with the given unique name, arguments, and options.
Expand Down
7 changes: 7 additions & 0 deletions sdk/go/docker/image.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions sdk/java/src/main/java/com/pulumi/docker/Image.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ public Output<Optional<String>> imageName() {
public Output<Optional<String>> registryServer() {
return Codegen.optional(this.registryServer);
}
/**
* The digest of the manifest pushed to the registry, e.g.: repo[:tag]@&lt;algorithm&gt;:&lt;hash&gt;
*
*/
@Export(name="repoDigest", type=String.class, parameters={})
private Output</* @Nullable */ String> repoDigest;

/**
* @return The digest of the manifest pushed to the registry, e.g.: repo[:tag]@&lt;algorithm&gt;:&lt;hash&gt;
*
*/
public Output<Optional<String>> repoDigest() {
return Codegen.optional(this.repoDigest);
}

/**
*
Expand Down
6 changes: 6 additions & 0 deletions sdk/nodejs/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ export class Image extends pulumi.CustomResource {
* The name of the registry server hosting the image.
*/
public /*out*/ readonly registryServer!: pulumi.Output<string | undefined>;
/**
* The digest of the manifest pushed to the registry, e.g.: repo[:tag]@<algorithm>:<hash>
*/
public /*out*/ readonly repoDigest!: pulumi.Output<string | undefined>;

/**
* Create a Image resource with the given unique name, arguments, and options.
Expand All @@ -88,10 +92,12 @@ export class Image extends pulumi.CustomResource {
resourceInputs["skipPush"] = (args ? args.skipPush : undefined) ?? false;
resourceInputs["baseImageName"] = undefined /*out*/;
resourceInputs["registryServer"] = undefined /*out*/;
resourceInputs["repoDigest"] = undefined /*out*/;
} else {
resourceInputs["baseImageName"] = undefined /*out*/;
resourceInputs["imageName"] = undefined /*out*/;
resourceInputs["registryServer"] = undefined /*out*/;
resourceInputs["repoDigest"] = undefined /*out*/;
}
opts = pulumi.mergeOptions(utilities.resourceOptsDefaults(), opts);
const aliasOpts = { aliases: [{ type: "docker:image:Image" }] };
Expand Down
10 changes: 10 additions & 0 deletions sdk/python/pulumi_docker/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ def _internal_init(__self__,
__props__.__dict__["skip_push"] = skip_push
__props__.__dict__["base_image_name"] = None
__props__.__dict__["registry_server"] = None
__props__.__dict__["repo_digest"] = None
alias_opts = pulumi.ResourceOptions(aliases=[pulumi.Alias(type_="docker:image:Image")])
opts = pulumi.ResourceOptions.merge(opts, alias_opts)
super(Image, __self__).__init__(
Expand Down Expand Up @@ -212,6 +213,7 @@ def get(resource_name: str,
__props__.__dict__["base_image_name"] = None
__props__.__dict__["image_name"] = None
__props__.__dict__["registry_server"] = None
__props__.__dict__["repo_digest"] = None
return Image(resource_name, opts=opts, __props__=__props__)

@property
Expand All @@ -238,3 +240,11 @@ def registry_server(self) -> pulumi.Output[Optional[str]]:
"""
return pulumi.get(self, "registry_server")

@property
@pulumi.getter(name="repoDigest")
def repo_digest(self) -> pulumi.Output[Optional[str]]:
"""
The digest of the manifest pushed to the registry, e.g.: repo[:tag]@<algorithm>:<hash>
"""
return pulumi.get(self, "repo_digest")

0 comments on commit bc43269

Please sign in to comment.