From e69338be34fc4eb422a9b0f294c47ee009ba4d3a Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Thu, 13 Sep 2018 10:09:08 -0700 Subject: [PATCH 1/3] Added v1alpha3 config I added a v1alpha3 version of the skaffold config, since adding different buildcontexts to the kaniko builder requires a breaking config change. Now, new buildcontexts can be easily added to the KanikoBuildContext type. I also added a transform function so that 'skaffold fix' can convert v1alpha2 configs to v1alpha3, and fixed unit tests to pass with the new config. This is part 1 of 3 PRs to incorporate more kaniko buildcontexts into the kaniko builder. --- cmd/skaffold/app/cmd/init.go | 20 +- examples/annotated-skaffold.yaml | 5 +- examples/bazel/skaffold.yaml | 2 +- examples/getting-started/skaffold.yaml | 2 +- examples/helm-deployment/skaffold.yaml | 2 +- examples/kaniko/pod.yaml | 45 ++++ examples/kaniko/skaffold.yaml | 5 +- examples/kustomize/skaffold.yaml | 2 +- examples/microservices/skaffold.yaml | 2 +- .../skaffold.yaml | 2 +- pkg/skaffold/bazel/bazel.go | 4 +- pkg/skaffold/bazel/bazel_test.go | 6 +- pkg/skaffold/build/build.go | 4 +- pkg/skaffold/build/gcb/cloud_build.go | 6 +- pkg/skaffold/build/gcb/desc.go | 4 +- pkg/skaffold/build/gcb/desc_test.go | 18 +- pkg/skaffold/build/gcb/project.go | 4 +- pkg/skaffold/build/gcb/project_test.go | 26 +- pkg/skaffold/build/gcb/types.go | 6 +- pkg/skaffold/build/kaniko/kaniko.go | 6 +- pkg/skaffold/build/kaniko/run.go | 10 +- pkg/skaffold/build/kaniko/types.go | 6 +- pkg/skaffold/build/local/bazel.go | 4 +- pkg/skaffold/build/local/docker.go | 4 +- pkg/skaffold/build/local/local.go | 8 +- pkg/skaffold/build/local/local_test.go | 34 +-- pkg/skaffold/build/local/types.go | 6 +- pkg/skaffold/build/parallel.go | 6 +- pkg/skaffold/build/sequence.go | 4 +- pkg/skaffold/config/config.go | 8 +- pkg/skaffold/config/config_test.go | 84 +++--- pkg/skaffold/config/profile_test.go | 30 +-- pkg/skaffold/config/transform/transforms.go | 67 +++++ pkg/skaffold/config/util.go | 5 + pkg/skaffold/deploy/helm.go | 12 +- pkg/skaffold/deploy/helm_test.go | 38 +-- pkg/skaffold/deploy/kubectl.go | 6 +- pkg/skaffold/deploy/kubectl/cli.go | 4 +- pkg/skaffold/deploy/kubectl_test.go | 26 +- pkg/skaffold/deploy/kustomize.go | 6 +- pkg/skaffold/docker/context.go | 8 +- pkg/skaffold/docker/context_test.go | 4 +- pkg/skaffold/docker/image.go | 6 +- pkg/skaffold/docker/image_test.go | 14 +- pkg/skaffold/docker/parse.go | 4 +- pkg/skaffold/docker/parse_test.go | 4 +- pkg/skaffold/kubernetes/colorpicker.go | 4 +- pkg/skaffold/kubernetes/colorpicker_test.go | 4 +- pkg/skaffold/runner/changes.go | 6 +- pkg/skaffold/runner/runner.go | 18 +- pkg/skaffold/runner/runner_test.go | 70 ++--- pkg/skaffold/runner/timings.go | 4 +- pkg/skaffold/schema/transform.go | 2 + pkg/skaffold/schema/v1alpha3/config.go | 251 ++++++++++++++++++ pkg/skaffold/schema/v1alpha3/defaults.go | 195 ++++++++++++++ pkg/skaffold/schema/v1alpha3/profiles.go | 125 +++++++++ skaffold.yaml | 2 +- 57 files changed, 978 insertions(+), 282 deletions(-) create mode 100644 examples/kaniko/pod.yaml create mode 100644 pkg/skaffold/schema/v1alpha3/config.go create mode 100644 pkg/skaffold/schema/v1alpha3/defaults.go create mode 100644 pkg/skaffold/schema/v1alpha3/profiles.go diff --git a/cmd/skaffold/app/cmd/init.go b/cmd/skaffold/app/cmd/init.go index 0b273d3f738..f933aee9bb8 100644 --- a/cmd/skaffold/app/cmd/init.go +++ b/cmd/skaffold/app/cmd/init.go @@ -35,7 +35,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/config" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "k8s.io/apimachinery/pkg/runtime" @@ -206,23 +206,23 @@ func promptUserForDockerfile(image string, dockerfiles []string) dockerfilePair } } -func processBuildArtifacts(pairs []dockerfilePair) v1alpha2.BuildConfig { - var config v1alpha2.BuildConfig +func processBuildArtifacts(pairs []dockerfilePair) v1alpha3.BuildConfig { + var config v1alpha3.BuildConfig if len(pairs) > 0 { - var artifacts []*v1alpha2.Artifact + var artifacts []*v1alpha3.Artifact for _, pair := range pairs { workspace := filepath.Dir(pair.Dockerfile) dockerfilePath := filepath.Base(pair.Dockerfile) - a := &v1alpha2.Artifact{ + a := &v1alpha3.Artifact{ ImageName: pair.ImageName, } if workspace != "." { a.Workspace = workspace } if dockerfilePath != constants.DefaultDockerfilePath { - a.ArtifactType = v1alpha2.ArtifactType{ - DockerArtifact: &v1alpha2.DockerArtifact{ + a.ArtifactType = v1alpha3.ArtifactType{ + DockerArtifact: &v1alpha3.DockerArtifact{ DockerfilePath: dockerfilePath, }, } @@ -246,9 +246,9 @@ func generateSkaffoldConfig(k8sConfigs []string, dockerfilePairs []dockerfilePai } config.Build = processBuildArtifacts(dockerfilePairs) - config.Deploy = v1alpha2.DeployConfig{ - DeployType: v1alpha2.DeployType{ - KubectlDeploy: &v1alpha2.KubectlDeploy{ + config.Deploy = v1alpha3.DeployConfig{ + DeployType: v1alpha3.DeployType{ + KubectlDeploy: &v1alpha3.KubectlDeploy{ Manifests: k8sConfigs, }, }, diff --git a/examples/annotated-skaffold.yaml b/examples/annotated-skaffold.yaml index 3f2a69a0686..4a17d2b0a04 100644 --- a/examples/annotated-skaffold.yaml +++ b/examples/annotated-skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: # tagPolicy determines how skaffold is going to tag your images. @@ -101,7 +101,8 @@ build: # See https://github.com/GoogleContainerTools/kaniko#running-kaniko-in-a-kubernetes-cluster # # kaniko: - # gcsBucket: k8s-skaffold + # buildContext: + # gcsBucket: k8s-skaffold # pullSecret: /a/secret/path/serviceaccount.json # namespace: default # timeout: 20m diff --git a/examples/bazel/skaffold.yaml b/examples/bazel/skaffold.yaml index a29ce7b74db..6424b8091a3 100644 --- a/examples/bazel/skaffold.yaml +++ b/examples/bazel/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: artifacts: diff --git a/examples/getting-started/skaffold.yaml b/examples/getting-started/skaffold.yaml index 2c5d8ef12b6..fb4d4adbc4c 100644 --- a/examples/getting-started/skaffold.yaml +++ b/examples/getting-started/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: artifacts: diff --git a/examples/helm-deployment/skaffold.yaml b/examples/helm-deployment/skaffold.yaml index 6511d582764..ecd82eb8efe 100644 --- a/examples/helm-deployment/skaffold.yaml +++ b/examples/helm-deployment/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: tagPolicy: diff --git a/examples/kaniko/pod.yaml b/examples/kaniko/pod.yaml new file mode 100644 index 00000000000..0627014e862 --- /dev/null +++ b/examples/kaniko/pod.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: Pod +metadata: + name: kaniko +spec: + initContainers: + - name: init-container + image: ubuntu + args: ["sh", "-c", "cp -L -r /kaniko/buildcontext/* /kaniko/emptydir && ls /kaniko/emptydir && stat /kaniko/emptydir/Dockerfile"] + volumeMounts: + - name: build-context + mountPath: /kaniko/buildcontext + - name: empty-dir + mountPath: /kaniko/emptydir + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=Dockerfile", + "--context=dir:///kaniko/emptydir", + "--destination=gcr.io/priya-wadhwa/test:test"] + volumeMounts: + - name: kaniko-secret + mountPath: /secret + - name: build-context + mountPath: /kaniko/buildcontext + - name: empty-dir + mountPath: /kaniko/emptydir + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /secret/kaniko-secret.json + restartPolicy: Never + volumes: + - name: kaniko-secret + secret: + secretName: kaniko + # - name: build-context + # persistentVolumeClaim: + # claimName: pv-claim-kaniko + - name: build-context + configMap: + # Provide the name of the ConfigMap containing the files you want + # to add to the container + name: kaniko-configmap77a0c64f84c48aeb56093119c709807b + - name: empty-dir + emptyDir: {} diff --git a/examples/kaniko/skaffold.yaml b/examples/kaniko/skaffold.yaml index 1b81d4a523d..09271f92719 100644 --- a/examples/kaniko/skaffold.yaml +++ b/examples/kaniko/skaffold.yaml @@ -1,10 +1,11 @@ -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: artifacts: - imageName: gcr.io/k8s-skaffold/skaffold-example kaniko: - gcsBucket: skaffold-kaniko + buildContext: + gcsBucket: skaffold-kaniko pullSecretName: e2esecret namespace: default deploy: diff --git a/examples/kustomize/skaffold.yaml b/examples/kustomize/skaffold.yaml index 65edfabae9a..0ad12da902c 100644 --- a/examples/kustomize/skaffold.yaml +++ b/examples/kustomize/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config deploy: kustomize: {} diff --git a/examples/microservices/skaffold.yaml b/examples/microservices/skaffold.yaml index 1cc1615e56c..09625d7e8a1 100644 --- a/examples/microservices/skaffold.yaml +++ b/examples/microservices/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: artifacts: diff --git a/examples/tagging-with-environment-variables/skaffold.yaml b/examples/tagging-with-environment-variables/skaffold.yaml index 93dc15c23e5..4cb86eb796b 100644 --- a/examples/tagging-with-environment-variables/skaffold.yaml +++ b/examples/tagging-with-environment-variables/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: artifacts: diff --git a/pkg/skaffold/bazel/bazel.go b/pkg/skaffold/bazel/bazel.go index 366cca74927..28829104d38 100644 --- a/pkg/skaffold/bazel/bazel.go +++ b/pkg/skaffold/bazel/bazel.go @@ -23,7 +23,7 @@ import ( "path/filepath" "strings" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/pkg/errors" ) @@ -36,7 +36,7 @@ func query(target string) string { // GetDependencies finds the sources dependencies for the given bazel artifact. // All paths are relative to the workspace. -func GetDependencies(workspace string, a *v1alpha2.BazelArtifact) ([]string, error) { +func GetDependencies(workspace string, a *v1alpha3.BazelArtifact) ([]string, error) { cmd := exec.Command("bazel", "query", query(a.BuildTarget), "--noimplicit_deps", "--order_output=no") cmd.Dir = workspace stdout, err := util.RunCmdOut(cmd) diff --git a/pkg/skaffold/bazel/bazel_test.go b/pkg/skaffold/bazel/bazel_test.go index 73e63b2fa3b..b76abcd0e5c 100644 --- a/pkg/skaffold/bazel/bazel_test.go +++ b/pkg/skaffold/bazel/bazel_test.go @@ -19,7 +19,7 @@ package bazel import ( "testing" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/testutil" ) @@ -36,7 +36,7 @@ func TestGetDependenciesWithWorkspace(t *testing.T) { defer cleanup() tmpDir.Write("WORKSPACE", "") - deps, err := GetDependencies(tmpDir.Root(), &v1alpha2.BazelArtifact{ + deps, err := GetDependencies(tmpDir.Root(), &v1alpha3.BazelArtifact{ BuildTarget: "target", }) @@ -51,7 +51,7 @@ func TestGetDependenciesWithoutWorkspace(t *testing.T) { nil, ) - deps, err := GetDependencies(".", &v1alpha2.BazelArtifact{ + deps, err := GetDependencies(".", &v1alpha3.BazelArtifact{ BuildTarget: "target2", }) diff --git a/pkg/skaffold/build/build.go b/pkg/skaffold/build/build.go index fee764e4b69..94ff2223274 100644 --- a/pkg/skaffold/build/build.go +++ b/pkg/skaffold/build/build.go @@ -21,7 +21,7 @@ import ( "io" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/tag" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" ) // Artifact is the result corresponding to each successful build. @@ -37,5 +37,5 @@ type Artifact struct { type Builder interface { Labels() map[string]string - Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha2.Artifact) ([]Artifact, error) + Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha3.Artifact) ([]Artifact, error) } diff --git a/pkg/skaffold/build/gcb/cloud_build.go b/pkg/skaffold/build/gcb/cloud_build.go index 7adcd2ad15c..646564500c5 100644 --- a/pkg/skaffold/build/gcb/cloud_build.go +++ b/pkg/skaffold/build/gcb/cloud_build.go @@ -29,7 +29,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/color" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/version" "github.com/pkg/errors" @@ -41,11 +41,11 @@ import ( ) // Build builds a list of artifacts with Google Cloud Build. -func (b *Builder) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha2.Artifact) ([]build.Artifact, error) { +func (b *Builder) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha3.Artifact) ([]build.Artifact, error) { return build.InParallel(ctx, out, tagger, artifacts, b.buildArtifact) } -func (b *Builder) buildArtifact(ctx context.Context, out io.Writer, tagger tag.Tagger, artifact *v1alpha2.Artifact) (string, error) { +func (b *Builder) buildArtifact(ctx context.Context, out io.Writer, tagger tag.Tagger, artifact *v1alpha3.Artifact) (string, error) { client, err := google.DefaultClient(ctx, cloudbuild.CloudPlatformScope) if err != nil { return "", errors.Wrap(err, "getting google client") diff --git a/pkg/skaffold/build/gcb/desc.go b/pkg/skaffold/build/gcb/desc.go index 9ced4e2a5bd..8f2cf585945 100644 --- a/pkg/skaffold/build/gcb/desc.go +++ b/pkg/skaffold/build/gcb/desc.go @@ -18,11 +18,11 @@ package gcb import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" cloudbuild "google.golang.org/api/cloudbuild/v1" ) -func (b *Builder) buildDescription(artifact *v1alpha2.Artifact, bucket, object string) *cloudbuild.Build { +func (b *Builder) buildDescription(artifact *v1alpha3.Artifact, bucket, object string) *cloudbuild.Build { var steps []*cloudbuild.BuildStep for _, cacheFrom := range artifact.DockerArtifact.CacheFrom { diff --git a/pkg/skaffold/build/gcb/desc_test.go b/pkg/skaffold/build/gcb/desc_test.go index ab51863302a..433373b5f8a 100644 --- a/pkg/skaffold/build/gcb/desc_test.go +++ b/pkg/skaffold/build/gcb/desc_test.go @@ -19,17 +19,17 @@ package gcb import ( "testing" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/testutil" cloudbuild "google.golang.org/api/cloudbuild/v1" ) func TestBuildDescription(t *testing.T) { - artifact := &v1alpha2.Artifact{ + artifact := &v1alpha3.Artifact{ ImageName: "nginx", - ArtifactType: v1alpha2.ArtifactType{ - DockerArtifact: &v1alpha2.DockerArtifact{ + ArtifactType: v1alpha3.ArtifactType{ + DockerArtifact: &v1alpha3.DockerArtifact{ DockerfilePath: "Dockerfile", BuildArgs: map[string]*string{ "arg1": util.StringPtr("value1"), @@ -40,7 +40,7 @@ func TestBuildDescription(t *testing.T) { } builder := Builder{ - GoogleCloudBuild: &v1alpha2.GoogleCloudBuild{ + GoogleCloudBuild: &v1alpha3.GoogleCloudBuild{ DockerImage: "docker/docker", DiskSizeGb: 100, MachineType: "n1-standard-1", @@ -73,10 +73,10 @@ func TestBuildDescription(t *testing.T) { } func TestPullCacheFrom(t *testing.T) { - artifact := &v1alpha2.Artifact{ + artifact := &v1alpha3.Artifact{ ImageName: "nginx", - ArtifactType: v1alpha2.ArtifactType{ - DockerArtifact: &v1alpha2.DockerArtifact{ + ArtifactType: v1alpha3.ArtifactType{ + DockerArtifact: &v1alpha3.DockerArtifact{ DockerfilePath: "Dockerfile", CacheFrom: []string{"from/image1", "from/image2"}, }, @@ -84,7 +84,7 @@ func TestPullCacheFrom(t *testing.T) { } builder := Builder{ - GoogleCloudBuild: &v1alpha2.GoogleCloudBuild{ + GoogleCloudBuild: &v1alpha3.GoogleCloudBuild{ DockerImage: "docker/docker", }, } diff --git a/pkg/skaffold/build/gcb/project.go b/pkg/skaffold/build/gcb/project.go index e3ff9161aef..462535b8590 100644 --- a/pkg/skaffold/build/gcb/project.go +++ b/pkg/skaffold/build/gcb/project.go @@ -20,13 +20,13 @@ import ( "fmt" "strings" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/docker/distribution/reference" "github.com/docker/docker/registry" "github.com/pkg/errors" ) -func (b *Builder) guessProjectID(artifact *v1alpha2.Artifact) (string, error) { +func (b *Builder) guessProjectID(artifact *v1alpha3.Artifact) (string, error) { if b.ProjectID != "" { return b.ProjectID, nil } diff --git a/pkg/skaffold/build/gcb/project_test.go b/pkg/skaffold/build/gcb/project_test.go index 760b1828be8..1b031a7891d 100644 --- a/pkg/skaffold/build/gcb/project_test.go +++ b/pkg/skaffold/build/gcb/project_test.go @@ -19,46 +19,46 @@ package gcb import ( "testing" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/testutil" ) func TestGuessProjectID(t *testing.T) { var tests = []struct { description string - config *v1alpha2.GoogleCloudBuild - artifact *v1alpha2.Artifact + config *v1alpha3.GoogleCloudBuild + artifact *v1alpha3.Artifact expected string shouldErr bool }{ { description: "fixed projectId", - config: &v1alpha2.GoogleCloudBuild{ProjectID: "fixed"}, - artifact: &v1alpha2.Artifact{ImageName: "any"}, + config: &v1alpha3.GoogleCloudBuild{ProjectID: "fixed"}, + artifact: &v1alpha3.Artifact{ImageName: "any"}, expected: "fixed", }, { description: "gcr.io", - config: &v1alpha2.GoogleCloudBuild{}, - artifact: &v1alpha2.Artifact{ImageName: "gcr.io/project/image"}, + config: &v1alpha3.GoogleCloudBuild{}, + artifact: &v1alpha3.Artifact{ImageName: "gcr.io/project/image"}, expected: "project", }, { description: "eu.gcr.io", - config: &v1alpha2.GoogleCloudBuild{}, - artifact: &v1alpha2.Artifact{ImageName: "gcr.io/project/image"}, + config: &v1alpha3.GoogleCloudBuild{}, + artifact: &v1alpha3.Artifact{ImageName: "gcr.io/project/image"}, expected: "project", }, { description: "docker hub", - config: &v1alpha2.GoogleCloudBuild{}, - artifact: &v1alpha2.Artifact{ImageName: "project/image"}, + config: &v1alpha3.GoogleCloudBuild{}, + artifact: &v1alpha3.Artifact{ImageName: "project/image"}, shouldErr: true, }, { description: "invalid GCR image", - config: &v1alpha2.GoogleCloudBuild{}, - artifact: &v1alpha2.Artifact{ImageName: "gcr.io"}, + config: &v1alpha3.GoogleCloudBuild{}, + artifact: &v1alpha3.Artifact{ImageName: "gcr.io"}, shouldErr: true, }, } diff --git a/pkg/skaffold/build/gcb/types.go b/pkg/skaffold/build/gcb/types.go index b8c0ff3ad9d..8bd24ddaea0 100644 --- a/pkg/skaffold/build/gcb/types.go +++ b/pkg/skaffold/build/gcb/types.go @@ -20,7 +20,7 @@ import ( "time" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" ) const ( @@ -54,11 +54,11 @@ const ( // Builder builds artifacts with Google Cloud Build. type Builder struct { - *v1alpha2.GoogleCloudBuild + *v1alpha3.GoogleCloudBuild } // NewBuilder creates a new Builder that builds artifacts with Google Cloud Build. -func NewBuilder(cfg *v1alpha2.GoogleCloudBuild) *Builder { +func NewBuilder(cfg *v1alpha3.GoogleCloudBuild) *Builder { return &Builder{ GoogleCloudBuild: cfg, } diff --git a/pkg/skaffold/build/kaniko/kaniko.go b/pkg/skaffold/build/kaniko/kaniko.go index ec3e5f4c504..4eaefe89f5f 100644 --- a/pkg/skaffold/build/kaniko/kaniko.go +++ b/pkg/skaffold/build/kaniko/kaniko.go @@ -23,12 +23,12 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/tag" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/pkg/errors" ) // Build builds a list of artifacts with Kaniko. -func (b *Builder) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha2.Artifact) ([]build.Artifact, error) { +func (b *Builder) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha3.Artifact) ([]build.Artifact, error) { teardown, err := b.setupSecret() if err != nil { return nil, errors.Wrap(err, "setting up secret") @@ -38,7 +38,7 @@ func (b *Builder) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, a return build.InParallel(ctx, out, tagger, artifacts, b.buildArtifact) } -func (b *Builder) buildArtifact(ctx context.Context, out io.Writer, tagger tag.Tagger, artifact *v1alpha2.Artifact) (string, error) { +func (b *Builder) buildArtifact(ctx context.Context, out io.Writer, tagger tag.Tagger, artifact *v1alpha3.Artifact) (string, error) { initialTag, err := runKaniko(ctx, out, artifact, b.KanikoBuild) if err != nil { return "", errors.Wrapf(err, "kaniko build for [%s]", artifact.ImageName) diff --git a/pkg/skaffold/build/kaniko/run.go b/pkg/skaffold/build/kaniko/run.go index 20a96e6c733..b339309c3c4 100644 --- a/pkg/skaffold/build/kaniko/run.go +++ b/pkg/skaffold/build/kaniko/run.go @@ -28,7 +28,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -39,15 +39,15 @@ import ( const kanikoContainerName = "kaniko" -func runKaniko(ctx context.Context, out io.Writer, artifact *v1alpha2.Artifact, cfg *v1alpha2.KanikoBuild) (string, error) { +func runKaniko(ctx context.Context, out io.Writer, artifact *v1alpha3.Artifact, cfg *v1alpha3.KanikoBuild) (string, error) { dockerfilePath := artifact.DockerArtifact.DockerfilePath initialTag := util.RandomID() tarName := fmt.Sprintf("context-%s.tar.gz", initialTag) - if err := docker.UploadContextToGCS(ctx, artifact.Workspace, artifact.DockerArtifact, cfg.GCSBucket, tarName); err != nil { + if err := docker.UploadContextToGCS(ctx, artifact.Workspace, artifact.DockerArtifact, cfg.BuildContext.GCSBucket, tarName); err != nil { return "", errors.Wrap(err, "uploading tar to gcs") } - defer gcsDelete(ctx, cfg.GCSBucket, tarName) + defer gcsDelete(ctx, cfg.BuildContext.GCSBucket, tarName) client, err := kubernetes.GetClientset() if err != nil { @@ -58,7 +58,7 @@ func runKaniko(ctx context.Context, out io.Writer, artifact *v1alpha2.Artifact, imageDst := fmt.Sprintf("%s:%s", artifact.ImageName, initialTag) args := []string{ fmt.Sprintf("--dockerfile=%s", dockerfilePath), - fmt.Sprintf("--context=gs://%s/%s", cfg.GCSBucket, tarName), + fmt.Sprintf("--context=gs://%s/%s", cfg.BuildContext.GCSBucket, tarName), fmt.Sprintf("--destination=%s", imageDst), fmt.Sprintf("-v=%s", logrus.GetLevel().String()), } diff --git a/pkg/skaffold/build/kaniko/types.go b/pkg/skaffold/build/kaniko/types.go index f599715a76e..1834ed25354 100644 --- a/pkg/skaffold/build/kaniko/types.go +++ b/pkg/skaffold/build/kaniko/types.go @@ -18,16 +18,16 @@ package kaniko import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" ) // Builder builds docker artifacts on Kubernetes, using Kaniko. type Builder struct { - *v1alpha2.KanikoBuild + *v1alpha3.KanikoBuild } // NewBuilder creates a new Builder that builds artifacts with Kaniko. -func NewBuilder(cfg *v1alpha2.KanikoBuild) *Builder { +func NewBuilder(cfg *v1alpha3.KanikoBuild) *Builder { return &Builder{ KanikoBuild: cfg, } diff --git a/pkg/skaffold/build/local/bazel.go b/pkg/skaffold/build/local/bazel.go index 374d122ae02..9db6b92649e 100644 --- a/pkg/skaffold/build/local/bazel.go +++ b/pkg/skaffold/build/local/bazel.go @@ -26,11 +26,11 @@ import ( "strings" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/pkg/errors" ) -func (b *Builder) buildBazel(ctx context.Context, out io.Writer, workspace string, a *v1alpha2.BazelArtifact) (string, error) { +func (b *Builder) buildBazel(ctx context.Context, out io.Writer, workspace string, a *v1alpha3.BazelArtifact) (string, error) { cmd := exec.CommandContext(ctx, "bazel", "build", a.BuildTarget) cmd.Dir = workspace cmd.Stdout = out diff --git a/pkg/skaffold/build/local/docker.go b/pkg/skaffold/build/local/docker.go index 564dea1063d..34dbc777e88 100644 --- a/pkg/skaffold/build/local/docker.go +++ b/pkg/skaffold/build/local/docker.go @@ -24,12 +24,12 @@ import ( "os/exec" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/pkg/errors" ) -func (b *Builder) buildDocker(ctx context.Context, out io.Writer, workspace string, a *v1alpha2.DockerArtifact) (string, error) { +func (b *Builder) buildDocker(ctx context.Context, out io.Writer, workspace string, a *v1alpha3.DockerArtifact) (string, error) { initialTag := util.RandomID() if b.cfg.UseDockerCLI || b.cfg.UseBuildkit { diff --git a/pkg/skaffold/build/local/local.go b/pkg/skaffold/build/local/local.go index 9b3b9b8e29f..e9b9c2aa67a 100644 --- a/pkg/skaffold/build/local/local.go +++ b/pkg/skaffold/build/local/local.go @@ -25,13 +25,13 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/tag" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/color" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/pkg/errors" ) // Build runs a docker build on the host and tags the resulting image with // its checksum. It streams build progress to the writer argument. -func (b *Builder) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha2.Artifact) ([]build.Artifact, error) { +func (b *Builder) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha3.Artifact) ([]build.Artifact, error) { if b.localCluster { if _, err := color.Default.Fprintf(out, "Found [%s] context, using local docker daemon.\n", b.kubeContext); err != nil { return nil, errors.Wrap(err, "writing status") @@ -43,7 +43,7 @@ func (b *Builder) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, a return build.InSequence(ctx, out, tagger, artifacts, b.buildArtifact) } -func (b *Builder) buildArtifact(ctx context.Context, out io.Writer, tagger tag.Tagger, artifact *v1alpha2.Artifact) (string, error) { +func (b *Builder) buildArtifact(ctx context.Context, out io.Writer, tagger tag.Tagger, artifact *v1alpha3.Artifact) (string, error) { initialTag, err := b.runBuildForArtifact(ctx, out, artifact) if err != nil { return "", errors.Wrap(err, "build artifact") @@ -87,7 +87,7 @@ func (b *Builder) buildArtifact(ctx context.Context, out io.Writer, tagger tag.T return tag, nil } -func (b *Builder) runBuildForArtifact(ctx context.Context, out io.Writer, artifact *v1alpha2.Artifact) (string, error) { +func (b *Builder) runBuildForArtifact(ctx context.Context, out io.Writer, artifact *v1alpha3.Artifact) (string, error) { switch { case artifact.DockerArtifact != nil: return b.buildDocker(ctx, out, artifact.Workspace, artifact.DockerArtifact) diff --git a/pkg/skaffold/build/local/local_test.go b/pkg/skaffold/build/local/local_test.go index e7c9342044b..9e5eb7f9537 100644 --- a/pkg/skaffold/build/local/local_test.go +++ b/pkg/skaffold/build/local/local_test.go @@ -26,7 +26,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/tag" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/testutil" "github.com/docker/docker/api/types" @@ -67,11 +67,11 @@ func TestLocalRun(t *testing.T) { var tests = []struct { description string - config *v1alpha2.LocalBuild + config *v1alpha3.LocalBuild out io.Writer api docker.APIClient tagger tag.Tagger - artifacts []*v1alpha2.Artifact + artifacts []*v1alpha3.Artifact expected []build.Artifact localCluster bool shouldErr bool @@ -79,15 +79,15 @@ func TestLocalRun(t *testing.T) { { description: "single build", out: ioutil.Discard, - config: &v1alpha2.LocalBuild{ + config: &v1alpha3.LocalBuild{ SkipPush: util.BoolPtr(false), }, - artifacts: []*v1alpha2.Artifact{ + artifacts: []*v1alpha3.Artifact{ { ImageName: "gcr.io/test/image", Workspace: tmpDir.Root(), - ArtifactType: v1alpha2.ArtifactType{ - DockerArtifact: &v1alpha2.DockerArtifact{}, + ArtifactType: v1alpha3.ArtifactType{ + DockerArtifact: &v1alpha3.DockerArtifact{}, }, }, }, @@ -103,16 +103,16 @@ func TestLocalRun(t *testing.T) { { description: "subset build", out: ioutil.Discard, - config: &v1alpha2.LocalBuild{ + config: &v1alpha3.LocalBuild{ SkipPush: util.BoolPtr(true), }, tagger: &tag.ChecksumTagger{}, - artifacts: []*v1alpha2.Artifact{ + artifacts: []*v1alpha3.Artifact{ { ImageName: "gcr.io/test/image", Workspace: tmpDir.Root(), - ArtifactType: v1alpha2.ArtifactType{ - DockerArtifact: &v1alpha2.DockerArtifact{}, + ArtifactType: v1alpha3.ArtifactType{ + DockerArtifact: &v1alpha3.DockerArtifact{}, }, }, }, @@ -127,14 +127,14 @@ func TestLocalRun(t *testing.T) { { description: "local cluster bad writer", out: &testutil.BadWriter{}, - config: &v1alpha2.LocalBuild{}, + config: &v1alpha3.LocalBuild{}, shouldErr: true, localCluster: true, }, { description: "error image build", out: ioutil.Discard, - artifacts: []*v1alpha2.Artifact{{}}, + artifacts: []*v1alpha3.Artifact{{}}, tagger: &tag.ChecksumTagger{}, api: testutil.NewFakeImageAPIClient(map[string]string{}, &testutil.FakeImageAPIOptions{ ErrImageBuild: true, @@ -144,7 +144,7 @@ func TestLocalRun(t *testing.T) { { description: "error image tag", out: ioutil.Discard, - artifacts: []*v1alpha2.Artifact{{}}, + artifacts: []*v1alpha3.Artifact{{}}, tagger: &tag.ChecksumTagger{}, api: testutil.NewFakeImageAPIClient(map[string]string{}, &testutil.FakeImageAPIOptions{ ErrImageTag: true, @@ -154,7 +154,7 @@ func TestLocalRun(t *testing.T) { { description: "bad writer", out: &testutil.BadWriter{}, - artifacts: []*v1alpha2.Artifact{{}}, + artifacts: []*v1alpha3.Artifact{{}}, tagger: &tag.ChecksumTagger{}, api: testutil.NewFakeImageAPIClient(map[string]string{}, &testutil.FakeImageAPIOptions{}), shouldErr: true, @@ -162,7 +162,7 @@ func TestLocalRun(t *testing.T) { { description: "error image inspect", out: &testutil.BadWriter{}, - artifacts: []*v1alpha2.Artifact{{}}, + artifacts: []*v1alpha3.Artifact{{}}, tagger: &tag.ChecksumTagger{}, api: testutil.NewFakeImageAPIClient(map[string]string{}, &testutil.FakeImageAPIOptions{ ErrImageInspect: true, @@ -172,7 +172,7 @@ func TestLocalRun(t *testing.T) { { description: "error tagger", out: ioutil.Discard, - artifacts: []*v1alpha2.Artifact{{}}, + artifacts: []*v1alpha3.Artifact{{}}, tagger: &FakeTagger{Err: fmt.Errorf("")}, api: testutil.NewFakeImageAPIClient(map[string]string{}, &testutil.FakeImageAPIOptions{}), shouldErr: true, diff --git a/pkg/skaffold/build/local/types.go b/pkg/skaffold/build/local/types.go index 9762f3f4b34..550b32d6ddb 100644 --- a/pkg/skaffold/build/local/types.go +++ b/pkg/skaffold/build/local/types.go @@ -22,14 +22,14 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) // Builder uses the host docker daemon to build and tag the image. type Builder struct { - cfg *v1alpha2.LocalBuild + cfg *v1alpha3.LocalBuild api docker.APIClient localCluster bool @@ -40,7 +40,7 @@ type Builder struct { } // NewBuilder returns an new instance of a local Builder. -func NewBuilder(cfg *v1alpha2.LocalBuild, kubeContext string) (*Builder, error) { +func NewBuilder(cfg *v1alpha3.LocalBuild, kubeContext string) (*Builder, error) { api, err := docker.NewAPIClient() if err != nil { return nil, errors.Wrap(err, "getting docker client") diff --git a/pkg/skaffold/build/parallel.go b/pkg/skaffold/build/parallel.go index eb22ba8082a..79707544451 100644 --- a/pkg/skaffold/build/parallel.go +++ b/pkg/skaffold/build/parallel.go @@ -24,16 +24,16 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/tag" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/color" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/pkg/errors" ) const bufferedLinesPerArtifact = 10000 -type artifactBuilder func(ctx context.Context, out io.Writer, tagger tag.Tagger, artifact *v1alpha2.Artifact) (string, error) +type artifactBuilder func(ctx context.Context, out io.Writer, tagger tag.Tagger, artifact *v1alpha3.Artifact) (string, error) // InParallel builds a list of artifacts in parallel but prints the logs in sequential order. -func InParallel(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha2.Artifact, buildArtifact artifactBuilder) ([]Artifact, error) { +func InParallel(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha3.Artifact, buildArtifact artifactBuilder) ([]Artifact, error) { ctx, cancel := context.WithCancel(ctx) defer cancel() diff --git a/pkg/skaffold/build/sequence.go b/pkg/skaffold/build/sequence.go index 03e8940d078..be43b4c0e0b 100644 --- a/pkg/skaffold/build/sequence.go +++ b/pkg/skaffold/build/sequence.go @@ -22,12 +22,12 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/tag" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/color" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/pkg/errors" ) // InSequence builds a list of artifacts in sequence. -func InSequence(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha2.Artifact, buildArtifact artifactBuilder) ([]Artifact, error) { +func InSequence(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha3.Artifact, buildArtifact artifactBuilder) ([]Artifact, error) { var builds []Artifact for _, artifact := range artifacts { diff --git a/pkg/skaffold/config/config.go b/pkg/skaffold/config/config.go index 07790f83879..b056662362c 100644 --- a/pkg/skaffold/config/config.go +++ b/pkg/skaffold/config/config.go @@ -17,14 +17,14 @@ limitations under the License. package config import ( - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" ) // SkaffoldConfig references the most recent skaffold config version -type SkaffoldConfig = v1alpha2.SkaffoldConfig +type SkaffoldConfig = v1alpha3.SkaffoldConfig -const LatestVersion string = v1alpha2.Version +const LatestVersion string = v1alpha3.Version func NewConfig() (*SkaffoldConfig, error) { - return v1alpha2.NewConfig() + return v1alpha3.NewConfig() } diff --git a/pkg/skaffold/config/config_test.go b/pkg/skaffold/config/config_test.go index 6ca9e13570c..0193d62eca0 100644 --- a/pkg/skaffold/config/config_test.go +++ b/pkg/skaffold/config/config_test.go @@ -20,18 +20,18 @@ import ( "testing" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/testutil" "k8s.io/client-go/tools/clientcmd/api" ) const ( minimalConfig = ` -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config ` simpleConfig = ` -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: tagPolicy: @@ -43,7 +43,7 @@ deploy: ` // This config has two tag policies set. invalidConfig = ` -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: tagPolicy: @@ -56,7 +56,7 @@ deploy: ` completeConfig = ` -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: tagPolicy: @@ -79,18 +79,20 @@ deploy: - svc.yaml ` minimalKanikoConfig = ` -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: kaniko: - gcsBucket: demo + buildContext: + gcsBucket: demo ` completeKanikoConfig = ` -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: kaniko: - gcsBucket: demo + buildContext: + gcsBucket: demo pullSecret: /secret.json pullSecretName: secret-name namespace: nskaniko @@ -184,16 +186,16 @@ func TestParseConfig(t *testing.T) { } func config(ops ...func(*SkaffoldConfig)) *SkaffoldConfig { - cfg := &SkaffoldConfig{APIVersion: "skaffold/v1alpha2", Kind: "Config"} + cfg := &SkaffoldConfig{APIVersion: "skaffold/v1alpha3", Kind: "Config"} for _, op := range ops { op(cfg) } return cfg } -func withLocalBuild(ops ...func(*v1alpha2.BuildConfig)) func(*SkaffoldConfig) { +func withLocalBuild(ops ...func(*v1alpha3.BuildConfig)) func(*SkaffoldConfig) { return func(cfg *SkaffoldConfig) { - b := v1alpha2.BuildConfig{BuildType: v1alpha2.BuildType{LocalBuild: &v1alpha2.LocalBuild{}}} + b := v1alpha3.BuildConfig{BuildType: v1alpha3.BuildType{LocalBuild: &v1alpha3.LocalBuild{}}} for _, op := range ops { op(&b) } @@ -201,9 +203,9 @@ func withLocalBuild(ops ...func(*v1alpha2.BuildConfig)) func(*SkaffoldConfig) { } } -func withGoogleCloudBuild(id string, ops ...func(*v1alpha2.BuildConfig)) func(*SkaffoldConfig) { +func withGoogleCloudBuild(id string, ops ...func(*v1alpha3.BuildConfig)) func(*SkaffoldConfig) { return func(cfg *SkaffoldConfig) { - b := v1alpha2.BuildConfig{BuildType: v1alpha2.BuildType{GoogleCloudBuild: &v1alpha2.GoogleCloudBuild{ + b := v1alpha3.BuildConfig{BuildType: v1alpha3.BuildType{GoogleCloudBuild: &v1alpha3.GoogleCloudBuild{ ProjectID: id, DockerImage: "gcr.io/cloud-builders/docker", }}} @@ -214,10 +216,12 @@ func withGoogleCloudBuild(id string, ops ...func(*v1alpha2.BuildConfig)) func(*S } } -func withKanikoBuild(bucket, secretName, namespace, secret string, timeout string, ops ...func(*v1alpha2.BuildConfig)) func(*SkaffoldConfig) { +func withKanikoBuild(bucket, secretName, namespace, secret string, timeout string, ops ...func(*v1alpha3.BuildConfig)) func(*SkaffoldConfig) { return func(cfg *SkaffoldConfig) { - b := v1alpha2.BuildConfig{BuildType: v1alpha2.BuildType{KanikoBuild: &v1alpha2.KanikoBuild{ - GCSBucket: bucket, + b := v1alpha3.BuildConfig{BuildType: v1alpha3.BuildType{KanikoBuild: &v1alpha3.KanikoBuild{ + BuildContext: v1alpha3.KanikoBuildContext{ + GCSBucket: bucket, + }, PullSecretName: secretName, Namespace: namespace, PullSecret: secret, @@ -232,9 +236,9 @@ func withKanikoBuild(bucket, secretName, namespace, secret string, timeout strin func withKubectlDeploy(manifests ...string) func(*SkaffoldConfig) { return func(cfg *SkaffoldConfig) { - cfg.Deploy = v1alpha2.DeployConfig{ - DeployType: v1alpha2.DeployType{ - KubectlDeploy: &v1alpha2.KubectlDeploy{ + cfg.Deploy = v1alpha3.DeployConfig{ + DeployType: v1alpha3.DeployType{ + KubectlDeploy: &v1alpha3.KubectlDeploy{ Manifests: manifests, }, }, @@ -244,21 +248,21 @@ func withKubectlDeploy(manifests ...string) func(*SkaffoldConfig) { func withHelmDeploy() func(*SkaffoldConfig) { return func(cfg *SkaffoldConfig) { - cfg.Deploy = v1alpha2.DeployConfig{ - DeployType: v1alpha2.DeployType{ - HelmDeploy: &v1alpha2.HelmDeploy{}, + cfg.Deploy = v1alpha3.DeployConfig{ + DeployType: v1alpha3.DeployType{ + HelmDeploy: &v1alpha3.HelmDeploy{}, }, } } } -func withDockerArtifact(image, workspace, dockerfile string) func(*v1alpha2.BuildConfig) { - return func(cfg *v1alpha2.BuildConfig) { - cfg.Artifacts = append(cfg.Artifacts, &v1alpha2.Artifact{ +func withDockerArtifact(image, workspace, dockerfile string) func(*v1alpha3.BuildConfig) { + return func(cfg *v1alpha3.BuildConfig) { + cfg.Artifacts = append(cfg.Artifacts, &v1alpha3.Artifact{ ImageName: image, Workspace: workspace, - ArtifactType: v1alpha2.ArtifactType{ - DockerArtifact: &v1alpha2.DockerArtifact{ + ArtifactType: v1alpha3.ArtifactType{ + DockerArtifact: &v1alpha3.DockerArtifact{ DockerfilePath: dockerfile, }, }, @@ -266,13 +270,13 @@ func withDockerArtifact(image, workspace, dockerfile string) func(*v1alpha2.Buil } } -func withBazelArtifact(image, workspace, target string) func(*v1alpha2.BuildConfig) { - return func(cfg *v1alpha2.BuildConfig) { - cfg.Artifacts = append(cfg.Artifacts, &v1alpha2.Artifact{ +func withBazelArtifact(image, workspace, target string) func(*v1alpha3.BuildConfig) { + return func(cfg *v1alpha3.BuildConfig) { + cfg.Artifacts = append(cfg.Artifacts, &v1alpha3.Artifact{ ImageName: image, Workspace: workspace, - ArtifactType: v1alpha2.ArtifactType{ - BazelArtifact: &v1alpha2.BazelArtifact{ + ArtifactType: v1alpha3.ArtifactType{ + BazelArtifact: &v1alpha3.BazelArtifact{ BuildTarget: target, }, }, @@ -280,19 +284,19 @@ func withBazelArtifact(image, workspace, target string) func(*v1alpha2.BuildConf } } -func withTagPolicy(tagPolicy v1alpha2.TagPolicy) func(*v1alpha2.BuildConfig) { - return func(cfg *v1alpha2.BuildConfig) { cfg.TagPolicy = tagPolicy } +func withTagPolicy(tagPolicy v1alpha3.TagPolicy) func(*v1alpha3.BuildConfig) { + return func(cfg *v1alpha3.BuildConfig) { cfg.TagPolicy = tagPolicy } } -func withGitTagger() func(*v1alpha2.BuildConfig) { - return withTagPolicy(v1alpha2.TagPolicy{GitTagger: &v1alpha2.GitTagger{}}) +func withGitTagger() func(*v1alpha3.BuildConfig) { + return withTagPolicy(v1alpha3.TagPolicy{GitTagger: &v1alpha3.GitTagger{}}) } -func withShaTagger() func(*v1alpha2.BuildConfig) { - return withTagPolicy(v1alpha2.TagPolicy{ShaTagger: &v1alpha2.ShaTagger{}}) +func withShaTagger() func(*v1alpha3.BuildConfig) { + return withTagPolicy(v1alpha3.TagPolicy{ShaTagger: &v1alpha3.ShaTagger{}}) } -func withProfiles(profiles ...v1alpha2.Profile) func(*SkaffoldConfig) { +func withProfiles(profiles ...v1alpha3.Profile) func(*SkaffoldConfig) { return func(cfg *SkaffoldConfig) { cfg.Profiles = profiles } diff --git a/pkg/skaffold/config/profile_test.go b/pkg/skaffold/config/profile_test.go index 22447586517..af3471337df 100644 --- a/pkg/skaffold/config/profile_test.go +++ b/pkg/skaffold/config/profile_test.go @@ -19,7 +19,7 @@ package config import ( "testing" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/testutil" ) @@ -47,11 +47,11 @@ func TestApplyProfiles(t *testing.T) { withDockerArtifact("image", ".", "Dockerfile"), ), withKubectlDeploy("k8s/*.yaml"), - withProfiles(v1alpha2.Profile{ + withProfiles(v1alpha3.Profile{ Name: "profile", - Build: v1alpha2.BuildConfig{ - BuildType: v1alpha2.BuildType{ - GoogleCloudBuild: &v1alpha2.GoogleCloudBuild{ + Build: v1alpha3.BuildConfig{ + BuildType: v1alpha3.BuildType{ + GoogleCloudBuild: &v1alpha3.GoogleCloudBuild{ ProjectID: "my-project", }, }, @@ -75,10 +75,10 @@ func TestApplyProfiles(t *testing.T) { withDockerArtifact("image", ".", "Dockerfile"), ), withKubectlDeploy("k8s/*.yaml"), - withProfiles(v1alpha2.Profile{ + withProfiles(v1alpha3.Profile{ Name: "dev", - Build: v1alpha2.BuildConfig{ - TagPolicy: v1alpha2.TagPolicy{ShaTagger: &v1alpha2.ShaTagger{}}, + Build: v1alpha3.BuildConfig{ + TagPolicy: v1alpha3.TagPolicy{ShaTagger: &v1alpha3.ShaTagger{}}, }, }), ), @@ -99,10 +99,10 @@ func TestApplyProfiles(t *testing.T) { withDockerArtifact("image", ".", "Dockerfile"), ), withKubectlDeploy("k8s/*.yaml"), - withProfiles(v1alpha2.Profile{ + withProfiles(v1alpha3.Profile{ Name: "profile", - Build: v1alpha2.BuildConfig{ - Artifacts: []*v1alpha2.Artifact{ + Build: v1alpha3.BuildConfig{ + Artifacts: []*v1alpha3.Artifact{ {ImageName: "image"}, {ImageName: "imageProd"}, }, @@ -126,11 +126,11 @@ func TestApplyProfiles(t *testing.T) { withGitTagger(), ), withKubectlDeploy("k8s/*.yaml"), - withProfiles(v1alpha2.Profile{ + withProfiles(v1alpha3.Profile{ Name: "profile", - Deploy: v1alpha2.DeployConfig{ - DeployType: v1alpha2.DeployType{ - HelmDeploy: &v1alpha2.HelmDeploy{}, + Deploy: v1alpha3.DeployConfig{ + DeployType: v1alpha3.DeployType{ + HelmDeploy: &v1alpha3.HelmDeploy{}, }, }, }), diff --git a/pkg/skaffold/config/transform/transforms.go b/pkg/skaffold/config/transform/transforms.go index 77d6b7c0ed7..9c81b19b365 100644 --- a/pkg/skaffold/config/transform/transforms.go +++ b/pkg/skaffold/config/transform/transforms.go @@ -17,15 +17,19 @@ limitations under the License. package transform import ( + "encoding/json" "fmt" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha1" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" + "github.com/pkg/errors" "github.com/sirupsen/logrus" ) +// ToV1Alpha2 transforms v1alpha1 configs to v1alpha2 func ToV1Alpha2(vc util.VersionedConfig) (util.VersionedConfig, error) { if vc.GetVersion() != v1alpha1.Version { return nil, fmt.Errorf("Incompatible version: %s", vc.GetVersion()) @@ -115,3 +119,66 @@ func ToV1Alpha2(vc util.VersionedConfig) (util.VersionedConfig, error) { } return newConfig, nil } + +// ToV1Alpha3 transforms configs from v1alpha2 to v1alpha3 +func ToV1Alpha3(vc util.VersionedConfig) (util.VersionedConfig, error) { + if vc.GetVersion() != v1alpha2.Version { + return nil, fmt.Errorf("Incompatible version: %s", vc.GetVersion()) + } + oldConfig := vc.(*v1alpha2.SkaffoldConfig) + + // convert v1alpha2.Deploy to v1alpha3.Deploy (should be the same) + var newDeploy v1alpha3.DeployConfig + if err := convert(oldConfig.Deploy, &newDeploy); err != nil { + return nil, errors.Wrap(err, "converting deploy config") + } + + // convert v1alpha2.Profiles to v1alpha3.Profiles (should be the same) + var newProfiles []v1alpha3.Profile + if oldConfig.Profiles != nil { + if err := convert(oldConfig.Profiles, &newProfiles); err != nil { + return nil, errors.Wrap(err, "converting new profile") + } + } + + // convert v1alpha2.Build to v1alpha3.Build (different only for kaniko) + oldKanikoBuilder := oldConfig.Build.KanikoBuild + oldConfig.Build.KanikoBuild = nil + + // copy over old build config to new build config + var newBuild v1alpha3.BuildConfig + if err := convert(oldConfig.Build, &newBuild); err != nil { + return nil, errors.Wrap(err, "converting new build") + } + // if the kaniko build was set, then convert it + if oldKanikoBuilder != nil { + newBuild.BuildType.KanikoBuild = &v1alpha3.KanikoBuild{ + BuildContext: v1alpha3.KanikoBuildContext{ + GCSBucket: oldKanikoBuilder.GCSBucket, + }, + Namespace: oldKanikoBuilder.Namespace, + PullSecret: oldKanikoBuilder.PullSecret, + PullSecretName: oldKanikoBuilder.PullSecretName, + Timeout: oldKanikoBuilder.Timeout, + } + } + newConfig := &v1alpha3.SkaffoldConfig{ + APIVersion: v1alpha3.Version, + Kind: oldConfig.Kind, + Deploy: newDeploy, + Build: newBuild, + Profiles: newProfiles, + } + return newConfig, nil +} + +func convert(old interface{}, new interface{}) error { + o, err := json.Marshal(old) + if err != nil { + return errors.Wrap(err, "marshalling old") + } + if err := json.Unmarshal(o, &new); err != nil { + return errors.Wrap(err, "unmarshalling new") + } + return nil +} diff --git a/pkg/skaffold/config/util.go b/pkg/skaffold/config/util.go index 687c5550490..aa545f62c70 100644 --- a/pkg/skaffold/config/util.go +++ b/pkg/skaffold/config/util.go @@ -22,6 +22,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha1" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/yamltags" ) @@ -29,6 +30,7 @@ import ( var Versions = []string{ v1alpha1.Version, v1alpha2.Version, + v1alpha3.Version, } var schemaVersions = map[string]func() util.VersionedConfig{ @@ -38,6 +40,9 @@ var schemaVersions = map[string]func() util.VersionedConfig{ v1alpha2.Version: func() util.VersionedConfig { return new(v1alpha2.SkaffoldConfig) }, + v1alpha3.Version: func() util.VersionedConfig { + return new(v1alpha3.SkaffoldConfig) + }, } func GetConfig(contents []byte, useDefault bool) (util.VersionedConfig, error) { diff --git a/pkg/skaffold/deploy/helm.go b/pkg/skaffold/deploy/helm.go index 4028e9dbfea..e6eab8af14f 100644 --- a/pkg/skaffold/deploy/helm.go +++ b/pkg/skaffold/deploy/helm.go @@ -33,7 +33,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/tag" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/color" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -41,7 +41,7 @@ import ( ) type HelmDeployer struct { - *v1alpha2.HelmDeploy + *v1alpha3.HelmDeploy kubeContext string namespace string @@ -49,7 +49,7 @@ type HelmDeployer struct { // NewHelmDeployer returns a new HelmDeployer for a DeployConfig filled // with the needed configuration for `helm` -func NewHelmDeployer(cfg *v1alpha2.HelmDeploy, kubeContext string, namespace string) *HelmDeployer { +func NewHelmDeployer(cfg *v1alpha3.HelmDeploy, kubeContext string, namespace string) *HelmDeployer { return &HelmDeployer{ HelmDeploy: cfg, kubeContext: kubeContext, @@ -115,7 +115,7 @@ func (h *HelmDeployer) helm(ctx context.Context, out io.Writer, arg ...string) e return util.RunCmd(cmd) } -func (h *HelmDeployer) deployRelease(ctx context.Context, out io.Writer, r v1alpha2.HelmRelease, builds []build.Artifact) ([]Artifact, error) { +func (h *HelmDeployer) deployRelease(ctx context.Context, out io.Writer, r v1alpha3.HelmRelease, builds []build.Artifact) ([]Artifact, error) { isInstalled := true releaseName, err := evaluateReleaseName(r.Name) @@ -268,7 +268,7 @@ func extractTag(imageName string) string { // packageChart packages the chart and returns path to the chart archive file. // If this function returns an error, it will always be wrapped. -func (h *HelmDeployer) packageChart(ctx context.Context, r v1alpha2.HelmRelease) (string, error) { +func (h *HelmDeployer) packageChart(ctx context.Context, r v1alpha3.HelmRelease) (string, error) { tmp := os.TempDir() packageArgs := []string{"package", r.ChartPath, "--destination", tmp} if r.Packaged.Version != "" { @@ -321,7 +321,7 @@ func (h *HelmDeployer) getDeployResults(ctx context.Context, namespace string, r return parseReleaseInfo(namespace, b) } -func (h *HelmDeployer) deleteRelease(ctx context.Context, out io.Writer, r v1alpha2.HelmRelease) error { +func (h *HelmDeployer) deleteRelease(ctx context.Context, out io.Writer, r v1alpha3.HelmRelease) error { releaseName, err := evaluateReleaseName(r.Name) if err != nil { return errors.Wrap(err, "cannot parse the release name template") diff --git a/pkg/skaffold/deploy/helm_test.go b/pkg/skaffold/deploy/helm_test.go index c5403c1f03d..419c3b1fbe6 100644 --- a/pkg/skaffold/deploy/helm_test.go +++ b/pkg/skaffold/deploy/helm_test.go @@ -28,7 +28,7 @@ import ( "testing" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/testutil" "github.com/sirupsen/logrus" @@ -48,8 +48,8 @@ var testBuildsFoo = []build.Artifact{ }, } -var testDeployConfig = &v1alpha2.HelmDeploy{ - Releases: []v1alpha2.HelmRelease{ +var testDeployConfig = &v1alpha3.HelmDeploy{ + Releases: []v1alpha3.HelmRelease{ { Name: "skaffold-helm", ChartPath: "examples/test", @@ -66,8 +66,8 @@ var testDeployConfig = &v1alpha2.HelmDeploy{ }, } -var testDeployRecreatePodsConfig = &v1alpha2.HelmDeploy{ - Releases: []v1alpha2.HelmRelease{ +var testDeployRecreatePodsConfig = &v1alpha3.HelmDeploy{ + Releases: []v1alpha3.HelmRelease{ { Name: "skaffold-helm", ChartPath: "examples/test", @@ -85,8 +85,8 @@ var testDeployRecreatePodsConfig = &v1alpha2.HelmDeploy{ }, } -var testDeployHelmStyleConfig = &v1alpha2.HelmDeploy{ - Releases: []v1alpha2.HelmRelease{ +var testDeployHelmStyleConfig = &v1alpha3.HelmDeploy{ + Releases: []v1alpha3.HelmRelease{ { Name: "skaffold-helm", ChartPath: "examples/test", @@ -99,17 +99,17 @@ var testDeployHelmStyleConfig = &v1alpha2.HelmDeploy{ SetValues: map[string]string{ "some.key": "somevalue", }, - ImageStrategy: v1alpha2.HelmImageStrategy{ - HelmImageConfig: v1alpha2.HelmImageConfig{ - HelmConventionConfig: &v1alpha2.HelmConventionConfig{}, + ImageStrategy: v1alpha3.HelmImageStrategy{ + HelmImageConfig: v1alpha3.HelmImageConfig{ + HelmConventionConfig: &v1alpha3.HelmConventionConfig{}, }, }, }, }, } -var testDeployConfigParameterUnmatched = &v1alpha2.HelmDeploy{ - Releases: []v1alpha2.HelmRelease{ +var testDeployConfigParameterUnmatched = &v1alpha3.HelmDeploy{ + Releases: []v1alpha3.HelmRelease{ { Name: "skaffold-helm", ChartPath: "examples/test", @@ -120,15 +120,15 @@ var testDeployConfigParameterUnmatched = &v1alpha2.HelmDeploy{ }, } -var testDeployFooWithPackaged = &v1alpha2.HelmDeploy{ - Releases: []v1alpha2.HelmRelease{ +var testDeployFooWithPackaged = &v1alpha3.HelmDeploy{ + Releases: []v1alpha3.HelmRelease{ { Name: "foo", ChartPath: "testdata/foo", Values: map[string]string{ "image": "foo", }, - Packaged: &v1alpha2.HelmPackaged{ + Packaged: &v1alpha3.HelmPackaged{ Version: "0.1.2", AppVersion: "1.2.3", }, @@ -136,8 +136,8 @@ var testDeployFooWithPackaged = &v1alpha2.HelmDeploy{ }, } -var testDeployWithTemplatedName = &v1alpha2.HelmDeploy{ - Releases: []v1alpha2.HelmRelease{ +var testDeployWithTemplatedName = &v1alpha3.HelmDeploy{ + Releases: []v1alpha3.HelmRelease{ { Name: "{{.USER}}-skaffold-helm", ChartPath: "examples/test", @@ -521,8 +521,8 @@ func TestHelmDependencies(t *testing.T) { folder.Write(file, "") } - deployer := NewHelmDeployer(&v1alpha2.HelmDeploy{ - Releases: []v1alpha2.HelmRelease{ + deployer := NewHelmDeployer(&v1alpha3.HelmDeploy{ + Releases: []v1alpha3.HelmRelease{ { Name: "skaffold-helm", ChartPath: folder.Root(), diff --git a/pkg/skaffold/deploy/kubectl.go b/pkg/skaffold/deploy/kubectl.go index cb4027931b0..4e131d7a50a 100644 --- a/pkg/skaffold/deploy/kubectl.go +++ b/pkg/skaffold/deploy/kubectl.go @@ -27,7 +27,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy/kubectl" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -35,7 +35,7 @@ import ( // KubectlDeployer deploys workflows using kubectl CLI. type KubectlDeployer struct { - *v1alpha2.KubectlDeploy + *v1alpha3.KubectlDeploy workingDir string kubectl kubectl.CLI @@ -43,7 +43,7 @@ type KubectlDeployer struct { // NewKubectlDeployer returns a new KubectlDeployer for a DeployConfig filled // with the needed configuration for `kubectl apply` -func NewKubectlDeployer(workingDir string, cfg *v1alpha2.KubectlDeploy, kubeContext string, namespace string) *KubectlDeployer { +func NewKubectlDeployer(workingDir string, cfg *v1alpha3.KubectlDeploy, kubeContext string, namespace string) *KubectlDeployer { return &KubectlDeployer{ KubectlDeploy: cfg, workingDir: workingDir, diff --git a/pkg/skaffold/deploy/kubectl/cli.go b/pkg/skaffold/deploy/kubectl/cli.go index c1a937c6318..45a87036306 100644 --- a/pkg/skaffold/deploy/kubectl/cli.go +++ b/pkg/skaffold/deploy/kubectl/cli.go @@ -21,7 +21,7 @@ import ( "io" "os/exec" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -31,7 +31,7 @@ import ( type CLI struct { Namespace string KubeContext string - Flags v1alpha2.KubectlFlags + Flags v1alpha3.KubectlFlags previousApply ManifestList } diff --git a/pkg/skaffold/deploy/kubectl_test.go b/pkg/skaffold/deploy/kubectl_test.go index 8b54f9ac207..a9ddf3704e6 100644 --- a/pkg/skaffold/deploy/kubectl_test.go +++ b/pkg/skaffold/deploy/kubectl_test.go @@ -23,7 +23,7 @@ import ( "testing" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/testutil" "github.com/pkg/errors" @@ -56,7 +56,7 @@ spec: func TestKubectlDeploy(t *testing.T) { var tests = []struct { description string - cfg *v1alpha2.KubectlDeploy + cfg *v1alpha3.KubectlDeploy builds []build.Artifact command util.Command shouldErr bool @@ -64,7 +64,7 @@ func TestKubectlDeploy(t *testing.T) { { description: "parameter mismatch", shouldErr: true, - cfg: &v1alpha2.KubectlDeploy{ + cfg: &v1alpha3.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, builds: []build.Artifact{ @@ -77,7 +77,7 @@ func TestKubectlDeploy(t *testing.T) { { description: "missing manifest file", shouldErr: true, - cfg: &v1alpha2.KubectlDeploy{ + cfg: &v1alpha3.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, builds: []build.Artifact{ @@ -89,7 +89,7 @@ func TestKubectlDeploy(t *testing.T) { }, { description: "deploy success", - cfg: &v1alpha2.KubectlDeploy{ + cfg: &v1alpha3.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, command: testutil.NewFakeCmd("kubectl --context kubecontext --namespace testNamespace apply -f -", nil), @@ -103,7 +103,7 @@ func TestKubectlDeploy(t *testing.T) { { description: "deploy command error", shouldErr: true, - cfg: &v1alpha2.KubectlDeploy{ + cfg: &v1alpha3.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, command: testutil.NewFakeCmd("kubectl --context kubecontext --namespace testNamespace apply -f -", fmt.Errorf("")), @@ -117,9 +117,9 @@ func TestKubectlDeploy(t *testing.T) { { description: "additional flags", shouldErr: true, - cfg: &v1alpha2.KubectlDeploy{ + cfg: &v1alpha3.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, - Flags: v1alpha2.KubectlFlags{ + Flags: v1alpha3.KubectlFlags{ Global: []string{"-v=0"}, Apply: []string{"--overwrite=true"}, Delete: []string{"ignored"}, @@ -158,20 +158,20 @@ func TestKubectlDeploy(t *testing.T) { func TestKubectlCleanup(t *testing.T) { var tests = []struct { description string - cfg *v1alpha2.KubectlDeploy + cfg *v1alpha3.KubectlDeploy command util.Command shouldErr bool }{ { description: "cleanup success", - cfg: &v1alpha2.KubectlDeploy{ + cfg: &v1alpha3.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, command: testutil.NewFakeCmd("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -", nil), }, { description: "cleanup error", - cfg: &v1alpha2.KubectlDeploy{ + cfg: &v1alpha3.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, }, command: testutil.NewFakeCmd("kubectl --context kubecontext --namespace testNamespace delete --ignore-not-found=true -f -", errors.New("BUG")), @@ -179,9 +179,9 @@ func TestKubectlCleanup(t *testing.T) { }, { description: "additional flags", - cfg: &v1alpha2.KubectlDeploy{ + cfg: &v1alpha3.KubectlDeploy{ Manifests: []string{"deployment.yaml"}, - Flags: v1alpha2.KubectlFlags{ + Flags: v1alpha3.KubectlFlags{ Global: []string{"-v=0"}, Apply: []string{"ignored"}, Delete: []string{"--grace-period=1"}, diff --git a/pkg/skaffold/deploy/kustomize.go b/pkg/skaffold/deploy/kustomize.go index 9cd5dd1441e..7ca748d6164 100644 --- a/pkg/skaffold/deploy/kustomize.go +++ b/pkg/skaffold/deploy/kustomize.go @@ -24,18 +24,18 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy/kubectl" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/pkg/errors" ) type KustomizeDeployer struct { - *v1alpha2.KustomizeDeploy + *v1alpha3.KustomizeDeploy kubectl kubectl.CLI } -func NewKustomizeDeployer(cfg *v1alpha2.KustomizeDeploy, kubeContext string, namespace string) *KustomizeDeployer { +func NewKustomizeDeployer(cfg *v1alpha3.KustomizeDeploy, kubeContext string, namespace string) *KustomizeDeployer { return &KustomizeDeployer{ KustomizeDeploy: cfg, kubectl: kubectl.CLI{ diff --git a/pkg/skaffold/docker/context.go b/pkg/skaffold/docker/context.go index b7b6ea8d503..fea931e161c 100644 --- a/pkg/skaffold/docker/context.go +++ b/pkg/skaffold/docker/context.go @@ -23,7 +23,7 @@ import ( "strings" cstorage "cloud.google.com/go/storage" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/pkg/errors" ) @@ -40,7 +40,7 @@ func NormalizeDockerfilePath(context, dockerfile string) (string, error) { return filepath.Abs(dockerfile) } -func CreateDockerTarContext(w io.Writer, workspace string, a *v1alpha2.DockerArtifact) error { +func CreateDockerTarContext(w io.Writer, workspace string, a *v1alpha3.DockerArtifact) error { paths, err := GetDependencies(workspace, a) if err != nil { return errors.Wrap(err, "getting relative tar paths") @@ -53,7 +53,7 @@ func CreateDockerTarContext(w io.Writer, workspace string, a *v1alpha2.DockerArt return nil } -func CreateDockerTarGzContext(w io.Writer, workspace string, a *v1alpha2.DockerArtifact) error { +func CreateDockerTarGzContext(w io.Writer, workspace string, a *v1alpha3.DockerArtifact) error { paths, err := GetDependencies(workspace, a) if err != nil { return errors.Wrap(err, "getting relative tar paths") @@ -66,7 +66,7 @@ func CreateDockerTarGzContext(w io.Writer, workspace string, a *v1alpha2.DockerA return nil } -func UploadContextToGCS(ctx context.Context, workspace string, a *v1alpha2.DockerArtifact, bucket, objectName string) error { +func UploadContextToGCS(ctx context.Context, workspace string, a *v1alpha3.DockerArtifact, bucket, objectName string) error { c, err := cstorage.NewClient(ctx) if err != nil { return err diff --git a/pkg/skaffold/docker/context_test.go b/pkg/skaffold/docker/context_test.go index f1900624d91..375a7fe94dd 100644 --- a/pkg/skaffold/docker/context_test.go +++ b/pkg/skaffold/docker/context_test.go @@ -21,7 +21,7 @@ import ( "io" "testing" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/testutil" ) @@ -33,7 +33,7 @@ func TestDockerContext(t *testing.T) { RetrieveImage = imageFetcher.fetch defer func() { RetrieveImage = retrieveImage }() - artifact := &v1alpha2.DockerArtifact{ + artifact := &v1alpha3.DockerArtifact{ DockerfilePath: "Dockerfile", BuildArgs: map[string]*string{}, } diff --git a/pkg/skaffold/docker/image.go b/pkg/skaffold/docker/image.go index 66cd9211916..0849c6ebfed 100644 --- a/pkg/skaffold/docker/image.go +++ b/pkg/skaffold/docker/image.go @@ -23,7 +23,7 @@ import ( "net/http" "sort" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/docker/docker/api/types" "github.com/docker/docker/client" "github.com/docker/docker/pkg/jsonmessage" @@ -40,7 +40,7 @@ import ( ) // BuildArtifact performs a docker build and returns nothing -func BuildArtifact(ctx context.Context, out io.Writer, cli APIClient, workspace string, a *v1alpha2.DockerArtifact, initialTag string) error { +func BuildArtifact(ctx context.Context, out io.Writer, cli APIClient, workspace string, a *v1alpha3.DockerArtifact, initialTag string) error { logrus.Debugf("Running docker build: context: %s, dockerfile: %s", workspace, a.DockerfilePath) // Like `docker build`, we ignore the errors @@ -175,7 +175,7 @@ func RemoteDigest(identifier string) (string, error) { } // GetBuildArgs gives the build args flags for docker build. -func GetBuildArgs(a *v1alpha2.DockerArtifact) []string { +func GetBuildArgs(a *v1alpha3.DockerArtifact) []string { var args []string var keys []string diff --git a/pkg/skaffold/docker/image_test.go b/pkg/skaffold/docker/image_test.go index 85231a5f363..5ebdeb8bab0 100644 --- a/pkg/skaffold/docker/image_test.go +++ b/pkg/skaffold/docker/image_test.go @@ -24,7 +24,7 @@ import ( "os" "testing" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/testutil" "github.com/google/go-cmp/cmp" @@ -122,7 +122,7 @@ func TestRunBuildArtifact(t *testing.T) { t.Run(test.description, func(t *testing.T) { api := testutil.NewFakeImageAPIClient(test.tagToImageID, test.testOpts) - err := BuildArtifact(context.Background(), ioutil.Discard, api, ".", &v1alpha2.DockerArtifact{}, "finalimage") + err := BuildArtifact(context.Background(), ioutil.Discard, api, ".", &v1alpha3.DockerArtifact{}, "finalimage") testutil.CheckError(t, test.shouldErr, err) }) @@ -173,12 +173,12 @@ func TestDigest(t *testing.T) { func TestGetBuildArgs(t *testing.T) { tests := []struct { description string - artifact *v1alpha2.DockerArtifact + artifact *v1alpha3.DockerArtifact want []string }{ { description: "build args", - artifact: &v1alpha2.DockerArtifact{ + artifact: &v1alpha3.DockerArtifact{ BuildArgs: map[string]*string{ "key1": util.StringPtr("value1"), "key2": nil, @@ -188,21 +188,21 @@ func TestGetBuildArgs(t *testing.T) { }, { description: "cache from", - artifact: &v1alpha2.DockerArtifact{ + artifact: &v1alpha3.DockerArtifact{ CacheFrom: []string{"gcr.io/foo/bar", "baz:latest"}, }, want: []string{"--cache-from", "gcr.io/foo/bar", "--cache-from", "baz:latest"}, }, { description: "target", - artifact: &v1alpha2.DockerArtifact{ + artifact: &v1alpha3.DockerArtifact{ Target: "stage1", }, want: []string{"--target", "stage1"}, }, { description: "all", - artifact: &v1alpha2.DockerArtifact{ + artifact: &v1alpha3.DockerArtifact{ BuildArgs: map[string]*string{ "key1": util.StringPtr("value1"), }, diff --git a/pkg/skaffold/docker/parse.go b/pkg/skaffold/docker/parse.go index d99efc76d34..cc59e7a6e00 100644 --- a/pkg/skaffold/docker/parse.go +++ b/pkg/skaffold/docker/parse.go @@ -26,7 +26,7 @@ import ( "strings" "sync" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/docker/docker/builder/dockerignore" "github.com/docker/docker/pkg/fileutils" "github.com/google/go-containerregistry/pkg/v1" @@ -219,7 +219,7 @@ func readDockerfile(workspace, absDockerfilePath string, buildArgs map[string]*s // GetDependencies finds the sources dependencies for the given docker artifact. // All paths are relative to the workspace. -func GetDependencies(workspace string, a *v1alpha2.DockerArtifact) ([]string, error) { +func GetDependencies(workspace string, a *v1alpha3.DockerArtifact) ([]string, error) { absDockerfilePath, err := NormalizeDockerfilePath(workspace, a.DockerfilePath) if err != nil { return nil, errors.Wrap(err, "normalizing dockerfile path") diff --git a/pkg/skaffold/docker/parse_test.go b/pkg/skaffold/docker/parse_test.go index 742a1664199..6cd110cdb5f 100644 --- a/pkg/skaffold/docker/parse_test.go +++ b/pkg/skaffold/docker/parse_test.go @@ -21,7 +21,7 @@ import ( "path/filepath" "testing" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util" "github.com/GoogleContainerTools/skaffold/testutil" "github.com/google/go-containerregistry/pkg/v1" @@ -373,7 +373,7 @@ func TestGetDependencies(t *testing.T) { } workspace := tmpDir.Path(test.workspace) - deps, err := GetDependencies(workspace, &v1alpha2.DockerArtifact{ + deps, err := GetDependencies(workspace, &v1alpha3.DockerArtifact{ BuildArgs: test.buildArgs, DockerfilePath: "Dockerfile", }) diff --git a/pkg/skaffold/kubernetes/colorpicker.go b/pkg/skaffold/kubernetes/colorpicker.go index 2ec6e354e8b..a212b648406 100644 --- a/pkg/skaffold/kubernetes/colorpicker.go +++ b/pkg/skaffold/kubernetes/colorpicker.go @@ -20,7 +20,7 @@ import ( "strings" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/color" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" v1 "k8s.io/api/core/v1" ) @@ -53,7 +53,7 @@ type colorPicker struct { // sequentially from `colorCodes`. If all colors are used, the first color will be used // again. The formatter for the associated color will then be returned by `Pick` each // time it is called for the artifact and can be used to write to out in that color. -func NewColorPicker(artifacts []*v1alpha2.Artifact) ColorPicker { +func NewColorPicker(artifacts []*v1alpha3.Artifact) ColorPicker { c := colorPicker{imageColors: map[string]color.Color{}} for i, artifact := range artifacts { c.imageColors[artifact.ImageName] = colorCodes[i%len(colorCodes)] diff --git a/pkg/skaffold/kubernetes/colorpicker_test.go b/pkg/skaffold/kubernetes/colorpicker_test.go index 8eee5b28252..264b413fdba 100644 --- a/pkg/skaffold/kubernetes/colorpicker_test.go +++ b/pkg/skaffold/kubernetes/colorpicker_test.go @@ -20,7 +20,7 @@ import ( "testing" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/color" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" v1 "k8s.io/api/core/v1" ) @@ -70,7 +70,7 @@ func TestColorPicker(t *testing.T) { }, } - picker := NewColorPicker([]*v1alpha2.Artifact{ + picker := NewColorPicker([]*v1alpha3.Artifact{ {ImageName: "image"}, {ImageName: "second"}, }) diff --git a/pkg/skaffold/runner/changes.go b/pkg/skaffold/runner/changes.go index caf8cbd6887..4a02496bd82 100644 --- a/pkg/skaffold/runner/changes.go +++ b/pkg/skaffold/runner/changes.go @@ -17,16 +17,16 @@ limitations under the License. package runner import ( - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" ) type changes struct { - dirtyArtifacts []*v1alpha2.Artifact + dirtyArtifacts []*v1alpha3.Artifact needsRedeploy bool needsReload bool } -func (c *changes) Add(a *v1alpha2.Artifact) { +func (c *changes) Add(a *v1alpha3.Artifact) { c.dirtyArtifacts = append(c.dirtyArtifacts, a) } diff --git a/pkg/skaffold/runner/runner.go b/pkg/skaffold/runner/runner.go index fbdd1a496c5..e5830d95e1c 100644 --- a/pkg/skaffold/runner/runner.go +++ b/pkg/skaffold/runner/runner.go @@ -37,7 +37,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes" kubectx "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/context" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/watch" "github.com/pkg/errors" @@ -98,7 +98,7 @@ func NewForConfig(opts *config.SkaffoldOptions, cfg *config.SkaffoldConfig) (*Sk }, nil } -func getBuilder(cfg *v1alpha2.BuildConfig, kubeContext string) (build.Builder, error) { +func getBuilder(cfg *v1alpha3.BuildConfig, kubeContext string) (build.Builder, error) { switch { case cfg.LocalBuild != nil: logrus.Debugf("Using builder: local") @@ -117,7 +117,7 @@ func getBuilder(cfg *v1alpha2.BuildConfig, kubeContext string) (build.Builder, e } } -func getDeployer(cfg *v1alpha2.DeployConfig, kubeContext string, namespace string) (deploy.Deployer, error) { +func getDeployer(cfg *v1alpha3.DeployConfig, kubeContext string, namespace string) (deploy.Deployer, error) { switch { case cfg.KubectlDeploy != nil: // TODO(dgageot): this should be the folder containing skaffold.yaml. Should also be moved elsewhere. @@ -138,7 +138,7 @@ func getDeployer(cfg *v1alpha2.DeployConfig, kubeContext string, namespace strin } } -func getTagger(t v1alpha2.TagPolicy, customTag string) (tag.Tagger, error) { +func getTagger(t v1alpha3.TagPolicy, customTag string) (tag.Tagger, error) { switch { case customTag != "": return &tag.CustomTag{ @@ -163,7 +163,7 @@ func getTagger(t v1alpha2.TagPolicy, customTag string) (tag.Tagger, error) { } // Run builds artifacts and then deploys them. -func (r *SkaffoldRunner) Run(ctx context.Context, out io.Writer, artifacts []*v1alpha2.Artifact) error { +func (r *SkaffoldRunner) Run(ctx context.Context, out io.Writer, artifacts []*v1alpha3.Artifact) error { bRes, err := r.Build(ctx, out, r.Tagger, artifacts) if err != nil { return errors.Wrap(err, "build step") @@ -178,7 +178,7 @@ func (r *SkaffoldRunner) Run(ctx context.Context, out io.Writer, artifacts []*v1 } // TailLogs prints the logs for deployed artifacts. -func (r *SkaffoldRunner) TailLogs(ctx context.Context, out io.Writer, artifacts []*v1alpha2.Artifact, bRes []build.Artifact) error { +func (r *SkaffoldRunner) TailLogs(ctx context.Context, out io.Writer, artifacts []*v1alpha3.Artifact, bRes []build.Artifact) error { if !r.opts.Tail { return nil } @@ -200,7 +200,7 @@ func (r *SkaffoldRunner) TailLogs(ctx context.Context, out io.Writer, artifacts // Dev watches for changes and runs the skaffold build and deploy // pipeline until interrrupted by the user. -func (r *SkaffoldRunner) Dev(ctx context.Context, out io.Writer, artifacts []*v1alpha2.Artifact) ([]build.Artifact, error) { +func (r *SkaffoldRunner) Dev(ctx context.Context, out io.Writer, artifacts []*v1alpha3.Artifact) ([]build.Artifact, error) { imageList := kubernetes.NewImageList() colorPicker := kubernetes.NewColorPicker(artifacts) logger := kubernetes.NewLogAggregator(out, imageList, colorPicker) @@ -307,7 +307,7 @@ func (r *SkaffoldRunner) Dev(ctx context.Context, out io.Writer, artifacts []*v1 return nil, watcher.Run(ctx, PollInterval, onChange) } -func (r *SkaffoldRunner) shouldWatch(artifact *v1alpha2.Artifact) bool { +func (r *SkaffoldRunner) shouldWatch(artifact *v1alpha3.Artifact) bool { if len(r.opts.Watch) == 0 { return true } @@ -349,7 +349,7 @@ func mergeWithPreviousBuilds(builds, previous []build.Artifact) []build.Artifact return merged } -func dependenciesForArtifact(a *v1alpha2.Artifact) ([]string, error) { +func dependenciesForArtifact(a *v1alpha3.Artifact) ([]string, error) { var ( paths []string err error diff --git a/pkg/skaffold/runner/runner_test.go b/pkg/skaffold/runner/runner_test.go index 9fc94ce53ea..96e4f94f797 100644 --- a/pkg/skaffold/runner/runner_test.go +++ b/pkg/skaffold/runner/runner_test.go @@ -30,7 +30,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/config" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/watch" "github.com/GoogleContainerTools/skaffold/testutil" clientgo "k8s.io/client-go/kubernetes" @@ -46,7 +46,7 @@ func (t *TestBuilder) Labels() map[string]string { return map[string]string{} } -func (t *TestBuilder) Build(ctx context.Context, w io.Writer, tagger tag.Tagger, artifacts []*v1alpha2.Artifact) ([]build.Artifact, error) { +func (t *TestBuilder) Build(ctx context.Context, w io.Writer, tagger tag.Tagger, artifacts []*v1alpha3.Artifact) ([]build.Artifact, error) { if len(t.errors) > 0 { err := t.errors[0] t.errors = t.errors[1:] @@ -129,7 +129,7 @@ func (t *TestWatcher) Run(ctx context.Context, pollInterval time.Duration, onCha func TestNewForConfig(t *testing.T) { var tests = []struct { description string - config *v1alpha2.SkaffoldConfig + config *v1alpha3.SkaffoldConfig shouldErr bool expectedBuilder build.Builder expectedDeployer deploy.Deployer @@ -137,15 +137,15 @@ func TestNewForConfig(t *testing.T) { { description: "local builder config", config: &config.SkaffoldConfig{ - Build: v1alpha2.BuildConfig{ - TagPolicy: v1alpha2.TagPolicy{ShaTagger: &v1alpha2.ShaTagger{}}, - BuildType: v1alpha2.BuildType{ - LocalBuild: &v1alpha2.LocalBuild{}, + Build: v1alpha3.BuildConfig{ + TagPolicy: v1alpha3.TagPolicy{ShaTagger: &v1alpha3.ShaTagger{}}, + BuildType: v1alpha3.BuildType{ + LocalBuild: &v1alpha3.LocalBuild{}, }, }, - Deploy: v1alpha2.DeployConfig{ - DeployType: v1alpha2.DeployType{ - KubectlDeploy: &v1alpha2.KubectlDeploy{}, + Deploy: v1alpha3.DeployConfig{ + DeployType: v1alpha3.DeployType{ + KubectlDeploy: &v1alpha3.KubectlDeploy{}, }, }, }, @@ -154,16 +154,16 @@ func TestNewForConfig(t *testing.T) { }, { description: "bad tagger config", - config: &v1alpha2.SkaffoldConfig{ - Build: v1alpha2.BuildConfig{ - TagPolicy: v1alpha2.TagPolicy{}, - BuildType: v1alpha2.BuildType{ - LocalBuild: &v1alpha2.LocalBuild{}, + config: &v1alpha3.SkaffoldConfig{ + Build: v1alpha3.BuildConfig{ + TagPolicy: v1alpha3.TagPolicy{}, + BuildType: v1alpha3.BuildType{ + LocalBuild: &v1alpha3.LocalBuild{}, }, }, - Deploy: v1alpha2.DeployConfig{ - DeployType: v1alpha2.DeployType{ - KubectlDeploy: &v1alpha2.KubectlDeploy{}, + Deploy: v1alpha3.DeployConfig{ + DeployType: v1alpha3.DeployType{ + KubectlDeploy: &v1alpha3.KubectlDeploy{}, }, }, }, @@ -171,8 +171,8 @@ func TestNewForConfig(t *testing.T) { }, { description: "unknown builder", - config: &v1alpha2.SkaffoldConfig{ - Build: v1alpha2.BuildConfig{}, + config: &v1alpha3.SkaffoldConfig{ + Build: v1alpha3.BuildConfig{}, }, shouldErr: true, expectedBuilder: &local.Builder{}, @@ -181,10 +181,10 @@ func TestNewForConfig(t *testing.T) { { description: "unknown tagger", config: &config.SkaffoldConfig{ - Build: v1alpha2.BuildConfig{ - TagPolicy: v1alpha2.TagPolicy{}, - BuildType: v1alpha2.BuildType{ - LocalBuild: &v1alpha2.LocalBuild{}, + Build: v1alpha3.BuildConfig{ + TagPolicy: v1alpha3.TagPolicy{}, + BuildType: v1alpha3.BuildType{ + LocalBuild: &v1alpha3.LocalBuild{}, }, }}, shouldErr: true, @@ -194,10 +194,10 @@ func TestNewForConfig(t *testing.T) { { description: "unknown deployer", config: &config.SkaffoldConfig{ - Build: v1alpha2.BuildConfig{ - TagPolicy: v1alpha2.TagPolicy{ShaTagger: &v1alpha2.ShaTagger{}}, - BuildType: v1alpha2.BuildType{ - LocalBuild: &v1alpha2.LocalBuild{}, + Build: v1alpha3.BuildConfig{ + TagPolicy: v1alpha3.TagPolicy{ShaTagger: &v1alpha3.ShaTagger{}}, + BuildType: v1alpha3.BuildType{ + LocalBuild: &v1alpha3.LocalBuild{}, }, }, }, @@ -229,13 +229,13 @@ func TestRun(t *testing.T) { }{ { description: "run no error", - config: &v1alpha2.SkaffoldConfig{}, + config: &v1alpha3.SkaffoldConfig{}, builder: &TestBuilder{}, deployer: &TestDeployer{}, }, { description: "run build error", - config: &v1alpha2.SkaffoldConfig{}, + config: &v1alpha3.SkaffoldConfig{}, builder: &TestBuilder{ errors: []error{fmt.Errorf("")}, }, @@ -243,9 +243,9 @@ func TestRun(t *testing.T) { }, { description: "run deploy error", - config: &v1alpha2.SkaffoldConfig{ - Build: v1alpha2.BuildConfig{ - Artifacts: []*v1alpha2.Artifact{ + config: &v1alpha3.SkaffoldConfig{ + Build: v1alpha3.BuildConfig{ + Artifacts: []*v1alpha3.Artifact{ { ImageName: "test", }, @@ -350,7 +350,7 @@ func TestBuildAndDeployAllArtifacts(t *testing.T) { builder := &TestBuilder{} deployer := &TestDeployer{} - artifacts := []*v1alpha2.Artifact{ + artifacts := []*v1alpha3.Artifact{ {ImageName: "image1"}, {ImageName: "image2"}, } @@ -433,7 +433,7 @@ func TestShouldWatch(t *testing.T) { }, } - match := runner.shouldWatch(&v1alpha2.Artifact{ + match := runner.shouldWatch(&v1alpha3.Artifact{ ImageName: "domain/image", }) diff --git a/pkg/skaffold/runner/timings.go b/pkg/skaffold/runner/timings.go index e11002d8443..51cc589f1ae 100644 --- a/pkg/skaffold/runner/timings.go +++ b/pkg/skaffold/runner/timings.go @@ -25,7 +25,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/tag" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/color" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/deploy" - "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha3" ) // WithTimings creates a deployer that logs the duration of each phase. @@ -43,7 +43,7 @@ type withTimings struct { deploy.Deployer } -func (w withTimings) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha2.Artifact) ([]build.Artifact, error) { +func (w withTimings) Build(ctx context.Context, out io.Writer, tagger tag.Tagger, artifacts []*v1alpha3.Artifact) ([]build.Artifact, error) { start := time.Now() color.Default.Fprintln(out, "Starting build...") diff --git a/pkg/skaffold/schema/transform.go b/pkg/skaffold/schema/transform.go index 28310b5f4b0..03c1ac74290 100644 --- a/pkg/skaffold/schema/transform.go +++ b/pkg/skaffold/schema/transform.go @@ -23,6 +23,7 @@ import ( "github.com/GoogleContainerTools/skaffold/pkg/skaffold/config/transform" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha1" + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/v1alpha2" "github.com/pkg/errors" ) @@ -33,6 +34,7 @@ type Transform func(vc util.VersionedConfig) (util.VersionedConfig, error) // since the last schema version should not have a transform var transformers = map[string]Transform{ v1alpha1.Version: transform.ToV1Alpha2, + v1alpha2.Version: transform.ToV1Alpha3, } func RunTransform(vc util.VersionedConfig) (util.VersionedConfig, error) { diff --git a/pkg/skaffold/schema/v1alpha3/config.go b/pkg/skaffold/schema/v1alpha3/config.go new file mode 100644 index 00000000000..8028b52804f --- /dev/null +++ b/pkg/skaffold/schema/v1alpha3/config.go @@ -0,0 +1,251 @@ +/* +Copyright 2018 The Skaffold Authors + +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 v1alpha3 + +import ( + "github.com/pkg/errors" + yaml "gopkg.in/yaml.v2" +) + +const Version string = "skaffold/v1alpha3" + +type SkaffoldConfig struct { + APIVersion string `yaml:"apiVersion"` + Kind string `yaml:"kind"` + + Build BuildConfig `yaml:"build,omitempty"` + Deploy DeployConfig `yaml:"deploy,omitempty"` + Profiles []Profile `yaml:"profiles,omitempty"` +} + +func (c *SkaffoldConfig) GetVersion() string { + return c.APIVersion +} + +// BuildConfig contains all the configuration for the build steps +type BuildConfig struct { + Artifacts []*Artifact `yaml:"artifacts,omitempty"` + TagPolicy TagPolicy `yaml:"tagPolicy,omitempty"` + BuildType `yaml:",inline"` +} + +// TagPolicy contains all the configuration for the tagging step +type TagPolicy struct { + GitTagger *GitTagger `yaml:"gitCommit,omitempty" yamltags:"oneOf=tag"` + ShaTagger *ShaTagger `yaml:"sha256,omitempty" yamltags:"oneOf=tag"` + EnvTemplateTagger *EnvTemplateTagger `yaml:"envTemplate,omitempty" yamltags:"oneOf=tag"` + DateTimeTagger *DateTimeTagger `yaml:"dateTime,omitempty" yamltags:"oneOf=tag"` +} + +// ShaTagger contains the configuration for the SHA tagger. +type ShaTagger struct{} + +// GitTagger contains the configuration for the git tagger. +type GitTagger struct{} + +// EnvTemplateTagger contains the configuration for the envTemplate tagger. +type EnvTemplateTagger struct { + Template string `yaml:"template"` +} + +// DateTimeTagger contains the configuration for the DateTime tagger. +type DateTimeTagger struct { + Format string `yaml:"format,omitempty"` + TimeZone string `yaml:"timezone,omitempty"` +} + +// BuildType contains the specific implementation and parameters needed +// for the build step. Only one field should be populated. +type BuildType struct { + LocalBuild *LocalBuild `yaml:"local,omitempty" yamltags:"oneOf=build"` + GoogleCloudBuild *GoogleCloudBuild `yaml:"googleCloudBuild,omitempty" yamltags:"oneOf=build"` + KanikoBuild *KanikoBuild `yaml:"kaniko,omitempty" yamltags:"oneOf=build"` +} + +// LocalBuild contains the fields needed to do a build on the local docker daemon +// and optionally push to a repository. +type LocalBuild struct { + SkipPush *bool `yaml:"skipPush,omitempty"` + UseDockerCLI bool `yaml:"useDockerCLI,omitempty"` + UseBuildkit bool `yaml:"useBuildkit,omitempty"` +} + +// GoogleCloudBuild contains the fields needed to do a remote build on +// Google Cloud Build. +type GoogleCloudBuild struct { + ProjectID string `yaml:"projectId"` + DiskSizeGb int64 `yaml:"diskSizeGb,omitempty"` + MachineType string `yaml:"machineType,omitempty"` + Timeout string `yaml:"timeout,omitempty"` + DockerImage string `yaml:"dockerImage,omitempty"` +} + +// KanikoBuildContext contains the different fields available to specify +// a kaniko build context +type KanikoBuildContext struct { + GCSBucket string `yaml:"gcsBucket,omitempty" yamltags:"oneOf=buildContext"` +} + +// KanikoBuild contains the fields needed to do a on-cluster build using +// the kaniko image +type KanikoBuild struct { + BuildContext KanikoBuildContext `yaml:"buildContext,omitempty"` + PullSecret string `yaml:"pullSecret,omitempty"` + PullSecretName string `yaml:"pullSecretName,omitempty"` + Namespace string `yaml:"namespace,omitempty"` + Timeout string `yaml:"timeout,omitempty"` +} + +// DeployConfig contains all the configuration needed by the deploy steps +type DeployConfig struct { + DeployType `yaml:",inline"` +} + +// DeployType contains the specific implementation and parameters needed +// for the deploy step. Only one field should be populated. +type DeployType struct { + HelmDeploy *HelmDeploy `yaml:"helm,omitempty" yamltags:"oneOf=deploy"` + KubectlDeploy *KubectlDeploy `yaml:"kubectl,omitempty" yamltags:"oneOf=deploy"` + KustomizeDeploy *KustomizeDeploy `yaml:"kustomize,omitempty" yamltags:"oneOf=deploy"` +} + +// KubectlDeploy contains the configuration needed for deploying with `kubectl apply` +type KubectlDeploy struct { + Manifests []string `yaml:"manifests,omitempty"` + RemoteManifests []string `yaml:"remoteManifests,omitempty"` + Flags KubectlFlags `yaml:"flags,omitempty"` +} + +// KubectlFlags describes additional options flags that are passed on the command +// line to kubectl either on every command (Global), on creations (Apply) +// or deletions (Delete). +type KubectlFlags struct { + Global []string `yaml:"global,omitempty"` + Apply []string `yaml:"apply,omitempty"` + Delete []string `yaml:"delete,omitempty"` +} + +// HelmDeploy contains the configuration needed for deploying with helm +type HelmDeploy struct { + Releases []HelmRelease `yaml:"releases,omitempty"` +} + +type KustomizeDeploy struct { + KustomizePath string `yaml:"kustomizePath,omitempty"` + Flags KubectlFlags `yaml:"flags,omitempty"` +} + +type HelmRelease struct { + Name string `yaml:"name"` + ChartPath string `yaml:"chartPath"` + ValuesFilePath string `yaml:"valuesFilePath"` + Values map[string]string `yaml:"values,omitempty"` + Namespace string `yaml:"namespace"` + Version string `yaml:"version"` + SetValues map[string]string `yaml:"setValues"` + SetValueTemplates map[string]string `yaml:"setValueTemplates"` + Wait bool `yaml:"wait"` + RecreatePods bool `yaml:"recreatePods"` + Overrides map[string]interface{} `yaml:"overrides"` + Packaged *HelmPackaged `yaml:"packaged"` + ImageStrategy HelmImageStrategy `yaml:"imageStrategy"` +} + +// HelmPackaged represents parameters for packaging helm chart. +type HelmPackaged struct { + // Version sets the version on the chart to this semver version. + Version string `yaml:"version"` + + // AppVersion set the appVersion on the chart to this version + AppVersion string `yaml:"appVersion"` +} + +type HelmImageStrategy struct { + HelmImageConfig `yaml:",inline"` +} + +type HelmImageConfig struct { + HelmFQNConfig *HelmFQNConfig `yaml:"fqn"` + HelmConventionConfig *HelmConventionConfig `yaml:"helm"` +} + +// HelmFQNConfig represents image config to use the FullyQualifiedImageName as param to set +type HelmFQNConfig struct { + Property string `yaml:"property"` +} + +// HelmConventionConfig represents image config in the syntax of image.repository and image.tag +type HelmConventionConfig struct { +} + +// Artifact represents items that need to be built, along with the context in which +// they should be built. +type Artifact struct { + ImageName string `yaml:"imageName"` + Workspace string `yaml:"workspace,omitempty"` + ArtifactType `yaml:",inline"` +} + +// Profile is additional configuration that overrides default +// configuration when it is activated. +type Profile struct { + Name string `yaml:"name"` + Build BuildConfig `yaml:"build,omitempty"` + Deploy DeployConfig `yaml:"deploy,omitempty"` +} + +type ArtifactType struct { + DockerArtifact *DockerArtifact `yaml:"docker,omitempty" yamltags:"oneOf=artifact"` + BazelArtifact *BazelArtifact `yaml:"bazel,omitempty" yamltags:"oneOf=artifact"` +} + +type DockerArtifact struct { + DockerfilePath string `yaml:"dockerfilePath,omitempty"` + BuildArgs map[string]*string `yaml:"buildArgs,omitempty"` + CacheFrom []string `yaml:"cacheFrom,omitempty"` + Target string `yaml:"target,omitempty"` +} + +type BazelArtifact struct { + BuildTarget string `yaml:"target"` +} + +// Parse reads a SkaffoldConfig from yaml. +func (c *SkaffoldConfig) Parse(contents []byte, useDefaults bool) error { + if err := yaml.UnmarshalStrict(contents, c); err != nil { + return err + } + + if useDefaults { + if err := c.setDefaultValues(); err != nil { + return errors.Wrap(err, "applying default values") + } + } + + return nil +} + +func NewConfig() (*SkaffoldConfig, error) { + cfg := &SkaffoldConfig{} + if err := cfg.setBaseDefaultValues(); err != nil { + return nil, err + } + if err := cfg.setDefaultValues(); err != nil { + return nil, err + } + return cfg, nil +} diff --git a/pkg/skaffold/schema/v1alpha3/defaults.go b/pkg/skaffold/schema/v1alpha3/defaults.go new file mode 100644 index 00000000000..965f6abf0b8 --- /dev/null +++ b/pkg/skaffold/schema/v1alpha3/defaults.go @@ -0,0 +1,195 @@ +/* +Copyright 2018 The Skaffold Authors + +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 v1alpha3 + +import ( + "fmt" + + homedir "github.com/mitchellh/go-homedir" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/constants" + kubectx "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/context" +) + +func (c *SkaffoldConfig) setBaseDefaultValues() error { + c.APIVersion = Version + c.Kind = "Config" + return nil +} + +func (c *SkaffoldConfig) setDefaultValues() error { + c.defaultToLocalBuild() + c.defaultToKubectlDeploy() + c.setDefaultCloudBuildDockerImage() + c.setDefaultTagger() + c.setDefaultKustomizePath() + c.setDefaultKubectlManifests() + c.setDefaultKanikoTimeout() + if err := c.setDefaultKanikoNamespace(); err != nil { + return err + } + if err := c.setDefaultKanikoSecret(); err != nil { + return err + } + + for _, a := range c.Build.Artifacts { + c.defaultToDockerArtifact(a) + c.setDefaultDockerfile(a) + c.setDefaultWorkspace(a) + } + + return nil +} + +func (c *SkaffoldConfig) defaultToLocalBuild() { + if c.Build.BuildType != (BuildType{}) { + return + } + + logrus.Debugf("Defaulting build type to local build") + c.Build.BuildType.LocalBuild = &LocalBuild{} +} + +func (c *SkaffoldConfig) defaultToKubectlDeploy() { + if c.Deploy.DeployType != (DeployType{}) { + return + } + + logrus.Debugf("Defaulting deploy type to kubectl") + c.Deploy.DeployType.KubectlDeploy = &KubectlDeploy{} +} + +func (c *SkaffoldConfig) setDefaultCloudBuildDockerImage() { + cloudBuild := c.Build.BuildType.GoogleCloudBuild + if cloudBuild == nil { + return + } + + if cloudBuild.DockerImage == "" { + cloudBuild.DockerImage = constants.DefaultCloudBuildDockerImage + } +} + +func (c *SkaffoldConfig) setDefaultTagger() { + if c.Build.TagPolicy != (TagPolicy{}) { + return + } + + c.Build.TagPolicy = TagPolicy{GitTagger: &GitTagger{}} +} + +func (c *SkaffoldConfig) setDefaultKustomizePath() { + if c.Deploy.KustomizeDeploy != nil && c.Deploy.KustomizeDeploy.KustomizePath == "" { + c.Deploy.KustomizeDeploy.KustomizePath = constants.DefaultKustomizationPath + } +} + +func (c *SkaffoldConfig) setDefaultKubectlManifests() { + if c.Deploy.KubectlDeploy != nil && len(c.Deploy.KubectlDeploy.Manifests) == 0 { + c.Deploy.KubectlDeploy.Manifests = constants.DefaultKubectlManifests + } +} + +func (c *SkaffoldConfig) defaultToDockerArtifact(a *Artifact) { + if a.ArtifactType == (ArtifactType{}) { + a.ArtifactType = ArtifactType{ + DockerArtifact: &DockerArtifact{}, + } + } +} + +func (c *SkaffoldConfig) setDefaultDockerfile(a *Artifact) { + if a.DockerArtifact != nil && a.DockerArtifact.DockerfilePath == "" { + a.DockerArtifact.DockerfilePath = constants.DefaultDockerfilePath + } +} + +func (c *SkaffoldConfig) setDefaultWorkspace(a *Artifact) { + if a.Workspace == "" { + a.Workspace = "." + } +} + +func (c *SkaffoldConfig) setDefaultKanikoNamespace() error { + kaniko := c.Build.KanikoBuild + if kaniko == nil { + return nil + } + + if kaniko.Namespace == "" { + ns, err := currentNamespace() + if err != nil { + return errors.Wrap(err, "getting current namespace") + } + + kaniko.Namespace = ns + } + + return nil +} + +func (c *SkaffoldConfig) setDefaultKanikoTimeout() { + kaniko := c.Build.KanikoBuild + if kaniko == nil { + return + } + + if kaniko.Timeout == "" { + kaniko.Timeout = constants.DefaultKanikoTimeout + } +} + +func (c *SkaffoldConfig) setDefaultKanikoSecret() error { + kaniko := c.Build.KanikoBuild + if kaniko == nil { + return nil + } + + if kaniko.PullSecretName == "" { + kaniko.PullSecretName = constants.DefaultKanikoSecretName + } + + if kaniko.PullSecret != "" { + absPath, err := homedir.Expand(kaniko.PullSecret) + if err != nil { + return fmt.Errorf("unable to expand pullSecret %s", kaniko.PullSecret) + } + + kaniko.PullSecret = absPath + return nil + } + + return nil +} + +func currentNamespace() (string, error) { + cfg, err := kubectx.CurrentConfig() + if err != nil { + return "", err + } + + current, present := cfg.Contexts[cfg.CurrentContext] + if present { + if current.Namespace != "" { + return current.Namespace, nil + } + } + + return "default", nil +} diff --git a/pkg/skaffold/schema/v1alpha3/profiles.go b/pkg/skaffold/schema/v1alpha3/profiles.go new file mode 100644 index 00000000000..224827e77b3 --- /dev/null +++ b/pkg/skaffold/schema/v1alpha3/profiles.go @@ -0,0 +1,125 @@ +/* +Copyright 2018 The Skaffold Authors + +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 v1alpha3 + +import ( + "fmt" + "reflect" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + + "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/util" +) + +// ApplyProfiles returns configuration modified by the application +// of a list of profiles. +func (c *SkaffoldConfig) ApplyProfiles(profiles []string) error { + byName := profilesByName(c.Profiles) + for _, name := range profiles { + profile, present := byName[name] + if !present { + return fmt.Errorf("couldn't find profile %s", name) + } + + applyProfile(c, profile) + } + if err := c.setDefaultValues(); err != nil { + return errors.Wrap(err, "applying default values") + } + + return nil +} + +func applyProfile(config *SkaffoldConfig, profile Profile) { + logrus.Infof("applying profile: %s", profile.Name) + + // this intentionally removes the Profiles field from the returned config + *config = SkaffoldConfig{ + APIVersion: config.APIVersion, + Kind: config.Kind, + Build: overlayProfileField(config.Build, profile.Build).(BuildConfig), + Deploy: overlayProfileField(config.Deploy, profile.Deploy).(DeployConfig), + } +} + +func profilesByName(profiles []Profile) map[string]Profile { + byName := make(map[string]Profile) + for _, profile := range profiles { + byName[profile.Name] = profile + } + return byName +} + +// if we find a oneOf tag, the fields in this struct are themselves pointers to structs, +// but should be treated as values. the first non-nil one we find is what we should use. +func overlayOneOfField(config interface{}, profile interface{}) interface{} { + v := reflect.ValueOf(profile) // the profile itself + t := reflect.TypeOf(profile) // the type of the profile, used for getting struct field types + for i := 0; i < v.NumField(); i++ { + fieldType := t.Field(i) // the field type (e.g. 'LocalBuild' for BuildConfig) + fieldValue := v.Field(i).Interface() // the value of the field itself + + if fieldValue != nil && !reflect.ValueOf(fieldValue).IsNil() { + ret := reflect.New(t) // New(t) returns a Value representing pointer to new zero value for type t + ret.Elem().FieldByName(fieldType.Name).Set(reflect.ValueOf(fieldValue)) // set the value + return reflect.Indirect(ret).Interface() // since ret is a pointer, dereference it + } + } + // if we're here, we didn't find any values set in the profile config. just return the original. + logrus.Infof("no values found in profile for field %s, using original config values", t.Name()) + return config +} + +func overlayStructField(config interface{}, profile interface{}) interface{} { + // we already know the top level fields for whatever struct we have are themselves structs + // (and not one-of values), so we need to recursively overlay them + configValue := reflect.ValueOf(config) + profileValue := reflect.ValueOf(profile) + t := reflect.TypeOf(profile) + finalConfig := reflect.New(t) + + for i := 0; i < profileValue.NumField(); i++ { + fieldType := t.Field(i) + overlay := overlayProfileField(configValue.Field(i).Interface(), profileValue.Field(i).Interface()) + finalConfig.Elem().FieldByName(fieldType.Name).Set(reflect.ValueOf(overlay)) + } + return reflect.Indirect(finalConfig).Interface() // since finalConfig is a pointer, dereference it +} + +func overlayProfileField(config interface{}, profile interface{}) interface{} { + v := reflect.ValueOf(profile) // the profile itself + t := reflect.TypeOf(profile) // the type of the profile, used for getting struct field types + logrus.Debugf("overlaying profile on config for field %s", t.Name()) + switch v.Kind() { + case reflect.Struct: + // check the first field of the struct for a oneOf yamltag. + if util.IsOneOf(t.Field(0)) { + return overlayOneOfField(config, profile) + } + return overlayStructField(config, profile) + case reflect.Slice: + // either return the values provided in the profile, or the original values if none were provided. + if v.Len() == 0 { + return config + } + return v.Interface() + default: + logrus.Warnf("unknown field type in profile overlay: %s. falling back to original config values", v.Kind()) + return config + } +} diff --git a/skaffold.yaml b/skaffold.yaml index cde7040e532..c8fd93c6c19 100644 --- a/skaffold.yaml +++ b/skaffold.yaml @@ -1,4 +1,4 @@ -apiVersion: skaffold/v1alpha2 +apiVersion: skaffold/v1alpha3 kind: Config build: artifacts: From 532f48c45affae563722f1c06675e07cad7d5d94 Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Thu, 13 Sep 2018 15:44:03 -0700 Subject: [PATCH 2/3] Added integration test to test skaffold fix with v1alpha3 --- examples/kaniko/pod.yaml | 45 ------------------- integration/run_test.go | 45 +++++++++++++------ .../{old-config => v1alpha1}/Dockerfile | 0 .../{old-config => v1alpha1}/k8s-pod.yaml | 0 .../testdata/{old-config => v1alpha1}/main.go | 0 .../{old-config => v1alpha1}/skaffold.yaml | 0 integration/testdata/v1alpha2/Dockerfile | 6 +++ integration/testdata/v1alpha2/k8s-pod.yaml | 8 ++++ integration/testdata/v1alpha2/main.go | 13 ++++++ integration/testdata/v1alpha2/skaffold.yaml | 13 ++++++ 10 files changed, 71 insertions(+), 59 deletions(-) delete mode 100644 examples/kaniko/pod.yaml rename integration/testdata/{old-config => v1alpha1}/Dockerfile (100%) rename integration/testdata/{old-config => v1alpha1}/k8s-pod.yaml (100%) rename integration/testdata/{old-config => v1alpha1}/main.go (100%) rename integration/testdata/{old-config => v1alpha1}/skaffold.yaml (100%) create mode 100644 integration/testdata/v1alpha2/Dockerfile create mode 100644 integration/testdata/v1alpha2/k8s-pod.yaml create mode 100644 integration/testdata/v1alpha2/main.go create mode 100644 integration/testdata/v1alpha2/skaffold.yaml diff --git a/examples/kaniko/pod.yaml b/examples/kaniko/pod.yaml deleted file mode 100644 index 0627014e862..00000000000 --- a/examples/kaniko/pod.yaml +++ /dev/null @@ -1,45 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: kaniko -spec: - initContainers: - - name: init-container - image: ubuntu - args: ["sh", "-c", "cp -L -r /kaniko/buildcontext/* /kaniko/emptydir && ls /kaniko/emptydir && stat /kaniko/emptydir/Dockerfile"] - volumeMounts: - - name: build-context - mountPath: /kaniko/buildcontext - - name: empty-dir - mountPath: /kaniko/emptydir - containers: - - name: kaniko - image: gcr.io/kaniko-project/executor:latest - args: ["--dockerfile=Dockerfile", - "--context=dir:///kaniko/emptydir", - "--destination=gcr.io/priya-wadhwa/test:test"] - volumeMounts: - - name: kaniko-secret - mountPath: /secret - - name: build-context - mountPath: /kaniko/buildcontext - - name: empty-dir - mountPath: /kaniko/emptydir - env: - - name: GOOGLE_APPLICATION_CREDENTIALS - value: /secret/kaniko-secret.json - restartPolicy: Never - volumes: - - name: kaniko-secret - secret: - secretName: kaniko - # - name: build-context - # persistentVolumeClaim: - # claimName: pv-claim-kaniko - - name: build-context - configMap: - # Provide the name of the ConfigMap containing the files you want - # to add to the container - name: kaniko-configmap77a0c64f84c48aeb56093119c709807b - - name: empty-dir - emptyDir: {} diff --git a/integration/run_test.go b/integration/run_test.go index 7b0f3b9200c..76e17642cbc 100644 --- a/integration/run_test.go +++ b/integration/run_test.go @@ -221,22 +221,39 @@ func setupNamespace(t *testing.T) (*v1.Namespace, func()) { } } func TestFix(t *testing.T) { - ns, deleteNs := setupNamespace(t) - defer deleteNs() - - fixCmd := exec.Command("skaffold", "fix", "-f", "skaffold.yaml") - fixCmd.Dir = "testdata/old-config" - out, err := util.RunCmdOut(fixCmd) - if err != nil { - t.Fatalf("testing error: %v", err) + tests := []struct { + name string + directory string + }{ + { + name: "test v1alpha1 to v1alpha2 fix", + directory: "testdata/v1alpha1", + }, + { + name: "test v1alpha2 to v1alpha3 kaniko fix", + directory: "testdata/v1alpha2", + }, } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + ns, deleteNs := setupNamespace(t) + defer deleteNs() - runCmd := exec.Command("skaffold", "run", "--namespace", ns.Name, "-f", "-") - runCmd.Dir = "testdata/old-config" - runCmd.Stdin = bytes.NewReader(out) - err = util.RunCmd(runCmd) - if err != nil { - t.Fatalf("testing error: %v", err) + fixCmd := exec.Command("skaffold", "fix", "-f", "skaffold.yaml") + fixCmd.Dir = test.directory + out, err := util.RunCmdOut(fixCmd) + if err != nil { + t.Fatalf("testing error: %v", err) + } + + runCmd := exec.Command("skaffold", "run", "--namespace", ns.Name, "-f", "-") + runCmd.Dir = test.directory + runCmd.Stdin = bytes.NewReader(out) + err = util.RunCmd(runCmd) + if err != nil { + t.Fatalf("testing error: %v", err) + } + }) } } diff --git a/integration/testdata/old-config/Dockerfile b/integration/testdata/v1alpha1/Dockerfile similarity index 100% rename from integration/testdata/old-config/Dockerfile rename to integration/testdata/v1alpha1/Dockerfile diff --git a/integration/testdata/old-config/k8s-pod.yaml b/integration/testdata/v1alpha1/k8s-pod.yaml similarity index 100% rename from integration/testdata/old-config/k8s-pod.yaml rename to integration/testdata/v1alpha1/k8s-pod.yaml diff --git a/integration/testdata/old-config/main.go b/integration/testdata/v1alpha1/main.go similarity index 100% rename from integration/testdata/old-config/main.go rename to integration/testdata/v1alpha1/main.go diff --git a/integration/testdata/old-config/skaffold.yaml b/integration/testdata/v1alpha1/skaffold.yaml similarity index 100% rename from integration/testdata/old-config/skaffold.yaml rename to integration/testdata/v1alpha1/skaffold.yaml diff --git a/integration/testdata/v1alpha2/Dockerfile b/integration/testdata/v1alpha2/Dockerfile new file mode 100644 index 00000000000..2d107918ad0 --- /dev/null +++ b/integration/testdata/v1alpha2/Dockerfile @@ -0,0 +1,6 @@ +FROM gcr.io/google-appengine/golang + +WORKDIR /go/src/github.com/GoogleCloudPlatform/skaffold +CMD ["./app"] +COPY main.go . +RUN go build -o app main.go diff --git a/integration/testdata/v1alpha2/k8s-pod.yaml b/integration/testdata/v1alpha2/k8s-pod.yaml new file mode 100644 index 00000000000..df436eb186b --- /dev/null +++ b/integration/testdata/v1alpha2/k8s-pod.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Pod +metadata: + name: getting-started-kaniko +spec: + containers: + - name: getting-started + image: gcr.io/k8s-skaffold/skaffold-example diff --git a/integration/testdata/v1alpha2/main.go b/integration/testdata/v1alpha2/main.go new file mode 100644 index 00000000000..64b7bdfc4a1 --- /dev/null +++ b/integration/testdata/v1alpha2/main.go @@ -0,0 +1,13 @@ +package main + +import ( + "fmt" + "time" +) + +func main() { + for { + fmt.Println("Hello world!") + time.Sleep(time.Second * 1) + } +} diff --git a/integration/testdata/v1alpha2/skaffold.yaml b/integration/testdata/v1alpha2/skaffold.yaml new file mode 100644 index 00000000000..1b81d4a523d --- /dev/null +++ b/integration/testdata/v1alpha2/skaffold.yaml @@ -0,0 +1,13 @@ +apiVersion: skaffold/v1alpha2 +kind: Config +build: + artifacts: + - imageName: gcr.io/k8s-skaffold/skaffold-example + kaniko: + gcsBucket: skaffold-kaniko + pullSecretName: e2esecret + namespace: default +deploy: + kubectl: + manifests: + - k8s-* From 6ed0663bff6a460f1d486209b8ada286c105d437 Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Thu, 13 Sep 2018 16:03:38 -0700 Subject: [PATCH 3/3] fix code review nit --- integration/run_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/run_test.go b/integration/run_test.go index 76e17642cbc..e834a1b98ab 100644 --- a/integration/run_test.go +++ b/integration/run_test.go @@ -230,7 +230,7 @@ func TestFix(t *testing.T) { directory: "testdata/v1alpha1", }, { - name: "test v1alpha2 to v1alpha3 kaniko fix", + name: "test v1alpha2 to v1alpha3 fix", directory: "testdata/v1alpha2", }, }