Skip to content

Commit

Permalink
dockercompose: use the liveupdate reconciler instead of the build-and…
Browse files Browse the repository at this point in the history
…-deployer (#5616)

* dockercompose: use the liveupdate reconciler instead of the build-and-deployer

* integration: add live-update integration tests
  • Loading branch information
nicks authored Mar 23, 2022
1 parent 296ab00 commit 1b88d04
Show file tree
Hide file tree
Showing 25 changed files with 168 additions and 80 deletions.
10 changes: 5 additions & 5 deletions integration/dcbuild/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM golang:1.17-alpine
RUN apk add curl
WORKDIR /go/src/github.com/tilt-dev/integration/dcbuild/cmd/dcbuild
FROM alpine
RUN apk add busybox-extras curl
WORKDIR /app
ADD . .
RUN go install github.com/tilt-dev/integration/dcbuild/cmd/dcbuild
ENTRYPOINT /go/bin/dcbuild
RUN ./compile.sh
ENTRYPOINT ./start.sh ./main.sh
10 changes: 9 additions & 1 deletion integration/dcbuild/Tiltfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# -*- mode: Python -*-

docker_compose('docker-compose.yaml')
docker_build('gcr.io/windmill-test-containers/dcbuild', 'cmd/dcbuild', dockerfile='Dockerfile')

docker_build('gcr.io/windmill-test-containers/dcbuild',
'.',
dockerfile='Dockerfile',
live_update=[
sync('.', '/app'),
run('/app/compile.sh'),
run('/app/restart.sh'),
])
3 changes: 0 additions & 3 deletions integration/dcbuild/cmd/dcbuild/go.mod

This file was deleted.

17 changes: 0 additions & 17 deletions integration/dcbuild/cmd/dcbuild/main.go

This file was deleted.

3 changes: 3 additions & 0 deletions integration/dcbuild/compile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

cat source.txt | sed "s/MESSAGE/🍄 One-Up! 🍄/" > compiled.txt
6 changes: 6 additions & 0 deletions integration/dcbuild/main.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

set -ex

cp compiled.txt index.html
exec httpd -f -p 8000
25 changes: 25 additions & 0 deletions integration/dcbuild/restart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/sh
#
# A helper script to restart a given process as part of a Live Update.
#
# Further reading:
# https://docs.tilt.dev/live_update_reference.html#restarting-your-process
#
# Usage:
# Copy start.sh and restart.sh to your container working dir.
#
# Make your container entrypoint:
# ./start.sh path-to-binary [args]
#
# To restart the container:
# ./restart.sh

set -u

touch restart.txt
PID="$(cat process.txt)"
if [ $? -ne 0 ]; then
echo "unable to read process.txt. was your process started with start.sh?"
exit 1
fi
kill "$PID"
1 change: 1 addition & 0 deletions integration/dcbuild/source.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MESSAGE
44 changes: 44 additions & 0 deletions integration/dcbuild/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/bin/sh
#
# A helper script to restart a given process as part of a Live Update.
#
# Further reading:
# https://docs.tilt.dev/live_update_reference.html#restarting-your-process
#
# Usage:
# Copy start.sh and restart.sh to your container working dir.
#
# Make your container entrypoint:
# ./start.sh path-to-binary [args]
#
# To restart the container:
# ./restart.sh

set -eu

process_id=""

trap quit TERM INT

quit() {
if [ -n "$process_id" ]; then
kill $process_id
fi
}

while true; do
rm -f restart.txt

"$@" &
process_id=$!
echo "$process_id" > process.txt
set +e
wait $process_id
EXIT_CODE=$?
set -e
if [ ! -f restart.txt ]; then
echo "Exiting with code $EXIT_CODE"
exit $EXIT_CODE
fi
echo "Restarting"
done
19 changes: 16 additions & 3 deletions integration/dcbuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ import (
"context"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// Ensures live-update works on tilt-handled image builds in dockercompose
func TestDockerComposeImageBuild(t *testing.T) {
f := newDCFixture(t, "dcbuild")

Expand All @@ -24,11 +28,20 @@ func TestDockerComposeImageBuild(t *testing.T) {
})
}, "gcr.io/windmill-test-containers/dcbuild")

f.CurlUntil(ctx, "dcbuild", "localhost:8000", "🍄 One-Up! 🍄")
f.CurlUntil(ctx, "dcbuild", "localhost:8000/index.html", "🍄 One-Up! 🍄")

cID1, err := f.dockerContainerID("dcbuild")
require.NoError(t, err)

f.ReplaceContents("cmd/dcbuild/main.go", "One-Up", "Two-Up")
f.ReplaceContents("compile.sh", "One-Up", "Two-Up")

ctx, cancel = context.WithTimeout(f.ctx, time.Minute)
defer cancel()
f.CurlUntil(ctx, "dcbuild", "localhost:8000", "🍄 Two-Up! 🍄")
f.CurlUntil(ctx, "dcbuild", "localhost:8000/index.html", "🍄 Two-Up! 🍄")

cID2, err := f.dockerContainerID("dcbuild")
require.NoError(t, err)

// Make sure the container was updated in-place
assert.Equal(t, cID1, cID2)
}
3 changes: 2 additions & 1 deletion internal/engine/buildcontrol/build_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,8 @@ func IsLiveUpdateTargetWaitingOnDeploy(state store.EngineState, mt *store.Manife
}

} else if mt.Manifest.IsDC() {
cInfos := liveupdates.RunningContainersForDC(mt.State.DockerResource())
dcs := state.DockerComposeServices[mt.Manifest.Name.String()]
cInfos := liveupdates.RunningContainersForDC(dcs)
if len(cInfos) != 0 {
return false
}
Expand Down
4 changes: 2 additions & 2 deletions internal/engine/buildcontrol/extractors.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func extractImageTargetsForLiveUpdates(specs []model.TargetSpec, stateSet store.
containers, err := liveupdates.RunningContainers(
state.KubernetesSelector,
state.KubernetesResource,
state.DockerResource)
state.DockerComposeService)

if err != nil {
return nil, RedirectToNextBuilderInfof("Error retrieving container info: %v", err)
Expand All @@ -140,7 +140,7 @@ func extractImageTargetsForLiveUpdates(specs []model.TargetSpec, stateSet store.
filesChanged: filesChanged,
containers: containers,
hasFileChangesIDs: hasFileChangesIDs,
isDC: state.DockerResource != nil,
isDC: state.DockerComposeService != nil,
})
}

Expand Down
8 changes: 5 additions & 3 deletions internal/engine/buildcontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/tilt-dev/tilt/internal/engine/buildcontrol"
"github.com/tilt-dev/tilt/internal/store"
"github.com/tilt-dev/tilt/internal/store/buildcontrols"
"github.com/tilt-dev/tilt/internal/store/dcconv"
"github.com/tilt-dev/tilt/internal/store/k8sconv"
"github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1"
"github.com/tilt-dev/tilt/pkg/model"
Expand Down Expand Up @@ -81,6 +80,7 @@ func (c *BuildController) needsBuild(ctx context.Context, st store.RStore) (buil
buildReason := mt.NextBuildReason()
targets := buildcontrol.BuildTargets(manifest)
buildStateSet := buildStateSet(ctx, manifest, state.KubernetesResources[manifest.Name.String()],
state.DockerComposeServices[manifest.Name.String()],
targets, ms, buildReason)

return buildEntry{
Expand Down Expand Up @@ -202,7 +202,9 @@ func SpanIDForBuildLog(buildCount int) logstore.SpanID {

// Extract a set of build states from a manifest for BuildAndDeploy.
func buildStateSet(ctx context.Context, manifest model.Manifest,
kresource *k8sconv.KubernetesResource, specs []model.TargetSpec,
kresource *k8sconv.KubernetesResource,
dcs *v1alpha1.DockerComposeService,
specs []model.TargetSpec,
ms *store.ManifestState, reason model.BuildReason) store.BuildStateSet {
result := store.BuildStateSet{}

Expand Down Expand Up @@ -241,7 +243,7 @@ func buildStateSet(ctx context.Context, manifest model.Manifest,
}

if manifest.IsDC() {
buildState.DockerResource = &dcconv.DockerResource{ContainerID: string(ms.DCRuntimeState().ContainerID)}
buildState.DockerComposeService = dcs
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/engine/buildcontroller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func TestBuildControllerDockerCompose(t *testing.T) {
call = f.nextCall()
s := call.state[imageTarget.ID()]
containers, err := liveupdates.RunningContainers(
nil, nil, s.DockerResource)
nil, nil, s.DockerComposeService)
require.NoError(t, err)
assert.Equal(t, "dc-sancho", containers[0].ContainerID.String())

Expand Down
1 change: 1 addition & 0 deletions internal/engine/testdata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func NewSanchoLiveUpdateDCManifest(f Fixture) model.Manifest {
return manifestbuilder.New(f, "sancho").
WithDockerCompose().
WithImageTarget(NewSanchoLiveUpdateImageTarget(f)).
WithLiveUpdateBAD().
Build()
}

Expand Down
19 changes: 11 additions & 8 deletions internal/engine/upper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@ type fakeBuildAndDeployer struct {
resultsByID store.BuildResultSet

// kClient registers deployed entities for subsequent retrieval.
kClient *k8s.FakeK8sClient
kClient *k8s.FakeK8sClient
dcClient *dockercompose.FakeDCClient

ctrlClient ctrlclient.Client

Expand Down Expand Up @@ -358,15 +359,16 @@ func (b *fakeBuildAndDeployer) BuildAndDeploy(ctx context.Context, st store.RSto
}

if !call.dc().Empty() && len(b.nextLiveUpdateContainerIDs) == 0 {
err = b.updateDockerComposeServiceStatus(ctx, call.dc(), iTargets)
if err != nil {
return result, err
}

dcContainerID := container.ID(fmt.Sprintf("dc-%s", path.Base(call.dc().ID().Name.String())))
if b.nextDockerComposeContainerID != "" {
dcContainerID = b.nextDockerComposeContainerID
}
b.dcClient.ContainerIdOutput = dcContainerID

err = b.updateDockerComposeServiceStatus(ctx, call.dc(), iTargets)
if err != nil {
return result, err
}

dcContainerState := b.nextDockerComposeContainerState
result[call.dc().ID()] = store.NewDockerComposeDeployResult(
Expand Down Expand Up @@ -545,13 +547,14 @@ func (b *fakeBuildAndDeployer) waitUntilBuildCompleted(ctx context.Context, key
}
}

func newFakeBuildAndDeployer(t *testing.T, kClient *k8s.FakeK8sClient, ctrlClient ctrlclient.Client, kaReconciler *kubernetesapply.Reconciler, dcReconciler *dockercomposeservice.Reconciler) *fakeBuildAndDeployer {
func newFakeBuildAndDeployer(t *testing.T, kClient *k8s.FakeK8sClient, dcClient *dockercompose.FakeDCClient, ctrlClient ctrlclient.Client, kaReconciler *kubernetesapply.Reconciler, dcReconciler *dockercomposeservice.Reconciler) *fakeBuildAndDeployer {
return &fakeBuildAndDeployer{
t: t,
calls: make(chan buildAndDeployCall, 20),
buildLogOutput: make(map[model.TargetID]string),
resultsByID: store.BuildResultSet{},
kClient: kClient,
dcClient: dcClient,
ctrlClient: ctrlClient,
kaReconciler: kaReconciler,
dcReconciler: dcReconciler,
Expand Down Expand Up @@ -3563,7 +3566,7 @@ func newTestFixture(t *testing.T, options ...fixtureOptions) *testFixture {
dp := dockerprune.NewDockerPruner(dockerClient)
dp.DisabledForTesting(true)

b := newFakeBuildAndDeployer(t, kClient, cdc, kar, dcr)
b := newFakeBuildAndDeployer(t, kClient, fakeDcc, cdc, kar, dcr)
bc := NewBuildController(b)

ret := &testFixture{
Expand Down
3 changes: 1 addition & 2 deletions internal/store/build_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"github.com/docker/distribution/reference"

"github.com/tilt-dev/tilt/internal/container"
"github.com/tilt-dev/tilt/internal/store/dcconv"
"github.com/tilt-dev/tilt/internal/store/k8sconv"
"github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1"
"github.com/tilt-dev/tilt/pkg/model"
Expand Down Expand Up @@ -274,7 +273,7 @@ type BuildState struct {

KubernetesResource *k8sconv.KubernetesResource

DockerResource *dcconv.DockerResource
DockerComposeService *v1alpha1.DockerComposeService
}

func NewBuildState(result BuildResult, files []string, pendingDeps []model.TargetID) BuildState {
Expand Down
9 changes: 0 additions & 9 deletions internal/store/dcconv/resource.go

This file was deleted.

9 changes: 0 additions & 9 deletions internal/store/engine_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/tilt-dev/tilt/internal/container"
"github.com/tilt-dev/tilt/internal/dockercompose"
"github.com/tilt-dev/tilt/internal/k8s"
"github.com/tilt-dev/tilt/internal/store/dcconv"
"github.com/tilt-dev/tilt/internal/store/k8sconv"
"github.com/tilt-dev/tilt/internal/timecmp"
"github.com/tilt-dev/tilt/internal/token"
Expand Down Expand Up @@ -600,14 +599,6 @@ func (ms *ManifestState) DCRuntimeState() dockercompose.State {
return ret
}

func (ms *ManifestState) DockerResource() *dcconv.DockerResource {
ret, ok := ms.RuntimeState.(dockercompose.State)
if !ok {
return nil
}
return &dcconv.DockerResource{ContainerID: string(ret.ContainerID)}
}

func (ms *ManifestState) IsDC() bool {
_, ok := ms.RuntimeState.(dockercompose.State)
return ok
Expand Down
Loading

0 comments on commit 1b88d04

Please sign in to comment.