Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ImageOptions to artifact builder. #4467

Closed
wants to merge 6 commits into from

Conversation

gsquared94
Copy link
Contributor

@gsquared94 gsquared94 commented Jul 14, 2020

Fixes: #4370

Description

This PR introduces ImageOptions to the different builders and currently only partially implements it for docker builder and buildpacks.
It recognizes Dev and Debug as build configurations and passes different build args like GO_GCFLAGS when building the artifact for debug vs dev. It also updates hashcode formula for image caching so that images for Dev vs Debug are cached separately.

User facing changes (remove if N/A)

Dockerfile can expose ARG SKAFFOLD_GO_GCFLAGS and ARG SKAFFOLD_GO_LDFLAGS and expect Skaffold to supply meaningful values.
Buildpacks auto set GOOGLE_GCFLAGS and GOOGLE_LDFLAGS (so far).

Note: The artifact cached during skaffold dev will have a different hashcode than skaffold debug for all builders going forward

@gsquared94 gsquared94 added this to the v1.13.0 milestone Jul 14, 2020
Copy link
Member

@briandealwis briandealwis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is looking good. We should endeavour to remove global state. As a trial, it would also be worth ading the capability to the buildpacks builder, specifically to set the GOOGLE_GOGCFLAGS and GOOGLE_GOLDFLAGS.

type Configuration int

const (
Release = iota
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should also include Dev here, to differentiate between build, dev, and debug.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed this to only have Dev and Debug since I also use this parameter in calculating cache hashcode. So having separate Build type would cause the image built by skaffold build not to be used for next skaffold dev

// FIXME: Tag should be []string but we don't support multiple tags yet
Tag string // image tag
Configuration Configuration // build image for release or debug
Args map[string]*string // additional builder specific args
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we call this BuilderArgs? The rest of these options are not specific around the builder.

(What do you envision this for? How would it be set? How is it different from the Docker artifact-builder's buildArgs?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've renamed it to BuildArgs.
The way I see this being used is in differentiating parameters that could influence build between the different skaffold actions like Dev, Build or Debug. Since skaffold.yaml doesn't have sections for these in case there are different settings required those can be put in this generic map. Whichever builder understands that setting would utilize it. This way since the setting affects the built image it also participates in cache hashcode calculation. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A concrete example could be to push the buildpacks builder image digest to this map so that if that changes it invalidates the cache. That'd solve this TODO:
image

pkg/skaffold/build/options.go Outdated Show resolved Hide resolved
pkg/skaffold/build/options.go Outdated Show resolved Hide resolved
@@ -112,3 +113,11 @@ func (b *Builder) getImageIDForTag(ctx context.Context, tag string) (string, err
}
return insp.ID, nil
}

func ToDockerOpts(opts *build.ImageOptions) *docker.BuildOptions {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be done in the docker builder itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushing ImageOptions into any of the actual builder implementations causes an import cycle (you had predicted this!). So I've defined ImageOptions as the generic builder-agnostic options object. The different builders define their own options object in their respective adapter package.

@@ -86,19 +87,19 @@ func (b *Builder) runBuildForArtifact(ctx context.Context, out io.Writer, a *lat

switch {
case a.DockerArtifact != nil:
return b.buildDocker(ctx, out, a, tag)
return b.buildDocker(ctx, out, a, ToDockerOpts(opts))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like this ImageOptions should be passed down into the builders.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from above

Pushing ImageOptions into any of the actual builder implementations causes an import cycle (you had predicted this!). So I've defined ImageOptions as the generic builder-agnostic options object. The different builders define their own options object in their respective adapter package.

pkg/skaffold/build/local/local.go Outdated Show resolved Hide resolved
pkg/skaffold/docker/options.go Outdated Show resolved Hide resolved
@codecov
Copy link

codecov bot commented Jul 15, 2020

Codecov Report

Merging #4467 into master will decrease coverage by 0.03%.
The diff coverage is 62.16%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #4467      +/-   ##
==========================================
- Coverage   72.22%   72.18%   -0.04%     
==========================================
  Files         329      336       +7     
  Lines       12850    13038     +188     
==========================================
+ Hits         9281     9412     +131     
- Misses       2976     3023      +47     
- Partials      593      603      +10     
Impacted Files Coverage Δ
pkg/skaffold/build/build.go 0.00% <ø> (ø)
pkg/skaffold/build/cluster/cluster.go 27.27% <0.00%> (ø)
pkg/skaffold/build/gcb/cloud_build.go 0.00% <0.00%> (ø)
pkg/skaffold/build/buildpacks/options.go 8.00% <8.00%> (ø)
pkg/skaffold/build/local/local.go 56.60% <52.17%> (-6.19%) ⬇️
pkg/skaffold/docker/options.go 56.00% <56.00%> (ø)
pkg/skaffold/build/cache/hash.go 74.69% <60.00%> (-1.26%) ⬇️
pkg/skaffold/build/buildpacks/build.go 77.77% <66.66%> (ø)
pkg/skaffold/build/options.go 66.66% <66.66%> (ø)
pkg/skaffold/build/buildpacks/lifecycle.go 82.92% <83.33%> (-0.83%) ⬇️
... and 42 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6b8b50a...538d50b. Read the comment docs.

@gsquared94 gsquared94 marked this pull request as ready for review July 17, 2020 22:31
@gsquared94 gsquared94 requested a review from a team as a code owner July 17, 2020 22:31
ARG GOGCFLAGS
RUN eval go build "${GOGCFLAGS}" -o /app .
ARG SKAFFOLD_GO_GCFLAGS
ARG SKAFFOLD_LD_GCFLAGS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be SKAFFOLD_GO_LDFLAGS

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😅 🤦🏽‍♂️

@@ -89,6 +90,13 @@ func getHashForArtifact(ctx context.Context, depLister DependencyLister, a *late
inputs = append(inputs, evaluatedEnv...)
}

// add image options hash
h, err := opts.Hash()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it would be nice if builders that have no change between build, dev, and debug would not need a rebuild. So buildpacks would need a rebuild between build and dev, but docker wouldn't.

@@ -1,6 +1,11 @@
FROM golang:1.12.9-alpine3.10 as builder

# These flag values are provided when building for debug
ARG SKAFFOLD_GO_GCFLAGS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't die on this hill, but this is really supposed to be the most minimal possible example, so this is kind of straying from that. maybe these can go in another example for debug? I don't care too much though

@@ -0,0 +1,82 @@
/*
Copyright 2019 The Skaffold Authors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Copyright 2019 The Skaffold Authors
Copyright 2020 The Skaffold Authors

@gsquared94
Copy link
Contributor Author

Closing in favor of #4606

@gsquared94 gsquared94 closed this Jul 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Skaffold helps build debuggable containers
4 participants