Skip to content

Commit 65f0e6b

Browse files
committed
fix: use dokku CONTAINER files for authoritative container ID lookup
Read container IDs from dokku's internal CONTAINER.process.N files instead of filtering docker ps output. These files are the authoritative source for current deployment containers and are properly updated when scaling down (stale files are removed during deploy). This avoids issues with orphaned containers from previous deployments that may still be running but are no longer part of the current formation.
1 parent 1b216d4 commit 65f0e6b

1 file changed

Lines changed: 19 additions & 42 deletions

File tree

tasks/integration_test.go

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -116,51 +116,31 @@ func skipIfDockerLinkUnsupportedT(t *testing.T) {
116116
}
117117
}
118118

119-
// retireAndCleanupContainers forces dokku to retire old containers from
120-
// previous deploys and then cleans up stopped containers
121-
func retireAndCleanupContainers() {
122-
subprocess.CallExecCommand(subprocess.ExecCommandInput{
123-
Command: "dokku",
124-
Args: []string{"ps:retire"},
125-
})
126-
subprocess.CallExecCommand(subprocess.ExecCommandInput{
127-
Command: "dokku",
128-
Args: []string{"cleanup"},
129-
})
130-
}
131-
132-
// getActiveContainers returns the IDs of running containers matching the given
133-
// app and process type, excluding retired containers (those renamed with a
134-
// timestamp suffix like "app.web.1.1640787924") and interim containers (those
135-
// with an ".upcoming-" suffix created during deployment).
136-
func getActiveContainers(appName, processType string) ([]string, error) {
137-
result, err := subprocess.CallExecCommand(subprocess.ExecCommandInput{
138-
Command: "docker",
139-
Args: []string{"ps", "--filter", fmt.Sprintf("label=com.dokku.app-name=%s", appName), "--filter", fmt.Sprintf("label=com.dokku.process-type=%s", processType), "--format", "{{.ID}}\t{{.Names}}"},
140-
})
119+
// getCurrentContainerIDs reads the container IDs from dokku's internal
120+
// CONTAINER files (e.g., /home/dokku/APP/CONTAINER.web.1) which are the
121+
// authoritative source for the current deployment's containers.
122+
func getCurrentContainerIDs(appName, processType string) ([]string, error) {
123+
scale, err := getPsScale(appName)
141124
if err != nil {
142125
return nil, err
143126
}
144-
output := strings.TrimSpace(result.StdoutContents())
145-
if output == "" {
127+
count, ok := scale[processType]
128+
if !ok || count == 0 {
146129
return nil, nil
147130
}
148131
var ids []string
149-
for _, line := range strings.Split(output, "\n") {
150-
parts := strings.SplitN(line, "\t", 2)
151-
if len(parts) != 2 {
132+
for i := 1; i <= count; i++ {
133+
result, err := subprocess.CallExecCommand(subprocess.ExecCommandInput{
134+
Command: "cat",
135+
Args: []string{fmt.Sprintf("/home/dokku/%s/CONTAINER.%s.%d", appName, processType, i)},
136+
})
137+
if err != nil {
152138
continue
153139
}
154-
containerID := parts[0]
155-
containerName := parts[1]
156-
// skip retired containers (app.process.N.TIMESTAMP) and
157-
// interim containers (app.process.N.upcoming-RANDOM)
158-
// active containers have exactly 3 dot-separated segments: app.process.N
159-
segments := strings.Split(containerName, ".")
160-
if len(segments) != 3 {
161-
continue
140+
id := strings.TrimSpace(result.StdoutContents())
141+
if id != "" {
142+
ids = append(ids, id)
162143
}
163-
ids = append(ids, containerID)
164144
}
165145
return ids, nil
166146
}
@@ -1047,8 +1027,7 @@ func TestIntegrationPsScale(t *testing.T) {
10471027
}
10481028

10491029
// verify initial web container count is 1 via docker ps
1050-
retireAndCleanupContainers()
1051-
initialContainers, err := getActiveContainers(appName, "web")
1030+
initialContainers, err := getCurrentContainerIDs(appName, "web")
10521031
if err != nil {
10531032
t.Fatalf("failed to list containers: %v", err)
10541033
}
@@ -1086,8 +1065,7 @@ func TestIntegrationPsScale(t *testing.T) {
10861065
}
10871066

10881067
// clean up old containers and verify 2 web containers via docker ps
1089-
retireAndCleanupContainers()
1090-
scaledContainers, err := getActiveContainers(appName, "web")
1068+
scaledContainers, err := getCurrentContainerIDs(appName, "web")
10911069
if err != nil {
10921070
t.Fatalf("failed to list containers after scale: %v", err)
10931071
}
@@ -1133,8 +1111,7 @@ func TestIntegrationPsScale(t *testing.T) {
11331111
}
11341112

11351113
// clean up old containers and verify 1 web container after scale down
1136-
retireAndCleanupContainers()
1137-
finalContainers, err := getActiveContainers(appName, "web")
1114+
finalContainers, err := getCurrentContainerIDs(appName, "web")
11381115
if err != nil {
11391116
t.Fatalf("failed to list containers after scale down: %v", err)
11401117
}

0 commit comments

Comments
 (0)