Skip to content

restore() does not bring back an image's .reg, .postsync and .prestart #27

Description

@TomlDev

LinboImageManager.restore moves every file out of the base image directory into the new backup, then moves the chosen backup's files back. Backups only ever contain the image-scoped sidecars (<image>.qcow2.desc, .info, .vdi), so the common ones — <name>.reg, <name>.postsync, <name>.prestart — are archived and never restored. After a rollback the image no longer has them.

Reproduced on 7.4 with linuxmusterTools@lmn74, in a scratch tree:

before: win11.qcow2  win11.qcow2.desc  win11.qcow2.info  win11.reg  win11.postsync
        backups/202601271107/{win11.qcow2, win11.qcow2.desc, win11.qcow2.info}

after restore("win11", "27/01/2026 11:07"):
        win11.qcow2  win11.qcow2.desc  win11.qcow2.info
        backups/202608111043/{win11.qcow2, win11.qcow2.desc, win11.qcow2.info, win11.reg, win11.postsync}

The registry patch and the postsync script are gone from the image; they exist only inside the new backup directory.

images.py already separates the two groups for exactly this reason — EXTRA_IMAGE_FILES is keyed on the image filename and EXTRA_COMMON_FILES on the image name, and delete_files and rename both treat them differently. restore is the one place that does not: it iterates the directory rather than the two lists.

Is that intentional? I can see an argument for archiving the whole directory as it stood. But the asymmetry with rename, which carries the common files across, makes it look unintended, and the practical effect is that a rollback silently loses configuration that was not part of what the user rolled back.

If it is a bug, the fix looks small — leave the EXTRA_COMMON_FILES in place instead of moving them, or move them back after the backup's files land. I did not want to send a patch for a behaviour that might be deliberate, so: which way would you like it?

Context: this surfaced while routing the image management operations in the API, linuxmuster/linuxmuster-api#33. That PR exposes restore as-is and documents this, since webui7 reaches the same code path today and routing it changes nothing for the worse.

Two smaller things found alongside, mentioned here only so they are written down somewhere:

  • Two restores of the same image within one minute collide: the new backup directory is datetime.now().strftime('%Y%m%d%H%M'), so the second raises ImageExistsError. Nothing is lost, and a caller can retry.
  • NAME_RULES['linbo_image'] accepts a leading dot, so an image can be renamed to .incoming and collide with the upload staging directory used by image_sync. Only a global-administrator can trigger it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions