-
Notifications
You must be signed in to change notification settings - Fork 3.9k
dockerd: initialize network config once #29963
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: master
Are you sure you want to change the base?
Changes from 1 commit
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 |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| #!/bin/sh | ||
|
|
||
| /etc/init.d/dockerd uciadd |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -40,14 +40,14 @@ find_network_device() { | |||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| boot() { | ||||||||||||||
| uciadd | ||||||||||||||
| rc_procd start_service | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| uciadd() { | ||||||||||||||
| local iface="${1}" | ||||||||||||||
| local device="${2}" | ||||||||||||||
| local zone="${3}" | ||||||||||||||
| local changed=0 | ||||||||||||||
|
|
||||||||||||||
| [ -z "${iface}" ] && { | ||||||||||||||
| iface="docker" | ||||||||||||||
|
|
@@ -69,6 +69,7 @@ uciadd() { | |||||||||||||
| uci_quiet set network.@interface[-1].proto="none" | ||||||||||||||
| uci_quiet set network.@interface[-1].auto="0" | ||||||||||||||
| uci_quiet commit network | ||||||||||||||
| changed=1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| # Add docker bridge device | ||||||||||||||
|
|
@@ -78,6 +79,7 @@ uciadd() { | |||||||||||||
| uci_quiet set network.@device[-1].type="bridge" | ||||||||||||||
| uci_quiet set network.@device[-1].name="${device}" | ||||||||||||||
| uci_quiet commit network | ||||||||||||||
| changed=1 | ||||||||||||||
| else | ||||||||||||||
| logger -t "dockerd-init" -p notice "Bridge device '${device}' already defined in network config" | ||||||||||||||
| fi | ||||||||||||||
|
|
@@ -92,16 +94,18 @@ uciadd() { | |||||||||||||
| uci_quiet set firewall.@zone[-1].forward="ACCEPT" | ||||||||||||||
| uci_quiet set firewall.@zone[-1].name="${zone}" | ||||||||||||||
| uci_quiet commit firewall | ||||||||||||||
| changed=1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| # Add interface to firewall zone | ||||||||||||||
| if uci_quiet get firewall.${zone}; then | ||||||||||||||
| uci_quiet del_list firewall.${zone}.network="${iface}" | ||||||||||||||
| if uci_quiet get firewall.${zone} \ | ||||||||||||||
| && ! uci_quiet get firewall.${zone}.network | tr ' ' '\n' | grep -Fxq "${iface}"; then | ||||||||||||||
|
Collaborator
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. This membership check never sees the list, so the reload it is meant to gate still fires on every boot. Use the non-silencing form for the read so its output reaches the pipe:
Suggested change
Generated by Claude Code
Collaborator
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. The membership check reads from
Suggested change
Generated by Claude Code |
||||||||||||||
| uci_quiet add_list firewall.${zone}.network="${iface}" | ||||||||||||||
| uci_quiet commit firewall | ||||||||||||||
| changed=1 | ||||||||||||||
| fi | ||||||||||||||
|
|
||||||||||||||
| reload_config | ||||||||||||||
| [ "${changed}" -eq 0 ] || reload_config | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| ucidel() { | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| #!/bin/sh | ||
|
|
||
| # shellcheck shell=busybox | ||
|
|
||
| init_script="${DOCKERD_INIT_SCRIPT:-/etc/init.d/dockerd}" | ||
| boot_body="$(sed -n '/^boot() {$/,/^}$/p' "${init_script}")" | ||
|
|
||
| echo "${boot_body}" | grep -q 'rc_procd start_service' || { | ||
| echo "dockerd boot() does not start the service" >&2 | ||
| exit 1 | ||
| } | ||
|
|
||
| if echo "${boot_body}" | grep -qw uciadd; then | ||
| echo "dockerd boot() must not re-run one-time UCI initialization" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| grep -q '\[ "${changed}" -eq 0 \] || reload_config' "${init_script}" || { | ||
| echo "dockerd uciadd() must reload only after changing UCI" >&2 | ||
| exit 1 | ||
| } |
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.
Removing
uciaddfromboot()looks like it regresses the case where dockerd is baked into the firmware image rather than installed at runtime.Package/dockerd/postinstrunsuciaddonly inside the[ -n "$IPKG_INSTROOT" ] || { ... }guard, so it is skipped during image build (ImageBuilder/buildroot), whereIPKG_INSTROOTis set. The build system'sdefault_postinstre-runs only/etc/uci-defaults/scripts on first boot, not the package'spostinst-pkgbody, so the guardeduciaddnever runs on such systems.boot()was therefore the only path that created thedockernetwork interface,docker0bridge device anddockerfirewall zone on first boot for image-preinstalled dockerd; it was idempotent for runtime installs becauseuciaddgates every mutation behindif ! uci_quiet get ....With this change, a device that ships dockerd in its image would boot without the docker network/firewall UCI config ever being created. This lines up with the maintainer's doubt in the PR thread ("I'm not sure the fix is as simple as removing from boot").
If the goal is only to avoid the
reload_configat boot (thedocker_devicesredefinition), consider addressing that specific reload/idempotency issue instead of dropping config creation entirely — e.g. keep the config-creation on first boot but skipreload_config, or move the one-time creation into an/etc/uci-defaults/script so it is deferred to first boot for image-preinstalled systems. Could you confirm how image-preinstalled installs are expected to get the docker network/firewall config after this change?Generated by Claude Code
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.
I think the idempotency is the issue, because we are dealing with the firewall the reload was to ensure the firewall is in the expected shape before dockerd starts if I recall correctly.
I'm not sure why this is an issue all of a sudden, or why reloading an unchanged firewall breaks anything.
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.
The failure mode is described in #29962: on a device where the docker zone already exists, every boot goes
uciadd→reload_config→ fw4 reload, and that reload fails withError: redefinition of symbol 'docker_devices', leaving fw4 running with no instances (reported on 25.12.4 withiptables=0). So the reload is not a harmless no-op — it re-runs fw4 against state where dockerd's nftables objects already exist.This PR keeps the boot-time
uciadd, so the firewall is still ensured to be in the expected shape before dockerd starts (and image-preinstalled setups still get initialized on first boot). The only change is thatreload_configis skipped whenuciadddidn't actually modify UCI — i.e. the everyday reboot path no longer touches fw4 at all.