Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,22 @@ public class RestoreBackupCommand extends Command {
private VirtualMachine.State vmState;
private Integer mountTimeout;

/**
* On-NAS format of the backup files: {@code qcow2} (default, also when null) or {@code rbddiff}
* for Ceph/RBD chains written with {@code rbd export-diff}. Decides both the file extension the
* agent looks for and how the volume is reconstructed.
*/
private String backupFormat;

/**
* For {@code rbddiff} backups: every backup directory of the chain from its full anchor up to
* and including the backup being restored, ordered root-first. {@code rbd import-diff} streams
* have no backing-file metadata, so the chain cannot be self-describing the way rebased qcow2
* files are — the agent has to be told which diffs to replay and in which order. Null/empty for
* qcow2 backups.
*/
private List<String> backupChainPaths;

protected RestoreBackupCommand() {
super();
}
Expand Down Expand Up @@ -164,4 +180,20 @@ public Integer getMountTimeout() {
public void setMountTimeout(Integer mountTimeout) {
this.mountTimeout = mountTimeout;
}

public String getBackupFormat() {
return backupFormat;
}

public void setBackupFormat(String backupFormat) {
this.backupFormat = backupFormat;
}

public List<String> getBackupChainPaths() {
return backupChainPaths;
}

public void setBackupChainPaths(List<String> backupChainPaths) {
this.backupChainPaths = backupChainPaths;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class TakeBackupCommand extends Command {

// Incremental backup fields (NAS provider; null/empty for legacy full-only callers).
private String mode; // "full" or "incremental"; null => legacy behaviour (script default)
private String method; // "qcow2" (bitmaps, push mode), "content" (pull mode) or "rbd" (Ceph export-diff); null => "qcow2"
private String bitmapNew; // Checkpoint/bitmap name to create with this backup (timestamp-based)
private String bitmapParent; // Incremental: parent bitmap to read changes since

Expand Down Expand Up @@ -125,6 +126,14 @@ public void setMode(String mode) {
this.mode = mode;
}

public String getMethod() {
return method;
}

public void setMethod(String method) {
this.method = method;
}

public String getBitmapNew() {
return bitmapNew;
}
Expand Down
2 changes: 1 addition & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Description: CloudStack server library

Package: cloudstack-agent
Architecture: all
Depends: ${python:Depends}, ${python3:Depends}, openjdk-17-jre-headless | java17-runtime-headless | java17-runtime | zulu-17, cloudstack-common (= ${source:Version}), lsb-base (>= 9), openssh-client, qemu-kvm (>= 2.5) | qemu-system-x86 (>= 5.2), libvirt-bin (>= 1.3) | libvirt-daemon-system (>= 3.0), iproute2, ebtables, vlan, ipset, python3-libvirt, ethtool, iptables, cryptsetup, rng-tools, rsync, ovmf, swtpm, lsb-release, ufw, apparmor, cpu-checker, libvirt-daemon-driver-storage-rbd, sysstat, python3-libnbd, socat
Depends: ${python:Depends}, ${python3:Depends}, openjdk-17-jre-headless | java17-runtime-headless | java17-runtime | zulu-17, cloudstack-common (= ${source:Version}), lsb-base (>= 9), openssh-client, qemu-kvm (>= 2.5) | qemu-system-x86 (>= 5.2), libvirt-bin (>= 1.3) | libvirt-daemon-system (>= 3.0), iproute2, ebtables, vlan, ipset, python3-libvirt, ethtool, iptables, cryptsetup, rng-tools, rsync, ovmf, swtpm, lsb-release, ufw, apparmor, cpu-checker, libvirt-daemon-driver-storage-rbd, sysstat, python3-libnbd, python3-rados, python3-rbd, ceph-common, socat

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we add python3-rados and rbd in this PR? Because those Python libraries aren't used here

Recommends: init-system-helpers
Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts
Description: CloudStack agent
Expand Down
3 changes: 3 additions & 0 deletions packaging/el8/cloud.spec
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ Requires: (libgcrypt > 1.8.3 or libgcrypt20)
Requires: (selinux-tools if selinux-tools)
Requires: sysstat
Requires: python3-libnbd
Requires: python3-rados
Requires: python3-rbd

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same here

Requires: ceph-common
Requires: socat
Provides: cloud-agent
Group: System Environment/Libraries
Expand Down
3 changes: 3 additions & 0 deletions packaging/suse15/cloud.spec
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ Requires: cifs-utils
Requires: (edk2-ovmf or qemu-ovmf-x86_64)
Requires: swtpm
Requires: (python3-libvirt or python3-libvirt-python)
Requires: (python3-rados or python3-ceph-common)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

And for these as well, tools aren't used in this PR

Requires: (python3-rbd or python3-ceph-common)
Requires: ceph-common
Requires: (qemu-img or qemu-tools)
Requires: qemu-kvm
Requires: cryptsetup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,21 @@ public final class NASBackupChainKeys {
/** UUID of the parent backup (full or previous incremental). Empty for full backups. */
public static final String PARENT_BACKUP_ID = "nas.parent_backup_id";

/** QEMU dirty-bitmap name created by this backup, used as the {@code <incremental>} reference for the next one. */
/**
* Name of the point-in-time anchor this backup created, used as the parent reference for the
* next backup in the chain. Its meaning depends on the chain format: for {@link #FORMAT_QCOW2}
* chains it is the QEMU dirty-bitmap name used as the {@code <incremental>} reference; for
* {@link #FORMAT_RBD_DIFF} chains it is the RBD snapshot name used as {@code --from-snap}.
*/
public static final String BITMAP_NAME = "nas.bitmap_name";

/**
* On-NAS format of the chain this backup belongs to: {@link #FORMAT_QCOW2} (rebased qcow2
* files, the file-based storage path) or {@link #FORMAT_RBD_DIFF} ({@code rbd export-diff}
* streams, the Ceph/RBD path). Absent on legacy-full backups, which are always qcow2.
*/
public static final String CHAIN_FORMAT = "nas.chain_format";

/** Identifier shared by every backup in the same chain (the full anchors a chain; its incrementals inherit the id). */
public static final String CHAIN_ID = "nas.chain_id";

Expand All @@ -48,6 +60,31 @@ public final class NASBackupChainKeys {
// "legacy-full" mode token (which sets make_checkpoint=0).
public static final String TYPE_LEGACY_FULL = "legacy-full";

/**
* In-memory backup-method sentinels used by {@code ChainDecision.method}: how a backup is
* taken, independent of whether it is a full or an incremental ({@code ChainDecision.mode}).
*
* <p>{@link #METHOD_QCOW2}: libvirt push-mode backup; incrementals come from QEMU persistent
* dirty bitmaps (libvirt checkpoints), which only qcow2 volumes can carry.</p>
*/
public static final String METHOD_QCOW2 = "qcow2";

/**
* Content-based libvirt pull-mode backup, used for raw block-device storage such as
* LINSTOR/DRBD which cannot carry persistent dirty bitmaps. A full is written as a sparse
* qcow2 in a single pass; an incremental is a qcow2 overlay on the disk's NBD export,
* safe-rebased onto the parent so it holds only the clusters that differ.
*/
public static final String METHOD_CONTENT = "content";
Comment thread
weizhouapache marked this conversation as resolved.

/**
* Ceph-native backup, used for RBD volumes. They are raw and cannot carry a persistent dirty
* bitmap, so each cycle anchors on an RBD snapshot and exports the delta with
* {@code rbd export-diff}. Unlike the other methods this one writes {@link #FORMAT_RBD_DIFF}
* streams rather than qcow2 files, which is what {@link #CHAIN_FORMAT} records for restore.
*/
public static final String METHOD_RBD = "rbd";

/**
* VM-scoped detail (stored in {@code vm_instance_details}) holding the QEMU dirty-bitmap
* name that currently exists on the running VM and is therefore the only valid parent
Expand All @@ -57,6 +94,10 @@ public final class NASBackupChainKeys {
*/
public static final String VM_ACTIVE_CHECKPOINT_ID = "nas.active_checkpoint_id";

/** Chain format values persisted under {@link #CHAIN_FORMAT}; also the on-NAS file extension. */
public static final String FORMAT_QCOW2 = "qcow2";
public static final String FORMAT_RBD_DIFF = "rbddiff";

private NASBackupChainKeys() {
}
}
Loading
Loading