Skip to content

Commit 4f5e2cc

Browse files
committed
cmd/hi: share the test-container prefix matcher and check the k3s image
Factor the hs-/ts-/derp-/k3s- prefix set into one helper used by cleanup and docker; add a doctor check for the ghcr k3s image.
1 parent b2240cc commit 4f5e2cc

3 files changed

Lines changed: 60 additions & 4 deletions

File tree

cmd/hi/cleanup.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,29 @@ func removeContainerWithRetry(ctx context.Context, cli *client.Client, container
187187
return err == nil
188188
}
189189

190+
// testContainerNamePrefixes are the name prefixes used by containers that the
191+
// integration test harness creates (headscale, tailscale, DERP, and k3s).
192+
var testContainerNamePrefixes = []string{"hs-", "ts-", "derp-", "k3s-"}
193+
194+
// matchesTestContainerPrefix reports whether name belongs to an integration
195+
// test container, ignoring any leading "/" that Docker prefixes names with.
196+
func matchesTestContainerPrefix(name string) bool {
197+
name = strings.TrimPrefix(name, "/")
198+
for _, prefix := range testContainerNamePrefixes {
199+
if strings.HasPrefix(name, prefix) {
200+
return true
201+
}
202+
}
203+
204+
return false
205+
}
206+
190207
// isTestContainerName reports whether any of the container names belong to an
191208
// integration test container.
192209
func isTestContainerName(names []string) bool {
193210
for _, name := range names {
194211
if strings.Contains(name, "headscale-test-suite") ||
195-
strings.Contains(name, "hs-") ||
196-
strings.Contains(name, "ts-") ||
197-
strings.Contains(name, "derp-") {
212+
matchesTestContainerPrefix(name) {
198213
return true
199214
}
200215
}

cmd/hi/docker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ func getCurrentTestContainers(containers []container.Summary, testContainerID st
735735
for _, cont := range containers {
736736
for _, name := range cont.Names {
737737
containerName := strings.TrimPrefix(name, "/")
738-
if strings.HasPrefix(containerName, "hs-") || strings.HasPrefix(containerName, "ts-") {
738+
if matchesTestContainerPrefix(containerName) {
739739
// Check if container has matching run ID label
740740
if cont.Labels != nil && cont.Labels["hi.run-id"] == runID {
741741
testRunContainers = append(testRunContainers, testContainer{

cmd/hi/doctor.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"strings"
1111

1212
"github.com/juanfont/headscale/integration/dockertestutil"
13+
"github.com/juanfont/headscale/integration/k3sic"
1314
)
1415

1516
const (
@@ -21,6 +22,7 @@ const (
2122
nameDockerContext = "Docker Context"
2223
nameDockerSocket = "Docker Socket"
2324
nameGolangImage = "Golang Image"
25+
nameK3sImage = "K3s Image"
2426
nameGoInstall = "Go Installation"
2527
)
2628

@@ -66,6 +68,7 @@ func runDoctorCheck(ctx context.Context) error {
6668
results = append(results, checkDockerSocket(ctx))
6769
results = append(results, checkDockerHubCredentials())
6870
results = append(results, checkGolangImage(ctx))
71+
results = append(results, checkK3sImage(ctx))
6972
}
7073

7174
// Check 3: Go installation
@@ -242,6 +245,44 @@ func checkGolangImage(ctx context.Context) DoctorResult {
242245
return pass(nameGolangImage, fmt.Sprintf("Golang image %s is now available", imageName))
243246
}
244247

248+
// checkK3sImage verifies the ghcr k3s image used by TestK8sOperator is available
249+
// locally or can be pulled. The image is pinned (see [k3sic.K3sImage]).
250+
func checkK3sImage(ctx context.Context) DoctorResult {
251+
cli, err := createDockerClient(ctx)
252+
if err != nil {
253+
return fail(nameK3sImage, "Cannot create Docker client for image check")
254+
}
255+
defer cli.Close()
256+
257+
imageName := k3sic.K3sImage
258+
259+
available, err := checkImageAvailableLocally(ctx, cli, imageName)
260+
if err != nil {
261+
return fail(
262+
nameK3sImage,
263+
fmt.Sprintf("Cannot check k3s image %s: %v", imageName, err),
264+
"Check Docker daemon status",
265+
"Try: docker images | grep k3s",
266+
)
267+
}
268+
269+
if available {
270+
return pass(nameK3sImage, fmt.Sprintf("K3s image %s is available locally", imageName))
271+
}
272+
273+
err = ensureImageAvailable(ctx, cli, imageName, false)
274+
if err != nil {
275+
return warn(
276+
nameK3sImage,
277+
fmt.Sprintf("K3s image %s not available locally and could not pull: %v", imageName, err),
278+
"Only TestK8sOperator needs this image; other tests are unaffected",
279+
"Try: docker pull "+imageName,
280+
)
281+
}
282+
283+
return pass(nameK3sImage, fmt.Sprintf("K3s image %s is now available", imageName))
284+
}
285+
245286
// checkGoInstallation verifies Go is installed and working.
246287
func checkGoInstallation(ctx context.Context) DoctorResult {
247288
_, err := exec.LookPath("go")

0 commit comments

Comments
 (0)