Skip to content

Commit

Permalink
tiltfile: add 'entrypoint' opt arg to docker_build and custom_build, …
Browse files Browse the repository at this point in the history
…translate into image target [ch2886] (#1833)

* tiltfile: add 'entrypoint' opt arg to docker_build and custom_build, translate into image target

* tests

* rename a fastBuild-related field to free up better names

* fix comment

* fix goimports asdfg why are my filewatchers broken?
  • Loading branch information
Maia McCormick authored Jul 11, 2019
1 parent b3e6eb5 commit 71d688d
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 8 deletions.
32 changes: 25 additions & 7 deletions internal/tiltfile/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ type dockerImage struct {
baseDockerfile dockerfile.Dockerfile
configurationRef container.RefSelector
deploymentRef reference.Named
syncs []pathSync
runs []model.Run
entrypoint string
cachePaths []string
hotReload bool
matchInEnvVars bool
ignores []string
onlys []string
entrypoint model.Cmd // optional: if specified, we override the image entrypoint/k8s command with this

// fast-build properties -- will be deprecated
syncs []pathSync
runs []model.Run
fbEntrypoint string
hotReload bool

dbDockerfilePath localPath
dbDockerfile dockerfile.Dockerfile
Expand Down Expand Up @@ -81,7 +84,7 @@ func (d *dockerImage) Type() dockerImageBuildType {
}

func (s *tiltfileState) dockerBuild(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var dockerRef string
var dockerRef, entrypoint string
var contextVal, dockerfilePathVal, buildArgs, dockerfileContentsVal, cacheVal, liveUpdateVal, ignoreVal, onlyVal starlark.Value
var matchInEnvVars bool
if err := starlark.UnpackArgs(fn.Name(), args, kwargs,
Expand All @@ -95,6 +98,7 @@ func (s *tiltfileState) dockerBuild(thread *starlark.Thread, fn *starlark.Builti
"match_in_env_vars?", &matchInEnvVars,
"ignore?", &ignoreVal,
"only?", &onlyVal,
"entrypoint?", &entrypoint,
); err != nil {
return nil, err
}
Expand Down Expand Up @@ -178,6 +182,11 @@ func (s *tiltfileState) dockerBuild(thread *starlark.Thread, fn *starlark.Builti
return nil, error2
}

var entrypointCmd model.Cmd
if entrypoint != "" {
entrypointCmd = model.ToShellCmd(entrypoint)
}

r := &dockerImage{
dbDockerfilePath: dockerfilePath,
dbDockerfile: dockerfile.Dockerfile(dockerfileContents),
Expand All @@ -189,6 +198,7 @@ func (s *tiltfileState) dockerBuild(thread *starlark.Thread, fn *starlark.Builti
matchInEnvVars: matchInEnvVars,
ignores: ignores,
onlys: onlys,
entrypoint: entrypointCmd,
}
err = s.buildIndex.addImage(r)
if err != nil {
Expand All @@ -207,7 +217,7 @@ func (s *tiltfileState) fastBuildForImage(image *dockerImage) model.FastBuild {
BaseDockerfile: image.baseDockerfile.String(),
Syncs: s.syncsToDomain(image),
Runs: image.runs,
Entrypoint: model.ToShellCmd(image.entrypoint),
Entrypoint: model.ToShellCmd(image.fbEntrypoint),
HotReload: image.hotReload,
}
}
Expand All @@ -219,6 +229,7 @@ func (s *tiltfileState) customBuild(thread *starlark.Thread, fn *starlark.Builti
var disablePush bool
var liveUpdateVal, ignoreVal starlark.Value
var matchInEnvVars bool
var entrypoint string

err := starlark.UnpackArgs(fn.Name(), args, kwargs,
"ref", &dockerRef,
Expand All @@ -229,6 +240,7 @@ func (s *tiltfileState) customBuild(thread *starlark.Thread, fn *starlark.Builti
"live_update?", &liveUpdateVal,
"match_in_env_vars?", &matchInEnvVars,
"ignore?", &ignoreVal,
"entrypoint?", &entrypoint,
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -269,6 +281,11 @@ func (s *tiltfileState) customBuild(thread *starlark.Thread, fn *starlark.Builti
return nil, error
}

var entrypointCmd model.Cmd
if entrypoint != "" {
entrypointCmd = model.ToShellCmd(entrypoint)
}

img := &dockerImage{
configurationRef: container.NewRefSelector(ref),
customCommand: command,
Expand All @@ -278,6 +295,7 @@ func (s *tiltfileState) customBuild(thread *starlark.Thread, fn *starlark.Builti
liveUpdate: liveUpdate,
matchInEnvVars: matchInEnvVars,
ignores: ignores,
entrypoint: entrypointCmd,
}

err = s.buildIndex.addImage(img)
Expand Down Expand Up @@ -397,7 +415,7 @@ func (s *tiltfileState) fastBuild(thread *starlark.Thread, fn *starlark.Builtin,
baseDockerfilePath: baseDockerfilePath,
baseDockerfile: df,
configurationRef: container.NewRefSelector(ref),
entrypoint: entrypoint,
fbEntrypoint: entrypoint,
cachePaths: cachePaths,
}
err = s.buildIndex.addImage(r)
Expand Down
14 changes: 14 additions & 0 deletions internal/tiltfile/tiltfile_docker_compose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,20 @@ dc_resource('no-svc-with-this-name-eek', 'gcr.io/foo')
f.loadErrString("no Docker Compose service found with name")
}

func TestDockerComposeDoesntSupportEntrypointOverride(t *testing.T) {
f := newFixture(t)
defer f.TearDown()

f.dockerfile("foo/Dockerfile")
f.file("docker-compose.yml", simpleConfig)
f.file("Tiltfile", `docker_build('gcr.io/foo', './foo', entrypoint='./foo')
docker_compose('docker-compose.yml')
dc_resource('foo', 'gcr.io/foo')
`)

f.loadErrString("docker_build/custom_build.entrypoint not supported for Docker Compose resources")
}

func (f *fixture) assertDcManifest(name string, opts ...interface{}) model.Manifest {
m := f.assertNextManifest(name)

Expand Down
12 changes: 11 additions & 1 deletion internal/tiltfile/tiltfile_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,10 @@ func (s *tiltfileState) imgTargetsForDependencyIDsHelper(ids []model.TargetID, c
MatchInEnvVars: image.matchInEnvVars,
}.WithCachePaths(image.cachePaths)

if !image.entrypoint.Empty() {
iTarget = iTarget.WithOverrideCommand(image.entrypoint)
}

lu := image.liveUpdate

switch image.Type() {
Expand Down Expand Up @@ -982,6 +986,13 @@ func (s *tiltfileState) translateDC(dc dcResourceSet) ([]model.Manifest, error)
if err != nil {
return nil, errors.Wrapf(err, "getting image build info for %s", svc.Name)
}

for _, iTarg := range iTargets {
if !iTarg.OverrideCmd.Empty() {
return nil, fmt.Errorf("docker_build/custom_build.entrypoint not supported for Docker Compose resources")
}
}

m = m.WithImageTargets(iTargets)

err = s.checkForImpossibleLiveUpdates(m)
Expand All @@ -996,7 +1007,6 @@ func (s *tiltfileState) translateDC(dc dcResourceSet) ([]model.Manifest, error)
s.configFiles = sliceutils.DedupedAndSorted(append(s.configFiles, configFiles...))
}
if len(dc.configPaths) != 0 {

s.configFiles = sliceutils.DedupedAndSorted(append(s.configFiles, dc.configPaths...))
}

Expand Down
56 changes: 56 additions & 0 deletions internal/tiltfile/tiltfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (

appsv1 "k8s.io/api/apps/v1"

"github.com/windmilleng/tilt/internal/sliceutils"

"github.com/stretchr/testify/assert"
"github.com/windmilleng/wmclient/pkg/analytics"
v1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -3592,6 +3594,42 @@ func TestDisableFeatureThatDoesntExist(t *testing.T) {
f.loadErrString("Unknown feature flag: testflag")
}

func TestDockerBuildEntrypoint(t *testing.T) {
f := newFixture(t)
defer f.TearDown()

f.dockerfile("Dockerfile")
f.yaml("foo.yaml", deployment("foo", image("gcr.io/foo")))
f.file("Tiltfile", `
docker_build('gcr.io/foo', '.', entrypoint="/bin/the_app")
k8s_yaml('foo.yaml')
`)

f.load()
f.assertNextManifest("foo", db(image("gcr.io/foo"), entrypoint("/bin/the_app")))
}

func TestCustomBuildEntrypoint(t *testing.T) {
f := newFixture(t)
defer f.TearDown()

f.dockerfile("Dockerfile")
f.yaml("foo.yaml", deployment("foo", image("gcr.io/foo")))
f.file("Tiltfile", `
custom_build('gcr.io/foo', 'docker build -t $EXPECTED_REF foo',
['foo'], entrypoint="/bin/the_app")
k8s_yaml('foo.yaml')
`)

f.load()
f.assertNextManifest("foo", cb(
image("gcr.io/foo"),
deps(f.JoinPath("foo")),
cmd("docker build -t $EXPECTED_REF foo"),
entrypoint("/bin/the_app")),
)
}

type fixture struct {
ctx context.Context
out *bytes.Buffer
Expand Down Expand Up @@ -3874,6 +3912,11 @@ func (f *fixture) assertNextManifest(name string, opts ...interface{}) model.Man

for _, matcher := range opt.matchers {
switch matcher := matcher.(type) {
case entrypointHelper:
if !sliceutils.StringSliceEquals(matcher.cmd.Argv, image.OverrideCmd.Argv) {
f.t.Fatalf("expected OverrideCommand (aka entrypoint) %v, got %v",
matcher.cmd.Argv, image.OverrideCmd.Argv)
}
case nestedFBHelper:
dbInfo := image.DockerBuildInfo()
if matcher.fb == nil {
Expand Down Expand Up @@ -3936,6 +3979,11 @@ func (f *fixture) assertNextManifest(name string, opts ...interface{}) model.Man
assert.Equal(f.t, matcher.tag, cbInfo.Tag)
case disablePushHelper:
assert.Equal(f.t, matcher.disabled, cbInfo.DisablePush)
case entrypointHelper:
if !sliceutils.StringSliceEquals(matcher.cmd.Argv, image.OverrideCmd.Argv) {
f.t.Fatalf("expected OverrideCommand (aka entrypoint) %v, got %v",
matcher.cmd.Argv, image.OverrideCmd.Argv)
}
case fbHelper:
if cbInfo.Fast.Empty() {
f.t.Fatalf("Expected manifest %v to have fast build, but it didn't", m.Name)
Expand Down Expand Up @@ -4375,6 +4423,14 @@ func cb(img imageHelper, opts ...interface{}) cbHelper {
return cbHelper{img, opts}
}

type entrypointHelper struct {
cmd model.Cmd
}

func entrypoint(command string) entrypointHelper {
return entrypointHelper{model.ToShellCmd(command)}
}

type nestedFBHelper struct {
fb *fbHelper
}
Expand Down

0 comments on commit 71d688d

Please sign in to comment.