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

tiltfile: pass TILT_HOST + TILT_PORT to local() commands #4773

Merged
merged 4 commits into from
Jul 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 8 additions & 5 deletions internal/cli/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion internal/engine/upper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3884,7 +3884,7 @@ func newTestFixture(t *testing.T) *testFixture {
k8sContextExt := k8scontext.NewExtension("fake-context", env)
versionExt := version.NewExtension(model.TiltBuild{Version: "0.5.0"})
configExt := config.NewExtension("up")
tfl := tiltfile.ProvideTiltfileLoader(ta, b.kClient, k8sContextExt, versionExt, configExt, fakeDcc, "localhost", feature.MainDefaults, env)
tfl := tiltfile.ProvideTiltfileLoader(ta, b.kClient, k8sContextExt, versionExt, configExt, fakeDcc, "localhost", model.WebPort(12345), feature.MainDefaults, env)
cc := configs.NewConfigsController(tfl, dockerClient, cdc)
dcw := dcwatch.NewEventWatcher(fakeDcc, dockerClient)
dclm := runtimelog.NewDockerComposeLogManager(fakeDcc)
Expand Down
19 changes: 19 additions & 0 deletions internal/tiltfile/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"

"github.com/tilt-dev/tilt/internal/k8s"
Expand Down Expand Up @@ -80,6 +81,12 @@ func (s *tiltfileState) execLocalCmd(t *starlark.Thread, cmd model.Cmd, logOutpu
c.Stderr = io.MultiWriter(stderr, logOutput)
}

// if Tilt was invoked with `tilt up --port=XXXXX`, local() calls to use the Tilt API will fail due to trying to
// connect to the default port, so explicitly populate the TILT_PORT environment variable if it isn't already
addEnvIfNotPresent(c, "TILT_PORT", strconv.Itoa(int(s.webPort)))
// some Tilt commands, such as `tilt dump engine`, also require the host
addEnvIfNotPresent(c, "TILT_HOST", string(s.webHost))

err = c.Run()
if err != nil {
// If we already logged the output, we don't need to log it again.
Expand Down Expand Up @@ -303,3 +310,15 @@ func hasYAMLExtension(fname string) bool {
ext := filepath.Ext(fname)
return strings.EqualFold(ext, ".yaml") || strings.EqualFold(ext, ".yml")
}

func addEnvIfNotPresent(c *exec.Cmd, key, value string) bool {
prefix := key + "="
for _, e := range c.Env {
if strings.HasPrefix(e, prefix) {
return false
}
}

c.Env = append(c.Env, key+"="+value)
return true
}
5 changes: 4 additions & 1 deletion internal/tiltfile/tiltfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func ProvideTiltfileLoader(
configExt *config.Extension,
dcCli dockercompose.DockerComposeClient,
webHost model.WebHost,
webPort model.WebPort,
fDefaults feature.Defaults,
env k8s.Env) TiltfileLoader {
return tiltfileLoader{
Expand All @@ -117,6 +118,7 @@ func ProvideTiltfileLoader(
configExt: configExt,
dcCli: dcCli,
webHost: webHost,
webPort: webPort,
fDefaults: fDefaults,
env: env,
}
Expand All @@ -127,6 +129,7 @@ type tiltfileLoader struct {
kCli k8s.Client
dcCli dockercompose.DockerComposeClient
webHost model.WebHost
webPort model.WebPort

k8sContextExt k8scontext.Extension
versionExt version.Extension
Expand Down Expand Up @@ -172,7 +175,7 @@ func (tfl tiltfileLoader) Load(ctx context.Context, filename string, userConfigS

localRegistry := tfl.kCli.LocalRegistry(ctx)

s := newTiltfileState(ctx, tfl.dcCli, tfl.webHost, tfl.k8sContextExt, tfl.versionExt, tfl.configExt, localRegistry, feature.FromDefaults(tfl.fDefaults))
s := newTiltfileState(ctx, tfl.dcCli, tfl.webHost, tfl.webPort, tfl.k8sContextExt, tfl.versionExt, tfl.configExt, localRegistry, feature.FromDefaults(tfl.fDefaults))

manifests, result, err := s.loadManifests(absFilename, userConfigState)

Expand Down
3 changes: 3 additions & 0 deletions internal/tiltfile/tiltfile_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ type tiltfileState struct {
ctx context.Context
dcCli dockercompose.DockerComposeClient
webHost model.WebHost
webPort model.WebPort
k8sContextExt k8scontext.Extension
versionExt version.Extension
configExt *config.Extension
Expand Down Expand Up @@ -134,6 +135,7 @@ func newTiltfileState(
ctx context.Context,
dcCli dockercompose.DockerComposeClient,
webHost model.WebHost,
webPort model.WebPort,
k8sContextExt k8scontext.Extension,
versionExt version.Extension,
configExt *config.Extension,
Expand All @@ -143,6 +145,7 @@ func newTiltfileState(
ctx: ctx,
dcCli: dcCli,
webHost: webHost,
webPort: webPort,
k8sContextExt: k8sContextExt,
versionExt: versionExt,
configExt: configExt,
Expand Down
57 changes: 56 additions & 1 deletion internal/tiltfile/tiltfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ local('echo foobar', echo_off=True)

assert.NotContains(t, f.out.String(), "local: echo foobar")
}

func TestLocalArgvCmd(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("windows doesn't support argv commands. Go converts it to a single string")
Expand All @@ -358,6 +359,60 @@ func TestLocalArgvCmd(t *testing.T) {
assert.Contains(t, f.out.String(), `a"b`)
}

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

resetEnv := func() {
tiltVars := []string{"TILT_HOST", "TILT_PORT"}
for _, key := range tiltVars {
if originalValue, ok := os.LookupEnv(key); ok {
// unset for test then restore after
require.NoError(t, os.Unsetenv(key))
t.Cleanup(func() {
require.NoError(t, os.Setenv(key, originalValue))
})
} else {
// already unset, make sure still unset after test completes
t.Cleanup(func() {
require.NoError(t, os.Unsetenv(key))
})
}
}
}
resetEnv()

doTest := func(t testing.TB, expectedHost string, expectedPort int) {
t.Helper()

f.file("Tiltfile", `
local(command='echo Tilt host is $TILT_HOST', command_bat='echo Tilt host is %TILT_HOST%', echo_off=True)
local(command='echo Tilt port is $TILT_PORT', command_bat='echo Tilt port is %TILT_PORT%', echo_off=True)
`)
f.load()

assert.Contains(t, f.out.String(), fmt.Sprintf(`Tilt host is %s`, expectedHost))
assert.Contains(t, f.out.String(), fmt.Sprintf(`Tilt port is %d`, expectedPort))
}

t.Run("Implicit", func(t *testing.T) {
resetEnv()
// $TILT_HOST + $TILT_PORT are not explicitly defined anywhere in the test fixture but should be
// auto-populated (hardcoded to 1.2.3.4/12345 for tests - no real apiserver is actually loaded)
f.webHost = "1.2.3.4"
doTest(t, "1.2.3.4", 12345)
})

t.Run("Explicit", func(t *testing.T) {
resetEnv()
require.NoError(t, os.Setenv("TILT_HOST", "7.8.9.0"))
require.NoError(t, os.Setenv("TILT_PORT", "7890"))

// if values were explicitly passed (e.g. `local('...', env={"TILT_PORT": 7890})`, they should be respected
doTest(t, "7.8.9.0", 7890)
})
}

func TestReadFile(t *testing.T) {
f := newFixture(t)
defer f.TearDown()
Expand Down Expand Up @@ -5610,7 +5665,7 @@ func (f *fixture) newTiltfileLoader() TiltfileLoader {
k8sContextExt := k8scontext.NewExtension(f.k8sContext, f.k8sEnv)
versionExt := version.NewExtension(model.TiltBuild{Version: "0.5.0"})
configExt := config.NewExtension("up")
return ProvideTiltfileLoader(f.ta, f.kCli, k8sContextExt, versionExt, configExt, dcc, f.webHost, features, f.k8sEnv)
return ProvideTiltfileLoader(f.ta, f.kCli, k8sContextExt, versionExt, configExt, dcc, f.webHost, model.WebPort(12345), features, f.k8sEnv)
}

func newFixture(t *testing.T) *fixture {
Expand Down