Repository navigation
feat(cmd): add cobbler check command - #106
Merged
Merged
Conversation
SchoolGuy
force-pushed
the
feat/cobbler-check
branch
from
October 27, 2026 12:34
8bbda32 to
674997a
Compare
Expose cobblerclient's Check() action as a new top-level, zero-flag command that reports potential Cobbler server configuration problems in the classic numbered-list format. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The published cobblerd test image omits wget, which the server's check action shells out to probe. Without it, cobbler check surfaces as an XML-RPC fault instead of a reported suggestion, which broke Test_CheckCmd in CI. Install wget on container startup via zypper. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
SchoolGuy
force-pushed
the
feat/cobbler-check
branch
from
November 9, 2026 21:21
674997a to
42e3a47
Compare
15 of 20 tasks
Also fix the coverage-upload step's version guard, which had been left pointing at v4.0.0b5 since the previous bump to b6 and so never fired. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Cobbler 4.0.0b7 split the XML-RPC bind-address env var into separate IPv4/IPv6 variants and dropped the old combined COBBLER_XMLRPC_BIND_ADDRESS name. Without this, cobblerd silently falls back to binding 127.0.0.1 only, which breaks the published 25151 port the dev-stack script waits on. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.0.0-rc6's Settings.ConvertServerToIp (bool) can't decode Cobbler
4.0.0b7's reshaped convert_server_to_ip ({enabled, protocol}), which made
`cobbler setting edit`/`setting report` fail outright. v1.0.0-rc8 fixes the
field's type; verified `setting report`/`setting edit` and the full test
suite pass against a live v4.0.0b7 server.
v1.0.0-rc9 additionally fixes a server-side NetworkInterface bug this PR's
`cobbler check` work surfaced: a stray, unbacked IPv6Option._default_gateway
attribute corrupted the ipv6 dict's key set on every transaction clone,
which broke this client's decode heuristic for the whole ipv6 struct (not
just the gateway). if_gateway/ipv6_default_gateway are now DefaultGateway
on IPv4Option/IPv6Option - see a later commit in this branch for the
corresponding cmd/interface.go update.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds build-rpm-docker-leap16, mirroring the existing Tumbleweed target but against registry.opensuse.org/opensuse/leap:16.0, which is the actual release-validation target distro for Cobbler 4.0.0 (SLES 16.0 compatible). Needed to build and install cobbler-cli locally for manual release validation without relying on the OBS package feed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Both printField (cmd/root.go) and printDumpVars (cmd/utils.go) formatted values with %s in their default case. %s on a value whose kind isn't explicitly handled and doesn't implement Stringer renders as literal "%!s(uint=42)" garbage instead of its content. Neither switch's default case is currently reachable with garbled output given today's known XML-RPC response kinds, but %v is the strictly safer default for whatever kind a future Cobbler API field or decoder change adds, with no behavior change for the kinds that reach it today. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
profileBoolFlagMetadata's "enable-ipxe" and "enable-menu" entries were missing IsInheritable: true (unlike the equivalent systemBoolFlagMetadata entry), so addBoolFlags() never registered their "-inherit" companion flags. The shared switch-case in updateProfileFromFlags() unconditionally looks up the "-inherit" flag once the base flag changes, dereferencing a nil *pflag.Flag and panicking on any "profile edit/add --enable-ipxe" or "--enable-menu" invocation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
rsync_sync() in the cobbler server hard-requires mirror_locally=True for the rsync breed, but repo add/edit had no flag to set it, so no rsync-breed repo could be synced through the documented CLI. Wire up a plain bool flag (mirror_locally is non-inheritable on both the Python item and the vendored client's Repo struct, so no -inherit companion is needed, matching the existing keep-updated convention). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A failed new-mode add (any item type) permanently leaked a dangling name claim server-side, because cobbler-cli issued its new_*/modify_*/save_* XML-RPC calls with no transaction_begin/commit/ abort wrapping, going through cobblerd's older, leak-prone no-transaction path. Add a withTransaction helper (cmd/root.go) and wrap the mutating RPC sequence of add/edit/remove commands in it, aborting on any error so a failed attempt is cleanly discarded server-side instead of lingering in cobblerd's unsaved_items cache for up to an hour. Initial scope was narrower than "every mutating command" because testing against a live cobbler-dev container surfaced several independent, pre-existing server/client bugs that a transaction exposes but a non-transactional call silently swallows: - Template and the network interface commands are plain BaseItem types; cobbler's transaction-aware modify_item/remove_item code unconditionally touches attributes (kernel_options, depth) that only exist on InheritableItem/BootableItem subtypes, crashing with an AttributeError. - The three *_group item types are InheritableItem but not BootableItem, hitting the same kernel_options crash on add/edit/copy/rename. - Every copy/rename command's post-mutate "look up the new/renamed item" step uses cobblerclient's type-specific Get<Type>Handle, which never forwards the session token, so it couldn't see an item staged earlier in the same open transaction. - System add/edit hit a cobblerclient bug independent of the above: a stray top-level VirtPXEBoot field with no matching server-side attribute (the real one is nested under virt.pxe_boot). All of the above have since been fixed upstream (BaseItem/InheritableItem transaction-aware code, Get<Type>Handle token forwarding, and the VirtPXEBoot field), so every remaining item type's add/edit/copy/rename -- template, network interface, the three *_group types, and System's add/edit/copy/rename -- is now wrapped in withTransaction too, closing the dangling-name-leak bug across the board. Regression test: cmd/distro_test.go's Test_DistroAddCmd_FailedAddDoesNotLeakDanglingName - a distro add with a bad initrd path fails after new_distro already claimed the name; immediately retrying with the same name and valid fields now succeeds right away instead of failing with "already exists". Confirmed failing before this fix and passing after. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The flag was parsed but never consulted, so `setting report --name <x>` always dumped every setting instead of just the one requested. Reuse settingsFieldByMapstructureTag (already used by setting edit) to look up the named field and print only it, matching the error message style used there for unknown names. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
`template report` printed Content as a blank field whenever it held real text, giving no hint that `template content --name <x>` exists to view it. Replace the raw value with a short "<N bytes, not shown -- see 'cobbler template content --name <name>'>" indicator when content is non-empty, while leaving empty content printed as before. The full content is intentionally never inlined, since it can be an arbitrarily large autoinstall template body. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
NetworkInterface.SystemName was never populated by Client.GetNetworkInterfaces() (cobbler's system_name is a derived property with no backing attribute, so BaseItem.to_dict() never includes it), so `interface list` grouped every interface under a blank system header. Fixed by resolving system_uid -> name client-side via Client.GetSystems() instead. `interface report --name <x>` also silently ignored --system-name whenever --name was set, so it failed identically with or without --system-name whenever the name was ambiguous across systems (interface names are only unique per-system, not globally). Fixed by filtering on system_uid (resolved from --system-name) when both flags are given, and by adding a dedicated errItemAmbiguous sentinel so the report command can replace resolveUID's generic "use --uid to disambiguate" message with one that explains the --system-name requirement. The --system-name-only report branch had the same system_name-matching defect and is fixed the same way. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
cobblerclient.BuildisoOptions.ExcludeSystems and the Python API's build_iso(exclude_systems=...) parameter already existed end-to-end, but NewBuildisoCmd never registered a --exclude-systems flag to set it. With no --systems given, buildiso includes every system in the collection by design, but operators had no practical way to narrow that list without explicitly naming every system to include. Add a plain bool flag mirroring the existing --airgapped/--standalone/ --exclude-dns flags. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
cobblerclient's System struct dropped the stray top-level VirtPXEBoot field in favor of the correct nested Virt.PxeBoot; updateSystemFromFlags still wrote the old field name. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
cobbler replicate has only ever been exercised between two Cobbler servers running the exact same version; mixed-version replication is untested at this time and may fail outright or silently transfer incompatible/ incomplete data. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
distro gains --remote-boot-iso, needed for casper (Ubuntu live-server/Subiquity) netboot to locate its live filesystem over the network -- cobblerclient's Distro struct already had the underlying field missing entirely. distro/profile/system gain --autoinstall-meta-json: a raw JSON object string merged on top of --autoinstall-meta, since the existing flag's pflag StringToString type can only represent flat key=value strings and cannot carry the list/nested-object values some autoinstall_meta keys require (e.g. cloud-init's cloud_init_user_data_modules). Also fixes a copy-paste bug in profile's --autoinstall-meta-inherit handling (checked "boot-loaders-inherit" instead of "autoinstall-meta-inherit", borrowed from the adjacent case block) and the same gap entirely missing from distro's handling (always treated the flag as setting new data rather than marking inherited). system's handling was already correct and used as the reference. image's --kernel-options, --kernel-options-post, --autoinstall-meta, and --template-files flags were entirely non-functional: the switch-case handling for them existed in updateImageFromFlags, but no command ever called addMapFlags to register the underlying flags on any of the five image subcommands, unlike every other item type. Fixed by registering the same distroMapFlagMetadata profile already reuses (the four keys are identical). Also fixes two further bugs in the same block: --autoinstall-meta-inherit checked "boot-loaders-inherit".Changed instead of "autoinstall-meta-inherit".Changed (same copy-paste as profile's), and the kernel-options-post branch assigned its new value to image.KernelOptions.Data instead of image.KernelOptionsPost.Data, silently corrupting kernel-options whenever kernel-options-post was set. image also gains --autoinstall-meta-json for parity with the other three item types. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
profile/system's virt-ram and virt-file-size int/float flag metadata was
missing IsInheritable, so addIntFlags/addFloatFlags never registered
their "-inherit" companion flags. The shared switch-case's
cmd.Flags().Lookup("virt-ram-inherit").Changed (and the file-size
equivalent) then dereferenced a nil *pflag.Flag, segfaulting
"cobbler profile/system edit --virt-ram=<n>" and --virt-file-size.
profile.go's two case bodies additionally had their Lookup() target
copy-pasted from the unrelated "virt-auto-boot-inherit" case (and the
virt-file-size branch set profile.Virt.AutoBoot instead of
profile.Virt.FileSize) -- fixed to look up and set their own fields.
system's virt-cpus had the same missing-IsInheritable bug, fixed here too:
systemIntFlagMetadata's "virt-cpus" entry now registers its
"virt-cpus-inherit" companion flag.
addStringFlags was the only one of the add*Flags helpers (addBoolFlags,
addIntFlags, addFloatFlags all already did this) that ignored
IsInheritable entirely, so no string-typed metadata could ever get its
"-inherit" companion flag registered. repoStringFlagMetadata's
"createrepo-flags"/"proxy" entries and interface.go's "virt-bridge"
flag hit the same nil-Lookup panic as a result -- fixed by the same
mechanism, closing the systemic gap across int/float/bool/string-typed
inheritable flags.
image.go has a further, differently-shaped version of this bug (checks
"owners-inherit" and misuses GetBool for both fields) -- deliberately
left for a separate fix, not touched here.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
cobbler replicate can now also replicate menus, (non built-in) templates, network interfaces, and distro/profile/system groups, each selectable via its own --<type>s pattern flag, matching the new fields on cobblerclient.ReplicateOptions. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add --kernel-options-json, --kernel-options-post-json, and --template-files-json, mirroring the existing --autoinstall-meta-json across distro/profile/system/image: a raw JSON object merged on top of the flat stringToString flag, for values the key=value syntax can't represent (a list/nested-object, or a value containing a comma). With the previous commit's implicit JSON-sniffing gone, this is the only way left to set a structured value. Shared the merge logic behind a new mergeJSONObjectFlag/ mergeJSONStringMapFlag helper pair in cmd/utils.go and switched the four existing --autoinstall-meta-json call sites to use it too, instead of each repeating its own inline json.Unmarshal loop. Also fixes a copy-paste bug found while touching this code: distro.go's kernel-options-post handling wrote the result into distro.KernelOptions.Data instead of distro.KernelOptionsPost.Data, so --kernel-options-post silently never took effect on distro (profile/system/image were not affected). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
SchoolGuy
force-pushed
the
feat/cobbler-check
branch
from
November 10, 2026 13:11
345ba05 to
04c64f4
Compare
Mirrors the cobblerclient/cobbler server fix for the IPv6Option dict corruption (the if_gateway/ipv6_default_gateway fields were removed from NetworkInterface; both are now DefaultGateway on IPv4Option/IPv6Option). This fixes the Test_InterfaceEditCmd_AllFlags integration failure: the corrupted ipv6 dict key set previously broke cobblerclient's decode heuristic for the whole ipv6 struct, not just the gateway field, so ipv6-address silently failed to round-trip too. Requires the cobblerclient v1.0.0-rc9 bump from a prior commit on this branch, which already contains the server-side fix.
SchoolGuy
force-pushed
the
feat/cobbler-check
branch
from
November 10, 2026 13:17
04c64f4 to
8bd4bc8
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
cobbler checkcommand that calls cobblerclient's existingCheck()action and reports potential Cobbler server configuration problems (settings, missing dependencies, boot-loader files, services, etc.).cobblerdand runcobbler sync.cmd/root.go, add aCHANGELOG.mdentry, and add docs (docs/commands/check.rst+ toctree entry).