diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index c38d6a00..b61e800e 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -506,6 +506,8 @@ jobs: uses: webfactory/ssh-agent@v0.7.0 with: ssh-private-key: ${{ secrets.PRIVATE_SSH_KEY_FOR_DIGITALOCEAN }} + - name: Expose GitHub Actions runtime + uses: crazy-max/ghaction-github-runtime@v3 - name: Run tests run: cd examples && go test -v -json -count=1 -cover -timeout 2h -tags=${{ matrix.language }} -parallel 4 . 2>&1 | tee /tmp/gotest.log | gotestfmt diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index 7b701bd6..1f9f51d0 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -426,6 +426,8 @@ jobs: uses: webfactory/ssh-agent@v0.7.0 with: ssh-private-key: ${{ secrets.PRIVATE_SSH_KEY_FOR_DIGITALOCEAN }} + - name: Expose GitHub Actions runtime + uses: crazy-max/ghaction-github-runtime@v3 - name: Run tests run: cd examples && go test -v -json -count=1 -cover -timeout 2h -tags=${{ matrix.language }} -parallel 4 . 2>&1 | tee /tmp/gotest.log | gotestfmt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f77a33a..cc0e6fee 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -474,6 +474,8 @@ jobs: uses: webfactory/ssh-agent@v0.7.0 with: ssh-private-key: ${{ secrets.PRIVATE_SSH_KEY_FOR_DIGITALOCEAN }} + - name: Expose GitHub Actions runtime + uses: crazy-max/ghaction-github-runtime@v3 - name: Run tests run: cd examples && go test -v -json -count=1 -cover -timeout 2h -tags=${{ matrix.language }} -parallel 4 . 2>&1 | tee /tmp/gotest.log | gotestfmt diff --git a/.github/workflows/run-acceptance-tests.yml b/.github/workflows/run-acceptance-tests.yml index f01d8c75..88deefe4 100644 --- a/.github/workflows/run-acceptance-tests.yml +++ b/.github/workflows/run-acceptance-tests.yml @@ -423,6 +423,8 @@ jobs: uses: webfactory/ssh-agent@v0.7.0 with: ssh-private-key: ${{ secrets.PRIVATE_SSH_KEY_FOR_DIGITALOCEAN }} + - name: Expose GitHub Actions runtime + uses: crazy-max/ghaction-github-runtime@v3 - name: Run tests if: matrix.testTarget == 'local' run: cd examples && go test -v -json -count=1 -cover -timeout 2h -tags=${{ diff --git a/examples/buildx/app/Dockerfile b/examples/buildx/app/Dockerfile new file mode 100644 index 00000000..e17a80c7 --- /dev/null +++ b/examples/buildx/app/Dockerfile @@ -0,0 +1,2 @@ +FROM alpine +RUN echo 👍 diff --git a/examples/buildx/app/Dockerfile.buildArgs b/examples/buildx/app/Dockerfile.buildArgs new file mode 100644 index 00000000..438ee017 --- /dev/null +++ b/examples/buildx/app/Dockerfile.buildArgs @@ -0,0 +1,5 @@ +FROM alpine + +ARG SET_ME_TO_TRUE +RUN [ "$SET_ME_TO_TRUE" = "true" ] +RUN echo "That's the correct build arg, thanks! 👍" diff --git a/examples/buildx/app/Dockerfile.emptyContext b/examples/buildx/app/Dockerfile.emptyContext new file mode 100644 index 00000000..769593b2 --- /dev/null +++ b/examples/buildx/app/Dockerfile.emptyContext @@ -0,0 +1,2 @@ +FROM alpine +RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍" diff --git a/examples/buildx/app/Dockerfile.extraHosts b/examples/buildx/app/Dockerfile.extraHosts new file mode 100644 index 00000000..35b15f4e --- /dev/null +++ b/examples/buildx/app/Dockerfile.extraHosts @@ -0,0 +1,3 @@ +FROM bash AS base + +RUN getent hosts metadata.google.internal diff --git a/examples/buildx/app/Dockerfile.multiPlatform b/examples/buildx/app/Dockerfile.multiPlatform new file mode 100644 index 00000000..49d3c839 --- /dev/null +++ b/examples/buildx/app/Dockerfile.multiPlatform @@ -0,0 +1,7 @@ +FROM --platform=$BUILDPLATFORM alpine as build +RUN echo ${BUILDPLATFORM} > buildplatform +RUN echo ${TARGETPLATFORM} > targetplatform + +FROM build +RUN cat buildplatform +RUN cat targetplatform diff --git a/examples/buildx/app/Dockerfile.namedContexts b/examples/buildx/app/Dockerfile.namedContexts new file mode 100644 index 00000000..6e53dba1 --- /dev/null +++ b/examples/buildx/app/Dockerfile.namedContexts @@ -0,0 +1,5 @@ +# syntax=docker/dockerfile:1.4 +FROM golang:latest + +RUN version="$(go version)" && echo $version && [ "$version" = "go version go1.21.7 linux/amd64" ] +RUN echo "This image uses named contexts to pin golang:latest to a specific SHA 👍" diff --git a/examples/buildx/app/Dockerfile.secrets b/examples/buildx/app/Dockerfile.secrets new file mode 100644 index 00000000..513bbd26 --- /dev/null +++ b/examples/buildx/app/Dockerfile.secrets @@ -0,0 +1,4 @@ +FROM alpine + +RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ] + diff --git a/examples/buildx/app/Dockerfile.sshMount b/examples/buildx/app/Dockerfile.sshMount new file mode 100644 index 00000000..055cb780 --- /dev/null +++ b/examples/buildx/app/Dockerfile.sshMount @@ -0,0 +1,5 @@ +FROM alpine + +RUN apk add openssh-client + +RUN --mount=type=ssh ssh-add -l diff --git a/examples/buildx/app/Dockerfile.targets b/examples/buildx/app/Dockerfile.targets new file mode 100644 index 00000000..7cddec71 --- /dev/null +++ b/examples/buildx/app/Dockerfile.targets @@ -0,0 +1,8 @@ +FROM alpine as build-me +RUN echo 👍 + +FROM build-me as also-build-me +RUN echo 🤙 + +FROM build-me as dont-build-me +RUN [ "true" = "false" ] diff --git a/examples/buildx/csharp/.gitignore b/examples/buildx/csharp/.gitignore new file mode 100644 index 00000000..e6452706 --- /dev/null +++ b/examples/buildx/csharp/.gitignore @@ -0,0 +1,353 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ diff --git a/examples/buildx/csharp/Program.cs b/examples/buildx/csharp/Program.cs new file mode 100644 index 00000000..20204856 --- /dev/null +++ b/examples/buildx/csharp/Program.cs @@ -0,0 +1,262 @@ +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Docker = Pulumi.Docker; + +return await Deployment.RunAsync(() => +{ + var config = new Config(); + var dockerHubPassword = config.Require("dockerHubPassword"); + var multiPlatform = new Docker.Buildx.Image("multiPlatform", new() + { + Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs + { + Location = "app/Dockerfile.multiPlatform", + }, + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + Platforms = new[] + { + Docker.Buildx.Platform.Plan9_amd64, + Docker.Buildx.Platform.Plan9_386, + }, + }); + + var registryPush = new Docker.Buildx.Image("registryPush", new() + { + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + Tags = new[] + { + "docker.io/pulumibot/buildkit-e2e:example", + }, + Exports = new[] + { + new Docker.Buildx.Inputs.ExportEntryArgs + { + Registry = new Docker.Buildx.Inputs.ExportRegistryArgs + { + OciMediaTypes = true, + Push = false, + }, + }, + }, + Registries = new[] + { + new Docker.Buildx.Inputs.RegistryAuthArgs + { + Address = "docker.io", + Username = "pulumibot", + Password = dockerHubPassword, + }, + }, + }); + + var cached = new Docker.Buildx.Image("cached", new() + { + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + CacheTo = new[] + { + new Docker.Buildx.Inputs.CacheToEntryArgs + { + Local = new Docker.Buildx.Inputs.CacheToLocalArgs + { + Dest = "tmp/cache", + Mode = Docker.Buildx.CacheMode.Max, + }, + }, + }, + CacheFrom = new[] + { + new Docker.Buildx.Inputs.CacheFromEntryArgs + { + Local = new Docker.Buildx.Inputs.CacheFromLocalArgs + { + Src = "tmp/cache", + }, + }, + }, + }); + + var buildArgs = new Docker.Buildx.Image("buildArgs", new() + { + Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs + { + Location = "app/Dockerfile.buildArgs", + }, + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + BuildArgs = + { + { "SET_ME_TO_TRUE", "true" }, + }, + }); + + var extraHosts = new Docker.Buildx.Image("extraHosts", new() + { + Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs + { + Location = "app/Dockerfile.extraHosts", + }, + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + AddHosts = new[] + { + "metadata.google.internal:169.254.169.254", + }, + }); + + var sshMount = new Docker.Buildx.Image("sshMount", new() + { + Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs + { + Location = "app/Dockerfile.sshMount", + }, + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + Ssh = new[] + { + new Docker.Buildx.Inputs.SSHArgs + { + Id = "default", + }, + }, + }); + + var secrets = new Docker.Buildx.Image("secrets", new() + { + Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs + { + Location = "app/Dockerfile.secrets", + }, + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + Secrets = + { + { "password", "hunter2" }, + }, + }); + + var labels = new Docker.Buildx.Image("labels", new() + { + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + Labels = + { + { "description", "This image will get a descriptive label 👍" }, + }, + }); + + var targets = new Docker.Buildx.Image("targets", new() + { + Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs + { + Location = "app/Dockerfile.targets", + }, + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + Targets = new[] + { + "build-me", + "also-build-me", + }, + }); + + var namedContexts = new Docker.Buildx.Image("namedContexts", new() + { + Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs + { + Location = "app/Dockerfile.namedContexts", + }, + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + Named = + { + { "golang:latest", new Docker.Buildx.Inputs.ContextArgs + { + Location = "docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984", + } }, + }, + }, + }); + + var remoteContext = new Docker.Buildx.Image("remoteContext", new() + { + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile", + }, + }); + + var remoteContextWithInline = new Docker.Buildx.Image("remoteContextWithInline", new() + { + Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs + { + Inline = @"FROM busybox +COPY hello.c ./ +", + }, + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "https://github.com/docker-library/hello-world.git", + }, + }); + + var inline = new Docker.Buildx.Image("inline", new() + { + Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs + { + Inline = @"FROM alpine +RUN echo ""This uses an inline Dockerfile! 👍"" +", + }, + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + }); + + var dockerLoad = new Docker.Buildx.Image("dockerLoad", new() + { + Context = new Docker.Buildx.Inputs.BuildContextArgs + { + Location = "app", + }, + Exports = new[] + { + new Docker.Buildx.Inputs.ExportEntryArgs + { + Docker = new Docker.Buildx.Inputs.ExportDockerArgs + { + Tar = true, + }, + }, + }, + }); + + return new Dictionary + { + ["platforms"] = multiPlatform.Platforms, + }; +}); + diff --git a/examples/buildx/csharp/Pulumi.yaml b/examples/buildx/csharp/Pulumi.yaml new file mode 100644 index 00000000..a377f391 --- /dev/null +++ b/examples/buildx/csharp/Pulumi.yaml @@ -0,0 +1,3 @@ +name: buildx-examples +runtime: dotnet +description: Examples of buildx.Image diff --git a/examples/buildx/csharp/app/Dockerfile b/examples/buildx/csharp/app/Dockerfile new file mode 100644 index 00000000..e17a80c7 --- /dev/null +++ b/examples/buildx/csharp/app/Dockerfile @@ -0,0 +1,2 @@ +FROM alpine +RUN echo 👍 diff --git a/examples/buildx/csharp/app/Dockerfile.buildArgs b/examples/buildx/csharp/app/Dockerfile.buildArgs new file mode 100644 index 00000000..438ee017 --- /dev/null +++ b/examples/buildx/csharp/app/Dockerfile.buildArgs @@ -0,0 +1,5 @@ +FROM alpine + +ARG SET_ME_TO_TRUE +RUN [ "$SET_ME_TO_TRUE" = "true" ] +RUN echo "That's the correct build arg, thanks! 👍" diff --git a/examples/buildx/csharp/app/Dockerfile.emptyContext b/examples/buildx/csharp/app/Dockerfile.emptyContext new file mode 100644 index 00000000..769593b2 --- /dev/null +++ b/examples/buildx/csharp/app/Dockerfile.emptyContext @@ -0,0 +1,2 @@ +FROM alpine +RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍" diff --git a/examples/buildx/csharp/app/Dockerfile.extraHosts b/examples/buildx/csharp/app/Dockerfile.extraHosts new file mode 100644 index 00000000..35b15f4e --- /dev/null +++ b/examples/buildx/csharp/app/Dockerfile.extraHosts @@ -0,0 +1,3 @@ +FROM bash AS base + +RUN getent hosts metadata.google.internal diff --git a/examples/buildx/csharp/app/Dockerfile.multiPlatform b/examples/buildx/csharp/app/Dockerfile.multiPlatform new file mode 100644 index 00000000..49d3c839 --- /dev/null +++ b/examples/buildx/csharp/app/Dockerfile.multiPlatform @@ -0,0 +1,7 @@ +FROM --platform=$BUILDPLATFORM alpine as build +RUN echo ${BUILDPLATFORM} > buildplatform +RUN echo ${TARGETPLATFORM} > targetplatform + +FROM build +RUN cat buildplatform +RUN cat targetplatform diff --git a/examples/buildx/csharp/app/Dockerfile.namedContexts b/examples/buildx/csharp/app/Dockerfile.namedContexts new file mode 100644 index 00000000..6e53dba1 --- /dev/null +++ b/examples/buildx/csharp/app/Dockerfile.namedContexts @@ -0,0 +1,5 @@ +# syntax=docker/dockerfile:1.4 +FROM golang:latest + +RUN version="$(go version)" && echo $version && [ "$version" = "go version go1.21.7 linux/amd64" ] +RUN echo "This image uses named contexts to pin golang:latest to a specific SHA 👍" diff --git a/examples/buildx/csharp/app/Dockerfile.secrets b/examples/buildx/csharp/app/Dockerfile.secrets new file mode 100644 index 00000000..513bbd26 --- /dev/null +++ b/examples/buildx/csharp/app/Dockerfile.secrets @@ -0,0 +1,4 @@ +FROM alpine + +RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ] + diff --git a/examples/buildx/csharp/app/Dockerfile.sshMount b/examples/buildx/csharp/app/Dockerfile.sshMount new file mode 100644 index 00000000..055cb780 --- /dev/null +++ b/examples/buildx/csharp/app/Dockerfile.sshMount @@ -0,0 +1,5 @@ +FROM alpine + +RUN apk add openssh-client + +RUN --mount=type=ssh ssh-add -l diff --git a/examples/buildx/csharp/app/Dockerfile.targets b/examples/buildx/csharp/app/Dockerfile.targets new file mode 100644 index 00000000..7cddec71 --- /dev/null +++ b/examples/buildx/csharp/app/Dockerfile.targets @@ -0,0 +1,8 @@ +FROM alpine as build-me +RUN echo 👍 + +FROM build-me as also-build-me +RUN echo 🤙 + +FROM build-me as dont-build-me +RUN [ "true" = "false" ] diff --git a/examples/buildx/csharp/buildx-examples.csproj b/examples/buildx/csharp/buildx-examples.csproj new file mode 100644 index 00000000..2f2a3274 --- /dev/null +++ b/examples/buildx/csharp/buildx-examples.csproj @@ -0,0 +1,14 @@ + + + + Exe + net6.0 + enable + + + + + + + + diff --git a/examples/buildx/go/Pulumi.yaml b/examples/buildx/go/Pulumi.yaml new file mode 100644 index 00000000..8d31364a --- /dev/null +++ b/examples/buildx/go/Pulumi.yaml @@ -0,0 +1,3 @@ +name: buildx-examples +runtime: go +description: Examples of buildx.Image diff --git a/examples/buildx/go/app/Dockerfile b/examples/buildx/go/app/Dockerfile new file mode 100644 index 00000000..e17a80c7 --- /dev/null +++ b/examples/buildx/go/app/Dockerfile @@ -0,0 +1,2 @@ +FROM alpine +RUN echo 👍 diff --git a/examples/buildx/go/app/Dockerfile.buildArgs b/examples/buildx/go/app/Dockerfile.buildArgs new file mode 100644 index 00000000..438ee017 --- /dev/null +++ b/examples/buildx/go/app/Dockerfile.buildArgs @@ -0,0 +1,5 @@ +FROM alpine + +ARG SET_ME_TO_TRUE +RUN [ "$SET_ME_TO_TRUE" = "true" ] +RUN echo "That's the correct build arg, thanks! 👍" diff --git a/examples/buildx/go/app/Dockerfile.emptyContext b/examples/buildx/go/app/Dockerfile.emptyContext new file mode 100644 index 00000000..769593b2 --- /dev/null +++ b/examples/buildx/go/app/Dockerfile.emptyContext @@ -0,0 +1,2 @@ +FROM alpine +RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍" diff --git a/examples/buildx/go/app/Dockerfile.extraHosts b/examples/buildx/go/app/Dockerfile.extraHosts new file mode 100644 index 00000000..35b15f4e --- /dev/null +++ b/examples/buildx/go/app/Dockerfile.extraHosts @@ -0,0 +1,3 @@ +FROM bash AS base + +RUN getent hosts metadata.google.internal diff --git a/examples/buildx/go/app/Dockerfile.multiPlatform b/examples/buildx/go/app/Dockerfile.multiPlatform new file mode 100644 index 00000000..49d3c839 --- /dev/null +++ b/examples/buildx/go/app/Dockerfile.multiPlatform @@ -0,0 +1,7 @@ +FROM --platform=$BUILDPLATFORM alpine as build +RUN echo ${BUILDPLATFORM} > buildplatform +RUN echo ${TARGETPLATFORM} > targetplatform + +FROM build +RUN cat buildplatform +RUN cat targetplatform diff --git a/examples/buildx/go/app/Dockerfile.namedContexts b/examples/buildx/go/app/Dockerfile.namedContexts new file mode 100644 index 00000000..6e53dba1 --- /dev/null +++ b/examples/buildx/go/app/Dockerfile.namedContexts @@ -0,0 +1,5 @@ +# syntax=docker/dockerfile:1.4 +FROM golang:latest + +RUN version="$(go version)" && echo $version && [ "$version" = "go version go1.21.7 linux/amd64" ] +RUN echo "This image uses named contexts to pin golang:latest to a specific SHA 👍" diff --git a/examples/buildx/go/app/Dockerfile.secrets b/examples/buildx/go/app/Dockerfile.secrets new file mode 100644 index 00000000..513bbd26 --- /dev/null +++ b/examples/buildx/go/app/Dockerfile.secrets @@ -0,0 +1,4 @@ +FROM alpine + +RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ] + diff --git a/examples/buildx/go/app/Dockerfile.sshMount b/examples/buildx/go/app/Dockerfile.sshMount new file mode 100644 index 00000000..055cb780 --- /dev/null +++ b/examples/buildx/go/app/Dockerfile.sshMount @@ -0,0 +1,5 @@ +FROM alpine + +RUN apk add openssh-client + +RUN --mount=type=ssh ssh-add -l diff --git a/examples/buildx/go/app/Dockerfile.targets b/examples/buildx/go/app/Dockerfile.targets new file mode 100644 index 00000000..7cddec71 --- /dev/null +++ b/examples/buildx/go/app/Dockerfile.targets @@ -0,0 +1,8 @@ +FROM alpine as build-me +RUN echo 👍 + +FROM build-me as also-build-me +RUN echo 🤙 + +FROM build-me as dont-build-me +RUN [ "true" = "false" ] diff --git a/examples/buildx/go/go.mod b/examples/buildx/go/go.mod new file mode 100644 index 00000000..0019c974 --- /dev/null +++ b/examples/buildx/go/go.mod @@ -0,0 +1,8 @@ +module buildx-examples + +go 1.20 + +require ( + github.com/pulumi/pulumi/sdk/v3 v3.30.0 + github.com/pulumi/pulumi-docker/sdk/v4 v4.6.0-alpha.1708450847+573e3670.dirty +) \ No newline at end of file diff --git a/examples/buildx/go/main.go b/examples/buildx/go/main.go new file mode 100644 index 00000000..92baf8a9 --- /dev/null +++ b/examples/buildx/go/main.go @@ -0,0 +1,225 @@ +package main + +import ( + "github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + cfg := config.New(ctx, "") + dockerHubPassword := cfg.Require("dockerHubPassword") + multiPlatform, err := buildx.NewImage(ctx, "multiPlatform", &buildx.ImageArgs{ + Dockerfile: &buildx.DockerfileArgs{ + Location: pulumi.String("app/Dockerfile.multiPlatform"), + }, + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + Platforms: buildx.PlatformArray{ + buildx.Platform_Plan9_amd64, + buildx.Platform_Plan9_386, + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "registryPush", &buildx.ImageArgs{ + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + Tags: pulumi.StringArray{ + pulumi.String("docker.io/pulumibot/buildkit-e2e:example"), + }, + Exports: buildx.ExportEntryArray{ + &buildx.ExportEntryArgs{ + Registry: &buildx.ExportRegistryArgs{ + OciMediaTypes: pulumi.Bool(true), + Push: pulumi.Bool(false), + }, + }, + }, + Registries: buildx.RegistryAuthArray{ + &buildx.RegistryAuthArgs{ + Address: pulumi.String("docker.io"), + Username: pulumi.String("pulumibot"), + Password: pulumi.String(dockerHubPassword), + }, + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "cached", &buildx.ImageArgs{ + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + CacheTo: buildx.CacheToEntryArray{ + &buildx.CacheToEntryArgs{ + Local: &buildx.CacheToLocalArgs{ + Dest: pulumi.String("tmp/cache"), + Mode: buildx.CacheModeMax, + }, + }, + }, + CacheFrom: buildx.CacheFromEntryArray{ + &buildx.CacheFromEntryArgs{ + Local: &buildx.CacheFromLocalArgs{ + Src: pulumi.String("tmp/cache"), + }, + }, + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "buildArgs", &buildx.ImageArgs{ + Dockerfile: &buildx.DockerfileArgs{ + Location: pulumi.String("app/Dockerfile.buildArgs"), + }, + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + BuildArgs: pulumi.StringMap{ + "SET_ME_TO_TRUE": pulumi.String("true"), + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "extraHosts", &buildx.ImageArgs{ + Dockerfile: &buildx.DockerfileArgs{ + Location: pulumi.String("app/Dockerfile.extraHosts"), + }, + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + AddHosts: pulumi.StringArray{ + pulumi.String("metadata.google.internal:169.254.169.254"), + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "sshMount", &buildx.ImageArgs{ + Dockerfile: &buildx.DockerfileArgs{ + Location: pulumi.String("app/Dockerfile.sshMount"), + }, + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + Ssh: buildx.SSHArray{ + &buildx.SSHArgs{ + Id: pulumi.String("default"), + }, + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "secrets", &buildx.ImageArgs{ + Dockerfile: &buildx.DockerfileArgs{ + Location: pulumi.String("app/Dockerfile.secrets"), + }, + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + Secrets: pulumi.StringMap{ + "password": pulumi.String("hunter2"), + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "labels", &buildx.ImageArgs{ + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + Labels: pulumi.StringMap{ + "description": pulumi.String("This image will get a descriptive label 👍"), + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "targets", &buildx.ImageArgs{ + Dockerfile: &buildx.DockerfileArgs{ + Location: pulumi.String("app/Dockerfile.targets"), + }, + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + Targets: pulumi.StringArray{ + pulumi.String("build-me"), + pulumi.String("also-build-me"), + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "namedContexts", &buildx.ImageArgs{ + Dockerfile: &buildx.DockerfileArgs{ + Location: pulumi.String("app/Dockerfile.namedContexts"), + }, + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + Named: buildx.ContextMap{ + "golang:latest": &buildx.ContextArgs{ + Location: pulumi.String("docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984"), + }, + }, + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "remoteContext", &buildx.ImageArgs{ + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile"), + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "remoteContextWithInline", &buildx.ImageArgs{ + Dockerfile: &buildx.DockerfileArgs{ + Inline: pulumi.String("FROM busybox\nCOPY hello.c ./\n"), + }, + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("https://github.com/docker-library/hello-world.git"), + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "inline", &buildx.ImageArgs{ + Dockerfile: &buildx.DockerfileArgs{ + Inline: pulumi.String("FROM alpine\nRUN echo \"This uses an inline Dockerfile! 👍\"\n"), + }, + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + }) + if err != nil { + return err + } + _, err = buildx.NewImage(ctx, "dockerLoad", &buildx.ImageArgs{ + Context: &buildx.BuildContextArgs{ + Location: pulumi.String("app"), + }, + Exports: buildx.ExportEntryArray{ + &buildx.ExportEntryArgs{ + Docker: &buildx.ExportDockerArgs{ + Tar: pulumi.Bool(true), + }, + }, + }, + }) + if err != nil { + return err + } + ctx.Export("platforms", multiPlatform.Platforms) + return nil + }) +} diff --git a/examples/buildx/java/Pulumi.yaml b/examples/buildx/java/Pulumi.yaml new file mode 100644 index 00000000..d9bb66cc --- /dev/null +++ b/examples/buildx/java/Pulumi.yaml @@ -0,0 +1,3 @@ +name: buildx-examples +runtime: java +description: Examples of buildx.Image diff --git a/examples/buildx/java/app/Dockerfile b/examples/buildx/java/app/Dockerfile new file mode 100644 index 00000000..e17a80c7 --- /dev/null +++ b/examples/buildx/java/app/Dockerfile @@ -0,0 +1,2 @@ +FROM alpine +RUN echo 👍 diff --git a/examples/buildx/java/app/Dockerfile.buildArgs b/examples/buildx/java/app/Dockerfile.buildArgs new file mode 100644 index 00000000..438ee017 --- /dev/null +++ b/examples/buildx/java/app/Dockerfile.buildArgs @@ -0,0 +1,5 @@ +FROM alpine + +ARG SET_ME_TO_TRUE +RUN [ "$SET_ME_TO_TRUE" = "true" ] +RUN echo "That's the correct build arg, thanks! 👍" diff --git a/examples/buildx/java/app/Dockerfile.emptyContext b/examples/buildx/java/app/Dockerfile.emptyContext new file mode 100644 index 00000000..769593b2 --- /dev/null +++ b/examples/buildx/java/app/Dockerfile.emptyContext @@ -0,0 +1,2 @@ +FROM alpine +RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍" diff --git a/examples/buildx/java/app/Dockerfile.extraHosts b/examples/buildx/java/app/Dockerfile.extraHosts new file mode 100644 index 00000000..35b15f4e --- /dev/null +++ b/examples/buildx/java/app/Dockerfile.extraHosts @@ -0,0 +1,3 @@ +FROM bash AS base + +RUN getent hosts metadata.google.internal diff --git a/examples/buildx/java/app/Dockerfile.multiPlatform b/examples/buildx/java/app/Dockerfile.multiPlatform new file mode 100644 index 00000000..49d3c839 --- /dev/null +++ b/examples/buildx/java/app/Dockerfile.multiPlatform @@ -0,0 +1,7 @@ +FROM --platform=$BUILDPLATFORM alpine as build +RUN echo ${BUILDPLATFORM} > buildplatform +RUN echo ${TARGETPLATFORM} > targetplatform + +FROM build +RUN cat buildplatform +RUN cat targetplatform diff --git a/examples/buildx/java/app/Dockerfile.namedContexts b/examples/buildx/java/app/Dockerfile.namedContexts new file mode 100644 index 00000000..6e53dba1 --- /dev/null +++ b/examples/buildx/java/app/Dockerfile.namedContexts @@ -0,0 +1,5 @@ +# syntax=docker/dockerfile:1.4 +FROM golang:latest + +RUN version="$(go version)" && echo $version && [ "$version" = "go version go1.21.7 linux/amd64" ] +RUN echo "This image uses named contexts to pin golang:latest to a specific SHA 👍" diff --git a/examples/buildx/java/app/Dockerfile.secrets b/examples/buildx/java/app/Dockerfile.secrets new file mode 100644 index 00000000..513bbd26 --- /dev/null +++ b/examples/buildx/java/app/Dockerfile.secrets @@ -0,0 +1,4 @@ +FROM alpine + +RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ] + diff --git a/examples/buildx/java/app/Dockerfile.sshMount b/examples/buildx/java/app/Dockerfile.sshMount new file mode 100644 index 00000000..055cb780 --- /dev/null +++ b/examples/buildx/java/app/Dockerfile.sshMount @@ -0,0 +1,5 @@ +FROM alpine + +RUN apk add openssh-client + +RUN --mount=type=ssh ssh-add -l diff --git a/examples/buildx/java/app/Dockerfile.targets b/examples/buildx/java/app/Dockerfile.targets new file mode 100644 index 00000000..7cddec71 --- /dev/null +++ b/examples/buildx/java/app/Dockerfile.targets @@ -0,0 +1,8 @@ +FROM alpine as build-me +RUN echo 👍 + +FROM build-me as also-build-me +RUN echo 🤙 + +FROM build-me as dont-build-me +RUN [ "true" = "false" ] diff --git a/examples/buildx/java/pom.xml b/examples/buildx/java/pom.xml new file mode 100644 index 00000000..84d617e0 --- /dev/null +++ b/examples/buildx/java/pom.xml @@ -0,0 +1,92 @@ + + + 4.0.0 + + com.pulumi + buildx-examples + 1.0-SNAPSHOT + + + UTF-8 + 11 + 11 + 11 + generated_program.App + + + + + + com.pulumi + pulumi + (,1.0] + + + com.pulumi + docker + [0.0.0,) + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + + true + ${mainClass} + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.4.2 + + + + true + ${mainClass} + + + + jar-with-dependencies + + + + + make-my-jar-with-dependencies + package + + single + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + ${mainClass} + ${mainArgs} + + + + org.apache.maven.plugins + maven-wrapper-plugin + 3.1.1 + + 3.8.5 + + + + + diff --git a/examples/buildx/java/src/main/java/generated_program/App.java b/examples/buildx/java/src/main/java/generated_program/App.java new file mode 100644 index 00000000..ffe80bd7 --- /dev/null +++ b/examples/buildx/java/src/main/java/generated_program/App.java @@ -0,0 +1,192 @@ +package generated_program; + +import com.pulumi.Context; +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.docker.buildx.Image; +import com.pulumi.docker.buildx.ImageArgs; +import com.pulumi.docker.buildx.DockerfileArgs; +import com.pulumi.docker.buildx.BuildContextArgs; +import com.pulumi.docker.buildx.ExportEntryArgs; +import com.pulumi.docker.buildx.ExportRegistryArgs; +import com.pulumi.docker.buildx.RegistryAuthArgs; +import com.pulumi.docker.buildx.CacheToEntryArgs; +import com.pulumi.docker.buildx.CacheToLocalArgs; +import com.pulumi.docker.buildx.CacheFromEntryArgs; +import com.pulumi.docker.buildx.CacheFromLocalArgs; +import com.pulumi.docker.buildx.ExportDockerArgs; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class App { + public static void main(String[] args) { + Pulumi.run(App::stack); + } + + public static void stack(Context ctx) { + final var config = ctx.config(); + final var dockerHubPassword = config.get("dockerHubPassword"); + var multiPlatform = new Image("multiPlatform", ImageArgs.builder() + .dockerfile(DockerfileArgs.builder() + .location("app/Dockerfile.multiPlatform") + .build()) + .context(BuildContextArgs.builder() + .location("app") + .build()) + .platforms( + "plan9/amd64", + "plan9/386") + .build()); + + var registryPush = new Image("registryPush", ImageArgs.builder() + .context(BuildContextArgs.builder() + .location("app") + .build()) + .tags("docker.io/pulumibot/buildkit-e2e:example") + .exports(ExportEntryArgs.builder() + .registry(ExportRegistryArgs.builder() + .ociMediaTypes(true) + .push(false) + .build()) + .build()) + .registries(RegistryAuthArgs.builder() + .address("docker.io") + .username("pulumibot") + .password(dockerHubPassword) + .build()) + .build()); + + var cached = new Image("cached", ImageArgs.builder() + .context(BuildContextArgs.builder() + .location("app") + .build()) + .cacheTo(CacheToEntryArgs.builder() + .local(CacheToLocalArgs.builder() + .dest("tmp/cache") + .mode("max") + .build()) + .build()) + .cacheFrom(CacheFromEntryArgs.builder() + .local(CacheFromLocalArgs.builder() + .src("tmp/cache") + .build()) + .build()) + .build()); + + var buildArgs = new Image("buildArgs", ImageArgs.builder() + .dockerfile(DockerfileArgs.builder() + .location("app/Dockerfile.buildArgs") + .build()) + .context(BuildContextArgs.builder() + .location("app") + .build()) + .buildArgs(Map.of("SET_ME_TO_TRUE", "true")) + .build()); + + var extraHosts = new Image("extraHosts", ImageArgs.builder() + .dockerfile(DockerfileArgs.builder() + .location("app/Dockerfile.extraHosts") + .build()) + .context(BuildContextArgs.builder() + .location("app") + .build()) + .addHosts("metadata.google.internal:169.254.169.254") + .build()); + + var sshMount = new Image("sshMount", ImageArgs.builder() + .dockerfile(DockerfileArgs.builder() + .location("app/Dockerfile.sshMount") + .build()) + .context(BuildContextArgs.builder() + .location("app") + .build()) + .ssh(SSHArgs.builder() + .id("default") + .build()) + .build()); + + var secrets = new Image("secrets", ImageArgs.builder() + .dockerfile(DockerfileArgs.builder() + .location("app/Dockerfile.secrets") + .build()) + .context(BuildContextArgs.builder() + .location("app") + .build()) + .secrets(Map.of("password", "hunter2")) + .build()); + + var labels = new Image("labels", ImageArgs.builder() + .context(BuildContextArgs.builder() + .location("app") + .build()) + .labels(Map.of("description", "This image will get a descriptive label 👍")) + .build()); + + var targets = new Image("targets", ImageArgs.builder() + .dockerfile(DockerfileArgs.builder() + .location("app/Dockerfile.targets") + .build()) + .context(BuildContextArgs.builder() + .location("app") + .build()) + .targets( + "build-me", + "also-build-me") + .build()); + + var namedContexts = new Image("namedContexts", ImageArgs.builder() + .dockerfile(DockerfileArgs.builder() + .location("app/Dockerfile.namedContexts") + .build()) + .context(BuildContextArgs.builder() + .location("app") + .named(Map.of("golang:latest", Map.of("location", "docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984"))) + .build()) + .build()); + + var remoteContext = new Image("remoteContext", ImageArgs.builder() + .context(BuildContextArgs.builder() + .location("https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile") + .build()) + .build()); + + var remoteContextWithInline = new Image("remoteContextWithInline", ImageArgs.builder() + .dockerfile(DockerfileArgs.builder() + .inline( + "FROM busybox\n" + + "COPY hello.c ./") + .build()) + .context(BuildContextArgs.builder() + .location("https://github.com/docker-library/hello-world.git") + .build()) + .build()); + + var inline = new Image("inline", ImageArgs.builder() + .dockerfile(DockerfileArgs.builder() + .inline( + "FROM alpine\n" + + "RUN echo 'This uses an inline Dockerfile! 👍'") + .build()) + .context(BuildContextArgs.builder() + .location("app") + .build()) + .build()); + + var dockerLoad = new Image("dockerLoad", ImageArgs.builder() + .context(BuildContextArgs.builder() + .location("app") + .build()) + .exports(ExportEntryArgs.builder() + .docker(ExportDockerArgs.builder() + .tar(true) + .build()) + .build()) + .build()); + + ctx.export("platforms", multiPlatform.platforms()); + } +} diff --git a/examples/buildx/py/.gitignore b/examples/buildx/py/.gitignore new file mode 100644 index 00000000..b664ab4e --- /dev/null +++ b/examples/buildx/py/.gitignore @@ -0,0 +1,2 @@ +*.pyc +venv/ \ No newline at end of file diff --git a/examples/buildx/py/Pulumi.yaml b/examples/buildx/py/Pulumi.yaml new file mode 100644 index 00000000..f790d69b --- /dev/null +++ b/examples/buildx/py/Pulumi.yaml @@ -0,0 +1,3 @@ +name: buildx-examples +runtime: python +description: Examples of buildx.Image diff --git a/examples/buildx/py/__main__.py b/examples/buildx/py/__main__.py new file mode 100644 index 00000000..f5ef5d3c --- /dev/null +++ b/examples/buildx/py/__main__.py @@ -0,0 +1,146 @@ +import pulumi +import pulumi_docker as docker + +config = pulumi.Config() +docker_hub_password = config.require("dockerHubPassword") +multi_platform = docker.buildx.Image("multiPlatform", + dockerfile=docker.buildx.DockerfileArgs( + location="app/Dockerfile.multiPlatform", + ), + context=docker.buildx.BuildContextArgs( + location="app", + ), + platforms=[ + "plan9/amd64", + "plan9/386", + ]) +registry_push = docker.buildx.Image("registryPush", + context=docker.buildx.BuildContextArgs( + location="app", + ), + tags=["docker.io/pulumibot/buildkit-e2e:example"], + exports=[docker.buildx.ExportEntryArgs( + registry=docker.buildx.ExportRegistryArgs( + oci_media_types=True, + push=False, + ), + )], + registries=[docker.buildx.RegistryAuthArgs( + address="docker.io", + username="pulumibot", + password=docker_hub_password, + )]) +cached = docker.buildx.Image("cached", + context=docker.buildx.BuildContextArgs( + location="app", + ), + cache_to=[docker.buildx.CacheToEntryArgs( + local=docker.buildx.CacheToLocalArgs( + dest="tmp/cache", + mode="max", + ), + )], + cache_from=[docker.buildx.CacheFromEntryArgs( + local=docker.buildx.CacheFromLocalArgs( + src="tmp/cache", + ), + )]) +build_args = docker.buildx.Image("buildArgs", + dockerfile=docker.buildx.DockerfileArgs( + location="app/Dockerfile.buildArgs", + ), + context=docker.buildx.BuildContextArgs( + location="app", + ), + build_args={ + "SET_ME_TO_TRUE": "true", + }) +extra_hosts = docker.buildx.Image("extraHosts", + dockerfile=docker.buildx.DockerfileArgs( + location="app/Dockerfile.extraHosts", + ), + context=docker.buildx.BuildContextArgs( + location="app", + ), + add_hosts=["metadata.google.internal:169.254.169.254"]) +ssh_mount = docker.buildx.Image("sshMount", + dockerfile=docker.buildx.DockerfileArgs( + location="app/Dockerfile.sshMount", + ), + context=docker.buildx.BuildContextArgs( + location="app", + ), + ssh=[docker.buildx.SSHArgs( + id="default", + )]) +secrets = docker.buildx.Image("secrets", + dockerfile=docker.buildx.DockerfileArgs( + location="app/Dockerfile.secrets", + ), + context=docker.buildx.BuildContextArgs( + location="app", + ), + secrets={ + "password": "hunter2", + }) +labels = docker.buildx.Image("labels", + context=docker.buildx.BuildContextArgs( + location="app", + ), + labels={ + "description": "This image will get a descriptive label 👍", + }) +targets = docker.buildx.Image("targets", + dockerfile=docker.buildx.DockerfileArgs( + location="app/Dockerfile.targets", + ), + context=docker.buildx.BuildContextArgs( + location="app", + ), + targets=[ + "build-me", + "also-build-me", + ]) +named_contexts = docker.buildx.Image("namedContexts", + dockerfile=docker.buildx.DockerfileArgs( + location="app/Dockerfile.namedContexts", + ), + context=docker.buildx.BuildContextArgs( + location="app", + named={ + "golang:latest": docker.buildx.ContextArgs( + location="docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984", + ), + }, + )) +remote_context = docker.buildx.Image("remoteContext", context=docker.buildx.BuildContextArgs( + location="https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile", +)) +remote_context_with_inline = docker.buildx.Image("remoteContextWithInline", + dockerfile=docker.buildx.DockerfileArgs( + inline="""FROM busybox +COPY hello.c ./ +""", + ), + context=docker.buildx.BuildContextArgs( + location="https://github.com/docker-library/hello-world.git", + )) +inline = docker.buildx.Image("inline", + dockerfile=docker.buildx.DockerfileArgs( + inline="""FROM alpine +RUN echo "This uses an inline Dockerfile! 👍" +""", + ), + context=docker.buildx.BuildContextArgs( + location="app", + )) +docker_load = docker.buildx.Image("dockerLoad", + context=docker.buildx.BuildContextArgs( + location="app", + ), + exports=[docker.buildx.ExportEntryArgs( + docker=docker.buildx.ExportDockerArgs( + tar=True, + ), + )]) +pulumi.export("platforms", multi_platform.platforms) diff --git a/examples/buildx/py/app/Dockerfile b/examples/buildx/py/app/Dockerfile new file mode 100644 index 00000000..e17a80c7 --- /dev/null +++ b/examples/buildx/py/app/Dockerfile @@ -0,0 +1,2 @@ +FROM alpine +RUN echo 👍 diff --git a/examples/buildx/py/app/Dockerfile.buildArgs b/examples/buildx/py/app/Dockerfile.buildArgs new file mode 100644 index 00000000..438ee017 --- /dev/null +++ b/examples/buildx/py/app/Dockerfile.buildArgs @@ -0,0 +1,5 @@ +FROM alpine + +ARG SET_ME_TO_TRUE +RUN [ "$SET_ME_TO_TRUE" = "true" ] +RUN echo "That's the correct build arg, thanks! 👍" diff --git a/examples/buildx/py/app/Dockerfile.emptyContext b/examples/buildx/py/app/Dockerfile.emptyContext new file mode 100644 index 00000000..769593b2 --- /dev/null +++ b/examples/buildx/py/app/Dockerfile.emptyContext @@ -0,0 +1,2 @@ +FROM alpine +RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍" diff --git a/examples/buildx/py/app/Dockerfile.extraHosts b/examples/buildx/py/app/Dockerfile.extraHosts new file mode 100644 index 00000000..35b15f4e --- /dev/null +++ b/examples/buildx/py/app/Dockerfile.extraHosts @@ -0,0 +1,3 @@ +FROM bash AS base + +RUN getent hosts metadata.google.internal diff --git a/examples/buildx/py/app/Dockerfile.multiPlatform b/examples/buildx/py/app/Dockerfile.multiPlatform new file mode 100644 index 00000000..49d3c839 --- /dev/null +++ b/examples/buildx/py/app/Dockerfile.multiPlatform @@ -0,0 +1,7 @@ +FROM --platform=$BUILDPLATFORM alpine as build +RUN echo ${BUILDPLATFORM} > buildplatform +RUN echo ${TARGETPLATFORM} > targetplatform + +FROM build +RUN cat buildplatform +RUN cat targetplatform diff --git a/examples/buildx/py/app/Dockerfile.namedContexts b/examples/buildx/py/app/Dockerfile.namedContexts new file mode 100644 index 00000000..6e53dba1 --- /dev/null +++ b/examples/buildx/py/app/Dockerfile.namedContexts @@ -0,0 +1,5 @@ +# syntax=docker/dockerfile:1.4 +FROM golang:latest + +RUN version="$(go version)" && echo $version && [ "$version" = "go version go1.21.7 linux/amd64" ] +RUN echo "This image uses named contexts to pin golang:latest to a specific SHA 👍" diff --git a/examples/buildx/py/app/Dockerfile.secrets b/examples/buildx/py/app/Dockerfile.secrets new file mode 100644 index 00000000..513bbd26 --- /dev/null +++ b/examples/buildx/py/app/Dockerfile.secrets @@ -0,0 +1,4 @@ +FROM alpine + +RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ] + diff --git a/examples/buildx/py/app/Dockerfile.sshMount b/examples/buildx/py/app/Dockerfile.sshMount new file mode 100644 index 00000000..055cb780 --- /dev/null +++ b/examples/buildx/py/app/Dockerfile.sshMount @@ -0,0 +1,5 @@ +FROM alpine + +RUN apk add openssh-client + +RUN --mount=type=ssh ssh-add -l diff --git a/examples/buildx/py/app/Dockerfile.targets b/examples/buildx/py/app/Dockerfile.targets new file mode 100644 index 00000000..7cddec71 --- /dev/null +++ b/examples/buildx/py/app/Dockerfile.targets @@ -0,0 +1,8 @@ +FROM alpine as build-me +RUN echo 👍 + +FROM build-me as also-build-me +RUN echo 🤙 + +FROM build-me as dont-build-me +RUN [ "true" = "false" ] diff --git a/examples/buildx/py/requirements.txt b/examples/buildx/py/requirements.txt new file mode 100644 index 00000000..e0b6f666 --- /dev/null +++ b/examples/buildx/py/requirements.txt @@ -0,0 +1,2 @@ +pulumi>=3.0.0,<4.0.0 +pulumi-docker>=4.0.0 diff --git a/examples/buildx/ts/.gitignore b/examples/buildx/ts/.gitignore new file mode 100644 index 00000000..dc902b57 --- /dev/null +++ b/examples/buildx/ts/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/node_modules/ \ No newline at end of file diff --git a/examples/buildx/ts/Pulumi.yaml b/examples/buildx/ts/Pulumi.yaml new file mode 100644 index 00000000..7822abee --- /dev/null +++ b/examples/buildx/ts/Pulumi.yaml @@ -0,0 +1,3 @@ +name: buildx-examples +runtime: nodejs +description: Examples of buildx.Image diff --git a/examples/buildx/ts/app/Dockerfile b/examples/buildx/ts/app/Dockerfile new file mode 100644 index 00000000..e17a80c7 --- /dev/null +++ b/examples/buildx/ts/app/Dockerfile @@ -0,0 +1,2 @@ +FROM alpine +RUN echo 👍 diff --git a/examples/buildx/ts/app/Dockerfile.buildArgs b/examples/buildx/ts/app/Dockerfile.buildArgs new file mode 100644 index 00000000..438ee017 --- /dev/null +++ b/examples/buildx/ts/app/Dockerfile.buildArgs @@ -0,0 +1,5 @@ +FROM alpine + +ARG SET_ME_TO_TRUE +RUN [ "$SET_ME_TO_TRUE" = "true" ] +RUN echo "That's the correct build arg, thanks! 👍" diff --git a/examples/buildx/ts/app/Dockerfile.emptyContext b/examples/buildx/ts/app/Dockerfile.emptyContext new file mode 100644 index 00000000..769593b2 --- /dev/null +++ b/examples/buildx/ts/app/Dockerfile.emptyContext @@ -0,0 +1,2 @@ +FROM alpine +RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍" diff --git a/examples/buildx/ts/app/Dockerfile.extraHosts b/examples/buildx/ts/app/Dockerfile.extraHosts new file mode 100644 index 00000000..35b15f4e --- /dev/null +++ b/examples/buildx/ts/app/Dockerfile.extraHosts @@ -0,0 +1,3 @@ +FROM bash AS base + +RUN getent hosts metadata.google.internal diff --git a/examples/buildx/ts/app/Dockerfile.multiPlatform b/examples/buildx/ts/app/Dockerfile.multiPlatform new file mode 100644 index 00000000..49d3c839 --- /dev/null +++ b/examples/buildx/ts/app/Dockerfile.multiPlatform @@ -0,0 +1,7 @@ +FROM --platform=$BUILDPLATFORM alpine as build +RUN echo ${BUILDPLATFORM} > buildplatform +RUN echo ${TARGETPLATFORM} > targetplatform + +FROM build +RUN cat buildplatform +RUN cat targetplatform diff --git a/examples/buildx/ts/app/Dockerfile.namedContexts b/examples/buildx/ts/app/Dockerfile.namedContexts new file mode 100644 index 00000000..6e53dba1 --- /dev/null +++ b/examples/buildx/ts/app/Dockerfile.namedContexts @@ -0,0 +1,5 @@ +# syntax=docker/dockerfile:1.4 +FROM golang:latest + +RUN version="$(go version)" && echo $version && [ "$version" = "go version go1.21.7 linux/amd64" ] +RUN echo "This image uses named contexts to pin golang:latest to a specific SHA 👍" diff --git a/examples/buildx/ts/app/Dockerfile.secrets b/examples/buildx/ts/app/Dockerfile.secrets new file mode 100644 index 00000000..513bbd26 --- /dev/null +++ b/examples/buildx/ts/app/Dockerfile.secrets @@ -0,0 +1,4 @@ +FROM alpine + +RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ] + diff --git a/examples/buildx/ts/app/Dockerfile.sshMount b/examples/buildx/ts/app/Dockerfile.sshMount new file mode 100644 index 00000000..055cb780 --- /dev/null +++ b/examples/buildx/ts/app/Dockerfile.sshMount @@ -0,0 +1,5 @@ +FROM alpine + +RUN apk add openssh-client + +RUN --mount=type=ssh ssh-add -l diff --git a/examples/buildx/ts/app/Dockerfile.targets b/examples/buildx/ts/app/Dockerfile.targets new file mode 100644 index 00000000..7cddec71 --- /dev/null +++ b/examples/buildx/ts/app/Dockerfile.targets @@ -0,0 +1,8 @@ +FROM alpine as build-me +RUN echo 👍 + +FROM build-me as also-build-me +RUN echo 🤙 + +FROM build-me as dont-build-me +RUN [ "true" = "false" ] diff --git a/examples/buildx/ts/index.ts b/examples/buildx/ts/index.ts new file mode 100644 index 00000000..3f965d68 --- /dev/null +++ b/examples/buildx/ts/index.ts @@ -0,0 +1,159 @@ +import * as pulumi from "@pulumi/pulumi"; +import * as docker from "@pulumi/docker"; + +const config = new pulumi.Config(); +const dockerHubPassword = config.require("dockerHubPassword"); +const multiPlatform = new docker.buildx.Image("multiPlatform", { + dockerfile: { + location: "app/Dockerfile.multiPlatform", + }, + context: { + location: "app", + }, + platforms: [ + "plan9/amd64", + "plan9/386", + ], +}); +const registryPush = new docker.buildx.Image("registryPush", { + context: { + location: "app", + }, + tags: ["docker.io/pulumibot/buildkit-e2e:example"], + exports: [{ + registry: { + ociMediaTypes: true, + push: false, + }, + }], + registries: [{ + address: "docker.io", + username: "pulumibot", + password: dockerHubPassword, + }], +}); +const cached = new docker.buildx.Image("cached", { + context: { + location: "app", + }, + cacheTo: [{ + local: { + dest: "tmp/cache", + mode: "max", + }, + }], + cacheFrom: [{ + local: { + src: "tmp/cache", + }, + }], +}); +const buildArgs = new docker.buildx.Image("buildArgs", { + dockerfile: { + location: "app/Dockerfile.buildArgs", + }, + context: { + location: "app", + }, + buildArgs: { + SET_ME_TO_TRUE: "true", + }, +}); +const extraHosts = new docker.buildx.Image("extraHosts", { + dockerfile: { + location: "app/Dockerfile.extraHosts", + }, + context: { + location: "app", + }, + addHosts: ["metadata.google.internal:169.254.169.254"], +}); +const sshMount = new docker.buildx.Image("sshMount", { + dockerfile: { + location: "app/Dockerfile.sshMount", + }, + context: { + location: "app", + }, + ssh: [{ + id: "default", + }], +}); +const secrets = new docker.buildx.Image("secrets", { + dockerfile: { + location: "app/Dockerfile.secrets", + }, + context: { + location: "app", + }, + secrets: { + password: "hunter2", + }, +}); +const labels = new docker.buildx.Image("labels", { + context: { + location: "app", + }, + labels: { + description: "This image will get a descriptive label 👍", + }, +}); +const targets = new docker.buildx.Image("targets", { + dockerfile: { + location: "app/Dockerfile.targets", + }, + context: { + location: "app", + }, + targets: [ + "build-me", + "also-build-me", + ], +}); +const namedContexts = new docker.buildx.Image("namedContexts", { + dockerfile: { + location: "app/Dockerfile.namedContexts", + }, + context: { + location: "app", + named: { + "golang:latest": { + location: "docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984", + }, + }, + }, +}); +const remoteContext = new docker.buildx.Image("remoteContext", {context: { + location: "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile", +}}); +const remoteContextWithInline = new docker.buildx.Image("remoteContextWithInline", { + dockerfile: { + inline: `FROM busybox +COPY hello.c ./ +`, + }, + context: { + location: "https://github.com/docker-library/hello-world.git", + }, +}); +const inline = new docker.buildx.Image("inline", { + dockerfile: { + inline: `FROM alpine +RUN echo "This uses an inline Dockerfile! 👍" +`, + }, + context: { + location: "app", + }, +}); +const dockerLoad = new docker.buildx.Image("dockerLoad", { + context: { + location: "app", + }, + exports: [{ + docker: { + tar: true, + }, + }], +}); +export const platforms = multiPlatform.platforms; diff --git a/examples/buildx/ts/package.json b/examples/buildx/ts/package.json new file mode 100644 index 00000000..214501ba --- /dev/null +++ b/examples/buildx/ts/package.json @@ -0,0 +1,10 @@ +{ + "name": "buildx-examples", + "devDependencies": { + "@types/node": "^14" + }, + "dependencies": { + "typescript": "^4.0.0", + "@pulumi/pulumi": "^3.0.0" + } +} diff --git a/examples/buildx/ts/tsconfig.json b/examples/buildx/ts/tsconfig.json new file mode 100644 index 00000000..11fc69af --- /dev/null +++ b/examples/buildx/ts/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "strict": true, + "outDir": "bin", + "target": "es2016", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "experimentalDecorators": true, + "pretty": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.ts", + ] +} \ No newline at end of file diff --git a/examples/buildx/yaml/.dockerignore b/examples/buildx/yaml/.dockerignore new file mode 100644 index 00000000..55418ecb --- /dev/null +++ b/examples/buildx/yaml/.dockerignore @@ -0,0 +1,2 @@ +.dockerignore +state diff --git a/examples/buildx/yaml/Pulumi.yaml b/examples/buildx/yaml/Pulumi.yaml new file mode 100644 index 00000000..aa638137 --- /dev/null +++ b/examples/buildx/yaml/Pulumi.yaml @@ -0,0 +1,180 @@ +name: buildx-examples +runtime: yaml +description: Examples of buildx.Image + +resources: + # docker buildx build -f app/Dockerfile.multiPlatform --platform plan9/amd64,plan9/386 app + multiPlatform: + type: docker:buildx/image:Image + properties: + dockerfile: + location: "app/Dockerfile.multiPlatform" + context: + location: "app" + platforms: + - plan9/amd64 + - plan9/386 + + # docker buildx build --output=type=registry app + registryPush: + type: docker:buildx/image:Image + properties: + context: + location: "app" + tags: ["docker.io/pulumibot/buildkit-e2e:example"] + exports: + - registry: + ociMediaTypes: true + push: false # Omit this to actually push images. + registries: + - address: docker.io + username: pulumibot + password: ${dockerHubPassword} + + # docker buildx build --cache-to=type=local,dest=tmp/cache,mode=max --cache-from=type=local,src=tmp/cache app + cached: + type: docker:buildx/image:Image + properties: + context: + location: "app" + cacheTo: + - local: + dest: tmp/cache + mode: max + cacheFrom: + - local: + src: tmp/cache + + # docker buildx build -f app/Dockerfile.buildArgs --build-arg SET_ME_TO_TRUE=true app + buildArgs: + type: docker:buildx/image:Image + properties: + dockerfile: + location: "app/Dockerfile.buildArgs" + context: + location: "app" + buildArgs: + SET_ME_TO_TRUE: "true" + + # docker buildx build -f app/Dockerfile.extraHosts --add-host metadata.google.internal:169.254.169.254 app + extraHosts: + type: docker:buildx/image:Image + properties: + dockerfile: + location: "app/Dockerfile.extraHosts" + context: + location: "app" + addHosts: + - "metadata.google.internal:169.254.169.254" + + # docker buildx build -f app/Dockerfile.sshMount --ssh default app + sshMount: + type: docker:buildx/image:Image + properties: + dockerfile: + location: "app/Dockerfile.sshMount" + context: + location: "app" + ssh: + - id: default + + # PASSWORD=hunter2 docker buildx build -f app/Dockerfile.secrets --secret id=password,env=PASSWORD app + secrets: + type: docker:buildx/image:Image + properties: + dockerfile: + location: "app/Dockerfile.secrets" + context: + location: "app" + secrets: + password: hunter2 + + # docker buildx build --label "description=This image will get a descriptive label 👍" app + labels: + type: docker:buildx/image:Image + properties: + context: + location: "app" + labels: + description: "This image will get a descriptive label 👍" + + # docker buildx build -f app/Dockerfile.targets --target build-me --target also-build-me app + targets: + type: docker:buildx/image:Image + properties: + dockerfile: + location: "app/Dockerfile.targets" + context: + location: "app" + targets: + - "build-me" + - "also-build-me" + + # docker buildx build -f app/Dockerfile.namedContexts \ + # --build-context golang:latest=docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984 app + namedContexts: + type: docker:buildx/image:Image + properties: + dockerfile: + location: "app/Dockerfile.namedContexts" + context: + location: app + named: + "golang:latest": + location: "docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984" + + # docker buildx build https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile + remoteContext: + type: docker:buildx/image:Image + properties: + context: + location: "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile" + + # docker buildx build -f - https://github.com/docker-library/hello-world.git < buildplatform +RUN echo ${TARGETPLATFORM} > targetplatform + +FROM build +RUN cat buildplatform +RUN cat targetplatform diff --git a/examples/buildx/yaml/app/Dockerfile.namedContexts b/examples/buildx/yaml/app/Dockerfile.namedContexts new file mode 100644 index 00000000..6e53dba1 --- /dev/null +++ b/examples/buildx/yaml/app/Dockerfile.namedContexts @@ -0,0 +1,5 @@ +# syntax=docker/dockerfile:1.4 +FROM golang:latest + +RUN version="$(go version)" && echo $version && [ "$version" = "go version go1.21.7 linux/amd64" ] +RUN echo "This image uses named contexts to pin golang:latest to a specific SHA 👍" diff --git a/examples/buildx/yaml/app/Dockerfile.secrets b/examples/buildx/yaml/app/Dockerfile.secrets new file mode 100644 index 00000000..513bbd26 --- /dev/null +++ b/examples/buildx/yaml/app/Dockerfile.secrets @@ -0,0 +1,4 @@ +FROM alpine + +RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ] + diff --git a/examples/buildx/yaml/app/Dockerfile.sshMount b/examples/buildx/yaml/app/Dockerfile.sshMount new file mode 100644 index 00000000..055cb780 --- /dev/null +++ b/examples/buildx/yaml/app/Dockerfile.sshMount @@ -0,0 +1,5 @@ +FROM alpine + +RUN apk add openssh-client + +RUN --mount=type=ssh ssh-add -l diff --git a/examples/buildx/yaml/app/Dockerfile.targets b/examples/buildx/yaml/app/Dockerfile.targets new file mode 100644 index 00000000..7cddec71 --- /dev/null +++ b/examples/buildx/yaml/app/Dockerfile.targets @@ -0,0 +1,8 @@ +FROM alpine as build-me +RUN echo 👍 + +FROM build-me as also-build-me +RUN echo 🤙 + +FROM build-me as dont-build-me +RUN [ "true" = "false" ] diff --git a/examples/examples_dotnet_test.go b/examples/examples_dotnet_test.go index 1fe80d0b..f51db679 100644 --- a/examples/examples_dotnet_test.go +++ b/examples/examples_dotnet_test.go @@ -27,6 +27,18 @@ import ( "github.com/stretchr/testify/assert" ) +func TestBuildxCs(t *testing.T) { + test := getCsharpBaseOptions(t). + With(integration.ProgramTestOptions{ + Dir: path.Join(getCwd(t), "buildx", "csharp"), + Secrets: map[string]string{ + "dockerHubPassword": os.Getenv("DOCKER_HUB_PASSWORD"), + }, + }) + + integration.ProgramTest(t, &test) +} + func TestNginxCs(t *testing.T) { test := getCsharpBaseOptions(t). With(integration.ProgramTestOptions{ diff --git a/examples/examples_go_test.go b/examples/examples_go_test.go index 2bb0a9cf..59ae6589 100644 --- a/examples/examples_go_test.go +++ b/examples/examples_go_test.go @@ -32,8 +32,21 @@ import ( "github.com/stretchr/testify/require" ) -func TestNginxGo(t *testing.T) { +func TestBuildx(t *testing.T) { + test := base.With(integration.ProgramTestOptions{ + Dependencies: []string{ + "github.com/pulumi/pulumi-docker/sdk/v4=../sdk", + }, + Dir: path.Join(getCwd(t), "buildx", "go"), + Secrets: map[string]string{ + "dockerHubPassword": os.Getenv("DOCKER_HUB_PASSWORD"), + }, + }) + + integration.ProgramTest(t, &test) +} +func TestNginxGo(t *testing.T) { cwd, err := os.Getwd() if !assert.NoError(t, err) { t.FailNow() diff --git a/examples/examples_java_test.go b/examples/examples_java_test.go new file mode 100644 index 00000000..e2ee284e --- /dev/null +++ b/examples/examples_java_test.go @@ -0,0 +1,56 @@ +// Copyright 2024, Pulumi Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//go:build java || all +// +build java all + +package examples + +import ( + "fmt" + "os" + "path" + "path/filepath" + "testing" + + "github.com/pulumi/pulumi/pkg/v3/engine" + "github.com/pulumi/pulumi/pkg/v3/testing/integration" +) + +func TestBuildxJava(t *testing.T) { + t.Skip("not working") + + test := getJavaBase(t, path.Join("buildx", "java"), integration.ProgramTestOptions{ + Secrets: map[string]string{ + "dockerHubPassword": os.Getenv("DOCKER_HUB_PASSWORD"), + }, + }) + + integration.ProgramTest(t, &test) +} + +func getJavaBase(t *testing.T, dir string, testSpecificOptions integration.ProgramTestOptions) integration.ProgramTestOptions { + repoRoot, err := filepath.Abs(filepath.Join("..", "..")) + if err != nil { + panic(err) + } + opts := integration.ProgramTestOptions{ + Dir: filepath.Join(getCwd(t), dir), + Env: []string{fmt.Sprintf("PULUMI_REPO_ROOT=%s", repoRoot)}, + PrepareProject: func(*engine.Projinfo) error { + return nil // needed because defaultPrepareProject does not know about java + }, + } + opts = opts.With(getBaseOptions()).With(testSpecificOptions) + return opts +} diff --git a/examples/examples_nodejs_test.go b/examples/examples_nodejs_test.go index f0460f6c..e9c2fcf7 100644 --- a/examples/examples_nodejs_test.go +++ b/examples/examples_nodejs_test.go @@ -33,6 +33,18 @@ import ( "github.com/stretchr/testify/assert" ) +func TestBuildxTs(t *testing.T) { + test := getJsOptions(t). + With(integration.ProgramTestOptions{ + Dir: path.Join(getCwd(t), "buildx", "ts"), + Secrets: map[string]string{ + "dockerHubPassword": os.Getenv("DOCKER_HUB_PASSWORD"), + }, + }) + + integration.ProgramTest(t, &test) +} + func TestNginxTs(t *testing.T) { test := getJsOptions(t). With(integration.ProgramTestOptions{ diff --git a/examples/examples_py_test.go b/examples/examples_py_test.go index fd59854d..8e75912e 100644 --- a/examples/examples_py_test.go +++ b/examples/examples_py_test.go @@ -24,6 +24,18 @@ import ( "github.com/pulumi/pulumi/pkg/v3/testing/integration" ) +func TestBuildxPy(t *testing.T) { + test := getPyOptions(t). + With(integration.ProgramTestOptions{ + Dir: path.Join(getCwd(t), "buildx", "py"), + Secrets: map[string]string{ + "dockerHubPassword": os.Getenv("DOCKER_HUB_PASSWORD"), + }, + }) + + integration.ProgramTest(t, &test) +} + func TestAzureContainerRegistryPy(t *testing.T) { location := os.Getenv("AZURE_LOCATION") if location == "" { diff --git a/examples/examples_yaml_test.go b/examples/examples_yaml_test.go index 26825ce3..644d53d1 100644 --- a/examples/examples_yaml_test.go +++ b/examples/examples_yaml_test.go @@ -30,6 +30,15 @@ import ( "github.com/pulumi/pulumi/pkg/v3/testing/integration" ) +func TestBuildxYAML(t *testing.T) { + integration.ProgramTest(t, &integration.ProgramTestOptions{ + Dir: path.Join(getCwd(t), "buildx", "yaml"), + Secrets: map[string]string{ + "dockerHubPassword": os.Getenv("DOCKER_HUB_PASSWORD"), + }, + }) +} + func TestUnknownInputsYAML(t *testing.T) { cwd, err := os.Getwd() if !assert.NoError(t, err) { @@ -86,9 +95,9 @@ func TestBuildOnPreviewYAML(t *testing.T) { var outputBuf bytes.Buffer integration.ProgramTest(t, &integration.ProgramTestOptions{ Dir: path.Join(cwd, "test-build-on-preview", "yaml"), - SkipUpdate: true, //only run Preview + SkipUpdate: true, // only run Preview SkipExportImport: true, - Verbose: true, //we need this to verify the build output logs + Verbose: true, // we need this to verify the build output logs AllowEmptyPreviewChanges: true, Stdout: &outputBuf, ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) { @@ -97,6 +106,7 @@ func TestBuildOnPreviewYAML(t *testing.T) { }, }) } + func TestDockerSwarmYAML(t *testing.T) { cwd, err := os.Getwd() if !assert.NoError(t, err) { @@ -142,9 +152,9 @@ func TestUnknownsBuildOnPreviewWarnsYAML(t *testing.T) { var outputBuf bytes.Buffer integration.ProgramTest(t, &integration.ProgramTestOptions{ Dir: path.Join(cwd, "test-unknowns", "yaml-build-on-preview"), - SkipUpdate: true, //only run Preview + SkipUpdate: true, // only run Preview SkipExportImport: true, - Verbose: true, //we need this to verify the build output logs + Verbose: true, // we need this to verify the build output logs AllowEmptyPreviewChanges: true, Stderr: &outputBuf, ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) { diff --git a/examples/gen.go b/examples/gen.go new file mode 100644 index 00000000..336bbb11 --- /dev/null +++ b/examples/gen.go @@ -0,0 +1,14 @@ +//go:generate /bin/sh -c "export PATH=\"$(realpath ../bin):$PATH\"; pulumi convert -C buildx/yaml --from yaml --language dotnet --out ../csharp --generate-only" +//go:generate /bin/sh -c "export PATH=\"$(realpath ../bin):$PATH\"; pulumi convert -C buildx/yaml --from yaml --language go --out ../go --generate-only" +//go:generate /bin/sh -c "export PATH=\"$(realpath ../bin):$PATH\"; pulumi convert -C buildx/yaml --from yaml --language nodejs --out ../ts --generate-only" +//go:generate /bin/sh -c "export PATH=\"$(realpath ../bin):$PATH\"; pulumi convert -C buildx/yaml --from yaml --language python --out ../py --generate-only" +//go:generate /bin/sh -c "export PATH=\"$(realpath ../bin):$PATH\"; pulumi convert -C buildx/yaml --from yaml --language java --out ../java --generate-only" +//go:generate rm -rf buildx/*/app +//go:generate cp -r buildx/app buildx/yaml/. +//go:generate cp -r buildx/app buildx/csharp/. +//go:generate cp -r buildx/app buildx/go/. +//go:generate cp -r buildx/app buildx/ts/. +//go:generate cp -r buildx/app buildx/py/. +//go:generate cp -r buildx/app buildx/java/. + +package examples diff --git a/provider/cmd/pulumi-resource-docker/schema.json b/provider/cmd/pulumi-resource-docker/schema.json index c25cd489..0fdb8a63 100644 --- a/provider/cmd/pulumi-resource-docker/schema.json +++ b/provider/cmd/pulumi-resource-docker/schema.json @@ -726,13 +726,6 @@ "$ref": "#/types/docker:buildx/image:ExportLocal", "description": "Export to a local directory as files and directories." }, - "manifests": { - "type": "array", - "items": { - "$ref": "#/types/docker:buildx/image:Manifest" - }, - "description": "An output property populated for exporters that pushed image\nmanifest(s) to a registry." - }, "oci": { "$ref": "#/types/docker:buildx/image:ExportOCI", "description": "Identical to the Docker exporter but uses OCI media types by default." @@ -961,48 +954,21 @@ "dest" ] }, - "docker:buildx/image:Manifest": { - "properties": { - "digest": { - "type": "string", - "description": "The SHA256 digest of the manifest." - }, - "platform": { - "$ref": "#/types/docker:buildx/image:ManifestPlatform", - "description": "The manifest's platform." - }, - "ref": { - "type": "string", - "description": "The manifest's canonical ref." + "docker:buildx/image:NetworkMode": { + "type": "string", + "enum": [ + { + "description": "The default sandbox network mode.", + "value": "default" }, - "size": { - "type": "integer", - "description": "The size of the manifest in bytes." - } - }, - "type": "object", - "required": [ - "digest", - "platform", - "ref", - "size" - ] - }, - "docker:buildx/image:ManifestPlatform": { - "properties": { - "architecture": { - "type": "string", - "description": "The manifest's architecture." + { + "description": "Host network mode.", + "value": "host" }, - "os": { - "type": "string", - "description": "The manifest's operating systen." + { + "description": "Disable network access.", + "value": "none" } - }, - "type": "object", - "required": [ - "os", - "architecture" ] }, "docker:buildx/image:Platform": { @@ -1115,6 +1081,25 @@ "address" ] }, + "docker:buildx/image:SSH": { + "properties": { + "id": { + "type": "string", + "description": "Useful for distinguishing different servers that are part of the same\nbuild.\n\nA value of `default` is appropriate if only dealing with a single host." + }, + "paths": { + "type": "array", + "items": { + "type": "string" + }, + "description": "SSH agent socket or private keys to expose to the build under the given\nidentifier.\n\nDefaults to `[$SSH_AUTH_SOCK]`.\n\nNote that your keys are **not** automatically added when using an\nagent. Run `ssh-add -l` locally to confirm which public keys are\nvisible to the agent; these will be exposed to your build." + } + }, + "type": "object", + "required": [ + "id" + ] + }, "docker:config/registryAuth:registryAuth": { "properties": { "address": { @@ -3089,6 +3074,13 @@ "docker:buildx/image:Image": { "description": "A Docker image built using buildx -- Docker's interface to the improved\nBuildKit backend.\n\n## Stability\n\n**This resource is experimental and subject to change.**\n\nAPI types are unstable. Subsequent releases _may_ require manual edits\nto your state file(s) in order to adopt API changes.\n\n`retainOnDelete: true` is recommended with this resource until it is\nstable. This enables future API changes to be adopted more easily by renaming\nresources.\n\nOnly use this resource if you understand and accept the risks.\n\n## Migrating v3 and v4 Image resources\n\nThe `buildx.Image` resource provides a superset of functionality over the `Image` resources available in versions 3 and 4 of the Pulumi Docker provider.\nExisting `Image` resources can be converted to `build.Image` resources with minor modifications.\n\n### Behavioral differences\n\nThere are several key behavioral differences to keep in mind when transitioning images to the new `buildx.Image` resource.\n\n#### Previews\n\nVersion `3.x` of the Pulumi Docker provider always builds images during preview operations.\nThis is helpful as a safeguard to prevent \"broken\" images from merging, but users found the behavior unnecessarily redundant when running previews and updates locally.\n\nVersion `4.x` changed build-on-preview behavior to be opt-in.\nBy default, `v4.x` `Image` resources do _not_ build during previews, but this behavior can be toggled with the `buildOnPreview` option.\nSome users felt this made previews in CI less helpful because they no longer detected bad images by default.\n\nThe default behavior of the `buildx.Image` resource has been changed to strike a better balance between CI use cases and manual updates.\nBy default, Pulumi will now only build `buildx.Image` resources during previews when it detects a CI environment like GitHub Actions.\nPreviews run in non-CI environments will not build images.\nThis behavior is still configurable with `buildOnPreview`.\n\n#### Push behavior\n\nVersions `3.x` and `4.x` of the Pulumi Docker provider attempt to push images to remote registries by default.\nThey expose a `skipPush: true` option to disable pushing.\n\nThe `buildx.Image` resource matches the Docker CLI's behavior and does not push images anywhere by default.\n\nTo push images to a registry you can include `push: true` (equivalent to Docker's `--push` flag) or configure an `export` of type `registry` (equivalent to Docker's `--output type=registry`).\nLike Docker, if an image is configured without exports you will see a warning with instructions for how to enable pushing, but the build will still proceed normally.\n\n#### Secrets\n\nVersion `3.x` of the Pulumi Docker provider supports secrets by way of the `extraOptions` field.\n\nVersion `4.x` of the Pulumi Docker provider does not support secrets.\n\nThe `buildx.Image` resource supports secrets but does not require those secrets to exist on-disk or in environment variables.\nInstead, they should be passed directly as values.\n(Please be sure to familiarize yourself with Pulumi's [native secret handling](https://www.pulumi.com/docs/concepts/secrets/).)\nPulumi also provides [ESC](https://www.pulumi.com/product/esc/) to make it easier to share secrets across stacks and environments.\n\n#### Caching\n\nVersion `3.x` of the Pulumi Docker provider exposes `cacheFrom: bool | { stages: [...] }`.\nIt builds targets individually and pushes them to separate images for caching.\n\nVersion `4.x` exposes a similar parameter `cacheFrom: { images: [...] }` which pushes and pulls inline caches.\n\nBoth versions 3 and 4 require specific environment variables to be set and deviate from Docker's native caching behavior.\nThis can result in inefficient builds due to unnecessary image pulls, repeated file transfers, etc.\n\nThe `buildx.Image` resource delegates all caching behavior to Docker.\n`cacheFrom` and `cacheTo` options (equivalent to Docker's `--cache-to` and `--cache-from`) are exposed and provide additional cache targets, such as local disk, S3 storage, etc.\n\n#### Outputs\n\nTODO:\n\n#### Tag deletion and refreshes\n\nVersions 3 and 4 of Pulumi Docker provider do not delete tags when the `Image` resource is deleted, nor do they confirm expected tags exist during `refresh` operations.\n\nThe `buidx.Image` will query your registries during `refresh` to ensure the expected tags exist.\nIf any are missing a subsequent `update` will push them.\n\nWhen a `buildx.Image` is deleted, it will _attempt_ to also delete any pushed tags.\nDeletion of remote tags is not guaranteed, because not all registries currently support this operation (`docker.io` in particular).\n\nUse the [`retainOnDelete: true`](https://www.pulumi.com/docs/concepts/options/retainondelete/) option if you do not want tags deleted.\n\n### Example migration\n\nExamples of \"fully-featured\" `v3` and `v4` `Image` resources are shown below, along with an example `buildx.Image` resource showing how they would look after migration.\n\nThe `v3` resource leverages `buildx` via a `DOCKER_BUILDKIT` environment variable and CLI flags passed in with `extraOption`.\nAfter migration, the environment variable is no longer needed and CLI flags are now properties on the `buildx.Image`.\nIn almost all cases, properties of `buildx.Image` are named after the Docker CLI flag they correspond to.\n\nThe `v4` resource is less functional than its `v3` counterpart because it lacks the flexibility of `extraOptions`.\nIt it is shown with parameters similar to the `v3` example for completeness.\n\n{{% examples %}}\n## Example Usage\n{{% example %}}\n### v3/v4 migration\n\n```typescript\n\n// v3 Image\nconst v3 = new docker.Image(\"v3-image\", {\n imageName: \"myregistry.com/user/repo:latest\",\n localImageName: \"local-tag\",\n skipPush: false,\n build: {\n dockerfile: \"./Dockerfile\",\n context: \"../app\",\n target: \"mytarget\",\n args: {\n MY_BUILD_ARG: \"foo\",\n },\n env: {\n DOCKER_BUILDKIT: \"1\",\n },\n extraOptions: [\n \"--cache-from\",\n \"type=registry,myregistry.com/user/repo:cache\",\n \"--cache-to\",\n \"type=registry,myregistry.com/user/repo:cache\",\n \"--add-host\",\n \"metadata.google.internal:169.254.169.254\",\n \"--secret\",\n \"id=mysecret,src=/local/secret\",\n \"--ssh\",\n \"default=/home/runner/.ssh/id_ed25519\",\n \"--network\",\n \"host\",\n \"--platform\",\n \"linux/amd64\",\n ],\n },\n registry: {\n server: \"myregistry.com\",\n username: \"username\",\n password: pulumi.secret(\"password\"),\n },\n});\n\n// v3 Image after migrating to buildx.Image\nconst v3Migrated = new docker.buildx.Image(\"v3-to-buildx\", {\n tags: [\"myregistry.com/user/repo:latest\", \"local-tag\"],\n push: true,\n dockerfile: {\n location: \"./Dockerfile\",\n },\n context: {\n location: \"../app\",\n },\n targets: [\"mytarget\"],\n buildArgs: {\n MY_BUILD_ARG: \"foo\",\n },\n cacheFrom: [{ registry: { ref: \"myregistry.com/user/repo:cache\" } }],\n cacheTo: [{ registry: { ref: \"myregistry.com/user/repo:cache\" } }],\n secrets: {\n mysecret: \"value\",\n },\n addHosts: [\"metadata.google.internal:169.254.169.254\"],\n ssh: {\n default: [\"/home/runner/.ssh/id_ed25519\"],\n },\n network: \"host\",\n platforms: [\"linux/amd64\"],\n registries: [{\n address: \"myregistry.com\",\n username: \"username\",\n password: pulumi.secret(\"password\"),\n }],\n});\n\n\n// v4 Image\nconst v4 = new docker.Image(\"v4-image\", {\n imageName: \"myregistry.com/user/repo:latest\",\n skipPush: false,\n build: {\n dockerfile: \"./Dockerfile\",\n context: \"../app\",\n target: \"mytarget\",\n args: {\n MY_BUILD_ARG: \"foo\",\n },\n cacheFrom: {\n images: [\"myregistry.com/user/repo:cache\"],\n },\n addHosts: [\"metadata.google.internal:169.254.169.254\"],\n network: \"host\",\n platform: \"linux/amd64\",\n },\n buildOnPreview: true,\n registry: {\n server: \"myregistry.com\",\n username: \"username\",\n password: pulumi.secret(\"password\"),\n },\n});\n\n// v4 Image after migrating to buildx.Image\nconst v4Migrated = new docker.buildx.Image(\"v4-to-buildx\", {\n tags: [\"myregistry.com/user/repo:latest\"],\n push: true,\n dockerfile: {\n location: \"./Dockerfile\",\n },\n context: {\n location: \"../app\",\n },\n targets: [\"mytarget\"],\n buildArgs: {\n MY_BUILD_ARG: \"foo\",\n },\n cacheFrom: [{ registry: { ref: \"myregistry.com/user/repo:cache\" } }],\n cacheTo: [{ registry: { ref: \"myregistry.com/user/repo:cache\" } }],\n addHosts: [\"metadata.google.internal:169.254.169.254\"],\n network: \"host\",\n platforms: [\"linux/amd64\"],\n registries: [{\n address: \"myregistry.com\",\n username: \"username\",\n password: pulumi.secret(\"password\"),\n }],\n});\n\n```\n\n{{% /example %}}\n\n\n{{% examples %}}\n## Example Usage\n{{% example %}}\n### Push to AWS ECR with caching\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport * as docker from \"@pulumi/docker\";\n\nconst ecrRepository = new aws.ecr.Repository(\"ecr-repository\", {});\nconst authToken = aws.ecr.getAuthorizationTokenOutput({\n registryId: ecrRepository.registryId,\n});\nconst myImage = new docker.buildx.Image(\"my-image\", {\n cacheFrom: [{\n registry: {\n ref: pulumi.interpolate`${ecrRepository.repositoryUrl}:cache`,\n },\n }],\n cacheTo: [{\n registry: {\n imageManifest: true,\n ociMediaTypes: true,\n ref: pulumi.interpolate`${ecrRepository.repositoryUrl}:cache`,\n },\n }],\n context: {\n location: \"./app\",\n },\n dockerfile: {\n location: \"./Dockerfile\",\n },\n push: true,\n registries: [{\n address: ecrRepository.repositoryUrl,\n password: authToken.apply(authToken =\u003e authToken.password),\n username: authToken.apply(authToken =\u003e authToken.userName),\n }],\n tags: [pulumi.interpolate`${ecrRepository.repositoryUrl}:latest`],\n});\n```\n```python\nimport pulumi\nimport pulumi_aws as aws\nimport pulumi_docker as docker\n\necr_repository = aws.ecr.Repository(\"ecr-repository\")\nauth_token = aws.ecr.get_authorization_token_output(registry_id=ecr_repository.registry_id)\nmy_image = docker.buildx.Image(\"my-image\",\n cache_from=[docker.buildx.CacheFromEntryArgs(\n registry=docker.buildx.CacheFromRegistryArgs(\n ref=ecr_repository.repository_url.apply(lambda repository_url: f\"{repository_url}:cache\"),\n ),\n )],\n cache_to=[docker.buildx.CacheToEntryArgs(\n registry=docker.buildx.CacheToRegistryArgs(\n image_manifest=True,\n oci_media_types=True,\n ref=ecr_repository.repository_url.apply(lambda repository_url: f\"{repository_url}:cache\"),\n ),\n )],\n context=docker.buildx.BuildContextArgs(\n location=\"./app\",\n ),\n dockerfile=docker.buildx.DockerfileArgs(\n location=\"./Dockerfile\",\n ),\n push=True,\n registries=[docker.buildx.RegistryAuthArgs(\n address=ecr_repository.repository_url,\n password=auth_token.password,\n username=auth_token.user_name,\n )],\n tags=[ecr_repository.repository_url.apply(lambda repository_url: f\"{repository_url}:latest\")])\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Aws = Pulumi.Aws;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var ecrRepository = new Aws.Ecr.Repository(\"ecr-repository\");\n\n var authToken = Aws.Ecr.GetAuthorizationToken.Invoke(new()\n {\n RegistryId = ecrRepository.RegistryId,\n });\n\n var myImage = new Docker.Buildx.Image(\"my-image\", new()\n {\n CacheFrom = new[]\n {\n new Docker.Buildx.Inputs.CacheFromEntryArgs\n {\n Registry = new Docker.Buildx.Inputs.CacheFromRegistryArgs\n {\n Ref = ecrRepository.RepositoryUrl.Apply(repositoryUrl =\u003e $\"{repositoryUrl}:cache\"),\n },\n },\n },\n CacheTo = new[]\n {\n new Docker.Buildx.Inputs.CacheToEntryArgs\n {\n Registry = new Docker.Buildx.Inputs.CacheToRegistryArgs\n {\n ImageManifest = true,\n OciMediaTypes = true,\n Ref = ecrRepository.RepositoryUrl.Apply(repositoryUrl =\u003e $\"{repositoryUrl}:cache\"),\n },\n },\n },\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"./app\",\n },\n Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs\n {\n Location = \"./Dockerfile\",\n },\n Push = true,\n Registries = new[]\n {\n new Docker.Buildx.Inputs.RegistryAuthArgs\n {\n Address = ecrRepository.RepositoryUrl,\n Password = authToken.Apply(getAuthorizationTokenResult =\u003e getAuthorizationTokenResult.Password),\n Username = authToken.Apply(getAuthorizationTokenResult =\u003e getAuthorizationTokenResult.UserName),\n },\n },\n Tags = new[]\n {\n ecrRepository.RepositoryUrl.Apply(repositoryUrl =\u003e $\"{repositoryUrl}:latest\"),\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ecr\"\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\tecrRepository, err := ecr.NewRepository(ctx, \"ecr-repository\", nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tauthToken := ecr.GetAuthorizationTokenOutput(ctx, ecr.GetAuthorizationTokenOutputArgs{\n\t\t\tRegistryId: ecrRepository.RegistryId,\n\t\t}, nil)\n\t\t_, err = buildx.NewImage(ctx, \"my-image\", \u0026buildx.ImageArgs{\n\t\t\tCacheFrom: buildx.CacheFromEntryArray{\n\t\t\t\t\u0026buildx.CacheFromEntryArgs{\n\t\t\t\t\tRegistry: \u0026buildx.CacheFromRegistryArgs{\n\t\t\t\t\t\tRef: ecrRepository.RepositoryUrl.ApplyT(func(repositoryUrl string) (string, error) {\n\t\t\t\t\t\t\treturn fmt.Sprintf(\"%v:cache\", repositoryUrl), nil\n\t\t\t\t\t\t}).(pulumi.StringOutput),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tCacheTo: buildx.CacheToEntryArray{\n\t\t\t\t\u0026buildx.CacheToEntryArgs{\n\t\t\t\t\tRegistry: \u0026buildx.CacheToRegistryArgs{\n\t\t\t\t\t\tImageManifest: pulumi.Bool(true),\n\t\t\t\t\t\tOciMediaTypes: pulumi.Bool(true),\n\t\t\t\t\t\tRef: ecrRepository.RepositoryUrl.ApplyT(func(repositoryUrl string) (string, error) {\n\t\t\t\t\t\t\treturn fmt.Sprintf(\"%v:cache\", repositoryUrl), nil\n\t\t\t\t\t\t}).(pulumi.StringOutput),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"./app\"),\n\t\t\t},\n\t\t\tDockerfile: \u0026buildx.DockerfileArgs{\n\t\t\t\tLocation: pulumi.String(\"./Dockerfile\"),\n\t\t\t},\n\t\t\tPush: pulumi.Bool(true),\n\t\t\tRegistries: buildx.RegistryAuthArray{\n\t\t\t\t\u0026buildx.RegistryAuthArgs{\n\t\t\t\t\tAddress: ecrRepository.RepositoryUrl,\n\t\t\t\t\tPassword: authToken.ApplyT(func(authToken ecr.GetAuthorizationTokenResult) (*string, error) {\n\t\t\t\t\t\treturn \u0026authToken.Password, nil\n\t\t\t\t\t}).(pulumi.StringPtrOutput),\n\t\t\t\t\tUsername: authToken.ApplyT(func(authToken ecr.GetAuthorizationTokenResult) (*string, error) {\n\t\t\t\t\t\treturn \u0026authToken.UserName, nil\n\t\t\t\t\t}).(pulumi.StringPtrOutput),\n\t\t\t\t},\n\t\t\t},\n\t\t\tTags: pulumi.StringArray{\n\t\t\t\tecrRepository.RepositoryUrl.ApplyT(func(repositoryUrl string) (string, error) {\n\t\t\t\t\treturn fmt.Sprintf(\"%v:latest\", repositoryUrl), nil\n\t\t\t\t}).(pulumi.StringOutput),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Push to AWS ECR with caching\nname: ecr\nresources:\n ecr-repository:\n type: aws:ecr:Repository\n my-image:\n properties:\n cacheFrom:\n - registry:\n ref: ${ecr-repository.repositoryUrl}:cache\n cacheTo:\n - registry:\n imageManifest: true\n ociMediaTypes: true\n ref: ${ecr-repository.repositoryUrl}:cache\n context:\n location: ./app\n dockerfile:\n location: ./Dockerfile\n push: true\n registries:\n - address: ${ecr-repository.repositoryUrl}\n password: ${auth-token.password}\n username: ${auth-token.userName}\n tags:\n - ${ecr-repository.repositoryUrl}:latest\n type: docker:buildx/image:Image\nruntime: yaml\nvariables:\n auth-token:\n fn::aws:ecr:getAuthorizationToken:\n registryId: ${ecr-repository.registryId}\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.aws.ecr.Repository;\nimport com.pulumi.aws.ecr.EcrFunctions;\nimport com.pulumi.aws.ecr.inputs.GetAuthorizationTokenArgs;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.CacheFromEntryArgs;\nimport com.pulumi.docker.buildx.inputs.CacheFromRegistryArgs;\nimport com.pulumi.docker.buildx.inputs.CacheToEntryArgs;\nimport com.pulumi.docker.buildx.inputs.CacheToRegistryArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport com.pulumi.docker.buildx.inputs.DockerfileArgs;\nimport com.pulumi.docker.buildx.inputs.RegistryAuthArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var ecrRepository = new Repository(\"ecrRepository\");\n\n final var authToken = EcrFunctions.getAuthorizationToken(GetAuthorizationTokenArgs.builder()\n .registryId(ecrRepository.registryId())\n .build());\n\n var myImage = new Image(\"myImage\", ImageArgs.builder() \n .cacheFrom(CacheFromEntryArgs.builder()\n .registry(CacheFromRegistryArgs.builder()\n .ref(ecrRepository.repositoryUrl().applyValue(repositoryUrl -\u003e String.format(\"%s:cache\", repositoryUrl)))\n .build())\n .build())\n .cacheTo(CacheToEntryArgs.builder()\n .registry(CacheToRegistryArgs.builder()\n .imageManifest(true)\n .ociMediaTypes(true)\n .ref(ecrRepository.repositoryUrl().applyValue(repositoryUrl -\u003e String.format(\"%s:cache\", repositoryUrl)))\n .build())\n .build())\n .context(BuildContextArgs.builder()\n .location(\"./app\")\n .build())\n .dockerfile(DockerfileArgs.builder()\n .location(\"./Dockerfile\")\n .build())\n .push(true)\n .registries(RegistryAuthArgs.builder()\n .address(ecrRepository.repositoryUrl())\n .password(authToken.applyValue(getAuthorizationTokenResult -\u003e getAuthorizationTokenResult).applyValue(authToken -\u003e authToken.applyValue(getAuthorizationTokenResult -\u003e getAuthorizationTokenResult.password())))\n .username(authToken.applyValue(getAuthorizationTokenResult -\u003e getAuthorizationTokenResult).applyValue(authToken -\u003e authToken.applyValue(getAuthorizationTokenResult -\u003e getAuthorizationTokenResult.userName())))\n .build())\n .tags(ecrRepository.repositoryUrl().applyValue(repositoryUrl -\u003e String.format(\"%s:latest\", repositoryUrl)))\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% example %}}\n### Multi-platform image\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst image = new docker.buildx.Image(\"image\", {\n context: {\n location: \"app\",\n },\n platforms: [\n docker.buildx.image.Platform.Plan9_amd64,\n docker.buildx.image.Platform.Plan9_386,\n ],\n});\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\nimage = docker.buildx.Image(\"image\",\n context=docker.buildx.BuildContextArgs(\n location=\"app\",\n ),\n platforms=[\n docker.buildx/image.Platform.PLAN9_AMD64,\n docker.buildx/image.Platform.PLAN9_386,\n ])\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var image = new Docker.Buildx.Image(\"image\", new()\n {\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"app\",\n },\n Platforms = new[]\n {\n Docker.Buildx.Image.Platform.Plan9_amd64,\n Docker.Buildx.Image.Platform.Plan9_386,\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := buildx.NewImage(ctx, \"image\", \u0026buildx.ImageArgs{\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"app\"),\n\t\t\t},\n\t\t\tPlatforms: buildx.PlatformArray{\n\t\t\t\tbuildx.Platform_Plan9_amd64,\n\t\t\t\tbuildx.Platform_Plan9_386,\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Multi-platform image\nname: multi-platform\nresources:\n image:\n properties:\n context:\n location: app\n platforms:\n - plan9/amd64\n - plan9/386\n type: docker:buildx/image:Image\nruntime: yaml\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var image = new Image(\"image\", ImageArgs.builder() \n .context(BuildContextArgs.builder()\n .location(\"app\")\n .build())\n .platforms( \n \"plan9/amd64\",\n \"plan9/386\")\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% example %}}\n### Registry export\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst image = new docker.buildx.Image(\"image\", {\n context: {\n location: \"app\",\n },\n push: true,\n registries: [{\n address: \"docker.io\",\n password: dockerHubPassword,\n username: \"pulumibot\",\n }],\n tags: [\"docker.io/pulumi/pulumi:3.107.0\"],\n});\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\nimage = docker.buildx.Image(\"image\",\n context=docker.buildx.BuildContextArgs(\n location=\"app\",\n ),\n push=True,\n registries=[docker.buildx.RegistryAuthArgs(\n address=\"docker.io\",\n password=docker_hub_password,\n username=\"pulumibot\",\n )],\n tags=[\"docker.io/pulumi/pulumi:3.107.0\"])\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var image = new Docker.Buildx.Image(\"image\", new()\n {\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"app\",\n },\n Push = true,\n Registries = new[]\n {\n new Docker.Buildx.Inputs.RegistryAuthArgs\n {\n Address = \"docker.io\",\n Password = dockerHubPassword,\n Username = \"pulumibot\",\n },\n },\n Tags = new[]\n {\n \"docker.io/pulumi/pulumi:3.107.0\",\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := buildx.NewImage(ctx, \"image\", \u0026buildx.ImageArgs{\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"app\"),\n\t\t\t},\n\t\t\tPush: pulumi.Bool(true),\n\t\t\tRegistries: buildx.RegistryAuthArray{\n\t\t\t\t\u0026buildx.RegistryAuthArgs{\n\t\t\t\t\tAddress: pulumi.String(\"docker.io\"),\n\t\t\t\t\tPassword: pulumi.Any(dockerHubPassword),\n\t\t\t\t\tUsername: pulumi.String(\"pulumibot\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\tTags: pulumi.StringArray{\n\t\t\t\tpulumi.String(\"docker.io/pulumi/pulumi:3.107.0\"),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Registry export\nname: registry\nresources:\n image:\n properties:\n context:\n location: app\n push: true\n registries:\n - address: docker.io\n password: ${dockerHubPassword}\n username: pulumibot\n tags:\n - docker.io/pulumi/pulumi:3.107.0\n type: docker:buildx/image:Image\nruntime: yaml\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport com.pulumi.docker.buildx.inputs.RegistryAuthArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var image = new Image(\"image\", ImageArgs.builder() \n .context(BuildContextArgs.builder()\n .location(\"app\")\n .build())\n .push(true)\n .registries(RegistryAuthArgs.builder()\n .address(\"docker.io\")\n .password(dockerHubPassword)\n .username(\"pulumibot\")\n .build())\n .tags(\"docker.io/pulumi/pulumi:3.107.0\")\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% example %}}\n### Caching\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst image = new docker.buildx.Image(\"image\", {\n cacheFrom: [{\n local: {\n src: \"tmp/cache\",\n },\n }],\n cacheTo: [{\n local: {\n dest: \"tmp/cache\",\n mode: docker.buildx.image.CacheMode.Max,\n },\n }],\n context: {\n location: \"app\",\n },\n});\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\nimage = docker.buildx.Image(\"image\",\n cache_from=[docker.buildx.CacheFromEntryArgs(\n local=docker.buildx.CacheFromLocalArgs(\n src=\"tmp/cache\",\n ),\n )],\n cache_to=[docker.buildx.CacheToEntryArgs(\n local=docker.buildx.CacheToLocalArgs(\n dest=\"tmp/cache\",\n mode=docker.buildx/image.CacheMode.MAX,\n ),\n )],\n context=docker.buildx.BuildContextArgs(\n location=\"app\",\n ))\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var image = new Docker.Buildx.Image(\"image\", new()\n {\n CacheFrom = new[]\n {\n new Docker.Buildx.Inputs.CacheFromEntryArgs\n {\n Local = new Docker.Buildx.Inputs.CacheFromLocalArgs\n {\n Src = \"tmp/cache\",\n },\n },\n },\n CacheTo = new[]\n {\n new Docker.Buildx.Inputs.CacheToEntryArgs\n {\n Local = new Docker.Buildx.Inputs.CacheToLocalArgs\n {\n Dest = \"tmp/cache\",\n Mode = Docker.Buildx.Image.CacheMode.Max,\n },\n },\n },\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"app\",\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := buildx.NewImage(ctx, \"image\", \u0026buildx.ImageArgs{\n\t\t\tCacheFrom: buildx.CacheFromEntryArray{\n\t\t\t\t\u0026buildx.CacheFromEntryArgs{\n\t\t\t\t\tLocal: \u0026buildx.CacheFromLocalArgs{\n\t\t\t\t\t\tSrc: pulumi.String(\"tmp/cache\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tCacheTo: buildx.CacheToEntryArray{\n\t\t\t\t\u0026buildx.CacheToEntryArgs{\n\t\t\t\t\tLocal: \u0026buildx.CacheToLocalArgs{\n\t\t\t\t\t\tDest: pulumi.String(\"tmp/cache\"),\n\t\t\t\t\t\tMode: buildx.CacheModeMax,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"app\"),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Caching\nname: caching\nresources:\n image:\n properties:\n cacheFrom:\n - local:\n src: tmp/cache\n cacheTo:\n - local:\n dest: tmp/cache\n mode: max\n context:\n location: app\n type: docker:buildx/image:Image\nruntime: yaml\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.CacheFromEntryArgs;\nimport com.pulumi.docker.buildx.inputs.CacheFromLocalArgs;\nimport com.pulumi.docker.buildx.inputs.CacheToEntryArgs;\nimport com.pulumi.docker.buildx.inputs.CacheToLocalArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var image = new Image(\"image\", ImageArgs.builder() \n .cacheFrom(CacheFromEntryArgs.builder()\n .local(CacheFromLocalArgs.builder()\n .src(\"tmp/cache\")\n .build())\n .build())\n .cacheTo(CacheToEntryArgs.builder()\n .local(CacheToLocalArgs.builder()\n .dest(\"tmp/cache\")\n .mode(\"max\")\n .build())\n .build())\n .context(BuildContextArgs.builder()\n .location(\"app\")\n .build())\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% example %}}\n### Build arguments\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst image = new docker.buildx.Image(\"image\", {\n buildArgs: {\n SET_ME_TO_TRUE: \"true\",\n },\n context: {\n location: \"app\",\n },\n});\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\nimage = docker.buildx.Image(\"image\",\n build_args={\n \"SET_ME_TO_TRUE\": \"true\",\n },\n context=docker.buildx.BuildContextArgs(\n location=\"app\",\n ))\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var image = new Docker.Buildx.Image(\"image\", new()\n {\n BuildArgs = \n {\n { \"SET_ME_TO_TRUE\", \"true\" },\n },\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"app\",\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := buildx.NewImage(ctx, \"image\", \u0026buildx.ImageArgs{\n\t\t\tBuildArgs: pulumi.StringMap{\n\t\t\t\t\"SET_ME_TO_TRUE\": pulumi.String(\"true\"),\n\t\t\t},\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"app\"),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Build arguments\nname: build-args\nresources:\n image:\n properties:\n buildArgs:\n SET_ME_TO_TRUE: \"true\"\n context:\n location: app\n type: docker:buildx/image:Image\nruntime: yaml\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var image = new Image(\"image\", ImageArgs.builder() \n .buildArgs(Map.of(\"SET_ME_TO_TRUE\", \"true\"))\n .context(BuildContextArgs.builder()\n .location(\"app\")\n .build())\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% example %}}\n### Build targets\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst image = new docker.buildx.Image(\"image\", {\n context: {\n location: \"app\",\n },\n targets: [\n \"build-me\",\n \"also-build-me\",\n ],\n});\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\nimage = docker.buildx.Image(\"image\",\n context=docker.buildx.BuildContextArgs(\n location=\"app\",\n ),\n targets=[\n \"build-me\",\n \"also-build-me\",\n ])\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var image = new Docker.Buildx.Image(\"image\", new()\n {\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"app\",\n },\n Targets = new[]\n {\n \"build-me\",\n \"also-build-me\",\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := buildx.NewImage(ctx, \"image\", \u0026buildx.ImageArgs{\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"app\"),\n\t\t\t},\n\t\t\tTargets: pulumi.StringArray{\n\t\t\t\tpulumi.String(\"build-me\"),\n\t\t\t\tpulumi.String(\"also-build-me\"),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Build targets\nname: build-targets\nresources:\n image:\n properties:\n context:\n location: app\n targets:\n - build-me\n - also-build-me\n type: docker:buildx/image:Image\nruntime: yaml\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var image = new Image(\"image\", ImageArgs.builder() \n .context(BuildContextArgs.builder()\n .location(\"app\")\n .build())\n .targets( \n \"build-me\",\n \"also-build-me\")\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% example %}}\n### Named contexts\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst image = new docker.buildx.Image(\"image\", {context: {\n location: \"app\",\n named: {\n \"golang:latest\": {\n location: \"docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984\",\n },\n },\n}});\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\nimage = docker.buildx.Image(\"image\", context=docker.buildx.BuildContextArgs(\n location=\"app\",\n named={\n \"golang:latest\": docker.buildx.ContextArgs(\n location=\"docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984\",\n ),\n },\n))\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var image = new Docker.Buildx.Image(\"image\", new()\n {\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"app\",\n Named = \n {\n { \"golang:latest\", new Docker.Buildx.Inputs.ContextArgs\n {\n Location = \"docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984\",\n } },\n },\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := buildx.NewImage(ctx, \"image\", \u0026buildx.ImageArgs{\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"app\"),\n\t\t\t\tNamed: buildx.ContextMap{\n\t\t\t\t\t\"golang:latest\": \u0026buildx.ContextArgs{\n\t\t\t\t\t\tLocation: pulumi.String(\"docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Named contexts\nname: named-contexts\nresources:\n image:\n properties:\n context:\n location: app\n named:\n golang:latest:\n location: docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984\n type: docker:buildx/image:Image\nruntime: yaml\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var image = new Image(\"image\", ImageArgs.builder() \n .context(BuildContextArgs.builder()\n .location(\"app\")\n .named(Map.of(\"golang:latest\", Map.of(\"location\", \"docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984\")))\n .build())\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% example %}}\n### Remote context\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst image = new docker.buildx.Image(\"image\", {context: {\n location: \"https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile\",\n}});\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\nimage = docker.buildx.Image(\"image\", context=docker.buildx.BuildContextArgs(\n location=\"https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile\",\n))\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var image = new Docker.Buildx.Image(\"image\", new()\n {\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile\",\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := buildx.NewImage(ctx, \"image\", \u0026buildx.ImageArgs{\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile\"),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Remote context\nname: remote-context\nresources:\n image:\n properties:\n context:\n location: https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile\n type: docker:buildx/image:Image\nruntime: yaml\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var image = new Image(\"image\", ImageArgs.builder() \n .context(BuildContextArgs.builder()\n .location(\"https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile\")\n .build())\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% example %}}\n### Inline Dockerfile\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst image = new docker.buildx.Image(\"image\", {\n context: {\n location: \"app\",\n },\n dockerfile: {\n inline: `FROM busybox\nCOPY hello.c ./\n`,\n },\n});\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\nimage = docker.buildx.Image(\"image\",\n context=docker.buildx.BuildContextArgs(\n location=\"app\",\n ),\n dockerfile=docker.buildx.DockerfileArgs(\n inline=\"\"\"FROM busybox\nCOPY hello.c ./\n\"\"\",\n ))\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var image = new Docker.Buildx.Image(\"image\", new()\n {\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"app\",\n },\n Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs\n {\n Inline = @\"FROM busybox\nCOPY hello.c ./\n\",\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := buildx.NewImage(ctx, \"image\", \u0026buildx.ImageArgs{\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"app\"),\n\t\t\t},\n\t\t\tDockerfile: \u0026buildx.DockerfileArgs{\n\t\t\t\tInline: pulumi.String(\"FROM busybox\\nCOPY hello.c ./\\n\"),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Inline Dockerfile\nname: inline\nresources:\n image:\n properties:\n context:\n location: app\n dockerfile:\n inline: |\n FROM busybox\n COPY hello.c ./\n type: docker:buildx/image:Image\nruntime: yaml\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport com.pulumi.docker.buildx.inputs.DockerfileArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var image = new Image(\"image\", ImageArgs.builder() \n .context(BuildContextArgs.builder()\n .location(\"app\")\n .build())\n .dockerfile(DockerfileArgs.builder()\n .inline(\"\"\"\nFROM busybox\nCOPY hello.c ./\n \"\"\")\n .build())\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% example %}}\n### Remote context\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst image = new docker.buildx.Image(\"image\", {\n context: {\n location: \"https://github.com/docker-library/hello-world.git\",\n },\n dockerfile: {\n location: \"app/Dockerfile\",\n },\n});\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\nimage = docker.buildx.Image(\"image\",\n context=docker.buildx.BuildContextArgs(\n location=\"https://github.com/docker-library/hello-world.git\",\n ),\n dockerfile=docker.buildx.DockerfileArgs(\n location=\"app/Dockerfile\",\n ))\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var image = new Docker.Buildx.Image(\"image\", new()\n {\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"https://github.com/docker-library/hello-world.git\",\n },\n Dockerfile = new Docker.Buildx.Inputs.DockerfileArgs\n {\n Location = \"app/Dockerfile\",\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := buildx.NewImage(ctx, \"image\", \u0026buildx.ImageArgs{\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"https://github.com/docker-library/hello-world.git\"),\n\t\t\t},\n\t\t\tDockerfile: \u0026buildx.DockerfileArgs{\n\t\t\t\tLocation: pulumi.String(\"app/Dockerfile\"),\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Remote context\nname: remote-context\nresources:\n image:\n properties:\n context:\n location: https://github.com/docker-library/hello-world.git\n dockerfile:\n location: app/Dockerfile\n type: docker:buildx/image:Image\nruntime: yaml\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport com.pulumi.docker.buildx.inputs.DockerfileArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var image = new Image(\"image\", ImageArgs.builder() \n .context(BuildContextArgs.builder()\n .location(\"https://github.com/docker-library/hello-world.git\")\n .build())\n .dockerfile(DockerfileArgs.builder()\n .location(\"app/Dockerfile\")\n .build())\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% example %}}\n### Local export\n\n```typescript\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as docker from \"@pulumi/docker\";\n\nconst image = new docker.buildx.Image(\"image\", {\n context: {\n location: \"app\",\n },\n exports: [{\n docker: {\n tar: true,\n },\n }],\n});\n```\n```python\nimport pulumi\nimport pulumi_docker as docker\n\nimage = docker.buildx.Image(\"image\",\n context=docker.buildx.BuildContextArgs(\n location=\"app\",\n ),\n exports=[docker.buildx.ExportEntryArgs(\n docker=docker.buildx.ExportDockerArgs(\n tar=True,\n ),\n )])\n```\n```csharp\nusing System.Collections.Generic;\nusing System.Linq;\nusing Pulumi;\nusing Docker = Pulumi.Docker;\n\nreturn await Deployment.RunAsync(() =\u003e \n{\n var image = new Docker.Buildx.Image(\"image\", new()\n {\n Context = new Docker.Buildx.Inputs.BuildContextArgs\n {\n Location = \"app\",\n },\n Exports = new[]\n {\n new Docker.Buildx.Inputs.ExportEntryArgs\n {\n Docker = new Docker.Buildx.Inputs.ExportDockerArgs\n {\n Tar = true,\n },\n },\n },\n });\n\n});\n\n```\n```go\npackage main\n\nimport (\n\t\"github.com/pulumi/pulumi-docker/sdk/v4/go/docker/buildx\"\n\t\"github.com/pulumi/pulumi/sdk/v3/go/pulumi\"\n)\n\nfunc main() {\n\tpulumi.Run(func(ctx *pulumi.Context) error {\n\t\t_, err := buildx.NewImage(ctx, \"image\", \u0026buildx.ImageArgs{\n\t\t\tContext: \u0026buildx.BuildContextArgs{\n\t\t\t\tLocation: pulumi.String(\"app\"),\n\t\t\t},\n\t\t\tExports: buildx.ExportEntryArray{\n\t\t\t\t\u0026buildx.ExportEntryArgs{\n\t\t\t\t\tDocker: \u0026buildx.ExportDockerArgs{\n\t\t\t\t\t\tTar: pulumi.Bool(true),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n```\n```yaml\ndescription: Local export\nname: docker-load\nresources:\n image:\n properties:\n context:\n location: app\n exports:\n - docker:\n tar: true\n type: docker:buildx/image:Image\nruntime: yaml\n```\n```java\npackage generated_program;\n\nimport com.pulumi.Context;\nimport com.pulumi.Pulumi;\nimport com.pulumi.core.Output;\nimport com.pulumi.docker.buildx.Image;\nimport com.pulumi.docker.buildx.ImageArgs;\nimport com.pulumi.docker.buildx.inputs.BuildContextArgs;\nimport com.pulumi.docker.buildx.inputs.ExportEntryArgs;\nimport com.pulumi.docker.buildx.inputs.ExportDockerArgs;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.io.File;\nimport java.nio.file.Files;\nimport java.nio.file.Paths;\n\npublic class App {\n public static void main(String[] args) {\n Pulumi.run(App::stack);\n }\n\n public static void stack(Context ctx) {\n var image = new Image(\"image\", ImageArgs.builder() \n .context(BuildContextArgs.builder()\n .location(\"app\")\n .build())\n .exports(ExportEntryArgs.builder()\n .docker(ExportDockerArgs.builder()\n .tar(true)\n .build())\n .build())\n .build());\n\n }\n}\n```\n{{% /example %}}\n{{% /examples %}}", "properties": { + "addHosts": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Custom `host:ip` mappings to use during the build.\n\nEquivalent to Docker's `--add-host` flag." + }, "buildArgs": { "type": "object", "additionalProperties": { @@ -3098,7 +3090,7 @@ }, "buildOnPreview": { "type": "boolean", - "description": "When `true`, attempt to build the image during previews. The image will\nnot be pushed to registries, however caches will still be populated." + "description": "By default, preview behavior depends on the execution environment. If\nPulumi detects the operation is running on a CI system (GitHub Actions,\nTravis CI, Azure Pipelines, etc.) then it will build images during\npreviews as a safeguard. Otherwise, if not running on CI, previews will\nnot build images.\n\nSetting this to `false` forces previews to never perform builds, and\nsetting it to `true` will always build the image during previews.\n\nImages built during previews are never exported to registries, however\ncache manifests are still exported.\n\nOn-disk Dockerfiles are always validated for syntactic correctness\nregardless of this setting." }, "builder": { "$ref": "#/types/docker:buildx/image:BuilderConfig", @@ -3129,12 +3121,9 @@ "digests": { "type": "object", "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } + "type": "string" }, - "description": "A mapping of platform type to refs which were pushed to registries." + "description": "A mapping of target names to the SHA256 digest of their pushed manifest.\n\nIf no target was specified 'default' is used as the target name.\n\nPushed manifests can be referenced as `\u003ctag\u003e@\u003cdigest\u003e`." }, "dockerfile": { "$ref": "#/types/docker:buildx/image:Dockerfile", @@ -3154,6 +3143,19 @@ }, "description": "Attach arbitrary key/value metadata to the image.\n\nEquivalent to Docker's `--label` flag." }, + "load": { + "type": "boolean", + "description": "When `true` the build will automatically include a `docker` export.\n\nDefaults to `false`.\n\nEquivalent to Docker's `--load` flag." + }, + "network": { + "$ref": "#/types/docker:buildx/image:NetworkMode", + "description": "Set the network mode for `RUN` instructions. Defaults to `default`.\n\nFor custom networks, configure your builder with `--driver-opt network=...`.\n\nEquivalent to Docker's `--network` flag.", + "default": "default" + }, + "noCache": { + "type": "boolean", + "description": "Do not import cache manifests when building the image.\n\nEquivalent to Docker's `--no-cache` flag." + }, "platforms": { "type": "array", "items": { @@ -3165,6 +3167,14 @@ "type": "boolean", "description": "Always pull referenced images.\n\nEquivalent to Docker's `--pull` flag." }, + "push": { + "type": "boolean", + "description": "When `true` the build will automatically include a `registry` export.\n\nDefaults to `false`.\n\nEquivalent to Docker's `--push` flag." + }, + "ref": { + "type": "string", + "description": "If the image was pushed to any registries then this will contain a\nsingle fully-qualified tag including the build's digest.\n\nThis is only for convenience and may not be appropriate for situations\nwhere multiple tags or registries are involved. In those cases this\noutput is not guaranteed to be stable.\n\nFor more control over tags consumed by downstream resources you should\nuse the `Digests` output." + }, "registries": { "type": "array", "items": { @@ -3177,8 +3187,14 @@ "additionalProperties": { "type": "string" }, - "description": "A mapping of secret names to their corresponding values.\n\nUnlike the Docker CLI, these can be passed by value and do not need to\nexist on-disk or in environment variables.\n\nBuild arguments and environment variables are persistent in the final\nimage, so you should use this for sensitive values.\n\nSimilar to Docker's `--secret` flag.", - "secret": true + "description": "A mapping of secret names to their corresponding values.\n\nUnlike the Docker CLI, these can be passed by value and do not need to\nexist on-disk or in environment variables.\n\nBuild arguments and environment variables are persistent in the final\nimage, so you should use this for sensitive values.\n\nSimilar to Docker's `--secret` flag." + }, + "ssh": { + "type": "array", + "items": { + "$ref": "#/types/docker:buildx/image:SSH" + }, + "description": "SSH agent socket or keys to expose to the build.\n\nEquivalent to Docker's `--ssh` flag." }, "tags": { "type": "array", @@ -3195,7 +3211,19 @@ "description": "Set the target build stage(s) to build.\n\nIf not specified all targets will be built by default.\n\nEquivalent to Docker's `--target` flag." } }, + "required": [ + "digests", + "contextHash", + "ref" + ], "inputProperties": { + "addHosts": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Custom `host:ip` mappings to use during the build.\n\nEquivalent to Docker's `--add-host` flag." + }, "buildArgs": { "type": "object", "additionalProperties": { @@ -3205,7 +3233,7 @@ }, "buildOnPreview": { "type": "boolean", - "description": "When `true`, attempt to build the image during previews. The image will\nnot be pushed to registries, however caches will still be populated." + "description": "By default, preview behavior depends on the execution environment. If\nPulumi detects the operation is running on a CI system (GitHub Actions,\nTravis CI, Azure Pipelines, etc.) then it will build images during\npreviews as a safeguard. Otherwise, if not running on CI, previews will\nnot build images.\n\nSetting this to `false` forces previews to never perform builds, and\nsetting it to `true` will always build the image during previews.\n\nImages built during previews are never exported to registries, however\ncache manifests are still exported.\n\nOn-disk Dockerfiles are always validated for syntactic correctness\nregardless of this setting." }, "builder": { "$ref": "#/types/docker:buildx/image:BuilderConfig", @@ -3247,6 +3275,19 @@ }, "description": "Attach arbitrary key/value metadata to the image.\n\nEquivalent to Docker's `--label` flag." }, + "load": { + "type": "boolean", + "description": "When `true` the build will automatically include a `docker` export.\n\nDefaults to `false`.\n\nEquivalent to Docker's `--load` flag." + }, + "network": { + "$ref": "#/types/docker:buildx/image:NetworkMode", + "description": "Set the network mode for `RUN` instructions. Defaults to `default`.\n\nFor custom networks, configure your builder with `--driver-opt network=...`.\n\nEquivalent to Docker's `--network` flag.", + "default": "default" + }, + "noCache": { + "type": "boolean", + "description": "Do not import cache manifests when building the image.\n\nEquivalent to Docker's `--no-cache` flag." + }, "platforms": { "type": "array", "items": { @@ -3258,6 +3299,10 @@ "type": "boolean", "description": "Always pull referenced images.\n\nEquivalent to Docker's `--pull` flag." }, + "push": { + "type": "boolean", + "description": "When `true` the build will automatically include a `registry` export.\n\nDefaults to `false`.\n\nEquivalent to Docker's `--push` flag." + }, "registries": { "type": "array", "items": { @@ -3270,8 +3315,14 @@ "additionalProperties": { "type": "string" }, - "description": "A mapping of secret names to their corresponding values.\n\nUnlike the Docker CLI, these can be passed by value and do not need to\nexist on-disk or in environment variables.\n\nBuild arguments and environment variables are persistent in the final\nimage, so you should use this for sensitive values.\n\nSimilar to Docker's `--secret` flag.", - "secret": true + "description": "A mapping of secret names to their corresponding values.\n\nUnlike the Docker CLI, these can be passed by value and do not need to\nexist on-disk or in environment variables.\n\nBuild arguments and environment variables are persistent in the final\nimage, so you should use this for sensitive values.\n\nSimilar to Docker's `--secret` flag." + }, + "ssh": { + "type": "array", + "items": { + "$ref": "#/types/docker:buildx/image:SSH" + }, + "description": "SSH agent socket or keys to expose to the build.\n\nEquivalent to Docker's `--ssh` flag." }, "tags": { "type": "array", diff --git a/provider/go.mod b/provider/go.mod index 8a83e03d..49b708d5 100644 --- a/provider/go.mod +++ b/provider/go.mod @@ -22,7 +22,9 @@ require ( github.com/pulumi/pulumi-go-provider/integration v0.10.0 github.com/pulumi/pulumi-terraform-bridge/v3 v3.76.0 github.com/pulumi/pulumi/pkg/v3 v3.107.0 + github.com/pulumi/pulumi/sdk v1.14.1 github.com/pulumi/pulumi/sdk/v3 v3.107.0 + github.com/sirupsen/logrus v1.9.3 github.com/spf13/afero v1.9.5 github.com/stretchr/testify v1.8.4 github.com/terraform-providers/terraform-provider-docker v0.0.0 @@ -266,7 +268,6 @@ require ( github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect github.com/skeema/knownhosts v1.2.1 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/cobra v1.8.0 // indirect diff --git a/provider/go.sum b/provider/go.sum index e501ab43..c24279c2 100644 --- a/provider/go.sum +++ b/provider/go.sum @@ -749,6 +749,7 @@ github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -760,6 +761,7 @@ github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc= github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= @@ -945,6 +947,7 @@ github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNW github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/cheggaaa/pb v1.0.18/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo= github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= @@ -1162,6 +1165,7 @@ github.com/digitalocean/godo v1.78.0/go.mod h1:GBmu8MkjZmNARE7IXRPmkbbnocNN8+uBm github.com/digitalocean/godo v1.88.0/go.mod h1:NRpFznZFvhHjBoqZAaOD3khVzsJ3EibzKqFL4R60dmA= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/djherbis/times v1.2.0/go.mod h1:CGMZlo255K5r4Yw0b9RRfFQpM2y7uOmxg4jm9HsaVf8= github.com/djherbis/times v1.5.0 h1:79myA211VwPhFTqUk8xehWrsEO+zcIZj0zT8mXPVARU= github.com/djherbis/times v1.5.0/go.mod h1:5q7FDLvbNg1L/KaBmPcWlVR9NmoKo3+ucqUA3ijQhA0= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= @@ -1224,6 +1228,7 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= @@ -1266,6 +1271,7 @@ github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -1297,6 +1303,7 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= @@ -1434,6 +1441,7 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6 github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= @@ -1923,6 +1931,7 @@ github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= @@ -2022,6 +2031,7 @@ github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2J github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= @@ -2254,6 +2264,7 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= @@ -2375,8 +2386,6 @@ github.com/pulumi/esc v0.6.2 h1:+z+l8cuwIauLSwXQS0uoI3rqB+YG4SzsZYtHfNoXBvw= github.com/pulumi/esc v0.6.2/go.mod h1:jNnYNjzsOgVTjCp0LL24NsCk8ZJxq4IoLQdCT0X7l8k= github.com/pulumi/providertest v0.0.10 h1:bx77G0JYPO2Alf/SHRP05XpAYMrboKJkMIVkbFclVhI= github.com/pulumi/providertest v0.0.10/go.mod h1:HsxjVsytcMIuNj19w1lT2W0QXY0oReXl1+h6eD2JXP8= -github.com/pulumi/pulumi-go-provider v0.14.1-0.20240215003739-1759a7d2465b h1:HqGl6ZTRBAR3C/nUAZS6Fq5/NriAm/nrl9UkpUAOojY= -github.com/pulumi/pulumi-go-provider v0.14.1-0.20240215003739-1759a7d2465b/go.mod h1:Jb4jciqN/Ayi0eiTjbQkhZh/JMvdz8t60Zz7NtJTwN8= github.com/pulumi/pulumi-go-provider v0.14.1-0.20240301190400-aeddefa8dc54 h1:ajfW0p4tM1BLYoZRuy+CJoEcT3US6KXmAfCNNzi1Has= github.com/pulumi/pulumi-go-provider v0.14.1-0.20240301190400-aeddefa8dc54/go.mod h1:fpmTbPgwdzd4OtUcgE0wYRNzqEY5r88T/c3J1UM/lpA= github.com/pulumi/pulumi-go-provider/integration v0.10.0 h1:GHesnrrvkboSjkZpC+qRwjkXBp5d+fSXqlIO92zQxvc= @@ -2391,6 +2400,8 @@ github.com/pulumi/pulumi-yaml v1.5.0 h1:HfXu+WSFNpycref9CK935cViYJzXwSgHGWM/Repy github.com/pulumi/pulumi-yaml v1.5.0/go.mod h1:AvKSmEQv2EkPbpvAQroR1eP1LkJGC8z5NDM34rVWOtg= github.com/pulumi/pulumi/pkg/v3 v3.107.0 h1:HRyIl1c9ur0PVQW+GuFL1APBEuGa/fQQMp3F+WluxW8= github.com/pulumi/pulumi/pkg/v3 v3.107.0/go.mod h1:7edfZu4FlrXdIn4339tJ+SQX5VKGqbFntmpc8cai0Zg= +github.com/pulumi/pulumi/sdk v1.14.1 h1:FnUPMgO2AgqvKzSBOy3F2X4nJ8n/SaXCOP2eYSNkAxk= +github.com/pulumi/pulumi/sdk v1.14.1/go.mod h1:7HttsBa/x9udp5/sO8r/ibSpoQ7/zFo7a16zHWHktZ4= github.com/pulumi/pulumi/sdk/v3 v3.107.0 h1:bef+ayh9+4KkAqXih4EjlHfQXRY24NWPwWBIQhBxTjg= github.com/pulumi/pulumi/sdk/v3 v3.107.0/go.mod h1:Ml3rpGfyZlI4zQCG7LN2XDSmH4XUNYdyBwJ3yEr/OpI= github.com/pulumi/schema-tools v0.1.2 h1:Fd9xvUjgck4NA+7/jSk7InqCUT4Kj940+EcnbQKpfZo= @@ -2506,6 +2517,7 @@ github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155 github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= @@ -2527,6 +2539,7 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU= github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= +github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -2561,6 +2574,7 @@ github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= +github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= github.com/texttheater/golang-levenshtein v1.0.1 h1:+cRNoVrfiwufQPhoMzB6N0Yf/Mqajr6t1lOv8GyGE2U= github.com/texttheater/golang-levenshtein v1.0.1/go.mod h1:PYAKrbF5sAiq9wd+H82hs7gNaen0CplQ9uvm6+enD/8= github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= @@ -2579,8 +2593,10 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 h1:X9dsIWPuuEJlPX//UmRKophhOKCGXc46RVIGuttks68= github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7/go.mod h1:UxoP3EypF8JfGEjAII8jx1q8rQyDnX8qdTCs/UQBVIE= +github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -2615,6 +2631,7 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= @@ -2807,6 +2824,7 @@ golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= @@ -2820,6 +2838,7 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -2939,6 +2958,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -3070,6 +3090,7 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -3118,6 +3139,7 @@ golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -3303,6 +3325,7 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -3682,6 +3705,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= @@ -3703,6 +3727,9 @@ gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76 gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= +gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= gopkg.in/telebot.v3 v3.0.0/go.mod h1:7rExV8/0mDDNu9epSrDm/8j22KLaActH1Tbee6YjzWg= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= diff --git a/provider/internal/client.go b/provider/internal/client.go index b92e5ec1..d74d538e 100644 --- a/provider/internal/client.go +++ b/provider/internal/client.go @@ -238,6 +238,11 @@ func (d *docker) Build( namedContexts[name] = buildx.NamedContext{Path: v} } + ssh, err := controllerapi.CreateSSH(opts.SSH) + if err != nil { + return nil, err + } + payload := map[string]buildx.Options{} for _, target := range build.Targets() { targetName := target @@ -252,18 +257,21 @@ func (d *docker) Build( NamedContexts: namedContexts, InStream: strings.NewReader(""), }, - BuildArgs: opts.BuildArgs, - CacheFrom: cacheFrom, - CacheTo: cacheTo, - Exports: exports, - NoCache: opts.NoCache, - Labels: opts.Labels, - Platforms: platforms, - Pull: opts.Pull, - Tags: opts.Tags, - Target: target, + BuildArgs: opts.BuildArgs, + CacheFrom: cacheFrom, + CacheTo: cacheTo, + Exports: exports, + ExtraHosts: opts.ExtraHosts, + NetworkMode: opts.NetworkMode, + NoCache: opts.NoCache, + Labels: opts.Labels, + Platforms: platforms, + Pull: opts.Pull, + Tags: opts.Tags, + Target: target, Session: []session.Attachable{ + ssh, authprovider.NewDockerAuthProvider(&configfile.ConfigFile{AuthConfigs: auths}, nil), build.Secrets(), }, diff --git a/provider/internal/export.go b/provider/internal/export.go index 500c44dc..e6595fda 100644 --- a/provider/internal/export.go +++ b/provider/internal/export.go @@ -42,8 +42,6 @@ type ExportEntry struct { Raw Raw `pulumi:"raw,optional"` Disabled bool `pulumi:"disabled,optional"` - - Manifests []Manifest `pulumi:"manifests,optional" provider:"output"` } func (e *ExportEntry) Annotate(a infer.Annotator) { @@ -73,10 +71,6 @@ func (e *ExportEntry) Annotate(a infer.Annotator) { a.Describe(&e.Disabled, dedent(` When "true" this entry will be excluded. Defaults to "false". `)) - a.Describe(&e.Manifests, dedent(` - An output property populated for exporters that pushed image - manifest(s) to a registry. - `)) } func (e ExportEntry) String() string { diff --git a/provider/internal/image.go b/provider/internal/image.go index 7977c2ce..f36067de 100644 --- a/provider/internal/image.go +++ b/provider/internal/image.go @@ -24,14 +24,17 @@ import ( "github.com/docker/buildx/util/buildflags" "github.com/docker/buildx/util/platformutil" "github.com/docker/docker/errdefs" + "github.com/moby/buildkit/exporter/containerimage/exptypes" "github.com/moby/buildkit/frontend/dockerfile/instructions" "github.com/moby/buildkit/frontend/dockerfile/parser" "github.com/moby/buildkit/session" "github.com/moby/buildkit/session/secrets/secretsprovider" + "github.com/opencontainers/go-digest" "github.com/spf13/afero" provider "github.com/pulumi/pulumi-go-provider" "github.com/pulumi/pulumi-go-provider/infer" + "github.com/pulumi/pulumi/sdk/go/common/util/ciutil" "github.com/pulumi/pulumi/sdk/v3/go/common/diag" "github.com/pulumi/pulumi/sdk/v3/go/common/resource" ) @@ -83,8 +86,9 @@ func (i *Image) Annotate(a infer.Annotator) { // ImageArgs instantiates a new Image. type ImageArgs struct { + AddHosts []string `pulumi:"addHosts,optional"` BuildArgs map[string]string `pulumi:"buildArgs,optional"` - BuildOnPreview bool `pulumi:"buildOnPreview,optional"` + BuildOnPreview *bool `pulumi:"buildOnPreview,optional"` Builder BuilderConfig `pulumi:"builder,optional"` CacheFrom []CacheFromEntry `pulumi:"cacheFrom,optional"` CacheTo []CacheToEntry `pulumi:"cacheTo,optional"` @@ -92,16 +96,26 @@ type ImageArgs struct { Dockerfile Dockerfile `pulumi:"dockerfile,optional"` Exports []ExportEntry `pulumi:"exports,optional"` Labels map[string]string `pulumi:"labels,optional"` + Load bool `pulumi:"load,optional"` + Network NetworkMode `pulumi:"network,optional"` + NoCache bool `pulumi:"noCache,optional"` Platforms []Platform `pulumi:"platforms,optional"` Pull bool `pulumi:"pull,optional"` + Push bool `pulumi:"push,optional"` Registries []RegistryAuth `pulumi:"registries,optional"` - Secrets map[string]string `pulumi:"secrets,optional" provider:"secret"` + Secrets map[string]string `pulumi:"secrets,optional"` + SSH []SSH `pulumi:"ssh,optional"` Tags []string `pulumi:"tags,optional"` Targets []string `pulumi:"targets,optional"` } // Annotate describes inputs to the Image resource. func (ia *ImageArgs) Annotate(a infer.Annotator) { + a.Describe(&ia.AddHosts, dedent(` + Custom "host:ip" mappings to use during the build. + + Equivalent to Docker's "--add-host" flag. + `)) a.Describe(&ia.BuildArgs, dedent(` "ARG" names and values to set during the build. @@ -114,8 +128,20 @@ func (ia *ImageArgs) Annotate(a infer.Annotator) { Equivalent to Docker's "--build-arg" flag. `)) a.Describe(&ia.BuildOnPreview, dedent(` - When "true", attempt to build the image during previews. The image will - not be pushed to registries, however caches will still be populated. + By default, preview behavior depends on the execution environment. If + Pulumi detects the operation is running on a CI system (GitHub Actions, + Travis CI, Azure Pipelines, etc.) then it will build images during + previews as a safeguard. Otherwise, if not running on CI, previews will + not build images. + + Setting this to "false" forces previews to never perform builds, and + setting it to "true" will always build the image during previews. + + Images built during previews are never exported to registries, however + cache manifests are still exported. + + On-disk Dockerfiles are always validated for syntactic correctness + regardless of this setting. `)) a.Describe(&ia.Builder, dedent(` Builder configuration. @@ -153,6 +179,25 @@ func (ia *ImageArgs) Annotate(a infer.Annotator) { Equivalent to Docker's "--label" flag. `)) + a.Describe(&ia.Load, dedent(` + When "true" the build will automatically include a "docker" export. + + Defaults to "false". + + Equivalent to Docker's "--load" flag. + `)) + a.Describe(&ia.Network, dedent(` + Set the network mode for "RUN" instructions. Defaults to "default". + + For custom networks, configure your builder with "--driver-opt network=...". + + Equivalent to Docker's "--network" flag. + `)) + a.Describe(&ia.NoCache, dedent(` + Do not import cache manifests when building the image. + + Equivalent to Docker's "--no-cache" flag. + `)) a.Describe(&ia.Platforms, dedent(` Set target platform(s) for the build. Defaults to the host's platform. @@ -163,6 +208,13 @@ func (ia *ImageArgs) Annotate(a infer.Annotator) { Equivalent to Docker's "--pull" flag. `)) + a.Describe(&ia.Push, dedent(` + When "true" the build will automatically include a "registry" export. + + Defaults to "false". + + Equivalent to Docker's "--push" flag. + `)) a.Describe(&ia.Secrets, dedent(` A mapping of secret names to their corresponding values. @@ -174,6 +226,11 @@ func (ia *ImageArgs) Annotate(a infer.Annotator) { Similar to Docker's "--secret" flag. `)) + a.Describe(&ia.SSH, dedent(` + SSH agent socket or keys to expose to the build. + + Equivalent to Docker's "--ssh" flag. + `)) a.Describe(&ia.Tags, dedent(` Name and optionally a tag (format: "name:tag"). @@ -198,14 +255,17 @@ func (ia *ImageArgs) Annotate(a infer.Annotator) { Similar to "docker login". `)) + + a.SetDefault(&ia.Network, NetworkModeDefault) } // ImageState is serialized to the program's state file. type ImageState struct { ImageArgs - Digests map[Platform][]string `pulumi:"digests,optional" provider:"output"` - ContextHash string `pulumi:"contextHash,optional" provider:"internal,output"` + Digests map[string]string `pulumi:"digests" provider:"output"` + ContextHash string `pulumi:"contextHash" provider:"output"` + Ref string `pulumi:"ref" provider:"output"` } // Annotate describes outputs of the Image resource. @@ -213,13 +273,29 @@ func (is *ImageState) Annotate(a infer.Annotator) { is.ImageArgs.Annotate(a) a.Describe(&is.Digests, dedent(` - A mapping of platform type to refs which were pushed to registries.`, + A mapping of target names to the SHA256 digest of their pushed manifest. + + If no target was specified 'default' is used as the target name. + + Pushed manifests can be referenced as "@". + `, )) a.Describe(&is.ContextHash, dedent(` A preliminary hash of the image's build context. Pulumi uses this to determine if an image _may_ need to be re-built. `)) + a.Describe(&is.Ref, dedent(` + If the image was pushed to any registries then this will contain a + single fully-qualified tag including the build's digest. + + This is only for convenience and may not be appropriate for situations + where multiple tags or registries are involved. In those cases this + output is not guaranteed to be stable. + + For more control over tags consumed by downstream resources you should + use the "Digests" output. + `)) } // Check validates ImageArgs, sets defaults, and ensures our client is @@ -283,18 +359,24 @@ func newCheckFailure(property string, err error) checkFailure { func (ia *ImageArgs) withoutUnknowns(preview bool) ImageArgs { filtered := ImageArgs{ + AddHosts: filter(stringKeeper{preview}, ia.AddHosts...), BuildArgs: mapKeeper{preview}.keep(ia.BuildArgs), - Builder: ia.Builder, BuildOnPreview: ia.BuildOnPreview, + Builder: ia.Builder, CacheFrom: filter(stringerKeeper[CacheFromEntry]{preview}, ia.CacheFrom...), CacheTo: filter(stringerKeeper[CacheToEntry]{preview}, ia.CacheTo...), Context: contextKeeper{preview}.keep(ia.Context), Dockerfile: ia.Dockerfile, Exports: filter(stringerKeeper[ExportEntry]{preview}, ia.Exports...), Labels: mapKeeper{preview}.keep(ia.Labels), + Load: ia.Load, + Network: ia.Network, + NoCache: ia.NoCache, Platforms: filter(stringerKeeper[Platform]{preview}, ia.Platforms...), Pull: ia.Pull, + Push: ia.Push, Registries: filter(registryKeeper{preview}, ia.Registries...), + SSH: filter(stringerKeeper[SSH]{preview}, ia.SSH...), Secrets: mapKeeper{preview}.keep(ia.Secrets), Tags: filter(stringKeeper{preview}, ia.Tags...), Targets: filter(stringKeeper{preview}, ia.Targets...), @@ -309,6 +391,26 @@ func (ia *ImageArgs) buildable() bool { return reflect.DeepEqual(ia, &filtered) } +// isExported returns true if the args include a registry export. +func (ia *ImageArgs) isExported() bool { + if ia.Push { + return true + } + for _, e := range ia.Exports { + if e.pushed() { + return true + } + } + return false +} + +func (ia *ImageArgs) shouldBuildOnPreview() bool { + if ia.BuildOnPreview != nil { + return *ia.BuildOnPreview + } + return ciutil.IsCI() +} + type build struct { opts controllerapi.BuildOptions targets []string @@ -349,6 +451,13 @@ func (ia ImageArgs) toBuilds( targets = []string{""} } + if len(opts.Exports) == 0 { + ctx.Log(diag.Warning, + "No exports were specified so the build will only remain in the local build cache. "+ + "Use `push` to upload the image to a registry.", + ) + } + // Check if we need a workaround for multi-platform caching (https://github.com/docker/buildx/issues/1044). if len(ia.Platforms) <= 1 || len(ia.CacheTo) == 0 { return []Build{ @@ -477,11 +586,20 @@ func (ia *ImageArgs) toBuildOptions(preview bool) (controllerapi.BuildOptions, e var multierr error if len(ia.Exports) > 1 { - multierr = errors.Join( - multierr, + multierr = errors.Join(multierr, newCheckFailure("exports", fmt.Errorf("multiple exports are currently unsupported")), ) } + if ia.Push && ia.Load { + multierr = errors.Join(multierr, + newCheckFailure("push", fmt.Errorf("push and load may not be set together at the moment")), + ) + } + if len(ia.Exports) > 0 && (ia.Push || ia.Load) { + multierr = errors.Join(multierr, + newCheckFailure("exports", fmt.Errorf("exports can't be provided with push or load")), + ) + } if ia.Context.Location != "" { abs, err := filepath.Abs(ia.Context.Location) @@ -520,6 +638,12 @@ func (ia *ImageArgs) toBuildOptions(preview bool) (controllerapi.BuildOptions, e filtered := ia.withoutUnknowns(preview) exports := []*controllerapi.ExportEntry{} + if filtered.Push { + filtered.Exports = append(filtered.Exports, ExportEntry{Raw: "type=registry"}) + } + if filtered.Load { + filtered.Exports = append(filtered.Exports, ExportEntry{Raw: "type=docker"}) + } for _, e := range filtered.Exports { if strings.Count(e.String(), "type=") > 1 { multierr = errors.Join( @@ -548,8 +672,8 @@ func (ia *ImageArgs) toBuildOptions(preview bool) (controllerapi.BuildOptions, e continue } exports = append(exports, exp) - } + if preview { // Don't perform registry pushes during previews. for _, e := range exports { @@ -615,6 +739,19 @@ func (ia *ImageArgs) toBuildOptions(preview bool) (controllerapi.BuildOptions, e cacheTo = append(cacheTo, parsed[0]) } + ssh := []*controllerapi.SSH{} + for _, s := range filtered.SSH { + parsed, err := buildflags.ParseSSHSpecs([]string{s.String()}) + if err != nil { + multierr = errors.Join(multierr, newCheckFailure("ssh", err)) + continue + } + if len(parsed) == 0 { + continue + } + ssh = append(ssh, parsed[0]) + } + if filtered.Dockerfile.Location != "" && filtered.Dockerfile.Inline != "" { multierr = errors.Join( multierr, @@ -639,12 +776,15 @@ func (ia *ImageArgs) toBuildOptions(preview bool) (controllerapi.BuildOptions, e ContextPath: filtered.Context.Location, DockerfileName: filtered.Dockerfile.Location, Exports: exports, + ExtraHosts: filtered.AddHosts, Labels: filtered.Labels, + NetworkMode: string(filtered.Network), + NoCache: filtered.NoCache, NamedContexts: filtered.Context.Named.Map(), Platforms: platforms, Pull: filtered.Pull, + SSH: ssh, Tags: filtered.Tags, - // Target: filtered.Targets, } return opts, multierr @@ -685,7 +825,7 @@ func (i *Image) Update( } state.ContextHash = hash - if preview && !input.BuildOnPreview { + if preview && !input.shouldBuildOnPreview() { return state, nil } if preview && !input.buildable() { @@ -693,16 +833,42 @@ func (i *Image) Update( return state, nil } - for _, b := range builds { + result, err := cfg.client.Build(ctx, name, builds[0]) + if err != nil { + return state, err + } + // Run any remaining cache builds. + for idx := 1; idx < len(builds); idx++ { + b := builds[idx] _, err = cfg.client.Build(ctx, name, b) if err != nil { return state, err } } - _, _, state, err = i.Read(ctx, name, input, state) + var dgst digest.Digest + state.Digests = map[string]string{} + for target, resp := range result { + if d, ok := resp.ExporterResponse[exptypes.ExporterImageDigestKey]; ok { + + dgst = digest.Digest(d) + state.Digests[target] = d + } + } + + // Take the first registry tag we find and add a digest to it. That becomes + // our simplified "ref" output. + for _, tag := range state.Tags { + ref, ok := addDigest(tag, dgst.String()) + if !ok { + continue + } + + state.Ref = ref + break + } - return state, err + return state, nil } // Create initializes a new resource and performs an Update on it. @@ -737,20 +903,29 @@ func (*Image) Read( } } - // Do a lookup on all of the tags we expected to push and update our export - // with the manifest we pushed. - digests := map[Platform][]string{} - for idx, export := range state.Exports { - // We only care about exports that could have pushed tags. - if !export.pushed() { - continue - } + if !state.isExported() { + // Nothing was pushed -- all done. + return name, input, state, nil + } + + tagsToKeep := []string{} + + // Do a lookup on all of the tags at the digests we expect to see. + for _, tag := range state.Tags { + for _, d := range state.Digests { + digest := digest.Digest(d) - state.Exports[idx].Manifests = []Manifest{} - for _, tag := range state.Tags { - // Does the tag still exist? - infos, err := cfg.client.Inspect(ctx, name, tag) + ref, ok := addDigest(tag, digest.String()) + if !ok { + // Not a pushed tag. + tagsToKeep = append(tagsToKeep, tag) + break + } + + // Does a tag with this digest exist? + infos, err := cfg.client.Inspect(ctx, name, ref) if err != nil { + ctx.Log(diag.Warning, err.Error()) continue } @@ -764,38 +939,20 @@ func (*Image) Read( continue } - os, arch := m.Descriptor.Platform.OS, m.Descriptor.Platform.Architecture - platform := Platform(fmt.Sprintf("%s/%s", os, arch)) - - if _, ok := digests[platform]; !ok { - digests[platform] = []string{} - } - - digests[platform] = slices.Compact(append(digests[platform], m.Ref.String())) - - state.Exports[idx].Manifests = append( - state.Exports[idx].Manifests, - Manifest{ - Digest: m.Descriptor.Digest.String(), - Platform: ManifestPlatform{ - OS: m.Descriptor.Platform.OS, - Architecture: m.Descriptor.Platform.Architecture, - }, - Ref: m.Ref.String(), - Size: m.Descriptor.Size, - }, - ) + tagsToKeep = append(tagsToKeep, tag) + break } } } - state.Digests = digests // If we couldn't find the tags we expected then return an empty ID to // delete the resource. - if len(input.Tags) > 0 && len(digests) == 0 { + if len(input.Tags) > 0 && len(tagsToKeep) == 0 { return "", input, state, nil } + state.Tags = tagsToKeep + return name, input, state, nil } @@ -811,21 +968,23 @@ func (*Image) Delete( var multierr error - for _, refs := range state.Digests { - for _, ref := range refs { - deletions, err := cfg.client.Delete(context.Context(ctx), ref) - if errdefs.IsNotFound(err) { - continue // Nothing to do. - } - multierr = errors.Join(multierr, err) + for _, tag := range state.Tags { + ref, err := reference.ParseNamed(tag) + if err != nil { + continue + } + deletions, err := cfg.client.Delete(context.Context(ctx), ref.String()) + if errdefs.IsNotFound(err) { + continue // Nothing to do. + } + multierr = errors.Join(multierr, err) - for _, d := range deletions { - if d.Deleted != "" { - ctx.Log(diag.Info, d.Deleted) - } - if d.Untagged != "" { - ctx.Log(diag.Info, d.Untagged) - } + for _, d := range deletions { + if d.Deleted != "" { + ctx.Log(diag.Info, d.Deleted) + } + if d.Untagged != "" { + ctx.Log(diag.Info, d.Untagged) } } } @@ -846,9 +1005,15 @@ func (*Image) Diff( diff := map[string]provider.PropertyDiff{} update := provider.PropertyDiff{Kind: provider.Update} + if !reflect.DeepEqual(olds.AddHosts, news.AddHosts) { + diff["addHosts"] = update + } if !reflect.DeepEqual(olds.BuildArgs, news.BuildArgs) { diff["buildArgs"] = update } + if olds.BuildOnPreview != news.BuildOnPreview { + diff["buildOnPreview"] = update + } if !reflect.DeepEqual(olds.Builder, news.Builder) { diff["builder"] = update } @@ -859,11 +1024,10 @@ func (*Image) Diff( diff["cacheTo"] = update } if olds.Context.Location != news.Context.Location { - diff["context"] = update + diff["context.location"] = update } - // Use string comparison to ignore any manifests attached to the export. - if fmt.Sprint(olds.Exports) != fmt.Sprint(news.Exports) { - diff["exports"] = update + if !reflect.DeepEqual(olds.Context.Named, news.Context.Named) { + diff["context.named"] = update } if olds.Dockerfile.Location != news.Dockerfile.Location { diff["dockerfile.location"] = update @@ -871,8 +1035,21 @@ func (*Image) Diff( if olds.Dockerfile.Inline != news.Dockerfile.Inline { diff["dockerfile.inline"] = update } - if !reflect.DeepEqual(olds.Context.Named, news.Context.Named) { - diff["context.named"] = update + // Use string comparison to ignore any manifests attached to the export. + if fmt.Sprint(olds.Exports) != fmt.Sprint(news.Exports) { + diff["exports"] = update + } + if !reflect.DeepEqual(olds.Labels, news.Labels) { + diff["labels"] = update + } + if olds.Load != news.Load { + diff["load"] = update + } + if olds.Network != news.Network { + diff["network"] = update + } + if !reflect.DeepEqual(olds.NoCache, news.NoCache) { + diff["noCache"] = update } if !reflect.DeepEqual(olds.Platforms, news.Platforms) { diff["platforms"] = update @@ -880,6 +1057,15 @@ func (*Image) Diff( if olds.Pull != news.Pull { diff["pull"] = update } + if olds.Push != news.Push { + diff["push"] = update + } + if !reflect.DeepEqual(olds.Secrets, news.Secrets) { + diff["secrets"] = update + } + if !reflect.DeepEqual(olds.SSH, news.SSH) { + diff["ssh"] = update + } if !reflect.DeepEqual(olds.Tags, news.Tags) { diff["tags"] = update } @@ -889,8 +1075,8 @@ func (*Image) Diff( // pull=true indicates that we want to keep base layers up-to-date. In this // case we'll always perform the build. - if news.Pull && len(news.Exports) > 0 { - diff["exports"] = update + if news.Pull && (len(news.Exports) > 0 || news.Push || news.Load) { + diff["contextHash"] = update } // Check if anything has changed in our build context. @@ -915,7 +1101,7 @@ func (*Image) Diff( if (oldr.Username == newr.Username) && (oldr.Address == newr.Address) { continue } - diff["registries"] = update + diff[fmt.Sprintf("registries[%d]", idx)] = update break } } @@ -938,3 +1124,26 @@ func parseDockerfile(r io.Reader) error { } return nil } + +// addDigest constructs a tagged ref with an "@" suffix. +// +// Returns false if the given ref was not fully qualified. +func addDigest(ref, digest string) (string, bool) { + named, err := reference.ParseNamed(ref) + if err != nil { + return "", false + } + tag := "latest" + if tagged, ok := named.(reference.Tagged); ok { + tag = tagged.Tag() + } + + full, err := reference.Parse( + fmt.Sprintf("%s:%s@%s", named.Name(), tag, digest), + ) + if err != nil { + return "", false + } + + return full.String(), true +} diff --git a/provider/internal/image_test.go b/provider/internal/image_test.go index b13eb63f..bc8acd5e 100644 --- a/provider/internal/image_test.go +++ b/provider/internal/image_test.go @@ -2,6 +2,7 @@ package internal import ( "errors" + "fmt" "os" "path/filepath" "testing" @@ -13,6 +14,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types/image" "github.com/moby/buildkit/client" + "github.com/moby/buildkit/exporter/containerimage/exptypes" v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -34,9 +36,7 @@ func TestLifecycle(t *testing.T) { return NewMockClient(ctrl) } - ref, err := reference.ParseNamed("docker.io/pulumibot/buildkit-e2e") - require.NoError(t, err) - digestRef, err := reference.WithDigest(ref, "sha256:7f9fc9830dbb80a7fd23b9903d587b6433a9e87969de4868e551bc2959e63dd9") + _, err := reference.ParseNamed("docker.io/pulumibot/buildkit-e2e") require.NoError(t, err) tests := []struct { @@ -51,29 +51,23 @@ func TestLifecycle(t *testing.T) { ctrl := gomock.NewController(t) c := NewMockClient(ctrl) c.EXPECT().Auth(gomock.Any(), "test", gomock.Any()).Return(nil).AnyTimes() - gomock.InOrder( - c.EXPECT().BuildKitEnabled().Return(true, nil), // Preview. - c.EXPECT().BuildKitEnabled().Return(true, nil), // Create. - c.EXPECT().Build(gomock.Any(), "test", gomock.AssignableToTypeOf(build{})).DoAndReturn( - func(_ provider.Context, name string, b Build) (map[string]*client.SolveResponse, error) { - assert.Equal(t, "../testdata/Dockerfile", b.BuildOptions().DockerfileName) - return map[string]*client.SolveResponse{ - b.Targets()[0]: {ExporterResponse: map[string]string{"containerimage.digest": "SHA256:digest"}}, - }, nil - }, - ), - c.EXPECT().Inspect(gomock.Any(), "test", "docker.io/pulumibot/buildkit-e2e").Return( - []manifesttypes.ImageManifest{ - { - Ref: &manifesttypes.SerializableNamed{Named: digestRef}, - Descriptor: v1.Descriptor{Platform: &v1.Platform{OS: "linux", Architecture: "arm64"}}, + c.EXPECT().BuildKitEnabled().Return(true, nil).AnyTimes() + c.EXPECT().Build(gomock.Any(), "test", gomock.AssignableToTypeOf(build{})).DoAndReturn( + func(_ provider.Context, name string, b Build) (map[string]*client.SolveResponse, error) { + assert.Equal(t, "../testdata/Dockerfile", b.BuildOptions().DockerfileName) + return map[string]*client.SolveResponse{ + b.Targets()[0]: { + ExporterResponse: map[string]string{ + exptypes.ExporterImageDigestKey: "sha256:98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4", + }, }, - }, nil, - ), - c.EXPECT().Inspect(gomock.Any(), "test", "docker.io/pulumibot/buildkit-e2e:main"), - c.EXPECT().Delete(gomock.Any(), digestRef.String()).Return( - []image.DeleteResponse{{Deleted: "deleted"}, {Untagged: "untagged"}}, nil), - ) + }, nil + }, + ).AnyTimes() + c.EXPECT().Delete(gomock.Any(), "docker.io/pulumibot/buildkit-e2e").Return( + []image.DeleteResponse{{Deleted: "deleted"}, {Untagged: "untagged"}}, nil) + c.EXPECT().Delete(gomock.Any(), "docker.io/pulumibot/buildkit-e2e:main").Return( + []image.DeleteResponse{{Deleted: "deleted"}, {Untagged: "untagged"}}, nil) return c }, op: func(t *testing.T) integration.Operation { @@ -220,18 +214,15 @@ func TestLifecycle(t *testing.T) { client: func(t *testing.T) Client { ctrl := gomock.NewController(t) c := NewMockClient(ctrl) - gomock.InOrder( - c.EXPECT().BuildKitEnabled().Return(true, nil), // Preview. - c.EXPECT().BuildKitEnabled().Return(true, nil), // Create. - c.EXPECT().Build(gomock.Any(), "test", gomock.AssignableToTypeOf(build{})).DoAndReturn( - func(_ provider.Context, name string, b Build) (map[string]*client.SolveResponse, error) { - assert.Equal(t, "../testdata/Dockerfile", b.BuildOptions().DockerfileName) - return map[string]*client.SolveResponse{ - b.Targets()[0]: {ExporterResponse: map[string]string{"image.name": "test:latest"}}, - }, nil - }, - ), - ) + c.EXPECT().BuildKitEnabled().Return(true, nil).AnyTimes() + c.EXPECT().Build(gomock.Any(), "test", gomock.AssignableToTypeOf(build{})).DoAndReturn( + func(_ provider.Context, name string, b Build) (map[string]*client.SolveResponse, error) { + assert.Equal(t, "../testdata/Dockerfile", b.BuildOptions().DockerfileName) + return map[string]*client.SolveResponse{ + b.Targets()[0]: {ExporterResponse: map[string]string{"image.name": "test:latest"}}, + }, nil + }, + ).AnyTimes() return c }, op: func(t *testing.T) integration.Operation { @@ -284,8 +275,7 @@ func TestDelete(t *testing.T) { t.Run("image was already deleted", func(t *testing.T) { ctrl := gomock.NewController(t) client := NewMockClient(ctrl) - client.EXPECT().Delete(gomock.Any(), "foo").Return(nil, errNotFound{}) - client.EXPECT().Delete(gomock.Any(), "bar").Return(nil, errNotFound{}) + client.EXPECT().Delete(gomock.Any(), "docker.io/pulumi/test:foo").Return(nil, errNotFound{}) s := newServer(client) err := s.Configure(provider.ConfigureRequest{}) @@ -295,12 +285,15 @@ func TestDelete(t *testing.T) { ID: "foo,bar", Urn: _fakeURN, Properties: resource.PropertyMap{ + "tags": resource.NewArrayProperty([]resource.PropertyValue{ + resource.NewStringProperty("docker.io/pulumi/test:foo"), + }), + "push": resource.NewBoolProperty(true), "digests": resource.NewObjectProperty(resource.PropertyMap{ - "digests": resource.NewArrayProperty([]resource.PropertyValue{ - resource.NewStringProperty("foo"), - resource.NewStringProperty("bar"), - }), + "default": resource.NewStringProperty("sha256:foo"), }), + "contextHash": resource.NewStringProperty(""), + "ref": resource.NewStringProperty(""), }, }) assert.NoError(t, err) @@ -309,24 +302,26 @@ func TestDelete(t *testing.T) { func TestRead(t *testing.T) { tag := "docker.io/pulumi/pulumitest" + digest := "sha256:3be99cafdcd80a8e620da56bdc215acab6213bb608d3d492c0ba1807128786a1" ref, err := reference.ParseNamed(tag) require.NoError(t, err) ctrl := gomock.NewController(t) client := NewMockClient(ctrl) - client.EXPECT().Inspect(gomock.Any(), "my-image", tag).Return([]manifesttypes.ImageManifest{ - { - Descriptor: v1.Descriptor{Platform: &v1.Platform{Architecture: "arm64"}}, - Ref: &manifesttypes.SerializableNamed{Named: ref}, - }, - { - Descriptor: v1.Descriptor{Platform: &v1.Platform{Architecture: "unknown"}}, - Ref: &manifesttypes.SerializableNamed{Named: ref}, - }, - { - Descriptor: v1.Descriptor{}, - }, - }, nil) + client.EXPECT().Inspect(gomock.Any(), "my-image", fmt.Sprintf("%s:latest@%s", tag, digest)).Return( + []manifesttypes.ImageManifest{ + { + Descriptor: v1.Descriptor{Platform: &v1.Platform{Architecture: "arm64"}}, + Ref: &manifesttypes.SerializableNamed{Named: ref}, + }, + { + Descriptor: v1.Descriptor{Platform: &v1.Platform{Architecture: "unknown"}}, + Ref: &manifesttypes.SerializableNamed{Named: ref}, + }, + { + Descriptor: v1.Descriptor{}, + }, + }, nil) s := newServer(client) err = s.Configure(provider.ConfigureRequest{}) @@ -344,6 +339,9 @@ func TestRead(t *testing.T) { "tags": resource.NewArrayProperty([]resource.PropertyValue{ resource.NewStringProperty(tag), }), + "digests": resource.NewObjectProperty(resource.PropertyMap{ + "default": resource.NewStringProperty(digest), + }), }, }) require.NoError(t, err) @@ -361,6 +359,7 @@ func TestDiff(t *testing.T) { baseState := ImageState{ ContextHash: "f04bea490d45e7ae69d542846511e7c90eb683deaa1e0df19e9fca4d227265c2", ImageArgs: baseArgs, + Digests: map[string]string{}, } tests := []struct { @@ -476,7 +475,16 @@ func TestDiff(t *testing.T) { wantChanges: true, }, { - name: "diff if file changes", + name: "diff if named context changes", + olds: func(*testing.T, ImageState) ImageState { return baseState }, + news: func(_ *testing.T, a ImageArgs) ImageArgs { + a.Context.Named = NamedContexts{"foo": Context{Location: "bar"}} + return a + }, + wantChanges: true, + }, + { + name: "diff if dockerfile location changes", olds: func(*testing.T, ImageState) ImageState { return baseState }, news: func(_ *testing.T, a ImageArgs) ImageArgs { a.Dockerfile.Location = "testdata/ignores/basedir/Dockerfile" @@ -484,6 +492,15 @@ func TestDiff(t *testing.T) { }, wantChanges: true, }, + { + name: "diff if dockerfile inline changes", + olds: func(*testing.T, ImageState) ImageState { return baseState }, + news: func(_ *testing.T, a ImageArgs) ImageArgs { + a.Dockerfile.Inline = "FROM scratch" + return a + }, + wantChanges: true, + }, { name: "diff if platforms change", olds: func(*testing.T, ImageState) ImageState { return baseState }, @@ -529,6 +546,51 @@ func TestDiff(t *testing.T) { }, wantChanges: true, }, + { + name: "diff if targets change", + olds: func(*testing.T, ImageState) ImageState { return baseState }, + news: func(_ *testing.T, a ImageArgs) ImageArgs { + a.Targets = []string{"foo"} + return a + }, + wantChanges: true, + }, + { + name: "diff if pulling", + olds: func(*testing.T, ImageState) ImageState { return baseState }, + news: func(_ *testing.T, a ImageArgs) ImageArgs { + a.Pull = true + return a + }, + wantChanges: true, + }, + { + name: "diff if noCache changes", + olds: func(*testing.T, ImageState) ImageState { return baseState }, + news: func(_ *testing.T, a ImageArgs) ImageArgs { + a.NoCache = true + return a + }, + wantChanges: true, + }, + { + name: "diff if labels change", + olds: func(*testing.T, ImageState) ImageState { return baseState }, + news: func(_ *testing.T, a ImageArgs) ImageArgs { + a.Labels = map[string]string{"foo": "bar"} + return a + }, + wantChanges: true, + }, + { + name: "diff if secrets change", + olds: func(*testing.T, ImageState) ImageState { return baseState }, + news: func(_ *testing.T, a ImageArgs) ImageArgs { + a.Secrets = map[string]string{"foo": "bar"} + return a + }, + wantChanges: true, + }, } s := newServer(nil) @@ -735,6 +797,10 @@ func TestBuildable(t *testing.T) { } func TestToBuilds(t *testing.T) { + ctrl := gomock.NewController(t) + pctx := NewMockProviderContext(ctrl) + pctx.EXPECT().Log(gomock.Any(), gomock.Any()).AnyTimes() + t.Run("single-platform caching", func(t *testing.T) { ia := ImageArgs{ Tags: []string{"foo", "bar"}, @@ -758,7 +824,8 @@ func TestToBuilds(t *testing.T) { {Registry: &CacheFromRegistry{Ref: "docker.io/foo/bar:baz"}}, }, } - builds, err := ia.toBuilds(nil, false) + + builds, err := ia.toBuilds(pctx, false) assert.NoError(t, err) assert.Len(t, builds, 1) }) @@ -790,7 +857,7 @@ func TestToBuilds(t *testing.T) { }, } - builds, err := ia.toBuilds(nil, false) + builds, err := ia.toBuilds(pctx, false) assert.NoError(t, err) assert.Len(t, builds, 3) diff --git a/provider/internal/network.go b/provider/internal/network.go new file mode 100644 index 00000000..0e7902b0 --- /dev/null +++ b/provider/internal/network.go @@ -0,0 +1,30 @@ +package internal + +import "github.com/pulumi/pulumi-go-provider/infer" + +var _ = (infer.Enum[NetworkMode])((*NetworkMode)(nil)) + +type NetworkMode string + +const ( + NetworkModeDefault NetworkMode = "default" + NetworkModeHost NetworkMode = "host" + NetworkModeNone NetworkMode = "none" +) + +func (NetworkMode) Values() []infer.EnumValue[NetworkMode] { + return []infer.EnumValue[NetworkMode]{ + { + Value: NetworkModeDefault, + Description: "The default sandbox network mode.", + }, + { + Value: NetworkModeHost, + Description: "Host network mode.", + }, + { + Value: NetworkModeNone, + Description: "Disable network access.", + }, + } +} diff --git a/provider/internal/ssh.go b/provider/internal/ssh.go new file mode 100644 index 00000000..81b3d5b3 --- /dev/null +++ b/provider/internal/ssh.go @@ -0,0 +1,45 @@ +package internal + +import ( + "strings" + + "github.com/pulumi/pulumi-go-provider/infer" +) + +type SSH struct { + ID string `pulumi:"id"` + Paths []string `pulumi:"paths,optional"` +} + +func (s *SSH) Annotate(a infer.Annotator) { + a.Describe(&s.ID, dedent(` + Useful for distinguishing different servers that are part of the same + build. + + A value of "default" is appropriate if only dealing with a single host. + `)) + a.Describe(&s.Paths, dedent(` + SSH agent socket or private keys to expose to the build under the given + identifier. + + Defaults to "[$SSH_AUTH_SOCK]". + + Note that your keys are **not** automatically added when using an + agent. Run "ssh-add -l" locally to confirm which public keys are + visible to the agent; these will be exposed to your build. + `)) +} + +func (s SSH) String() string { + if s.ID == "" { + return "" + } + + r := s.ID + + if len(s.Paths) > 0 { + r += "=" + strings.Join(s.Paths, ",") + } + + return r +} diff --git a/sdk/dotnet/Buildx/Enums.cs b/sdk/dotnet/Buildx/Enums.cs index de7584c1..39bfcadd 100644 --- a/sdk/dotnet/Buildx/Enums.cs +++ b/sdk/dotnet/Buildx/Enums.cs @@ -79,6 +79,44 @@ private CompressionType(string value) public override string ToString() => _value; } + [EnumType] + public readonly struct NetworkMode : IEquatable + { + private readonly string _value; + + private NetworkMode(string value) + { + _value = value ?? throw new ArgumentNullException(nameof(value)); + } + + /// + /// The default sandbox network mode. + /// + public static NetworkMode @Default { get; } = new NetworkMode("default"); + /// + /// Host network mode. + /// + public static NetworkMode Host { get; } = new NetworkMode("host"); + /// + /// Disable network access. + /// + public static NetworkMode None { get; } = new NetworkMode("none"); + + public static bool operator ==(NetworkMode left, NetworkMode right) => left.Equals(right); + public static bool operator !=(NetworkMode left, NetworkMode right) => !left.Equals(right); + + public static explicit operator string(NetworkMode value) => value._value; + + [EditorBrowsable(EditorBrowsableState.Never)] + public override bool Equals(object? obj) => obj is NetworkMode other && Equals(other); + public bool Equals(NetworkMode other) => string.Equals(_value, other._value, StringComparison.Ordinal); + + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => _value?.GetHashCode() ?? 0; + + public override string ToString() => _value; + } + [EnumType] public readonly struct Platform : IEquatable { diff --git a/sdk/dotnet/Buildx/Image.cs b/sdk/dotnet/Buildx/Image.cs index 68629861..d031d3b4 100644 --- a/sdk/dotnet/Buildx/Image.cs +++ b/sdk/dotnet/Buildx/Image.cs @@ -461,6 +461,14 @@ namespace Pulumi.Docker.Buildx [DockerResourceType("docker:buildx/image:Image")] public partial class Image : global::Pulumi.CustomResource { + /// + /// Custom `host:ip` mappings to use during the build. + /// + /// Equivalent to Docker's `--add-host` flag. + /// + [Output("addHosts")] + public Output> AddHosts { get; private set; } = null!; + /// /// `ARG` names and values to set during the build. /// @@ -476,8 +484,20 @@ public partial class Image : global::Pulumi.CustomResource public Output?> BuildArgs { get; private set; } = null!; /// - /// When `true`, attempt to build the image during previews. The image will - /// not be pushed to registries, however caches will still be populated. + /// By default, preview behavior depends on the execution environment. If + /// Pulumi detects the operation is running on a CI system (GitHub Actions, + /// Travis CI, Azure Pipelines, etc.) then it will build images during + /// previews as a safeguard. Otherwise, if not running on CI, previews will + /// not build images. + /// + /// Setting this to `false` forces previews to never perform builds, and + /// setting it to `true` will always build the image during previews. + /// + /// Images built during previews are never exported to registries, however + /// cache manifests are still exported. + /// + /// On-disk Dockerfiles are always validated for syntactic correctness + /// regardless of this setting. /// [Output("buildOnPreview")] public Output BuildOnPreview { get; private set; } = null!; @@ -518,13 +538,17 @@ public partial class Image : global::Pulumi.CustomResource /// Pulumi uses this to determine if an image _may_ need to be re-built. /// [Output("contextHash")] - public Output ContextHash { get; private set; } = null!; + public Output ContextHash { get; private set; } = null!; /// - /// A mapping of platform type to refs which were pushed to registries. + /// A mapping of target names to the SHA256 digest of their pushed manifest. + /// + /// If no target was specified 'default' is used as the target name. + /// + /// Pushed manifests can be referenced as `<tag>@<digest>`. /// [Output("digests")] - public Output>?> Digests { get; private set; } = null!; + public Output> Digests { get; private set; } = null!; /// /// Dockerfile settings. @@ -553,6 +577,34 @@ public partial class Image : global::Pulumi.CustomResource [Output("labels")] public Output?> Labels { get; private set; } = null!; + /// + /// When `true` the build will automatically include a `docker` export. + /// + /// Defaults to `false`. + /// + /// Equivalent to Docker's `--load` flag. + /// + [Output("load")] + public Output Load { get; private set; } = null!; + + /// + /// Set the network mode for `RUN` instructions. Defaults to `default`. + /// + /// For custom networks, configure your builder with `--driver-opt network=...`. + /// + /// Equivalent to Docker's `--network` flag. + /// + [Output("network")] + public Output Network { get; private set; } = null!; + + /// + /// Do not import cache manifests when building the image. + /// + /// Equivalent to Docker's `--no-cache` flag. + /// + [Output("noCache")] + public Output NoCache { get; private set; } = null!; + /// /// Set target platform(s) for the build. Defaults to the host's platform. /// @@ -569,6 +621,30 @@ public partial class Image : global::Pulumi.CustomResource [Output("pull")] public Output Pull { get; private set; } = null!; + /// + /// When `true` the build will automatically include a `registry` export. + /// + /// Defaults to `false`. + /// + /// Equivalent to Docker's `--push` flag. + /// + [Output("push")] + public Output Push { get; private set; } = null!; + + /// + /// If the image was pushed to any registries then this will contain a + /// single fully-qualified tag including the build's digest. + /// + /// This is only for convenience and may not be appropriate for situations + /// where multiple tags or registries are involved. In those cases this + /// output is not guaranteed to be stable. + /// + /// For more control over tags consumed by downstream resources you should + /// use the `Digests` output. + /// + [Output("ref")] + public Output Ref { get; private set; } = null!; + /// /// Registry credentials. Required if reading or exporting to private /// repositories. @@ -595,6 +671,14 @@ public partial class Image : global::Pulumi.CustomResource [Output("secrets")] public Output?> Secrets { get; private set; } = null!; + /// + /// SSH agent socket or keys to expose to the build. + /// + /// Equivalent to Docker's `--ssh` flag. + /// + [Output("ssh")] + public Output> Ssh { get; private set; } = null!; + /// /// Name and optionally a tag (format: `name:tag`). /// @@ -639,10 +723,6 @@ private static CustomResourceOptions MakeResourceOptions(CustomResourceOptions? var defaultOptions = new CustomResourceOptions { Version = Utilities.Version, - AdditionalSecretOutputs = - { - "secrets", - }, }; var merged = CustomResourceOptions.Merge(defaultOptions, options); // Override the ID if one was specified for consistency with other language SDKs. @@ -665,6 +745,20 @@ public static Image Get(string name, Input id, CustomResourceOptions? op public sealed class ImageArgs : global::Pulumi.ResourceArgs { + [Input("addHosts")] + private InputList? _addHosts; + + /// + /// Custom `host:ip` mappings to use during the build. + /// + /// Equivalent to Docker's `--add-host` flag. + /// + public InputList AddHosts + { + get => _addHosts ?? (_addHosts = new InputList()); + set => _addHosts = value; + } + [Input("buildArgs")] private InputMap? _buildArgs; @@ -686,8 +780,20 @@ public InputMap BuildArgs } /// - /// When `true`, attempt to build the image during previews. The image will - /// not be pushed to registries, however caches will still be populated. + /// By default, preview behavior depends on the execution environment. If + /// Pulumi detects the operation is running on a CI system (GitHub Actions, + /// Travis CI, Azure Pipelines, etc.) then it will build images during + /// previews as a safeguard. Otherwise, if not running on CI, previews will + /// not build images. + /// + /// Setting this to `false` forces previews to never perform builds, and + /// setting it to `true` will always build the image during previews. + /// + /// Images built during previews are never exported to registries, however + /// cache manifests are still exported. + /// + /// On-disk Dockerfiles are always validated for syntactic correctness + /// regardless of this setting. /// [Input("buildOnPreview")] public Input? BuildOnPreview { get; set; } @@ -773,6 +879,34 @@ public InputMap Labels set => _labels = value; } + /// + /// When `true` the build will automatically include a `docker` export. + /// + /// Defaults to `false`. + /// + /// Equivalent to Docker's `--load` flag. + /// + [Input("load")] + public Input? Load { get; set; } + + /// + /// Set the network mode for `RUN` instructions. Defaults to `default`. + /// + /// For custom networks, configure your builder with `--driver-opt network=...`. + /// + /// Equivalent to Docker's `--network` flag. + /// + [Input("network")] + public Input? Network { get; set; } + + /// + /// Do not import cache manifests when building the image. + /// + /// Equivalent to Docker's `--no-cache` flag. + /// + [Input("noCache")] + public Input? NoCache { get; set; } + [Input("platforms")] private InputList? _platforms; @@ -795,6 +929,16 @@ public InputList Platforms [Input("pull")] public Input? Pull { get; set; } + /// + /// When `true` the build will automatically include a `registry` export. + /// + /// Defaults to `false`. + /// + /// Equivalent to Docker's `--push` flag. + /// + [Input("push")] + public Input? Push { get; set; } + [Input("registries")] private InputList? _registries; @@ -830,11 +974,21 @@ public InputList Registries public InputMap Secrets { get => _secrets ?? (_secrets = new InputMap()); - set - { - var emptySecret = Output.CreateSecret(ImmutableDictionary.Create()); - _secrets = Output.All(value, emptySecret).Apply(v => v[0]); - } + set => _secrets = value; + } + + [Input("ssh")] + private InputList? _ssh; + + /// + /// SSH agent socket or keys to expose to the build. + /// + /// Equivalent to Docker's `--ssh` flag. + /// + public InputList Ssh + { + get => _ssh ?? (_ssh = new InputList()); + set => _ssh = value; } [Input("tags")] @@ -872,6 +1026,7 @@ public InputList Targets public ImageArgs() { + Network = Pulumi.Docker.Buildx.NetworkMode.@Default; } public static new ImageArgs Empty => new ImageArgs(); } diff --git a/sdk/dotnet/Buildx/Inputs/ExportEntryArgs.cs b/sdk/dotnet/Buildx/Inputs/ExportEntryArgs.cs index 6e5583c9..e7b816c4 100644 --- a/sdk/dotnet/Buildx/Inputs/ExportEntryArgs.cs +++ b/sdk/dotnet/Buildx/Inputs/ExportEntryArgs.cs @@ -36,19 +36,6 @@ public sealed class ExportEntryArgs : global::Pulumi.ResourceArgs [Input("local")] public Input? Local { get; set; } - [Input("manifests")] - private InputList? _manifests; - - /// - /// An output property populated for exporters that pushed image - /// manifest(s) to a registry. - /// - public InputList Manifests - { - get => _manifests ?? (_manifests = new InputList()); - set => _manifests = value; - } - /// /// Identical to the Docker exporter but uses OCI media types by default. /// diff --git a/sdk/dotnet/Buildx/Inputs/ManifestArgs.cs b/sdk/dotnet/Buildx/Inputs/ManifestArgs.cs deleted file mode 100644 index b371ec8d..00000000 --- a/sdk/dotnet/Buildx/Inputs/ManifestArgs.cs +++ /dev/null @@ -1,44 +0,0 @@ -// *** WARNING: this file was generated by the Pulumi Terraform Bridge (tfgen) Tool. *** -// *** Do not edit by hand unless you're certain you know what you are doing! *** - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Threading.Tasks; -using Pulumi.Serialization; - -namespace Pulumi.Docker.Buildx.Inputs -{ - - public sealed class ManifestArgs : global::Pulumi.ResourceArgs - { - /// - /// The SHA256 digest of the manifest. - /// - [Input("digest", required: true)] - public Input Digest { get; set; } = null!; - - /// - /// The manifest's platform. - /// - [Input("platform", required: true)] - public Input Platform { get; set; } = null!; - - /// - /// The manifest's canonical ref. - /// - [Input("ref", required: true)] - public Input Ref { get; set; } = null!; - - /// - /// The size of the manifest in bytes. - /// - [Input("size", required: true)] - public Input Size { get; set; } = null!; - - public ManifestArgs() - { - } - public static new ManifestArgs Empty => new ManifestArgs(); - } -} diff --git a/sdk/dotnet/Buildx/Inputs/ManifestPlatformArgs.cs b/sdk/dotnet/Buildx/Inputs/ManifestPlatformArgs.cs deleted file mode 100644 index 9b95fb8a..00000000 --- a/sdk/dotnet/Buildx/Inputs/ManifestPlatformArgs.cs +++ /dev/null @@ -1,32 +0,0 @@ -// *** WARNING: this file was generated by the Pulumi Terraform Bridge (tfgen) Tool. *** -// *** Do not edit by hand unless you're certain you know what you are doing! *** - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Threading.Tasks; -using Pulumi.Serialization; - -namespace Pulumi.Docker.Buildx.Inputs -{ - - public sealed class ManifestPlatformArgs : global::Pulumi.ResourceArgs - { - /// - /// The manifest's architecture. - /// - [Input("architecture", required: true)] - public Input Architecture { get; set; } = null!; - - /// - /// The manifest's operating systen. - /// - [Input("os", required: true)] - public Input Os { get; set; } = null!; - - public ManifestPlatformArgs() - { - } - public static new ManifestPlatformArgs Empty => new ManifestPlatformArgs(); - } -} diff --git a/sdk/dotnet/Buildx/Inputs/SSHArgs.cs b/sdk/dotnet/Buildx/Inputs/SSHArgs.cs new file mode 100644 index 00000000..2f07c7ac --- /dev/null +++ b/sdk/dotnet/Buildx/Inputs/SSHArgs.cs @@ -0,0 +1,48 @@ +// *** WARNING: this file was generated by the Pulumi Terraform Bridge (tfgen) Tool. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Pulumi.Serialization; + +namespace Pulumi.Docker.Buildx.Inputs +{ + + public sealed class SSHArgs : global::Pulumi.ResourceArgs + { + /// + /// Useful for distinguishing different servers that are part of the same + /// build. + /// + /// A value of `default` is appropriate if only dealing with a single host. + /// + [Input("id", required: true)] + public Input Id { get; set; } = null!; + + [Input("paths")] + private InputList? _paths; + + /// + /// SSH agent socket or private keys to expose to the build under the given + /// identifier. + /// + /// Defaults to `[$SSH_AUTH_SOCK]`. + /// + /// Note that your keys are **not** automatically added when using an + /// agent. Run `ssh-add -l` locally to confirm which public keys are + /// visible to the agent; these will be exposed to your build. + /// + public InputList Paths + { + get => _paths ?? (_paths = new InputList()); + set => _paths = value; + } + + public SSHArgs() + { + } + public static new SSHArgs Empty => new SSHArgs(); + } +} diff --git a/sdk/dotnet/Buildx/Outputs/ExportEntry.cs b/sdk/dotnet/Buildx/Outputs/ExportEntry.cs index 727ede06..e294ffc4 100644 --- a/sdk/dotnet/Buildx/Outputs/ExportEntry.cs +++ b/sdk/dotnet/Buildx/Outputs/ExportEntry.cs @@ -30,11 +30,6 @@ public sealed class ExportEntry /// public readonly Outputs.ExportLocal? Local; /// - /// An output property populated for exporters that pushed image - /// manifest(s) to a registry. - /// - public readonly ImmutableArray Manifests; - /// /// Identical to the Docker exporter but uses OCI media types by default. /// public readonly Outputs.ExportOCI? Oci; @@ -62,8 +57,6 @@ private ExportEntry( Outputs.ExportLocal? local, - ImmutableArray manifests, - Outputs.ExportOCI? oci, string? raw, @@ -76,7 +69,6 @@ private ExportEntry( Docker = docker; Image = image; Local = local; - Manifests = manifests; Oci = oci; Raw = raw; Registry = registry; diff --git a/sdk/dotnet/Buildx/Outputs/Manifest.cs b/sdk/dotnet/Buildx/Outputs/Manifest.cs deleted file mode 100644 index 1badef99..00000000 --- a/sdk/dotnet/Buildx/Outputs/Manifest.cs +++ /dev/null @@ -1,49 +0,0 @@ -// *** WARNING: this file was generated by the Pulumi Terraform Bridge (tfgen) Tool. *** -// *** Do not edit by hand unless you're certain you know what you are doing! *** - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Threading.Tasks; -using Pulumi.Serialization; - -namespace Pulumi.Docker.Buildx.Outputs -{ - - [OutputType] - public sealed class Manifest - { - /// - /// The SHA256 digest of the manifest. - /// - public readonly string Digest; - /// - /// The manifest's platform. - /// - public readonly Outputs.ManifestPlatform Platform; - /// - /// The manifest's canonical ref. - /// - public readonly string Ref; - /// - /// The size of the manifest in bytes. - /// - public readonly int Size; - - [OutputConstructor] - private Manifest( - string digest, - - Outputs.ManifestPlatform platform, - - string @ref, - - int size) - { - Digest = digest; - Platform = platform; - Ref = @ref; - Size = size; - } - } -} diff --git a/sdk/dotnet/Buildx/Outputs/ManifestPlatform.cs b/sdk/dotnet/Buildx/Outputs/ManifestPlatform.cs deleted file mode 100644 index 7c8aec5c..00000000 --- a/sdk/dotnet/Buildx/Outputs/ManifestPlatform.cs +++ /dev/null @@ -1,35 +0,0 @@ -// *** WARNING: this file was generated by the Pulumi Terraform Bridge (tfgen) Tool. *** -// *** Do not edit by hand unless you're certain you know what you are doing! *** - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Threading.Tasks; -using Pulumi.Serialization; - -namespace Pulumi.Docker.Buildx.Outputs -{ - - [OutputType] - public sealed class ManifestPlatform - { - /// - /// The manifest's architecture. - /// - public readonly string Architecture; - /// - /// The manifest's operating systen. - /// - public readonly string Os; - - [OutputConstructor] - private ManifestPlatform( - string architecture, - - string os) - { - Architecture = architecture; - Os = os; - } - } -} diff --git a/sdk/dotnet/Buildx/Outputs/SSH.cs b/sdk/dotnet/Buildx/Outputs/SSH.cs new file mode 100644 index 00000000..296684d6 --- /dev/null +++ b/sdk/dotnet/Buildx/Outputs/SSH.cs @@ -0,0 +1,45 @@ +// *** WARNING: this file was generated by the Pulumi Terraform Bridge (tfgen) Tool. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Pulumi.Serialization; + +namespace Pulumi.Docker.Buildx.Outputs +{ + + [OutputType] + public sealed class SSH + { + /// + /// Useful for distinguishing different servers that are part of the same + /// build. + /// + /// A value of `default` is appropriate if only dealing with a single host. + /// + public readonly string Id; + /// + /// SSH agent socket or private keys to expose to the build under the given + /// identifier. + /// + /// Defaults to `[$SSH_AUTH_SOCK]`. + /// + /// Note that your keys are **not** automatically added when using an + /// agent. Run `ssh-add -l` locally to confirm which public keys are + /// visible to the agent; these will be exposed to your build. + /// + public readonly ImmutableArray Paths; + + [OutputConstructor] + private SSH( + string id, + + ImmutableArray paths) + { + Id = id; + Paths = paths; + } + } +} diff --git a/sdk/go/docker/buildx/image.go b/sdk/go/docker/buildx/image.go index 782929d0..6de584bb 100644 --- a/sdk/go/docker/buildx/image.go +++ b/sdk/go/docker/buildx/image.go @@ -508,6 +508,10 @@ import ( type Image struct { pulumi.CustomResourceState + // Custom `host:ip` mappings to use during the build. + // + // Equivalent to Docker's `--add-host` flag. + AddHosts pulumi.StringArrayOutput `pulumi:"addHosts"` // `ARG` names and values to set during the build. // // These variables are accessed like environment variables inside `RUN` @@ -518,8 +522,20 @@ type Image struct { // // Equivalent to Docker's `--build-arg` flag. BuildArgs pulumi.StringMapOutput `pulumi:"buildArgs"` - // When `true`, attempt to build the image during previews. The image will - // not be pushed to registries, however caches will still be populated. + // By default, preview behavior depends on the execution environment. If + // Pulumi detects the operation is running on a CI system (GitHub Actions, + // Travis CI, Azure Pipelines, etc.) then it will build images during + // previews as a safeguard. Otherwise, if not running on CI, previews will + // not build images. + // + // Setting this to `false` forces previews to never perform builds, and + // setting it to `true` will always build the image during previews. + // + // Images built during previews are never exported to registries, however + // cache manifests are still exported. + // + // On-disk Dockerfiles are always validated for syntactic correctness + // regardless of this setting. BuildOnPreview pulumi.BoolPtrOutput `pulumi:"buildOnPreview"` // Builder configuration. Builder BuilderConfigPtrOutput `pulumi:"builder"` @@ -538,9 +554,13 @@ type Image struct { // A preliminary hash of the image's build context. // // Pulumi uses this to determine if an image _may_ need to be re-built. - ContextHash pulumi.StringPtrOutput `pulumi:"contextHash"` - // A mapping of platform type to refs which were pushed to registries. - Digests pulumi.StringArrayMapOutput `pulumi:"digests"` + ContextHash pulumi.StringOutput `pulumi:"contextHash"` + // A mapping of target names to the SHA256 digest of their pushed manifest. + // + // If no target was specified 'default' is used as the target name. + // + // Pushed manifests can be referenced as `@`. + Digests pulumi.StringMapOutput `pulumi:"digests"` // Dockerfile settings. // // Equivalent to Docker's `--file` flag. @@ -556,6 +576,22 @@ type Image struct { // // Equivalent to Docker's `--label` flag. Labels pulumi.StringMapOutput `pulumi:"labels"` + // When `true` the build will automatically include a `docker` export. + // + // Defaults to `false`. + // + // Equivalent to Docker's `--load` flag. + Load pulumi.BoolPtrOutput `pulumi:"load"` + // Set the network mode for `RUN` instructions. Defaults to `default`. + // + // For custom networks, configure your builder with `--driver-opt network=...`. + // + // Equivalent to Docker's `--network` flag. + Network NetworkModePtrOutput `pulumi:"network"` + // Do not import cache manifests when building the image. + // + // Equivalent to Docker's `--no-cache` flag. + NoCache pulumi.BoolPtrOutput `pulumi:"noCache"` // Set target platform(s) for the build. Defaults to the host's platform. // // Equivalent to Docker's `--platform` flag. @@ -564,6 +600,22 @@ type Image struct { // // Equivalent to Docker's `--pull` flag. Pull pulumi.BoolPtrOutput `pulumi:"pull"` + // When `true` the build will automatically include a `registry` export. + // + // Defaults to `false`. + // + // Equivalent to Docker's `--push` flag. + Push pulumi.BoolPtrOutput `pulumi:"push"` + // If the image was pushed to any registries then this will contain a + // single fully-qualified tag including the build's digest. + // + // This is only for convenience and may not be appropriate for situations + // where multiple tags or registries are involved. In those cases this + // output is not guaranteed to be stable. + // + // For more control over tags consumed by downstream resources you should + // use the `Digests` output. + Ref pulumi.StringOutput `pulumi:"ref"` // Registry credentials. Required if reading or exporting to private // repositories. // @@ -582,6 +634,10 @@ type Image struct { // // Similar to Docker's `--secret` flag. Secrets pulumi.StringMapOutput `pulumi:"secrets"` + // SSH agent socket or keys to expose to the build. + // + // Equivalent to Docker's `--ssh` flag. + Ssh SSHArrayOutput `pulumi:"ssh"` // Name and optionally a tag (format: `name:tag`). // // If exporting to a registry, the name should include the fully qualified @@ -604,13 +660,9 @@ func NewImage(ctx *pulumi.Context, args = &ImageArgs{} } - if args.Secrets != nil { - args.Secrets = pulumi.ToSecret(args.Secrets).(pulumi.StringMapInput) + if args.Network == nil { + args.Network = NetworkMode("default") } - secrets := pulumi.AdditionalSecretOutputs([]string{ - "secrets", - }) - opts = append(opts, secrets) opts = internal.PkgResourceDefaultOpts(opts) var resource Image err := ctx.RegisterResource("docker:buildx/image:Image", name, args, &resource, opts...) @@ -644,6 +696,10 @@ func (ImageState) ElementType() reflect.Type { } type imageArgs struct { + // Custom `host:ip` mappings to use during the build. + // + // Equivalent to Docker's `--add-host` flag. + AddHosts []string `pulumi:"addHosts"` // `ARG` names and values to set during the build. // // These variables are accessed like environment variables inside `RUN` @@ -654,8 +710,20 @@ type imageArgs struct { // // Equivalent to Docker's `--build-arg` flag. BuildArgs map[string]string `pulumi:"buildArgs"` - // When `true`, attempt to build the image during previews. The image will - // not be pushed to registries, however caches will still be populated. + // By default, preview behavior depends on the execution environment. If + // Pulumi detects the operation is running on a CI system (GitHub Actions, + // Travis CI, Azure Pipelines, etc.) then it will build images during + // previews as a safeguard. Otherwise, if not running on CI, previews will + // not build images. + // + // Setting this to `false` forces previews to never perform builds, and + // setting it to `true` will always build the image during previews. + // + // Images built during previews are never exported to registries, however + // cache manifests are still exported. + // + // On-disk Dockerfiles are always validated for syntactic correctness + // regardless of this setting. BuildOnPreview *bool `pulumi:"buildOnPreview"` // Builder configuration. Builder *BuilderConfig `pulumi:"builder"` @@ -686,6 +754,22 @@ type imageArgs struct { // // Equivalent to Docker's `--label` flag. Labels map[string]string `pulumi:"labels"` + // When `true` the build will automatically include a `docker` export. + // + // Defaults to `false`. + // + // Equivalent to Docker's `--load` flag. + Load *bool `pulumi:"load"` + // Set the network mode for `RUN` instructions. Defaults to `default`. + // + // For custom networks, configure your builder with `--driver-opt network=...`. + // + // Equivalent to Docker's `--network` flag. + Network *NetworkMode `pulumi:"network"` + // Do not import cache manifests when building the image. + // + // Equivalent to Docker's `--no-cache` flag. + NoCache *bool `pulumi:"noCache"` // Set target platform(s) for the build. Defaults to the host's platform. // // Equivalent to Docker's `--platform` flag. @@ -694,6 +778,12 @@ type imageArgs struct { // // Equivalent to Docker's `--pull` flag. Pull *bool `pulumi:"pull"` + // When `true` the build will automatically include a `registry` export. + // + // Defaults to `false`. + // + // Equivalent to Docker's `--push` flag. + Push *bool `pulumi:"push"` // Registry credentials. Required if reading or exporting to private // repositories. // @@ -712,6 +802,10 @@ type imageArgs struct { // // Similar to Docker's `--secret` flag. Secrets map[string]string `pulumi:"secrets"` + // SSH agent socket or keys to expose to the build. + // + // Equivalent to Docker's `--ssh` flag. + Ssh []SSH `pulumi:"ssh"` // Name and optionally a tag (format: `name:tag`). // // If exporting to a registry, the name should include the fully qualified @@ -729,6 +823,10 @@ type imageArgs struct { // The set of arguments for constructing a Image resource. type ImageArgs struct { + // Custom `host:ip` mappings to use during the build. + // + // Equivalent to Docker's `--add-host` flag. + AddHosts pulumi.StringArrayInput // `ARG` names and values to set during the build. // // These variables are accessed like environment variables inside `RUN` @@ -739,8 +837,20 @@ type ImageArgs struct { // // Equivalent to Docker's `--build-arg` flag. BuildArgs pulumi.StringMapInput - // When `true`, attempt to build the image during previews. The image will - // not be pushed to registries, however caches will still be populated. + // By default, preview behavior depends on the execution environment. If + // Pulumi detects the operation is running on a CI system (GitHub Actions, + // Travis CI, Azure Pipelines, etc.) then it will build images during + // previews as a safeguard. Otherwise, if not running on CI, previews will + // not build images. + // + // Setting this to `false` forces previews to never perform builds, and + // setting it to `true` will always build the image during previews. + // + // Images built during previews are never exported to registries, however + // cache manifests are still exported. + // + // On-disk Dockerfiles are always validated for syntactic correctness + // regardless of this setting. BuildOnPreview pulumi.BoolPtrInput // Builder configuration. Builder BuilderConfigPtrInput @@ -771,6 +881,22 @@ type ImageArgs struct { // // Equivalent to Docker's `--label` flag. Labels pulumi.StringMapInput + // When `true` the build will automatically include a `docker` export. + // + // Defaults to `false`. + // + // Equivalent to Docker's `--load` flag. + Load pulumi.BoolPtrInput + // Set the network mode for `RUN` instructions. Defaults to `default`. + // + // For custom networks, configure your builder with `--driver-opt network=...`. + // + // Equivalent to Docker's `--network` flag. + Network NetworkModePtrInput + // Do not import cache manifests when building the image. + // + // Equivalent to Docker's `--no-cache` flag. + NoCache pulumi.BoolPtrInput // Set target platform(s) for the build. Defaults to the host's platform. // // Equivalent to Docker's `--platform` flag. @@ -779,6 +905,12 @@ type ImageArgs struct { // // Equivalent to Docker's `--pull` flag. Pull pulumi.BoolPtrInput + // When `true` the build will automatically include a `registry` export. + // + // Defaults to `false`. + // + // Equivalent to Docker's `--push` flag. + Push pulumi.BoolPtrInput // Registry credentials. Required if reading or exporting to private // repositories. // @@ -797,6 +929,10 @@ type ImageArgs struct { // // Similar to Docker's `--secret` flag. Secrets pulumi.StringMapInput + // SSH agent socket or keys to expose to the build. + // + // Equivalent to Docker's `--ssh` flag. + Ssh SSHArrayInput // Name and optionally a tag (format: `name:tag`). // // If exporting to a registry, the name should include the fully qualified @@ -899,6 +1035,13 @@ func (o ImageOutput) ToImageOutputWithContext(ctx context.Context) ImageOutput { return o } +// Custom `host:ip` mappings to use during the build. +// +// Equivalent to Docker's `--add-host` flag. +func (o ImageOutput) AddHosts() pulumi.StringArrayOutput { + return o.ApplyT(func(v *Image) pulumi.StringArrayOutput { return v.AddHosts }).(pulumi.StringArrayOutput) +} + // `ARG` names and values to set during the build. // // These variables are accessed like environment variables inside `RUN` @@ -912,8 +1055,20 @@ func (o ImageOutput) BuildArgs() pulumi.StringMapOutput { return o.ApplyT(func(v *Image) pulumi.StringMapOutput { return v.BuildArgs }).(pulumi.StringMapOutput) } -// When `true`, attempt to build the image during previews. The image will -// not be pushed to registries, however caches will still be populated. +// By default, preview behavior depends on the execution environment. If +// Pulumi detects the operation is running on a CI system (GitHub Actions, +// Travis CI, Azure Pipelines, etc.) then it will build images during +// previews as a safeguard. Otherwise, if not running on CI, previews will +// not build images. +// +// Setting this to `false` forces previews to never perform builds, and +// setting it to `true` will always build the image during previews. +// +// Images built during previews are never exported to registries, however +// cache manifests are still exported. +// +// On-disk Dockerfiles are always validated for syntactic correctness +// regardless of this setting. func (o ImageOutput) BuildOnPreview() pulumi.BoolPtrOutput { return o.ApplyT(func(v *Image) pulumi.BoolPtrOutput { return v.BuildOnPreview }).(pulumi.BoolPtrOutput) } @@ -947,13 +1102,17 @@ func (o ImageOutput) Context() BuildContextPtrOutput { // A preliminary hash of the image's build context. // // Pulumi uses this to determine if an image _may_ need to be re-built. -func (o ImageOutput) ContextHash() pulumi.StringPtrOutput { - return o.ApplyT(func(v *Image) pulumi.StringPtrOutput { return v.ContextHash }).(pulumi.StringPtrOutput) +func (o ImageOutput) ContextHash() pulumi.StringOutput { + return o.ApplyT(func(v *Image) pulumi.StringOutput { return v.ContextHash }).(pulumi.StringOutput) } -// A mapping of platform type to refs which were pushed to registries. -func (o ImageOutput) Digests() pulumi.StringArrayMapOutput { - return o.ApplyT(func(v *Image) pulumi.StringArrayMapOutput { return v.Digests }).(pulumi.StringArrayMapOutput) +// A mapping of target names to the SHA256 digest of their pushed manifest. +// +// If no target was specified 'default' is used as the target name. +// +// Pushed manifests can be referenced as `@`. +func (o ImageOutput) Digests() pulumi.StringMapOutput { + return o.ApplyT(func(v *Image) pulumi.StringMapOutput { return v.Digests }).(pulumi.StringMapOutput) } // Dockerfile settings. @@ -980,6 +1139,31 @@ func (o ImageOutput) Labels() pulumi.StringMapOutput { return o.ApplyT(func(v *Image) pulumi.StringMapOutput { return v.Labels }).(pulumi.StringMapOutput) } +// When `true` the build will automatically include a `docker` export. +// +// Defaults to `false`. +// +// Equivalent to Docker's `--load` flag. +func (o ImageOutput) Load() pulumi.BoolPtrOutput { + return o.ApplyT(func(v *Image) pulumi.BoolPtrOutput { return v.Load }).(pulumi.BoolPtrOutput) +} + +// Set the network mode for `RUN` instructions. Defaults to `default`. +// +// For custom networks, configure your builder with `--driver-opt network=...`. +// +// Equivalent to Docker's `--network` flag. +func (o ImageOutput) Network() NetworkModePtrOutput { + return o.ApplyT(func(v *Image) NetworkModePtrOutput { return v.Network }).(NetworkModePtrOutput) +} + +// Do not import cache manifests when building the image. +// +// Equivalent to Docker's `--no-cache` flag. +func (o ImageOutput) NoCache() pulumi.BoolPtrOutput { + return o.ApplyT(func(v *Image) pulumi.BoolPtrOutput { return v.NoCache }).(pulumi.BoolPtrOutput) +} + // Set target platform(s) for the build. Defaults to the host's platform. // // Equivalent to Docker's `--platform` flag. @@ -994,6 +1178,28 @@ func (o ImageOutput) Pull() pulumi.BoolPtrOutput { return o.ApplyT(func(v *Image) pulumi.BoolPtrOutput { return v.Pull }).(pulumi.BoolPtrOutput) } +// When `true` the build will automatically include a `registry` export. +// +// Defaults to `false`. +// +// Equivalent to Docker's `--push` flag. +func (o ImageOutput) Push() pulumi.BoolPtrOutput { + return o.ApplyT(func(v *Image) pulumi.BoolPtrOutput { return v.Push }).(pulumi.BoolPtrOutput) +} + +// If the image was pushed to any registries then this will contain a +// single fully-qualified tag including the build's digest. +// +// This is only for convenience and may not be appropriate for situations +// where multiple tags or registries are involved. In those cases this +// output is not guaranteed to be stable. +// +// For more control over tags consumed by downstream resources you should +// use the `Digests` output. +func (o ImageOutput) Ref() pulumi.StringOutput { + return o.ApplyT(func(v *Image) pulumi.StringOutput { return v.Ref }).(pulumi.StringOutput) +} + // Registry credentials. Required if reading or exporting to private // repositories. // @@ -1018,6 +1224,13 @@ func (o ImageOutput) Secrets() pulumi.StringMapOutput { return o.ApplyT(func(v *Image) pulumi.StringMapOutput { return v.Secrets }).(pulumi.StringMapOutput) } +// SSH agent socket or keys to expose to the build. +// +// Equivalent to Docker's `--ssh` flag. +func (o ImageOutput) Ssh() SSHArrayOutput { + return o.ApplyT(func(v *Image) SSHArrayOutput { return v.Ssh }).(SSHArrayOutput) +} + // Name and optionally a tag (format: `name:tag`). // // If exporting to a registry, the name should include the fully qualified diff --git a/sdk/go/docker/buildx/pulumiEnums.go b/sdk/go/docker/buildx/pulumiEnums.go index 5a230a8c..098931dc 100644 --- a/sdk/go/docker/buildx/pulumiEnums.go +++ b/sdk/go/docker/buildx/pulumiEnums.go @@ -347,6 +347,176 @@ func (in *compressionTypePtr) ToCompressionTypePtrOutputWithContext(ctx context. return pulumi.ToOutputWithContext(ctx, in).(CompressionTypePtrOutput) } +type NetworkMode string + +const ( + // The default sandbox network mode. + NetworkModeDefault = NetworkMode("default") + // Host network mode. + NetworkModeHost = NetworkMode("host") + // Disable network access. + NetworkModeNone = NetworkMode("none") +) + +func (NetworkMode) ElementType() reflect.Type { + return reflect.TypeOf((*NetworkMode)(nil)).Elem() +} + +func (e NetworkMode) ToNetworkModeOutput() NetworkModeOutput { + return pulumi.ToOutput(e).(NetworkModeOutput) +} + +func (e NetworkMode) ToNetworkModeOutputWithContext(ctx context.Context) NetworkModeOutput { + return pulumi.ToOutputWithContext(ctx, e).(NetworkModeOutput) +} + +func (e NetworkMode) ToNetworkModePtrOutput() NetworkModePtrOutput { + return e.ToNetworkModePtrOutputWithContext(context.Background()) +} + +func (e NetworkMode) ToNetworkModePtrOutputWithContext(ctx context.Context) NetworkModePtrOutput { + return NetworkMode(e).ToNetworkModeOutputWithContext(ctx).ToNetworkModePtrOutputWithContext(ctx) +} + +func (e NetworkMode) ToStringOutput() pulumi.StringOutput { + return pulumi.ToOutput(pulumi.String(e)).(pulumi.StringOutput) +} + +func (e NetworkMode) ToStringOutputWithContext(ctx context.Context) pulumi.StringOutput { + return pulumi.ToOutputWithContext(ctx, pulumi.String(e)).(pulumi.StringOutput) +} + +func (e NetworkMode) ToStringPtrOutput() pulumi.StringPtrOutput { + return pulumi.String(e).ToStringPtrOutputWithContext(context.Background()) +} + +func (e NetworkMode) ToStringPtrOutputWithContext(ctx context.Context) pulumi.StringPtrOutput { + return pulumi.String(e).ToStringOutputWithContext(ctx).ToStringPtrOutputWithContext(ctx) +} + +type NetworkModeOutput struct{ *pulumi.OutputState } + +func (NetworkModeOutput) ElementType() reflect.Type { + return reflect.TypeOf((*NetworkMode)(nil)).Elem() +} + +func (o NetworkModeOutput) ToNetworkModeOutput() NetworkModeOutput { + return o +} + +func (o NetworkModeOutput) ToNetworkModeOutputWithContext(ctx context.Context) NetworkModeOutput { + return o +} + +func (o NetworkModeOutput) ToNetworkModePtrOutput() NetworkModePtrOutput { + return o.ToNetworkModePtrOutputWithContext(context.Background()) +} + +func (o NetworkModeOutput) ToNetworkModePtrOutputWithContext(ctx context.Context) NetworkModePtrOutput { + return o.ApplyTWithContext(ctx, func(_ context.Context, v NetworkMode) *NetworkMode { + return &v + }).(NetworkModePtrOutput) +} + +func (o NetworkModeOutput) ToStringOutput() pulumi.StringOutput { + return o.ToStringOutputWithContext(context.Background()) +} + +func (o NetworkModeOutput) ToStringOutputWithContext(ctx context.Context) pulumi.StringOutput { + return o.ApplyTWithContext(ctx, func(_ context.Context, e NetworkMode) string { + return string(e) + }).(pulumi.StringOutput) +} + +func (o NetworkModeOutput) ToStringPtrOutput() pulumi.StringPtrOutput { + return o.ToStringPtrOutputWithContext(context.Background()) +} + +func (o NetworkModeOutput) ToStringPtrOutputWithContext(ctx context.Context) pulumi.StringPtrOutput { + return o.ApplyTWithContext(ctx, func(_ context.Context, e NetworkMode) *string { + v := string(e) + return &v + }).(pulumi.StringPtrOutput) +} + +type NetworkModePtrOutput struct{ *pulumi.OutputState } + +func (NetworkModePtrOutput) ElementType() reflect.Type { + return reflect.TypeOf((**NetworkMode)(nil)).Elem() +} + +func (o NetworkModePtrOutput) ToNetworkModePtrOutput() NetworkModePtrOutput { + return o +} + +func (o NetworkModePtrOutput) ToNetworkModePtrOutputWithContext(ctx context.Context) NetworkModePtrOutput { + return o +} + +func (o NetworkModePtrOutput) Elem() NetworkModeOutput { + return o.ApplyT(func(v *NetworkMode) NetworkMode { + if v != nil { + return *v + } + var ret NetworkMode + return ret + }).(NetworkModeOutput) +} + +func (o NetworkModePtrOutput) ToStringPtrOutput() pulumi.StringPtrOutput { + return o.ToStringPtrOutputWithContext(context.Background()) +} + +func (o NetworkModePtrOutput) ToStringPtrOutputWithContext(ctx context.Context) pulumi.StringPtrOutput { + return o.ApplyTWithContext(ctx, func(_ context.Context, e *NetworkMode) *string { + if e == nil { + return nil + } + v := string(*e) + return &v + }).(pulumi.StringPtrOutput) +} + +// NetworkModeInput is an input type that accepts values of the NetworkMode enum +// A concrete instance of `NetworkModeInput` can be one of the following: +// +// NetworkModeDefault +// NetworkModeHost +// NetworkModeNone +type NetworkModeInput interface { + pulumi.Input + + ToNetworkModeOutput() NetworkModeOutput + ToNetworkModeOutputWithContext(context.Context) NetworkModeOutput +} + +var networkModePtrType = reflect.TypeOf((**NetworkMode)(nil)).Elem() + +type NetworkModePtrInput interface { + pulumi.Input + + ToNetworkModePtrOutput() NetworkModePtrOutput + ToNetworkModePtrOutputWithContext(context.Context) NetworkModePtrOutput +} + +type networkModePtr string + +func NetworkModePtr(v string) NetworkModePtrInput { + return (*networkModePtr)(&v) +} + +func (*networkModePtr) ElementType() reflect.Type { + return networkModePtrType +} + +func (in *networkModePtr) ToNetworkModePtrOutput() NetworkModePtrOutput { + return pulumi.ToOutput(in).(NetworkModePtrOutput) +} + +func (in *networkModePtr) ToNetworkModePtrOutputWithContext(ctx context.Context) NetworkModePtrOutput { + return pulumi.ToOutputWithContext(ctx, in).(NetworkModePtrOutput) +} + type Platform string const ( @@ -614,6 +784,8 @@ func init() { pulumi.RegisterInputType(reflect.TypeOf((*CacheModePtrInput)(nil)).Elem(), CacheMode("min")) pulumi.RegisterInputType(reflect.TypeOf((*CompressionTypeInput)(nil)).Elem(), CompressionType("gzip")) pulumi.RegisterInputType(reflect.TypeOf((*CompressionTypePtrInput)(nil)).Elem(), CompressionType("gzip")) + pulumi.RegisterInputType(reflect.TypeOf((*NetworkModeInput)(nil)).Elem(), NetworkMode("default")) + pulumi.RegisterInputType(reflect.TypeOf((*NetworkModePtrInput)(nil)).Elem(), NetworkMode("default")) pulumi.RegisterInputType(reflect.TypeOf((*PlatformInput)(nil)).Elem(), Platform("darwin/386")) pulumi.RegisterInputType(reflect.TypeOf((*PlatformPtrInput)(nil)).Elem(), Platform("darwin/386")) pulumi.RegisterInputType(reflect.TypeOf((*PlatformArrayInput)(nil)).Elem(), PlatformArray{}) @@ -621,6 +793,8 @@ func init() { pulumi.RegisterOutputType(CacheModePtrOutput{}) pulumi.RegisterOutputType(CompressionTypeOutput{}) pulumi.RegisterOutputType(CompressionTypePtrOutput{}) + pulumi.RegisterOutputType(NetworkModeOutput{}) + pulumi.RegisterOutputType(NetworkModePtrOutput{}) pulumi.RegisterOutputType(PlatformOutput{}) pulumi.RegisterOutputType(PlatformPtrOutput{}) pulumi.RegisterOutputType(PlatformArrayOutput{}) diff --git a/sdk/go/docker/buildx/pulumiTypes.go b/sdk/go/docker/buildx/pulumiTypes.go index 2026da88..0b396711 100644 --- a/sdk/go/docker/buildx/pulumiTypes.go +++ b/sdk/go/docker/buildx/pulumiTypes.go @@ -4268,9 +4268,6 @@ type ExportEntry struct { Image *ExportImage `pulumi:"image"` // Export to a local directory as files and directories. Local *ExportLocal `pulumi:"local"` - // An output property populated for exporters that pushed image - // manifest(s) to a registry. - Manifests []Manifest `pulumi:"manifests"` // Identical to the Docker exporter but uses OCI media types by default. Oci *ExportOCI `pulumi:"oci"` // A raw string as you would provide it to the Docker CLI (e.g., @@ -4319,9 +4316,6 @@ type ExportEntryArgs struct { Image ExportImagePtrInput `pulumi:"image"` // Export to a local directory as files and directories. Local ExportLocalPtrInput `pulumi:"local"` - // An output property populated for exporters that pushed image - // manifest(s) to a registry. - Manifests ManifestArrayInput `pulumi:"manifests"` // Identical to the Docker exporter but uses OCI media types by default. Oci ExportOCIPtrInput `pulumi:"oci"` // A raw string as you would provide it to the Docker CLI (e.g., @@ -4413,12 +4407,6 @@ func (o ExportEntryOutput) Local() ExportLocalPtrOutput { return o.ApplyT(func(v ExportEntry) *ExportLocal { return v.Local }).(ExportLocalPtrOutput) } -// An output property populated for exporters that pushed image -// manifest(s) to a registry. -func (o ExportEntryOutput) Manifests() ManifestArrayOutput { - return o.ApplyT(func(v ExportEntry) []Manifest { return v.Manifests }).(ManifestArrayOutput) -} - // Identical to the Docker exporter but uses OCI media types by default. func (o ExportEntryOutput) Oci() ExportOCIPtrOutput { return o.ApplyT(func(v ExportEntry) *ExportOCI { return v.Oci }).(ExportOCIPtrOutput) @@ -5953,191 +5941,6 @@ func (o ExportTarPtrOutput) Dest() pulumi.StringPtrOutput { }).(pulumi.StringPtrOutput) } -type Manifest struct { - // The SHA256 digest of the manifest. - Digest string `pulumi:"digest"` - // The manifest's platform. - Platform ManifestPlatform `pulumi:"platform"` - // The manifest's canonical ref. - Ref string `pulumi:"ref"` - // The size of the manifest in bytes. - Size int `pulumi:"size"` -} - -// ManifestInput is an input type that accepts ManifestArgs and ManifestOutput values. -// You can construct a concrete instance of `ManifestInput` via: -// -// ManifestArgs{...} -type ManifestInput interface { - pulumi.Input - - ToManifestOutput() ManifestOutput - ToManifestOutputWithContext(context.Context) ManifestOutput -} - -type ManifestArgs struct { - // The SHA256 digest of the manifest. - Digest pulumi.StringInput `pulumi:"digest"` - // The manifest's platform. - Platform ManifestPlatformInput `pulumi:"platform"` - // The manifest's canonical ref. - Ref pulumi.StringInput `pulumi:"ref"` - // The size of the manifest in bytes. - Size pulumi.IntInput `pulumi:"size"` -} - -func (ManifestArgs) ElementType() reflect.Type { - return reflect.TypeOf((*Manifest)(nil)).Elem() -} - -func (i ManifestArgs) ToManifestOutput() ManifestOutput { - return i.ToManifestOutputWithContext(context.Background()) -} - -func (i ManifestArgs) ToManifestOutputWithContext(ctx context.Context) ManifestOutput { - return pulumi.ToOutputWithContext(ctx, i).(ManifestOutput) -} - -// ManifestArrayInput is an input type that accepts ManifestArray and ManifestArrayOutput values. -// You can construct a concrete instance of `ManifestArrayInput` via: -// -// ManifestArray{ ManifestArgs{...} } -type ManifestArrayInput interface { - pulumi.Input - - ToManifestArrayOutput() ManifestArrayOutput - ToManifestArrayOutputWithContext(context.Context) ManifestArrayOutput -} - -type ManifestArray []ManifestInput - -func (ManifestArray) ElementType() reflect.Type { - return reflect.TypeOf((*[]Manifest)(nil)).Elem() -} - -func (i ManifestArray) ToManifestArrayOutput() ManifestArrayOutput { - return i.ToManifestArrayOutputWithContext(context.Background()) -} - -func (i ManifestArray) ToManifestArrayOutputWithContext(ctx context.Context) ManifestArrayOutput { - return pulumi.ToOutputWithContext(ctx, i).(ManifestArrayOutput) -} - -type ManifestOutput struct{ *pulumi.OutputState } - -func (ManifestOutput) ElementType() reflect.Type { - return reflect.TypeOf((*Manifest)(nil)).Elem() -} - -func (o ManifestOutput) ToManifestOutput() ManifestOutput { - return o -} - -func (o ManifestOutput) ToManifestOutputWithContext(ctx context.Context) ManifestOutput { - return o -} - -// The SHA256 digest of the manifest. -func (o ManifestOutput) Digest() pulumi.StringOutput { - return o.ApplyT(func(v Manifest) string { return v.Digest }).(pulumi.StringOutput) -} - -// The manifest's platform. -func (o ManifestOutput) Platform() ManifestPlatformOutput { - return o.ApplyT(func(v Manifest) ManifestPlatform { return v.Platform }).(ManifestPlatformOutput) -} - -// The manifest's canonical ref. -func (o ManifestOutput) Ref() pulumi.StringOutput { - return o.ApplyT(func(v Manifest) string { return v.Ref }).(pulumi.StringOutput) -} - -// The size of the manifest in bytes. -func (o ManifestOutput) Size() pulumi.IntOutput { - return o.ApplyT(func(v Manifest) int { return v.Size }).(pulumi.IntOutput) -} - -type ManifestArrayOutput struct{ *pulumi.OutputState } - -func (ManifestArrayOutput) ElementType() reflect.Type { - return reflect.TypeOf((*[]Manifest)(nil)).Elem() -} - -func (o ManifestArrayOutput) ToManifestArrayOutput() ManifestArrayOutput { - return o -} - -func (o ManifestArrayOutput) ToManifestArrayOutputWithContext(ctx context.Context) ManifestArrayOutput { - return o -} - -func (o ManifestArrayOutput) Index(i pulumi.IntInput) ManifestOutput { - return pulumi.All(o, i).ApplyT(func(vs []interface{}) Manifest { - return vs[0].([]Manifest)[vs[1].(int)] - }).(ManifestOutput) -} - -type ManifestPlatform struct { - // The manifest's architecture. - Architecture string `pulumi:"architecture"` - // The manifest's operating systen. - Os string `pulumi:"os"` -} - -// ManifestPlatformInput is an input type that accepts ManifestPlatformArgs and ManifestPlatformOutput values. -// You can construct a concrete instance of `ManifestPlatformInput` via: -// -// ManifestPlatformArgs{...} -type ManifestPlatformInput interface { - pulumi.Input - - ToManifestPlatformOutput() ManifestPlatformOutput - ToManifestPlatformOutputWithContext(context.Context) ManifestPlatformOutput -} - -type ManifestPlatformArgs struct { - // The manifest's architecture. - Architecture pulumi.StringInput `pulumi:"architecture"` - // The manifest's operating systen. - Os pulumi.StringInput `pulumi:"os"` -} - -func (ManifestPlatformArgs) ElementType() reflect.Type { - return reflect.TypeOf((*ManifestPlatform)(nil)).Elem() -} - -func (i ManifestPlatformArgs) ToManifestPlatformOutput() ManifestPlatformOutput { - return i.ToManifestPlatformOutputWithContext(context.Background()) -} - -func (i ManifestPlatformArgs) ToManifestPlatformOutputWithContext(ctx context.Context) ManifestPlatformOutput { - return pulumi.ToOutputWithContext(ctx, i).(ManifestPlatformOutput) -} - -type ManifestPlatformOutput struct{ *pulumi.OutputState } - -func (ManifestPlatformOutput) ElementType() reflect.Type { - return reflect.TypeOf((*ManifestPlatform)(nil)).Elem() -} - -func (o ManifestPlatformOutput) ToManifestPlatformOutput() ManifestPlatformOutput { - return o -} - -func (o ManifestPlatformOutput) ToManifestPlatformOutputWithContext(ctx context.Context) ManifestPlatformOutput { - return o -} - -// The manifest's architecture. -func (o ManifestPlatformOutput) Architecture() pulumi.StringOutput { - return o.ApplyT(func(v ManifestPlatform) string { return v.Architecture }).(pulumi.StringOutput) -} - -// The manifest's operating systen. -func (o ManifestPlatformOutput) Os() pulumi.StringOutput { - return o.ApplyT(func(v ManifestPlatform) string { return v.Os }).(pulumi.StringOutput) -} - type RegistryAuth struct { // The registry's address (e.g. "docker.io"). Address string `pulumi:"address"` @@ -6253,6 +6056,142 @@ func (o RegistryAuthArrayOutput) Index(i pulumi.IntInput) RegistryAuthOutput { }).(RegistryAuthOutput) } +type SSH struct { + // Useful for distinguishing different servers that are part of the same + // build. + // + // A value of `default` is appropriate if only dealing with a single host. + Id string `pulumi:"id"` + // SSH agent socket or private keys to expose to the build under the given + // identifier. + // + // Defaults to `[$SSH_AUTH_SOCK]`. + // + // Note that your keys are **not** automatically added when using an + // agent. Run `ssh-add -l` locally to confirm which public keys are + // visible to the agent; these will be exposed to your build. + Paths []string `pulumi:"paths"` +} + +// SSHInput is an input type that accepts SSHArgs and SSHOutput values. +// You can construct a concrete instance of `SSHInput` via: +// +// SSHArgs{...} +type SSHInput interface { + pulumi.Input + + ToSSHOutput() SSHOutput + ToSSHOutputWithContext(context.Context) SSHOutput +} + +type SSHArgs struct { + // Useful for distinguishing different servers that are part of the same + // build. + // + // A value of `default` is appropriate if only dealing with a single host. + Id pulumi.StringInput `pulumi:"id"` + // SSH agent socket or private keys to expose to the build under the given + // identifier. + // + // Defaults to `[$SSH_AUTH_SOCK]`. + // + // Note that your keys are **not** automatically added when using an + // agent. Run `ssh-add -l` locally to confirm which public keys are + // visible to the agent; these will be exposed to your build. + Paths pulumi.StringArrayInput `pulumi:"paths"` +} + +func (SSHArgs) ElementType() reflect.Type { + return reflect.TypeOf((*SSH)(nil)).Elem() +} + +func (i SSHArgs) ToSSHOutput() SSHOutput { + return i.ToSSHOutputWithContext(context.Background()) +} + +func (i SSHArgs) ToSSHOutputWithContext(ctx context.Context) SSHOutput { + return pulumi.ToOutputWithContext(ctx, i).(SSHOutput) +} + +// SSHArrayInput is an input type that accepts SSHArray and SSHArrayOutput values. +// You can construct a concrete instance of `SSHArrayInput` via: +// +// SSHArray{ SSHArgs{...} } +type SSHArrayInput interface { + pulumi.Input + + ToSSHArrayOutput() SSHArrayOutput + ToSSHArrayOutputWithContext(context.Context) SSHArrayOutput +} + +type SSHArray []SSHInput + +func (SSHArray) ElementType() reflect.Type { + return reflect.TypeOf((*[]SSH)(nil)).Elem() +} + +func (i SSHArray) ToSSHArrayOutput() SSHArrayOutput { + return i.ToSSHArrayOutputWithContext(context.Background()) +} + +func (i SSHArray) ToSSHArrayOutputWithContext(ctx context.Context) SSHArrayOutput { + return pulumi.ToOutputWithContext(ctx, i).(SSHArrayOutput) +} + +type SSHOutput struct{ *pulumi.OutputState } + +func (SSHOutput) ElementType() reflect.Type { + return reflect.TypeOf((*SSH)(nil)).Elem() +} + +func (o SSHOutput) ToSSHOutput() SSHOutput { + return o +} + +func (o SSHOutput) ToSSHOutputWithContext(ctx context.Context) SSHOutput { + return o +} + +// Useful for distinguishing different servers that are part of the same +// build. +// +// A value of `default` is appropriate if only dealing with a single host. +func (o SSHOutput) Id() pulumi.StringOutput { + return o.ApplyT(func(v SSH) string { return v.Id }).(pulumi.StringOutput) +} + +// SSH agent socket or private keys to expose to the build under the given +// identifier. +// +// Defaults to `[$SSH_AUTH_SOCK]`. +// +// Note that your keys are **not** automatically added when using an +// agent. Run `ssh-add -l` locally to confirm which public keys are +// visible to the agent; these will be exposed to your build. +func (o SSHOutput) Paths() pulumi.StringArrayOutput { + return o.ApplyT(func(v SSH) []string { return v.Paths }).(pulumi.StringArrayOutput) +} + +type SSHArrayOutput struct{ *pulumi.OutputState } + +func (SSHArrayOutput) ElementType() reflect.Type { + return reflect.TypeOf((*[]SSH)(nil)).Elem() +} + +func (o SSHArrayOutput) ToSSHArrayOutput() SSHArrayOutput { + return o +} + +func (o SSHArrayOutput) ToSSHArrayOutputWithContext(ctx context.Context) SSHArrayOutput { + return o +} + +func (o SSHArrayOutput) Index(i pulumi.IntInput) SSHOutput { + return pulumi.All(o, i).ApplyT(func(vs []interface{}) SSH { + return vs[0].([]SSH)[vs[1].(int)] + }).(SSHOutput) +} + func init() { pulumi.RegisterInputType(reflect.TypeOf((*BuildContextInput)(nil)).Elem(), BuildContextArgs{}) pulumi.RegisterInputType(reflect.TypeOf((*BuildContextPtrInput)(nil)).Elem(), BuildContextArgs{}) @@ -6302,11 +6241,10 @@ func init() { pulumi.RegisterInputType(reflect.TypeOf((*ExportRegistryPtrInput)(nil)).Elem(), ExportRegistryArgs{}) pulumi.RegisterInputType(reflect.TypeOf((*ExportTarInput)(nil)).Elem(), ExportTarArgs{}) pulumi.RegisterInputType(reflect.TypeOf((*ExportTarPtrInput)(nil)).Elem(), ExportTarArgs{}) - pulumi.RegisterInputType(reflect.TypeOf((*ManifestInput)(nil)).Elem(), ManifestArgs{}) - pulumi.RegisterInputType(reflect.TypeOf((*ManifestArrayInput)(nil)).Elem(), ManifestArray{}) - pulumi.RegisterInputType(reflect.TypeOf((*ManifestPlatformInput)(nil)).Elem(), ManifestPlatformArgs{}) pulumi.RegisterInputType(reflect.TypeOf((*RegistryAuthInput)(nil)).Elem(), RegistryAuthArgs{}) pulumi.RegisterInputType(reflect.TypeOf((*RegistryAuthArrayInput)(nil)).Elem(), RegistryAuthArray{}) + pulumi.RegisterInputType(reflect.TypeOf((*SSHInput)(nil)).Elem(), SSHArgs{}) + pulumi.RegisterInputType(reflect.TypeOf((*SSHArrayInput)(nil)).Elem(), SSHArray{}) pulumi.RegisterOutputType(BuildContextOutput{}) pulumi.RegisterOutputType(BuildContextPtrOutput{}) pulumi.RegisterOutputType(BuilderConfigOutput{}) @@ -6355,9 +6293,8 @@ func init() { pulumi.RegisterOutputType(ExportRegistryPtrOutput{}) pulumi.RegisterOutputType(ExportTarOutput{}) pulumi.RegisterOutputType(ExportTarPtrOutput{}) - pulumi.RegisterOutputType(ManifestOutput{}) - pulumi.RegisterOutputType(ManifestArrayOutput{}) - pulumi.RegisterOutputType(ManifestPlatformOutput{}) pulumi.RegisterOutputType(RegistryAuthOutput{}) pulumi.RegisterOutputType(RegistryAuthArrayOutput{}) + pulumi.RegisterOutputType(SSHOutput{}) + pulumi.RegisterOutputType(SSHArrayOutput{}) } diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/Image.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/Image.java index 1bff2d86..38198db8 100644 --- a/sdk/java/src/main/java/com/pulumi/docker/buildx/Image.java +++ b/sdk/java/src/main/java/com/pulumi/docker/buildx/Image.java @@ -9,6 +9,7 @@ import com.pulumi.core.internal.Codegen; import com.pulumi.docker.Utilities; import com.pulumi.docker.buildx.ImageArgs; +import com.pulumi.docker.buildx.enums.NetworkMode; import com.pulumi.docker.buildx.enums.Platform; import com.pulumi.docker.buildx.outputs.BuildContext; import com.pulumi.docker.buildx.outputs.BuilderConfig; @@ -17,6 +18,7 @@ import com.pulumi.docker.buildx.outputs.Dockerfile; import com.pulumi.docker.buildx.outputs.ExportEntry; import com.pulumi.docker.buildx.outputs.RegistryAuth; +import com.pulumi.docker.buildx.outputs.SSH; import java.lang.Boolean; import java.lang.String; import java.util.List; @@ -570,6 +572,24 @@ */ @ResourceType(type="docker:buildx/image:Image") public class Image extends com.pulumi.resources.CustomResource { + /** + * Custom `host:ip` mappings to use during the build. + * + * Equivalent to Docker's `--add-host` flag. + * + */ + @Export(name="addHosts", refs={List.class,String.class}, tree="[0,1]") + private Output> addHosts; + + /** + * @return Custom `host:ip` mappings to use during the build. + * + * Equivalent to Docker's `--add-host` flag. + * + */ + public Output>> addHosts() { + return Codegen.optional(this.addHosts); + } /** * `ARG` names and values to set during the build. * @@ -601,16 +621,40 @@ public Output>> buildArgs() { return Codegen.optional(this.buildArgs); } /** - * When `true`, attempt to build the image during previews. The image will - * not be pushed to registries, however caches will still be populated. + * By default, preview behavior depends on the execution environment. If + * Pulumi detects the operation is running on a CI system (GitHub Actions, + * Travis CI, Azure Pipelines, etc.) then it will build images during + * previews as a safeguard. Otherwise, if not running on CI, previews will + * not build images. + * + * Setting this to `false` forces previews to never perform builds, and + * setting it to `true` will always build the image during previews. + * + * Images built during previews are never exported to registries, however + * cache manifests are still exported. + * + * On-disk Dockerfiles are always validated for syntactic correctness + * regardless of this setting. * */ @Export(name="buildOnPreview", refs={Boolean.class}, tree="[0]") private Output buildOnPreview; /** - * @return When `true`, attempt to build the image during previews. The image will - * not be pushed to registries, however caches will still be populated. + * @return By default, preview behavior depends on the execution environment. If + * Pulumi detects the operation is running on a CI system (GitHub Actions, + * Travis CI, Azure Pipelines, etc.) then it will build images during + * previews as a safeguard. Otherwise, if not running on CI, previews will + * not build images. + * + * Setting this to `false` forces previews to never perform builds, and + * setting it to `true` will always build the image during previews. + * + * Images built during previews are never exported to registries, however + * cache manifests are still exported. + * + * On-disk Dockerfiles are always validated for syntactic correctness + * regardless of this setting. * */ public Output> buildOnPreview() { @@ -691,7 +735,7 @@ public Output> context() { * */ @Export(name="contextHash", refs={String.class}, tree="[0]") - private Output contextHash; + private Output contextHash; /** * @return A preliminary hash of the image's build context. @@ -699,22 +743,30 @@ public Output> context() { * Pulumi uses this to determine if an image _may_ need to be re-built. * */ - public Output> contextHash() { - return Codegen.optional(this.contextHash); + public Output contextHash() { + return this.contextHash; } /** - * A mapping of platform type to refs which were pushed to registries. + * A mapping of target names to the SHA256 digest of their pushed manifest. + * + * If no target was specified 'default' is used as the target name. + * + * Pushed manifests can be referenced as `<tag>@<digest>`. * */ - @Export(name="digests", refs={Map.class,String.class,List.class}, tree="[0,1,[2,1]]") - private Output>> digests; + @Export(name="digests", refs={Map.class,String.class}, tree="[0,1,1]") + private Output> digests; /** - * @return A mapping of platform type to refs which were pushed to registries. + * @return A mapping of target names to the SHA256 digest of their pushed manifest. + * + * If no target was specified 'default' is used as the target name. + * + * Pushed manifests can be referenced as `<tag>@<digest>`. * */ - public Output>>> digests() { - return Codegen.optional(this.digests); + public Output> digests() { + return this.digests; } /** * Dockerfile settings. @@ -776,6 +828,68 @@ public Output>> exports() { public Output>> labels() { return Codegen.optional(this.labels); } + /** + * When `true` the build will automatically include a `docker` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--load` flag. + * + */ + @Export(name="load", refs={Boolean.class}, tree="[0]") + private Output load; + + /** + * @return When `true` the build will automatically include a `docker` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--load` flag. + * + */ + public Output> load() { + return Codegen.optional(this.load); + } + /** + * Set the network mode for `RUN` instructions. Defaults to `default`. + * + * For custom networks, configure your builder with `--driver-opt network=...`. + * + * Equivalent to Docker's `--network` flag. + * + */ + @Export(name="network", refs={NetworkMode.class}, tree="[0]") + private Output network; + + /** + * @return Set the network mode for `RUN` instructions. Defaults to `default`. + * + * For custom networks, configure your builder with `--driver-opt network=...`. + * + * Equivalent to Docker's `--network` flag. + * + */ + public Output> network() { + return Codegen.optional(this.network); + } + /** + * Do not import cache manifests when building the image. + * + * Equivalent to Docker's `--no-cache` flag. + * + */ + @Export(name="noCache", refs={Boolean.class}, tree="[0]") + private Output noCache; + + /** + * @return Do not import cache manifests when building the image. + * + * Equivalent to Docker's `--no-cache` flag. + * + */ + public Output> noCache() { + return Codegen.optional(this.noCache); + } /** * Set target platform(s) for the build. Defaults to the host's platform. * @@ -812,6 +926,58 @@ public Output>> platforms() { public Output> pull() { return Codegen.optional(this.pull); } + /** + * When `true` the build will automatically include a `registry` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--push` flag. + * + */ + @Export(name="push", refs={Boolean.class}, tree="[0]") + private Output push; + + /** + * @return When `true` the build will automatically include a `registry` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--push` flag. + * + */ + public Output> push() { + return Codegen.optional(this.push); + } + /** + * If the image was pushed to any registries then this will contain a + * single fully-qualified tag including the build's digest. + * + * This is only for convenience and may not be appropriate for situations + * where multiple tags or registries are involved. In those cases this + * output is not guaranteed to be stable. + * + * For more control over tags consumed by downstream resources you should + * use the `Digests` output. + * + */ + @Export(name="ref", refs={String.class}, tree="[0]") + private Output ref; + + /** + * @return If the image was pushed to any registries then this will contain a + * single fully-qualified tag including the build's digest. + * + * This is only for convenience and may not be appropriate for situations + * where multiple tags or registries are involved. In those cases this + * output is not guaranteed to be stable. + * + * For more control over tags consumed by downstream resources you should + * use the `Digests` output. + * + */ + public Output ref() { + return this.ref; + } /** * Registry credentials. Required if reading or exporting to private * repositories. @@ -868,6 +1034,24 @@ public Output>> registries() { public Output>> secrets() { return Codegen.optional(this.secrets); } + /** + * SSH agent socket or keys to expose to the build. + * + * Equivalent to Docker's `--ssh` flag. + * + */ + @Export(name="ssh", refs={List.class,SSH.class}, tree="[0,1]") + private Output> ssh; + + /** + * @return SSH agent socket or keys to expose to the build. + * + * Equivalent to Docker's `--ssh` flag. + * + */ + public Output>> ssh() { + return Codegen.optional(this.ssh); + } /** * Name and optionally a tag (format: `name:tag`). * @@ -947,9 +1131,6 @@ private Image(String name, Output id, @Nullable com.pulumi.resources.Cus private static com.pulumi.resources.CustomResourceOptions makeResourceOptions(@Nullable com.pulumi.resources.CustomResourceOptions options, @Nullable Output id) { var defaultOptions = com.pulumi.resources.CustomResourceOptions.builder() .version(Utilities.getVersion()) - .additionalSecretOutputs(List.of( - "secrets" - )) .build(); return com.pulumi.resources.CustomResourceOptions.merge(defaultOptions, options, id); } diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/ImageArgs.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/ImageArgs.java index b53352b4..2406a894 100644 --- a/sdk/java/src/main/java/com/pulumi/docker/buildx/ImageArgs.java +++ b/sdk/java/src/main/java/com/pulumi/docker/buildx/ImageArgs.java @@ -5,6 +5,8 @@ import com.pulumi.core.Output; import com.pulumi.core.annotations.Import; +import com.pulumi.core.internal.Codegen; +import com.pulumi.docker.buildx.enums.NetworkMode; import com.pulumi.docker.buildx.enums.Platform; import com.pulumi.docker.buildx.inputs.BuildContextArgs; import com.pulumi.docker.buildx.inputs.BuilderConfigArgs; @@ -13,6 +15,7 @@ import com.pulumi.docker.buildx.inputs.DockerfileArgs; import com.pulumi.docker.buildx.inputs.ExportEntryArgs; import com.pulumi.docker.buildx.inputs.RegistryAuthArgs; +import com.pulumi.docker.buildx.inputs.SSHArgs; import java.lang.Boolean; import java.lang.String; import java.util.List; @@ -26,6 +29,25 @@ public final class ImageArgs extends com.pulumi.resources.ResourceArgs { public static final ImageArgs Empty = new ImageArgs(); + /** + * Custom `host:ip` mappings to use during the build. + * + * Equivalent to Docker's `--add-host` flag. + * + */ + @Import(name="addHosts") + private @Nullable Output> addHosts; + + /** + * @return Custom `host:ip` mappings to use during the build. + * + * Equivalent to Docker's `--add-host` flag. + * + */ + public Optional>> addHosts() { + return Optional.ofNullable(this.addHosts); + } + /** * `ARG` names and values to set during the build. * @@ -58,16 +80,40 @@ public Optional>> buildArgs() { } /** - * When `true`, attempt to build the image during previews. The image will - * not be pushed to registries, however caches will still be populated. + * By default, preview behavior depends on the execution environment. If + * Pulumi detects the operation is running on a CI system (GitHub Actions, + * Travis CI, Azure Pipelines, etc.) then it will build images during + * previews as a safeguard. Otherwise, if not running on CI, previews will + * not build images. + * + * Setting this to `false` forces previews to never perform builds, and + * setting it to `true` will always build the image during previews. + * + * Images built during previews are never exported to registries, however + * cache manifests are still exported. + * + * On-disk Dockerfiles are always validated for syntactic correctness + * regardless of this setting. * */ @Import(name="buildOnPreview") private @Nullable Output buildOnPreview; /** - * @return When `true`, attempt to build the image during previews. The image will - * not be pushed to registries, however caches will still be populated. + * @return By default, preview behavior depends on the execution environment. If + * Pulumi detects the operation is running on a CI system (GitHub Actions, + * Travis CI, Azure Pipelines, etc.) then it will build images during + * previews as a safeguard. Otherwise, if not running on CI, previews will + * not build images. + * + * Setting this to `false` forces previews to never perform builds, and + * setting it to `true` will always build the image during previews. + * + * Images built during previews are never exported to registries, however + * cache manifests are still exported. + * + * On-disk Dockerfiles are always validated for syntactic correctness + * regardless of this setting. * */ public Optional> buildOnPreview() { @@ -209,6 +255,71 @@ public Optional>> labels() { return Optional.ofNullable(this.labels); } + /** + * When `true` the build will automatically include a `docker` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--load` flag. + * + */ + @Import(name="load") + private @Nullable Output load; + + /** + * @return When `true` the build will automatically include a `docker` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--load` flag. + * + */ + public Optional> load() { + return Optional.ofNullable(this.load); + } + + /** + * Set the network mode for `RUN` instructions. Defaults to `default`. + * + * For custom networks, configure your builder with `--driver-opt network=...`. + * + * Equivalent to Docker's `--network` flag. + * + */ + @Import(name="network") + private @Nullable Output network; + + /** + * @return Set the network mode for `RUN` instructions. Defaults to `default`. + * + * For custom networks, configure your builder with `--driver-opt network=...`. + * + * Equivalent to Docker's `--network` flag. + * + */ + public Optional> network() { + return Optional.ofNullable(this.network); + } + + /** + * Do not import cache manifests when building the image. + * + * Equivalent to Docker's `--no-cache` flag. + * + */ + @Import(name="noCache") + private @Nullable Output noCache; + + /** + * @return Do not import cache manifests when building the image. + * + * Equivalent to Docker's `--no-cache` flag. + * + */ + public Optional> noCache() { + return Optional.ofNullable(this.noCache); + } + /** * Set target platform(s) for the build. Defaults to the host's platform. * @@ -247,6 +358,29 @@ public Optional> pull() { return Optional.ofNullable(this.pull); } + /** + * When `true` the build will automatically include a `registry` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--push` flag. + * + */ + @Import(name="push") + private @Nullable Output push; + + /** + * @return When `true` the build will automatically include a `registry` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--push` flag. + * + */ + public Optional> push() { + return Optional.ofNullable(this.push); + } + /** * Registry credentials. Required if reading or exporting to private * repositories. @@ -305,6 +439,25 @@ public Optional>> secrets() { return Optional.ofNullable(this.secrets); } + /** + * SSH agent socket or keys to expose to the build. + * + * Equivalent to Docker's `--ssh` flag. + * + */ + @Import(name="ssh") + private @Nullable Output> ssh; + + /** + * @return SSH agent socket or keys to expose to the build. + * + * Equivalent to Docker's `--ssh` flag. + * + */ + public Optional>> ssh() { + return Optional.ofNullable(this.ssh); + } + /** * Name and optionally a tag (format: `name:tag`). * @@ -356,6 +509,7 @@ public Optional>> targets() { private ImageArgs() {} private ImageArgs(ImageArgs $) { + this.addHosts = $.addHosts; this.buildArgs = $.buildArgs; this.buildOnPreview = $.buildOnPreview; this.builder = $.builder; @@ -365,10 +519,15 @@ private ImageArgs(ImageArgs $) { this.dockerfile = $.dockerfile; this.exports = $.exports; this.labels = $.labels; + this.load = $.load; + this.network = $.network; + this.noCache = $.noCache; this.platforms = $.platforms; this.pull = $.pull; + this.push = $.push; this.registries = $.registries; this.secrets = $.secrets; + this.ssh = $.ssh; this.tags = $.tags; this.targets = $.targets; } @@ -391,6 +550,43 @@ public Builder(ImageArgs defaults) { $ = new ImageArgs(Objects.requireNonNull(defaults)); } + /** + * @param addHosts Custom `host:ip` mappings to use during the build. + * + * Equivalent to Docker's `--add-host` flag. + * + * @return builder + * + */ + public Builder addHosts(@Nullable Output> addHosts) { + $.addHosts = addHosts; + return this; + } + + /** + * @param addHosts Custom `host:ip` mappings to use during the build. + * + * Equivalent to Docker's `--add-host` flag. + * + * @return builder + * + */ + public Builder addHosts(List addHosts) { + return addHosts(Output.of(addHosts)); + } + + /** + * @param addHosts Custom `host:ip` mappings to use during the build. + * + * Equivalent to Docker's `--add-host` flag. + * + * @return builder + * + */ + public Builder addHosts(String... addHosts) { + return addHosts(List.of(addHosts)); + } + /** * @param buildArgs `ARG` names and values to set during the build. * @@ -429,8 +625,20 @@ public Builder buildArgs(Map buildArgs) { } /** - * @param buildOnPreview When `true`, attempt to build the image during previews. The image will - * not be pushed to registries, however caches will still be populated. + * @param buildOnPreview By default, preview behavior depends on the execution environment. If + * Pulumi detects the operation is running on a CI system (GitHub Actions, + * Travis CI, Azure Pipelines, etc.) then it will build images during + * previews as a safeguard. Otherwise, if not running on CI, previews will + * not build images. + * + * Setting this to `false` forces previews to never perform builds, and + * setting it to `true` will always build the image during previews. + * + * Images built during previews are never exported to registries, however + * cache manifests are still exported. + * + * On-disk Dockerfiles are always validated for syntactic correctness + * regardless of this setting. * * @return builder * @@ -441,8 +649,20 @@ public Builder buildOnPreview(@Nullable Output buildOnPreview) { } /** - * @param buildOnPreview When `true`, attempt to build the image during previews. The image will - * not be pushed to registries, however caches will still be populated. + * @param buildOnPreview By default, preview behavior depends on the execution environment. If + * Pulumi detects the operation is running on a CI system (GitHub Actions, + * Travis CI, Azure Pipelines, etc.) then it will build images during + * previews as a safeguard. Otherwise, if not running on CI, previews will + * not build images. + * + * Setting this to `false` forces previews to never perform builds, and + * setting it to `true` will always build the image during previews. + * + * Images built during previews are never exported to registries, however + * cache manifests are still exported. + * + * On-disk Dockerfiles are always validated for syntactic correctness + * regardless of this setting. * * @return builder * @@ -667,6 +887,89 @@ public Builder labels(Map labels) { return labels(Output.of(labels)); } + /** + * @param load When `true` the build will automatically include a `docker` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--load` flag. + * + * @return builder + * + */ + public Builder load(@Nullable Output load) { + $.load = load; + return this; + } + + /** + * @param load When `true` the build will automatically include a `docker` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--load` flag. + * + * @return builder + * + */ + public Builder load(Boolean load) { + return load(Output.of(load)); + } + + /** + * @param network Set the network mode for `RUN` instructions. Defaults to `default`. + * + * For custom networks, configure your builder with `--driver-opt network=...`. + * + * Equivalent to Docker's `--network` flag. + * + * @return builder + * + */ + public Builder network(@Nullable Output network) { + $.network = network; + return this; + } + + /** + * @param network Set the network mode for `RUN` instructions. Defaults to `default`. + * + * For custom networks, configure your builder with `--driver-opt network=...`. + * + * Equivalent to Docker's `--network` flag. + * + * @return builder + * + */ + public Builder network(NetworkMode network) { + return network(Output.of(network)); + } + + /** + * @param noCache Do not import cache manifests when building the image. + * + * Equivalent to Docker's `--no-cache` flag. + * + * @return builder + * + */ + public Builder noCache(@Nullable Output noCache) { + $.noCache = noCache; + return this; + } + + /** + * @param noCache Do not import cache manifests when building the image. + * + * Equivalent to Docker's `--no-cache` flag. + * + * @return builder + * + */ + public Builder noCache(Boolean noCache) { + return noCache(Output.of(noCache)); + } + /** * @param platforms Set target platform(s) for the build. Defaults to the host's platform. * @@ -729,6 +1032,35 @@ public Builder pull(Boolean pull) { return pull(Output.of(pull)); } + /** + * @param push When `true` the build will automatically include a `registry` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--push` flag. + * + * @return builder + * + */ + public Builder push(@Nullable Output push) { + $.push = push; + return this; + } + + /** + * @param push When `true` the build will automatically include a `registry` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--push` flag. + * + * @return builder + * + */ + public Builder push(Boolean push) { + return push(Output.of(push)); + } + /** * @param registries Registry credentials. Required if reading or exporting to private * repositories. @@ -815,6 +1147,43 @@ public Builder secrets(Map secrets) { return secrets(Output.of(secrets)); } + /** + * @param ssh SSH agent socket or keys to expose to the build. + * + * Equivalent to Docker's `--ssh` flag. + * + * @return builder + * + */ + public Builder ssh(@Nullable Output> ssh) { + $.ssh = ssh; + return this; + } + + /** + * @param ssh SSH agent socket or keys to expose to the build. + * + * Equivalent to Docker's `--ssh` flag. + * + * @return builder + * + */ + public Builder ssh(List ssh) { + return ssh(Output.of(ssh)); + } + + /** + * @param ssh SSH agent socket or keys to expose to the build. + * + * Equivalent to Docker's `--ssh` flag. + * + * @return builder + * + */ + public Builder ssh(SSHArgs... ssh) { + return ssh(List.of(ssh)); + } + /** * @param tags Name and optionally a tag (format: `name:tag`). * @@ -905,6 +1274,7 @@ public Builder targets(String... targets) { } public ImageArgs build() { + $.network = Codegen.objectProp("network", NetworkMode.class).output().arg($.network).def(NetworkMode.Default_).getNullable(); return $; } } diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/enums/NetworkMode.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/enums/NetworkMode.java new file mode 100644 index 00000000..707c9e36 --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/docker/buildx/enums/NetworkMode.java @@ -0,0 +1,46 @@ +// *** WARNING: this file was generated by pulumi-java-gen. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +package com.pulumi.docker.buildx.enums; + +import com.pulumi.core.annotations.EnumType; +import java.lang.String; +import java.util.Objects; +import java.util.StringJoiner; + + @EnumType + public enum NetworkMode { + /** + * The default sandbox network mode. + * + */ + Default_("default"), + /** + * Host network mode. + * + */ + Host("host"), + /** + * Disable network access. + * + */ + None("none"); + + private final String value; + + NetworkMode(String value) { + this.value = Objects.requireNonNull(value); + } + + @EnumType.Converter + public String getValue() { + return this.value; + } + + @Override + public String toString() { + return new StringJoiner(", ", "NetworkMode[", "]") + .add("value='" + this.value + "'") + .toString(); + } + } diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/ExportEntryArgs.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/ExportEntryArgs.java index adb18808..7501c12b 100644 --- a/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/ExportEntryArgs.java +++ b/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/ExportEntryArgs.java @@ -11,10 +11,8 @@ import com.pulumi.docker.buildx.inputs.ExportOCIArgs; import com.pulumi.docker.buildx.inputs.ExportRegistryArgs; import com.pulumi.docker.buildx.inputs.ExportTarArgs; -import com.pulumi.docker.buildx.inputs.ManifestArgs; import java.lang.Boolean; import java.lang.String; -import java.util.List; import java.util.Objects; import java.util.Optional; import javax.annotation.Nullable; @@ -84,23 +82,6 @@ public Optional> local() { return Optional.ofNullable(this.local); } - /** - * An output property populated for exporters that pushed image - * manifest(s) to a registry. - * - */ - @Import(name="manifests") - private @Nullable Output> manifests; - - /** - * @return An output property populated for exporters that pushed image - * manifest(s) to a registry. - * - */ - public Optional>> manifests() { - return Optional.ofNullable(this.manifests); - } - /** * Identical to the Docker exporter but uses OCI media types by default. * @@ -170,7 +151,6 @@ private ExportEntryArgs(ExportEntryArgs $) { this.docker = $.docker; this.image = $.image; this.local = $.local; - this.manifests = $.manifests; this.oci = $.oci; this.raw = $.raw; this.registry = $.registry; @@ -279,40 +259,6 @@ public Builder local(ExportLocalArgs local) { return local(Output.of(local)); } - /** - * @param manifests An output property populated for exporters that pushed image - * manifest(s) to a registry. - * - * @return builder - * - */ - public Builder manifests(@Nullable Output> manifests) { - $.manifests = manifests; - return this; - } - - /** - * @param manifests An output property populated for exporters that pushed image - * manifest(s) to a registry. - * - * @return builder - * - */ - public Builder manifests(List manifests) { - return manifests(Output.of(manifests)); - } - - /** - * @param manifests An output property populated for exporters that pushed image - * manifest(s) to a registry. - * - * @return builder - * - */ - public Builder manifests(ManifestArgs... manifests) { - return manifests(List.of(manifests)); - } - /** * @param oci Identical to the Docker exporter but uses OCI media types by default. * diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/ManifestArgs.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/ManifestArgs.java deleted file mode 100644 index 374c19c7..00000000 --- a/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/ManifestArgs.java +++ /dev/null @@ -1,207 +0,0 @@ -// *** WARNING: this file was generated by pulumi-java-gen. *** -// *** Do not edit by hand unless you're certain you know what you are doing! *** - -package com.pulumi.docker.buildx.inputs; - -import com.pulumi.core.Output; -import com.pulumi.core.annotations.Import; -import com.pulumi.docker.buildx.inputs.ManifestPlatformArgs; -import com.pulumi.exceptions.MissingRequiredPropertyException; -import java.lang.Integer; -import java.lang.String; -import java.util.Objects; - - -public final class ManifestArgs extends com.pulumi.resources.ResourceArgs { - - public static final ManifestArgs Empty = new ManifestArgs(); - - /** - * The SHA256 digest of the manifest. - * - */ - @Import(name="digest", required=true) - private Output digest; - - /** - * @return The SHA256 digest of the manifest. - * - */ - public Output digest() { - return this.digest; - } - - /** - * The manifest's platform. - * - */ - @Import(name="platform", required=true) - private Output platform; - - /** - * @return The manifest's platform. - * - */ - public Output platform() { - return this.platform; - } - - /** - * The manifest's canonical ref. - * - */ - @Import(name="ref", required=true) - private Output ref; - - /** - * @return The manifest's canonical ref. - * - */ - public Output ref() { - return this.ref; - } - - /** - * The size of the manifest in bytes. - * - */ - @Import(name="size", required=true) - private Output size; - - /** - * @return The size of the manifest in bytes. - * - */ - public Output size() { - return this.size; - } - - private ManifestArgs() {} - - private ManifestArgs(ManifestArgs $) { - this.digest = $.digest; - this.platform = $.platform; - this.ref = $.ref; - this.size = $.size; - } - - public static Builder builder() { - return new Builder(); - } - public static Builder builder(ManifestArgs defaults) { - return new Builder(defaults); - } - - public static final class Builder { - private ManifestArgs $; - - public Builder() { - $ = new ManifestArgs(); - } - - public Builder(ManifestArgs defaults) { - $ = new ManifestArgs(Objects.requireNonNull(defaults)); - } - - /** - * @param digest The SHA256 digest of the manifest. - * - * @return builder - * - */ - public Builder digest(Output digest) { - $.digest = digest; - return this; - } - - /** - * @param digest The SHA256 digest of the manifest. - * - * @return builder - * - */ - public Builder digest(String digest) { - return digest(Output.of(digest)); - } - - /** - * @param platform The manifest's platform. - * - * @return builder - * - */ - public Builder platform(Output platform) { - $.platform = platform; - return this; - } - - /** - * @param platform The manifest's platform. - * - * @return builder - * - */ - public Builder platform(ManifestPlatformArgs platform) { - return platform(Output.of(platform)); - } - - /** - * @param ref The manifest's canonical ref. - * - * @return builder - * - */ - public Builder ref(Output ref) { - $.ref = ref; - return this; - } - - /** - * @param ref The manifest's canonical ref. - * - * @return builder - * - */ - public Builder ref(String ref) { - return ref(Output.of(ref)); - } - - /** - * @param size The size of the manifest in bytes. - * - * @return builder - * - */ - public Builder size(Output size) { - $.size = size; - return this; - } - - /** - * @param size The size of the manifest in bytes. - * - * @return builder - * - */ - public Builder size(Integer size) { - return size(Output.of(size)); - } - - public ManifestArgs build() { - if ($.digest == null) { - throw new MissingRequiredPropertyException("ManifestArgs", "digest"); - } - if ($.platform == null) { - throw new MissingRequiredPropertyException("ManifestArgs", "platform"); - } - if ($.ref == null) { - throw new MissingRequiredPropertyException("ManifestArgs", "ref"); - } - if ($.size == null) { - throw new MissingRequiredPropertyException("ManifestArgs", "size"); - } - return $; - } - } - -} diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/ManifestPlatformArgs.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/ManifestPlatformArgs.java deleted file mode 100644 index 6b8deb81..00000000 --- a/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/ManifestPlatformArgs.java +++ /dev/null @@ -1,125 +0,0 @@ -// *** WARNING: this file was generated by pulumi-java-gen. *** -// *** Do not edit by hand unless you're certain you know what you are doing! *** - -package com.pulumi.docker.buildx.inputs; - -import com.pulumi.core.Output; -import com.pulumi.core.annotations.Import; -import com.pulumi.exceptions.MissingRequiredPropertyException; -import java.lang.String; -import java.util.Objects; - - -public final class ManifestPlatformArgs extends com.pulumi.resources.ResourceArgs { - - public static final ManifestPlatformArgs Empty = new ManifestPlatformArgs(); - - /** - * The manifest's architecture. - * - */ - @Import(name="architecture", required=true) - private Output architecture; - - /** - * @return The manifest's architecture. - * - */ - public Output architecture() { - return this.architecture; - } - - /** - * The manifest's operating systen. - * - */ - @Import(name="os", required=true) - private Output os; - - /** - * @return The manifest's operating systen. - * - */ - public Output os() { - return this.os; - } - - private ManifestPlatformArgs() {} - - private ManifestPlatformArgs(ManifestPlatformArgs $) { - this.architecture = $.architecture; - this.os = $.os; - } - - public static Builder builder() { - return new Builder(); - } - public static Builder builder(ManifestPlatformArgs defaults) { - return new Builder(defaults); - } - - public static final class Builder { - private ManifestPlatformArgs $; - - public Builder() { - $ = new ManifestPlatformArgs(); - } - - public Builder(ManifestPlatformArgs defaults) { - $ = new ManifestPlatformArgs(Objects.requireNonNull(defaults)); - } - - /** - * @param architecture The manifest's architecture. - * - * @return builder - * - */ - public Builder architecture(Output architecture) { - $.architecture = architecture; - return this; - } - - /** - * @param architecture The manifest's architecture. - * - * @return builder - * - */ - public Builder architecture(String architecture) { - return architecture(Output.of(architecture)); - } - - /** - * @param os The manifest's operating systen. - * - * @return builder - * - */ - public Builder os(Output os) { - $.os = os; - return this; - } - - /** - * @param os The manifest's operating systen. - * - * @return builder - * - */ - public Builder os(String os) { - return os(Output.of(os)); - } - - public ManifestPlatformArgs build() { - if ($.architecture == null) { - throw new MissingRequiredPropertyException("ManifestPlatformArgs", "architecture"); - } - if ($.os == null) { - throw new MissingRequiredPropertyException("ManifestPlatformArgs", "os"); - } - return $; - } - } - -} diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/SSHArgs.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/SSHArgs.java new file mode 100644 index 00000000..33e78b8a --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/docker/buildx/inputs/SSHArgs.java @@ -0,0 +1,182 @@ +// *** WARNING: this file was generated by pulumi-java-gen. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +package com.pulumi.docker.buildx.inputs; + +import com.pulumi.core.Output; +import com.pulumi.core.annotations.Import; +import com.pulumi.exceptions.MissingRequiredPropertyException; +import java.lang.String; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import javax.annotation.Nullable; + + +public final class SSHArgs extends com.pulumi.resources.ResourceArgs { + + public static final SSHArgs Empty = new SSHArgs(); + + /** + * Useful for distinguishing different servers that are part of the same + * build. + * + * A value of `default` is appropriate if only dealing with a single host. + * + */ + @Import(name="id", required=true) + private Output id; + + /** + * @return Useful for distinguishing different servers that are part of the same + * build. + * + * A value of `default` is appropriate if only dealing with a single host. + * + */ + public Output id() { + return this.id; + } + + /** + * SSH agent socket or private keys to expose to the build under the given + * identifier. + * + * Defaults to `[$SSH_AUTH_SOCK]`. + * + * Note that your keys are **not** automatically added when using an + * agent. Run `ssh-add -l` locally to confirm which public keys are + * visible to the agent; these will be exposed to your build. + * + */ + @Import(name="paths") + private @Nullable Output> paths; + + /** + * @return SSH agent socket or private keys to expose to the build under the given + * identifier. + * + * Defaults to `[$SSH_AUTH_SOCK]`. + * + * Note that your keys are **not** automatically added when using an + * agent. Run `ssh-add -l` locally to confirm which public keys are + * visible to the agent; these will be exposed to your build. + * + */ + public Optional>> paths() { + return Optional.ofNullable(this.paths); + } + + private SSHArgs() {} + + private SSHArgs(SSHArgs $) { + this.id = $.id; + this.paths = $.paths; + } + + public static Builder builder() { + return new Builder(); + } + public static Builder builder(SSHArgs defaults) { + return new Builder(defaults); + } + + public static final class Builder { + private SSHArgs $; + + public Builder() { + $ = new SSHArgs(); + } + + public Builder(SSHArgs defaults) { + $ = new SSHArgs(Objects.requireNonNull(defaults)); + } + + /** + * @param id Useful for distinguishing different servers that are part of the same + * build. + * + * A value of `default` is appropriate if only dealing with a single host. + * + * @return builder + * + */ + public Builder id(Output id) { + $.id = id; + return this; + } + + /** + * @param id Useful for distinguishing different servers that are part of the same + * build. + * + * A value of `default` is appropriate if only dealing with a single host. + * + * @return builder + * + */ + public Builder id(String id) { + return id(Output.of(id)); + } + + /** + * @param paths SSH agent socket or private keys to expose to the build under the given + * identifier. + * + * Defaults to `[$SSH_AUTH_SOCK]`. + * + * Note that your keys are **not** automatically added when using an + * agent. Run `ssh-add -l` locally to confirm which public keys are + * visible to the agent; these will be exposed to your build. + * + * @return builder + * + */ + public Builder paths(@Nullable Output> paths) { + $.paths = paths; + return this; + } + + /** + * @param paths SSH agent socket or private keys to expose to the build under the given + * identifier. + * + * Defaults to `[$SSH_AUTH_SOCK]`. + * + * Note that your keys are **not** automatically added when using an + * agent. Run `ssh-add -l` locally to confirm which public keys are + * visible to the agent; these will be exposed to your build. + * + * @return builder + * + */ + public Builder paths(List paths) { + return paths(Output.of(paths)); + } + + /** + * @param paths SSH agent socket or private keys to expose to the build under the given + * identifier. + * + * Defaults to `[$SSH_AUTH_SOCK]`. + * + * Note that your keys are **not** automatically added when using an + * agent. Run `ssh-add -l` locally to confirm which public keys are + * visible to the agent; these will be exposed to your build. + * + * @return builder + * + */ + public Builder paths(String... paths) { + return paths(List.of(paths)); + } + + public SSHArgs build() { + if ($.id == null) { + throw new MissingRequiredPropertyException("SSHArgs", "id"); + } + return $; + } + } + +} diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/ExportEntry.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/ExportEntry.java index a7fbdf62..a17f1481 100644 --- a/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/ExportEntry.java +++ b/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/ExportEntry.java @@ -10,10 +10,8 @@ import com.pulumi.docker.buildx.outputs.ExportOCI; import com.pulumi.docker.buildx.outputs.ExportRegistry; import com.pulumi.docker.buildx.outputs.ExportTar; -import com.pulumi.docker.buildx.outputs.Manifest; import java.lang.Boolean; import java.lang.String; -import java.util.List; import java.util.Objects; import java.util.Optional; import javax.annotation.Nullable; @@ -40,12 +38,6 @@ public final class ExportEntry { * */ private @Nullable ExportLocal local; - /** - * @return An output property populated for exporters that pushed image - * manifest(s) to a registry. - * - */ - private @Nullable List manifests; /** * @return Identical to the Docker exporter but uses OCI media types by default. * @@ -97,14 +89,6 @@ public Optional image() { public Optional local() { return Optional.ofNullable(this.local); } - /** - * @return An output property populated for exporters that pushed image - * manifest(s) to a registry. - * - */ - public List manifests() { - return this.manifests == null ? List.of() : this.manifests; - } /** * @return Identical to the Docker exporter but uses OCI media types by default. * @@ -148,7 +132,6 @@ public static final class Builder { private @Nullable ExportDocker docker; private @Nullable ExportImage image; private @Nullable ExportLocal local; - private @Nullable List manifests; private @Nullable ExportOCI oci; private @Nullable String raw; private @Nullable ExportRegistry registry; @@ -160,7 +143,6 @@ public Builder(ExportEntry defaults) { this.docker = defaults.docker; this.image = defaults.image; this.local = defaults.local; - this.manifests = defaults.manifests; this.oci = defaults.oci; this.raw = defaults.raw; this.registry = defaults.registry; @@ -192,15 +174,6 @@ public Builder local(@Nullable ExportLocal local) { return this; } @CustomType.Setter - public Builder manifests(@Nullable List manifests) { - - this.manifests = manifests; - return this; - } - public Builder manifests(Manifest... manifests) { - return manifests(List.of(manifests)); - } - @CustomType.Setter public Builder oci(@Nullable ExportOCI oci) { this.oci = oci; @@ -230,7 +203,6 @@ public ExportEntry build() { _resultValue.docker = docker; _resultValue.image = image; _resultValue.local = local; - _resultValue.manifests = manifests; _resultValue.oci = oci; _resultValue.raw = raw; _resultValue.registry = registry; diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/Manifest.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/Manifest.java deleted file mode 100644 index 7635db5b..00000000 --- a/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/Manifest.java +++ /dev/null @@ -1,129 +0,0 @@ -// *** WARNING: this file was generated by pulumi-java-gen. *** -// *** Do not edit by hand unless you're certain you know what you are doing! *** - -package com.pulumi.docker.buildx.outputs; - -import com.pulumi.core.annotations.CustomType; -import com.pulumi.docker.buildx.outputs.ManifestPlatform; -import com.pulumi.exceptions.MissingRequiredPropertyException; -import java.lang.Integer; -import java.lang.String; -import java.util.Objects; - -@CustomType -public final class Manifest { - /** - * @return The SHA256 digest of the manifest. - * - */ - private String digest; - /** - * @return The manifest's platform. - * - */ - private ManifestPlatform platform; - /** - * @return The manifest's canonical ref. - * - */ - private String ref; - /** - * @return The size of the manifest in bytes. - * - */ - private Integer size; - - private Manifest() {} - /** - * @return The SHA256 digest of the manifest. - * - */ - public String digest() { - return this.digest; - } - /** - * @return The manifest's platform. - * - */ - public ManifestPlatform platform() { - return this.platform; - } - /** - * @return The manifest's canonical ref. - * - */ - public String ref() { - return this.ref; - } - /** - * @return The size of the manifest in bytes. - * - */ - public Integer size() { - return this.size; - } - - public static Builder builder() { - return new Builder(); - } - - public static Builder builder(Manifest defaults) { - return new Builder(defaults); - } - @CustomType.Builder - public static final class Builder { - private String digest; - private ManifestPlatform platform; - private String ref; - private Integer size; - public Builder() {} - public Builder(Manifest defaults) { - Objects.requireNonNull(defaults); - this.digest = defaults.digest; - this.platform = defaults.platform; - this.ref = defaults.ref; - this.size = defaults.size; - } - - @CustomType.Setter - public Builder digest(String digest) { - if (digest == null) { - throw new MissingRequiredPropertyException("Manifest", "digest"); - } - this.digest = digest; - return this; - } - @CustomType.Setter - public Builder platform(ManifestPlatform platform) { - if (platform == null) { - throw new MissingRequiredPropertyException("Manifest", "platform"); - } - this.platform = platform; - return this; - } - @CustomType.Setter - public Builder ref(String ref) { - if (ref == null) { - throw new MissingRequiredPropertyException("Manifest", "ref"); - } - this.ref = ref; - return this; - } - @CustomType.Setter - public Builder size(Integer size) { - if (size == null) { - throw new MissingRequiredPropertyException("Manifest", "size"); - } - this.size = size; - return this; - } - public Manifest build() { - final var _resultValue = new Manifest(); - _resultValue.digest = digest; - _resultValue.platform = platform; - _resultValue.ref = ref; - _resultValue.size = size; - return _resultValue; - } - } -} diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/ManifestPlatform.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/ManifestPlatform.java deleted file mode 100644 index f96447e3..00000000 --- a/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/ManifestPlatform.java +++ /dev/null @@ -1,81 +0,0 @@ -// *** WARNING: this file was generated by pulumi-java-gen. *** -// *** Do not edit by hand unless you're certain you know what you are doing! *** - -package com.pulumi.docker.buildx.outputs; - -import com.pulumi.core.annotations.CustomType; -import com.pulumi.exceptions.MissingRequiredPropertyException; -import java.lang.String; -import java.util.Objects; - -@CustomType -public final class ManifestPlatform { - /** - * @return The manifest's architecture. - * - */ - private String architecture; - /** - * @return The manifest's operating systen. - * - */ - private String os; - - private ManifestPlatform() {} - /** - * @return The manifest's architecture. - * - */ - public String architecture() { - return this.architecture; - } - /** - * @return The manifest's operating systen. - * - */ - public String os() { - return this.os; - } - - public static Builder builder() { - return new Builder(); - } - - public static Builder builder(ManifestPlatform defaults) { - return new Builder(defaults); - } - @CustomType.Builder - public static final class Builder { - private String architecture; - private String os; - public Builder() {} - public Builder(ManifestPlatform defaults) { - Objects.requireNonNull(defaults); - this.architecture = defaults.architecture; - this.os = defaults.os; - } - - @CustomType.Setter - public Builder architecture(String architecture) { - if (architecture == null) { - throw new MissingRequiredPropertyException("ManifestPlatform", "architecture"); - } - this.architecture = architecture; - return this; - } - @CustomType.Setter - public Builder os(String os) { - if (os == null) { - throw new MissingRequiredPropertyException("ManifestPlatform", "os"); - } - this.os = os; - return this; - } - public ManifestPlatform build() { - final var _resultValue = new ManifestPlatform(); - _resultValue.architecture = architecture; - _resultValue.os = os; - return _resultValue; - } - } -} diff --git a/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/SSH.java b/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/SSH.java new file mode 100644 index 00000000..50289939 --- /dev/null +++ b/sdk/java/src/main/java/com/pulumi/docker/buildx/outputs/SSH.java @@ -0,0 +1,104 @@ +// *** WARNING: this file was generated by pulumi-java-gen. *** +// *** Do not edit by hand unless you're certain you know what you are doing! *** + +package com.pulumi.docker.buildx.outputs; + +import com.pulumi.core.annotations.CustomType; +import com.pulumi.exceptions.MissingRequiredPropertyException; +import java.lang.String; +import java.util.List; +import java.util.Objects; +import javax.annotation.Nullable; + +@CustomType +public final class SSH { + /** + * @return Useful for distinguishing different servers that are part of the same + * build. + * + * A value of `default` is appropriate if only dealing with a single host. + * + */ + private String id; + /** + * @return SSH agent socket or private keys to expose to the build under the given + * identifier. + * + * Defaults to `[$SSH_AUTH_SOCK]`. + * + * Note that your keys are **not** automatically added when using an + * agent. Run `ssh-add -l` locally to confirm which public keys are + * visible to the agent; these will be exposed to your build. + * + */ + private @Nullable List paths; + + private SSH() {} + /** + * @return Useful for distinguishing different servers that are part of the same + * build. + * + * A value of `default` is appropriate if only dealing with a single host. + * + */ + public String id() { + return this.id; + } + /** + * @return SSH agent socket or private keys to expose to the build under the given + * identifier. + * + * Defaults to `[$SSH_AUTH_SOCK]`. + * + * Note that your keys are **not** automatically added when using an + * agent. Run `ssh-add -l` locally to confirm which public keys are + * visible to the agent; these will be exposed to your build. + * + */ + public List paths() { + return this.paths == null ? List.of() : this.paths; + } + + public static Builder builder() { + return new Builder(); + } + + public static Builder builder(SSH defaults) { + return new Builder(defaults); + } + @CustomType.Builder + public static final class Builder { + private String id; + private @Nullable List paths; + public Builder() {} + public Builder(SSH defaults) { + Objects.requireNonNull(defaults); + this.id = defaults.id; + this.paths = defaults.paths; + } + + @CustomType.Setter + public Builder id(String id) { + if (id == null) { + throw new MissingRequiredPropertyException("SSH", "id"); + } + this.id = id; + return this; + } + @CustomType.Setter + public Builder paths(@Nullable List paths) { + + this.paths = paths; + return this; + } + public Builder paths(String... paths) { + return paths(List.of(paths)); + } + public SSH build() { + final var _resultValue = new SSH(); + _resultValue.id = id; + _resultValue.paths = paths; + return _resultValue; + } + } +} diff --git a/sdk/nodejs/buildx/image.ts b/sdk/nodejs/buildx/image.ts index c3a92a55..62ac37c6 100644 --- a/sdk/nodejs/buildx/image.ts +++ b/sdk/nodejs/buildx/image.ts @@ -470,6 +470,12 @@ export class Image extends pulumi.CustomResource { return obj['__pulumiType'] === Image.__pulumiType; } + /** + * Custom `host:ip` mappings to use during the build. + * + * Equivalent to Docker's `--add-host` flag. + */ + public readonly addHosts!: pulumi.Output; /** * `ARG` names and values to set during the build. * @@ -483,8 +489,20 @@ export class Image extends pulumi.CustomResource { */ public readonly buildArgs!: pulumi.Output<{[key: string]: string} | undefined>; /** - * When `true`, attempt to build the image during previews. The image will - * not be pushed to registries, however caches will still be populated. + * By default, preview behavior depends on the execution environment. If + * Pulumi detects the operation is running on a CI system (GitHub Actions, + * Travis CI, Azure Pipelines, etc.) then it will build images during + * previews as a safeguard. Otherwise, if not running on CI, previews will + * not build images. + * + * Setting this to `false` forces previews to never perform builds, and + * setting it to `true` will always build the image during previews. + * + * Images built during previews are never exported to registries, however + * cache manifests are still exported. + * + * On-disk Dockerfiles are always validated for syntactic correctness + * regardless of this setting. */ public readonly buildOnPreview!: pulumi.Output; /** @@ -514,11 +532,15 @@ export class Image extends pulumi.CustomResource { * * Pulumi uses this to determine if an image _may_ need to be re-built. */ - public /*out*/ readonly contextHash!: pulumi.Output; + public /*out*/ readonly contextHash!: pulumi.Output; /** - * A mapping of platform type to refs which were pushed to registries. + * A mapping of target names to the SHA256 digest of their pushed manifest. + * + * If no target was specified 'default' is used as the target name. + * + * Pushed manifests can be referenced as `@`. */ - public /*out*/ readonly digests!: pulumi.Output<{[key: string]: string[]} | undefined>; + public /*out*/ readonly digests!: pulumi.Output<{[key: string]: string}>; /** * Dockerfile settings. * @@ -540,6 +562,28 @@ export class Image extends pulumi.CustomResource { * Equivalent to Docker's `--label` flag. */ public readonly labels!: pulumi.Output<{[key: string]: string} | undefined>; + /** + * When `true` the build will automatically include a `docker` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--load` flag. + */ + public readonly load!: pulumi.Output; + /** + * Set the network mode for `RUN` instructions. Defaults to `default`. + * + * For custom networks, configure your builder with `--driver-opt network=...`. + * + * Equivalent to Docker's `--network` flag. + */ + public readonly network!: pulumi.Output; + /** + * Do not import cache manifests when building the image. + * + * Equivalent to Docker's `--no-cache` flag. + */ + public readonly noCache!: pulumi.Output; /** * Set target platform(s) for the build. Defaults to the host's platform. * @@ -552,6 +596,26 @@ export class Image extends pulumi.CustomResource { * Equivalent to Docker's `--pull` flag. */ public readonly pull!: pulumi.Output; + /** + * When `true` the build will automatically include a `registry` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--push` flag. + */ + public readonly push!: pulumi.Output; + /** + * If the image was pushed to any registries then this will contain a + * single fully-qualified tag including the build's digest. + * + * This is only for convenience and may not be appropriate for situations + * where multiple tags or registries are involved. In those cases this + * output is not guaranteed to be stable. + * + * For more control over tags consumed by downstream resources you should + * use the `Digests` output. + */ + public /*out*/ readonly ref!: pulumi.Output; /** * Registry credentials. Required if reading or exporting to private * repositories. @@ -574,6 +638,12 @@ export class Image extends pulumi.CustomResource { * Similar to Docker's `--secret` flag. */ public readonly secrets!: pulumi.Output<{[key: string]: string} | undefined>; + /** + * SSH agent socket or keys to expose to the build. + * + * Equivalent to Docker's `--ssh` flag. + */ + public readonly ssh!: pulumi.Output; /** * Name and optionally a tag (format: `name:tag`). * @@ -603,6 +673,7 @@ export class Image extends pulumi.CustomResource { let resourceInputs: pulumi.Inputs = {}; opts = opts || {}; if (!opts.id) { + resourceInputs["addHosts"] = args ? args.addHosts : undefined; resourceInputs["buildArgs"] = args ? args.buildArgs : undefined; resourceInputs["buildOnPreview"] = args ? args.buildOnPreview : undefined; resourceInputs["builder"] = args ? args.builder : undefined; @@ -612,15 +683,22 @@ export class Image extends pulumi.CustomResource { resourceInputs["dockerfile"] = args ? args.dockerfile : undefined; resourceInputs["exports"] = args ? args.exports : undefined; resourceInputs["labels"] = args ? args.labels : undefined; + resourceInputs["load"] = args ? args.load : undefined; + resourceInputs["network"] = (args ? args.network : undefined) ?? "default"; + resourceInputs["noCache"] = args ? args.noCache : undefined; resourceInputs["platforms"] = args ? args.platforms : undefined; resourceInputs["pull"] = args ? args.pull : undefined; + resourceInputs["push"] = args ? args.push : undefined; resourceInputs["registries"] = args ? args.registries : undefined; - resourceInputs["secrets"] = args?.secrets ? pulumi.secret(args.secrets) : undefined; + resourceInputs["secrets"] = args ? args.secrets : undefined; + resourceInputs["ssh"] = args ? args.ssh : undefined; resourceInputs["tags"] = args ? args.tags : undefined; resourceInputs["targets"] = args ? args.targets : undefined; resourceInputs["contextHash"] = undefined /*out*/; resourceInputs["digests"] = undefined /*out*/; + resourceInputs["ref"] = undefined /*out*/; } else { + resourceInputs["addHosts"] = undefined /*out*/; resourceInputs["buildArgs"] = undefined /*out*/; resourceInputs["buildOnPreview"] = undefined /*out*/; resourceInputs["builder"] = undefined /*out*/; @@ -632,16 +710,20 @@ export class Image extends pulumi.CustomResource { resourceInputs["dockerfile"] = undefined /*out*/; resourceInputs["exports"] = undefined /*out*/; resourceInputs["labels"] = undefined /*out*/; + resourceInputs["load"] = undefined /*out*/; + resourceInputs["network"] = undefined /*out*/; + resourceInputs["noCache"] = undefined /*out*/; resourceInputs["platforms"] = undefined /*out*/; resourceInputs["pull"] = undefined /*out*/; + resourceInputs["push"] = undefined /*out*/; + resourceInputs["ref"] = undefined /*out*/; resourceInputs["registries"] = undefined /*out*/; resourceInputs["secrets"] = undefined /*out*/; + resourceInputs["ssh"] = undefined /*out*/; resourceInputs["tags"] = undefined /*out*/; resourceInputs["targets"] = undefined /*out*/; } opts = pulumi.mergeOptions(utilities.resourceOptsDefaults(), opts); - const secretOpts = { additionalSecretOutputs: ["secrets"] }; - opts = pulumi.mergeOptions(opts, secretOpts); super(Image.__pulumiType, name, resourceInputs, opts); } } @@ -650,6 +732,12 @@ export class Image extends pulumi.CustomResource { * The set of arguments for constructing a Image resource. */ export interface ImageArgs { + /** + * Custom `host:ip` mappings to use during the build. + * + * Equivalent to Docker's `--add-host` flag. + */ + addHosts?: pulumi.Input[]>; /** * `ARG` names and values to set during the build. * @@ -663,8 +751,20 @@ export interface ImageArgs { */ buildArgs?: pulumi.Input<{[key: string]: pulumi.Input}>; /** - * When `true`, attempt to build the image during previews. The image will - * not be pushed to registries, however caches will still be populated. + * By default, preview behavior depends on the execution environment. If + * Pulumi detects the operation is running on a CI system (GitHub Actions, + * Travis CI, Azure Pipelines, etc.) then it will build images during + * previews as a safeguard. Otherwise, if not running on CI, previews will + * not build images. + * + * Setting this to `false` forces previews to never perform builds, and + * setting it to `true` will always build the image during previews. + * + * Images built during previews are never exported to registries, however + * cache manifests are still exported. + * + * On-disk Dockerfiles are always validated for syntactic correctness + * regardless of this setting. */ buildOnPreview?: pulumi.Input; /** @@ -710,6 +810,28 @@ export interface ImageArgs { * Equivalent to Docker's `--label` flag. */ labels?: pulumi.Input<{[key: string]: pulumi.Input}>; + /** + * When `true` the build will automatically include a `docker` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--load` flag. + */ + load?: pulumi.Input; + /** + * Set the network mode for `RUN` instructions. Defaults to `default`. + * + * For custom networks, configure your builder with `--driver-opt network=...`. + * + * Equivalent to Docker's `--network` flag. + */ + network?: pulumi.Input; + /** + * Do not import cache manifests when building the image. + * + * Equivalent to Docker's `--no-cache` flag. + */ + noCache?: pulumi.Input; /** * Set target platform(s) for the build. Defaults to the host's platform. * @@ -722,6 +844,14 @@ export interface ImageArgs { * Equivalent to Docker's `--pull` flag. */ pull?: pulumi.Input; + /** + * When `true` the build will automatically include a `registry` export. + * + * Defaults to `false`. + * + * Equivalent to Docker's `--push` flag. + */ + push?: pulumi.Input; /** * Registry credentials. Required if reading or exporting to private * repositories. @@ -744,6 +874,12 @@ export interface ImageArgs { * Similar to Docker's `--secret` flag. */ secrets?: pulumi.Input<{[key: string]: pulumi.Input}>; + /** + * SSH agent socket or keys to expose to the build. + * + * Equivalent to Docker's `--ssh` flag. + */ + ssh?: pulumi.Input[]>; /** * Name and optionally a tag (format: `name:tag`). * diff --git a/sdk/nodejs/types/enums/buildx/index.ts b/sdk/nodejs/types/enums/buildx/index.ts index c5215764..00c5847d 100644 --- a/sdk/nodejs/types/enums/buildx/index.ts +++ b/sdk/nodejs/types/enums/buildx/index.ts @@ -32,6 +32,23 @@ export const CompressionType = { export type CompressionType = (typeof CompressionType)[keyof typeof CompressionType]; +export const NetworkMode = { + /** + * The default sandbox network mode. + */ + Default: "default", + /** + * Host network mode. + */ + Host: "host", + /** + * Disable network access. + */ + None: "none", +} as const; + +export type NetworkMode = (typeof NetworkMode)[keyof typeof NetworkMode]; + export const Platform = { Darwin_386: "darwin/386", Darwin_amd64: "darwin/amd64", diff --git a/sdk/nodejs/types/input.ts b/sdk/nodejs/types/input.ts index 2ffc68af..58ba745b 100644 --- a/sdk/nodejs/types/input.ts +++ b/sdk/nodejs/types/input.ts @@ -1877,11 +1877,6 @@ export namespace buildx { * Export to a local directory as files and directories. */ local?: pulumi.Input; - /** - * An output property populated for exporters that pushed image - * manifest(s) to a registry. - */ - manifests?: pulumi.Input[]>; /** * Identical to the Docker exporter but uses OCI media types by default. */ @@ -2126,36 +2121,6 @@ export namespace buildx { dest: pulumi.Input; } - export interface Manifest { - /** - * The SHA256 digest of the manifest. - */ - digest: pulumi.Input; - /** - * The manifest's platform. - */ - platform: pulumi.Input; - /** - * The manifest's canonical ref. - */ - ref: pulumi.Input; - /** - * The size of the manifest in bytes. - */ - size: pulumi.Input; - } - - export interface ManifestPlatform { - /** - * The manifest's architecture. - */ - architecture: pulumi.Input; - /** - * The manifest's operating systen. - */ - os: pulumi.Input; - } - export interface RegistryAuth { /** * The registry's address (e.g. "docker.io"). @@ -2170,6 +2135,27 @@ export namespace buildx { */ username?: pulumi.Input; } + + export interface SSH { + /** + * Useful for distinguishing different servers that are part of the same + * build. + * + * A value of `default` is appropriate if only dealing with a single host. + */ + id: pulumi.Input; + /** + * SSH agent socket or private keys to expose to the build under the given + * identifier. + * + * Defaults to `[$SSH_AUTH_SOCK]`. + * + * Note that your keys are **not** automatically added when using an + * agent. Run `ssh-add -l` locally to confirm which public keys are + * visible to the agent; these will be exposed to your build. + */ + paths?: pulumi.Input[]>; + } } export namespace config { diff --git a/sdk/nodejs/types/output.ts b/sdk/nodejs/types/output.ts index 3d322d6d..d3f8f652 100644 --- a/sdk/nodejs/types/output.ts +++ b/sdk/nodejs/types/output.ts @@ -1803,11 +1803,6 @@ export namespace buildx { * Export to a local directory as files and directories. */ local?: outputs.buildx.ExportLocal; - /** - * An output property populated for exporters that pushed image - * manifest(s) to a registry. - */ - manifests?: outputs.buildx.Manifest[]; /** * Identical to the Docker exporter but uses OCI media types by default. */ @@ -2052,36 +2047,6 @@ export namespace buildx { dest: string; } - export interface Manifest { - /** - * The SHA256 digest of the manifest. - */ - digest: string; - /** - * The manifest's platform. - */ - platform: outputs.buildx.ManifestPlatform; - /** - * The manifest's canonical ref. - */ - ref: string; - /** - * The size of the manifest in bytes. - */ - size: number; - } - - export interface ManifestPlatform { - /** - * The manifest's architecture. - */ - architecture: string; - /** - * The manifest's operating systen. - */ - os: string; - } - export interface RegistryAuth { /** * The registry's address (e.g. "docker.io"). @@ -2097,6 +2062,27 @@ export namespace buildx { username?: string; } + export interface SSH { + /** + * Useful for distinguishing different servers that are part of the same + * build. + * + * A value of `default` is appropriate if only dealing with a single host. + */ + id: string; + /** + * SSH agent socket or private keys to expose to the build under the given + * identifier. + * + * Defaults to `[$SSH_AUTH_SOCK]`. + * + * Note that your keys are **not** automatically added when using an + * agent. Run `ssh-add -l` locally to confirm which public keys are + * visible to the agent; these will be exposed to your build. + */ + paths?: string[]; + } + } export namespace config { diff --git a/sdk/python/pulumi_docker/buildx/_enums.py b/sdk/python/pulumi_docker/buildx/_enums.py index 8bfd91af..e3281503 100644 --- a/sdk/python/pulumi_docker/buildx/_enums.py +++ b/sdk/python/pulumi_docker/buildx/_enums.py @@ -7,6 +7,7 @@ __all__ = [ 'CacheMode', 'CompressionType', + 'NetworkMode', 'Platform', ] @@ -37,6 +38,21 @@ class CompressionType(str, Enum): """ +class NetworkMode(str, Enum): + DEFAULT = "default" + """ + The default sandbox network mode. + """ + HOST = "host" + """ + Host network mode. + """ + NONE = "none" + """ + Disable network access. + """ + + class Platform(str, Enum): DARWIN_386 = "darwin/386" DARWIN_AMD64 = "darwin/amd64" diff --git a/sdk/python/pulumi_docker/buildx/_inputs.py b/sdk/python/pulumi_docker/buildx/_inputs.py index 41e983dd..5f3e07ff 100644 --- a/sdk/python/pulumi_docker/buildx/_inputs.py +++ b/sdk/python/pulumi_docker/buildx/_inputs.py @@ -35,9 +35,8 @@ 'ExportOCIArgs', 'ExportRegistryArgs', 'ExportTarArgs', - 'ManifestPlatformArgs', - 'ManifestArgs', 'RegistryAuthArgs', + 'SSHArgs', ] @pulumi.input_type @@ -1726,7 +1725,6 @@ def __init__(__self__, *, docker: Optional[pulumi.Input['ExportDockerArgs']] = None, image: Optional[pulumi.Input['ExportImageArgs']] = None, local: Optional[pulumi.Input['ExportLocalArgs']] = None, - manifests: Optional[pulumi.Input[Sequence[pulumi.Input['ManifestArgs']]]] = None, oci: Optional[pulumi.Input['ExportOCIArgs']] = None, raw: Optional[pulumi.Input[str]] = None, registry: Optional[pulumi.Input['ExportRegistryArgs']] = None, @@ -1736,8 +1734,6 @@ def __init__(__self__, *, :param pulumi.Input['ExportDockerArgs'] docker: Export as a Docker image layout. :param pulumi.Input['ExportImageArgs'] image: Outputs the build result into a container image format. :param pulumi.Input['ExportLocalArgs'] local: Export to a local directory as files and directories. - :param pulumi.Input[Sequence[pulumi.Input['ManifestArgs']]] manifests: An output property populated for exporters that pushed image - manifest(s) to a registry. :param pulumi.Input['ExportOCIArgs'] oci: Identical to the Docker exporter but uses OCI media types by default. :param pulumi.Input[str] raw: A raw string as you would provide it to the Docker CLI (e.g., `type=docker`) @@ -1752,8 +1748,6 @@ def __init__(__self__, *, pulumi.set(__self__, "image", image) if local is not None: pulumi.set(__self__, "local", local) - if manifests is not None: - pulumi.set(__self__, "manifests", manifests) if oci is not None: pulumi.set(__self__, "oci", oci) if raw is not None: @@ -1811,19 +1805,6 @@ def local(self) -> Optional[pulumi.Input['ExportLocalArgs']]: def local(self, value: Optional[pulumi.Input['ExportLocalArgs']]): pulumi.set(self, "local", value) - @property - @pulumi.getter - def manifests(self) -> Optional[pulumi.Input[Sequence[pulumi.Input['ManifestArgs']]]]: - """ - An output property populated for exporters that pushed image - manifest(s) to a registry. - """ - return pulumi.get(self, "manifests") - - @manifests.setter - def manifests(self, value: Optional[pulumi.Input[Sequence[pulumi.Input['ManifestArgs']]]]): - pulumi.set(self, "manifests", value) - @property @pulumi.getter def oci(self) -> Optional[pulumi.Input['ExportOCIArgs']]: @@ -2543,110 +2524,6 @@ def dest(self, value: pulumi.Input[str]): pulumi.set(self, "dest", value) -@pulumi.input_type -class ManifestPlatformArgs: - def __init__(__self__, *, - architecture: pulumi.Input[str], - os: pulumi.Input[str]): - """ - :param pulumi.Input[str] architecture: The manifest's architecture. - :param pulumi.Input[str] os: The manifest's operating systen. - """ - pulumi.set(__self__, "architecture", architecture) - pulumi.set(__self__, "os", os) - - @property - @pulumi.getter - def architecture(self) -> pulumi.Input[str]: - """ - The manifest's architecture. - """ - return pulumi.get(self, "architecture") - - @architecture.setter - def architecture(self, value: pulumi.Input[str]): - pulumi.set(self, "architecture", value) - - @property - @pulumi.getter - def os(self) -> pulumi.Input[str]: - """ - The manifest's operating systen. - """ - return pulumi.get(self, "os") - - @os.setter - def os(self, value: pulumi.Input[str]): - pulumi.set(self, "os", value) - - -@pulumi.input_type -class ManifestArgs: - def __init__(__self__, *, - digest: pulumi.Input[str], - platform: pulumi.Input['ManifestPlatformArgs'], - ref: pulumi.Input[str], - size: pulumi.Input[int]): - """ - :param pulumi.Input[str] digest: The SHA256 digest of the manifest. - :param pulumi.Input['ManifestPlatformArgs'] platform: The manifest's platform. - :param pulumi.Input[str] ref: The manifest's canonical ref. - :param pulumi.Input[int] size: The size of the manifest in bytes. - """ - pulumi.set(__self__, "digest", digest) - pulumi.set(__self__, "platform", platform) - pulumi.set(__self__, "ref", ref) - pulumi.set(__self__, "size", size) - - @property - @pulumi.getter - def digest(self) -> pulumi.Input[str]: - """ - The SHA256 digest of the manifest. - """ - return pulumi.get(self, "digest") - - @digest.setter - def digest(self, value: pulumi.Input[str]): - pulumi.set(self, "digest", value) - - @property - @pulumi.getter - def platform(self) -> pulumi.Input['ManifestPlatformArgs']: - """ - The manifest's platform. - """ - return pulumi.get(self, "platform") - - @platform.setter - def platform(self, value: pulumi.Input['ManifestPlatformArgs']): - pulumi.set(self, "platform", value) - - @property - @pulumi.getter - def ref(self) -> pulumi.Input[str]: - """ - The manifest's canonical ref. - """ - return pulumi.get(self, "ref") - - @ref.setter - def ref(self, value: pulumi.Input[str]): - pulumi.set(self, "ref", value) - - @property - @pulumi.getter - def size(self) -> pulumi.Input[int]: - """ - The size of the manifest in bytes. - """ - return pulumi.get(self, "size") - - @size.setter - def size(self, value: pulumi.Input[int]): - pulumi.set(self, "size", value) - - @pulumi.input_type class RegistryAuthArgs: def __init__(__self__, *, @@ -2701,3 +2578,61 @@ def username(self, value: Optional[pulumi.Input[str]]): pulumi.set(self, "username", value) +@pulumi.input_type +class SSHArgs: + def __init__(__self__, *, + id: pulumi.Input[str], + paths: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None): + """ + :param pulumi.Input[str] id: Useful for distinguishing different servers that are part of the same + build. + + A value of `default` is appropriate if only dealing with a single host. + :param pulumi.Input[Sequence[pulumi.Input[str]]] paths: SSH agent socket or private keys to expose to the build under the given + identifier. + + Defaults to `[$SSH_AUTH_SOCK]`. + + Note that your keys are **not** automatically added when using an + agent. Run `ssh-add -l` locally to confirm which public keys are + visible to the agent; these will be exposed to your build. + """ + pulumi.set(__self__, "id", id) + if paths is not None: + pulumi.set(__self__, "paths", paths) + + @property + @pulumi.getter + def id(self) -> pulumi.Input[str]: + """ + Useful for distinguishing different servers that are part of the same + build. + + A value of `default` is appropriate if only dealing with a single host. + """ + return pulumi.get(self, "id") + + @id.setter + def id(self, value: pulumi.Input[str]): + pulumi.set(self, "id", value) + + @property + @pulumi.getter + def paths(self) -> Optional[pulumi.Input[Sequence[pulumi.Input[str]]]]: + """ + SSH agent socket or private keys to expose to the build under the given + identifier. + + Defaults to `[$SSH_AUTH_SOCK]`. + + Note that your keys are **not** automatically added when using an + agent. Run `ssh-add -l` locally to confirm which public keys are + visible to the agent; these will be exposed to your build. + """ + return pulumi.get(self, "paths") + + @paths.setter + def paths(self, value: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]]): + pulumi.set(self, "paths", value) + + diff --git a/sdk/python/pulumi_docker/buildx/image.py b/sdk/python/pulumi_docker/buildx/image.py index f5e7bd5e..cfcf7a29 100644 --- a/sdk/python/pulumi_docker/buildx/image.py +++ b/sdk/python/pulumi_docker/buildx/image.py @@ -17,6 +17,7 @@ @pulumi.input_type class ImageArgs: def __init__(__self__, *, + add_hosts: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, build_args: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, build_on_preview: Optional[pulumi.Input[bool]] = None, builder: Optional[pulumi.Input['BuilderConfigArgs']] = None, @@ -26,14 +27,22 @@ def __init__(__self__, *, dockerfile: Optional[pulumi.Input['DockerfileArgs']] = None, exports: Optional[pulumi.Input[Sequence[pulumi.Input['ExportEntryArgs']]]] = None, labels: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, + load: Optional[pulumi.Input[bool]] = None, + network: Optional[pulumi.Input['NetworkMode']] = None, + no_cache: Optional[pulumi.Input[bool]] = None, platforms: Optional[pulumi.Input[Sequence[pulumi.Input['Platform']]]] = None, pull: Optional[pulumi.Input[bool]] = None, + push: Optional[pulumi.Input[bool]] = None, registries: Optional[pulumi.Input[Sequence[pulumi.Input['RegistryAuthArgs']]]] = None, secrets: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, + ssh: Optional[pulumi.Input[Sequence[pulumi.Input['SSHArgs']]]] = None, tags: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, targets: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None): """ The set of arguments for constructing a Image resource. + :param pulumi.Input[Sequence[pulumi.Input[str]]] add_hosts: Custom `host:ip` mappings to use during the build. + + Equivalent to Docker's `--add-host` flag. :param pulumi.Input[Mapping[str, pulumi.Input[str]]] build_args: `ARG` names and values to set during the build. These variables are accessed like environment variables inside `RUN` @@ -43,8 +52,20 @@ def __init__(__self__, *, if these arguments are sensitive. Equivalent to Docker's `--build-arg` flag. - :param pulumi.Input[bool] build_on_preview: When `true`, attempt to build the image during previews. The image will - not be pushed to registries, however caches will still be populated. + :param pulumi.Input[bool] build_on_preview: By default, preview behavior depends on the execution environment. If + Pulumi detects the operation is running on a CI system (GitHub Actions, + Travis CI, Azure Pipelines, etc.) then it will build images during + previews as a safeguard. Otherwise, if not running on CI, previews will + not build images. + + Setting this to `false` forces previews to never perform builds, and + setting it to `true` will always build the image during previews. + + Images built during previews are never exported to registries, however + cache manifests are still exported. + + On-disk Dockerfiles are always validated for syntactic correctness + regardless of this setting. :param pulumi.Input['BuilderConfigArgs'] builder: Builder configuration. :param pulumi.Input[Sequence[pulumi.Input['CacheFromEntryArgs']]] cache_from: Cache export configuration. @@ -67,12 +88,30 @@ def __init__(__self__, *, :param pulumi.Input[Mapping[str, pulumi.Input[str]]] labels: Attach arbitrary key/value metadata to the image. Equivalent to Docker's `--label` flag. + :param pulumi.Input[bool] load: When `true` the build will automatically include a `docker` export. + + Defaults to `false`. + + Equivalent to Docker's `--load` flag. + :param pulumi.Input['NetworkMode'] network: Set the network mode for `RUN` instructions. Defaults to `default`. + + For custom networks, configure your builder with `--driver-opt network=...`. + + Equivalent to Docker's `--network` flag. + :param pulumi.Input[bool] no_cache: Do not import cache manifests when building the image. + + Equivalent to Docker's `--no-cache` flag. :param pulumi.Input[Sequence[pulumi.Input['Platform']]] platforms: Set target platform(s) for the build. Defaults to the host's platform. Equivalent to Docker's `--platform` flag. :param pulumi.Input[bool] pull: Always pull referenced images. Equivalent to Docker's `--pull` flag. + :param pulumi.Input[bool] push: When `true` the build will automatically include a `registry` export. + + Defaults to `false`. + + Equivalent to Docker's `--push` flag. :param pulumi.Input[Sequence[pulumi.Input['RegistryAuthArgs']]] registries: Registry credentials. Required if reading or exporting to private repositories. @@ -89,6 +128,9 @@ def __init__(__self__, *, image, so you should use this for sensitive values. Similar to Docker's `--secret` flag. + :param pulumi.Input[Sequence[pulumi.Input['SSHArgs']]] ssh: SSH agent socket or keys to expose to the build. + + Equivalent to Docker's `--ssh` flag. :param pulumi.Input[Sequence[pulumi.Input[str]]] tags: Name and optionally a tag (format: `name:tag`). If exporting to a registry, the name should include the fully qualified @@ -101,6 +143,8 @@ def __init__(__self__, *, Equivalent to Docker's `--target` flag. """ + if add_hosts is not None: + pulumi.set(__self__, "add_hosts", add_hosts) if build_args is not None: pulumi.set(__self__, "build_args", build_args) if build_on_preview is not None: @@ -119,19 +163,45 @@ def __init__(__self__, *, pulumi.set(__self__, "exports", exports) if labels is not None: pulumi.set(__self__, "labels", labels) + if load is not None: + pulumi.set(__self__, "load", load) + if network is None: + network = 'default' + if network is not None: + pulumi.set(__self__, "network", network) + if no_cache is not None: + pulumi.set(__self__, "no_cache", no_cache) if platforms is not None: pulumi.set(__self__, "platforms", platforms) if pull is not None: pulumi.set(__self__, "pull", pull) + if push is not None: + pulumi.set(__self__, "push", push) if registries is not None: pulumi.set(__self__, "registries", registries) if secrets is not None: pulumi.set(__self__, "secrets", secrets) + if ssh is not None: + pulumi.set(__self__, "ssh", ssh) if tags is not None: pulumi.set(__self__, "tags", tags) if targets is not None: pulumi.set(__self__, "targets", targets) + @property + @pulumi.getter(name="addHosts") + def add_hosts(self) -> Optional[pulumi.Input[Sequence[pulumi.Input[str]]]]: + """ + Custom `host:ip` mappings to use during the build. + + Equivalent to Docker's `--add-host` flag. + """ + return pulumi.get(self, "add_hosts") + + @add_hosts.setter + def add_hosts(self, value: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]]): + pulumi.set(self, "add_hosts", value) + @property @pulumi.getter(name="buildArgs") def build_args(self) -> Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]: @@ -156,8 +226,20 @@ def build_args(self, value: Optional[pulumi.Input[Mapping[str, pulumi.Input[str] @pulumi.getter(name="buildOnPreview") def build_on_preview(self) -> Optional[pulumi.Input[bool]]: """ - When `true`, attempt to build the image during previews. The image will - not be pushed to registries, however caches will still be populated. + By default, preview behavior depends on the execution environment. If + Pulumi detects the operation is running on a CI system (GitHub Actions, + Travis CI, Azure Pipelines, etc.) then it will build images during + previews as a safeguard. Otherwise, if not running on CI, previews will + not build images. + + Setting this to `false` forces previews to never perform builds, and + setting it to `true` will always build the image during previews. + + Images built during previews are never exported to registries, however + cache manifests are still exported. + + On-disk Dockerfiles are always validated for syntactic correctness + regardless of this setting. """ return pulumi.get(self, "build_on_preview") @@ -264,6 +346,52 @@ def labels(self) -> Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]: def labels(self, value: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]): pulumi.set(self, "labels", value) + @property + @pulumi.getter + def load(self) -> Optional[pulumi.Input[bool]]: + """ + When `true` the build will automatically include a `docker` export. + + Defaults to `false`. + + Equivalent to Docker's `--load` flag. + """ + return pulumi.get(self, "load") + + @load.setter + def load(self, value: Optional[pulumi.Input[bool]]): + pulumi.set(self, "load", value) + + @property + @pulumi.getter + def network(self) -> Optional[pulumi.Input['NetworkMode']]: + """ + Set the network mode for `RUN` instructions. Defaults to `default`. + + For custom networks, configure your builder with `--driver-opt network=...`. + + Equivalent to Docker's `--network` flag. + """ + return pulumi.get(self, "network") + + @network.setter + def network(self, value: Optional[pulumi.Input['NetworkMode']]): + pulumi.set(self, "network", value) + + @property + @pulumi.getter(name="noCache") + def no_cache(self) -> Optional[pulumi.Input[bool]]: + """ + Do not import cache manifests when building the image. + + Equivalent to Docker's `--no-cache` flag. + """ + return pulumi.get(self, "no_cache") + + @no_cache.setter + def no_cache(self, value: Optional[pulumi.Input[bool]]): + pulumi.set(self, "no_cache", value) + @property @pulumi.getter def platforms(self) -> Optional[pulumi.Input[Sequence[pulumi.Input['Platform']]]]: @@ -292,6 +420,22 @@ def pull(self) -> Optional[pulumi.Input[bool]]: def pull(self, value: Optional[pulumi.Input[bool]]): pulumi.set(self, "pull", value) + @property + @pulumi.getter + def push(self) -> Optional[pulumi.Input[bool]]: + """ + When `true` the build will automatically include a `registry` export. + + Defaults to `false`. + + Equivalent to Docker's `--push` flag. + """ + return pulumi.get(self, "push") + + @push.setter + def push(self, value: Optional[pulumi.Input[bool]]): + pulumi.set(self, "push", value) + @property @pulumi.getter def registries(self) -> Optional[pulumi.Input[Sequence[pulumi.Input['RegistryAuthArgs']]]]: @@ -330,6 +474,20 @@ def secrets(self) -> Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]: def secrets(self, value: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]]): pulumi.set(self, "secrets", value) + @property + @pulumi.getter + def ssh(self) -> Optional[pulumi.Input[Sequence[pulumi.Input['SSHArgs']]]]: + """ + SSH agent socket or keys to expose to the build. + + Equivalent to Docker's `--ssh` flag. + """ + return pulumi.get(self, "ssh") + + @ssh.setter + def ssh(self, value: Optional[pulumi.Input[Sequence[pulumi.Input['SSHArgs']]]]): + pulumi.set(self, "ssh", value) + @property @pulumi.getter def tags(self) -> Optional[pulumi.Input[Sequence[pulumi.Input[str]]]]: @@ -369,6 +527,7 @@ class Image(pulumi.CustomResource): def __init__(__self__, resource_name: str, opts: Optional[pulumi.ResourceOptions] = None, + add_hosts: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, build_args: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, build_on_preview: Optional[pulumi.Input[bool]] = None, builder: Optional[pulumi.Input[pulumi.InputType['BuilderConfigArgs']]] = None, @@ -378,10 +537,15 @@ def __init__(__self__, dockerfile: Optional[pulumi.Input[pulumi.InputType['DockerfileArgs']]] = None, exports: Optional[pulumi.Input[Sequence[pulumi.Input[pulumi.InputType['ExportEntryArgs']]]]] = None, labels: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, + load: Optional[pulumi.Input[bool]] = None, + network: Optional[pulumi.Input['NetworkMode']] = None, + no_cache: Optional[pulumi.Input[bool]] = None, platforms: Optional[pulumi.Input[Sequence[pulumi.Input['Platform']]]] = None, pull: Optional[pulumi.Input[bool]] = None, + push: Optional[pulumi.Input[bool]] = None, registries: Optional[pulumi.Input[Sequence[pulumi.Input[pulumi.InputType['RegistryAuthArgs']]]]] = None, secrets: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, + ssh: Optional[pulumi.Input[Sequence[pulumi.Input[pulumi.InputType['SSHArgs']]]]] = None, tags: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, targets: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, __props__=None): @@ -672,6 +836,9 @@ def __init__(__self__, :param str resource_name: The name of the resource. :param pulumi.ResourceOptions opts: Options for the resource. + :param pulumi.Input[Sequence[pulumi.Input[str]]] add_hosts: Custom `host:ip` mappings to use during the build. + + Equivalent to Docker's `--add-host` flag. :param pulumi.Input[Mapping[str, pulumi.Input[str]]] build_args: `ARG` names and values to set during the build. These variables are accessed like environment variables inside `RUN` @@ -681,8 +848,20 @@ def __init__(__self__, if these arguments are sensitive. Equivalent to Docker's `--build-arg` flag. - :param pulumi.Input[bool] build_on_preview: When `true`, attempt to build the image during previews. The image will - not be pushed to registries, however caches will still be populated. + :param pulumi.Input[bool] build_on_preview: By default, preview behavior depends on the execution environment. If + Pulumi detects the operation is running on a CI system (GitHub Actions, + Travis CI, Azure Pipelines, etc.) then it will build images during + previews as a safeguard. Otherwise, if not running on CI, previews will + not build images. + + Setting this to `false` forces previews to never perform builds, and + setting it to `true` will always build the image during previews. + + Images built during previews are never exported to registries, however + cache manifests are still exported. + + On-disk Dockerfiles are always validated for syntactic correctness + regardless of this setting. :param pulumi.Input[pulumi.InputType['BuilderConfigArgs']] builder: Builder configuration. :param pulumi.Input[Sequence[pulumi.Input[pulumi.InputType['CacheFromEntryArgs']]]] cache_from: Cache export configuration. @@ -705,12 +884,30 @@ def __init__(__self__, :param pulumi.Input[Mapping[str, pulumi.Input[str]]] labels: Attach arbitrary key/value metadata to the image. Equivalent to Docker's `--label` flag. + :param pulumi.Input[bool] load: When `true` the build will automatically include a `docker` export. + + Defaults to `false`. + + Equivalent to Docker's `--load` flag. + :param pulumi.Input['NetworkMode'] network: Set the network mode for `RUN` instructions. Defaults to `default`. + + For custom networks, configure your builder with `--driver-opt network=...`. + + Equivalent to Docker's `--network` flag. + :param pulumi.Input[bool] no_cache: Do not import cache manifests when building the image. + + Equivalent to Docker's `--no-cache` flag. :param pulumi.Input[Sequence[pulumi.Input['Platform']]] platforms: Set target platform(s) for the build. Defaults to the host's platform. Equivalent to Docker's `--platform` flag. :param pulumi.Input[bool] pull: Always pull referenced images. Equivalent to Docker's `--pull` flag. + :param pulumi.Input[bool] push: When `true` the build will automatically include a `registry` export. + + Defaults to `false`. + + Equivalent to Docker's `--push` flag. :param pulumi.Input[Sequence[pulumi.Input[pulumi.InputType['RegistryAuthArgs']]]] registries: Registry credentials. Required if reading or exporting to private repositories. @@ -727,6 +924,9 @@ def __init__(__self__, image, so you should use this for sensitive values. Similar to Docker's `--secret` flag. + :param pulumi.Input[Sequence[pulumi.Input[pulumi.InputType['SSHArgs']]]] ssh: SSH agent socket or keys to expose to the build. + + Equivalent to Docker's `--ssh` flag. :param pulumi.Input[Sequence[pulumi.Input[str]]] tags: Name and optionally a tag (format: `name:tag`). If exporting to a registry, the name should include the fully qualified @@ -1045,6 +1245,7 @@ def __init__(__self__, resource_name: str, *args, **kwargs): def _internal_init(__self__, resource_name: str, opts: Optional[pulumi.ResourceOptions] = None, + add_hosts: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, build_args: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, build_on_preview: Optional[pulumi.Input[bool]] = None, builder: Optional[pulumi.Input[pulumi.InputType['BuilderConfigArgs']]] = None, @@ -1054,10 +1255,15 @@ def _internal_init(__self__, dockerfile: Optional[pulumi.Input[pulumi.InputType['DockerfileArgs']]] = None, exports: Optional[pulumi.Input[Sequence[pulumi.Input[pulumi.InputType['ExportEntryArgs']]]]] = None, labels: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, + load: Optional[pulumi.Input[bool]] = None, + network: Optional[pulumi.Input['NetworkMode']] = None, + no_cache: Optional[pulumi.Input[bool]] = None, platforms: Optional[pulumi.Input[Sequence[pulumi.Input['Platform']]]] = None, pull: Optional[pulumi.Input[bool]] = None, + push: Optional[pulumi.Input[bool]] = None, registries: Optional[pulumi.Input[Sequence[pulumi.Input[pulumi.InputType['RegistryAuthArgs']]]]] = None, secrets: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, + ssh: Optional[pulumi.Input[Sequence[pulumi.Input[pulumi.InputType['SSHArgs']]]]] = None, tags: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, targets: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, __props__=None): @@ -1069,6 +1275,7 @@ def _internal_init(__self__, raise TypeError('__props__ is only valid when passed in combination with a valid opts.id to get an existing resource') __props__ = ImageArgs.__new__(ImageArgs) + __props__.__dict__["add_hosts"] = add_hosts __props__.__dict__["build_args"] = build_args __props__.__dict__["build_on_preview"] = build_on_preview __props__.__dict__["builder"] = builder @@ -1078,16 +1285,22 @@ def _internal_init(__self__, __props__.__dict__["dockerfile"] = dockerfile __props__.__dict__["exports"] = exports __props__.__dict__["labels"] = labels + __props__.__dict__["load"] = load + if network is None: + network = 'default' + __props__.__dict__["network"] = network + __props__.__dict__["no_cache"] = no_cache __props__.__dict__["platforms"] = platforms __props__.__dict__["pull"] = pull + __props__.__dict__["push"] = push __props__.__dict__["registries"] = registries - __props__.__dict__["secrets"] = None if secrets is None else pulumi.Output.secret(secrets) + __props__.__dict__["secrets"] = secrets + __props__.__dict__["ssh"] = ssh __props__.__dict__["tags"] = tags __props__.__dict__["targets"] = targets __props__.__dict__["context_hash"] = None __props__.__dict__["digests"] = None - secret_opts = pulumi.ResourceOptions(additional_secret_outputs=["secrets"]) - opts = pulumi.ResourceOptions.merge(opts, secret_opts) + __props__.__dict__["ref"] = None super(Image, __self__).__init__( 'docker:buildx/image:Image', resource_name, @@ -1110,6 +1323,7 @@ def get(resource_name: str, __props__ = ImageArgs.__new__(ImageArgs) + __props__.__dict__["add_hosts"] = None __props__.__dict__["build_args"] = None __props__.__dict__["build_on_preview"] = None __props__.__dict__["builder"] = None @@ -1121,14 +1335,30 @@ def get(resource_name: str, __props__.__dict__["dockerfile"] = None __props__.__dict__["exports"] = None __props__.__dict__["labels"] = None + __props__.__dict__["load"] = None + __props__.__dict__["network"] = None + __props__.__dict__["no_cache"] = None __props__.__dict__["platforms"] = None __props__.__dict__["pull"] = None + __props__.__dict__["push"] = None + __props__.__dict__["ref"] = None __props__.__dict__["registries"] = None __props__.__dict__["secrets"] = None + __props__.__dict__["ssh"] = None __props__.__dict__["tags"] = None __props__.__dict__["targets"] = None return Image(resource_name, opts=opts, __props__=__props__) + @property + @pulumi.getter(name="addHosts") + def add_hosts(self) -> pulumi.Output[Optional[Sequence[str]]]: + """ + Custom `host:ip` mappings to use during the build. + + Equivalent to Docker's `--add-host` flag. + """ + return pulumi.get(self, "add_hosts") + @property @pulumi.getter(name="buildArgs") def build_args(self) -> pulumi.Output[Optional[Mapping[str, str]]]: @@ -1149,8 +1379,20 @@ def build_args(self) -> pulumi.Output[Optional[Mapping[str, str]]]: @pulumi.getter(name="buildOnPreview") def build_on_preview(self) -> pulumi.Output[Optional[bool]]: """ - When `true`, attempt to build the image during previews. The image will - not be pushed to registries, however caches will still be populated. + By default, preview behavior depends on the execution environment. If + Pulumi detects the operation is running on a CI system (GitHub Actions, + Travis CI, Azure Pipelines, etc.) then it will build images during + previews as a safeguard. Otherwise, if not running on CI, previews will + not build images. + + Setting this to `false` forces previews to never perform builds, and + setting it to `true` will always build the image during previews. + + Images built during previews are never exported to registries, however + cache manifests are still exported. + + On-disk Dockerfiles are always validated for syntactic correctness + regardless of this setting. """ return pulumi.get(self, "build_on_preview") @@ -1194,7 +1436,7 @@ def context(self) -> pulumi.Output[Optional['outputs.BuildContext']]: @property @pulumi.getter(name="contextHash") - def context_hash(self) -> pulumi.Output[Optional[str]]: + def context_hash(self) -> pulumi.Output[str]: """ A preliminary hash of the image's build context. @@ -1204,9 +1446,13 @@ def context_hash(self) -> pulumi.Output[Optional[str]]: @property @pulumi.getter - def digests(self) -> pulumi.Output[Optional[Mapping[str, Sequence[str]]]]: + def digests(self) -> pulumi.Output[Mapping[str, str]]: """ - A mapping of platform type to refs which were pushed to registries. + A mapping of target names to the SHA256 digest of their pushed manifest. + + If no target was specified 'default' is used as the target name. + + Pushed manifests can be referenced as `@`. """ return pulumi.get(self, "digests") @@ -1243,6 +1489,40 @@ def labels(self) -> pulumi.Output[Optional[Mapping[str, str]]]: """ return pulumi.get(self, "labels") + @property + @pulumi.getter + def load(self) -> pulumi.Output[Optional[bool]]: + """ + When `true` the build will automatically include a `docker` export. + + Defaults to `false`. + + Equivalent to Docker's `--load` flag. + """ + return pulumi.get(self, "load") + + @property + @pulumi.getter + def network(self) -> pulumi.Output[Optional['NetworkMode']]: + """ + Set the network mode for `RUN` instructions. Defaults to `default`. + + For custom networks, configure your builder with `--driver-opt network=...`. + + Equivalent to Docker's `--network` flag. + """ + return pulumi.get(self, "network") + + @property + @pulumi.getter(name="noCache") + def no_cache(self) -> pulumi.Output[Optional[bool]]: + """ + Do not import cache manifests when building the image. + + Equivalent to Docker's `--no-cache` flag. + """ + return pulumi.get(self, "no_cache") + @property @pulumi.getter def platforms(self) -> pulumi.Output[Optional[Sequence['Platform']]]: @@ -1263,6 +1543,34 @@ def pull(self) -> pulumi.Output[Optional[bool]]: """ return pulumi.get(self, "pull") + @property + @pulumi.getter + def push(self) -> pulumi.Output[Optional[bool]]: + """ + When `true` the build will automatically include a `registry` export. + + Defaults to `false`. + + Equivalent to Docker's `--push` flag. + """ + return pulumi.get(self, "push") + + @property + @pulumi.getter + def ref(self) -> pulumi.Output[str]: + """ + If the image was pushed to any registries then this will contain a + single fully-qualified tag including the build's digest. + + This is only for convenience and may not be appropriate for situations + where multiple tags or registries are involved. In those cases this + output is not guaranteed to be stable. + + For more control over tags consumed by downstream resources you should + use the `Digests` output. + """ + return pulumi.get(self, "ref") + @property @pulumi.getter def registries(self) -> pulumi.Output[Optional[Sequence['outputs.RegistryAuth']]]: @@ -1293,6 +1601,16 @@ def secrets(self) -> pulumi.Output[Optional[Mapping[str, str]]]: """ return pulumi.get(self, "secrets") + @property + @pulumi.getter + def ssh(self) -> pulumi.Output[Optional[Sequence['outputs.SSH']]]: + """ + SSH agent socket or keys to expose to the build. + + Equivalent to Docker's `--ssh` flag. + """ + return pulumi.get(self, "ssh") + @property @pulumi.getter def tags(self) -> pulumi.Output[Optional[Sequence[str]]]: diff --git a/sdk/python/pulumi_docker/buildx/outputs.py b/sdk/python/pulumi_docker/buildx/outputs.py index d695c496..4fdd5105 100644 --- a/sdk/python/pulumi_docker/buildx/outputs.py +++ b/sdk/python/pulumi_docker/buildx/outputs.py @@ -36,9 +36,8 @@ 'ExportOCI', 'ExportRegistry', 'ExportTar', - 'Manifest', - 'ManifestPlatform', 'RegistryAuth', + 'SSH', ] @pulumi.output_type @@ -1575,7 +1574,6 @@ def __init__(__self__, *, docker: Optional['outputs.ExportDocker'] = None, image: Optional['outputs.ExportImage'] = None, local: Optional['outputs.ExportLocal'] = None, - manifests: Optional[Sequence['outputs.Manifest']] = None, oci: Optional['outputs.ExportOCI'] = None, raw: Optional[str] = None, registry: Optional['outputs.ExportRegistry'] = None, @@ -1585,8 +1583,6 @@ def __init__(__self__, *, :param 'ExportDockerArgs' docker: Export as a Docker image layout. :param 'ExportImageArgs' image: Outputs the build result into a container image format. :param 'ExportLocalArgs' local: Export to a local directory as files and directories. - :param Sequence['ManifestArgs'] manifests: An output property populated for exporters that pushed image - manifest(s) to a registry. :param 'ExportOCIArgs' oci: Identical to the Docker exporter but uses OCI media types by default. :param str raw: A raw string as you would provide it to the Docker CLI (e.g., `type=docker`) @@ -1601,8 +1597,6 @@ def __init__(__self__, *, pulumi.set(__self__, "image", image) if local is not None: pulumi.set(__self__, "local", local) - if manifests is not None: - pulumi.set(__self__, "manifests", manifests) if oci is not None: pulumi.set(__self__, "oci", oci) if raw is not None: @@ -1644,15 +1638,6 @@ def local(self) -> Optional['outputs.ExportLocal']: """ return pulumi.get(self, "local") - @property - @pulumi.getter - def manifests(self) -> Optional[Sequence['outputs.Manifest']]: - """ - An output property populated for exporters that pushed image - manifest(s) to a registry. - """ - return pulumi.get(self, "manifests") - @property @pulumi.getter def oci(self) -> Optional['outputs.ExportOCI']: @@ -2287,86 +2272,6 @@ def dest(self) -> str: return pulumi.get(self, "dest") -@pulumi.output_type -class Manifest(dict): - def __init__(__self__, *, - digest: str, - platform: 'outputs.ManifestPlatform', - ref: str, - size: int): - """ - :param str digest: The SHA256 digest of the manifest. - :param 'ManifestPlatformArgs' platform: The manifest's platform. - :param str ref: The manifest's canonical ref. - :param int size: The size of the manifest in bytes. - """ - pulumi.set(__self__, "digest", digest) - pulumi.set(__self__, "platform", platform) - pulumi.set(__self__, "ref", ref) - pulumi.set(__self__, "size", size) - - @property - @pulumi.getter - def digest(self) -> str: - """ - The SHA256 digest of the manifest. - """ - return pulumi.get(self, "digest") - - @property - @pulumi.getter - def platform(self) -> 'outputs.ManifestPlatform': - """ - The manifest's platform. - """ - return pulumi.get(self, "platform") - - @property - @pulumi.getter - def ref(self) -> str: - """ - The manifest's canonical ref. - """ - return pulumi.get(self, "ref") - - @property - @pulumi.getter - def size(self) -> int: - """ - The size of the manifest in bytes. - """ - return pulumi.get(self, "size") - - -@pulumi.output_type -class ManifestPlatform(dict): - def __init__(__self__, *, - architecture: str, - os: str): - """ - :param str architecture: The manifest's architecture. - :param str os: The manifest's operating systen. - """ - pulumi.set(__self__, "architecture", architecture) - pulumi.set(__self__, "os", os) - - @property - @pulumi.getter - def architecture(self) -> str: - """ - The manifest's architecture. - """ - return pulumi.get(self, "architecture") - - @property - @pulumi.getter - def os(self) -> str: - """ - The manifest's operating systen. - """ - return pulumi.get(self, "os") - - @pulumi.output_type class RegistryAuth(dict): def __init__(__self__, *, @@ -2409,3 +2314,53 @@ def username(self) -> Optional[str]: return pulumi.get(self, "username") +@pulumi.output_type +class SSH(dict): + def __init__(__self__, *, + id: str, + paths: Optional[Sequence[str]] = None): + """ + :param str id: Useful for distinguishing different servers that are part of the same + build. + + A value of `default` is appropriate if only dealing with a single host. + :param Sequence[str] paths: SSH agent socket or private keys to expose to the build under the given + identifier. + + Defaults to `[$SSH_AUTH_SOCK]`. + + Note that your keys are **not** automatically added when using an + agent. Run `ssh-add -l` locally to confirm which public keys are + visible to the agent; these will be exposed to your build. + """ + pulumi.set(__self__, "id", id) + if paths is not None: + pulumi.set(__self__, "paths", paths) + + @property + @pulumi.getter + def id(self) -> str: + """ + Useful for distinguishing different servers that are part of the same + build. + + A value of `default` is appropriate if only dealing with a single host. + """ + return pulumi.get(self, "id") + + @property + @pulumi.getter + def paths(self) -> Optional[Sequence[str]]: + """ + SSH agent socket or private keys to expose to the build under the given + identifier. + + Defaults to `[$SSH_AUTH_SOCK]`. + + Note that your keys are **not** automatically added when using an + agent. Run `ssh-add -l` locally to confirm which public keys are + visible to the agent; these will be exposed to your build. + """ + return pulumi.get(self, "paths") + +