Skip to content

Commit

Permalink
Add dockerfile to custom dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
Priya Wadhwa committed May 1, 2019
1 parent 4a4d696 commit eb99598
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 15 deletions.
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)

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{
Dockerfile: &latest.DockerfileDependency{
Path: "Dockerfile",
BuildArgs: map[string]*string{
"file": stringPointer("foo"),
},
},
},
}

expected := []string{"Dockerfile", "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`.
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

0 comments on commit eb99598

Please sign in to comment.