You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
kuke daemon recreate left /run/kukeon/kukeond.sock as 0600 root:root, so a non-root member of the kukeon group had to sudo to reach the daemon after a recreate β unlike kuke init, which leaves it 0660 root:kukeon. Reproduced on an upgrade-recreate (v0.7.1 daemon β v0.9.0 binaries β kuke daemon recreate).
Root cause β recreate skipped both things kuke init does to make the socket group-accessible:
Provision with the wrong GID.resolveProvisionKukeondCell hardcoded KukeondSocketGID: 0 (recreate.go). With GID 0, bootstrap.go:472's if socketGID > 0 gate omits --socket-gid from the kukeond cell's persisted args, so kukeond serve defaults to socketModeRootOnly (0o600) and never chowns to the group. kuke init passes ensure.GID (init.go:562).
No host-side re-assert.recreate never ran the post-ready sysuser.ChownAndChmod(socket, 0, gid, 0o660) that init.go:604 runs after the daemon binds the listener. This is the authoritative correction (the daemon resets ownership on every start).
Fix
recreate.go: resolve the kukeon GID (via new lifecycle.LookupKukeonGID) and pass it as KukeondSocketGID; add a post-ready resolveApplySocketOwnership step (test-seamed via MockApplySocketOwnershipKey) that re-asserts root:kukeon 0o660, mirroring init. Prints a kukeond socket β¦: chown root:kukeon mode 0660 notice.
consts.go: new KukeonSocketMode = 0o660 as the single source of truth; init.go's local kukeonSocketMode now references it so init and recreate can't drift again (this drift is the bug).
lifecycle/socketdir.go: extract the existing inline kukeon-GID lookup into an exported LookupKukeonGID reused by both the run-dir ownership step and recreate.
Scope note (verified)
kuke daemon start/restart are not affected: they re-launch the existing kukeond cell via StartCell, whose persisted container args already carry --socket-gid (baked in at bootstrap.go:472 during the original init), so the daemon re-binds 0660 and chowns to the group itself. Only recreate re-provisions the cell from scratch and was dropping the GID. No host-side re-chown was added to start/restart.
Test plan
make test (full CI suite, GOWORK=off) β exit 0
GOWORK=off go build ./... β exit 0 (note: a bare go build ./... fails on a pre-existing third-party containerd/cgroups/v2 break; go.work documents that builds/tests must run GOWORK=off, which make and CI do)
GOWORK=off go vet on touched packages β exit 0
New unit tests: TestDaemonRecreate_AppliesSocketOwnership (ownership step invoked + chown notice printed) and TestDaemonRecreate_SocketOwnershipFailureIsWrapped (error propagation)
End-to-end kuke daemon recreate on a real host verifying stat -c '%U:%G %a' /run/kukeon/kukeond.sock β root:kukeon 660 β not run; the dev host has no initialized kukeon runtime to recreate. Recommend the reviewer confirm on a clean host.
LGTM β kuke daemon recreate now mirrors kuke init's socket-ownership path exactly: it resolves the kukeon GID and threads it into KukeondSocketGID (so bootstrap.go's if socketGID > 0 gate emits --socket-gid), then re-asserts root:kukeon 0o660 post-ready via resolveApplySocketOwnership β both halves the recreate path was previously dropping. The new consts.KukeonSocketMode collapses the init/recreate mode into one source of truth (the drift that caused the bug), and LookupKukeonGID is a clean extraction reused by both call sites with no duplicate inline lookups left behind. Errors wrapped with %w, no leaks, two new unit tests cover the ownership step + error propagation, CI all green.
Non-blocking, for you to run pre-merge: the one unchecked test-plan item is the documented host-gated e2e β kuke daemon recreate on a real initialized host, then stat -c '%U:%G %a' /run/kukeon/kukeond.sock β root:kukeon 660. The author flagged the dev host can't run it; the unit tests prove the wiring but not the on-host chown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
kuke daemon recreateleft/run/kukeon/kukeond.sockas0600 root:root, so a non-root member of thekukeongroup had tosudoto reach the daemon after a recreate β unlikekuke init, which leaves it0660 root:kukeon. Reproduced on an upgrade-recreate (v0.7.1daemon βv0.9.0binaries βkuke daemon recreate).Root cause β
recreateskipped both thingskuke initdoes to make the socket group-accessible:resolveProvisionKukeondCellhardcodedKukeondSocketGID: 0(recreate.go). With GID 0,bootstrap.go:472'sif socketGID > 0gate omits--socket-gidfrom the kukeond cell's persisted args, sokukeond servedefaults tosocketModeRootOnly(0o600) and never chowns to the group.kuke initpassesensure.GID(init.go:562).recreatenever ran the post-readysysuser.ChownAndChmod(socket, 0, gid, 0o660)thatinit.go:604runs after the daemon binds the listener. This is the authoritative correction (the daemon resets ownership on every start).Fix
recreate.go: resolve the kukeon GID (via newlifecycle.LookupKukeonGID) and pass it asKukeondSocketGID; add a post-readyresolveApplySocketOwnershipstep (test-seamed viaMockApplySocketOwnershipKey) that re-assertsroot:kukeon 0o660, mirroring init. Prints akukeond socket β¦: chown root:kukeon mode 0660notice.consts.go: newKukeonSocketMode = 0o660as the single source of truth;init.go's localkukeonSocketModenow references it so init and recreate can't drift again (this drift is the bug).lifecycle/socketdir.go: extract the existing inline kukeon-GID lookup into an exportedLookupKukeonGIDreused by both the run-dir ownership step and recreate.Scope note (verified)
kuke daemon start/restartare not affected: they re-launch the existing kukeond cell viaStartCell, whose persisted container args already carry--socket-gid(baked in atbootstrap.go:472during the originalinit), so the daemon re-binds0660and chowns to the group itself. Onlyrecreatere-provisions the cell from scratch and was dropping the GID. No host-side re-chown was added to start/restart.Test plan
make test(full CI suite,GOWORK=off) β exit 0GOWORK=off go build ./...β exit 0 (note: a barego build ./...fails on a pre-existing third-partycontainerd/cgroups/v2break;go.workdocuments that builds/tests must runGOWORK=off, whichmakeand CI do)GOWORK=off go veton touched packages β exit 0TestDaemonRecreate_AppliesSocketOwnership(ownership step invoked + chown notice printed) andTestDaemonRecreate_SocketOwnershipFailureIsWrapped(error propagation)kuke daemon recreateon a real host verifyingstat -c '%U:%G %a' /run/kukeon/kukeond.sockβroot:kukeon 660β not run; the dev host has no initialized kukeon runtime to recreate. Recommend the reviewer confirm on a clean host.