Compare commits
9 Commits
v0.0.10
...
v0.0.1-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6efd4b045b | ||
|
|
b6c5d4d511 | ||
|
|
b455d9037f | ||
|
|
f9b5ed8f67 | ||
|
|
16196bb547 | ||
|
|
5bec2f3e1c | ||
|
|
91c652a702 | ||
|
|
cbf957533e | ||
|
|
d50d156bd8 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1 +1,2 @@
|
||||
sdk/**/* linguist-generated=true
|
||||
provider/internal/mock*.go linguist-generated=true
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@
|
||||
**/.vs
|
||||
**/.idea
|
||||
**/.ionide
|
||||
**/.vscode
|
||||
*.swp
|
||||
Pulumi.*.yaml
|
||||
yarn.lock
|
||||
|
||||
@@ -1,36 +1,64 @@
|
||||
linters:
|
||||
enable-all: false
|
||||
enable:
|
||||
- depguard
|
||||
- errcheck
|
||||
- exhaustive
|
||||
- prealloc
|
||||
- gofumpt
|
||||
- revive
|
||||
- exportloopref
|
||||
- gci
|
||||
- gocritic
|
||||
- gofumpt
|
||||
- goheader
|
||||
- gosec
|
||||
- govet
|
||||
- importas
|
||||
- ineffassign
|
||||
- lll
|
||||
- misspell
|
||||
- nolintlint
|
||||
- nakedret
|
||||
- unconvert
|
||||
- unused
|
||||
- nolintlint
|
||||
- paralleltest
|
||||
- perfsprint
|
||||
- depguard
|
||||
- importas
|
||||
- prealloc
|
||||
- revive
|
||||
- unconvert
|
||||
- unused
|
||||
|
||||
linters-settings:
|
||||
nakedret:
|
||||
# Make an issue if func has more lines of code than this setting, and it has naked returns.
|
||||
# Default: 30
|
||||
max-func-lines: 60
|
||||
nolintlint:
|
||||
# Some linter exclusions are added to generated or templated files
|
||||
# pre-emptively.
|
||||
# Don't complain about these.
|
||||
allow-unused: true
|
||||
depguard:
|
||||
rules:
|
||||
protobuf:
|
||||
deny:
|
||||
- pkg: "github.com/golang/protobuf"
|
||||
desc: Use google.golang.org/protobuf instead
|
||||
gci:
|
||||
sections:
|
||||
- standard # Standard section: captures all standard library packages.
|
||||
- blank # Blank section: contains all blank imports.
|
||||
- default # Default section: contains all imports that could not be matched to another section type.
|
||||
- prefix(github.com/pulumi/) # Custom section: groups all imports with the github.com/pulumi/ prefix.
|
||||
- prefix(github.com/pulumi/pulumi-dockerbuild/) # Custom section: local imports
|
||||
custom-order: true
|
||||
gocritic:
|
||||
enable-all: true
|
||||
disabled-checks:
|
||||
- hugeParam
|
||||
- importShadow
|
||||
goheader:
|
||||
template: |-
|
||||
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.
|
||||
govet:
|
||||
enable:
|
||||
- nilness
|
||||
@@ -40,22 +68,18 @@ linters-settings:
|
||||
- sortslice
|
||||
# Detect write to struct/arrays by-value that aren't read again.
|
||||
- unusedwrite
|
||||
gci:
|
||||
sections:
|
||||
- standard # Standard section: captures all standard library packages.
|
||||
- blank # Blank section: contains all blank imports.
|
||||
- default # Default section: contains all imports that could not be matched to another section type.
|
||||
- prefix(github.com/pulumi/) # Custom section: groups all imports with the github.com/pulumi/ prefix.
|
||||
- prefix(github.com/pulumi/pulumi-dockerbuild) # Custom section: local imports
|
||||
custom-order: true
|
||||
depguard:
|
||||
rules:
|
||||
protobuf:
|
||||
deny:
|
||||
- pkg: "github.com/golang/protobuf"
|
||||
desc: Use google.golang.org/protobuf instead
|
||||
nakedret:
|
||||
# Make an issue if func has more lines of code than this setting, and it has naked returns.
|
||||
# Default: 30
|
||||
max-func-lines: 60
|
||||
nolintlint:
|
||||
# Some linter exclusions are added to generated or templated files
|
||||
# pre-emptively.
|
||||
# Don't complain about these.
|
||||
allow-unused: true
|
||||
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
exclude-rules:
|
||||
# Don't warn on unused parameters.
|
||||
# Parameter names are useful; replacing them with '_' is undesirable.
|
||||
|
||||
20
Makefile
20
Makefile
@@ -19,6 +19,7 @@ EXAMPLES_DIR := ${WORKING_DIR}/examples/yaml
|
||||
TESTPARALLELISM := 4
|
||||
|
||||
PULUMI := bin/pulumi
|
||||
GOGLANGCILINT := bin/golangci-lint
|
||||
|
||||
.PHONY: ensure
|
||||
ensure:: tidy lint test_provider examples
|
||||
@@ -44,7 +45,11 @@ test_all:: test_provider test_examples
|
||||
gen_examples:
|
||||
|
||||
examples: $(shell mkdir -p examples)
|
||||
examples: sdk examples/go examples/nodejs examples/python examples/dotnet examples/java
|
||||
examples: sdk examples/yaml examples/go examples/nodejs examples/python examples/dotnet examples/java
|
||||
|
||||
examples/yaml:
|
||||
rm -rf ${WORKING_DIR}/examples/yaml/app
|
||||
cp -r ${WORKING_DIR}/examples/app ${WORKING_DIR}/examples/yaml/app
|
||||
|
||||
examples/go: ${PULUMI} bin/${PROVIDER} ${WORKING_DIR}/examples/yaml/Pulumi.yaml
|
||||
$(call example,go)
|
||||
@@ -69,13 +74,15 @@ examples/java: ${PULUMI} bin/${PROVIDER} ${WORKING_DIR}/examples/yaml/Pulumi.yam
|
||||
${PULUMI}: go.sum
|
||||
GOBIN=${WORKING_DIR}/bin go install github.com/pulumi/pulumi/pkg/v3/cmd/pulumi
|
||||
|
||||
${GOGLANGCILINT}: go.sum
|
||||
GOBIN=${WORKING_DIR}/bin go install github.com/golangci/golangci-lint/cmd/golangci-lint
|
||||
|
||||
define pulumi_login
|
||||
export PULUMI_CONFIG_PASSPHRASE=asdfqwerty1234; \
|
||||
pulumi login --local;
|
||||
endef
|
||||
|
||||
define example
|
||||
echo "GOT $(1)"
|
||||
rm -rf ${WORKING_DIR}/examples/$(1)
|
||||
$(PULUMI) convert \
|
||||
--cwd ${WORKING_DIR}/examples/yaml \
|
||||
@@ -84,6 +91,7 @@ define example
|
||||
--non-interactive \
|
||||
--language $(1) \
|
||||
--out ${WORKING_DIR}/examples/$(1)
|
||||
cp -r ${WORKING_DIR}/examples/app ${WORKING_DIR}/examples/$(1)/app
|
||||
endef
|
||||
|
||||
up::
|
||||
@@ -113,8 +121,8 @@ build:: provider dotnet_sdk go_sdk nodejs_sdk python_sdk
|
||||
only_build:: build
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
golangci-lint run --fix -c .golangci.yml --timeout 10m
|
||||
lint: ${GOGLANGCILINT}
|
||||
${GOGLANGCILINT} run --fix -c .golangci.yml --timeout 10m
|
||||
|
||||
install:: install_nodejs_sdk install_dotnet_sdk
|
||||
cp $(WORKING_DIR)/bin/${PROVIDER} ${GOPATH}/bin
|
||||
@@ -236,3 +244,7 @@ sdk/java: $(PULUMI) bin/${PROVIDER}
|
||||
$(PULUMI) package gen-sdk --language java bin/${PROVIDER} -o ${TMPDIR}
|
||||
cd ${TMPDIR}/java/ && gradle --console=plain build
|
||||
mv -f ${TMPDIR}/java ${WORKING_DIR}/sdk/.
|
||||
|
||||
docs: $(shell find docs/yaml -type f)
|
||||
go generate docs/generate.go
|
||||
@touch docs
|
||||
|
||||
216
docs/generate.go
Normal file
216
docs/generate.go
Normal file
@@ -0,0 +1,216 @@
|
||||
// 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:generate go run generate.go yaml ../provider/internal/embed
|
||||
|
||||
// Package main ingests a multi-document YAML file and converts it into
|
||||
// Markdown examples.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 3 {
|
||||
fmt.Fprintf(os.Stdout, "Usage: %s <yaml source dir path> <markdown destination path>\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
yamlPath := os.Args[1]
|
||||
mdPath := os.Args[2]
|
||||
|
||||
if !filepath.IsAbs(yamlPath) {
|
||||
cwd, err := os.Getwd()
|
||||
contract.AssertNoErrorf(err, "getting working directory")
|
||||
yamlPath = filepath.Join(cwd, yamlPath)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(mdPath, 0o750); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fileInfo, err := os.Lstat(mdPath)
|
||||
if err != nil || !fileInfo.IsDir() {
|
||||
fmt.Fprintf(os.Stderr, "Expect markdown destination %q to be a directory\n", mdPath)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
yamlFiles, err := os.ReadDir(yamlPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, yamlFile := range yamlFiles {
|
||||
if err := processYaml(filepath.Join(yamlPath, yamlFile.Name()), mdPath); err != nil {
|
||||
log.Fatal(fmt.Errorf("processing %q: %w", yamlFile.Name(), err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func markdownExamples(examples []string) string {
|
||||
s := "{{% examples %}}\n## Example Usage\n"
|
||||
for _, example := range examples {
|
||||
s += example
|
||||
}
|
||||
s += "{{% /examples %}}"
|
||||
return s
|
||||
}
|
||||
|
||||
func markdownExample(description string,
|
||||
typescript string,
|
||||
python string,
|
||||
csharp string,
|
||||
golang string,
|
||||
yaml string,
|
||||
java string,
|
||||
) string {
|
||||
return fmt.Sprintf("{{%% example %%}}\n### %s\n\n"+
|
||||
"```typescript\n%s```\n"+
|
||||
"```python\n%s```\n"+
|
||||
"```csharp\n%s```\n"+
|
||||
"```go\n%s```\n"+
|
||||
"```yaml\n%s```\n"+
|
||||
"```java\n%s```\n"+
|
||||
"{{%% /example %%}}\n",
|
||||
description, typescript, python, csharp, golang, yaml, java)
|
||||
}
|
||||
|
||||
func convert(language, tempDir, programFile string) (string, error) {
|
||||
exampleDir := filepath.Join(tempDir, "example"+language)
|
||||
//nolint:gosec // No user-provided input.
|
||||
cmd := exec.Command(
|
||||
"pulumi",
|
||||
"convert",
|
||||
"--language",
|
||||
language,
|
||||
"--out",
|
||||
filepath.Clean(filepath.Join(tempDir, exampleDir)),
|
||||
"--generate-only",
|
||||
)
|
||||
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Dir = tempDir
|
||||
if err := cmd.Run(); err != nil {
|
||||
return "", fmt.Errorf("converting: %w", err)
|
||||
}
|
||||
content, err := os.ReadFile(filepath.Clean(filepath.Join(tempDir, exampleDir, programFile)))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("reading: %w", err)
|
||||
}
|
||||
|
||||
return string(content), nil
|
||||
}
|
||||
|
||||
func processYaml(path, mdDir string) error {
|
||||
yamlFile, err := os.Open(filepath.Clean(path))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
base := filepath.Base(path)
|
||||
md := strings.NewReplacer(".yaml", ".md", ".yml", ".md").Replace(base)
|
||||
|
||||
defer contract.IgnoreClose(yamlFile)
|
||||
decoder := yaml.NewDecoder(yamlFile)
|
||||
exampleStrings := []string{}
|
||||
for {
|
||||
keepGoing, err := func() (bool, error) {
|
||||
example := map[string]interface{}{}
|
||||
err := decoder.Decode(&example)
|
||||
if err == io.EOF {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
description, ok := example["description"].(string)
|
||||
if !ok {
|
||||
description = ""
|
||||
}
|
||||
dir, err := os.MkdirTemp("", "")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
contract.IgnoreError(os.RemoveAll(dir))
|
||||
}()
|
||||
|
||||
src, err := os.OpenFile(filepath.Clean(filepath.Join(dir, "Pulumi.yaml")), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
fmt.Println("Converting:", example)
|
||||
|
||||
if err := yaml.NewEncoder(src).Encode(example); err != nil {
|
||||
return false, err
|
||||
}
|
||||
contract.AssertNoErrorf(src.Close(), "closing")
|
||||
|
||||
typescript, err := convert("typescript", dir, "index.ts")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
python, err := convert("python", dir, "__main__.py")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
csharp, err := convert("csharp", dir, "Program.cs")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
golang, err := convert("go", dir, "main.go")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
java, err := convert("java", dir, "src/main/java/generated_program/App.java")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
yamlContent, err := os.ReadFile(filepath.Clean(filepath.Join(dir, "Pulumi.yaml")))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
yaml := string(yamlContent)
|
||||
|
||||
exampleStrings = append(exampleStrings, markdownExample(description, typescript, python, csharp, golang, yaml, java))
|
||||
|
||||
return true, nil
|
||||
}()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !keepGoing {
|
||||
break
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "Writing %s\n", filepath.Join(mdDir, md))
|
||||
f, err := os.OpenFile(filepath.Clean(filepath.Join(mdDir, md)), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer contract.IgnoreClose(f)
|
||||
_, err = f.WriteString(markdownExamples(exampleStrings))
|
||||
contract.AssertNoErrorf(err, "writing examples")
|
||||
return nil
|
||||
}
|
||||
180
docs/yaml/image-examples.yaml
Normal file
180
docs/yaml/image-examples.yaml
Normal file
@@ -0,0 +1,180 @@
|
||||
name: ecr
|
||||
description: Push to AWS ECR with caching
|
||||
outputs:
|
||||
ref: ${my-image.ref}
|
||||
resources:
|
||||
ecr-repository:
|
||||
type: aws:ecr:Repository
|
||||
my-image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
tags:
|
||||
- ${ecr-repository.repositoryUrl}:latest
|
||||
push: true
|
||||
context:
|
||||
location: ./app
|
||||
cacheFrom:
|
||||
- registry:
|
||||
ref: ${ecr-repository.repositoryUrl}:cache
|
||||
cacheTo:
|
||||
- registry:
|
||||
ref: ${ecr-repository.repositoryUrl}:cache
|
||||
imageManifest: true
|
||||
ociMediaTypes: true
|
||||
registries:
|
||||
- username: ${auth-token.userName}
|
||||
password: ${auth-token.password}
|
||||
address: ${ecr-repository.repositoryUrl}
|
||||
runtime: yaml
|
||||
variables:
|
||||
auth-token:
|
||||
fn::aws:ecr:getAuthorizationToken:
|
||||
registryId: ${ecr-repository.registryId}
|
||||
---
|
||||
name: multi-platform
|
||||
runtime: yaml
|
||||
description: Multi-platform image
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "app"
|
||||
platforms:
|
||||
- plan9/amd64
|
||||
- plan9/386
|
||||
---
|
||||
name: registry
|
||||
runtime: yaml
|
||||
description: Registry export
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
tags:
|
||||
- "docker.io/pulumi/pulumi:3.107.0"
|
||||
context:
|
||||
location: "app"
|
||||
push: true
|
||||
registries:
|
||||
- address: docker.io
|
||||
username: pulumibot
|
||||
password: ${dockerHubPassword}
|
||||
outputs:
|
||||
ref: ${my-image.ref}
|
||||
---
|
||||
name: caching
|
||||
runtime: yaml
|
||||
description: Caching
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "app"
|
||||
cacheTo:
|
||||
- local:
|
||||
dest: tmp/cache
|
||||
mode: max
|
||||
cacheFrom:
|
||||
- local:
|
||||
src: tmp/cache
|
||||
---
|
||||
name: dbc
|
||||
runtime: yaml
|
||||
description: Docker Build Cloud
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "app"
|
||||
exec: true
|
||||
builder:
|
||||
name: cloud-builder-name
|
||||
---
|
||||
name: build-args
|
||||
runtime: yaml
|
||||
description: Build arguments
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "app"
|
||||
buildArgs:
|
||||
SET_ME_TO_TRUE: "true"
|
||||
---
|
||||
name: build-target
|
||||
runtime: yaml
|
||||
description: Build target
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "app"
|
||||
target: "build-me"
|
||||
---
|
||||
name: named-contexts
|
||||
runtime: yaml
|
||||
description: Named contexts
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: app
|
||||
named:
|
||||
"golang:latest":
|
||||
location: "docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984"
|
||||
---
|
||||
name: remote-context
|
||||
runtime: yaml
|
||||
description: Remote context
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile"
|
||||
|
||||
---
|
||||
name: inline
|
||||
runtime: yaml
|
||||
description: Inline Dockerfile
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
dockerfile:
|
||||
inline: |
|
||||
FROM busybox
|
||||
COPY hello.c ./
|
||||
context:
|
||||
location: "app"
|
||||
---
|
||||
name: remote-context
|
||||
runtime: yaml
|
||||
description: Remote context
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
dockerfile:
|
||||
location: app/Dockerfile
|
||||
context:
|
||||
location: "https://github.com/docker-library/hello-world.git"
|
||||
---
|
||||
name: docker-load
|
||||
runtime: yaml
|
||||
description: Local export
|
||||
resources:
|
||||
image:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "app"
|
||||
exports:
|
||||
- docker:
|
||||
tar: true
|
||||
48
docs/yaml/index-examples.yaml
Normal file
48
docs/yaml/index-examples.yaml
Normal file
@@ -0,0 +1,48 @@
|
||||
name: registry-caching
|
||||
description: Multi-platform registry caching
|
||||
runtime: yaml
|
||||
resources:
|
||||
arm64:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "app"
|
||||
platforms:
|
||||
- linux/arm64
|
||||
tags:
|
||||
- "docker.io/pulumi/pulumi:3.107.0-arm64"
|
||||
cacheTo:
|
||||
- registry:
|
||||
ref: "docker.io/pulumi/pulumi:cache-arm64"
|
||||
mode: max
|
||||
cacheFrom:
|
||||
- registry:
|
||||
ref: "docker.io/pulumi/pulumi:cache-arm64"
|
||||
|
||||
amd64:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "app"
|
||||
platforms:
|
||||
- linux/amd64
|
||||
tags:
|
||||
- "docker.io/pulumi/pulumi:3.107.0-amd64"
|
||||
cacheTo:
|
||||
- registry:
|
||||
ref: "docker.io/pulumi/pulumi:cache-amd64"
|
||||
mode: max
|
||||
cacheFrom:
|
||||
- registry:
|
||||
ref: "docker.io/pulumi/pulumi:cache-amd64"
|
||||
|
||||
index:
|
||||
type: dockerbuild:index:Index
|
||||
properties:
|
||||
tag: "docker.io/pulumi/pulumi:3.107.0"
|
||||
sources:
|
||||
- ${amd64.ref}
|
||||
- ${arm64.ref}
|
||||
|
||||
outputs:
|
||||
ref: ${index.ref}
|
||||
2
examples/app/Dockerfile
Normal file
2
examples/app/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo 👍
|
||||
5
examples/app/Dockerfile.buildArgs
Normal file
5
examples/app/Dockerfile.buildArgs
Normal file
@@ -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! 👍"
|
||||
2
examples/app/Dockerfile.emptyContext
Normal file
2
examples/app/Dockerfile.emptyContext
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍"
|
||||
3
examples/app/Dockerfile.extraHosts
Normal file
3
examples/app/Dockerfile.extraHosts
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM bash AS base
|
||||
|
||||
RUN getent hosts metadata.google.internal
|
||||
7
examples/app/Dockerfile.multiPlatform
Normal file
7
examples/app/Dockerfile.multiPlatform
Normal file
@@ -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
|
||||
5
examples/app/Dockerfile.namedContexts
Normal file
5
examples/app/Dockerfile.namedContexts
Normal file
@@ -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 👍"
|
||||
4
examples/app/Dockerfile.secrets
Normal file
4
examples/app/Dockerfile.secrets
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM alpine
|
||||
|
||||
RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ]
|
||||
|
||||
5
examples/app/Dockerfile.sshMount
Normal file
5
examples/app/Dockerfile.sshMount
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM alpine
|
||||
|
||||
RUN apk add openssh-client
|
||||
|
||||
RUN --mount=type=ssh ssh-add -l
|
||||
8
examples/app/Dockerfile.target
Normal file
8
examples/app/Dockerfile.target
Normal file
@@ -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" ]
|
||||
@@ -5,14 +5,254 @@ using Dockerbuild = Pulumi.Dockerbuild;
|
||||
|
||||
return await Deployment.RunAsync(() =>
|
||||
{
|
||||
var myRandomResource = new Dockerbuild.Random("myRandomResource", new()
|
||||
var config = new Config();
|
||||
var dockerHubPassword = config.Require("dockerHubPassword");
|
||||
var multiPlatform = new Dockerbuild.Image("multiPlatform", new()
|
||||
{
|
||||
Length = 24,
|
||||
Dockerfile = new Dockerbuild.Inputs.DockerfileArgs
|
||||
{
|
||||
Location = "./app/Dockerfile.multiPlatform",
|
||||
},
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
Platforms = new[]
|
||||
{
|
||||
Dockerbuild.Platform.Plan9_amd64,
|
||||
Dockerbuild.Platform.Plan9_386,
|
||||
},
|
||||
});
|
||||
|
||||
var registryPush = new Dockerbuild.Image("registryPush", new()
|
||||
{
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
Tags = new[]
|
||||
{
|
||||
"docker.io/pulumibot/buildkit-e2e:example",
|
||||
},
|
||||
Exports = new[]
|
||||
{
|
||||
new Dockerbuild.Inputs.ExportArgs
|
||||
{
|
||||
Registry = new Dockerbuild.Inputs.ExportRegistryArgs
|
||||
{
|
||||
OciMediaTypes = true,
|
||||
Push = false,
|
||||
},
|
||||
},
|
||||
},
|
||||
Registries = new[]
|
||||
{
|
||||
new Dockerbuild.Inputs.RegistryArgs
|
||||
{
|
||||
Address = "docker.io",
|
||||
Username = "pulumibot",
|
||||
Password = dockerHubPassword,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
var cached = new Dockerbuild.Image("cached", new()
|
||||
{
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
CacheTo = new[]
|
||||
{
|
||||
new Dockerbuild.Inputs.CacheToArgs
|
||||
{
|
||||
Local = new Dockerbuild.Inputs.CacheToLocalArgs
|
||||
{
|
||||
Dest = "tmp/cache",
|
||||
Mode = Dockerbuild.CacheMode.Max,
|
||||
},
|
||||
},
|
||||
},
|
||||
CacheFrom = new[]
|
||||
{
|
||||
new Dockerbuild.Inputs.CacheFromArgs
|
||||
{
|
||||
Local = new Dockerbuild.Inputs.CacheFromLocalArgs
|
||||
{
|
||||
Src = "tmp/cache",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
var buildArgs = new Dockerbuild.Image("buildArgs", new()
|
||||
{
|
||||
Dockerfile = new Dockerbuild.Inputs.DockerfileArgs
|
||||
{
|
||||
Location = "./app/Dockerfile.buildArgs",
|
||||
},
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
BuildArgs =
|
||||
{
|
||||
{ "SET_ME_TO_TRUE", "true" },
|
||||
},
|
||||
});
|
||||
|
||||
var extraHosts = new Dockerbuild.Image("extraHosts", new()
|
||||
{
|
||||
Dockerfile = new Dockerbuild.Inputs.DockerfileArgs
|
||||
{
|
||||
Location = "./app/Dockerfile.extraHosts",
|
||||
},
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
AddHosts = new[]
|
||||
{
|
||||
"metadata.google.internal:169.254.169.254",
|
||||
},
|
||||
});
|
||||
|
||||
var sshMount = new Dockerbuild.Image("sshMount", new()
|
||||
{
|
||||
Dockerfile = new Dockerbuild.Inputs.DockerfileArgs
|
||||
{
|
||||
Location = "./app/Dockerfile.sshMount",
|
||||
},
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
Ssh = new[]
|
||||
{
|
||||
new Dockerbuild.Inputs.SSHArgs
|
||||
{
|
||||
Id = "default",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
var secrets = new Dockerbuild.Image("secrets", new()
|
||||
{
|
||||
Dockerfile = new Dockerbuild.Inputs.DockerfileArgs
|
||||
{
|
||||
Location = "./app/Dockerfile.secrets",
|
||||
},
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
Secrets =
|
||||
{
|
||||
{ "password", "hunter2" },
|
||||
},
|
||||
});
|
||||
|
||||
var labels = new Dockerbuild.Image("labels", new()
|
||||
{
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
Labels =
|
||||
{
|
||||
{ "description", "This image will get a descriptive label 👍" },
|
||||
},
|
||||
});
|
||||
|
||||
var target = new Dockerbuild.Image("target", new()
|
||||
{
|
||||
Dockerfile = new Dockerbuild.Inputs.DockerfileArgs
|
||||
{
|
||||
Location = "./app/Dockerfile.target",
|
||||
},
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
Target = "build-me",
|
||||
});
|
||||
|
||||
var namedContexts = new Dockerbuild.Image("namedContexts", new()
|
||||
{
|
||||
Dockerfile = new Dockerbuild.Inputs.DockerfileArgs
|
||||
{
|
||||
Location = "./app/Dockerfile.namedContexts",
|
||||
},
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
Named =
|
||||
{
|
||||
{ "golang:latest", new Dockerbuild.Inputs.ContextArgs
|
||||
{
|
||||
Location = "docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984",
|
||||
} },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
var remoteContext = new Dockerbuild.Image("remoteContext", new()
|
||||
{
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile",
|
||||
},
|
||||
});
|
||||
|
||||
var remoteContextWithInline = new Dockerbuild.Image("remoteContextWithInline", new()
|
||||
{
|
||||
Dockerfile = new Dockerbuild.Inputs.DockerfileArgs
|
||||
{
|
||||
Inline = @"FROM busybox
|
||||
COPY hello.c ./
|
||||
",
|
||||
},
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "https://github.com/docker-library/hello-world.git",
|
||||
},
|
||||
});
|
||||
|
||||
var inline = new Dockerbuild.Image("inline", new()
|
||||
{
|
||||
Dockerfile = new Dockerbuild.Inputs.DockerfileArgs
|
||||
{
|
||||
Inline = @"FROM alpine
|
||||
RUN echo ""This uses an inline Dockerfile! 👍""
|
||||
",
|
||||
},
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
});
|
||||
|
||||
var dockerLoad = new Dockerbuild.Image("dockerLoad", new()
|
||||
{
|
||||
Context = new Dockerbuild.Inputs.BuildContextArgs
|
||||
{
|
||||
Location = "./app",
|
||||
},
|
||||
Exports = new[]
|
||||
{
|
||||
new Dockerbuild.Inputs.ExportArgs
|
||||
{
|
||||
Docker = new Dockerbuild.Inputs.ExportDockerArgs
|
||||
{
|
||||
Tar = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return new Dictionary<string, object?>
|
||||
{
|
||||
["value"] = myRandomResource.Result,
|
||||
["platforms"] = multiPlatform.Platforms,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
name: provider-dockerbuild
|
||||
runtime: dotnet
|
||||
config:
|
||||
dockerHubPassword:
|
||||
type: string
|
||||
secret: true
|
||||
plugins:
|
||||
providers:
|
||||
- name: dockerbuild
|
||||
|
||||
2
examples/dotnet/app/Dockerfile
Normal file
2
examples/dotnet/app/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo 👍
|
||||
5
examples/dotnet/app/Dockerfile.buildArgs
Normal file
5
examples/dotnet/app/Dockerfile.buildArgs
Normal file
@@ -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! 👍"
|
||||
2
examples/dotnet/app/Dockerfile.emptyContext
Normal file
2
examples/dotnet/app/Dockerfile.emptyContext
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍"
|
||||
3
examples/dotnet/app/Dockerfile.extraHosts
Normal file
3
examples/dotnet/app/Dockerfile.extraHosts
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM bash AS base
|
||||
|
||||
RUN getent hosts metadata.google.internal
|
||||
7
examples/dotnet/app/Dockerfile.multiPlatform
Normal file
7
examples/dotnet/app/Dockerfile.multiPlatform
Normal file
@@ -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
|
||||
5
examples/dotnet/app/Dockerfile.namedContexts
Normal file
5
examples/dotnet/app/Dockerfile.namedContexts
Normal file
@@ -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 👍"
|
||||
4
examples/dotnet/app/Dockerfile.secrets
Normal file
4
examples/dotnet/app/Dockerfile.secrets
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM alpine
|
||||
|
||||
RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ]
|
||||
|
||||
5
examples/dotnet/app/Dockerfile.sshMount
Normal file
5
examples/dotnet/app/Dockerfile.sshMount
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM alpine
|
||||
|
||||
RUN apk add openssh-client
|
||||
|
||||
RUN --mount=type=ssh ssh-add -l
|
||||
8
examples/dotnet/app/Dockerfile.target
Normal file
8
examples/dotnet/app/Dockerfile.target
Normal file
@@ -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" ]
|
||||
@@ -1,5 +1,9 @@
|
||||
name: provider-dockerbuild
|
||||
runtime: go
|
||||
config:
|
||||
dockerHubPassword:
|
||||
type: string
|
||||
secret: true
|
||||
plugins:
|
||||
providers:
|
||||
- name: dockerbuild
|
||||
|
||||
2
examples/go/app/Dockerfile
Normal file
2
examples/go/app/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo 👍
|
||||
5
examples/go/app/Dockerfile.buildArgs
Normal file
5
examples/go/app/Dockerfile.buildArgs
Normal file
@@ -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! 👍"
|
||||
2
examples/go/app/Dockerfile.emptyContext
Normal file
2
examples/go/app/Dockerfile.emptyContext
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍"
|
||||
3
examples/go/app/Dockerfile.extraHosts
Normal file
3
examples/go/app/Dockerfile.extraHosts
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM bash AS base
|
||||
|
||||
RUN getent hosts metadata.google.internal
|
||||
7
examples/go/app/Dockerfile.multiPlatform
Normal file
7
examples/go/app/Dockerfile.multiPlatform
Normal file
@@ -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
|
||||
5
examples/go/app/Dockerfile.namedContexts
Normal file
5
examples/go/app/Dockerfile.namedContexts
Normal file
@@ -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 👍"
|
||||
4
examples/go/app/Dockerfile.secrets
Normal file
4
examples/go/app/Dockerfile.secrets
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM alpine
|
||||
|
||||
RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ]
|
||||
|
||||
5
examples/go/app/Dockerfile.sshMount
Normal file
5
examples/go/app/Dockerfile.sshMount
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM alpine
|
||||
|
||||
RUN apk add openssh-client
|
||||
|
||||
RUN --mount=type=ssh ssh-add -l
|
||||
8
examples/go/app/Dockerfile.target
Normal file
8
examples/go/app/Dockerfile.target
Normal file
@@ -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" ]
|
||||
@@ -3,17 +3,220 @@ package main
|
||||
import (
|
||||
"github.com/pulumi/pulumi-dockerbuild/sdk/go/dockerbuild"
|
||||
"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 {
|
||||
myRandomResource, err := dockerbuild.NewRandom(ctx, "myRandomResource", &dockerbuild.RandomArgs{
|
||||
Length: pulumi.Int(24),
|
||||
cfg := config.New(ctx, "")
|
||||
dockerHubPassword := cfg.Require("dockerHubPassword")
|
||||
multiPlatform, err := dockerbuild.NewImage(ctx, "multiPlatform", &dockerbuild.ImageArgs{
|
||||
Dockerfile: &dockerbuild.DockerfileArgs{
|
||||
Location: pulumi.String("./app/Dockerfile.multiPlatform"),
|
||||
},
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
Platforms: dockerbuild.PlatformArray{
|
||||
dockerbuild.Platform_Plan9_amd64,
|
||||
dockerbuild.Platform_Plan9_386,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Export("value", myRandomResource.Result)
|
||||
_, err = dockerbuild.NewImage(ctx, "registryPush", &dockerbuild.ImageArgs{
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
Tags: pulumi.StringArray{
|
||||
pulumi.String("docker.io/pulumibot/buildkit-e2e:example"),
|
||||
},
|
||||
Exports: dockerbuild.ExportArray{
|
||||
&dockerbuild.ExportArgs{
|
||||
Registry: &dockerbuild.ExportRegistryArgs{
|
||||
OciMediaTypes: pulumi.Bool(true),
|
||||
Push: pulumi.Bool(false),
|
||||
},
|
||||
},
|
||||
},
|
||||
Registries: dockerbuild.RegistryArray{
|
||||
&dockerbuild.RegistryArgs{
|
||||
Address: pulumi.String("docker.io"),
|
||||
Username: pulumi.String("pulumibot"),
|
||||
Password: pulumi.String(dockerHubPassword),
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "cached", &dockerbuild.ImageArgs{
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
CacheTo: dockerbuild.CacheToArray{
|
||||
&dockerbuild.CacheToArgs{
|
||||
Local: &dockerbuild.CacheToLocalArgs{
|
||||
Dest: pulumi.String("tmp/cache"),
|
||||
Mode: dockerbuild.CacheModeMax,
|
||||
},
|
||||
},
|
||||
},
|
||||
CacheFrom: dockerbuild.CacheFromArray{
|
||||
&dockerbuild.CacheFromArgs{
|
||||
Local: &dockerbuild.CacheFromLocalArgs{
|
||||
Src: pulumi.String("tmp/cache"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "buildArgs", &dockerbuild.ImageArgs{
|
||||
Dockerfile: &dockerbuild.DockerfileArgs{
|
||||
Location: pulumi.String("./app/Dockerfile.buildArgs"),
|
||||
},
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
BuildArgs: pulumi.StringMap{
|
||||
"SET_ME_TO_TRUE": pulumi.String("true"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "extraHosts", &dockerbuild.ImageArgs{
|
||||
Dockerfile: &dockerbuild.DockerfileArgs{
|
||||
Location: pulumi.String("./app/Dockerfile.extraHosts"),
|
||||
},
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
AddHosts: pulumi.StringArray{
|
||||
pulumi.String("metadata.google.internal:169.254.169.254"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "sshMount", &dockerbuild.ImageArgs{
|
||||
Dockerfile: &dockerbuild.DockerfileArgs{
|
||||
Location: pulumi.String("./app/Dockerfile.sshMount"),
|
||||
},
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
Ssh: dockerbuild.SSHArray{
|
||||
&dockerbuild.SSHArgs{
|
||||
Id: pulumi.String("default"),
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "secrets", &dockerbuild.ImageArgs{
|
||||
Dockerfile: &dockerbuild.DockerfileArgs{
|
||||
Location: pulumi.String("./app/Dockerfile.secrets"),
|
||||
},
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
Secrets: pulumi.StringMap{
|
||||
"password": pulumi.String("hunter2"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "labels", &dockerbuild.ImageArgs{
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
Labels: pulumi.StringMap{
|
||||
"description": pulumi.String("This image will get a descriptive label 👍"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "target", &dockerbuild.ImageArgs{
|
||||
Dockerfile: &dockerbuild.DockerfileArgs{
|
||||
Location: pulumi.String("./app/Dockerfile.target"),
|
||||
},
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
Target: pulumi.String("build-me"),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "namedContexts", &dockerbuild.ImageArgs{
|
||||
Dockerfile: &dockerbuild.DockerfileArgs{
|
||||
Location: pulumi.String("./app/Dockerfile.namedContexts"),
|
||||
},
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
Named: dockerbuild.ContextMap{
|
||||
"golang:latest": &dockerbuild.ContextArgs{
|
||||
Location: pulumi.String("docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "remoteContext", &dockerbuild.ImageArgs{
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "remoteContextWithInline", &dockerbuild.ImageArgs{
|
||||
Dockerfile: &dockerbuild.DockerfileArgs{
|
||||
Inline: pulumi.String("FROM busybox\nCOPY hello.c ./\n"),
|
||||
},
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("https://github.com/docker-library/hello-world.git"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "inline", &dockerbuild.ImageArgs{
|
||||
Dockerfile: &dockerbuild.DockerfileArgs{
|
||||
Inline: pulumi.String("FROM alpine\nRUN echo \"This uses an inline Dockerfile! 👍\"\n"),
|
||||
},
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dockerbuild.NewImage(ctx, "dockerLoad", &dockerbuild.ImageArgs{
|
||||
Context: &dockerbuild.BuildContextArgs{
|
||||
Location: pulumi.String("./app"),
|
||||
},
|
||||
Exports: dockerbuild.ExportArray{
|
||||
&dockerbuild.ExportArgs{
|
||||
Docker: &dockerbuild.ExportDockerArgs{
|
||||
Tar: pulumi.Bool(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.Export("platforms", multiPlatform.Platforms)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
name: provider-dockerbuild
|
||||
runtime: java
|
||||
config:
|
||||
dockerHubPassword:
|
||||
type: string
|
||||
secret: true
|
||||
plugins:
|
||||
providers:
|
||||
- name: dockerbuild
|
||||
|
||||
2
examples/java/app/Dockerfile
Normal file
2
examples/java/app/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo 👍
|
||||
5
examples/java/app/Dockerfile.buildArgs
Normal file
5
examples/java/app/Dockerfile.buildArgs
Normal file
@@ -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! 👍"
|
||||
2
examples/java/app/Dockerfile.emptyContext
Normal file
2
examples/java/app/Dockerfile.emptyContext
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍"
|
||||
3
examples/java/app/Dockerfile.extraHosts
Normal file
3
examples/java/app/Dockerfile.extraHosts
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM bash AS base
|
||||
|
||||
RUN getent hosts metadata.google.internal
|
||||
7
examples/java/app/Dockerfile.multiPlatform
Normal file
7
examples/java/app/Dockerfile.multiPlatform
Normal file
@@ -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
|
||||
5
examples/java/app/Dockerfile.namedContexts
Normal file
5
examples/java/app/Dockerfile.namedContexts
Normal file
@@ -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 👍"
|
||||
4
examples/java/app/Dockerfile.secrets
Normal file
4
examples/java/app/Dockerfile.secrets
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM alpine
|
||||
|
||||
RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ]
|
||||
|
||||
5
examples/java/app/Dockerfile.sshMount
Normal file
5
examples/java/app/Dockerfile.sshMount
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM alpine
|
||||
|
||||
RUN apk add openssh-client
|
||||
|
||||
RUN --mount=type=ssh ssh-add -l
|
||||
8
examples/java/app/Dockerfile.target
Normal file
8
examples/java/app/Dockerfile.target
Normal file
@@ -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" ]
|
||||
@@ -3,8 +3,19 @@ package generated_program;
|
||||
import com.pulumi.Context;
|
||||
import com.pulumi.Pulumi;
|
||||
import com.pulumi.core.Output;
|
||||
import com.pulumi.dockerbuild.Random;
|
||||
import com.pulumi.dockerbuild.RandomArgs;
|
||||
import com.pulumi.dockerbuild.Image;
|
||||
import com.pulumi.dockerbuild.ImageArgs;
|
||||
import com.pulumi.dockerbuild.inputs.DockerfileArgs;
|
||||
import com.pulumi.dockerbuild.inputs.BuildContextArgs;
|
||||
import com.pulumi.dockerbuild.inputs.ExportArgs;
|
||||
import com.pulumi.dockerbuild.inputs.ExportRegistryArgs;
|
||||
import com.pulumi.dockerbuild.inputs.RegistryArgs;
|
||||
import com.pulumi.dockerbuild.inputs.CacheToArgs;
|
||||
import com.pulumi.dockerbuild.inputs.CacheToLocalArgs;
|
||||
import com.pulumi.dockerbuild.inputs.CacheFromArgs;
|
||||
import com.pulumi.dockerbuild.inputs.CacheFromLocalArgs;
|
||||
import com.pulumi.dockerbuild.inputs.SSHArgs;
|
||||
import com.pulumi.dockerbuild.inputs.ExportDockerArgs;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
@@ -18,10 +29,165 @@ public class App {
|
||||
}
|
||||
|
||||
public static void stack(Context ctx) {
|
||||
var myRandomResource = new Random("myRandomResource", RandomArgs.builder()
|
||||
.length(24)
|
||||
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());
|
||||
|
||||
ctx.export("value", myRandomResource.result());
|
||||
var registryPush = new Image("registryPush", ImageArgs.builder()
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("./app")
|
||||
.build())
|
||||
.tags("docker.io/pulumibot/buildkit-e2e:example")
|
||||
.exports(ExportArgs.builder()
|
||||
.registry(ExportRegistryArgs.builder()
|
||||
.ociMediaTypes(true)
|
||||
.push(false)
|
||||
.build())
|
||||
.build())
|
||||
.registries(RegistryArgs.builder()
|
||||
.address("docker.io")
|
||||
.username("pulumibot")
|
||||
.password(dockerHubPassword)
|
||||
.build())
|
||||
.build());
|
||||
|
||||
var cached = new Image("cached", ImageArgs.builder()
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("./app")
|
||||
.build())
|
||||
.cacheTo(CacheToArgs.builder()
|
||||
.local(CacheToLocalArgs.builder()
|
||||
.dest("tmp/cache")
|
||||
.mode("max")
|
||||
.build())
|
||||
.build())
|
||||
.cacheFrom(CacheFromArgs.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 target = new Image("target", ImageArgs.builder()
|
||||
.dockerfile(DockerfileArgs.builder()
|
||||
.location("./app/Dockerfile.target")
|
||||
.build())
|
||||
.context(BuildContextArgs.builder()
|
||||
.location("./app")
|
||||
.build())
|
||||
.target("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
|
||||
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
|
||||
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(ExportArgs.builder()
|
||||
.docker(ExportDockerArgs.builder()
|
||||
.tar(true)
|
||||
.build())
|
||||
.build())
|
||||
.build());
|
||||
|
||||
ctx.export("platforms", multiPlatform.platforms());
|
||||
}
|
||||
}
|
||||
|
||||
50
examples/main_test.go
Normal file
50
examples/main_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package examples
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/ssh/agent"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
sock := sshagent()
|
||||
os.Setenv("SSH_AUTH_SOCK", sock)
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
// sshagent crates an in-memory SSH agent with one identity.
|
||||
func sshagent() string {
|
||||
dir := os.TempDir()
|
||||
sock := filepath.Join(dir, "test.sock")
|
||||
|
||||
// In case it already exists.
|
||||
_ = os.Remove(sock)
|
||||
|
||||
l, err := net.Listen("unix", sock)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
a := agent.NewKeyring()
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_ = a.Add(agent.AddedKey{PrivateKey: key})
|
||||
|
||||
go func() {
|
||||
conn, err := l.Accept()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
agent.ServeAgent(a, conn)
|
||||
}()
|
||||
|
||||
return sock
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
name: provider-dockerbuild
|
||||
runtime: nodejs
|
||||
config:
|
||||
dockerHubPassword:
|
||||
type: string
|
||||
secret: true
|
||||
plugins:
|
||||
providers:
|
||||
- name: dockerbuild
|
||||
|
||||
2
examples/nodejs/app/Dockerfile
Normal file
2
examples/nodejs/app/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo 👍
|
||||
5
examples/nodejs/app/Dockerfile.buildArgs
Normal file
5
examples/nodejs/app/Dockerfile.buildArgs
Normal file
@@ -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! 👍"
|
||||
2
examples/nodejs/app/Dockerfile.emptyContext
Normal file
2
examples/nodejs/app/Dockerfile.emptyContext
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍"
|
||||
3
examples/nodejs/app/Dockerfile.extraHosts
Normal file
3
examples/nodejs/app/Dockerfile.extraHosts
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM bash AS base
|
||||
|
||||
RUN getent hosts metadata.google.internal
|
||||
7
examples/nodejs/app/Dockerfile.multiPlatform
Normal file
7
examples/nodejs/app/Dockerfile.multiPlatform
Normal file
@@ -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
|
||||
5
examples/nodejs/app/Dockerfile.namedContexts
Normal file
5
examples/nodejs/app/Dockerfile.namedContexts
Normal file
@@ -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 👍"
|
||||
4
examples/nodejs/app/Dockerfile.secrets
Normal file
4
examples/nodejs/app/Dockerfile.secrets
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM alpine
|
||||
|
||||
RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ]
|
||||
|
||||
5
examples/nodejs/app/Dockerfile.sshMount
Normal file
5
examples/nodejs/app/Dockerfile.sshMount
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM alpine
|
||||
|
||||
RUN apk add openssh-client
|
||||
|
||||
RUN --mount=type=ssh ssh-add -l
|
||||
8
examples/nodejs/app/Dockerfile.target
Normal file
8
examples/nodejs/app/Dockerfile.target
Normal file
@@ -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" ]
|
||||
@@ -1,5 +1,156 @@
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as dockerbuild from "@pulumi/dockerbuild";
|
||||
|
||||
const myRandomResource = new dockerbuild.Random("myRandomResource", {length: 24});
|
||||
export const value = myRandomResource.result;
|
||||
const config = new pulumi.Config();
|
||||
const dockerHubPassword = config.require("dockerHubPassword");
|
||||
const multiPlatform = new dockerbuild.Image("multiPlatform", {
|
||||
dockerfile: {
|
||||
location: "./app/Dockerfile.multiPlatform",
|
||||
},
|
||||
context: {
|
||||
location: "./app",
|
||||
},
|
||||
platforms: [
|
||||
dockerbuild.Platform.Plan9_amd64,
|
||||
dockerbuild.Platform.Plan9_386,
|
||||
],
|
||||
});
|
||||
const registryPush = new dockerbuild.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 dockerbuild.Image("cached", {
|
||||
context: {
|
||||
location: "./app",
|
||||
},
|
||||
cacheTo: [{
|
||||
local: {
|
||||
dest: "tmp/cache",
|
||||
mode: dockerbuild.CacheMode.Max,
|
||||
},
|
||||
}],
|
||||
cacheFrom: [{
|
||||
local: {
|
||||
src: "tmp/cache",
|
||||
},
|
||||
}],
|
||||
});
|
||||
const buildArgs = new dockerbuild.Image("buildArgs", {
|
||||
dockerfile: {
|
||||
location: "./app/Dockerfile.buildArgs",
|
||||
},
|
||||
context: {
|
||||
location: "./app",
|
||||
},
|
||||
buildArgs: {
|
||||
SET_ME_TO_TRUE: "true",
|
||||
},
|
||||
});
|
||||
const extraHosts = new dockerbuild.Image("extraHosts", {
|
||||
dockerfile: {
|
||||
location: "./app/Dockerfile.extraHosts",
|
||||
},
|
||||
context: {
|
||||
location: "./app",
|
||||
},
|
||||
addHosts: ["metadata.google.internal:169.254.169.254"],
|
||||
});
|
||||
const sshMount = new dockerbuild.Image("sshMount", {
|
||||
dockerfile: {
|
||||
location: "./app/Dockerfile.sshMount",
|
||||
},
|
||||
context: {
|
||||
location: "./app",
|
||||
},
|
||||
ssh: [{
|
||||
id: "default",
|
||||
}],
|
||||
});
|
||||
const secrets = new dockerbuild.Image("secrets", {
|
||||
dockerfile: {
|
||||
location: "./app/Dockerfile.secrets",
|
||||
},
|
||||
context: {
|
||||
location: "./app",
|
||||
},
|
||||
secrets: {
|
||||
password: "hunter2",
|
||||
},
|
||||
});
|
||||
const labels = new dockerbuild.Image("labels", {
|
||||
context: {
|
||||
location: "./app",
|
||||
},
|
||||
labels: {
|
||||
description: "This image will get a descriptive label 👍",
|
||||
},
|
||||
});
|
||||
const target = new dockerbuild.Image("target", {
|
||||
dockerfile: {
|
||||
location: "./app/Dockerfile.target",
|
||||
},
|
||||
context: {
|
||||
location: "./app",
|
||||
},
|
||||
target: "build-me",
|
||||
});
|
||||
const namedContexts = new dockerbuild.Image("namedContexts", {
|
||||
dockerfile: {
|
||||
location: "./app/Dockerfile.namedContexts",
|
||||
},
|
||||
context: {
|
||||
location: "./app",
|
||||
named: {
|
||||
"golang:latest": {
|
||||
location: "docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const remoteContext = new dockerbuild.Image("remoteContext", {context: {
|
||||
location: "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile",
|
||||
}});
|
||||
const remoteContextWithInline = new dockerbuild.Image("remoteContextWithInline", {
|
||||
dockerfile: {
|
||||
inline: `FROM busybox
|
||||
COPY hello.c ./
|
||||
`,
|
||||
},
|
||||
context: {
|
||||
location: "https://github.com/docker-library/hello-world.git",
|
||||
},
|
||||
});
|
||||
const inline = new dockerbuild.Image("inline", {
|
||||
dockerfile: {
|
||||
inline: `FROM alpine
|
||||
RUN echo "This uses an inline Dockerfile! 👍"
|
||||
`,
|
||||
},
|
||||
context: {
|
||||
location: "./app",
|
||||
},
|
||||
});
|
||||
const dockerLoad = new dockerbuild.Image("dockerLoad", {
|
||||
context: {
|
||||
location: "./app",
|
||||
},
|
||||
exports: [{
|
||||
docker: {
|
||||
tar: true,
|
||||
},
|
||||
}],
|
||||
});
|
||||
export const platforms = multiPlatform.platforms;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
name: provider-dockerbuild
|
||||
runtime: python
|
||||
config:
|
||||
dockerHubPassword:
|
||||
type: string
|
||||
secret: true
|
||||
plugins:
|
||||
providers:
|
||||
- name: dockerbuild
|
||||
|
||||
@@ -1,5 +1,143 @@
|
||||
import pulumi
|
||||
import pulumi_dockerbuild as dockerbuild
|
||||
|
||||
my_random_resource = dockerbuild.Random("myRandomResource", length=24)
|
||||
pulumi.export("value", my_random_resource.result)
|
||||
config = pulumi.Config()
|
||||
docker_hub_password = config.require("dockerHubPassword")
|
||||
multi_platform = dockerbuild.Image("multiPlatform",
|
||||
dockerfile=dockerbuild.DockerfileArgs(
|
||||
location="./app/Dockerfile.multiPlatform",
|
||||
),
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
platforms=[
|
||||
dockerbuild.Platform.PLAN9_AMD64,
|
||||
dockerbuild.Platform.PLAN9_386,
|
||||
])
|
||||
registry_push = dockerbuild.Image("registryPush",
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
tags=["docker.io/pulumibot/buildkit-e2e:example"],
|
||||
exports=[dockerbuild.ExportArgs(
|
||||
registry=dockerbuild.ExportRegistryArgs(
|
||||
oci_media_types=True,
|
||||
push=False,
|
||||
),
|
||||
)],
|
||||
registries=[dockerbuild.RegistryArgs(
|
||||
address="docker.io",
|
||||
username="pulumibot",
|
||||
password=docker_hub_password,
|
||||
)])
|
||||
cached = dockerbuild.Image("cached",
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
cache_to=[dockerbuild.CacheToArgs(
|
||||
local=dockerbuild.CacheToLocalArgs(
|
||||
dest="tmp/cache",
|
||||
mode=dockerbuild.CacheMode.MAX,
|
||||
),
|
||||
)],
|
||||
cache_from=[dockerbuild.CacheFromArgs(
|
||||
local=dockerbuild.CacheFromLocalArgs(
|
||||
src="tmp/cache",
|
||||
),
|
||||
)])
|
||||
build_args = dockerbuild.Image("buildArgs",
|
||||
dockerfile=dockerbuild.DockerfileArgs(
|
||||
location="./app/Dockerfile.buildArgs",
|
||||
),
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
build_args={
|
||||
"SET_ME_TO_TRUE": "true",
|
||||
})
|
||||
extra_hosts = dockerbuild.Image("extraHosts",
|
||||
dockerfile=dockerbuild.DockerfileArgs(
|
||||
location="./app/Dockerfile.extraHosts",
|
||||
),
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
add_hosts=["metadata.google.internal:169.254.169.254"])
|
||||
ssh_mount = dockerbuild.Image("sshMount",
|
||||
dockerfile=dockerbuild.DockerfileArgs(
|
||||
location="./app/Dockerfile.sshMount",
|
||||
),
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
ssh=[dockerbuild.SSHArgs(
|
||||
id="default",
|
||||
)])
|
||||
secrets = dockerbuild.Image("secrets",
|
||||
dockerfile=dockerbuild.DockerfileArgs(
|
||||
location="./app/Dockerfile.secrets",
|
||||
),
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
secrets={
|
||||
"password": "hunter2",
|
||||
})
|
||||
labels = dockerbuild.Image("labels",
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
labels={
|
||||
"description": "This image will get a descriptive label 👍",
|
||||
})
|
||||
target = dockerbuild.Image("target",
|
||||
dockerfile=dockerbuild.DockerfileArgs(
|
||||
location="./app/Dockerfile.target",
|
||||
),
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
target="build-me")
|
||||
named_contexts = dockerbuild.Image("namedContexts",
|
||||
dockerfile=dockerbuild.DockerfileArgs(
|
||||
location="./app/Dockerfile.namedContexts",
|
||||
),
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
named={
|
||||
"golang:latest": dockerbuild.ContextArgs(
|
||||
location="docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984",
|
||||
),
|
||||
},
|
||||
))
|
||||
remote_context = dockerbuild.Image("remoteContext", context=dockerbuild.BuildContextArgs(
|
||||
location="https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile",
|
||||
))
|
||||
remote_context_with_inline = dockerbuild.Image("remoteContextWithInline",
|
||||
dockerfile=dockerbuild.DockerfileArgs(
|
||||
inline="""FROM busybox
|
||||
COPY hello.c ./
|
||||
""",
|
||||
),
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="https://github.com/docker-library/hello-world.git",
|
||||
))
|
||||
inline = dockerbuild.Image("inline",
|
||||
dockerfile=dockerbuild.DockerfileArgs(
|
||||
inline="""FROM alpine
|
||||
RUN echo "This uses an inline Dockerfile! 👍"
|
||||
""",
|
||||
),
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
))
|
||||
docker_load = dockerbuild.Image("dockerLoad",
|
||||
context=dockerbuild.BuildContextArgs(
|
||||
location="./app",
|
||||
),
|
||||
exports=[dockerbuild.ExportArgs(
|
||||
docker=dockerbuild.ExportDockerArgs(
|
||||
tar=True,
|
||||
),
|
||||
)])
|
||||
pulumi.export("platforms", multi_platform.platforms)
|
||||
|
||||
2
examples/python/app/Dockerfile
Normal file
2
examples/python/app/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo 👍
|
||||
5
examples/python/app/Dockerfile.buildArgs
Normal file
5
examples/python/app/Dockerfile.buildArgs
Normal file
@@ -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! 👍"
|
||||
2
examples/python/app/Dockerfile.emptyContext
Normal file
2
examples/python/app/Dockerfile.emptyContext
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍"
|
||||
3
examples/python/app/Dockerfile.extraHosts
Normal file
3
examples/python/app/Dockerfile.extraHosts
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM bash AS base
|
||||
|
||||
RUN getent hosts metadata.google.internal
|
||||
7
examples/python/app/Dockerfile.multiPlatform
Normal file
7
examples/python/app/Dockerfile.multiPlatform
Normal file
@@ -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
|
||||
5
examples/python/app/Dockerfile.namedContexts
Normal file
5
examples/python/app/Dockerfile.namedContexts
Normal file
@@ -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 👍"
|
||||
4
examples/python/app/Dockerfile.secrets
Normal file
4
examples/python/app/Dockerfile.secrets
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM alpine
|
||||
|
||||
RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ]
|
||||
|
||||
5
examples/python/app/Dockerfile.sshMount
Normal file
5
examples/python/app/Dockerfile.sshMount
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM alpine
|
||||
|
||||
RUN apk add openssh-client
|
||||
|
||||
RUN --mount=type=ssh ssh-add -l
|
||||
8
examples/python/app/Dockerfile.target
Normal file
8
examples/python/app/Dockerfile.target
Normal file
@@ -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" ]
|
||||
@@ -17,7 +17,8 @@ func TestPythonExample(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
test := integration.ProgramTestOptions{
|
||||
Dir: path.Join(cwd, "python"),
|
||||
Dir: path.Join(cwd, "python"),
|
||||
RelativeWorkDir: ".",
|
||||
Dependencies: []string{
|
||||
path.Join("..", "sdk", "python", "bin"),
|
||||
},
|
||||
|
||||
@@ -6,10 +6,176 @@ plugins:
|
||||
path: ../../bin
|
||||
|
||||
resources:
|
||||
myRandomResource:
|
||||
type: dockerbuild:Random
|
||||
# docker buildx build -f app/Dockerfile.multiPlatform --platform plan9/amd64,plan9/386 app
|
||||
multiPlatform:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
length: 24
|
||||
dockerfile:
|
||||
location: "./app/Dockerfile.multiPlatform"
|
||||
context:
|
||||
location: "./app"
|
||||
platforms:
|
||||
- plan9/amd64
|
||||
- plan9/386
|
||||
|
||||
# docker buildx build --output=type=registry app
|
||||
registryPush:
|
||||
type: dockerbuild:index: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: dockerbuild:index: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: dockerbuild:index: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: dockerbuild:index: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: dockerbuild:index: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: dockerbuild:index: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: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "./app"
|
||||
labels:
|
||||
description: "This image will get a descriptive label 👍"
|
||||
|
||||
# docker buildx build -f app/Dockerfile.target --target build-me app
|
||||
target:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
dockerfile:
|
||||
location: "./app/Dockerfile.target"
|
||||
context:
|
||||
location: "./app"
|
||||
target: "build-me"
|
||||
|
||||
# docker buildx build -f app/Dockerfile.namedContexts \
|
||||
# --build-context golang:latest=docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984 app
|
||||
namedContexts:
|
||||
type: dockerbuild:index: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: dockerbuild:index: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 <<EOF
|
||||
# FROM busybox
|
||||
# COPY hello.c ./
|
||||
# EOF
|
||||
remoteContextWithInline:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
dockerfile:
|
||||
inline: |
|
||||
FROM busybox
|
||||
COPY hello.c ./
|
||||
context:
|
||||
location: "https://github.com/docker-library/hello-world.git"
|
||||
|
||||
# echo "FROM alpine" | docker buildx build -f - .
|
||||
inline:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
dockerfile:
|
||||
inline: |
|
||||
FROM alpine
|
||||
RUN echo "This uses an inline Dockerfile! 👍"
|
||||
context:
|
||||
location: "./app"
|
||||
|
||||
# docker buildx build --load .
|
||||
dockerLoad:
|
||||
type: dockerbuild:index:Image
|
||||
properties:
|
||||
context:
|
||||
location: "./app"
|
||||
exports:
|
||||
- docker:
|
||||
tar: true
|
||||
|
||||
# docker buildx build - < app/Dockerfile.emptyContext
|
||||
#emptyContext:
|
||||
# type: dockerbuild:index:Image
|
||||
# properties:
|
||||
# file: "app/Dockerfile.emptyContext"
|
||||
# context: "-"
|
||||
config:
|
||||
dockerHubPassword:
|
||||
type: string
|
||||
secret: true
|
||||
|
||||
outputs:
|
||||
value: ${myRandomResource.result}
|
||||
platforms: ${multiPlatform.platforms}
|
||||
|
||||
2
examples/yaml/app/Dockerfile
Normal file
2
examples/yaml/app/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo 👍
|
||||
5
examples/yaml/app/Dockerfile.buildArgs
Normal file
5
examples/yaml/app/Dockerfile.buildArgs
Normal file
@@ -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! 👍"
|
||||
2
examples/yaml/app/Dockerfile.emptyContext
Normal file
2
examples/yaml/app/Dockerfile.emptyContext
Normal file
@@ -0,0 +1,2 @@
|
||||
FROM alpine
|
||||
RUN echo "This image doesn't use any local files, so it doesn't need a context parameter 👍"
|
||||
3
examples/yaml/app/Dockerfile.extraHosts
Normal file
3
examples/yaml/app/Dockerfile.extraHosts
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM bash AS base
|
||||
|
||||
RUN getent hosts metadata.google.internal
|
||||
7
examples/yaml/app/Dockerfile.multiPlatform
Normal file
7
examples/yaml/app/Dockerfile.multiPlatform
Normal file
@@ -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
|
||||
5
examples/yaml/app/Dockerfile.namedContexts
Normal file
5
examples/yaml/app/Dockerfile.namedContexts
Normal file
@@ -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 👍"
|
||||
4
examples/yaml/app/Dockerfile.secrets
Normal file
4
examples/yaml/app/Dockerfile.secrets
Normal file
@@ -0,0 +1,4 @@
|
||||
FROM alpine
|
||||
|
||||
RUN --mount=type=secret,id=password [ "$(cat /run/secrets/password)" = "hunter2" ]
|
||||
|
||||
5
examples/yaml/app/Dockerfile.sshMount
Normal file
5
examples/yaml/app/Dockerfile.sshMount
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM alpine
|
||||
|
||||
RUN apk add openssh-client
|
||||
|
||||
RUN --mount=type=ssh ssh-add -l
|
||||
8
examples/yaml/app/Dockerfile.target
Normal file
8
examples/yaml/app/Dockerfile.target
Normal file
@@ -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" ]
|
||||
389
go.mod
389
go.mod
@@ -4,25 +4,51 @@ go 1.21.7
|
||||
|
||||
require (
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
github.com/pulumi/pulumi-go-provider v0.14.1-0.20240301190400-aeddefa8dc54
|
||||
github.com/pulumi/pulumi-go-provider/integration v0.10.0
|
||||
github.com/distribution/reference v0.5.0
|
||||
github.com/docker/buildx v0.12.0-rc2.0.20240214233841-c9d1c41d206c
|
||||
github.com/docker/cli v25.0.3+incompatible
|
||||
github.com/docker/distribution v2.8.2+incompatible
|
||||
github.com/docker/docker v25.0.2+incompatible
|
||||
github.com/golangci/golangci-lint v1.57.1
|
||||
github.com/moby/buildkit v0.13.0-beta3.0.20240205165705-d6e142600ee5
|
||||
github.com/moby/patternmatcher v0.6.0
|
||||
github.com/muesli/reflow v0.3.0
|
||||
github.com/otiai10/copy v1.14.0
|
||||
github.com/pulumi/pulumi-go-provider v0.14.1-0.20240314105842-9fbffb634faf
|
||||
github.com/pulumi/pulumi-go-provider/integration v0.10.1-0.20240314105842-9fbffb634faf
|
||||
github.com/pulumi/pulumi-java/pkg v0.9.9
|
||||
github.com/pulumi/pulumi/pkg/v3 v3.111.1
|
||||
github.com/pulumi/pulumi/sdk/v3 v3.111.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/pulumi/pulumi/pkg/v3 v3.111.2-0.20240324200353-583e06df0c70
|
||||
github.com/pulumi/pulumi/sdk/v3 v3.111.2-0.20240324200353-583e06df0c70
|
||||
github.com/regclient/regclient v0.0.0-20240308005156-a7434cff9c6b
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/afero v1.11.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/theupdateframework/notary v0.7.0
|
||||
github.com/tonistiigi/fsutil v0.0.0-20240301111122-7525a1af2bb5
|
||||
go.uber.org/mock v0.3.0
|
||||
google.golang.org/protobuf v1.33.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.10 // indirect
|
||||
4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
|
||||
4d63.com/gochecknoglobals v0.2.1 // indirect
|
||||
cloud.google.com/go v0.112.0 // indirect
|
||||
cloud.google.com/go/compute v1.23.3 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.5 // indirect
|
||||
cloud.google.com/go/kms v1.15.5 // indirect
|
||||
cloud.google.com/go/logging v1.8.1 // indirect
|
||||
cloud.google.com/go/logging v1.9.0 // indirect
|
||||
cloud.google.com/go/longrunning v0.5.4 // indirect
|
||||
cloud.google.com/go/storage v1.35.1 // indirect
|
||||
cloud.google.com/go/storage v1.36.0 // indirect
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
github.com/4meepo/tagalign v1.3.3 // indirect
|
||||
github.com/Abirdcfly/dupword v0.0.14 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
|
||||
github.com/Antonboom/errname v0.1.12 // indirect
|
||||
github.com/Antonboom/nilnil v0.1.7 // indirect
|
||||
github.com/Antonboom/testifylint v1.2.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 // indirect
|
||||
@@ -33,125 +59,236 @@ require (
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect
|
||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/Microsoft/hcsshim v0.11.4 // indirect
|
||||
github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/alecthomas/chroma v0.10.0 // indirect
|
||||
github.com/alecthomas/go-check-sumtype v0.1.4 // indirect
|
||||
github.com/alexkohler/nakedret/v2 v2.0.4 // indirect
|
||||
github.com/alexkohler/prealloc v1.0.0 // indirect
|
||||
github.com/alingse/asasalint v0.0.11 // indirect
|
||||
github.com/apparentlymart/go-cidr v1.1.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/armon/go-metrics v0.4.0 // indirect
|
||||
github.com/armon/go-metrics v0.4.1 // indirect
|
||||
github.com/armon/go-radix v1.0.0 // indirect
|
||||
github.com/ashanbrown/forbidigo v1.6.0 // indirect
|
||||
github.com/ashanbrown/makezero v1.1.1 // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aws/aws-sdk-go v1.49.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.26.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.9 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.27.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.47.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.48.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
|
||||
github.com/aws/smithy-go v1.19.0 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/ccojocar/zxcvbn-go v1.0.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bkielbasa/cyclop v1.2.1 // indirect
|
||||
github.com/blizzy78/varnamelen v0.8.0 // indirect
|
||||
github.com/bombsimon/wsl/v4 v4.2.1 // indirect
|
||||
github.com/breml/bidichk v0.2.7 // indirect
|
||||
github.com/breml/errchkjson v0.3.6 // indirect
|
||||
github.com/butuzov/ireturn v0.3.0 // indirect
|
||||
github.com/butuzov/mirror v1.1.0 // indirect
|
||||
github.com/catenacyber/perfsprint v0.7.1 // indirect
|
||||
github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
|
||||
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/charithe/durationcheck v0.0.10 // indirect
|
||||
github.com/charmbracelet/bubbles v0.16.1 // indirect
|
||||
github.com/charmbracelet/bubbletea v0.24.2 // indirect
|
||||
github.com/charmbracelet/glamour v0.6.0 // indirect
|
||||
github.com/charmbracelet/lipgloss v0.7.1 // indirect
|
||||
github.com/chavacava/garif v0.1.0 // indirect
|
||||
github.com/cheggaaa/pb v1.0.29 // indirect
|
||||
github.com/ckaznocha/intrange v0.1.0 // indirect
|
||||
github.com/cloudflare/circl v1.3.7 // indirect
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/compose-spec/compose-go/v2 v2.0.0-rc.8 // indirect
|
||||
github.com/containerd/console v1.0.4 // indirect
|
||||
github.com/containerd/containerd v1.7.12 // indirect
|
||||
github.com/containerd/continuity v0.4.2 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/ttrpc v1.2.2 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.1.1 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
|
||||
github.com/curioswitch/go-reassign v0.2.0 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
||||
github.com/daixiang0/gci v0.12.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/deckarep/golang-set/v2 v2.5.0 // indirect
|
||||
github.com/denis-tingaikin/go-header v0.5.0 // indirect
|
||||
github.com/djherbis/times v1.5.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||
github.com/docker/cli-docs-tool v0.6.0 // indirect
|
||||
github.com/docker/docker-credential-helpers v0.8.0 // indirect
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/edsrzf/mmap-go v1.1.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/erikgeiser/promptkit v0.9.0 // indirect
|
||||
github.com/ettle/strcase v0.1.1 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/ettle/strcase v0.2.0 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/fatih/structtag v1.2.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/firefart/nonamedreturns v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/fvbommel/sortorder v1.1.0 // indirect
|
||||
github.com/fzipp/gocyclo v0.6.0 // indirect
|
||||
github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 // indirect
|
||||
github.com/ghostiam/protogetter v0.3.5 // indirect
|
||||
github.com/go-critic/go-critic v0.11.2 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.5.0 // indirect
|
||||
github.com/go-git/go-git/v5 v5.11.0 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/logr v1.3.0 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/gofrs/uuid v4.3.1+incompatible // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/swag v0.21.1 // indirect
|
||||
github.com/go-toolsmith/astcast v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astcopy v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astequal v1.2.0 // indirect
|
||||
github.com/go-toolsmith/astfmt v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astp v1.1.0 // indirect
|
||||
github.com/go-toolsmith/strparse v1.1.0 // indirect
|
||||
github.com/go-toolsmith/typep v1.1.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect
|
||||
github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/gofrs/uuid v4.2.0+incompatible // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.1.0 // indirect
|
||||
github.com/golang/glog v1.1.2 // indirect
|
||||
github.com/golang/glog v1.2.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
|
||||
github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e // indirect
|
||||
github.com/golangci/misspell v0.4.1 // indirect
|
||||
github.com/golangci/plugin-module-register v0.1.1 // indirect
|
||||
github.com/golangci/revgrep v0.5.2 // indirect
|
||||
github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect
|
||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20230406165453-00490a63f317 // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.4.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||
github.com/gordonklaus/ineffassign v0.1.0 // indirect
|
||||
github.com/gorilla/css v1.0.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
|
||||
github.com/gostaticanalysis/comment v1.4.2 // indirect
|
||||
github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
|
||||
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-hclog v1.2.2 // indirect
|
||||
github.com/hashicorp/go-cty-funcs v0.0.0-20230405223818-a090f58aa992 // indirect
|
||||
github.com/hashicorp/go-hclog v1.5.0 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-plugin v1.4.6 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.0 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/mlock v0.1.2 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 // indirect
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.18.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.19.1 // indirect
|
||||
github.com/hashicorp/vault/api v1.8.2 // indirect
|
||||
github.com/hashicorp/vault/sdk v0.6.1 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||
github.com/hexops/valast v1.4.4 // indirect
|
||||
github.com/iancoleman/strcase v0.2.0 // indirect
|
||||
github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/in-toto/in-toto-golang v0.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jgautheron/goconst v1.7.0 // indirect
|
||||
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
|
||||
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
|
||||
github.com/jjti/go-spancheck v0.5.3 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/julz/importas v0.1.0 // indirect
|
||||
github.com/karamaru-alpha/copyloopvar v1.0.8 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/kisielk/errcheck v1.7.0 // indirect
|
||||
github.com/kkHAIKE/contextcheck v1.1.4 // indirect
|
||||
github.com/klauspost/compress v1.17.4 // indirect
|
||||
github.com/kulti/thelper v0.6.3 // indirect
|
||||
github.com/kunwardeep/paralleltest v1.0.10 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/kyoh86/exportloopref v0.1.11 // indirect
|
||||
github.com/ldez/gomoddirectives v0.2.3 // indirect
|
||||
github.com/ldez/tagliatelle v0.5.0 // indirect
|
||||
github.com/leonklingele/grouper v1.1.1 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/lufeee/execinquery v1.2.1 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/macabu/inamedparam v0.1.3 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/maratori/testableexamples v1.0.0 // indirect
|
||||
github.com/maratori/testpackage v1.1.1 // indirect
|
||||
github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/mattn/go-shellwords v1.0.12 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mgechev/revive v1.3.7 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.21 // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-ps v1.0.0 // indirect
|
||||
@@ -159,20 +296,36 @@ require (
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/moby v23.0.3+incompatible // indirect
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/moby v25.0.4+incompatible // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/moby/sys/mountinfo v0.7.1 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/signal v0.7.0 // indirect
|
||||
github.com/moby/sys/user v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/moricho/tparallel v0.3.1 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/reflow v0.3.0 // indirect
|
||||
github.com/muesli/termenv v0.15.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/nakabonne/nestif v0.3.1 // indirect
|
||||
github.com/natefinch/atomic v1.0.1 // indirect
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d // indirect
|
||||
github.com/nishanths/exhaustive v0.12.0 // indirect
|
||||
github.com/nishanths/predeclared v0.2.2 // indirect
|
||||
github.com/nunnatsa/ginkgolinter v0.16.1 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
|
||||
github.com/opentracing/basictracer-go v1.1.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
|
||||
github.com/petar-dambovaliev/aho-corasick v0.0.0-20230725210150-fb29fc3c913e // indirect
|
||||
github.com/pgavlin/diff v0.0.0-20230503175810-113847418e2e // indirect
|
||||
github.com/pgavlin/fx v0.1.6 // indirect
|
||||
@@ -184,75 +337,151 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/term v1.1.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/polyfloyd/go-errorlint v1.4.8 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/client_golang v1.16.0 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.10.1 // indirect
|
||||
github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect
|
||||
github.com/pulumi/esc v0.6.2 // indirect
|
||||
github.com/pulumi/pulumi-yaml v1.6.0 // indirect
|
||||
github.com/quasilyte/go-ruleguard v0.4.2 // indirect
|
||||
github.com/quasilyte/gogrep v0.5.0 // indirect
|
||||
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
|
||||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/ryancurrah/gomodguard v1.3.1 // indirect
|
||||
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
|
||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect
|
||||
github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
|
||||
github.com/segmentio/asm v1.2.0 // indirect
|
||||
github.com/segmentio/encoding v0.3.6 // indirect
|
||||
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
|
||||
github.com/sashamelentyev/usestdlibvars v1.25.0 // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect
|
||||
github.com/securego/gosec/v2 v2.19.0 // indirect
|
||||
github.com/segmentio/asm v1.1.3 // indirect
|
||||
github.com/segmentio/encoding v0.3.5 // indirect
|
||||
github.com/sergi/go-diff v1.3.1 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.22.3 // indirect
|
||||
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 // indirect
|
||||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.24.2 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect
|
||||
github.com/sivchari/containedctx v1.0.3 // indirect
|
||||
github.com/sivchari/tenv v1.7.1 // indirect
|
||||
github.com/skeema/knownhosts v1.2.1 // indirect
|
||||
github.com/sonatard/noctx v0.0.2 // indirect
|
||||
github.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/cobra v1.7.0 // indirect
|
||||
github.com/sourcegraph/go-diff v0.7.0 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/cobra v1.8.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.12.0 // indirect
|
||||
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
|
||||
github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect
|
||||
github.com/tdakkota/asciicheck v0.2.0 // indirect
|
||||
github.com/tetafro/godot v1.4.16 // indirect
|
||||
github.com/texttheater/golang-levenshtein v1.0.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||
github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect
|
||||
github.com/timonwong/loggercheck v0.9.4 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/tomarrell/wrapcheck/v2 v2.8.3 // indirect
|
||||
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
|
||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
||||
github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 // indirect
|
||||
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 // indirect
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||
github.com/ulikunitz/xz v0.5.11 // indirect
|
||||
github.com/ultraware/funlen v0.1.0 // indirect
|
||||
github.com/ultraware/whitespace v0.1.0 // indirect
|
||||
github.com/uudashr/gocognit v1.1.2 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
github.com/xen0n/gosmopolitan v1.2.2 // indirect
|
||||
github.com/yagipy/maintidx v1.0.0 // indirect
|
||||
github.com/yeya24/promlinter v0.2.0 // indirect
|
||||
github.com/ykadowak/zerologlint v0.1.5 // indirect
|
||||
github.com/yuin/goldmark v1.5.2 // indirect
|
||||
github.com/yuin/goldmark-emoji v1.0.1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
github.com/zclconf/go-cty v1.14.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
github.com/zclconf/go-cty v1.14.1 // indirect
|
||||
gitlab.com/bosi/decorder v0.4.1 // indirect
|
||||
go-simpler.org/musttag v0.9.0 // indirect
|
||||
go-simpler.org/sloglint v0.5.0 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/otel v1.19.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.45.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
|
||||
go.opentelemetry.io/otel v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.42.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.21.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||
go.pennock.tech/tabular v1.1.3 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/automaxprocs v1.5.3 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.26.0 // indirect
|
||||
gocloud.dev v0.36.0 // indirect
|
||||
gocloud.dev/secrets/hashivault v0.27.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
golang.org/x/net v0.19.0 // indirect
|
||||
golang.org/x/oauth2 v0.14.0 // indirect
|
||||
golang.org/x/sync v0.5.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/term v0.15.0 // indirect
|
||||
gocloud.dev/secrets/hashivault v0.28.0 // indirect
|
||||
golang.org/x/crypto v0.21.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect
|
||||
golang.org/x/mod v0.16.0 // indirect
|
||||
golang.org/x/net v0.22.0 // indirect
|
||||
golang.org/x/oauth2 v0.16.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/term v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.4.0 // indirect
|
||||
golang.org/x/tools v0.15.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.19.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/api v0.151.0 // indirect
|
||||
google.golang.org/api v0.155.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/grpc v1.62.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
honnef.co/go/tools v0.4.7 // indirect
|
||||
k8s.io/api v0.26.7 // indirect
|
||||
k8s.io/apimachinery v0.26.7 // indirect
|
||||
k8s.io/apiserver v0.26.7 // indirect
|
||||
k8s.io/client-go v0.26.7 // indirect
|
||||
k8s.io/klog/v2 v2.90.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
||||
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect
|
||||
lukechampine.com/frand v1.4.2 // indirect
|
||||
mvdan.cc/gofumpt v0.6.0 // indirect
|
||||
mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2016-2023, Pulumi Corporation.
|
||||
// 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.
|
||||
@@ -12,13 +12,18 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package main invokes the provider as a gRPC server and runs forever.
|
||||
package main
|
||||
|
||||
import (
|
||||
p "github.com/pulumi/pulumi-go-provider"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil"
|
||||
|
||||
xyz "github.com/pulumi/pulumi-dockerbuild/provider"
|
||||
"github.com/pulumi/pulumi-dockerbuild/provider"
|
||||
)
|
||||
|
||||
// Serve the provider against Pulumi's Provider protocol.
|
||||
func main() { _ = p.RunProvider(xyz.Name, xyz.Version, xyz.Provider()) }
|
||||
func main() {
|
||||
err := provider.Serve()
|
||||
if err != nil {
|
||||
cmdutil.ExitError(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
16
provider/doc.go
Normal file
16
provider/doc.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// 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.
|
||||
|
||||
// Package provider serves a Docker Buildx Pulumi provider.
|
||||
package provider
|
||||
31
provider/internal/auth.go
Normal file
31
provider/internal/auth.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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.
|
||||
|
||||
package internal
|
||||
|
||||
import "github.com/pulumi/pulumi-go-provider/infer"
|
||||
|
||||
// Registry contains credentials for authenticating with a remote registry.
|
||||
type Registry struct {
|
||||
Address string `pulumi:"address"`
|
||||
Password string `pulumi:"password,optional" provider:"secret"`
|
||||
Username string `pulumi:"username,optional"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on Registry.
|
||||
func (r *Registry) Annotate(a infer.Annotator) {
|
||||
a.Describe(&r.Address, `The registry's address (e.g. "docker.io").`)
|
||||
a.Describe(&r.Username, `Username for the registry.`)
|
||||
a.Describe(&r.Password, `Password or token for the registry.`)
|
||||
}
|
||||
38
provider/internal/builder.go
Normal file
38
provider/internal/builder.go
Normal file
@@ -0,0 +1,38 @@
|
||||
// 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.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"github.com/pulumi/pulumi-go-provider/infer"
|
||||
)
|
||||
|
||||
var _ infer.Annotated = (*BuilderConfig)(nil)
|
||||
|
||||
// BuilderConfig configures the builder to use for an image build.
|
||||
type BuilderConfig struct {
|
||||
Name string `pulumi:"name,optional"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on BuilderConfig.
|
||||
func (b *BuilderConfig) Annotate(a infer.Annotator) {
|
||||
a.Describe(&b.Name, dedent(`
|
||||
Name of an existing buildx builder to use.
|
||||
|
||||
Only "docker-container", "kubernetes", or "remote" drivers are
|
||||
supported. The legacy "docker" driver is not supported.
|
||||
|
||||
Equivalent to Docker's "--builder" flag.
|
||||
`))
|
||||
}
|
||||
744
provider/internal/cache.go
Normal file
744
provider/internal/cache.go
Normal file
@@ -0,0 +1,744 @@
|
||||
// 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.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
controllerapi "github.com/docker/buildx/controller/pb"
|
||||
"github.com/docker/buildx/util/buildflags"
|
||||
|
||||
"github.com/pulumi/pulumi-go-provider/infer"
|
||||
)
|
||||
|
||||
var (
|
||||
_ fmt.Stringer = (*CacheFrom)(nil)
|
||||
_ fmt.Stringer = (*CacheFromAzureBlob)(nil)
|
||||
_ fmt.Stringer = (*CacheFromGitHubActions)(nil)
|
||||
_ fmt.Stringer = (*CacheFromLocal)(nil)
|
||||
_ fmt.Stringer = (*CacheFromRegistry)(nil)
|
||||
_ fmt.Stringer = (*CacheFromS3)(nil)
|
||||
_ fmt.Stringer = (*CacheTo)(nil)
|
||||
_ fmt.Stringer = (*CacheToAzureBlob)(nil)
|
||||
_ fmt.Stringer = (*CacheToGitHubActions)(nil)
|
||||
_ fmt.Stringer = (*CacheToInline)(nil)
|
||||
_ fmt.Stringer = (*CacheToLocal)(nil)
|
||||
_ fmt.Stringer = (*CacheToRegistry)(nil)
|
||||
_ fmt.Stringer = (*CacheToS3)(nil)
|
||||
_ fmt.Stringer = CacheWithCompression{}
|
||||
_ fmt.Stringer = CacheWithIgnoreError{}
|
||||
_ fmt.Stringer = CacheWithMode{}
|
||||
_ fmt.Stringer = CacheWithOCI{}
|
||||
_ infer.Annotated = (*CacheFrom)(nil)
|
||||
_ infer.Annotated = (*CacheFromAzureBlob)(nil)
|
||||
_ infer.Annotated = (*CacheFromGitHubActions)(nil)
|
||||
_ infer.Annotated = (*CacheFromLocal)(nil)
|
||||
_ infer.Annotated = (*CacheFromRegistry)(nil)
|
||||
_ infer.Annotated = (*CacheFromS3)(nil)
|
||||
_ infer.Annotated = (*CacheTo)(nil)
|
||||
_ infer.Annotated = (*CacheToInline)(nil)
|
||||
_ infer.Annotated = (*CacheToLocal)(nil)
|
||||
_ infer.Annotated = (*CacheWithCompression)(nil)
|
||||
_ infer.Annotated = (*CacheWithIgnoreError)(nil)
|
||||
_ infer.Annotated = (*CacheWithMode)(nil)
|
||||
_ infer.Annotated = (*CacheWithOCI)(nil)
|
||||
_ infer.Enum[CacheMode] = (*CacheMode)(nil)
|
||||
_ infer.Enum[CompressionType] = (*CompressionType)(nil)
|
||||
)
|
||||
|
||||
// CacheFromLocal pulls cache manifests from a local directory.
|
||||
type CacheFromLocal struct {
|
||||
Src string `pulumi:"src"`
|
||||
Digest string `pulumi:"digest,optional"`
|
||||
}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if the receiver is nil.
|
||||
func (c *CacheFromLocal) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
parts := []string{"type=local"}
|
||||
if c.Src != "" {
|
||||
parts = append(parts, "src="+c.Src)
|
||||
}
|
||||
if c.Digest != "" {
|
||||
parts = append(parts, "digest="+c.Digest)
|
||||
}
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on CacheFromLocal.
|
||||
func (c *CacheFromLocal) Annotate(a infer.Annotator) {
|
||||
a.Describe(&c.Src, "Path of the local directory where cache gets imported from.")
|
||||
a.Describe(&c.Digest, "Digest of manifest to import.")
|
||||
}
|
||||
|
||||
// CacheFromRegistry pulls cache manifests from a registry ref.
|
||||
type CacheFromRegistry struct {
|
||||
Ref string `pulumi:"ref"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on CacheFromRegistry.
|
||||
func (c *CacheFromRegistry) Annotate(a infer.Annotator) {
|
||||
a.Describe(&c.Ref, "Fully qualified name of the cache image to import.")
|
||||
}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if the receiver is nil.
|
||||
func (c *CacheFromRegistry) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return "type=registry,ref=" + c.Ref
|
||||
}
|
||||
|
||||
// CacheWithOCI exposes OCI media type options.
|
||||
type CacheWithOCI struct {
|
||||
OCI *bool `pulumi:"ociMediaTypes,optional"`
|
||||
ImageManifest *bool `pulumi:"imageManifest,optional"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on CacheWithOCI.
|
||||
func (c *CacheWithOCI) Annotate(a infer.Annotator) {
|
||||
a.Describe(&c.OCI, dedent(`
|
||||
Whether to use OCI media types in exported manifests. Defaults to
|
||||
"true".
|
||||
`))
|
||||
a.Describe(&c.ImageManifest, dedent(`
|
||||
Export cache manifest as an OCI-compatible image manifest instead of a
|
||||
manifest list. Requires "ociMediaTypes" to also be "true".
|
||||
|
||||
Some registries like AWS ECR will not work with caching if this is
|
||||
"false".
|
||||
|
||||
Defaults to "false" to match Docker's default behavior.
|
||||
`))
|
||||
|
||||
a.SetDefault(&c.OCI, true)
|
||||
a.SetDefault(&c.ImageManifest, false)
|
||||
}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if unknown.
|
||||
func (c CacheWithOCI) String() string {
|
||||
if c.OCI == nil {
|
||||
return ""
|
||||
}
|
||||
parts := []string{fmt.Sprintf("oci-mediatypes=%t", *c.OCI)}
|
||||
if c.ImageManifest != nil {
|
||||
parts = append(parts, fmt.Sprintf("image-manifest=%t", *c.ImageManifest))
|
||||
}
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
|
||||
// CacheFromGitHubActions pulls cache manifests from the GitHub actions cache.
|
||||
type CacheFromGitHubActions struct {
|
||||
URL string `pulumi:"url,optional"`
|
||||
Token string `pulumi:"token,optional" provider:"secret"`
|
||||
Scope string `pulumi:"scope,optional"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on CacheFromGitHubActions.
|
||||
func (c *CacheFromGitHubActions) Annotate(a infer.Annotator) {
|
||||
a.SetDefault(&c.URL, "", "ACTIONS_RUNTIME_URL")
|
||||
a.SetDefault(&c.Token, "", "ACTIONS_RUNTIME_TOKEN")
|
||||
a.SetDefault(&c.Scope, "", "buildkit")
|
||||
|
||||
a.Describe(&c.URL, dedent(`
|
||||
The cache server URL to use for artifacts.
|
||||
|
||||
Defaults to "$ACTIONS_RUNTIME_URL", although a separate action like
|
||||
"crazy-max/ghaction-github-runtime" is recommended to expose this
|
||||
environment variable to your jobs.
|
||||
`))
|
||||
a.Describe(&c.Token, dedent(`
|
||||
The GitHub Actions token to use. This is not a personal access tokens
|
||||
and is typically generated automatically as part of each job.
|
||||
|
||||
Defaults to "$ACTIONS_RUNTIME_TOKEN", although a separate action like
|
||||
"crazy-max/ghaction-github-runtime" is recommended to expose this
|
||||
environment variable to your jobs.
|
||||
|
||||
`))
|
||||
a.Describe(&c.Scope, dedent(`
|
||||
The scope to use for cache keys. Defaults to "buildkit".
|
||||
|
||||
This should be set if building and caching multiple images in one
|
||||
workflow, otherwise caches will overwrite each other.
|
||||
`))
|
||||
}
|
||||
|
||||
func (c *CacheFromGitHubActions) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
parts := []string{"type=gha"}
|
||||
if c.Scope != "" {
|
||||
parts = append(parts, "scope="+c.Scope)
|
||||
}
|
||||
if c.Token != "" {
|
||||
parts = append(parts, "token="+c.Token)
|
||||
}
|
||||
if c.URL != "" {
|
||||
parts = append(parts, "url="+c.URL)
|
||||
}
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
|
||||
// CacheFromAzureBlob pulls cache manifests from Azure
|
||||
// blob storage.
|
||||
type CacheFromAzureBlob struct {
|
||||
Name string `pulumi:"name"`
|
||||
AccountURL string `pulumi:"accountUrl,optional"`
|
||||
SecretAccessKey string `pulumi:"secretAccessKey,optional" provider:"secret"`
|
||||
}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if the receiver is nil.
|
||||
func (c *CacheFromAzureBlob) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
parts := []string{"type=azblob"}
|
||||
if c.Name != "" {
|
||||
parts = append(parts, "name="+c.Name)
|
||||
}
|
||||
if c.AccountURL != "" {
|
||||
parts = append(parts, "account_url="+c.AccountURL)
|
||||
}
|
||||
if c.SecretAccessKey != "" {
|
||||
parts = append(parts, "secret_access_key="+c.SecretAccessKey)
|
||||
}
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on CacheFromAzureBlob.
|
||||
func (c *CacheFromAzureBlob) Annotate(a infer.Annotator) {
|
||||
a.Describe(&c.Name, "The name of the cache image.")
|
||||
a.Describe(&c.AccountURL, "Base URL of the storage account.")
|
||||
a.Describe(&c.SecretAccessKey, "Blob storage account key.")
|
||||
}
|
||||
|
||||
// CacheToAzureBlob pushes cache manifests to Azure blob storage.
|
||||
type CacheToAzureBlob struct {
|
||||
CacheWithMode
|
||||
CacheWithIgnoreError
|
||||
|
||||
CacheFromAzureBlob
|
||||
}
|
||||
|
||||
func (c *CacheToAzureBlob) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return join(&c.CacheFromAzureBlob, c.CacheWithMode, c.CacheWithIgnoreError)
|
||||
}
|
||||
|
||||
// CacheFromS3 pulls cache manifests from S3-compatible APIs.
|
||||
type CacheFromS3 struct {
|
||||
Region string `pulumi:"region"`
|
||||
Bucket string `pulumi:"bucket"`
|
||||
Name string `pulumi:"name,optional"`
|
||||
EndpointURL string `pulumi:"endpointUrl,optional"`
|
||||
BlobsPrefix string `pulumi:"blobsPrefix,optional"`
|
||||
ManifestsPrefix string `pulumi:"manifestsPrefix,optional"`
|
||||
UsePathStyle *bool `pulumi:"usePathStyle,optional"`
|
||||
AccessKeyID string `pulumi:"accessKeyId,optional"`
|
||||
SecretAccessKey string `pulumi:"secretAccessKey,optional" provider:"secret"`
|
||||
SessionToken string `pulumi:"sessionToken,optional" provider:"secret"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings and defaults on CacheFromS3.
|
||||
func (c *CacheFromS3) Annotate(a infer.Annotator) {
|
||||
a.SetDefault(&c.Region, "", "AWS_REGION")
|
||||
a.SetDefault(&c.AccessKeyID, "", "AWS_ACCESS_KEY_ID")
|
||||
a.SetDefault(&c.SecretAccessKey, "", "AWS_SECRET_ACCESS_KEY")
|
||||
a.SetDefault(&c.SessionToken, "", "AWS_SESSION_TOKEN")
|
||||
|
||||
a.Describe(&c.Bucket, dedent(`
|
||||
Name of the S3 bucket.
|
||||
`))
|
||||
a.Describe(&c.Region, dedent(`
|
||||
The geographic location of the bucket. Defaults to "$AWS_REGION".
|
||||
`))
|
||||
a.Describe(&c.AccessKeyID, dedent(`
|
||||
Defaults to "$AWS_ACCESS_KEY_ID".
|
||||
`))
|
||||
a.Describe(&c.SecretAccessKey, dedent(`
|
||||
Defaults to "$AWS_SECRET_ACCESS_KEY".
|
||||
`))
|
||||
a.Describe(&c.SessionToken, dedent(`
|
||||
Defaults to "$AWS_SESSION_TOKEN".
|
||||
`))
|
||||
a.Describe(&c.BlobsPrefix, dedent(`
|
||||
Prefix to prepend to blob filenames.
|
||||
`))
|
||||
a.Describe(&c.EndpointURL, dedent(`
|
||||
Endpoint of the S3 bucket.
|
||||
`))
|
||||
a.Describe(&c.ManifestsPrefix, dedent(`
|
||||
Prefix to prepend on manifest filenames.
|
||||
`))
|
||||
a.Describe(&c.Name, dedent(`
|
||||
Name of the cache image.
|
||||
`))
|
||||
a.Describe(&c.UsePathStyle, dedent(`
|
||||
Uses "bucket" in the URL instead of hostname when "true".
|
||||
`))
|
||||
}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if the receiver is nil.
|
||||
func (c *CacheFromS3) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
parts := []string{"type=s3"}
|
||||
if c.Bucket != "" {
|
||||
parts = append(parts, "bucket="+c.Bucket)
|
||||
}
|
||||
if c.Name != "" {
|
||||
parts = append(parts, "name="+c.Name)
|
||||
}
|
||||
if c.EndpointURL != "" {
|
||||
parts = append(parts, "endpoint_url="+c.EndpointURL)
|
||||
}
|
||||
if c.BlobsPrefix != "" {
|
||||
parts = append(parts, "blobs_prefix="+c.BlobsPrefix)
|
||||
}
|
||||
if c.ManifestsPrefix != "" {
|
||||
parts = append(parts, "manifests_prefix="+c.ManifestsPrefix)
|
||||
}
|
||||
if c.UsePathStyle != nil {
|
||||
parts = append(parts, fmt.Sprintf("use_path_type=%t", *c.UsePathStyle))
|
||||
}
|
||||
if c.AccessKeyID != "" {
|
||||
parts = append(parts, "access_key_id="+c.AccessKeyID)
|
||||
}
|
||||
if c.SecretAccessKey != "" {
|
||||
parts = append(parts, "secret_access_key="+c.SecretAccessKey)
|
||||
}
|
||||
if c.SessionToken != "" {
|
||||
parts = append(parts, "session_token="+c.SessionToken)
|
||||
}
|
||||
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
|
||||
// CacheWithMode is a cache that can configure its mode.
|
||||
type CacheWithMode struct {
|
||||
Mode CacheMode `pulumi:"mode,optional"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings and defaults on CacheWithMode.
|
||||
func (c *CacheWithMode) Annotate(a infer.Annotator) {
|
||||
a.SetDefault(&c.Mode, Min)
|
||||
a.Describe(&c.Mode, dedent(`
|
||||
The cache mode to use. Defaults to "min".
|
||||
`))
|
||||
}
|
||||
|
||||
func (c CacheWithMode) String() string {
|
||||
if c.Mode == "" {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("mode=%s", c.Mode)
|
||||
}
|
||||
|
||||
// CacheWithIgnoreError exposes an option to ignore errors during caching.
|
||||
type CacheWithIgnoreError struct {
|
||||
IgnoreError *bool `pulumi:"ignoreError,optional"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings and defaults on CacheWithIgnoreError.
|
||||
func (c *CacheWithIgnoreError) Annotate(a infer.Annotator) {
|
||||
a.SetDefault(&c.IgnoreError, false)
|
||||
a.Describe(&c.IgnoreError, "Ignore errors caused by failed cache exports.")
|
||||
}
|
||||
|
||||
func (c CacheWithIgnoreError) String() string {
|
||||
if c.IgnoreError == nil {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("ignore-error=%t", *c.IgnoreError)
|
||||
}
|
||||
|
||||
// CacheToS3 pushes cache manifests to an S3-compatible API.
|
||||
type CacheToS3 struct {
|
||||
CacheWithMode
|
||||
CacheWithIgnoreError
|
||||
|
||||
CacheFromS3
|
||||
}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if the receiver is nil.
|
||||
func (c *CacheToS3) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return join(&c.CacheFromS3, c.CacheWithMode, c.CacheWithIgnoreError)
|
||||
}
|
||||
|
||||
// Raw is a CLI-encoded cache entry appropriate for passing directly to the
|
||||
// CLI. Useful if the Docker backend supports cache types not captured by our
|
||||
// API, or if the user just prefers "type=..." inputs.
|
||||
type Raw string
|
||||
|
||||
// String return the raw string as-is. This can be empty during previews where
|
||||
// the user has provided a value but it is unknown.
|
||||
func (c Raw) String() string {
|
||||
return string(c)
|
||||
}
|
||||
|
||||
// CacheFrom is a "union" type for all of our available `--cache-from` options.
|
||||
type CacheFrom struct {
|
||||
Local *CacheFromLocal `pulumi:"local,optional"`
|
||||
Registry *CacheFromRegistry `pulumi:"registry,optional"`
|
||||
GHA *CacheFromGitHubActions `pulumi:"gha,optional"`
|
||||
AZBlob *CacheFromAzureBlob `pulumi:"azblob,optional"`
|
||||
S3 *CacheFromS3 `pulumi:"s3,optional"`
|
||||
Raw Raw `pulumi:"raw,optional"`
|
||||
|
||||
Disabled bool `pulumi:"disabled,optional"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings and defaults on CacheFrom.
|
||||
func (c *CacheFrom) Annotate(a infer.Annotator) {
|
||||
a.Describe(&c.Local, dedent(`
|
||||
A simple backend which caches images on your local filesystem.
|
||||
`))
|
||||
a.Describe(&c.Registry, dedent(`
|
||||
Upload build caches to remote registries.
|
||||
`))
|
||||
a.Describe(&c.GHA, dedent(`
|
||||
Recommended for use with GitHub Actions workflows.
|
||||
|
||||
An action like "crazy-max/ghaction-github-runtime" is recommended to
|
||||
expose appropriate credentials to your GitHub workflow.
|
||||
`))
|
||||
a.Describe(&c.AZBlob, dedent(`
|
||||
Upload build caches to Azure's blob storage service.
|
||||
`))
|
||||
a.Describe(&c.S3, dedent(`
|
||||
Upload build caches to AWS S3 or an S3-compatible services such as
|
||||
MinIO.
|
||||
`))
|
||||
a.Describe(&c.Raw, dedent(`
|
||||
A raw string as you would provide it to the Docker CLI (e.g.,
|
||||
"type=inline").
|
||||
`))
|
||||
|
||||
a.Describe(&c.Disabled, dedent(`
|
||||
When "true" this entry will be excluded. Defaults to "false".
|
||||
`))
|
||||
}
|
||||
|
||||
// String returns a CLI-encoded value for this `--cache-from` entry, or an
|
||||
// empty string if disabled. `validate` should be called to ensure only one
|
||||
// entry was set.
|
||||
func (c CacheFrom) String() string {
|
||||
if c.Disabled {
|
||||
return ""
|
||||
}
|
||||
return join(c.Local, c.Registry, c.GHA, c.AZBlob, c.S3, c.Raw)
|
||||
}
|
||||
|
||||
func (c CacheFrom) validate(preview bool) (*controllerapi.CacheOptionsEntry, error) {
|
||||
if strings.Count(c.String(), "type=") > 1 {
|
||||
return nil, errors.New("cacheFrom should only specify one cache type")
|
||||
}
|
||||
parsed, err := buildflags.ParseCacheEntry([]string{c.String()})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(parsed) == 0 {
|
||||
// This can happen for example if we have a GHA cache but no GitHub
|
||||
// environment variables set.
|
||||
// Shouldn't happen...
|
||||
return nil, nil
|
||||
}
|
||||
return parsed[0], nil
|
||||
}
|
||||
|
||||
// CacheToInline embeds cache information directly into an image.
|
||||
type CacheToInline struct{}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if unknown.
|
||||
func (c *CacheToInline) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return "type=inline"
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on CacheToInline.
|
||||
func (c *CacheToInline) Annotate(a infer.Annotator) {
|
||||
a.Describe(&c, dedent(`
|
||||
Include an inline cache with the exported image.
|
||||
`))
|
||||
}
|
||||
|
||||
// CacheToLocal writes cache manifests to a local directory.
|
||||
type CacheToLocal struct {
|
||||
CacheWithCompression
|
||||
CacheWithIgnoreError
|
||||
CacheWithMode
|
||||
|
||||
Dest string `pulumi:"dest"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on CacheToLocal.
|
||||
func (c *CacheToLocal) Annotate(a infer.Annotator) {
|
||||
a.Describe(&c.Dest, dedent(`
|
||||
Path of the local directory to export the cache.
|
||||
`))
|
||||
}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if the receiver is nil.
|
||||
func (c *CacheToLocal) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return join(
|
||||
Raw("type=local,dest="+c.Dest),
|
||||
c.CacheWithCompression,
|
||||
c.CacheWithIgnoreError,
|
||||
)
|
||||
}
|
||||
|
||||
// CacheToRegistry pushes cache manifests to a remote registry.
|
||||
type CacheToRegistry struct {
|
||||
CacheWithMode
|
||||
CacheWithIgnoreError
|
||||
CacheWithOCI
|
||||
CacheWithCompression
|
||||
|
||||
CacheFromRegistry
|
||||
}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if the receiver is nil.
|
||||
func (c *CacheToRegistry) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return join(
|
||||
&c.CacheFromRegistry,
|
||||
c.CacheWithMode,
|
||||
c.CacheWithIgnoreError,
|
||||
c.CacheWithOCI,
|
||||
c.CacheWithCompression,
|
||||
)
|
||||
}
|
||||
|
||||
// CacheWithCompression is a cache with options to configure compression
|
||||
// settings.
|
||||
type CacheWithCompression struct {
|
||||
Compression CompressionType `pulumi:"compression,optional"`
|
||||
CompressionLevel int `pulumi:"compressionLevel,optional"`
|
||||
ForceCompression *bool `pulumi:"forceCompression,optional"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings and defaults on CacheWithCompression.
|
||||
func (c *CacheWithCompression) Annotate(a infer.Annotator) {
|
||||
a.SetDefault(&c.Compression, Gzip)
|
||||
a.SetDefault(&c.CompressionLevel, 0)
|
||||
a.SetDefault(&c.ForceCompression, false)
|
||||
|
||||
a.Describe(&c.Compression, "The compression type to use.")
|
||||
a.Describe(&c.CompressionLevel, "Compression level from 0 to 22.")
|
||||
a.Describe(&c.ForceCompression, "Forcefully apply compression.")
|
||||
}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if the receiver is nil.
|
||||
func (c CacheWithCompression) String() string {
|
||||
if c.CompressionLevel == 0 {
|
||||
return ""
|
||||
}
|
||||
parts := []string{}
|
||||
if c.Compression != "" {
|
||||
parts = append(parts, fmt.Sprintf("compression=%s", c.Compression))
|
||||
}
|
||||
if c.CompressionLevel > 0 {
|
||||
cl := c.CompressionLevel
|
||||
if cl > 22 {
|
||||
cl = 22
|
||||
}
|
||||
parts = append(parts, fmt.Sprintf("compression-level=%d", cl))
|
||||
}
|
||||
if c.ForceCompression != nil {
|
||||
parts = append(parts, fmt.Sprintf("force-compression=%t", *c.ForceCompression))
|
||||
}
|
||||
return strings.Join(parts, ",")
|
||||
}
|
||||
|
||||
// CacheToGitHubActions pushes cache manifests to the GitHub Actions cache
|
||||
// backend.
|
||||
type CacheToGitHubActions struct {
|
||||
CacheWithMode
|
||||
CacheWithIgnoreError
|
||||
|
||||
CacheFromGitHubActions
|
||||
}
|
||||
|
||||
// String returns the CLI-encoded value of these cache options, or an empty
|
||||
// string if the receiver is nil.
|
||||
func (c *CacheToGitHubActions) String() string {
|
||||
if c == nil {
|
||||
return ""
|
||||
}
|
||||
return join(&c.CacheFromGitHubActions, c.CacheWithMode, c.CacheWithIgnoreError)
|
||||
}
|
||||
|
||||
// CacheTo is a "union" type for all of our available `--cache-to` options.
|
||||
type CacheTo struct {
|
||||
Inline *CacheToInline `pulumi:"inline,optional"`
|
||||
Local *CacheToLocal `pulumi:"local,optional"`
|
||||
Registry *CacheToRegistry `pulumi:"registry,optional"`
|
||||
GHA *CacheToGitHubActions `pulumi:"gha,optional"`
|
||||
AZBlob *CacheToAzureBlob `pulumi:"azblob,optional"`
|
||||
S3 *CacheToS3 `pulumi:"s3,optional"`
|
||||
Raw Raw `pulumi:"raw,optional"`
|
||||
|
||||
Disabled bool `pulumi:"disabled,optional"`
|
||||
}
|
||||
|
||||
// Annotate sets docstrings and defaults on CacheTo.
|
||||
func (c *CacheTo) Annotate(a infer.Annotator) {
|
||||
a.Describe(&c.Inline, dedent(`
|
||||
The inline cache storage backend is the simplest implementation to get
|
||||
started with, but it does not handle multi-stage builds. Consider the
|
||||
"registry" cache backend instead.
|
||||
`))
|
||||
a.Describe(&c.Local, dedent(`
|
||||
A simple backend which caches imagines on your local filesystem.
|
||||
`))
|
||||
a.Describe(&c.Registry, dedent(`
|
||||
Push caches to remote registries. Incompatible with the "docker" build
|
||||
driver.
|
||||
`))
|
||||
a.Describe(&c.GHA, dedent(`
|
||||
Recommended for use with GitHub Actions workflows.
|
||||
|
||||
An action like "crazy-max/ghaction-github-runtime" is recommended to
|
||||
expose appropriate credentials to your GitHub workflow.
|
||||
`))
|
||||
a.Describe(&c.AZBlob, dedent(`
|
||||
Push cache to Azure's blob storage service.
|
||||
`))
|
||||
a.Describe(&c.S3, dedent(`
|
||||
Push cache to AWS S3 or S3-compatible services such as MinIO.
|
||||
`))
|
||||
a.Describe(&c.Raw, dedent(`
|
||||
A raw string as you would provide it to the Docker CLI (e.g.,
|
||||
"type=inline")`,
|
||||
))
|
||||
|
||||
a.Describe(&c.Disabled, dedent(`
|
||||
When "true" this entry will be excluded. Defaults to "false".
|
||||
`))
|
||||
}
|
||||
|
||||
// String returns a CLI-encoded value for this `--cache-to` entry, or an
|
||||
// empty string if disabled. `validate` should be called to ensure only one
|
||||
// entry was set.
|
||||
func (c CacheTo) String() string {
|
||||
if c.Disabled {
|
||||
return ""
|
||||
}
|
||||
return join(c.Inline, c.Local, c.Registry, c.GHA, c.AZBlob, c.S3, c.Raw)
|
||||
}
|
||||
|
||||
func (c CacheTo) validate(preview bool) (*controllerapi.CacheOptionsEntry, error) {
|
||||
if strings.Count(c.String(), "type=") > 1 {
|
||||
return nil, errors.New("cacheTo should only specify one cache type")
|
||||
}
|
||||
parsed, err := buildflags.ParseCacheEntry([]string{c.String()})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(parsed) == 0 {
|
||||
// This can happen for example if we have a GHA cache but no GitHub
|
||||
// environment variables set.
|
||||
// Shouldn't happen...
|
||||
return nil, nil
|
||||
}
|
||||
return parsed[0], nil
|
||||
}
|
||||
|
||||
// CacheMode controls the complexity of exported cache manifests.
|
||||
type CacheMode string
|
||||
|
||||
const (
|
||||
Min CacheMode = "min" // Min cache mode.
|
||||
Max CacheMode = "max" // Max cache mode.
|
||||
)
|
||||
|
||||
// Values returns all valid CacheMode values for SDK generation.
|
||||
func (CacheMode) Values() []infer.EnumValue[CacheMode] {
|
||||
return []infer.EnumValue[CacheMode]{
|
||||
{
|
||||
Value: Min,
|
||||
Description: "Only layers that are exported into the resulting image are cached.",
|
||||
},
|
||||
{
|
||||
Value: Max,
|
||||
Description: "All layers are cached, even those of intermediate steps.",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// CompressionType is the algorithm used for compressing blobs.
|
||||
type CompressionType string
|
||||
|
||||
const (
|
||||
Gzip CompressionType = "gzip" // Gzip compression.
|
||||
Estargz CompressionType = "estargz" // Estargz compression.
|
||||
Zstd CompressionType = "zstd" // Zstd compression.
|
||||
)
|
||||
|
||||
// Values returns all valid CompressionType values for SDK generation.
|
||||
func (CompressionType) Values() []infer.EnumValue[CompressionType] {
|
||||
return []infer.EnumValue[CompressionType]{
|
||||
{Value: Gzip, Description: "Use `gzip` for compression."},
|
||||
{Value: Estargz, Description: "Use `estargz` for compression."},
|
||||
{Value: Zstd, Description: "Use `zstd` for compression."},
|
||||
}
|
||||
}
|
||||
|
||||
type joiner struct{ sep string }
|
||||
|
||||
func (j joiner) join(ss ...fmt.Stringer) string {
|
||||
parts := []string{}
|
||||
for _, s := range ss {
|
||||
p := s.String()
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
parts = append(parts, p)
|
||||
}
|
||||
return strings.Join(parts, j.sep)
|
||||
}
|
||||
|
||||
func join(ss ...fmt.Stringer) string {
|
||||
return joiner{","}.join(ss...)
|
||||
}
|
||||
138
provider/internal/cache_test.go
Normal file
138
provider/internal/cache_test.go
Normal file
@@ -0,0 +1,138 @@
|
||||
// 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.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/buildx/util/buildflags"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
)
|
||||
|
||||
func TestCacheString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
given fmt.Stringer
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "s3",
|
||||
given: CacheTo{S3: &CacheToS3{
|
||||
CacheFromS3: CacheFromS3{
|
||||
Region: "us-west-2",
|
||||
Bucket: "bucket-foo",
|
||||
Name: "myname",
|
||||
EndpointURL: "https://some.endpoint",
|
||||
BlobsPrefix: "blob-prefix",
|
||||
ManifestsPrefix: "manifest-prefix",
|
||||
UsePathStyle: pulumi.BoolRef(true),
|
||||
AccessKeyID: "access-key-id",
|
||||
SecretAccessKey: "secret-key",
|
||||
SessionToken: "session",
|
||||
},
|
||||
}},
|
||||
//nolint:lll // Taken from AWS reference docs.
|
||||
want: "type=s3,bucket=bucket-foo,name=myname,endpoint_url=https://some.endpoint,blobs_prefix=blob-prefix,manifests_prefix=manifest-prefix,use_path_type=true,access_key_id=access-key-id,secret_access_key=secret-key,session_token=session",
|
||||
},
|
||||
{
|
||||
name: "gha",
|
||||
given: CacheTo{GHA: &CacheToGitHubActions{}},
|
||||
want: "type=gha",
|
||||
},
|
||||
{
|
||||
name: "from-local",
|
||||
given: CacheFrom{Local: &CacheFromLocal{Src: "/foo/bar"}},
|
||||
want: "type=local,src=/foo/bar",
|
||||
},
|
||||
{
|
||||
name: "to-local",
|
||||
given: CacheTo{Local: &CacheToLocal{Dest: "/foo/bar"}},
|
||||
want: "type=local,dest=/foo/bar",
|
||||
},
|
||||
{
|
||||
name: "inline",
|
||||
given: CacheTo{Inline: &CacheToInline{}},
|
||||
want: "type=inline",
|
||||
},
|
||||
{
|
||||
name: "raw",
|
||||
given: CacheTo{Raw: Raw("type=gha")},
|
||||
want: "type=gha",
|
||||
},
|
||||
{
|
||||
name: "compression",
|
||||
given: CacheTo{Local: &CacheToLocal{
|
||||
Dest: "/foo",
|
||||
CacheWithCompression: CacheWithCompression{
|
||||
Compression: "gz2",
|
||||
CompressionLevel: 100,
|
||||
ForceCompression: pulumi.BoolRef(true),
|
||||
},
|
||||
}},
|
||||
want: "type=local,dest=/foo,compression=gz2,compression-level=22,force-compression=true",
|
||||
},
|
||||
{
|
||||
name: "ignore-error",
|
||||
given: CacheTo{
|
||||
AZBlob: &CacheToAzureBlob{
|
||||
CacheWithIgnoreError: CacheWithIgnoreError{pulumi.BoolRef(true)},
|
||||
},
|
||||
},
|
||||
want: "type=azblob,ignore-error=true",
|
||||
},
|
||||
{
|
||||
name: "oci",
|
||||
given: CacheTo{
|
||||
Registry: &CacheToRegistry{
|
||||
CacheFromRegistry: CacheFromRegistry{Ref: "docker.io/foo/bar:baz"},
|
||||
CacheWithOCI: CacheWithOCI{
|
||||
OCI: pulumi.BoolRef(true),
|
||||
ImageManifest: pulumi.BoolRef(true),
|
||||
},
|
||||
},
|
||||
},
|
||||
want: "type=registry,ref=docker.io/foo/bar:baz,oci-mediatypes=true,image-manifest=true",
|
||||
},
|
||||
{
|
||||
name: "disabled-to",
|
||||
given: CacheTo{
|
||||
Raw: Raw("type=gha"),
|
||||
Disabled: true,
|
||||
},
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := tt.given.String()
|
||||
assert.Equal(t, tt.want, actual)
|
||||
|
||||
if tt.want != "" {
|
||||
// Our output should be parsable by Docker.
|
||||
_, err := buildflags.ParseCacheEntry([]string{actual})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
386
provider/internal/cli.go
Normal file
386
provider/internal/cli.go
Normal file
@@ -0,0 +1,386 @@
|
||||
// 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:generate go run go.uber.org/mock/mockgen -typed -package internal -source client.go -destination mockcli_test.go --self_package github.com/pulumi/pulumi-dockerbuild/provider/internal
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/buildx/commands"
|
||||
"github.com/docker/cli/cli-plugins/manager"
|
||||
"github.com/docker/cli/cli/command"
|
||||
cfgtypes "github.com/docker/cli/cli/config/types"
|
||||
"github.com/docker/cli/cli/streams"
|
||||
"github.com/moby/buildkit/client"
|
||||
cp "github.com/otiai10/copy"
|
||||
"github.com/regclient/regclient"
|
||||
"github.com/regclient/regclient/config"
|
||||
|
||||
provider "github.com/pulumi/pulumi-go-provider"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/diag"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
||||
)
|
||||
|
||||
// cli wraps a DockerCLI instance with scoped auth credentials. It satisfies
|
||||
// the Cli interface so it can be used with Docker's cobra.Commands directly.
|
||||
//
|
||||
// It buffers stdout/stderr, and layers temporary auth configs on top of the
|
||||
// host's existing auth.
|
||||
type cli struct {
|
||||
command.Cli
|
||||
|
||||
auths map[string]cfgtypes.AuthConfig
|
||||
host *host
|
||||
|
||||
in string // stdin
|
||||
r, w *os.File // stdout
|
||||
err bytes.Buffer // stderr
|
||||
done chan struct{} // signaled when all logs have been forwarded to the engine.
|
||||
}
|
||||
|
||||
// Cli wraps the Docker interface for mock generation.
|
||||
type Cli interface {
|
||||
command.Cli
|
||||
}
|
||||
|
||||
// wrap creates a new cli client with auth configs layered on top of our host's
|
||||
// auth.
|
||||
func wrap(host *host, registries ...Registry) (*cli, error) {
|
||||
// We need to create a new DockerCLI instance because we don't want the
|
||||
// auth changes we make to the ConfigFile to leak to the host.
|
||||
docker, err := newDockerCLI(host.config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
auths := map[string]cfgtypes.AuthConfig{}
|
||||
for k, v := range host.auths {
|
||||
auths[k] = v
|
||||
}
|
||||
|
||||
for _, r := range registries {
|
||||
// HostNewName takes care of DockerHub's special-casing for us.
|
||||
h := config.HostNewName(r.Address)
|
||||
auths[h.CredHost] = cfgtypes.AuthConfig{
|
||||
ServerAddress: h.Hostname,
|
||||
Username: r.Username,
|
||||
Password: r.Password,
|
||||
}
|
||||
}
|
||||
|
||||
// Override our config's auth and disable any credential helpers. Auth
|
||||
// lookups will now only return whatever we have in memory.
|
||||
cfg := docker.ConfigFile()
|
||||
cfg.AuthConfigs = auths
|
||||
cfg.CredentialHelpers = nil
|
||||
cfg.CredentialsStore = ""
|
||||
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wrapped := &cli{
|
||||
Cli: docker,
|
||||
host: host,
|
||||
auths: auths,
|
||||
r: r,
|
||||
w: w,
|
||||
}
|
||||
|
||||
return wrapped, nil
|
||||
}
|
||||
|
||||
func (c *cli) In() *streams.In {
|
||||
return streams.NewIn(io.NopCloser(strings.NewReader(c.in)))
|
||||
}
|
||||
|
||||
func (c *cli) Out() *streams.Out {
|
||||
return streams.NewOut(c.w)
|
||||
}
|
||||
|
||||
func (c *cli) Err() io.Writer {
|
||||
return &c.err
|
||||
}
|
||||
|
||||
// rc returns a registry client with matching auth.
|
||||
func (c *cli) rc() *regclient.RegClient {
|
||||
hosts := []config.Host{}
|
||||
for k, v := range c.auths {
|
||||
h := config.HostNewName(k)
|
||||
h.User = v.Username
|
||||
h.Pass = v.Password
|
||||
hosts = append(hosts, *h)
|
||||
}
|
||||
return regclient.New(
|
||||
regclient.WithConfigHost(hosts...),
|
||||
)
|
||||
}
|
||||
|
||||
// tail is meant to be called as a goroutine and will pipe output from the CLI
|
||||
// back to the Pulumi engine. Requires a corresponding call to close.
|
||||
func (c *cli) tail(ctx provider.Context) {
|
||||
c.done = make(chan struct{}, 1)
|
||||
defer func() {
|
||||
c.done <- struct{}{}
|
||||
if err := recover(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "recovered: %s\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
s := bufio.NewScanner(c.r)
|
||||
for s.Scan() {
|
||||
ctx.LogStatus(diag.Info, s.Text())
|
||||
}
|
||||
ctx.LogStatus(diag.Info, "") // clear confusing "DONE" statements.
|
||||
}
|
||||
|
||||
// close flushes any outstanding logs and cleans up resources.
|
||||
func (c *cli) Close() error {
|
||||
err := c.w.Close()
|
||||
err = errors.Join(err, c.r.Close())
|
||||
if c.done != nil {
|
||||
<-c.done
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// execBuild performs a build by os.Exec'ing the docker-buildx binary.
|
||||
// Credentials are communicated to docker-buildx via a temporary directory.
|
||||
// Secrets are communicated via dynamic environment variables.
|
||||
func (c *cli) execBuild(b Build) (*client.SolveResponse, error) {
|
||||
// Setup a temporary directory for auth, and clean it up when we're done.
|
||||
tmp, err := os.MkdirTemp("", "pulumi-docker-")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer contract.IgnoreError(os.RemoveAll(tmp))
|
||||
|
||||
opts := b.BuildOptions()
|
||||
|
||||
builder, err := c.host.builderFor(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Docker expects a "$DOCKER_CONFIG/contexts" directory in addition to
|
||||
// "$DOCKER_CONFIG/config.json", so we attempt to copy this from the host
|
||||
// to our temporary directory. This doesn't always exist, so we ignore errors.
|
||||
hostConfigDir := filepath.Dir(c.ConfigFile().Filename)
|
||||
_ = cp.Copy(
|
||||
filepath.Join(hostConfigDir, "contexts"),
|
||||
filepath.Join(tmp, "contexts"),
|
||||
)
|
||||
|
||||
// Save our temporary credentials to $tmp/config.json.
|
||||
tmpCfg := filepath.Join(tmp, filepath.Base(c.ConfigFile().Filename))
|
||||
c.ConfigFile().Filename = tmpCfg
|
||||
err = c.ConfigFile().Save()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We will spawn docker-buildx with DOCKER_CONFIG set to our temporary
|
||||
// directory for auth, but BUILDX_CONFIG will point to the host. There's a
|
||||
// bunch of builder state in there that we want to preserve.
|
||||
env := []string{
|
||||
"DOCKER_CONFIG=" + tmp,
|
||||
"BUILDX_CONFIG=" + filepath.Join(hostConfigDir, "buildx"),
|
||||
}
|
||||
|
||||
// We need to write to this file in order to recover information about the
|
||||
// build, like the digest.
|
||||
metadata := filepath.Clean(filepath.Join(tmp, "metadata.json"))
|
||||
args := []string{
|
||||
"buildx",
|
||||
"build",
|
||||
"--progress", "plain",
|
||||
"--metadata-file", metadata,
|
||||
"--builder", builder.name,
|
||||
}
|
||||
|
||||
// TODO: --allow
|
||||
// TODO: --annotation
|
||||
// TODO: --attest
|
||||
// TODO: --cgroup-parent
|
||||
|
||||
for k, v := range opts.BuildArgs {
|
||||
args = append(args, "--build-arg", fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
if opts.Builder != "" {
|
||||
args = append(args, "--builder", opts.Builder)
|
||||
}
|
||||
for _, c := range opts.CacheFrom {
|
||||
args = append(args, "--cache-from", attrcsv(c.Type, c.Attrs))
|
||||
}
|
||||
for _, c := range opts.CacheTo {
|
||||
args = append(args, "--cache-to", attrcsv(c.Type, c.Attrs))
|
||||
}
|
||||
if opts.ExportLoad {
|
||||
args = append(args, "--load")
|
||||
}
|
||||
if opts.ExportPush {
|
||||
args = append(args, "--push")
|
||||
}
|
||||
for _, e := range opts.Exports {
|
||||
args = append(args, "--output", attrcsv(e.Type, e.Attrs))
|
||||
}
|
||||
for _, h := range opts.ExtraHosts {
|
||||
args = append(args, "--add-host", h)
|
||||
}
|
||||
for k, v := range opts.NamedContexts {
|
||||
args = append(args, "--build-context", fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
for k, v := range opts.Labels {
|
||||
args = append(args, "--label", fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
if opts.NetworkMode != "" {
|
||||
args = append(args, "--network", opts.NetworkMode)
|
||||
}
|
||||
if opts.NoCache {
|
||||
args = append(args, "--no-cache")
|
||||
}
|
||||
for _, p := range opts.Platforms {
|
||||
args = append(args, "--platform", p)
|
||||
}
|
||||
if opts.Pull {
|
||||
args = append(args, "--pull")
|
||||
}
|
||||
for _, ssh := range opts.SSH {
|
||||
s := ssh.ID
|
||||
if len(ssh.Paths) > 0 {
|
||||
s += "=" + strings.Join(ssh.Paths, ",")
|
||||
}
|
||||
args = append(args, "--ssh", s)
|
||||
}
|
||||
for _, t := range opts.Tags {
|
||||
args = append(args, "--tag", t)
|
||||
}
|
||||
if opts.Target != "" {
|
||||
args = append(args, "--target", opts.Target)
|
||||
}
|
||||
if opts.DockerfileName != "" {
|
||||
args = append(args, "-f", opts.DockerfileName)
|
||||
}
|
||||
if in := b.Inline(); in != "" {
|
||||
c.in = in
|
||||
args = append(args, "-f", "-")
|
||||
}
|
||||
if opts.ContextPath != "" {
|
||||
args = append(args, opts.ContextPath)
|
||||
}
|
||||
|
||||
// We pass secrets by value via dynamic PULUMI_DOCKER_* environment
|
||||
// variables.
|
||||
for _, s := range opts.Secrets {
|
||||
envvar, err := resource.NewUniqueHex("PULUMI_DOCKER_", 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// We abuse the pb.Secret proto by stuffing the secret's value in
|
||||
// XXX_unrecognized. We never serialize this proto so this is tolerable.
|
||||
env = append(env, fmt.Sprintf("%s=%s", envvar, s.XXX_unrecognized))
|
||||
args = append(args, "--secret", fmt.Sprintf("id=%s,env=%s", s.ID, envvar))
|
||||
}
|
||||
|
||||
// Invoke docker-buildx.
|
||||
err = c.exec(args, env)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Read the metadata file and transform it back into the map[string]string
|
||||
// structure originally returned by the exporter.
|
||||
_, err = os.Stat(metadata)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("missing metadata: %w", err)
|
||||
}
|
||||
out, err := os.ReadFile(metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var raw map[string]any
|
||||
err = json.Unmarshal(out, &raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := map[string]string{}
|
||||
for k, v := range raw {
|
||||
switch vv := v.(type) {
|
||||
case string:
|
||||
resp[k] = vv
|
||||
default:
|
||||
out, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
resp[k] = string(out)
|
||||
}
|
||||
}
|
||||
|
||||
return &client.SolveResponse{ExporterResponse: resp}, nil
|
||||
}
|
||||
|
||||
// exec invokes a Docker plugin binary. The first argument should be the name
|
||||
// of the plugin's subcommand, e.g. "buildx".
|
||||
func (c *cli) exec(args, extraEnv []string) error {
|
||||
if len(args) == 0 {
|
||||
return errors.New("args must be non-empty")
|
||||
}
|
||||
name := args[0]
|
||||
|
||||
root := commands.NewRootCmd(name, false, c)
|
||||
plug, err := manager.GetPlugin(name, c, root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if plug.Err != nil {
|
||||
return plug.Err
|
||||
}
|
||||
|
||||
defer contract.IgnoreClose(c.w)
|
||||
|
||||
cmd, err := manager.PluginRunCommand(c, name, root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.Args = append([]string{cmd.Args[0]}, args...)
|
||||
cmd.Stderr = c.Err() // TODO: This is build output...
|
||||
cmd.Stdout = c.Out()
|
||||
cmd.Stdin = c.In()
|
||||
|
||||
cmd.Env = append(cmd.Env, extraEnv...)
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// attrcsv transforms key/values into a CSV: key1=value1,key2=value2,...
|
||||
func attrcsv(typ string, m map[string]string) string {
|
||||
s := []string{"type=" + typ}
|
||||
for k, v := range m {
|
||||
s = append(s, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
return strings.Join(s, ",")
|
||||
}
|
||||
39
provider/internal/cli_test.go
Normal file
39
provider/internal/cli_test.go
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestExec(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
h, err := newHost(nil)
|
||||
require.NoError(t, err)
|
||||
cli, err := wrap(h)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = cli.exec([]string{"buildx", "version"}, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
out, err := io.ReadAll(cli.r)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, string(out), "github.com/docker/buildx")
|
||||
}
|
||||
359
provider/internal/client.go
Normal file
359
provider/internal/client.go
Normal file
@@ -0,0 +1,359 @@
|
||||
// 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:generate go run go.uber.org/mock/mockgen -typed -package internal -source client.go -destination mockclient_test.go --self_package github.com/pulumi/pulumi-dockerbuild/provider/internal
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/distribution/reference"
|
||||
buildx "github.com/docker/buildx/build"
|
||||
"github.com/docker/buildx/commands"
|
||||
controllerapi "github.com/docker/buildx/controller/pb"
|
||||
"github.com/docker/buildx/util/dockerutil"
|
||||
"github.com/docker/buildx/util/platformutil"
|
||||
"github.com/docker/buildx/util/progress"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/flags"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/session"
|
||||
"github.com/moby/buildkit/session/auth/authprovider"
|
||||
"github.com/moby/buildkit/util/progress/progressui"
|
||||
"github.com/regclient/regclient/types/descriptor"
|
||||
"github.com/regclient/regclient/types/errs"
|
||||
"github.com/regclient/regclient/types/manifest"
|
||||
"github.com/regclient/regclient/types/ref"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
provider "github.com/pulumi/pulumi-go-provider"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/diag"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
||||
)
|
||||
|
||||
// Client handles all our Docker API calls.
|
||||
type Client interface {
|
||||
Build(ctx provider.Context, b Build) (*client.SolveResponse, error)
|
||||
BuildKitEnabled() (bool, error)
|
||||
Inspect(ctx context.Context, id string) ([]descriptor.Descriptor, error)
|
||||
Delete(ctx context.Context, id string) error
|
||||
|
||||
ManifestCreate(ctx provider.Context, push bool, target string, refs ...string) error
|
||||
ManifestInspect(ctx provider.Context, target string) (string, error)
|
||||
ManifestDelete(ctx provider.Context, target string) error
|
||||
}
|
||||
|
||||
// Build encapsulates all of the user-provider build parameters and options.
|
||||
type Build interface {
|
||||
BuildOptions() controllerapi.BuildOptions
|
||||
Inline() string
|
||||
ShouldExec() bool
|
||||
Secrets() session.Attachable
|
||||
}
|
||||
|
||||
var _ Client = (*cli)(nil)
|
||||
|
||||
func newDockerCLI(config *Config) (*command.DockerCli, error) {
|
||||
cli, err := command.NewDockerCli(
|
||||
command.WithDefaultContextStoreConfig(),
|
||||
command.WithContentTrustFromEnv(),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opts := flags.NewClientOptions()
|
||||
if config != nil && config.Host != "" {
|
||||
opts.Hosts = append(opts.Hosts, config.Host)
|
||||
}
|
||||
err = cli.Initialize(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: Log some version information for debugging.
|
||||
|
||||
// Disable the CLI's tendency to log randomly to stdout.
|
||||
logrus.SetOutput(io.Discard)
|
||||
|
||||
return cli, nil
|
||||
}
|
||||
|
||||
// Build performs a BuildKit build. Returns a map of target names (or one name,
|
||||
// "default", if no targets were specified) to SolveResponses, which capture
|
||||
// the build's digest and tags (if any).
|
||||
func (c *cli) Build(
|
||||
pctx provider.Context,
|
||||
build Build,
|
||||
) (*client.SolveResponse, error) {
|
||||
ctx := context.Context(pctx)
|
||||
opts := build.BuildOptions()
|
||||
|
||||
go c.tail(pctx)
|
||||
defer contract.IgnoreClose(c)
|
||||
|
||||
if build.ShouldExec() {
|
||||
return c.execBuild(build)
|
||||
}
|
||||
|
||||
b, err := c.host.builderFor(build)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
printer, err := progress.NewPrinter(ctx, c.w,
|
||||
progressui.PlainMode,
|
||||
progress.WithDesc(
|
||||
fmt.Sprintf("building with %q instance using %s driver", b.name, b.driver),
|
||||
fmt.Sprintf("%s:%s", b.driver, b.name),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating printer: %w", err)
|
||||
}
|
||||
|
||||
cacheFrom := []client.CacheOptionsEntry{}
|
||||
for _, c := range opts.CacheFrom {
|
||||
cacheFrom = append(cacheFrom, client.CacheOptionsEntry{
|
||||
Type: c.Type,
|
||||
Attrs: c.Attrs,
|
||||
})
|
||||
}
|
||||
cacheTo := []client.CacheOptionsEntry{}
|
||||
for _, c := range opts.CacheTo {
|
||||
cacheTo = append(cacheTo, client.CacheOptionsEntry{
|
||||
Type: c.Type,
|
||||
Attrs: c.Attrs,
|
||||
})
|
||||
}
|
||||
exports := []client.ExportEntry{}
|
||||
for _, e := range opts.Exports {
|
||||
exports = append(exports, client.ExportEntry{
|
||||
Type: e.Type,
|
||||
Attrs: e.Attrs,
|
||||
OutputDir: e.Destination,
|
||||
})
|
||||
}
|
||||
platforms, _ := platformutil.Parse(opts.Platforms)
|
||||
platforms = platformutil.Dedupe(platforms)
|
||||
|
||||
namedContexts := map[string]buildx.NamedContext{}
|
||||
for k, v := range opts.NamedContexts {
|
||||
ref, err := reference.ParseNormalizedNamed(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name := strings.TrimSuffix(reference.FamiliarString(ref), ":latest")
|
||||
namedContexts[name] = buildx.NamedContext{Path: v}
|
||||
}
|
||||
|
||||
ssh, err := controllerapi.CreateSSH(opts.SSH)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
target := opts.Target
|
||||
if target == "" {
|
||||
target = "default"
|
||||
}
|
||||
payload := map[string]buildx.Options{
|
||||
target: {
|
||||
Inputs: buildx.Inputs{
|
||||
ContextPath: opts.ContextPath,
|
||||
DockerfilePath: opts.DockerfileName,
|
||||
DockerfileInline: build.Inline(),
|
||||
NamedContexts: namedContexts,
|
||||
InStream: strings.NewReader(""),
|
||||
},
|
||||
// Disable default provenance for now. Docker's `manifest create`
|
||||
// doesn't handle manifests with provenance included; more reason
|
||||
// to use imagetools instead.
|
||||
Attests: map[string]*string{"provenance": nil},
|
||||
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: opts.Target,
|
||||
|
||||
Session: []session.Attachable{
|
||||
ssh,
|
||||
authprovider.NewDockerAuthProvider(c.ConfigFile(), nil),
|
||||
build.Secrets(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Perform the build.
|
||||
results, err := buildx.Build(
|
||||
ctx,
|
||||
b.nodes,
|
||||
payload,
|
||||
dockerutil.NewClient(c),
|
||||
filepath.Dir(c.ConfigFile().Filename),
|
||||
printer,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if printErr := printer.Wait(); printErr != nil {
|
||||
return results[target], printErr
|
||||
}
|
||||
for _, w := range printer.Warnings() {
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "%s", w.Short)
|
||||
for _, d := range w.Detail {
|
||||
fmt.Fprintf(b, "\n%s", d)
|
||||
}
|
||||
pctx.Log(diag.Warning, b.String())
|
||||
}
|
||||
|
||||
return results[target], err
|
||||
}
|
||||
|
||||
// BuildKitEnabled returns true if the client supports buildkit.
|
||||
func (c *cli) BuildKitEnabled() (bool, error) {
|
||||
return c.Cli.BuildKitEnabled()
|
||||
}
|
||||
|
||||
func (c *cli) ManifestCreate(ctx provider.Context, push bool, target string, refs ...string) error {
|
||||
// TODO: Create this manifest with regclient or imagetools.
|
||||
|
||||
go c.tail(ctx)
|
||||
defer contract.IgnoreClose(c)
|
||||
|
||||
args := []string{
|
||||
// "buildx",
|
||||
"imagetools",
|
||||
"create",
|
||||
"--tag", target,
|
||||
}
|
||||
|
||||
if !push {
|
||||
args = append(args, "--dry-run")
|
||||
}
|
||||
|
||||
args = append(args, refs...)
|
||||
|
||||
cmd := commands.NewRootCmd(os.Args[0], false, c)
|
||||
|
||||
cmd.SetArgs(args)
|
||||
return cmd.ExecuteContext(ctx)
|
||||
}
|
||||
|
||||
func (c *cli) ManifestInspect(ctx provider.Context, target string) (string, error) {
|
||||
rc := c.rc()
|
||||
|
||||
ref, err := ref.New(target)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
m, err := rc.ManifestHead(ctx, ref)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("fetching head: %w", err)
|
||||
}
|
||||
|
||||
return string(m.GetDescriptor().Digest), nil
|
||||
}
|
||||
|
||||
func (c *cli) ManifestDelete(ctx provider.Context, target string) error {
|
||||
rc := c.rc()
|
||||
|
||||
ref, err := ref.New(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = rc.ManifestDelete(context.Context(ctx), ref)
|
||||
if errors.Is(err, errs.ErrHTTPStatus) {
|
||||
ctx.Log(diag.Warning, "this registry does not support deletions")
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Inspect inspects an image.
|
||||
func (c *cli) Inspect(ctx context.Context, r string) ([]descriptor.Descriptor, error) {
|
||||
ref, err := ref.New(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rc := c.rc()
|
||||
|
||||
m, err := rc.ManifestGet(ctx, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if mi, ok := m.(manifest.Indexer); ok {
|
||||
return mi.GetManifestList()
|
||||
}
|
||||
|
||||
return []descriptor.Descriptor{m.GetDescriptor()}, nil
|
||||
}
|
||||
|
||||
// Delete attempts to delete an image with the given ref. Many registries don't
|
||||
// support the DELETE API yet, so this operation is not guaranteed to work.
|
||||
func (c *cli) Delete(ctx context.Context, r string) error {
|
||||
// Attempt to delete the ref locally if it exists.
|
||||
_, _ = c.Client().ImageRemove(ctx, r, types.ImageRemoveOptions{
|
||||
Force: true, // Needed in case the image has multiple tags.
|
||||
})
|
||||
|
||||
// Attempt to delete the ref remotely if it was pushed -- requires a
|
||||
// digest.
|
||||
ref, err := ref.New(r)
|
||||
if err != nil || ref.Digest == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
rc := c.rc()
|
||||
|
||||
// TODO: Multi-platform manifests are left dangling on ECR.
|
||||
|
||||
_ = rc.ManifestDelete(ctx, ref)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func normalizeReference(ref string) (reference.Named, error) {
|
||||
namedRef, err := reference.ParseNormalizedNamed(ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, isDigested := namedRef.(reference.Canonical); !isDigested {
|
||||
return reference.TagNameOnly(namedRef), nil
|
||||
}
|
||||
return namedRef, nil
|
||||
}
|
||||
382
provider/internal/client_test.go
Normal file
382
provider/internal/client_test.go
Normal file
@@ -0,0 +1,382 @@
|
||||
// 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.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
func TestAuth(t *testing.T) {
|
||||
t.Parallel()
|
||||
user := "pulumibot"
|
||||
if u := os.Getenv("DOCKER_HUB_USER"); u != "" {
|
||||
user = u
|
||||
}
|
||||
password := os.Getenv("DOCKER_HUB_PASSWORD")
|
||||
address := "docker.io"
|
||||
|
||||
cli := testcli(t, true, Registry{
|
||||
Address: address,
|
||||
Username: user,
|
||||
Password: password,
|
||||
})
|
||||
|
||||
_, err := cli.Client().
|
||||
RegistryLogin(context.Background(), registry.AuthConfig{ServerAddress: address})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestCustomHost(t *testing.T) {
|
||||
socket := "unix:///foo/bar.sock"
|
||||
|
||||
//nolint:paralleltest // not compatible with Setenv
|
||||
t.Run("env", func(t *testing.T) {
|
||||
t.Setenv("DOCKER_HOST", socket)
|
||||
|
||||
h, err := newHost(nil)
|
||||
require.NoError(t, err)
|
||||
cli, err := wrap(h)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, socket, cli.Client().DaemonHost())
|
||||
assert.Equal(t, socket, cli.DockerEndpoint().Host)
|
||||
})
|
||||
|
||||
t.Run("config", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
h, err := newHost(&Config{Host: socket})
|
||||
require.NoError(t, err)
|
||||
cli, err := wrap(h)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, socket, cli.Client().DaemonHost())
|
||||
assert.Equal(t, socket, cli.DockerEndpoint().Host)
|
||||
})
|
||||
}
|
||||
|
||||
func TestBuild(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Workaround for https://github.com/pulumi/pulumi-go-provider/issues/159
|
||||
ctrl, ctx := gomock.WithContext(context.Background(), t)
|
||||
pctx := NewMockProviderContext(ctrl)
|
||||
pctx.EXPECT().Log(gomock.Any(), gomock.Any()).AnyTimes()
|
||||
pctx.EXPECT().LogStatus(gomock.Any(), gomock.Any()).AnyTimes()
|
||||
pctx.EXPECT().Done().Return(ctx.Done()).AnyTimes()
|
||||
pctx.EXPECT().
|
||||
Value(gomock.Any()).
|
||||
DoAndReturn(func(key any) any { return ctx.Value(key) }).
|
||||
AnyTimes()
|
||||
pctx.EXPECT().Err().Return(ctx.Err()).AnyTimes()
|
||||
pctx.EXPECT().Deadline().Return(ctx.Deadline()).AnyTimes()
|
||||
|
||||
tmpdir := t.TempDir()
|
||||
|
||||
exampleContext := BuildContext{Context: Context{Location: "../../examples/app"}}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
skip bool
|
||||
args ImageArgs
|
||||
|
||||
auths []Registry
|
||||
}{
|
||||
{
|
||||
name: "multiPlatform",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Dockerfile: Dockerfile{
|
||||
Location: "../../examples/app/Dockerfile.multiPlatform",
|
||||
},
|
||||
Platforms: []Platform{"plan9/amd64", "plan9/arm64"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "registryPush",
|
||||
skip: os.Getenv("DOCKER_HUB_PASSWORD") == "",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Tags: []string{"docker.io/pulumibot/buildkit-e2e:unit"},
|
||||
Push: true,
|
||||
},
|
||||
auths: []Registry{{
|
||||
Address: "docker.io",
|
||||
Username: "pulumibot",
|
||||
Password: os.Getenv("DOCKER_HUB_PASSWORD"),
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "cached",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Tags: []string{"cached"},
|
||||
CacheTo: []CacheTo{{Local: &CacheToLocal{
|
||||
Dest: filepath.Join(tmpdir, "cache"),
|
||||
CacheWithMode: CacheWithMode{Mode: "max"},
|
||||
}}},
|
||||
CacheFrom: []CacheFrom{{Local: &CacheFromLocal{
|
||||
Src: filepath.Join(tmpdir, "cache"),
|
||||
}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "buildArgs",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Dockerfile: Dockerfile{
|
||||
Location: "../../examples/app/Dockerfile.buildArgs",
|
||||
},
|
||||
BuildArgs: map[string]string{
|
||||
"SET_ME_TO_TRUE": "true",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "extraHosts",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Dockerfile: Dockerfile{
|
||||
Location: "../../examples/app/Dockerfile.extraHosts",
|
||||
},
|
||||
AddHosts: []string{
|
||||
"metadata.google.internal:169.254.169.254",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sshMount",
|
||||
skip: os.Getenv("SSH_AUTH_SOCK") == "",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Dockerfile: Dockerfile{
|
||||
Location: "../../examples/app/Dockerfile.sshMount",
|
||||
},
|
||||
SSH: []SSH{{ID: "default"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "secrets",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Dockerfile: Dockerfile{
|
||||
Location: "../../examples/app/Dockerfile.secrets",
|
||||
},
|
||||
Secrets: map[string]string{
|
||||
"password": "hunter2",
|
||||
},
|
||||
NoCache: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "labels",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Labels: map[string]string{
|
||||
"description": "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "target",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Dockerfile: Dockerfile{
|
||||
Location: "../../examples/app/Dockerfile.target",
|
||||
},
|
||||
Target: "build-me",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "namedContext",
|
||||
args: ImageArgs{
|
||||
Context: BuildContext{
|
||||
Context: Context{
|
||||
Location: "../../examples/app",
|
||||
},
|
||||
Named: NamedContexts{
|
||||
"golang:latest": Context{
|
||||
Location: "docker-image://golang@sha256:b8e62cf593cdaff36efd90aa3a37de268e6781a2e68c6610940c48f7cdf36984",
|
||||
},
|
||||
},
|
||||
},
|
||||
Dockerfile: Dockerfile{
|
||||
Location: "../../examples/app/Dockerfile.namedContexts",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remoteContext",
|
||||
args: ImageArgs{
|
||||
Context: BuildContext{
|
||||
Context: Context{
|
||||
Location: "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "remoteContextWithInline",
|
||||
args: ImageArgs{
|
||||
Context: BuildContext{
|
||||
Context: Context{
|
||||
Location: "https://github.com/docker-library/hello-world.git",
|
||||
},
|
||||
},
|
||||
Dockerfile: Dockerfile{
|
||||
Inline: dedent(`
|
||||
FROM busybox
|
||||
COPY hello.c ./
|
||||
`),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "inline",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Dockerfile: Dockerfile{
|
||||
Inline: dedent(`
|
||||
FROM alpine
|
||||
RUN echo 👍
|
||||
`),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dockerLoad",
|
||||
args: ImageArgs{
|
||||
Context: exampleContext,
|
||||
Load: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Add an exec: true version for all of our test cases.
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
tt.name = "exec-" + tt.name
|
||||
tt.args.Exec = true
|
||||
tmpdir := filepath.Join(t.TempDir(), "exec")
|
||||
for _, c := range tt.args.CacheTo {
|
||||
if c.Local != nil {
|
||||
c.Local.Dest = tmpdir
|
||||
}
|
||||
}
|
||||
for _, c := range tt.args.CacheFrom {
|
||||
if c.Local != nil {
|
||||
c.Local.Src = tmpdir
|
||||
}
|
||||
}
|
||||
tests = append(tests, tt)
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if tt.skip {
|
||||
t.Skip()
|
||||
}
|
||||
cli := testcli(t, true, tt.auths...)
|
||||
|
||||
build, err := tt.args.toBuild(pctx, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = cli.Build(pctx, build)
|
||||
assert.NoError(t, err, cli.err.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildkitEnabled(t *testing.T) {
|
||||
t.Parallel()
|
||||
cli := testcli(t, false)
|
||||
ok, err := cli.BuildKitEnabled()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, ok)
|
||||
}
|
||||
|
||||
func TestInspect(t *testing.T) {
|
||||
t.Parallel()
|
||||
cli := testcli(t, false)
|
||||
descriptors, err := cli.Inspect(context.Background(), "pulumibot/myapp:buildx")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(
|
||||
t,
|
||||
"application/vnd.docker.distribution.manifest.v2+json",
|
||||
descriptors[0].MediaType,
|
||||
)
|
||||
}
|
||||
|
||||
func TestNormalizatReference(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
ref string
|
||||
want string
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
ref: "foo",
|
||||
want: "docker.io/library/foo:latest",
|
||||
},
|
||||
{
|
||||
ref: "pulumi/pulumi:v3.100.0",
|
||||
want: "docker.io/pulumi/pulumi:v3.100.0",
|
||||
},
|
||||
{
|
||||
ref: "invalid:ref:format",
|
||||
wantErr: "invalid reference format",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.ref, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ref, err := normalizeReference(tt.ref)
|
||||
if err != nil {
|
||||
assert.ErrorContains(t, err, tt.wantErr)
|
||||
} else {
|
||||
assert.Equal(t, ref.String(), tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// testcli returns a new standalone CLI instance. Set ping to true if a live
|
||||
// daemon is required -- the test will be skipped if the daemon is not available.
|
||||
func testcli(t *testing.T, ping bool, auths ...Registry) *cli {
|
||||
h, err := newHost(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
cli, err := wrap(h, auths...)
|
||||
require.NoError(t, err)
|
||||
|
||||
if ping {
|
||||
_, err := cli.Client().Ping(context.Background())
|
||||
if err != nil {
|
||||
t.Skip(err)
|
||||
}
|
||||
}
|
||||
|
||||
return cli
|
||||
}
|
||||
330
provider/internal/context.go
Normal file
330
provider/internal/context.go
Normal file
@@ -0,0 +1,330 @@
|
||||
// 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.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
gofs "io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
buildx "github.com/docker/buildx/build"
|
||||
"github.com/moby/patternmatcher/ignorefile"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/tonistiigi/fsutil"
|
||||
|
||||
"github.com/pulumi/pulumi-go-provider/infer"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
||||
)
|
||||
|
||||
var (
|
||||
_ infer.Annotated = (*Context)(nil)
|
||||
_ infer.Annotated = (*BuildContext)(nil)
|
||||
)
|
||||
|
||||
// Context represents Docker's `PATH | URL | -` context argument. Inline
|
||||
// context isn't supported yet.
|
||||
type Context struct {
|
||||
Location string `pulumi:"location"` // Location is a local directory or URL.
|
||||
}
|
||||
|
||||
// BuildContext represents Docker's named and unamed contexts.
|
||||
type BuildContext struct {
|
||||
Context
|
||||
Named NamedContexts `pulumi:"named,optional"`
|
||||
}
|
||||
|
||||
// NamedContexts correspond to Docker's `--build-context name=path` options.
|
||||
// The path can be local or a remote URL.
|
||||
type NamedContexts map[string]Context
|
||||
|
||||
// Map returns NamedContexts as a simple map.
|
||||
func (nc NamedContexts) Map() map[string]string {
|
||||
m := map[string]string{}
|
||||
for k, v := range nc {
|
||||
m[k] = v.Location
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on Context.
|
||||
func (c *Context) Annotate(a infer.Annotator) {
|
||||
a.Describe(&c.Location, dedent(`
|
||||
Resources to use for build context.
|
||||
|
||||
The location can be:
|
||||
* A relative or absolute path to a local directory (".", "./app",
|
||||
"/app", etc.).
|
||||
* A remote URL of a Git repository, tarball, or plain text file
|
||||
("https://github.com/user/myrepo.git", "http://server/context.tar.gz",
|
||||
etc.).
|
||||
`))
|
||||
}
|
||||
|
||||
// validate returns a non-nil CheckError if the Context is invalid. The
|
||||
// returned Dockerfile may have defaults set to match Docker's default
|
||||
// handling. The returned Dockerfile should be validated separately.
|
||||
func (c *Context) validate(preview bool, d Dockerfile) (Dockerfile, error) {
|
||||
if c.Location == "" && preview {
|
||||
// The field is required so we normally wouldn't need to check if it
|
||||
// exists, but during previews it can still be empty if the value is
|
||||
// unknown. This isn't an error, but it does prevent us from performing
|
||||
// a build later.
|
||||
return d, nil
|
||||
}
|
||||
|
||||
if buildx.IsRemoteURL(c.Location) {
|
||||
// We assume remote URLs are always valid.
|
||||
return d, nil
|
||||
}
|
||||
|
||||
abs, err := filepath.Abs(c.Location)
|
||||
if err != nil {
|
||||
return d, newCheckFailure(err, "context.location")
|
||||
}
|
||||
|
||||
if d.Location == "" && d.Inline == "" {
|
||||
// If a Dockerfile wasn't provided and our context is on-disk, then
|
||||
// set our Dockerfile to a default of <PATH>/Dockerfile.
|
||||
d.Location = filepath.Join(c.Location, "Dockerfile")
|
||||
}
|
||||
|
||||
if isLocalDir(afero.NewOsFs(), abs) {
|
||||
// Our context exists -- nothing else to check.
|
||||
return d, nil
|
||||
}
|
||||
|
||||
if c.Location != "-" {
|
||||
return d, newCheckFailure(
|
||||
fmt.Errorf("%q: not a valid directory or URL", c.Location),
|
||||
"context.location",
|
||||
)
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// Annotate sets docstrings on BuildContext.
|
||||
func (bc *BuildContext) Annotate(a infer.Annotator) {
|
||||
a.Describe(&bc.Named, dedent(`
|
||||
Additional build contexts to use.
|
||||
|
||||
These contexts are accessed with "FROM name" or "--from=name"
|
||||
statements when using Dockerfile 1.4+ syntax.
|
||||
|
||||
Values can be local paths, HTTP URLs, or "docker-image://" images.
|
||||
`))
|
||||
}
|
||||
|
||||
// hashFile hashes a file's contents and accumulates it into the provider Hash.
|
||||
func hashFile(
|
||||
h hash.Hash,
|
||||
fs fsutil.FS,
|
||||
relativePath string,
|
||||
fileMode gofs.FileMode,
|
||||
) error {
|
||||
if fileMode.IsDir() {
|
||||
return nil
|
||||
}
|
||||
if !(fileMode.IsRegular() || fileMode.Type() == os.ModeSymlink) {
|
||||
return nil
|
||||
}
|
||||
|
||||
f, err := fs.Open(relativePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not open %q: %w", relativePath, err)
|
||||
}
|
||||
defer contract.IgnoreClose(f)
|
||||
|
||||
_, err = io.Copy(h, f)
|
||||
if errors.Is(err, syscall.EISDIR) {
|
||||
// Ignore symlinks to directories.
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not copy %q to hash: %w", relativePath, err)
|
||||
}
|
||||
|
||||
h.Write([]byte(filepath.ToSlash(path.Clean(relativePath))))
|
||||
h.Write([]byte(fileMode.String()))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// hashBuildContext accumulates hashes for files in a directory. If the file is
|
||||
// a symlink, the location it points to is hashed. If it is a regular file, we
|
||||
// hash the contents of the file. In order to detect file renames and mode
|
||||
// changes, we also write to the accumulator a relative name and file mode.
|
||||
func hashBuildContext(
|
||||
contextPath, dockerfilePath string,
|
||||
namedContexts map[string]string,
|
||||
) (string, error) {
|
||||
h := sha256.New()
|
||||
fs := afero.NewOsFs()
|
||||
|
||||
// Grab .dockerignore if our context and/or Dockerfile is on-disk.
|
||||
excludes := []string{}
|
||||
if isLocalDir(fs, contextPath) || isLocalFile(fs, dockerfilePath) {
|
||||
e, err := getIgnorePatterns(fs, dockerfilePath, contextPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
excludes = e
|
||||
}
|
||||
|
||||
if isLocalFile(fs, dockerfilePath) {
|
||||
err := hashDockerfile(h, dockerfilePath)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
|
||||
if isLocalDir(fs, contextPath) {
|
||||
// Hash our context if it's on-disk.
|
||||
fs, err := rootFS(contextPath, excludes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := hashPath(h, fs); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// Hash any local named contexts.
|
||||
for _, namedContext := range namedContexts {
|
||||
if isLocalDir(fs, namedContext) {
|
||||
fs, err := rootFS(namedContext, excludes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := hashPath(h, fs); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hex.EncodeToString(h.Sum(nil)), nil
|
||||
}
|
||||
|
||||
// hashPath hashes all paths within the provided FS.
|
||||
func hashPath(h hash.Hash, fs fsutil.FS) (string, error) {
|
||||
err := fs.Walk(
|
||||
context.Background(),
|
||||
"/",
|
||||
func(filePath string, dir gofs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dir.IsDir() {
|
||||
return nil
|
||||
}
|
||||
// fsutil.Walk makes filePath relative to the root, we join it back to get an absolute path to
|
||||
// the file to hash.
|
||||
fi, err := dir.Info()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return hashFile(h, fs, filePath, fi.Mode())
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to hash build context: %w", err)
|
||||
}
|
||||
// create a hash of the entire input of the hash accumulator
|
||||
return hex.EncodeToString(h.Sum(nil)), nil
|
||||
}
|
||||
|
||||
// hashDockerfile hashes the contents of a Dockerfile.
|
||||
func hashDockerfile(h hash.Hash, path string) error {
|
||||
// The Dockerfile might be capture by .dockerignore, so we explicitly hash
|
||||
// its content (but not filename -- to match Docker) in order to detect
|
||||
// changes in it.
|
||||
df, err := os.ReadFile(filepath.Clean(path))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading dockerfile %q: %w", path, err)
|
||||
}
|
||||
_, err = h.Write(df)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error hashing dockerfile %q: %w", path, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getIgnorePatterns returns all patterns to ignore when constructing a build
|
||||
// context for the given Dockerfile, if any such patterns exist.
|
||||
//
|
||||
// Precedence is given to Dockerfile-specific ignore-files as per
|
||||
// https://docs.docker.com/build/building/context/#filename-and-location.
|
||||
func getIgnorePatterns(fs afero.Fs, dockerfilePath, contextRoot string) ([]string, error) {
|
||||
paths := []string{
|
||||
// Prefer <Dockerfile>.dockerignore if it's present.
|
||||
dockerfilePath + ".dockerignore",
|
||||
}
|
||||
|
||||
if isLocalDir(fs, contextRoot) {
|
||||
// Otherwise fall back to the ignore-file at the root of our build context.
|
||||
paths = append(paths, filepath.Join(contextRoot, ".dockerignore"))
|
||||
}
|
||||
|
||||
// Attempt to parse our candidate ignore-files, skipping any that don't
|
||||
// exist.
|
||||
for _, p := range paths {
|
||||
f, err := fs.Open(p)
|
||||
if errors.Is(err, afero.ErrFileNotFound) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading %q: %w", p, err)
|
||||
}
|
||||
|
||||
ignorePatterns, err := ignorefile.ReadAll(f)
|
||||
if err != nil {
|
||||
contract.IgnoreClose(f)
|
||||
return nil, fmt.Errorf("unable to parse %q: %w", p, err)
|
||||
}
|
||||
contract.IgnoreClose(f)
|
||||
return ignorePatterns, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func isLocalDir(fs afero.Fs, path string) bool {
|
||||
stat, err := fs.Stat(path)
|
||||
return err == nil && stat.IsDir()
|
||||
}
|
||||
|
||||
func isLocalFile(fs afero.Fs, path string) bool {
|
||||
stat, err := fs.Stat(path)
|
||||
return err == nil && !stat.IsDir()
|
||||
}
|
||||
|
||||
// rootFS returns a new fsutil.FS scoped to the given root and with the given
|
||||
// exclusions.
|
||||
func rootFS(root string, excludes []string) (fsutil.FS, error) {
|
||||
fs, err := fsutil.NewFS(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fsutil.NewFilterFS(fs, &fsutil.FilterOpt{ExcludePatterns: excludes})
|
||||
}
|
||||
416
provider/internal/context_test.go
Normal file
416
provider/internal/context_test.go
Normal file
@@ -0,0 +1,416 @@
|
||||
// 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.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var _dockerfile = "Dockerfile"
|
||||
|
||||
func TestValidateContext(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
c Context
|
||||
givenD Dockerfile
|
||||
preview bool
|
||||
|
||||
wantD *Dockerfile
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "relative",
|
||||
c: Context{
|
||||
Location: "../internal/../internal/testdata/noop",
|
||||
},
|
||||
wantD: &Dockerfile{
|
||||
Location: "../internal/testdata/noop/Dockerfile",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "missing directory",
|
||||
c: Context{
|
||||
Location: "/does/not/exist/",
|
||||
},
|
||||
wantErr: "not a valid directory",
|
||||
},
|
||||
{
|
||||
name: "missing default Dockerfile",
|
||||
c: Context{
|
||||
Location: "testdata",
|
||||
},
|
||||
wantD: &Dockerfile{Location: "testdata/Dockerfile"},
|
||||
},
|
||||
{
|
||||
name: "with explicit Dockerfile",
|
||||
c: Context{
|
||||
Location: "testdata",
|
||||
},
|
||||
givenD: Dockerfile{
|
||||
Location: "testdata/Dockerfile.invalid",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "default location",
|
||||
c: Context{},
|
||||
wantD: &Dockerfile{Location: "Dockerfile"},
|
||||
},
|
||||
{
|
||||
name: "remote context doesn't default to local Dockerfile",
|
||||
c: Context{
|
||||
Location: "https://raw.githubusercontent.com/pulumi/pulumi-docker/api-types/provider/testdata/Dockerfile",
|
||||
},
|
||||
wantD: &Dockerfile{},
|
||||
},
|
||||
{
|
||||
name: "preview",
|
||||
c: Context{},
|
||||
preview: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
d, err := tt.c.validate(tt.preview, tt.givenD)
|
||||
|
||||
if tt.wantErr == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.ErrorContains(t, err, tt.wantErr)
|
||||
}
|
||||
|
||||
if tt.wantD != nil {
|
||||
assert.Equal(t, tt.wantD.Location, d.Location)
|
||||
assert.Equal(t, tt.wantD.Inline, d.Inline)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHashIgnoresFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
step1Dir := "./testdata/ignores/basedir"
|
||||
baseResult, err := hashBuildContext(step1Dir, filepath.Join(step1Dir, _dockerfile), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
step2Dir := "./testdata/ignores/basedir-with-ignored-files"
|
||||
result, err := hashBuildContext(step2Dir, filepath.Join(step2Dir, _dockerfile), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, result, baseResult)
|
||||
}
|
||||
|
||||
// Tests that we handle .dockerignore exclusions such as "!foo/*/bar".
|
||||
//
|
||||
// See:
|
||||
// - https://github.com/moby/moby/issues/30018
|
||||
// - https://github.com/moby/moby/issues/45608
|
||||
//
|
||||
// Buildkit handles these correctly (according to spec), Docker's classic builder does not.
|
||||
func TestHashIgnoresWildcards(t *testing.T) {
|
||||
t.Parallel()
|
||||
baselineDir := "testdata/ignores-wildcard/basedir"
|
||||
baselineResult, err := hashBuildContext(
|
||||
baselineDir,
|
||||
filepath.Join(baselineDir, _dockerfile),
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
modIgnoredDir := "testdata/ignores-wildcard/basedir-modified-ignored-file"
|
||||
modIgnoredResult, err := hashBuildContext(
|
||||
modIgnoredDir,
|
||||
filepath.Join(modIgnoredDir, _dockerfile),
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
modIncludedDir := "testdata/ignores-wildcard/basedir-modified-included-file"
|
||||
modIncludedResult, err := hashBuildContext(
|
||||
modIncludedDir,
|
||||
filepath.Join(modIncludedDir, _dockerfile),
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(
|
||||
t,
|
||||
baselineResult,
|
||||
modIgnoredResult,
|
||||
"hash should not change when modifying ignored files",
|
||||
)
|
||||
assert.NotEqual(t, baselineResult, modIncludedResult,
|
||||
"hash should change when modifying included (via wildcard ignore exclusion) files")
|
||||
}
|
||||
|
||||
func BenchmarkHashBuildContext(b *testing.B) {
|
||||
dir := "testdata/ignores-wildcard/basedir-modified-ignored-file"
|
||||
for n := 0; n < b.N; n++ {
|
||||
_, err := hashBuildContext(dir, filepath.Join(dir, _dockerfile), nil)
|
||||
require.NoError(b, err)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that we handle .dockerignore exclusions such as "!foo/*/bar", as above, when using a
|
||||
// relative context path.
|
||||
//
|
||||
//nolint:paralleltest // Incompatible with os.Chdir.
|
||||
func TestHashIgnoresWildcardsRelative(t *testing.T) {
|
||||
err := os.Chdir("testdata")
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
err = os.Chdir("..")
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
|
||||
baselineDir := "../testdata/ignores-wildcard/basedir"
|
||||
baselineResult, err := hashBuildContext(
|
||||
baselineDir,
|
||||
filepath.Join(baselineDir, _dockerfile),
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
modIgnoredDir := "../testdata/ignores-wildcard/basedir-modified-ignored-file"
|
||||
modIgnoredResult, err := hashBuildContext(
|
||||
modIgnoredDir,
|
||||
filepath.Join(modIgnoredDir, _dockerfile),
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
modIncludedDir := "../testdata/ignores-wildcard/basedir-modified-included-file"
|
||||
modIncludedResult, err := hashBuildContext(
|
||||
modIncludedDir,
|
||||
filepath.Join(modIncludedDir, _dockerfile),
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(
|
||||
t,
|
||||
baselineResult,
|
||||
modIgnoredResult,
|
||||
"hash should not change when modifying ignored files",
|
||||
)
|
||||
assert.NotEqual(t, baselineResult, modIncludedResult,
|
||||
"hash should change when modifying included (via wildcard ignore exclusion) files")
|
||||
}
|
||||
|
||||
func TestHashIgnoresDockerfileOutsideDirMove(t *testing.T) {
|
||||
t.Parallel()
|
||||
appDir := "./testdata/dockerfile-location-irrelevant/app"
|
||||
baseResult, err := hashBuildContext(
|
||||
appDir,
|
||||
"./testdata/dockerfile-location-irrelevant/step1.Dockerfile",
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
result, err := hashBuildContext(
|
||||
appDir,
|
||||
"./testdata/dockerfile-location-irrelevant/step2.Dockerfile",
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, result, baseResult)
|
||||
}
|
||||
|
||||
func TestHashRenamingMatters(t *testing.T) {
|
||||
t.Parallel()
|
||||
step1Dir := "./testdata/filemode-matters/step1"
|
||||
baseResult, err := hashBuildContext(step1Dir, filepath.Join(step1Dir, _dockerfile), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
step2Dir := "./testdata/renaming-matters/step2"
|
||||
result, err := hashBuildContext(step2Dir, filepath.Join(step2Dir, _dockerfile), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NotEqual(t, result, baseResult)
|
||||
}
|
||||
|
||||
func TestHashFilemodeMatters(t *testing.T) {
|
||||
t.Parallel()
|
||||
step1Dir := "./testdata/filemode-matters/step1"
|
||||
baseResult, err := hashBuildContext(step1Dir, filepath.Join(step1Dir, _dockerfile), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
step2Dir := "./testdata/filemode-matters/step2-chmod-x"
|
||||
result, err := hashBuildContext(step2Dir, filepath.Join(step2Dir, _dockerfile), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NotEqual(t, result, baseResult)
|
||||
}
|
||||
|
||||
func TestHashDeepSymlinks(t *testing.T) {
|
||||
t.Parallel()
|
||||
dir := "./testdata/symlinks"
|
||||
_, err := hashBuildContext(dir, filepath.Join(dir, "Dockerfile"), nil)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestIgnoreIrregularFiles(t *testing.T) {
|
||||
t.Parallel()
|
||||
dir := t.TempDir()
|
||||
|
||||
// Create a Dockerfile
|
||||
dockerfile := filepath.Join(dir, "Dockerfile")
|
||||
err := os.WriteFile(dockerfile, []byte{}, 0o600)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create a pipe which should be ignored. (We will time out trying to read
|
||||
// it if it's not.)
|
||||
pipe := filepath.Join(dir, "pipe")
|
||||
err = syscall.Mkfifo(pipe, 0o666)
|
||||
require.NoError(t, err)
|
||||
// Confirm it's irregular.
|
||||
fi, err := os.Stat(pipe)
|
||||
require.NoError(t, err)
|
||||
assert.False(t, fi.Mode().IsRegular())
|
||||
|
||||
_, err = hashBuildContext(dir, dockerfile, nil)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestHashUnignoredDirs(t *testing.T) {
|
||||
t.Parallel()
|
||||
step1Dir := "./testdata/unignores/basedir"
|
||||
baseResult, err := hashBuildContext(step1Dir, filepath.Join(step1Dir, _dockerfile), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
step2Dir := "./testdata/unignores/basedir-with-unignored-files"
|
||||
unignoreResult, err := hashBuildContext(step2Dir, filepath.Join(step2Dir, _dockerfile), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, baseResult, unignoreResult)
|
||||
}
|
||||
|
||||
func TestDockerIgnore(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
dockerfile string
|
||||
context string
|
||||
fs map[string]string
|
||||
|
||||
want []string
|
||||
wantErr error
|
||||
}{
|
||||
{
|
||||
name: "Dockerfile with root dockerignore",
|
||||
dockerfile: "./foo/Dockerfile",
|
||||
fs: map[string]string{
|
||||
".dockerignore": "rootignore",
|
||||
},
|
||||
want: []string{"rootignore"},
|
||||
},
|
||||
{
|
||||
name: "Dockerfile with root dockerignore and custom dockerignore",
|
||||
dockerfile: "./foo/Dockerfile",
|
||||
fs: map[string]string{
|
||||
"foo/Dockerfile.dockerignore": "customignore",
|
||||
".dockerignore": "rootignore",
|
||||
},
|
||||
want: []string{"customignore"},
|
||||
},
|
||||
{
|
||||
name: "Dockerfile with root dockerignore and relative context",
|
||||
dockerfile: "./foo/Dockerfile",
|
||||
context: "../",
|
||||
fs: map[string]string{
|
||||
"../.dockerignore": "rootignore",
|
||||
},
|
||||
want: []string{"rootignore"},
|
||||
},
|
||||
{
|
||||
name: "Dockerfile without root dockerignore",
|
||||
dockerfile: "./foo/Dockerfile",
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "Dockerfile with invalid root dockerignore",
|
||||
dockerfile: "./foo/Dockerfile",
|
||||
fs: map[string]string{
|
||||
".dockerignore": strings.Repeat("*", bufio.MaxScanTokenSize),
|
||||
},
|
||||
wantErr: bufio.ErrTooLong,
|
||||
},
|
||||
{
|
||||
name: "custom.Dockerfile without custom dockerignore and without root dockerignore",
|
||||
dockerfile: "./foo/custom.Dockerfile",
|
||||
want: nil,
|
||||
},
|
||||
{
|
||||
name: "custom.Dockerfile with custom dockerignore and without root dockerignore",
|
||||
dockerfile: "./foo/custom.Dockerfile",
|
||||
fs: map[string]string{
|
||||
"foo/custom.Dockerfile.dockerignore": "customignore",
|
||||
},
|
||||
want: []string{"customignore"},
|
||||
},
|
||||
{
|
||||
name: "custom.Dockerfile with custom dockerignore and with root dockerignore",
|
||||
dockerfile: "foo/custom.Dockerfile",
|
||||
fs: map[string]string{
|
||||
"foo/custom.Dockerfile.dockerignore": "customignore",
|
||||
".dockerignore": "rootignore",
|
||||
},
|
||||
want: []string{"customignore"},
|
||||
},
|
||||
{
|
||||
name: "custom.Dockerfile without custom dockerignore and with root dockerignore",
|
||||
dockerfile: "foo/custom.Dockerfile",
|
||||
fs: map[string]string{
|
||||
".dockerignore": "rootignore",
|
||||
},
|
||||
want: []string{"rootignore"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
fs := afero.NewMemMapFs()
|
||||
for fname, fdata := range tt.fs {
|
||||
f, err := fs.Create(fname)
|
||||
require.NoError(t, err)
|
||||
_, err = f.WriteString(fdata)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
actual, err := getIgnorePatterns(fs, tt.dockerfile, tt.context)
|
||||
|
||||
assert.ErrorIs(t, err, tt.wantErr)
|
||||
assert.Equal(t, tt.want, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
870
provider/internal/coverage.out
Normal file
870
provider/internal/coverage.out
Normal file
@@ -0,0 +1,870 @@
|
||||
mode: set
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:34.47,36.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:38.65,40.9 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:40.9,42.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:43.2,44.9 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:44.9,46.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:47.2,48.9 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:48.9,50.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:51.2,51.46 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:51.46,53.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:54.2,55.18 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:60.3,62.27 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:62.27,64.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:68.2,68.13 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:68.13,70.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:72.2,73.62 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:73.62,75.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:77.2,81.59 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:81.59,83.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:83.16,85.4 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:87.3,88.23 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:88.23,90.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:92.3,92.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:95.2,95.66 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:98.69,99.13 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:100.17,101.42 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:102.27,103.38 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:104.15,105.52 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:106.10,107.61 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:111.66,118.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:123.36,127.16 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:127.16,129.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:131.2,134.9 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:134.9,136.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:138.2,141.19 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:141.19,144.3 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:146.2,146.78 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:146.78,150.3 3 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:152.2,152.24 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:152.24,154.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:154.17,156.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:157.3,157.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:157.23,160.4 2 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:161.3,161.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:166.2,166.21 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:166.21,168.46 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:168.46,171.4 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:174.2,174.16 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:178.102,185.18 4 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:185.18,186.31 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:186.31,188.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:189.3,189.21 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:193.2,193.27 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:193.27,196.17 3 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:196.17,198.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:198.9,198.22 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:198.22,199.36 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:199.36,200.13 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:202.4,202.67 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:202.67,203.13 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:205.4,205.19 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/deprecated/configencoding.go:209.2,209.20 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/auth.go:11.53,15.2 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/builder.go:13.53,22.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/buildx.go:33.46,36.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/buildx.go:39.54,46.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/buildx.go:46.16,48.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/buildx.go:49.2,56.12 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/buildx.go:60.44,76.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/buildx.go:79.69,84.2 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:39.42,40.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:40.14,42.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:43.2,44.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:44.17,46.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:47.2,47.20 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:47.20,49.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:50.2,50.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:53.54,56.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:62.57,64.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:66.45,67.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:67.14,69.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:70.2,70.51 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:78.52,92.2 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:94.39,95.18 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:95.18,97.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:98.2,99.28 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:99.28,101.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:102.2,102.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:111.62,138.2 6 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:140.50,141.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:141.14,143.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:144.2,145.19 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:145.19,147.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:148.2,148.19 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:148.19,150.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:151.2,151.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:151.17,153.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:154.2,154.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:163.46,164.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:164.14,166.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:167.2,168.18 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:168.18,170.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:171.2,171.24 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:171.24,173.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:174.2,174.29 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:174.29,176.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:177.2,177.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:180.58,184.2 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:193.44,194.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:194.14,196.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:197.2,197.77 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:213.51,249.2 14 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:251.39,252.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:252.14,254.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:255.2,256.20 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:256.20,258.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:259.2,259.18 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:259.18,261.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:262.2,262.25 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:262.25,264.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:265.2,265.25 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:265.25,267.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:268.2,268.29 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:268.29,270.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:271.2,271.27 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:271.27,273.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:274.2,274.25 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:274.25,276.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:277.2,277.29 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:277.29,279.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:280.2,280.26 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:280.26,282.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:284.2,284.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:291.53,296.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:298.40,299.18 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:299.18,301.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:302.2,302.39 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:309.60,312.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:314.47,315.26 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:315.26,317.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:318.2,318.55 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:328.37,329.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:329.14,331.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:332.2,332.70 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:337.30,339.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:352.54,380.2 7 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:382.41,383.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:383.16,385.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:386.2,386.64 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:391.41,392.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:392.14,394.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:395.2,395.22 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:406.52,410.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:412.40,413.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:413.14,415.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:416.2,420.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:432.43,433.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:433.14,435.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:436.2,442.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:451.60,459.2 6 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:461.47,462.29 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:462.29,464.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:465.2,466.25 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:466.25,468.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:469.2,469.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:469.28,471.14 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:471.14,473.4 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:474.3,474.65 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:476.2,476.31 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:476.31,478.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:479.2,479.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:489.48,490.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:490.14,492.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:493.2,493.81 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:508.52,541.2 8 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:543.39,544.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:544.16,546.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:547.2,547.74 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:557.56,568.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:578.68,584.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:588.49,590.23 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:590.23,592.14 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:592.14,593.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:595.3,595.27 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:597.2,597.35 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cache.go:600.38,602.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:31.62,33.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:33.16,35.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:55.2,56.28 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:56.28,58.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:60.2,60.31 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:60.31,67.3 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:80.2,100.16 6 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:100.16,102.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:104.2,114.21 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:177.32,179.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:181.34,183.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:185.31,187.2 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:190.41,192.28 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:192.28,197.3 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:198.2,200.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:205.42,207.15 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:207.15,209.35 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:209.35,211.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:214.2,215.15 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:215.15,217.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:218.2,218.30 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:222.29,225.19 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:225.19,227.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:228.2,228.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:231.76,235.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:235.16,237.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:238.2,243.16 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:243.16,245.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:251.2,252.52 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:252.52,257.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:260.2,263.16 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:263.16,265.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:266.2,298.35 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:298.35,300.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:301.2,301.24 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:301.24,303.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:304.2,304.35 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:304.35,306.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:307.2,307.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:307.33,309.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:310.2,310.21 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:310.21,312.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:313.2,313.21 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:313.21,315.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:316.2,316.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:316.33,318.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:319.2,319.36 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:319.36,321.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:322.2,322.39 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:322.39,324.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:325.2,325.32 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:325.32,327.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:328.2,328.18 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:328.18,330.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:331.2,331.35 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:331.35,333.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:334.2,334.15 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:334.15,336.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:337.2,337.31 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:337.31,339.25 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:339.25,341.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:342.3,342.34 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:344.2,344.30 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:344.30,346.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:347.2,347.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:347.23,349.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:350.2,350.31 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:350.31,352.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:353.2,353.32 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:353.32,356.3 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:357.2,357.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:357.28,359.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:361.2,361.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:361.33,367.3 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:369.2,370.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:370.16,372.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:376.2,377.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:377.16,379.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:380.2,381.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:381.16,383.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:384.2,386.16 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:386.16,388.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:389.2,390.24 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:390.24,391.25 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:392.15,393.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:394.11,396.18 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:396.18,397.13 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:399.4,399.25 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:403.2,404.18 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:404.18,406.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:407.2,409.8 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:414.60,417.20 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:417.20,419.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:420.2,425.16 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:425.16,427.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:428.2,428.21 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:428.21,430.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:432.2,445.16 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:445.16,447.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:448.2,455.18 6 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:467.54,469.22 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:469.22,471.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/cli.go:472.2,472.29 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:71.63,101.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:101.16,103.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:105.2,106.40 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:106.40,108.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:109.2,111.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:111.16,113.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:118.2,120.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:193.45,212.24 5 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:212.24,214.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:231.2,232.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:232.16,234.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:235.2,242.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:242.16,244.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:246.2,247.35 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:247.35,252.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:253.2,254.33 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:254.33,259.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:260.2,261.33 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:261.33,267.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:268.2,280.39 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:280.39,282.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:282.17,284.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:285.3,286.53 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:289.2,290.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:290.16,292.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:294.2,295.18 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:295.18,297.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:298.2,339.16 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:339.16,341.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:343.2,343.49 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:343.49,345.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:346.2,346.39 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:346.39,349.30 3 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:349.30,351.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:352.3,352.37 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:355.2,355.21 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:359.47,361.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:363.100,441.16 10 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:441.16,443.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:445.2,445.11 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:445.11,447.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:449.2,453.16 5 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:453.16,455.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:456.2,456.12 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:459.84,472.16 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:472.16,474.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:476.2,477.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:477.16,479.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:481.2,481.46 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:547.73,561.56 8 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:561.56,563.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:567.2,567.12 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:571.94,573.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:573.16,575.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:578.2,579.85 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:579.85,581.21 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:581.21,583.4 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:584.3,584.49 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:597.2,603.80 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:603.80,607.3 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:609.2,609.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:613.86,617.2 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:619.62,621.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:621.16,623.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:624.2,624.66 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:624.66,626.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/client.go:627.2,627.22 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:40.49,42.23 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:42.23,44.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:45.2,45.10 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:48.47,59.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:61.53,70.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:77.9,78.22 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:78.22,80.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:81.2,81.66 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:81.66,83.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:85.2,86.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:86.16,88.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:89.2,91.36 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:91.36,94.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:95.2,95.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:95.16,97.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:99.2,102.12 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:109.105,115.68 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:115.68,117.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:117.17,119.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:120.3,120.15 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:123.2,123.37 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:123.37,125.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:125.17,127.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:130.2,130.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:130.33,133.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:133.17,135.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:136.3,136.44 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:136.44,138.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:142.2,142.45 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:142.45,143.35 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:143.35,145.18 2 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:145.18,147.5 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:148.4,148.45 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:148.45,150.5 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:154.2,154.44 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:158.70,160.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:162.58,163.102 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:163.102,164.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:164.17,166.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:167.3,167.18 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:167.18,169.4 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:172.3,173.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:173.17,175.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:176.3,176.46 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:178.2,178.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:178.16,180.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:182.2,182.44 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:185.53,190.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:190.16,192.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:193.2,194.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:194.16,196.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:197.2,197.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:205.91,211.33 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:211.33,214.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:218.2,218.26 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:218.26,220.44 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:220.44,221.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:223.3,223.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:223.17,225.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:226.3,229.17 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:229.17,231.4 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:232.3,232.29 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:235.2,235.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:238.48,241.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:243.49,246.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:250.64,252.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:252.16,254.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/context.go:255.2,255.77 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/dedent.go:9.30,13.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/dockerfile.go:12.50,29.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:48.51,79.2 9 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:81.38,82.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:82.16,84.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:85.2,85.87 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:88.36,89.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:89.17,91.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:91.17,93.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:94.3,94.40 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:96.2,96.23 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:96.23,98.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:99.2,99.20 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:99.20,101.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:102.2,102.14 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:107.43,108.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:108.14,110.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:111.2,111.25 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:124.52,129.2 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:131.40,132.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:132.14,134.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:135.2,136.18 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:136.18,138.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:139.2,139.18 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:139.18,141.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:143.2,150.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:157.49,160.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:162.37,163.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:163.14,165.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:166.2,166.79 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:184.51,213.2 8 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:215.39,216.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:216.14,218.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:219.2,220.19 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:220.19,222.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:223.2,223.27 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:223.27,225.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:226.2,226.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:226.23,228.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:229.2,229.32 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:229.32,231.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:232.2,232.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:232.28,234.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:235.2,235.21 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:235.21,237.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:238.2,238.20 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:238.20,240.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:241.2,248.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:255.54,257.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:259.42,260.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:260.14,262.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:263.2,263.82 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:270.39,271.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:271.14,273.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:274.2,274.50 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:277.51,279.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:285.37,286.14 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:286.14,288.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:289.2,289.48 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:296.53,299.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:301.40,302.18 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:302.18,304.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:305.2,305.49 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:314.61,322.2 6 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:324.48,325.29 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:325.29,327.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:328.2,329.25 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:329.25,331.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:332.2,332.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:332.28,334.14 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:334.14,336.4 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:337.3,337.65 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:339.2,339.31 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:339.31,341.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:342.2,342.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:349.42,351.28 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:351.28,353.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:354.2,354.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:357.55,359.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:365.48,367.34 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:367.34,369.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:370.2,371.33 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:374.61,378.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/export.go:380.61,382.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:24.45,26.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:26.16,28.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:30.2,31.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:31.16,33.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:34.2,40.15 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:49.64,55.43 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:55.43,57.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:59.2,60.70 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:60.70,62.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:63.2,67.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:67.16,69.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:74.2,74.42 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:74.42,76.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:76.17,78.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:79.3,82.17 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:82.17,84.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:85.2,86.31 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:86.31,87.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:87.23,88.13 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:90.4,90.40 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:90.40,91.13 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:93.4,93.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:93.23,94.13 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:96.4,97.18 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:97.18,98.13 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:100.4,100.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:100.28,101.24 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:101.24,102.26 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:104.5,104.66 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:104.66,105.26 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:111.4,112.9 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:119.2,120.39 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:120.39,122.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/host.go:124.2,127.20 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:62.45,83.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:112.50,285.2 23 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:297.51,328.2 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:330.96,333.55 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:333.55,335.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:337.2,344.33 4 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:354.47,356.38 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:356.38,358.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:361.2,363.58 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:363.58,365.26 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:365.26,366.38 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:366.38,368.5 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:391.2,391.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:398.39,400.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:402.63,404.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:406.62,432.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:434.39,438.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:441.40,442.13 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:442.13,444.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:445.2,445.31 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:445.31,446.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:446.17,448.4 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:450.2,450.14 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:453.50,454.30 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:454.30,456.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:457.2,457.22 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:467.58,469.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:471.32,473.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:475.45,477.30 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:477.30,479.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:480.2,480.35 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:483.34,485.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:490.20,492.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:492.16,494.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:496.2,496.26 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:496.26,501.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:503.2,503.54 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:503.54,507.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:509.2,511.8 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:517.87,520.25 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:520.25,524.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:525.2,525.24 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:525.24,529.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:530.2,530.49 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:530.49,534.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:536.2,536.31 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:536.31,538.53 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:538.53,539.66 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:539.66,541.62 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:541.62,546.6 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:548.9,548.84 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:548.84,553.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:556.2,556.34 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:556.34,558.54 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:558.54,561.4 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:564.2,564.32 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:564.32,566.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:570.2,573.19 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:573.19,575.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:576.2,576.19 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:576.19,578.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:579.2,579.37 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:579.37,580.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:580.23,581.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:583.3,583.45 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:583.45,591.12 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:593.3,594.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:594.17,596.12 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:598.3,599.74 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:599.74,607.12 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:609.3,609.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:612.2,612.13 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:612.13,614.29 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:614.29,615.25 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:615.25,617.5 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:621.2,622.39 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:622.39,624.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:624.17,626.12 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:628.3,628.44 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:631.2,632.39 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:632.39,633.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:633.23,634.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:636.3,636.45 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:636.45,644.12 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:646.3,647.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:647.17,649.12 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:651.3,651.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:651.23,652.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:654.3,654.43 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:657.2,658.37 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:658.37,659.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:659.23,660.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:662.3,662.45 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:662.45,670.12 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:672.3,673.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:673.17,675.12 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:677.3,677.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:677.23,678.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:680.3,680.39 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:683.2,684.33 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:684.33,686.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:686.17,688.12 2 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:690.3,690.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:690.23,691.12 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:693.3,693.31 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:696.2,696.76 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:696.76,704.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:706.2,706.34 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:706.34,707.47 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:707.47,709.4 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:712.2,713.37 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:713.37,718.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:720.2,741.23 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:751.23,755.16 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:755.16,757.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:759.2,760.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:760.16,762.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:763.2,763.9 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:763.9,765.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:767.2,768.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:768.16,770.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:772.2,777.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:777.16,779.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:780.2,782.46 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:782.46,784.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:785.2,785.35 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:785.35,788.3 2 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:790.2,791.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:791.16,793.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:795.2,795.41 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:795.41,798.17 3 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:798.17,800.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:805.2,805.30 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:805.30,806.74 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:806.74,808.4 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:811.2,811.24 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:811.24,814.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:818.2,818.33 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:818.33,820.10 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:820.10,821.12 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:824.3,825.8 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:828.2,828.19 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:837.31,840.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:854.3,856.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:856.16,858.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:867.2,867.25 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:867.25,870.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:872.2,875.33 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:875.33,877.10 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:877.10,880.9 2 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:884.3,885.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:885.17,887.12 2 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:890.3,890.27 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:890.27,891.87 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:891.87,893.13 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:895.4,895.20 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:895.20,897.13 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:900.4,901.9 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:907.2,907.49 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:907.49,909.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:911.2,913.32 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:923.9,925.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:925.16,927.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:929.2,931.33 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:931.33,933.17 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:933.17,934.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:936.3,937.30 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:937.30,938.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:940.3,942.31 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:942.31,943.23 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:943.23,945.5 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:946.4,946.24 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:946.24,948.5 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:954.2,954.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:964.34,968.54 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:968.54,970.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:971.2,971.56 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:971.56,973.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:974.2,974.48 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:974.48,976.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:977.2,977.52 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:977.52,979.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:980.2,980.56 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:980.56,982.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:983.2,983.52 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:983.52,985.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:986.2,986.52 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:986.52,988.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:989.2,989.64 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:989.64,991.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:992.2,992.58 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:992.58,994.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:995.2,995.54 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:995.54,997.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:999.2,999.58 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:999.58,1001.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1002.2,1002.50 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1002.50,1004.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1005.2,1005.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1005.28,1007.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1008.2,1008.34 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1008.34,1010.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1011.2,1011.52 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1011.52,1013.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1014.2,1014.56 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1014.56,1016.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1017.2,1017.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1017.28,1019.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1020.2,1020.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1020.28,1022.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1023.2,1023.52 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1023.52,1025.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1026.2,1026.44 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1026.44,1028.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1029.2,1029.46 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1029.46,1031.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1032.2,1032.50 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1032.50,1034.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1038.2,1038.68 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1038.68,1040.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1043.2,1048.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1048.16,1050.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1051.2,1051.30 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1051.30,1053.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1056.2,1056.50 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1056.50,1058.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1058.8,1059.42 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1059.42,1061.74 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1061.74,1062.13 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1064.4,1065.9 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1069.2,1073.8 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1076.41,1078.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1078.16,1080.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1081.2,1082.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1082.16,1084.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1085.2,1085.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1091.51,1093.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1093.16,1095.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1096.2,1097.48 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1097.48,1099.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1101.2,1104.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1104.16,1106.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/image.go:1108.2,1108.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:40.46,50.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:52.50,71.2 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:78.32,81.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:89.24,93.16 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:93.16,95.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:97.2,97.13 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:97.13,99.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:103.2,104.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:104.16,106.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:108.2,109.19 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:117.44,122.16 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:122.16,124.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:132.2,133.84 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:133.84,136.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:137.2,137.85 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:137.85,140.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:141.2,141.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:141.16,143.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:145.2,145.49 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:145.49,147.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:149.2,149.32 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:157.48,159.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:159.16,161.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:176.2,176.74 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:176.74,184.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:186.2,186.35 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:186.35,187.61 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:187.61,195.4 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:198.2,198.28 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:201.82,203.16 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:203.16,205.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:206.2,208.70 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:208.70,210.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:211.2,211.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:219.34,223.26 3 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:223.26,225.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:226.2,226.52 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:226.52,228.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:229.2,229.52 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:229.52,231.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:232.2,232.54 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:232.54,234.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:237.2,241.8 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:248.19,251.55 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:251.55,253.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/images.go:255.2,259.33 4 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/network.go:15.60,30.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/platform.go:26.54,57.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/platform.go:59.35,61.2 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:14.49,16.26 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:16.26,17.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:17.17,18.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:20.3,20.29 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:22.2,22.15 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:28.43,29.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:29.16,31.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:32.2,32.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:39.43,40.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:40.16,42.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:43.2,43.41 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:52.51,53.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:53.16,55.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:56.2,56.44 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:62.64,63.31 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:63.31,65.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:66.2,68.26 3 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:68.26,69.20 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:69.20,70.12 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:72.3,72.20 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:72.20,73.12 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:75.3,75.22 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:77.2,77.17 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:82.59,83.38 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:83.38,85.3 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:87.2,89.29 3 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:89.29,90.42 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:90.42,91.12 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:93.3,93.15 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/preview.go:96.2,99.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/ssh.go:14.43,31.2 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/ssh.go:33.30,34.16 1 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/ssh.go:34.16,36.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/ssh.go:38.2,40.22 2 1
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/ssh.go:40.22,42.3 1 0
|
||||
github.com/pulumi/pulumi-docker/provider/v4/internal/ssh.go:44.2,44.10 1 1
|
||||
27
provider/internal/dedent.go
Normal file
27
provider/internal/dedent.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// 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.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
dd "github.com/muesli/reflow/dedent"
|
||||
)
|
||||
|
||||
func dedent(s string) string {
|
||||
return strings.TrimSpace(dd.String(
|
||||
strings.ReplaceAll(s, `"`, "`"),
|
||||
))
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user