Merge remote-tracking branch 'origin/master' into fix-chown
This commit is contained in:
commit
03fcc537c3
|
|
@ -1 +0,0 @@
|
|||
vendor/
|
||||
16
.travis.yml
16
.travis.yml
|
|
@ -2,9 +2,10 @@ language: go
|
|||
os: linux
|
||||
dist: bionic
|
||||
env:
|
||||
- IMAGE_REPO=localhost:5000
|
||||
global:
|
||||
- IMAGE_REPO=localhost:5000 REGISTRY=localhost:5000
|
||||
go:
|
||||
- "1.13.3"
|
||||
- "1.14"
|
||||
go_import_path: github.com/GoogleContainerTools/kaniko
|
||||
jobs:
|
||||
include:
|
||||
|
|
@ -21,11 +22,16 @@ jobs:
|
|||
- make travis-setup
|
||||
script:
|
||||
- make integration-test-layers
|
||||
- name: build-image-and-k8s-integration-test
|
||||
before_install:
|
||||
- make travis-setup
|
||||
- make minikube-setup
|
||||
script:
|
||||
- make images
|
||||
- make push
|
||||
- make integration-test-k8s
|
||||
- name: integration-test-misc
|
||||
before_install:
|
||||
- make travis-setup
|
||||
script:
|
||||
- make integration-test-misc
|
||||
- stage: build-images
|
||||
script:
|
||||
- make images
|
||||
|
|
|
|||
28
Makefile
28
Makefile
|
|
@ -55,28 +55,36 @@ out/warmer: $(GO_FILES)
|
|||
|
||||
.PHONY: travis-setup
|
||||
travis-setup:
|
||||
@ ./travis-setup.sh
|
||||
@ ./scripts/travis-setup.sh
|
||||
|
||||
.PHONY: minikube-setup
|
||||
minikube-setup:
|
||||
@ ./scripts/minikube-setup.sh
|
||||
|
||||
.PHONY: test
|
||||
test: out/executor
|
||||
@ ./test.sh
|
||||
@ ./scripts/test.sh
|
||||
|
||||
.PHONY: integration-test
|
||||
integration-test:
|
||||
@ ./integration-test.sh
|
||||
@ ./scripts/integration-test.sh
|
||||
|
||||
.PHONY: integration-test-run
|
||||
integration-test-run:
|
||||
@ ./integration-test.sh -run "TestRun"
|
||||
@ ./scripts/integration-test.sh -run "TestRun"
|
||||
|
||||
.PHONY: integration-test-layers
|
||||
integration-test-layers:
|
||||
@ ./integration-test.sh -run "TestLayers"
|
||||
@ ./scripts/integration-test.sh -run "TestLayers"
|
||||
|
||||
.PHONY: integration-test-k8s
|
||||
integration-test-k8s:
|
||||
@ ./scripts/integration-test.sh -run "TestK8s"
|
||||
|
||||
.PHONY: integration-test-misc
|
||||
integration-test-misc:
|
||||
$(eval RUN_ARG=$(shell ./misc-integration-test.sh))
|
||||
@ ./integration-test.sh -run "$(RUN_ARG)"
|
||||
$(eval RUN_ARG=$(shell ./scripts/misc-integration-test.sh))
|
||||
@ ./scripts/integration-test.sh -run "$(RUN_ARG)"
|
||||
|
||||
.PHONY: images
|
||||
images:
|
||||
|
|
@ -86,6 +94,6 @@ images:
|
|||
|
||||
.PHONY: push
|
||||
push:
|
||||
docker push $(REGISTRY)/executor:latest
|
||||
docker push $(REGISTRY)/executor:debug
|
||||
docker push $(REGISTRY)/warmer:latest
|
||||
docker push $(REGISTRY)/executor:latest
|
||||
docker push $(REGISTRY)/executor:debug
|
||||
docker push $(REGISTRY)/warmer:latest
|
||||
|
|
|
|||
28
README.md
28
README.md
|
|
@ -146,6 +146,7 @@ When running kaniko, use the `--context` flag with the appropriate prefix to spe
|
|||
| Source | Prefix | Example |
|
||||
|---------|---------|---------|
|
||||
| Local Directory | dir://[path to a directory in the kaniko container] | `dir:///workspace` |
|
||||
| Local Tar Gz | tar://[path to a .tar.gz in the kaniko container] | `tar://path/to/context.tar.gz` |
|
||||
| GCS Bucket | gs://[bucket name]/[path to .tar.gz] | `gs://kaniko-bucket/path/to/context.tar.gz` |
|
||||
| S3 Bucket | s3://[bucket name]/[path to .tar.gz] | `s3://kaniko-bucket/path/to/context.tar.gz` |
|
||||
| Azure Blob Storage| https://[account].[azureblobhostsuffix]/[container]/[path to .tar.gz] | `https://myaccount.blob.core.windows.net/container/path/to/context.tar.gz` |
|
||||
|
|
@ -260,21 +261,24 @@ kaniko will build and push the final image in this build step.
|
|||
Requirements:
|
||||
|
||||
- [Docker](https://docs.docker.com/install/)
|
||||
- [gcloud](https://cloud.google.com/sdk/install)
|
||||
|
||||
We can run the kaniko executor image locally in a Docker daemon to build and push an image from a Dockerfile.
|
||||
|
||||
1. Load the executor image into the Docker daemon by running:
|
||||
For example, when using gcloud and GCR you could run Kaniko as follows:
|
||||
```shell
|
||||
docker run \
|
||||
-v "$HOME"/.config/gcloud:/root/.config/gcloud \
|
||||
-v /path/to/context:/workspace \
|
||||
gcr.io/kaniko-project/executor:latest \
|
||||
--dockerfile /workspace/Dockerfile
|
||||
--destination "gcr.io/$PROJECT_ID/$IMAGE_NAME:$TAG"
|
||||
--context dir:///workspace/"
|
||||
```
|
||||
|
||||
```shell
|
||||
make images
|
||||
```
|
||||
|
||||
2. Run kaniko in Docker using [`run_in_docker.sh`](./run_in_docker.sh):
|
||||
|
||||
```shell
|
||||
./run_in_docker.sh <path to Dockerfile> <path to build context> <destination of final image>
|
||||
```
|
||||
There is also a utility script [`run_in_docker.sh`](./run_in_docker.sh) that can be used as follows:
|
||||
```shell
|
||||
./run_in_docker.sh <path to Dockerfile> <path to build context> <destination of final image>
|
||||
```
|
||||
|
||||
_NOTE: `run_in_docker.sh` expects a path to a
|
||||
Dockerfile relative to the absolute path of the build context._
|
||||
|
|
@ -284,7 +288,7 @@ context in the local directory `/home/user/kaniko-project`, and a Google Contain
|
|||
as a remote image destination:
|
||||
|
||||
```shell
|
||||
./run_in_docker.sh /workspace/Dockerfile /home/user/kaniko-project gcr.io//<project-id>/<tag>
|
||||
./run_in_docker.sh /workspace/Dockerfile /home/user/kaniko-project gcr.io/$PROJECT_ID/$TAG
|
||||
```
|
||||
|
||||
### Caching
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ func copyDockerfile() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// resolveSourceContext unpacks the source context if it is a tar in a bucket
|
||||
// resolveSourceContext unpacks the source context if it is a tar in a bucket or in kaniko container
|
||||
// it resets srcContext to be the path to the unpacked build context within the image
|
||||
func resolveSourceContext() error {
|
||||
if opts.SrcContext == "" && opts.Bucket == "" {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
# Builds the static Go image to execute in a Kubernetes job
|
||||
|
||||
FROM golang:1.13
|
||||
FROM golang:1.14
|
||||
ARG GOARCH=amd64
|
||||
WORKDIR /go/src/github.com/GoogleContainerTools/kaniko
|
||||
# Get GCR credential helper
|
||||
|
|
@ -35,7 +35,7 @@ FROM scratch
|
|||
COPY --from=0 /go/src/github.com/GoogleContainerTools/kaniko/out/executor /kaniko/executor
|
||||
COPY --from=0 /usr/local/bin/docker-credential-gcr /kaniko/docker-credential-gcr
|
||||
COPY --from=0 /go/src/github.com/awslabs/amazon-ecr-credential-helper/bin/linux-amd64/docker-credential-ecr-login /kaniko/docker-credential-ecr-login
|
||||
COPY --from=0 /usr/local/bin/docker-credential-acr-linux /kaniko/docker-credential-acr-linux
|
||||
COPY --from=0 /usr/local/bin/docker-credential-acr-linux /kaniko/docker-credential-acr
|
||||
COPY files/ca-certificates.crt /kaniko/ssl/certs/
|
||||
COPY --from=0 /root/.docker/config.json /kaniko/.docker/config.json
|
||||
ENV HOME /root
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
# Builds the static Go image to execute in a Kubernetes job
|
||||
|
||||
# Stage 0: Build the executor binary and get credential helpers
|
||||
FROM golang:1.13
|
||||
FROM golang:1.14
|
||||
ARG GOARCH=amd64
|
||||
WORKDIR /go/src/github.com/GoogleContainerTools/kaniko
|
||||
# Get GCR credential helper
|
||||
|
|
@ -25,6 +25,10 @@ RUN docker-credential-gcr configure-docker
|
|||
# Get Amazon ECR credential helper
|
||||
RUN go get -u github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cli/docker-credential-ecr-login
|
||||
RUN make -C /go/src/github.com/awslabs/amazon-ecr-credential-helper linux-amd64
|
||||
# ACR docker credential helper
|
||||
ADD https://aadacr.blob.core.windows.net/acr-docker-credential-helper/docker-credential-acr-linux-amd64.tar.gz /usr/local/bin
|
||||
RUN tar -C /usr/local/bin/ -xvzf /usr/local/bin/docker-credential-acr-linux-amd64.tar.gz
|
||||
|
||||
COPY . .
|
||||
RUN make GOARCH=${GOARCH} && make out/warmer
|
||||
|
||||
|
|
@ -39,6 +43,7 @@ FROM scratch
|
|||
COPY --from=0 /go/src/github.com/GoogleContainerTools/kaniko/out/* /kaniko/
|
||||
COPY --from=0 /usr/local/bin/docker-credential-gcr /kaniko/docker-credential-gcr
|
||||
COPY --from=0 /go/src/github.com/awslabs/amazon-ecr-credential-helper/bin/linux-amd64/docker-credential-ecr-login /kaniko/docker-credential-ecr-login
|
||||
COPY --from=0 /usr/local/bin/docker-credential-acr-linux /kaniko/docker-credential-acr
|
||||
COPY --from=1 /distroless/bazel-bin/experimental/busybox/busybox/ /busybox/
|
||||
# Declare /busybox as a volume to get it automatically whitelisted
|
||||
VOLUME /busybox
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
# Builds the static Go image to execute in a Kubernetes job
|
||||
|
||||
FROM golang:1.13
|
||||
FROM golang:1.14
|
||||
ARG GOARCH=amd64
|
||||
WORKDIR /go/src/github.com/GoogleContainerTools/kaniko
|
||||
# Get GCR credential helper
|
||||
|
|
@ -24,6 +24,9 @@ RUN docker-credential-gcr configure-docker
|
|||
# Get Amazon ECR credential helper
|
||||
RUN go get -u github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cli/docker-credential-ecr-login
|
||||
RUN make -C /go/src/github.com/awslabs/amazon-ecr-credential-helper linux-amd64
|
||||
# ACR docker credential helper
|
||||
ADD https://aadacr.blob.core.windows.net/acr-docker-credential-helper/docker-credential-acr-linux-amd64.tar.gz /usr/local/bin
|
||||
RUN tar -C /usr/local/bin/ -xvzf /usr/local/bin/docker-credential-acr-linux-amd64.tar.gz
|
||||
|
||||
COPY . .
|
||||
RUN make GOARCH=${GOARCH} out/warmer
|
||||
|
|
@ -32,6 +35,7 @@ FROM scratch
|
|||
COPY --from=0 /go/src/github.com/GoogleContainerTools/kaniko/out/warmer /kaniko/warmer
|
||||
COPY --from=0 /usr/local/bin/docker-credential-gcr /kaniko/docker-credential-gcr
|
||||
COPY --from=0 /go/src/github.com/awslabs/amazon-ecr-credential-helper/bin/linux-amd64/docker-credential-ecr-login /kaniko/docker-credential-ecr-login
|
||||
COPY --from=0 /usr/local/bin/docker-credential-acr-linux /kaniko/docker-credential-acr
|
||||
COPY files/ca-certificates.crt /kaniko/ssl/certs/
|
||||
COPY --from=0 /root/.docker/config.json /kaniko/.docker/config.json
|
||||
ENV HOME /root
|
||||
|
|
|
|||
|
|
@ -2,18 +2,21 @@ steps:
|
|||
# First, build kaniko
|
||||
- name: "gcr.io/cloud-builders/docker"
|
||||
args: ["build", "-f", "deploy/Dockerfile",
|
||||
"-t", "gcr.io/kaniko-project/executor:${COMMIT_SHA}", "."]
|
||||
"-t", "gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:${COMMIT_SHA}", "."]
|
||||
# Then, we want to build kaniko:debug
|
||||
- name: "gcr.io/cloud-builders/docker"
|
||||
args: ["build", "-f", "deploy/Dockerfile_debug",
|
||||
"-t", "gcr.io/kaniko-project/executor:debug-${COMMIT_SHA}", "."]
|
||||
"-t", "gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:debug-${COMMIT_SHA}", "."]
|
||||
- name: "gcr.io/cloud-builders/docker"
|
||||
args: ["build", "-f", "deploy/Dockerfile_debug",
|
||||
"-t", "gcr.io/kaniko-project/executor:debug", "."]
|
||||
"-t", "gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:debug", "."]
|
||||
# Then, we want to build the cache warmer
|
||||
- name: "gcr.io/cloud-builders/docker"
|
||||
args: ["build", "-f", "deploy/Dockerfile_warmer",
|
||||
"-t", "gcr.io/kaniko-project/warmer:${COMMIT_SHA}", "."]
|
||||
images: ["gcr.io/kaniko-project/executor:${COMMIT_SHA}",
|
||||
"gcr.io/kaniko-project/executor:debug-${COMMIT_SHA}",
|
||||
"gcr.io/kaniko-project/warmer:${COMMIT_SHA}"]
|
||||
"-t", "gcr.io/$PROJECT_ID/${_WARMER_IMAGE_NAME}:${COMMIT_SHA}", "."]
|
||||
images: ["gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:${COMMIT_SHA}",
|
||||
"gcr.io/$PROJECT_ID/${_EXECUTOR_IMAGE_NAME}:debug-${COMMIT_SHA}",
|
||||
"gcr.io/$PROJECT_ID/${_WARMER_IMAGE_NAME}:${COMMIT_SHA}"]
|
||||
substitutions:
|
||||
_EXECUTOR_IMAGE_NAME: executor
|
||||
_WARMER_IMAGE_NAME: warmer
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -1,6 +1,6 @@
|
|||
module github.com/GoogleContainerTools/kaniko
|
||||
|
||||
go 1.13
|
||||
go 1.14
|
||||
|
||||
replace (
|
||||
github.com/containerd/containerd v1.4.0-0.20191014053712-acdcf13d5eaf => github.com/containerd/containerd v0.0.0-20191014053712-acdcf13d5eaf
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|||
|
||||
if ! [ -x "$(command -v golangci-lint)" ]; then
|
||||
echo "Installing GolangCI-Lint"
|
||||
${DIR}/install_golint.sh -b $GOPATH/bin v1.21.0
|
||||
${DIR}/install_golint.sh -b $GOPATH/bin v1.23.7
|
||||
fi
|
||||
|
||||
golangci-lint run
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2018 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -ex
|
||||
|
||||
GCS_BUCKET="${GCS_BUCKET:-gs://kaniko-test-bucket}"
|
||||
IMAGE_REPO="${IMAGE_REPO:-gcr.io/kaniko-test}"
|
||||
|
||||
docker version
|
||||
|
||||
# Sets up a kokoro (Google internal integration testing tool) environment
|
||||
if [ -f "$KOKORO_GFILE_DIR"/common.sh ]; then
|
||||
echo "Installing dependencies..."
|
||||
source "$KOKORO_GFILE_DIR/common.sh"
|
||||
mkdir -p /usr/local/go/src/github.com/GoogleContainerTools/
|
||||
cp -r github/kaniko /usr/local/go/src/github.com/GoogleContainerTools/
|
||||
pushd /usr/local/go/src/github.com/GoogleContainerTools/kaniko
|
||||
echo "Installing container-diff..."
|
||||
mv $KOKORO_GFILE_DIR/container-diff-linux-amd64 $KOKORO_GFILE_DIR/container-diff
|
||||
chmod +x $KOKORO_GFILE_DIR/container-diff
|
||||
export PATH=$PATH:$KOKORO_GFILE_DIR
|
||||
cp $KOKORO_ROOT/src/keystore/72508_gcr_application_creds $HOME/.config/gcloud/application_default_credentials.json
|
||||
fi
|
||||
|
||||
echo "Running integration tests..."
|
||||
make out/executor
|
||||
make out/warmer
|
||||
go test ./integration/... -v --bucket "${GCS_BUCKET}" --repo "${IMAGE_REPO}" --timeout 50m "$@"
|
||||
|
|
@ -0,0 +1 @@
|
|||
scripts/integration-test.sh
|
||||
|
|
@ -185,23 +185,8 @@ func addServiceAccountFlags(flags []string, serviceAccount string) []string {
|
|||
return flags
|
||||
}
|
||||
|
||||
// BuildImage will build dockerfile (located at dockerfilesPath) using both kaniko and docker.
|
||||
// The resulting image will be tagged with imageRepo. If the dockerfile will be built with
|
||||
// context (i.e. it is in `buildContextTests`) the context will be pulled from gcsBucket.
|
||||
func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfilesPath, dockerfile string) error {
|
||||
_, ex, _, _ := runtime.Caller(0)
|
||||
cwd := filepath.Dir(ex)
|
||||
|
||||
return d.BuildImageWithContext(config, dockerfilesPath, dockerfile, cwd)
|
||||
}
|
||||
|
||||
func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig, dockerfilesPath, dockerfile, contextDir string) error {
|
||||
if _, present := d.filesBuilt[dockerfile]; present {
|
||||
return nil
|
||||
}
|
||||
gcsBucket, serviceAccount, imageRepo := config.gcsBucket, config.serviceAccount, config.imageRepo
|
||||
|
||||
fmt.Printf("Building images for Dockerfile %s\n", dockerfile)
|
||||
func (d *DockerFileBuilder) BuildDockerImage(imageRepo, dockerfilesPath, dockerfile, contextDir string) error {
|
||||
fmt.Printf("Building image for Dockerfile %s\n", dockerfile)
|
||||
|
||||
var buildArgs []string
|
||||
buildArgFlag := "--build-arg"
|
||||
|
|
@ -230,13 +215,39 @@ func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig,
|
|||
dockerCmd.Env = append(dockerCmd.Env, env...)
|
||||
}
|
||||
|
||||
timer := timing.Start(dockerfile + "_docker")
|
||||
out, err := RunCommandWithoutTest(dockerCmd)
|
||||
timing.DefaultRun.Stop(timer)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to build image %s with docker command \"%s\": %s %s", dockerImage, dockerCmd.Args, err, string(out))
|
||||
}
|
||||
fmt.Printf("Build image for Dockerfile %s as %s. docker build output: %s \n", dockerfile, dockerImage, out)
|
||||
return nil
|
||||
}
|
||||
|
||||
// BuildImage will build dockerfile (located at dockerfilesPath) using both kaniko and docker.
|
||||
// The resulting image will be tagged with imageRepo. If the dockerfile will be built with
|
||||
// context (i.e. it is in `buildContextTests`) the context will be pulled from gcsBucket.
|
||||
func (d *DockerFileBuilder) BuildImage(config *integrationTestConfig, dockerfilesPath, dockerfile string) error {
|
||||
_, ex, _, _ := runtime.Caller(0)
|
||||
cwd := filepath.Dir(ex)
|
||||
|
||||
return d.BuildImageWithContext(config, dockerfilesPath, dockerfile, cwd)
|
||||
}
|
||||
|
||||
func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig, dockerfilesPath, dockerfile, contextDir string) error {
|
||||
if _, present := d.filesBuilt[dockerfile]; present {
|
||||
return nil
|
||||
}
|
||||
gcsBucket, serviceAccount, imageRepo := config.gcsBucket, config.serviceAccount, config.imageRepo
|
||||
|
||||
var buildArgs []string
|
||||
buildArgFlag := "--build-arg"
|
||||
for _, arg := range argsMap[dockerfile] {
|
||||
buildArgs = append(buildArgs, buildArgFlag, arg)
|
||||
}
|
||||
|
||||
timer := timing.Start(dockerfile + "_docker")
|
||||
d.BuildDockerImage(imageRepo, dockerfilesPath, dockerfile, contextDir)
|
||||
timing.DefaultRun.Stop(timer)
|
||||
|
||||
contextFlag := "-c"
|
||||
contextPath := buildContextPath
|
||||
|
|
@ -269,7 +280,7 @@ func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig,
|
|||
}
|
||||
|
||||
// build kaniko image
|
||||
additionalFlags = append(buildArgs, additionalKanikoFlagsMap[dockerfile]...)
|
||||
additionalFlags := append(buildArgs, additionalKanikoFlagsMap[dockerfile]...)
|
||||
kanikoImage := GetKanikoImage(imageRepo, dockerfile)
|
||||
fmt.Printf("Going to build image with kaniko: %s, flags: %s \n", kanikoImage, additionalFlags)
|
||||
|
||||
|
|
@ -301,16 +312,16 @@ func (d *DockerFileBuilder) BuildImageWithContext(config *integrationTestConfig,
|
|||
kanikoCmd := exec.Command("docker", dockerRunFlags...)
|
||||
|
||||
timer = timing.Start(dockerfile + "_kaniko")
|
||||
out, err = RunCommandWithoutTest(kanikoCmd)
|
||||
out, err := RunCommandWithoutTest(kanikoCmd)
|
||||
timing.DefaultRun.Stop(timer)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to build image %s with kaniko command \"%s\": %s %s", dockerImage, kanikoCmd.Args, err, string(out))
|
||||
return fmt.Errorf("Failed to build image %s with kaniko command \"%s\": %s %s", kanikoImage, kanikoCmd.Args, err, string(out))
|
||||
}
|
||||
|
||||
if outputCheck := outputChecks[dockerfile]; outputCheck != nil {
|
||||
if err := outputCheck(dockerfile, out); err != nil {
|
||||
return fmt.Errorf("Output check failed for image %s with kaniko command \"%s\": %s %s", dockerImage, kanikoCmd.Args, err, string(out))
|
||||
return fmt.Errorf("Output check failed for image %s with kaniko command \"%s\": %s %s", kanikoImage, kanikoCmd.Args, err, string(out))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,11 +33,10 @@ import (
|
|||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1/daemon"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/timing"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||
"github.com/GoogleContainerTools/kaniko/testutil"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var config *integrationTestConfig
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: kaniko-test-{{.Name}}
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kaniko
|
||||
image: localhost:5000/executor:debug
|
||||
args: [ "--context=dir:///workspace",
|
||||
"--destination={{.KanikoImage}}"]
|
||||
volumeMounts:
|
||||
- name: context
|
||||
mountPath: /workspace
|
||||
restartPolicy: Never
|
||||
volumes:
|
||||
- name: context
|
||||
hostPath:
|
||||
path: {{.Context}}
|
||||
backoffLimit: 1
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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 integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type K8sConfig struct {
|
||||
KanikoImage string
|
||||
Context string
|
||||
Name string
|
||||
}
|
||||
|
||||
func TestK8s(t *testing.T) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dir := filepath.Join(cwd, "dockerfiles-with-context")
|
||||
|
||||
testDirs, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
builder := NewDockerFileBuilder()
|
||||
|
||||
for _, tdInfo := range testDirs {
|
||||
name := tdInfo.Name()
|
||||
testDir := filepath.Join(dir, name)
|
||||
|
||||
t.Run("test_k8s_with_context_"+name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if err := builder.BuildDockerImage(
|
||||
config.imageRepo, "", name, testDir,
|
||||
); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dockerImage := GetDockerImage(config.imageRepo, name)
|
||||
kanikoImage := GetKanikoImage(config.imageRepo, name)
|
||||
|
||||
tmpfile, err := ioutil.TempFile("", "k8s-job-*.yaml")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer os.Remove(tmpfile.Name()) // clean up
|
||||
tmpl := template.Must(template.ParseFiles("k8s-job.yaml"))
|
||||
job := K8sConfig{KanikoImage: kanikoImage, Context: testDir, Name: name}
|
||||
if err := tmpl.Execute(tmpfile, job); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Testing K8s based Kaniko building of dockerfile %s and push to %s \n",
|
||||
testDir, kanikoImage)
|
||||
content, err := ioutil.ReadFile(tmpfile.Name())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("K8s template %s:\n%s\n", tmpfile.Name(), content)
|
||||
|
||||
kubeCmd := exec.Command("kubectl", "apply", "-f", tmpfile.Name())
|
||||
RunCommand(kubeCmd, t)
|
||||
|
||||
fmt.Printf("Waiting for K8s kaniko build job to finish: %s\n",
|
||||
"job/kaniko-test-"+job.Name)
|
||||
|
||||
kubeWaitCmd := exec.Command("kubectl", "wait", "--for=condition=complete", "--timeout=60s",
|
||||
"job/kaniko-test-"+job.Name)
|
||||
RunCommand(kubeWaitCmd, t)
|
||||
|
||||
diff := containerDiff(t, daemonPrefix+dockerImage, kanikoImage, "--no-cache")
|
||||
|
||||
expected := fmt.Sprintf(emptyContainerDiff, dockerImage, kanikoImage, dockerImage, kanikoImage)
|
||||
checkContainerDiffOutput(t, diff, expected)
|
||||
})
|
||||
}
|
||||
|
||||
if err := logBenchmarks("benchmark"); err != nil {
|
||||
t.Logf("Failed to create benchmark file: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -43,12 +43,12 @@ func (b *AzureBlob) UnpackTarFromBuildContext() (string, error) {
|
|||
return "", errors.New("AZURE_STORAGE_ACCESS_KEY environment variable is not set")
|
||||
}
|
||||
|
||||
// Get storage accoutname for Azure Blob Storage
|
||||
// Get storage accountName for Azure Blob Storage
|
||||
u, _ := url.Parse(b.context)
|
||||
parts := azblob.NewBlobURLParts(*u)
|
||||
accountName := strings.Split(parts.Host, ".")[0]
|
||||
|
||||
// Generate credentail with accountname and accountkey
|
||||
// Generate credential with accountName and accountKey
|
||||
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
|
||||
if err != nil {
|
||||
return parts.Host, err
|
||||
|
|
@ -62,7 +62,7 @@ func (b *AzureBlob) UnpackTarFromBuildContext() (string, error) {
|
|||
return tarPath, err
|
||||
}
|
||||
|
||||
// Downloading contextfile from Azure Blob Storage
|
||||
// Downloading context file from Azure Blob Storage
|
||||
p := azblob.NewPipeline(credential, azblob.PipelineOptions{})
|
||||
blobURL := azblob.NewBlobURL(*u, p)
|
||||
ctx := context.Background()
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ import (
|
|||
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||
)
|
||||
|
||||
const (
|
||||
TarBuildContextPrefix = "tar://"
|
||||
)
|
||||
|
||||
// BuildContext unifies calls to download and unpack the build context.
|
||||
type BuildContext interface {
|
||||
// Unpacks a build context and returns the directory where it resides
|
||||
|
|
@ -51,6 +55,8 @@ func GetBuildContext(srcContext string) (BuildContext, error) {
|
|||
return &AzureBlob{context: srcContext}, nil
|
||||
}
|
||||
return nil, errors.New("url provided for https context is not in a supported format, please use the https url for Azure Blob Storage")
|
||||
case TarBuildContextPrefix:
|
||||
return &Tar{context: context}, nil
|
||||
}
|
||||
return nil, errors.New("unknown build context prefix provided, please use one of the following: gs://, dir://, s3://, git://, https://")
|
||||
return nil, errors.New("unknown build context prefix provided, please use one of the following: gs://, dir://, tar://, s3://, git://, https://")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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 buildcontext
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Tar unifies calls to download and unpack the build context.
|
||||
type Tar struct {
|
||||
context string
|
||||
}
|
||||
|
||||
// UnpackTarFromBuildContext unpack the compressed tar file
|
||||
func (t *Tar) UnpackTarFromBuildContext() (string, error) {
|
||||
directory := constants.BuildContextDir
|
||||
if err := os.MkdirAll(directory, 0750); err != nil {
|
||||
return "", errors.Wrap(err, "unpacking tar from build context")
|
||||
}
|
||||
|
||||
return directory, util.UnpackCompressedTar(t.context, directory)
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
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 buildcontext
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||
"github.com/GoogleContainerTools/kaniko/testutil"
|
||||
)
|
||||
|
||||
func TestBuildWithLocalTar(t *testing.T) {
|
||||
_, ex, _, _ := runtime.Caller(0)
|
||||
cwd := filepath.Dir(ex)
|
||||
|
||||
testDir := "test_dir"
|
||||
testDirLongPath := filepath.Join(cwd, testDir)
|
||||
dirUnpack := filepath.Join(testDirLongPath, "dir_where_to_unpack")
|
||||
|
||||
if err := os.MkdirAll(dirUnpack, 0750); err != nil {
|
||||
t.Errorf("Failed to create dir_where_to_extract: %v", err)
|
||||
}
|
||||
|
||||
validDockerfile := "Dockerfile_valid"
|
||||
invalidDockerfile := "Dockerfile_invalid"
|
||||
nonExistingDockerfile := "Dockerfile_non_existing"
|
||||
|
||||
files := map[string]string{
|
||||
validDockerfile: "FROM debian:9.11\nRUN echo \"valid\"",
|
||||
invalidDockerfile: "FROM debian:9.11\nRUN echo \"invalid\"",
|
||||
}
|
||||
|
||||
if err := testutil.SetupFiles(testDir, files); err != nil {
|
||||
t.Errorf("Failed to setup files %v on %s: %v", files, testDir, err)
|
||||
}
|
||||
|
||||
if err := os.Chdir(testDir); err != nil {
|
||||
t.Fatalf("Failed to Chdir on %s: %v", testDir, err)
|
||||
}
|
||||
|
||||
validTarPath := fmt.Sprintf("%s.tar.gz", validDockerfile)
|
||||
invalidTarPath := fmt.Sprintf("%s.tar.gz", invalidDockerfile)
|
||||
nonExistingTarPath := fmt.Sprintf("%s.tar.gz", nonExistingDockerfile)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
// Create Tar Gz File with dockerfile inside
|
||||
go func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
validTarFile, err := os.Create(validTarPath)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create %s: %v", validTarPath, err)
|
||||
}
|
||||
defer validTarFile.Close()
|
||||
|
||||
invalidTarFile, err := os.Create(invalidTarPath)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create %s: %v", invalidTarPath, err)
|
||||
}
|
||||
defer invalidTarFile.Close()
|
||||
|
||||
gw := gzip.NewWriter(validTarFile)
|
||||
defer gw.Close()
|
||||
|
||||
tw := util.NewTar(gw)
|
||||
defer tw.Close()
|
||||
|
||||
if err := tw.AddFileToTar(validDockerfile); err != nil {
|
||||
t.Errorf("Failed to add %s to %s: %v", validDockerfile, validTarPath, err)
|
||||
}
|
||||
}(&wg)
|
||||
|
||||
// Waiting for the Tar Gz file creation to be done before moving on
|
||||
wg.Wait()
|
||||
|
||||
tests := []struct {
|
||||
dockerfile string
|
||||
srcContext string
|
||||
unpackShouldErr bool
|
||||
srcShaShouldErr bool
|
||||
destShaShouldErr bool
|
||||
}{
|
||||
{
|
||||
dockerfile: validDockerfile,
|
||||
srcContext: filepath.Join(testDir, validTarPath),
|
||||
unpackShouldErr: false,
|
||||
srcShaShouldErr: false,
|
||||
destShaShouldErr: false,
|
||||
},
|
||||
{
|
||||
dockerfile: invalidDockerfile,
|
||||
srcContext: filepath.Join(testDir, invalidTarPath),
|
||||
unpackShouldErr: true,
|
||||
srcShaShouldErr: false,
|
||||
destShaShouldErr: true,
|
||||
},
|
||||
{
|
||||
dockerfile: nonExistingDockerfile,
|
||||
srcContext: filepath.Join(testDir, nonExistingTarPath),
|
||||
unpackShouldErr: true,
|
||||
srcShaShouldErr: true,
|
||||
destShaShouldErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.dockerfile, func(t *testing.T) {
|
||||
err := util.UnpackCompressedTar(filepath.Join(cwd, tt.srcContext), dirUnpack)
|
||||
testutil.CheckError(t, tt.unpackShouldErr, err)
|
||||
srcSHA, err := getSHAFromFilePath(tt.dockerfile)
|
||||
testutil.CheckError(t, tt.srcShaShouldErr, err)
|
||||
destSHA, err := getSHAFromFilePath(filepath.Join(dirUnpack, tt.dockerfile))
|
||||
testutil.CheckError(t, tt.destShaShouldErr, err)
|
||||
if err == nil {
|
||||
testutil.CheckDeepEqual(t, srcSHA, destSHA)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if err := os.RemoveAll(testDirLongPath); err != nil {
|
||||
t.Errorf("Failed to remove %s: %v", testDirLongPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
func getSHAFromFilePath(f string) (string, error) {
|
||||
data, err := ioutil.ReadFile(f)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sha, err := util.SHA256(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return sha, nil
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ type stageBuilder struct {
|
|||
stageIdxToDigest map[string]string
|
||||
snapshotter snapShotter
|
||||
layerCache cache.LayerCache
|
||||
pushCache cachePusher
|
||||
pushLayerToCache cachePusher
|
||||
}
|
||||
|
||||
// newStageBuilder returns a new type stageBuilder which contains all the information required to build the stage
|
||||
|
|
@ -116,7 +116,7 @@ func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage, cross
|
|||
layerCache: &cache.RegistryCache{
|
||||
Opts: opts,
|
||||
},
|
||||
pushCache: pushLayerToCache,
|
||||
pushLayerToCache: pushLayerToCache,
|
||||
}
|
||||
|
||||
for _, cmd := range s.stage.Commands {
|
||||
|
|
@ -166,9 +166,15 @@ func initializeConfig(img partial.WithConfigFile, opts *config.KanikoOptions) (*
|
|||
return imageConfig, nil
|
||||
}
|
||||
|
||||
func (s *stageBuilder) populateCompositeKey(command fmt.Stringer, files []string, compositeKey CompositeCache) (CompositeCache, error) {
|
||||
func (s *stageBuilder) populateCompositeKey(command fmt.Stringer, files []string, compositeKey CompositeCache, args *dockerfile.BuildArgs, env []string) (CompositeCache, error) {
|
||||
// First replace all the environment variables or args in the command
|
||||
replacementEnvs := args.ReplacementEnvs(env)
|
||||
resolvedCmd, err := util.ResolveEnvironmentReplacement(command.String(), replacementEnvs, false)
|
||||
if err != nil {
|
||||
return compositeKey, err
|
||||
}
|
||||
// Add the next command to the cache key.
|
||||
compositeKey.AddKey(command.String())
|
||||
compositeKey.AddKey(resolvedCmd)
|
||||
switch v := command.(type) {
|
||||
case *commands.CopyCommand:
|
||||
compositeKey = s.populateCopyCmdCompositeKey(command, v.From(), compositeKey)
|
||||
|
|
@ -221,7 +227,7 @@ func (s *stageBuilder) optimize(compositeKey CompositeCache, cfg v1.Config) erro
|
|||
return errors.Wrap(err, "failed to get files used from context")
|
||||
}
|
||||
|
||||
compositeKey, err = s.populateCompositeKey(command, files, compositeKey)
|
||||
compositeKey, err = s.populateCompositeKey(command, files, compositeKey, s.args, cfg.Env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -271,8 +277,6 @@ func (s *stageBuilder) build() error {
|
|||
compositeKey = NewCompositeCache(s.baseImageDigest)
|
||||
}
|
||||
|
||||
compositeKey.AddKey(s.opts.BuildArgs...)
|
||||
|
||||
// Apply optimizations to the instructions.
|
||||
if err := s.optimize(*compositeKey, s.cf.Config); err != nil {
|
||||
return errors.Wrap(err, "failed to optimize instructions")
|
||||
|
|
@ -329,7 +333,7 @@ func (s *stageBuilder) build() error {
|
|||
return errors.Wrap(err, "failed to get files used from context")
|
||||
}
|
||||
|
||||
*compositeKey, err = s.populateCompositeKey(command, files, *compositeKey)
|
||||
*compositeKey, err = s.populateCompositeKey(command, files, *compositeKey, s.args, s.cf.Config.Env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -378,7 +382,7 @@ func (s *stageBuilder) build() error {
|
|||
// Push layer to cache (in parallel) now along with new config file
|
||||
if s.opts.Cache && command.ShouldCacheOutput() {
|
||||
cacheGroup.Go(func() error {
|
||||
return s.pushCache(s.opts, ck, tarPath, command.String())
|
||||
return s.pushLayerToCache(s.opts, ck, tarPath, command.String())
|
||||
})
|
||||
}
|
||||
if err := s.saveSnapshotToImage(command.String(), tarPath); err != nil {
|
||||
|
|
|
|||
|
|
@ -497,7 +497,8 @@ func Test_stageBuilder_optimize(t *testing.T) {
|
|||
cf := &v1.ConfigFile{}
|
||||
snap := fakeSnapShotter{}
|
||||
lc := &fakeLayerCache{retrieve: tc.retrieve}
|
||||
sb := &stageBuilder{opts: tc.opts, cf: cf, snapshotter: snap, layerCache: lc}
|
||||
sb := &stageBuilder{opts: tc.opts, cf: cf, snapshotter: snap, layerCache: lc,
|
||||
args: dockerfile.NewBuildArgs([]string{})}
|
||||
ck := CompositeCache{}
|
||||
file, err := ioutil.TempFile("", "foo")
|
||||
if err != nil {
|
||||
|
|
@ -517,10 +518,135 @@ func Test_stageBuilder_optimize(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
type stageContext struct {
|
||||
command fmt.Stringer
|
||||
args *dockerfile.BuildArgs
|
||||
env []string
|
||||
}
|
||||
|
||||
func newStageContext(command string, args map[string]string, env []string) stageContext {
|
||||
dockerArgs := dockerfile.NewBuildArgs([]string{})
|
||||
for k, v := range args {
|
||||
dockerArgs.AddArg(k, &v)
|
||||
}
|
||||
return stageContext{MockDockerCommand{command: command}, dockerArgs, env}
|
||||
}
|
||||
|
||||
func Test_stageBuilder_populateCompositeKey(t *testing.T) {
|
||||
testCases := []struct {
|
||||
description string
|
||||
cmd1 stageContext
|
||||
cmd2 stageContext
|
||||
shdEqual bool
|
||||
}{
|
||||
{
|
||||
description: "cache key for same command, different buildargs, args not used in command",
|
||||
cmd1: newStageContext(
|
||||
"RUN echo const > test",
|
||||
map[string]string{"ARG": "foo"},
|
||||
[]string{"ENV=foo1"},
|
||||
),
|
||||
cmd2: newStageContext(
|
||||
"RUN echo const > test",
|
||||
map[string]string{"ARG": "bar"},
|
||||
[]string{"ENV=bar1"},
|
||||
),
|
||||
shdEqual: true,
|
||||
},
|
||||
{
|
||||
description: "cache key for same command with same build args",
|
||||
cmd1: newStageContext(
|
||||
"RUN echo $ARG > test",
|
||||
map[string]string{"ARG": "foo"},
|
||||
[]string{},
|
||||
),
|
||||
cmd2: newStageContext(
|
||||
"RUN echo $ARG > test",
|
||||
map[string]string{"ARG": "foo"},
|
||||
[]string{},
|
||||
),
|
||||
shdEqual: true,
|
||||
},
|
||||
{
|
||||
description: "cache key for same command with same env",
|
||||
cmd1: newStageContext(
|
||||
"RUN echo $ENV > test",
|
||||
map[string]string{"ARG": "foo"},
|
||||
[]string{"ENV=same"},
|
||||
),
|
||||
cmd2: newStageContext(
|
||||
"RUN echo $ENV > test",
|
||||
map[string]string{"ARG": "bar"},
|
||||
[]string{"ENV=same"},
|
||||
),
|
||||
shdEqual: true,
|
||||
},
|
||||
{
|
||||
description: "cache key for same command with a build arg values",
|
||||
cmd1: newStageContext(
|
||||
"RUN echo $ARG > test",
|
||||
map[string]string{"ARG": "foo"},
|
||||
[]string{},
|
||||
),
|
||||
cmd2: newStageContext(
|
||||
"RUN echo $ARG > test",
|
||||
map[string]string{"ARG": "bar"},
|
||||
[]string{},
|
||||
),
|
||||
},
|
||||
{
|
||||
description: "cache key for same command with different env values",
|
||||
cmd1: newStageContext(
|
||||
"RUN echo $ENV > test",
|
||||
map[string]string{"ARG": "foo"},
|
||||
[]string{"ENV=1"},
|
||||
),
|
||||
cmd2: newStageContext(
|
||||
"RUN echo $ENV > test",
|
||||
map[string]string{"ARG": "foo"},
|
||||
[]string{"ENV=2"},
|
||||
),
|
||||
},
|
||||
{
|
||||
description: "cache key for different command same context",
|
||||
cmd1: newStageContext(
|
||||
"RUN echo other > test",
|
||||
map[string]string{"ARG": "foo"},
|
||||
[]string{"ENV=1"},
|
||||
),
|
||||
cmd2: newStageContext(
|
||||
"RUN echo another > test",
|
||||
map[string]string{"ARG": "foo"},
|
||||
[]string{"ENV=1"},
|
||||
),
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
sb := &stageBuilder{opts: &config.KanikoOptions{SrcContext: "workspace"}}
|
||||
ck := CompositeCache{}
|
||||
|
||||
ck1, err := sb.populateCompositeKey(tc.cmd1.command, []string{}, ck, tc.cmd1.args, tc.cmd1.env)
|
||||
if err != nil {
|
||||
t.Errorf("Expected error to be nil but was %v", err)
|
||||
}
|
||||
ck2, err := sb.populateCompositeKey(tc.cmd2.command, []string{}, ck, tc.cmd2.args, tc.cmd2.env)
|
||||
if err != nil {
|
||||
t.Errorf("Expected error to be nil but was %v", err)
|
||||
}
|
||||
key1, key2 := hashCompositeKeys(t, ck1, ck2)
|
||||
if b := key1 == key2; b != tc.shdEqual {
|
||||
t.Errorf("expected keys to be equal as %t but found %t", tc.shdEqual, !tc.shdEqual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_stageBuilder_build(t *testing.T) {
|
||||
type testcase struct {
|
||||
description string
|
||||
opts *config.KanikoOptions
|
||||
args map[string]string
|
||||
layerCache *fakeLayerCache
|
||||
expectedCacheKeys []string
|
||||
pushedCacheKeys []string
|
||||
|
|
@ -544,6 +670,7 @@ func Test_stageBuilder_build(t *testing.T) {
|
|||
t.Errorf("couldn't create hash %v", err)
|
||||
}
|
||||
command := MockDockerCommand{
|
||||
command: "meow",
|
||||
contextFiles: []string{filePath},
|
||||
cacheCommand: MockCachedDockerCommand{
|
||||
contextFiles: []string{filePath},
|
||||
|
|
@ -576,6 +703,7 @@ func Test_stageBuilder_build(t *testing.T) {
|
|||
t.Errorf("couldn't create hash %v", err)
|
||||
}
|
||||
command := MockDockerCommand{
|
||||
command: "meow",
|
||||
contextFiles: []string{filePath},
|
||||
cacheCommand: MockCachedDockerCommand{
|
||||
contextFiles: []string{filePath},
|
||||
|
|
@ -838,6 +966,117 @@ COPY %s bar.txt
|
|||
commands: getCommands(dir, cmds),
|
||||
}
|
||||
}(),
|
||||
func() testcase {
|
||||
dir, _ := tempDirAndFile(t)
|
||||
ch := NewCompositeCache("")
|
||||
ch.AddKey("RUN foobar")
|
||||
hash, err := ch.Hash()
|
||||
if err != nil {
|
||||
t.Errorf("couldn't create hash %v", err)
|
||||
}
|
||||
|
||||
command := MockDockerCommand{
|
||||
command: "RUN foobar",
|
||||
contextFiles: []string{},
|
||||
cacheCommand: MockCachedDockerCommand{
|
||||
contextFiles: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
return testcase{
|
||||
description: "cached run command with no build arg value used uses cached layer and does not push anything",
|
||||
config: &v1.ConfigFile{Config: v1.Config{WorkingDir: dir}},
|
||||
opts: &config.KanikoOptions{Cache: true},
|
||||
args: map[string]string{
|
||||
"test": "value",
|
||||
},
|
||||
expectedCacheKeys: []string{hash},
|
||||
commands: []commands.DockerCommand{command},
|
||||
// layer key needs to be read.
|
||||
layerCache: &fakeLayerCache{
|
||||
img: &fakeImage{ImageLayers: []v1.Layer{fakeLayer{}}},
|
||||
keySequence: []string{hash},
|
||||
},
|
||||
rootDir: dir,
|
||||
}
|
||||
}(),
|
||||
func() testcase {
|
||||
dir, _ := tempDirAndFile(t)
|
||||
|
||||
ch := NewCompositeCache("")
|
||||
ch.AddKey("RUN value")
|
||||
hash, err := ch.Hash()
|
||||
if err != nil {
|
||||
t.Errorf("couldn't create hash %v", err)
|
||||
}
|
||||
|
||||
command := MockDockerCommand{
|
||||
command: "RUN $arg",
|
||||
contextFiles: []string{},
|
||||
cacheCommand: MockCachedDockerCommand{
|
||||
contextFiles: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
return testcase{
|
||||
description: "cached run command with same build arg does not push layer",
|
||||
config: &v1.ConfigFile{Config: v1.Config{WorkingDir: dir}},
|
||||
opts: &config.KanikoOptions{Cache: true},
|
||||
args: map[string]string{
|
||||
"arg": "value",
|
||||
},
|
||||
// layer key that exists
|
||||
layerCache: &fakeLayerCache{
|
||||
img: &fakeImage{ImageLayers: []v1.Layer{fakeLayer{}}},
|
||||
keySequence: []string{hash},
|
||||
},
|
||||
expectedCacheKeys: []string{hash},
|
||||
commands: []commands.DockerCommand{command},
|
||||
rootDir: dir,
|
||||
}
|
||||
}(),
|
||||
func() testcase {
|
||||
dir, _ := tempDirAndFile(t)
|
||||
|
||||
ch1 := NewCompositeCache("")
|
||||
ch1.AddKey("RUN value")
|
||||
hash1, err := ch1.Hash()
|
||||
if err != nil {
|
||||
t.Errorf("couldn't create hash %v", err)
|
||||
}
|
||||
|
||||
ch2 := NewCompositeCache("")
|
||||
ch2.AddKey("RUN anotherValue")
|
||||
hash2, err := ch2.Hash()
|
||||
if err != nil {
|
||||
t.Errorf("couldn't create hash %v", err)
|
||||
}
|
||||
command := MockDockerCommand{
|
||||
command: "RUN $arg",
|
||||
contextFiles: []string{},
|
||||
cacheCommand: MockCachedDockerCommand{
|
||||
contextFiles: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
return testcase{
|
||||
description: "cached run command with another build arg pushes layer",
|
||||
config: &v1.ConfigFile{Config: v1.Config{WorkingDir: dir}},
|
||||
opts: &config.KanikoOptions{Cache: true},
|
||||
args: map[string]string{
|
||||
"arg": "anotherValue",
|
||||
},
|
||||
// layer for arg=value already exists
|
||||
layerCache: &fakeLayerCache{
|
||||
img: &fakeImage{ImageLayers: []v1.Layer{fakeLayer{}}},
|
||||
keySequence: []string{hash1},
|
||||
},
|
||||
expectedCacheKeys: []string{hash2},
|
||||
pushedCacheKeys: []string{hash2},
|
||||
commands: []commands.DockerCommand{command},
|
||||
rootDir: dir,
|
||||
}
|
||||
}(),
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
|
|
@ -875,18 +1114,21 @@ COPY %s bar.txt
|
|||
}
|
||||
keys := []string{}
|
||||
sb := &stageBuilder{
|
||||
args: &dockerfile.BuildArgs{}, //required or code will panic
|
||||
args: dockerfile.NewBuildArgs([]string{}), //required or code will panic
|
||||
image: tc.image,
|
||||
opts: tc.opts,
|
||||
cf: cf,
|
||||
snapshotter: snap,
|
||||
layerCache: lc,
|
||||
pushCache: func(_ *config.KanikoOptions, cacheKey, _, _ string) error {
|
||||
pushLayerToCache: func(_ *config.KanikoOptions, cacheKey, _, _ string) error {
|
||||
keys = append(keys, cacheKey)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
sb.cmds = tc.commands
|
||||
for key, value := range tc.args {
|
||||
sb.args.AddArg(key, &value)
|
||||
}
|
||||
tmp := commands.RootDir
|
||||
if tc.rootDir != "" {
|
||||
commands.RootDir = tc.rootDir
|
||||
|
|
@ -993,3 +1235,15 @@ func generateTar(t *testing.T, dir string, fileNames ...string) []byte {
|
|||
}
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func hashCompositeKeys(t *testing.T, ck1 CompositeCache, ck2 CompositeCache) (string, string) {
|
||||
key1, err := ck1.Hash()
|
||||
if err != nil {
|
||||
t.Errorf("could not hash composite key due to %s", err)
|
||||
}
|
||||
key2, err := ck2.Hash()
|
||||
if err != nil {
|
||||
t.Errorf("could not hash composite key due to %s", err)
|
||||
}
|
||||
return key1, key2
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,13 +43,14 @@ func (f fakeSnapShotter) TakeSnapshot(_ []string) (string, error) {
|
|||
}
|
||||
|
||||
type MockDockerCommand struct {
|
||||
command string
|
||||
contextFiles []string
|
||||
cacheCommand commands.DockerCommand
|
||||
}
|
||||
|
||||
func (m MockDockerCommand) ExecuteCommand(c *v1.Config, args *dockerfile.BuildArgs) error { return nil }
|
||||
func (m MockDockerCommand) String() string {
|
||||
return "meow"
|
||||
return m.command
|
||||
}
|
||||
func (m MockDockerCommand) FilesToSnapshot() []string {
|
||||
return []string{"meow-snapshot-no-cache"}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2018 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -ex
|
||||
|
||||
GCS_BUCKET="${GCS_BUCKET:-gs://kaniko-test-bucket}"
|
||||
IMAGE_REPO="${IMAGE_REPO:-gcr.io/kaniko-test}"
|
||||
|
||||
docker version
|
||||
|
||||
# Sets up a kokoro (Google internal integration testing tool) environment
|
||||
if [ -f "$KOKORO_GFILE_DIR"/common.sh ]; then
|
||||
echo "Installing dependencies..."
|
||||
source "$KOKORO_GFILE_DIR/common.sh"
|
||||
mkdir -p /usr/local/go/src/github.com/GoogleContainerTools/
|
||||
cp -r github/kaniko /usr/local/go/src/github.com/GoogleContainerTools/
|
||||
pushd /usr/local/go/src/github.com/GoogleContainerTools/kaniko
|
||||
echo "Installing container-diff..."
|
||||
mv $KOKORO_GFILE_DIR/container-diff-linux-amd64 $KOKORO_GFILE_DIR/container-diff
|
||||
chmod +x $KOKORO_GFILE_DIR/container-diff
|
||||
export PATH=$PATH:$KOKORO_GFILE_DIR
|
||||
cp $KOKORO_ROOT/src/keystore/72508_gcr_application_creds $HOME/.config/gcloud/application_default_credentials.json
|
||||
fi
|
||||
|
||||
echo "Running integration tests..."
|
||||
make out/executor
|
||||
make out/warmer
|
||||
go test ./integration/... -v --bucket "${GCS_BUCKET}" --repo "${IMAGE_REPO}" --timeout 50m "$@"
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2020 Google LLC
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -ex
|
||||
|
||||
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
|
||||
chmod +x kubectl
|
||||
sudo mv kubectl /usr/local/bin/
|
||||
kubectl version --client
|
||||
|
||||
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
|
||||
chmod +x minikube
|
||||
sudo mv minikube /usr/local/bin/
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y liblz4-tool
|
||||
|
||||
sudo minikube start --vm-driver=none
|
||||
sudo minikube status
|
||||
sudo chown -R $USER $HOME/.kube $HOME/.minikube
|
||||
kubectl cluster-info
|
||||
|
|
@ -17,9 +17,9 @@
|
|||
# TestRun and TestLayers
|
||||
set -e
|
||||
|
||||
TESTS=$(./integration-test.sh -list=Test -mod=vendor)
|
||||
TESTS=$(./scripts/integration-test.sh -list=Test -mod=vendor)
|
||||
|
||||
TESTS=$(echo $TESTS | tr ' ' '\n' | grep 'Test'| grep -v 'TestRun' | grep -v 'TestLayers')
|
||||
TESTS=$(echo $TESTS | tr ' ' '\n' | grep 'Test'| grep -v 'TestRun' | grep -v 'TestLayers' | grep -v 'TestK8s')
|
||||
|
||||
RUN_ARG=''
|
||||
count=0
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
# cloud.google.com/go v0.26.0
|
||||
## explicit
|
||||
cloud.google.com/go/compute/metadata
|
||||
cloud.google.com/go/iam
|
||||
cloud.google.com/go/internal
|
||||
|
|
@ -7,11 +8,13 @@ cloud.google.com/go/internal/trace
|
|||
cloud.google.com/go/internal/version
|
||||
cloud.google.com/go/storage
|
||||
# github.com/Azure/azure-pipeline-go v0.2.2
|
||||
## explicit
|
||||
github.com/Azure/azure-pipeline-go/pipeline
|
||||
# github.com/Azure/azure-sdk-for-go v19.1.1+incompatible
|
||||
github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2017-10-01/containerregistry
|
||||
github.com/Azure/azure-sdk-for-go/version
|
||||
# github.com/Azure/azure-storage-blob-go v0.8.0
|
||||
## explicit
|
||||
github.com/Azure/azure-storage-blob-go/azblob
|
||||
# github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78
|
||||
github.com/Azure/go-ansiterm
|
||||
|
|
@ -28,7 +31,12 @@ github.com/Azure/go-autorest/version
|
|||
# github.com/Microsoft/go-winio v0.4.14
|
||||
github.com/Microsoft/go-winio
|
||||
github.com/Microsoft/go-winio/pkg/guid
|
||||
# github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7
|
||||
## explicit
|
||||
# github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239
|
||||
## explicit
|
||||
# github.com/aws/aws-sdk-go v1.25.19
|
||||
## explicit
|
||||
github.com/aws/aws-sdk-go/aws
|
||||
github.com/aws/aws-sdk-go/aws/awserr
|
||||
github.com/aws/aws-sdk-go/aws/awsutil
|
||||
|
|
@ -71,6 +79,7 @@ github.com/aws/aws-sdk-go/service/s3/s3manager
|
|||
github.com/aws/aws-sdk-go/service/sts
|
||||
github.com/aws/aws-sdk-go/service/sts/stsiface
|
||||
# github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973
|
||||
## explicit
|
||||
github.com/beorn7/perks/quantile
|
||||
# github.com/containerd/containerd v1.4.0-0.20191014053712-acdcf13d5eaf => github.com/containerd/containerd v0.0.0-20191014053712-acdcf13d5eaf
|
||||
github.com/containerd/containerd/cio
|
||||
|
|
@ -102,6 +111,7 @@ github.com/docker/distribution/digestset
|
|||
github.com/docker/distribution/reference
|
||||
github.com/docker/distribution/registry/api/errcode
|
||||
# github.com/docker/docker v1.14.0-0.20190319215453-e7b5f7dbe98c => github.com/docker/docker v0.0.0-20190319215453-e7b5f7dbe98c
|
||||
## explicit
|
||||
github.com/docker/docker/api
|
||||
github.com/docker/docker/api/types
|
||||
github.com/docker/docker/api/types/backend
|
||||
|
|
@ -194,10 +204,12 @@ github.com/docker/go-connections/tlsconfig
|
|||
# github.com/docker/go-events v0.0.0-20170721190031-9461782956ad
|
||||
github.com/docker/go-events
|
||||
# github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916
|
||||
## explicit
|
||||
github.com/docker/go-metrics
|
||||
# github.com/docker/go-units v0.4.0
|
||||
github.com/docker/go-units
|
||||
# github.com/docker/swarmkit v1.12.1-0.20180726190244-7567d47988d8
|
||||
## explicit
|
||||
github.com/docker/swarmkit/agent/exec
|
||||
github.com/docker/swarmkit/api
|
||||
github.com/docker/swarmkit/api/deepcopy
|
||||
|
|
@ -207,18 +219,24 @@ github.com/docker/swarmkit/manager/raftselector
|
|||
github.com/docker/swarmkit/protobuf/plugin
|
||||
github.com/docker/swarmkit/protobuf/ptypes
|
||||
# github.com/emirpasic/gods v1.9.0
|
||||
## explicit
|
||||
github.com/emirpasic/gods/containers
|
||||
github.com/emirpasic/gods/lists
|
||||
github.com/emirpasic/gods/lists/arraylist
|
||||
github.com/emirpasic/gods/trees
|
||||
github.com/emirpasic/gods/trees/binaryheap
|
||||
github.com/emirpasic/gods/utils
|
||||
# github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568
|
||||
## explicit
|
||||
# github.com/fsnotify/fsnotify v1.4.7
|
||||
github.com/fsnotify/fsnotify
|
||||
# github.com/genuinetools/amicontained v0.4.3
|
||||
## explicit
|
||||
github.com/genuinetools/amicontained/container
|
||||
# github.com/ghodss/yaml v1.0.0
|
||||
github.com/ghodss/yaml
|
||||
# github.com/gliderlabs/ssh v0.2.2
|
||||
## explicit
|
||||
# github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
|
||||
github.com/gogo/protobuf/gogoproto
|
||||
github.com/gogo/protobuf/proto
|
||||
|
|
@ -228,6 +246,7 @@ github.com/gogo/protobuf/types
|
|||
# github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
|
||||
github.com/golang/glog
|
||||
# github.com/golang/mock v1.3.1
|
||||
## explicit
|
||||
github.com/golang/mock/gomock
|
||||
# github.com/golang/protobuf v1.3.2
|
||||
github.com/golang/protobuf/proto
|
||||
|
|
@ -239,12 +258,14 @@ github.com/golang/protobuf/ptypes/timestamp
|
|||
# github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a
|
||||
github.com/google/btree
|
||||
# github.com/google/go-cmp v0.3.0
|
||||
## explicit
|
||||
github.com/google/go-cmp/cmp
|
||||
github.com/google/go-cmp/cmp/internal/diff
|
||||
github.com/google/go-cmp/cmp/internal/flags
|
||||
github.com/google/go-cmp/cmp/internal/function
|
||||
github.com/google/go-cmp/cmp/internal/value
|
||||
# github.com/google/go-containerregistry v0.0.0-20191218175032-34fb8ff33bed
|
||||
## explicit
|
||||
github.com/google/go-containerregistry/pkg/authn
|
||||
github.com/google/go-containerregistry/pkg/authn/k8schain
|
||||
github.com/google/go-containerregistry/pkg/internal/retry
|
||||
|
|
@ -266,12 +287,19 @@ github.com/google/go-containerregistry/pkg/v1/types
|
|||
github.com/google/go-containerregistry/pkg/v1/v1util
|
||||
github.com/google/go-containerregistry/pkg/v1/validate
|
||||
# github.com/google/go-github v17.0.0+incompatible
|
||||
## explicit
|
||||
github.com/google/go-github/github
|
||||
# github.com/google/go-querystring v1.0.0
|
||||
## explicit
|
||||
github.com/google/go-querystring/query
|
||||
# github.com/google/gofuzz v1.0.0
|
||||
github.com/google/gofuzz
|
||||
# github.com/google/martian v2.1.0+incompatible
|
||||
## explicit
|
||||
# github.com/google/uuid v1.0.0
|
||||
## explicit
|
||||
# github.com/googleapis/gax-go v2.0.0+incompatible
|
||||
## explicit
|
||||
github.com/googleapis/gax-go
|
||||
# github.com/googleapis/gnostic v0.2.2
|
||||
github.com/googleapis/gnostic/OpenAPIv2
|
||||
|
|
@ -285,34 +313,45 @@ github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc
|
|||
# github.com/hashicorp/go-immutable-radix v1.0.0
|
||||
github.com/hashicorp/go-immutable-radix
|
||||
# github.com/hashicorp/go-memdb v0.0.0-20180223233045-1289e7fffe71
|
||||
## explicit
|
||||
github.com/hashicorp/go-memdb
|
||||
# github.com/hashicorp/go-uuid v1.0.1
|
||||
## explicit
|
||||
# github.com/hashicorp/golang-lru v0.5.0
|
||||
github.com/hashicorp/golang-lru/simplelru
|
||||
# github.com/inconshreveable/mousetrap v1.0.0
|
||||
github.com/inconshreveable/mousetrap
|
||||
# github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
|
||||
## explicit
|
||||
github.com/jbenet/go-context/io
|
||||
# github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af
|
||||
github.com/jmespath/go-jmespath
|
||||
# github.com/json-iterator/go v1.1.8
|
||||
github.com/json-iterator/go
|
||||
# github.com/karrick/godirwalk v1.7.7
|
||||
## explicit
|
||||
github.com/karrick/godirwalk
|
||||
# github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e
|
||||
## explicit
|
||||
github.com/kevinburke/ssh_config
|
||||
# github.com/konsorten/go-windows-terminal-sequences v1.0.2
|
||||
github.com/konsorten/go-windows-terminal-sequences
|
||||
# github.com/mattn/go-ieproxy v0.0.0-20190805055040-f9202b1cfdeb
|
||||
## explicit
|
||||
github.com/mattn/go-ieproxy
|
||||
# github.com/mattn/go-shellwords v1.0.3
|
||||
## explicit
|
||||
github.com/mattn/go-shellwords
|
||||
# github.com/matttproud/golang_protobuf_extensions v1.0.1
|
||||
## explicit
|
||||
github.com/matttproud/golang_protobuf_extensions/pbutil
|
||||
# github.com/minio/highwayhash v1.0.0
|
||||
## explicit
|
||||
github.com/minio/highwayhash
|
||||
# github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mitchellh/go-homedir
|
||||
# github.com/moby/buildkit v0.0.0-20191111154543-00bfbab0390c
|
||||
## explicit
|
||||
github.com/moby/buildkit/frontend/dockerfile/command
|
||||
github.com/moby/buildkit/frontend/dockerfile/instructions
|
||||
github.com/moby/buildkit/frontend/dockerfile/parser
|
||||
|
|
@ -338,28 +377,37 @@ github.com/opencontainers/runc/libcontainer/devices
|
|||
github.com/opencontainers/runc/libcontainer/system
|
||||
github.com/opencontainers/runc/libcontainer/user
|
||||
# github.com/opencontainers/runtime-spec v1.0.1
|
||||
## explicit
|
||||
github.com/opencontainers/runtime-spec/specs-go
|
||||
# github.com/opencontainers/selinux v1.0.0-rc1
|
||||
## explicit
|
||||
github.com/opencontainers/selinux/go-selinux
|
||||
github.com/opencontainers/selinux/go-selinux/label
|
||||
# github.com/opentracing/opentracing-go v1.0.2
|
||||
## explicit
|
||||
github.com/opentracing/opentracing-go
|
||||
github.com/opentracing/opentracing-go/ext
|
||||
github.com/opentracing/opentracing-go/log
|
||||
# github.com/otiai10/copy v1.0.2
|
||||
## explicit
|
||||
github.com/otiai10/copy
|
||||
# github.com/pelletier/go-buffruneio v0.2.0
|
||||
## explicit
|
||||
github.com/pelletier/go-buffruneio
|
||||
# github.com/peterbourgon/diskv v2.0.1+incompatible
|
||||
github.com/peterbourgon/diskv
|
||||
# github.com/pkg/errors v0.9.1
|
||||
## explicit
|
||||
github.com/pkg/errors
|
||||
# github.com/prometheus/client_golang v0.9.0-pre1.0.20180210140205-a40133b69fbd
|
||||
## explicit
|
||||
github.com/prometheus/client_golang/prometheus
|
||||
github.com/prometheus/client_golang/prometheus/promhttp
|
||||
# github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910
|
||||
## explicit
|
||||
github.com/prometheus/client_model/go
|
||||
# github.com/prometheus/common v0.0.0-20180518154759-7600349dcfe1
|
||||
## explicit
|
||||
github.com/prometheus/common/expfmt
|
||||
github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg
|
||||
github.com/prometheus/common/model
|
||||
|
|
@ -367,17 +415,23 @@ github.com/prometheus/common/model
|
|||
github.com/prometheus/procfs
|
||||
github.com/prometheus/procfs/internal/fs
|
||||
# github.com/sergi/go-diff v1.0.0
|
||||
## explicit
|
||||
github.com/sergi/go-diff/diffmatchpatch
|
||||
# github.com/sirupsen/logrus v1.4.2
|
||||
## explicit
|
||||
github.com/sirupsen/logrus
|
||||
# github.com/spf13/afero v1.2.1
|
||||
## explicit
|
||||
github.com/spf13/afero
|
||||
github.com/spf13/afero/mem
|
||||
# github.com/spf13/cobra v0.0.5
|
||||
## explicit
|
||||
github.com/spf13/cobra
|
||||
# github.com/spf13/pflag v1.0.5
|
||||
## explicit
|
||||
github.com/spf13/pflag
|
||||
# github.com/src-d/gcfg v1.3.0
|
||||
## explicit
|
||||
github.com/src-d/gcfg
|
||||
github.com/src-d/gcfg/scanner
|
||||
github.com/src-d/gcfg/token
|
||||
|
|
@ -385,17 +439,21 @@ github.com/src-d/gcfg/types
|
|||
# github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
|
||||
github.com/syndtr/gocapability/capability
|
||||
# github.com/tonistiigi/fsutil v0.0.0-20191018213012-0f039a052ca1
|
||||
## explicit
|
||||
github.com/tonistiigi/fsutil
|
||||
github.com/tonistiigi/fsutil/types
|
||||
# github.com/vbatts/tar-split v0.10.2
|
||||
## explicit
|
||||
github.com/vbatts/tar-split/archive/tar
|
||||
github.com/vbatts/tar-split/tar/asm
|
||||
github.com/vbatts/tar-split/tar/storage
|
||||
# github.com/xanzy/ssh-agent v0.2.0
|
||||
## explicit
|
||||
github.com/xanzy/ssh-agent
|
||||
# go.etcd.io/bbolt v1.3.3
|
||||
go.etcd.io/bbolt
|
||||
# go.opencensus.io v0.14.0
|
||||
## explicit
|
||||
go.opencensus.io
|
||||
go.opencensus.io/exporter/stackdriver/propagation
|
||||
go.opencensus.io/internal
|
||||
|
|
@ -430,6 +488,7 @@ golang.org/x/crypto/ssh/agent
|
|||
golang.org/x/crypto/ssh/knownhosts
|
||||
golang.org/x/crypto/ssh/terminal
|
||||
# golang.org/x/net v0.0.0-20191004110552-13f9640d40b9
|
||||
## explicit
|
||||
golang.org/x/net/context
|
||||
golang.org/x/net/context/ctxhttp
|
||||
golang.org/x/net/http/httpguts
|
||||
|
|
@ -442,12 +501,14 @@ golang.org/x/net/internal/timeseries
|
|||
golang.org/x/net/proxy
|
||||
golang.org/x/net/trace
|
||||
# golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||
## explicit
|
||||
golang.org/x/oauth2
|
||||
golang.org/x/oauth2/google
|
||||
golang.org/x/oauth2/internal
|
||||
golang.org/x/oauth2/jws
|
||||
golang.org/x/oauth2/jwt
|
||||
# golang.org/x/sync v0.0.0-20190423024810-112230192c58
|
||||
## explicit
|
||||
golang.org/x/sync/errgroup
|
||||
golang.org/x/sync/singleflight
|
||||
golang.org/x/sync/syncmap
|
||||
|
|
@ -464,6 +525,7 @@ golang.org/x/text/unicode/norm
|
|||
# golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2
|
||||
golang.org/x/time/rate
|
||||
# google.golang.org/api v0.0.0-20180730000901-31ca0e01cd79
|
||||
## explicit
|
||||
google.golang.org/api/gensupport
|
||||
google.golang.org/api/googleapi
|
||||
google.golang.org/api/googleapi/internal/uritemplates
|
||||
|
|
@ -528,12 +590,16 @@ google.golang.org/grpc/tap
|
|||
# gopkg.in/inf.v0 v0.9.1
|
||||
gopkg.in/inf.v0
|
||||
# gopkg.in/src-d/go-billy.v4 v4.2.0
|
||||
## explicit
|
||||
gopkg.in/src-d/go-billy.v4
|
||||
gopkg.in/src-d/go-billy.v4/helper/chroot
|
||||
gopkg.in/src-d/go-billy.v4/helper/polyfill
|
||||
gopkg.in/src-d/go-billy.v4/osfs
|
||||
gopkg.in/src-d/go-billy.v4/util
|
||||
# gopkg.in/src-d/go-git-fixtures.v3 v3.5.0
|
||||
## explicit
|
||||
# gopkg.in/src-d/go-git.v4 v4.6.0
|
||||
## explicit
|
||||
gopkg.in/src-d/go-git.v4
|
||||
gopkg.in/src-d/go-git.v4/config
|
||||
gopkg.in/src-d/go-git.v4/internal/revision
|
||||
|
|
@ -575,6 +641,7 @@ gopkg.in/src-d/go-git.v4/utils/merkletrie/index
|
|||
gopkg.in/src-d/go-git.v4/utils/merkletrie/internal/frame
|
||||
gopkg.in/src-d/go-git.v4/utils/merkletrie/noder
|
||||
# gopkg.in/warnings.v0 v0.1.2
|
||||
## explicit
|
||||
gopkg.in/warnings.v0
|
||||
# gopkg.in/yaml.v2 v2.2.4
|
||||
gopkg.in/yaml.v2
|
||||
|
|
@ -699,3 +766,4 @@ k8s.io/kubernetes/pkg/credentialprovider/aws
|
|||
k8s.io/kubernetes/pkg/credentialprovider/azure
|
||||
k8s.io/kubernetes/pkg/credentialprovider/gcp
|
||||
k8s.io/kubernetes/pkg/credentialprovider/secrets
|
||||
# github.com/tonistiigi/fsutil v0.0.0-20190819224149-3d2716dd0a4d => github.com/tonistiigi/fsutil v0.0.0-20191018213012-0f039a052ca1
|
||||
|
|
|
|||
Loading…
Reference in New Issue