Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@Bl4ckk98
Copy link

@Bl4ckk98 Bl4ckk98 commented Oct 18, 2025

Have you ever wanted to delete System32 inside Winboat? Now you can!

I tried to keep bash at the bare minimum, however some was still needed.
This is now ready to test!
It's a draft, but any review on what is actually done is appreaciated to improve everything.

Actual features:

  • Cold snapshots (they require restarts).
  • Both volumes (legacy) and bind mounts are supported. For named volumes, a new alpine docker is started to clone the volume. It is then removed if canceled or finished.
  • User can decide to compress the snaps to save space, or to avoid compression for faster speeds.
  • User can decide the max number of snapshots (older ones get deleted).
  • User can decide where to save snaps. Only absolute paths are supported to avoid any potential damage. Write permissions are checked while user types in the directory. (Migration of existing snapshots is up to the user, however an alert is being shown if there are snapshots in the current snap directory).
    The SnapshotsManager gets automatically restarted in case of a path change. This is to avoid Winboat restarts.
  • Rich logs are saved in a new snapshots.log file.
  • New settings are being saved in the config file:
    "snapshotMaxCount": 3,
    "snapshotCompression": true,
    "rdpArgs": [],
    "snapshotPath": "/home/bl4ckk/.winboat/snapshots"
  • Pigz is being used for compression (it's actually faster), however there is fallback to gzip.
  • While snapshot is being created, it shows "Creating..." state.
  • After ungraceful stop (eg you brutally close Winboat) the snapshot process gets checked and recovered/canceled.
  • Showing "restoring" state.
  • Disable VM starts while restoring/snapping.
  • Possibility to save snapshot on another disk.
  • In case of restore, save a backup to rollback if something fails. This avoids any VM corruption.

TO IMPLEMENT:

  • Check if free space is enough before starting snap creation.
  • Check the written space during a restore.
  • Avoid negative numbers on snapshot limit.
  • Estimate snapshot size before creation. // Actually I am personally unable to implement this. If you do know how to do it, please feel fry to help me out

Yes, I tested deleting System32

Resolves #180

@Bl4ckk98 Bl4ckk98 changed the title Adding snapshots feature with some other features. Add snapshots feature Oct 21, 2025
snapshotCompression: boolean;
snapshotPath: string;
snapshotsInProgress: Record<string, {
name: string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is staying in config, please declare the type for the record (name/timestamp/currentsize/id) separately - similar to how RdpArg is - this will grow in future and I don't want it to blow out in line count/complexity too early

snapshotMaxCount: number;
snapshotCompression: boolean;
snapshotPath: string;
snapshotsInProgress: Record<string, {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does snapshotsInProgress mean, is this the snapshot we're in the middle of saving? does the fact it's in progress need to be written to disk?

It might be better to have a separate file/instance to store snapshot info in rather than adding it to config, but I'll leave that to Tibix or Levev to decide

if (this.#wbConfig.config.snapshotCompression) {
logger.info(`Creating compressed snapshot at ${outputFile}...`);
const hasPigz = await this.#hasCmd("pigz");
const cmd = hasPigz
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really sure what's going on here. are you flushing the disks in Windows before starting snapshot?
are you just tgz-ing the entire volume?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file at this size is too unwieldy and it and the functions within violate cyclomatic complexity metrics.
Ideally the functions would be split into smaller chunks that don't each require access to global state (i.e. make them effectively static - pass in args, return values) and then they can grouped in a way that makes sense and then distributed among a bunch of files in a snapshot subdirectory of lib

// Step 1: empty destination volume
logger.info(`Step 1: Emptying volume ${volumeName}...`);
const t0 = Date.now();
await execAsync(`docker run --rm -v "${volumeName}":/target alpine sh -c "rm -rf /target/*"`);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I ask for a little more detail? why do you pull in alpine?
Could you have just used docker export -> docker volume rm -> docker import?

@Simon-Weij
Copy link
Contributor

Functionally, this works fine for me. One thing I would change is that deleting a snapshot switches the delete button and cancel button, so maybe change that.

@Bl4ckk98
Copy link
Author

Functionally, this works fine for me. One thing I would change is that deleting a snapshot switches the delete button and cancel button, so maybe change that.

Many thanks <3 gonna change it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Add snapshots?

3 participants