Route the LINBO image management operations - #33
Open
TomlDev wants to merge 1 commit into
Open
Conversation
LinboImageManager already implements list, delete, rename, duplicate, restore and save_extras, and linuxmusterTools covers them with tests. The API routed none of them, so an image could be uploaded and downloaded but never renamed, copied, rolled back or deleted. Nine endpoints under /v1/linbo/images, global-administrator only like the rest of the router. Four points needed handling in the router rather than the library: - The manager returns silently when a group is unknown, so each endpoint resolves the group first and answers 404 itself. - LinboImageGroup.load() returns early for an image whose .info cannot be read, leaving base as None and diff_image unassigned. Such a group is refused with 409 and the recorded reason; it stays visible in the listing, flagged, which is where it gets noticed. - Backups are keyed internally by a display date, while save_extras takes a raw timestamp. The URLs take the raw YYYYMMDDhhmm form throughout and convert where the manager expects the other. - NameChecker.check returns a bool instead of raising, so its result is tested explicitly rather than relied on through an except branch. info is required in the sidecar body: save_extras deletes whatever the body omits, and an image without .info can no longer be read by the manifest, by LINBO or by this endpoint.
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.
LinboImageManageralready implementslist,delete,rename,duplicate,restoreandsave_extras, andlinuxmusterToolscovers them with tests. The API routed none of them, so an image could be uploaded and downloaded but never renamed, copied, rolled back or deleted. This is the last group of LINBO operations webui7 offers that the API does not.Nine endpoints under
/v1/linbo/images,RoleChecker("G")like the rest of the router. No existing code is modified./v1/linbo/images/v1/linbo/images/{image_name}/backups/v1/linbo/images/{image_name}/v1/linbo/images/{image_name}/diff/v1/linbo/images/{image_name}/backups/{timestamp}/v1/linbo/images/{image_name}/backups/{timestamp}/restore/v1/linbo/images/{image_name}/rename/v1/linbo/images/{image_name}/duplicate/v1/linbo/images/{image_name}/extrasGET /imagescomplements/images/manifestrather than replacing it: the manifest reports what sync clients need, this reports what an image management UI needs, which is thereg,postsyncandprestartcontents and the backup list.Decisions worth reviewing
The manager returns silently for an unknown group.
delete,rename,restoreandsave_extrasare all guarded byif group in self.groups:with no else, so a request for a nonexistent image would answer200. Each endpoint resolves the group first and answers404itself.An image with an unreadable
.infois refused with409.LinboImageGroup.load()returns early in that case, leavingbaseasNoneand never assigningdiff_imageat all, so touchinggroup.diff_imageraisesAttributeError. Such a group is rejected with the recorded reason instead. It still appears inGET /images, flagged with itserror, which is where it gets noticed.Backup timestamps.
LinboImageGroupkeys its backups by the display date fromtimestamp2date(27/01/2026 11:07), anddelete/restoretake that form whilesave_extrastakes the raw timestamp. The URLs use the rawYYYYMMDDhhmmform throughout and convert at the boundary, so the path segments stay free of slashes and spaces.NameChecker.checkreturns a bool rather than raising, so its result is tested explicitly rather than relied on through anexcept ValueErrorbranch.infois required in the sidecar body.save_extrasdeletes any sidecar the body leaves out. That is fine for the optional ones, butLinboImage.load_inforaisesIncompleteImageInfoErrorwithout.info, so a request that omitted it would leave the image unreadable to the manifest, to LINBO and to this endpoint rather than merely editing it.Known limitation: restore drops the common sidecars
restoremoves every top-level file into the new backup directory, and backups only ever contain the image-scoped sidecars, so.reg,.postsyncand.prestartare archived and never come back. After a rollback the image has lost them.This is existing
LinboImageManager.restorebehaviour and webui7 reaches it through the same call, so routing it changes nothing for the worse — but it is worth fixing inlinuxmuster-tools, and I would rather ask than send a patch for it. Happy to open a separate issue there, or to drop the two restore endpoints from this PR if you would prefer them held until the library side is settled.Two smaller notes from the same testing:
%Y%m%d%H%M. It surfaces as a409, so nothing is lost, but the message is not actionable.NAME_RULES['linbo_image']allows a leading dot, so a rename to.incomingwould collide with the upload staging directory. Only a global-administrator can reach it, so it is a footgun rather than a hole, and the fix would be a regex change inlinuxmuster-tools.Testing
pytests/test_linbo_image_management.py, 46 tests, in the mock style of the existingtest_linbo_images.py. Run on a 7.4 server againstlinuxmuster-tools@lmn74; the full suite shows the same failures before and after this branch, compared as sortedFAILED/ERRORid lists rather than counts.Beyond the unit tests:
/srv/linbo— duplicate, rename of an image with backups, list, restore, sidecar writes for both base and backup, diff deletion and deletion — which is how the restore behaviour above was found.GET /imageswas run against the real image tree and its response JSON-encoded, since this is the first endpoint to serialiseLinboImageGroup.to_dict().DELETE /images/upload/diffis genuinely ambiguous — it matches bothcancel_upload_endpointfor an image nameddiffanddelete_image_difffor one namedupload— and registration order settles it in favour of the older route; that case is pinned.