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 dockerfile to custom dependencies #2049

Merged
merged 2 commits into from
May 8, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions docs/content/en/schemas/v1beta10.json
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,11 @@
},
"CustomDependencies": {
"properties": {
"dockerfile": {
"$ref": "#/definitions/DockerfileDependency",
"description": "should be set if the artifact is built from a Dockerfile, from which skaffold can determine dependencies.",
"x-intellij-html-description": "should be set if the artifact is built from a Dockerfile, from which skaffold can determine dependencies."
},
"ignore": {
"items": {
"type": "string"
Expand All @@ -615,12 +620,13 @@
}
},
"preferredOrder": [
"dockerfile",
"paths",
"ignore"
],
"additionalProperties": false,
"description": "*alpha* used to specify dependencies for an artifact built by a custom build script.",
"x-intellij-html-description": "<em>alpha</em> used to specify dependencies for an artifact built by a custom build script."
"description": "*alpha* used to specify dependencies for an artifact built by a custom build script. Either `dockerfile` or `paths` should be specified for file watching to work as expected.",
"x-intellij-html-description": "<em>alpha</em> used to specify dependencies for an artifact built by a custom build script. Either <code>dockerfile</code> or <code>paths</code> should be specified for file watching to work as expected."
},
"DateTimeTagger": {
"properties": {
Expand Down Expand Up @@ -767,6 +773,40 @@
"description": "contains information about the docker `config.json` to mount.",
"x-intellij-html-description": "contains information about the docker <code>config.json</code> to mount."
},
"DockerfileDependency": {
"properties": {
"buildArgs": {
"additionalProperties": {
"type": "string"
},
"type": "object",
"description": "arguments passed to the docker build. It also accepts environment variables via the go template syntax.",
"x-intellij-html-description": "arguments passed to the docker build. It also accepts environment variables via the go template syntax.",
"default": "{}",
"examples": [
"{\"key1\": \"value1\", \"key2\": \"value2\", \"key3\": \"{{.ENV_VARIABLE}}\"}"
]
},
"path": {
"type": "string",
"description": "locates the Dockerfile relative to workspace.",
"x-intellij-html-description": "locates the Dockerfile relative to workspace."
},
"target": {
"type": "string",
"description": "Dockerfile target name to build.",
"x-intellij-html-description": "Dockerfile target name to build."
}
},
"preferredOrder": [
"path",
"target",
"buildArgs"
],
"additionalProperties": false,
"description": "*alpha* used to specify a custom build artifact that is built from a Dockerfile. This allows skaffold to determine dependencies from the Dockerfile.",
"x-intellij-html-description": "<em>alpha</em> used to specify a custom build artifact that is built from a Dockerfile. This allows skaffold to determine dependencies from the Dockerfile."
},
"EnvTemplateTagger": {
"required": [
"template"
Expand Down
29 changes: 19 additions & 10 deletions pkg/skaffold/build/custom/dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,24 @@ import (
)

// GetDependencies returns dependencies listed for a custom artifact
func GetDependencies(ctx context.Context, workspace string, a *latest.CustomArtifact) ([]string, error) {
files, err := docker.WalkWorkspace(workspace, a.Dependencies.Ignore, a.Dependencies.Paths)
if err != nil {
return nil, errors.Wrapf(err, "walking workspace %s", workspace)
}
var dependencies []string
for file := range files {
dependencies = append(dependencies, file)
func GetDependencies(ctx context.Context, workspace string, a *latest.CustomArtifact, insecureRegistries map[string]bool) ([]string, error) {

switch {
case a.Dependencies.Dockerfile != nil:
dockerfile := a.Dependencies.Dockerfile
return docker.GetDependencies(ctx, workspace, dockerfile.Path, dockerfile.BuildArgs, insecureRegistries)
priyawadhwa marked this conversation as resolved.
Show resolved Hide resolved

default:
files, err := docker.WalkWorkspace(workspace, a.Dependencies.Ignore, a.Dependencies.Paths)
if err != nil {
return nil, errors.Wrapf(err, "walking workspace %s", workspace)
}
var dependencies []string
for file := range files {
dependencies = append(dependencies, file)
}
sort.Strings(dependencies)
return dependencies, nil
}
sort.Strings(dependencies)
return dependencies, nil

}
41 changes: 39 additions & 2 deletions pkg/skaffold/build/custom/dependencies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,40 @@ import (
"github.com/GoogleContainerTools/skaffold/testutil"
)

func TestGetDependencies(t *testing.T) {
func TestGetDependenciesDockerfile(t *testing.T) {
tmpDir, cleanup := testutil.NewTempDir(t)
defer cleanup()

// Directory structure:
// foo
// bar
// - baz
// file
// Dockerfile
tmpDir.Write("foo", "")
tmpDir.Write("bar", "")
tmpDir.Mkdir("baz")
tmpDir.Write("baz/file", "")
tmpDir.Write("Dockerfile", "FROM scratch \n ARG file \n COPY $file baz/file .")

customArtifact := &latest.CustomArtifact{
Dependencies: &latest.CustomDependencies{
priyawadhwa marked this conversation as resolved.
Show resolved Hide resolved
Dockerfile: &latest.DockerfileDependency{
Path: "Dockerfile",
BuildArgs: map[string]*string{
"file": stringPointer("foo"),
},
},
},
}

expected := []string{"Dockerfile", filepath.FromSlash("baz/file"), "foo"}
deps, err := GetDependencies(context.Background(), tmpDir.Root(), customArtifact, nil)

testutil.CheckErrorAndDeepEqual(t, false, err, expected, deps)
}

func TestGetDependenciesPaths(t *testing.T) {
tmpDir, cleanup := testutil.NewTempDir(t)
defer cleanup()

Expand Down Expand Up @@ -66,9 +99,13 @@ func TestGetDependencies(t *testing.T) {
Paths: test.paths,
Ignore: test.ignore,
},
})
}, nil)
testutil.CheckErrorAndDeepEqual(t, false, err, test.expected, deps)
})
}

}

func stringPointer(s string) *string {
return &s
}
2 changes: 1 addition & 1 deletion pkg/skaffold/build/local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (b *Builder) DependenciesForArtifact(ctx context.Context, a *latest.Artifac
paths, err = jib.GetDependenciesGradle(ctx, a.Workspace, a.JibGradleArtifact)

case a.CustomArtifact != nil:
paths, err = custom.GetDependencies(ctx, a.Workspace, a.CustomArtifact)
paths, err = custom.GetDependencies(ctx, a.Workspace, a.CustomArtifact, b.insecureRegistries)

default:
return nil, fmt.Errorf("undefined artifact type: %+v", a.ArtifactType)
Expand Down
17 changes: 17 additions & 0 deletions pkg/skaffold/schema/latest/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -566,14 +566,31 @@ type CustomArtifact struct {
}

// CustomDependencies *alpha* is used to specify dependencies for an artifact built by a custom build script.
// Either `dockerfile` or `paths` should be specified for file watching to work as expected.
type CustomDependencies struct {
// Dockerfile should be set if the artifact is built from a Dockerfile, from which skaffold can determine dependencies.
Dockerfile *DockerfileDependency `yaml:"dockerfile,omitempty" yamltags:"oneOf=dependency"`
// Paths should be set to the file dependencies for this artifact, so that the skaffold file watcher knows when to rebuild and perform file synchronization.
Paths []string `yaml:"paths,omitempty" yamltags:"oneOf=dependency"`
// Ignore specifies the paths that should be ignored by skaffold's file watcher. If a file exists in both `paths` and in `ignore`, it will be ignored, and will be excluded from both rebuilds and file synchronization.
// Will only work in conjunction with `paths`.
priyawadhwa marked this conversation as resolved.
Show resolved Hide resolved
Ignore []string `yaml:"ignore,omitempty"`
}

// DockerfileDependency *alpha* is used to specify a custom build artifact that is built from a Dockerfile. This allows skaffold to determine dependencies from the Dockerfile.
type DockerfileDependency struct {
// Path locates the Dockerfile relative to workspace.
Path string `yaml:"path,omitempty"`

// Target is the Dockerfile target name to build.
Target string `yaml:"target,omitempty"`

// BuildArgs are arguments passed to the docker build.
// It also accepts environment variables via the go template syntax.
// For example: `{"key1": "value1", "key2": "value2", "key3": "{{.ENV_VARIABLE}}"}`.
BuildArgs map[string]*string `yaml:"buildArgs,omitempty"`
}

// KanikoArtifact *alpha* describes an artifact built from a Dockerfile,
// with kaniko.
type KanikoArtifact struct {
Expand Down