Repository navigation
Cloud VMs: retry DNS on a fallback resolver when the platform resolver returns SERVFAIL (#26640) #26661
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Cloud VMs: retry DNS on a fallback resolver when the platform resolver returns SERVFAIL (#26640) #26661
Changes from 19 commits
d3c8fb7
9f6ea2a
2120cc6
d35893f
71727a1
1742015
d6cb28a
4942f9e
b14bd06
93c740c
2d85f8c
cbf79d0
8e1439e
802c4bc
2e60d27
ce47d83
bcf11e8
9723782
8bd203b
ddadac8
3394aca
a7509d6
5413081
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,6 +49,7 @@ export const DEVBOX_TEMPLATE_FILES = [ | |
| "chrome-managed-policy.json", | ||
| "cmux-bashrc", | ||
| "cmux-devbox-boot", | ||
| "cmux-dns", | ||
| "cmux-tui-state-mount", | ||
| "cmux-motd", | ||
| "cmux-prompt.bash", | ||
|
|
@@ -521,6 +522,7 @@ export function devboxSourceManifest( | |
| cuaDriver: devboxCuaDriverVersion(dockerfile), | ||
| ghosttyVersion: devboxGhosttyVersion(dockerfile), | ||
| files, | ||
| dns: { units: DEVBOX_DNS_UNITS, install: devboxDnsInstallCommand }, | ||
| }; | ||
| if (schema >= 2) { | ||
| shell.dockerfileInstructions = createHash("sha256").update(normalizedDockerfileInstructions(dockerfile)).digest("hex"); | ||
|
|
@@ -1625,3 +1627,83 @@ export const DEVBOX_PRE_SNAPSHOT_SETTLE_SECONDS = 10; | |
| export function devboxSettleBeforeSnapshotCommand(): string { | ||
| return `sync && sleep ${DEVBOX_PRE_SNAPSHOT_SETTLE_SECONDS} && sync && echo "settled $(cut -d' ' -f1-3 /proc/loadavg)"`; | ||
| } | ||
|
|
||
| /** | ||
| * The DNS fallback (Freestyle only; services/vms/images/devbox/cmux-dns): a | ||
| * stub on 127.0.0.2:53 that asks the platform's resolver first and falls back | ||
| * to its last good answer, then DNS-over-HTTPS, when the platform resolver | ||
| * answers SERVFAIL or nothing (cmux issue 26640). Freestyle rewrites | ||
| * /etc/resolv.conf on every TLS rule change, so a path unit re-points it at | ||
| * the stub each time. The container recipe has none: its runtime owns | ||
| * resolv.conf. | ||
| */ | ||
| export const DEVBOX_DNS_PATH = "/usr/local/bin/cmux-dns"; | ||
| export const DEVBOX_DNS_UNITS: Readonly<Record<string, string>> = { | ||
| "/etc/systemd/system/cmux-dns.service": [ | ||
| "[Unit]", | ||
| "Description=cmux DNS fallback stub (127.0.0.2:53)", | ||
| "Before=nss-lookup.target", | ||
| "Wants=nss-lookup.target", | ||
| "", | ||
| "[Service]", | ||
| "Type=notify", | ||
| // The distribution interpreter, not whichever python3 is first on PATH. | ||
| `ExecStart=/usr/bin/python3 ${DEVBOX_DNS_PATH} serve`, | ||
| "Restart=always", | ||
| "RestartSec=1", | ||
| "DynamicUser=yes", | ||
| "AmbientCapabilities=CAP_NET_BIND_SERVICE", | ||
| "CapabilityBoundingSet=CAP_NET_BIND_SERVICE", | ||
| "", | ||
| "[Install]", | ||
| "WantedBy=multi-user.target", | ||
| ].join("\n") + "\n", | ||
| "/etc/systemd/system/cmux-dns-guard.service": [ | ||
| "[Unit]", | ||
| "Description=Point resolv.conf at the cmux DNS fallback", | ||
| "After=cmux-dns.service", | ||
| "", | ||
| "[Service]", | ||
| "Type=oneshot", | ||
| `ExecStart=/usr/bin/python3 ${DEVBOX_DNS_PATH} guard`, | ||
|
Comment on lines
+1667
to
+1668
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| "", | ||
| "[Install]", | ||
| "WantedBy=multi-user.target", | ||
| ].join("\n") + "\n", | ||
| "/etc/systemd/system/cmux-dns-guard.path": [ | ||
| "[Unit]", | ||
| "Description=Re-point resolv.conf at the cmux DNS fallback whenever the platform rewrites it", | ||
| "", | ||
| "[Path]", | ||
| "PathChanged=/etc/resolv.conf", | ||
| "Unit=cmux-dns-guard.service", | ||
| "", | ||
| "[Install]", | ||
| "WantedBy=multi-user.target", | ||
| ].join("\n") + "\n", | ||
| }; | ||
|
|
||
| /** Enables and starts the fallback once its files are in place, then waits until the stub answers. */ | ||
| export const devboxDnsInstallCommand = [ | ||
| `python3 -m py_compile ${DEVBOX_DNS_PATH}`, | ||
| "systemctl daemon-reload", | ||
| "systemctl enable --now cmux-dns.service cmux-dns-guard.path", | ||
| "systemctl enable cmux-dns-guard.service", | ||
| "systemctl start cmux-dns-guard.service", | ||
| // The stub itself must answer: libc would hide a dead one behind the | ||
| // platform resolvers listed after it. | ||
| `/usr/bin/python3 ${DEVBOX_DNS_PATH} probe`, | ||
| ].join(" && "); | ||
|
|
||
| /** The fallback is installed, answers on its own, and resolv.conf points at it first. */ | ||
| export const devboxDnsCheckCommand = [ | ||
| `test -x ${DEVBOX_DNS_PATH}`, | ||
| `python3 -m py_compile ${DEVBOX_DNS_PATH}`, | ||
| "systemctl is-active cmux-dns.service >/dev/null", | ||
| "systemctl is-active cmux-dns-guard.path >/dev/null", | ||
| "head -1 /etc/resolv.conf | grep -qx '# cmux-dns'", | ||
| "[ \"$(awk '$1 == \"nameserver\" { print $2; exit }' /etc/resolv.conf)\" = 127.0.0.2 ]", | ||
| `/usr/bin/python3 ${DEVBOX_DNS_PATH} probe github.com`, | ||
| "getent ahostsv4 github.com >/dev/null", | ||
|
Comment on lines
+1706
to
+1707
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| "echo dns-fallback-ok", | ||
| ].join(" && "); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script executed:
Repository: manaflow-ai/cmux
Length of output: 4957
Script executed:
Repository: manaflow-ai/cmux
Length of output: 1992
Default Freestyle manifest rows no longer match the devbox source fingerprint.
The source manifest now always records a
dnsentry, andDEVBOX_TEMPLATE_FILESnow includescmux-dns. The default rows were baked fromce1717b6, whose shell object has nodnskey. Their recorded digests therefore differ from the digest computed at head.devboxSourceDriftProblemsreports each default schema-2 row. This makesweb/scripts/validate-devbox-ladder.tsexit with an error. It also fails theexpect(devboxSourceDriftProblems(readImageManifest())).toEqual([])assertion inweb/tests/vm-image-manifest.test.ts.Regenerate the default images from the merged sources with
bun run devbox:promote -- freestyle, so the manifest records digests for the current sources. Do not change the fingerprint or the drift check to make the existing rows pass. The check's own remedy text says to promote a new bake or revert the sources with the manifest.