Skip to content

Commit

Permalink
liveupdate: fix handling of docker-compose restarts
Browse files Browse the repository at this point in the history
Fixes #5663
  • Loading branch information
nicks committed Apr 6, 2022
1 parent 544cefb commit 0931493
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 28 deletions.
17 changes: 10 additions & 7 deletions internal/controllers/core/liveupdate/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,14 +514,17 @@ func (r *Reconciler) garbageCollectFileChanges(res luResource, monitor *monitor)
// Go through all the container monitors, and delete any that are no longer
// being selected. We don't care why they're not being selected.
func (r *Reconciler) garbageCollectMonitorContainers(res luResource, monitor *monitor) {
podsByKey := map[monitorContainerKey]bool{}
for _, pod := range res.podNames() {
podsByKey[monitorContainerKey{podName: pod.Name, namespace: pod.Namespace}] = true
}
// All containers are guaranteed to have container IDs if they're still active.
containerIDs := map[string]bool{}
res.visitSelectedContainers(func(pod v1alpha1.Pod, c v1alpha1.Container) bool {
if c.ID != "" {
containerIDs[c.ID] = true
}
return false
})

for key := range monitor.containers {
podKey := monitorContainerKey{podName: key.podName, namespace: key.namespace}
if !podsByKey[podKey] {
if !containerIDs[key.containerID] {
delete(monitor.containers, key)
}
}
Expand Down Expand Up @@ -966,7 +969,7 @@ func (r *Reconciler) applyInternal(
ContainerName: cInfo.ContainerName.String(),
ContainerID: cInfo.ContainerID.String(),
PodName: cInfo.PodID.String(),
Namespace: cInfo.Namespace.String(),
Namespace: string(cInfo.Namespace),
LastFileTimeSynced: lastFileTimeSynced,
}

Expand Down
12 changes: 12 additions & 0 deletions internal/controllers/core/liveupdate/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ func TestConsumeFileEventsDockerCompose(t *testing.T) {
if assert.Equal(t, 1, len(f.cu.Calls)) {
assert.True(t, f.cu.Calls[0].HotReload)
}

f.assertSteadyState(&lu)

// Docker Compose containers can be restarted in-place,
// preserving their filesystem.
dc := &v1alpha1.DockerComposeService{}
f.MustGet(types.NamespacedName{Name: "frontend-service"}, dc)
dc = dc.DeepCopy()
dc.Status.ContainerState.StartedAt = apis.NowMicro()
f.UpdateStatus(dc)

f.assertSteadyState(&lu)
}

func TestConsumeFileEventsUpdateModeManual(t *testing.T) {
Expand Down
21 changes: 0 additions & 21 deletions internal/controllers/core/liveupdate/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"time"

"github.com/docker/distribution/reference"
"k8s.io/apimachinery/pkg/types"

"github.com/tilt-dev/tilt/internal/container"
"github.com/tilt-dev/tilt/internal/dockercompose"
Expand All @@ -22,9 +21,6 @@ type luResource interface {
// The time to start syncing changes from.
bestStartTime() time.Time

// The names of any pods, for tracking state.
podNames() []types.NamespacedName

// An iterator for visiting each container.
visitSelectedContainers(visit func(pod v1alpha1.Pod, c v1alpha1.Container) bool)
}
Expand All @@ -48,14 +44,6 @@ func (r *luK8sResource) bestStartTime() time.Time {
return startTime
}

func (r *luK8sResource) podNames() []types.NamespacedName {
result := []types.NamespacedName{}
for _, pod := range r.res.FilteredPods {
result = append(result, types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace})
}
return result
}

// Visit all selected containers.
func (r *luK8sResource) visitSelectedContainers(
visit func(pod v1alpha1.Pod, c v1alpha1.Container) bool) {
Expand Down Expand Up @@ -94,15 +82,6 @@ func (r *luDCResource) bestStartTime() time.Time {
return r.res.Status.LastApplyStartTime.Time
}

// In DockerCompose, we treat every container as a single-container pod.
func (r *luDCResource) podNames() []types.NamespacedName {
result := []types.NamespacedName{}
if r.res.Status.ContainerID != "" {
result = append(result, types.NamespacedName{Name: r.res.Status.ContainerID})
}
return result
}

// Visit all selected containers.
func (r *luDCResource) visitSelectedContainers(
visit func(pod v1alpha1.Pod, c v1alpha1.Container) bool) {
Expand Down

0 comments on commit 0931493

Please sign in to comment.