diff --git a/useruid.go b/useruid.go index 3e1e41c..8610c53 100644 --- a/useruid.go +++ b/useruid.go @@ -143,9 +143,15 @@ func statOwner(path string) (uid, gid int, ok bool) { // /etc/passwd and /etc/group directly via awk + sed so it works on // Debian (shadow tools) and Alpine/BusyBox (no shadow tools) alike — // no `usermod`/`groupmod`/`getent` runtime dependency. +// +// Intentionally no `# syntax=docker/dockerfile:X` directive: the +// instructions used here (ARG, FROM $ARG, USER, COPY, RUN) are all +// handled by buildkit's built-in frontend, and declaring an external +// frontend forces buildkit to pull `docker/dockerfile:*` from a +// registry before parsing — which hangs indefinitely in environments +// whose registry mirror routes docker.io through a broken upstream. func generateUIDDockerfile(baseImage, user string, hostUID, hostGID int) string { - return "# syntax=docker/dockerfile:1.4\n" + - "ARG _DEV_CONTAINERS_BASE_IMAGE=" + baseImage + "\n" + + return "ARG _DEV_CONTAINERS_BASE_IMAGE=" + baseImage + "\n" + "FROM $_DEV_CONTAINERS_BASE_IMAGE\n" + "USER root\n" + "ARG _REMOTE_USER=" + user + "\n" + diff --git a/useruid_test.go b/useruid_test.go index 5f16f7b..43d5758 100644 --- a/useruid_test.go +++ b/useruid_test.go @@ -57,6 +57,13 @@ func TestGenerateUIDDockerfile_ContainsKeyDirectives(t *testing.T) { t.Errorf("dockerfile missing %q\n--\n%s", want, df) } } + // Declaring an external dockerfile frontend forces buildkit to pull + // docker/dockerfile:* before parsing — which hangs in environments + // whose registry mirror routes docker.io through a broken upstream. + // Nothing in this Dockerfile needs a non-builtin frontend. + if strings.Contains(df, "# syntax=") { + t.Errorf("dockerfile must not declare a syntax= frontend; built-in frontend is sufficient\n--\n%s", df) + } } func TestUIDReconcileScript_PortableShape(t *testing.T) {