Compare commits
6 Commits
v0.9.99
...
8cb44c0c5d
Author | SHA1 | Date | |
---|---|---|---|
8cb44c0c5d | |||
c55021f30c | |||
783c9e46c2 | |||
b7f33c1fcb | |||
0f578d7c7d | |||
f87b96887c |
@ -4,4 +4,4 @@ bbuilder:
|
|||||||
published:
|
published:
|
||||||
- git submodule update --init
|
- git submodule update --init
|
||||||
- /bin/bash build-stable-deb.sh
|
- /bin/bash build-stable-deb.sh
|
||||||
- sudo /usr/local/bin/deploy-package -C pvc
|
- sudo /usr/local/bin/deploy-package -C pvc -D bookworm
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
## PVC Changelog
|
## PVC Changelog
|
||||||
|
|
||||||
|
###### [v0.9.100](https://github.com/parallelvirtualcluster/pvc/releases/tag/v0.9.100)
|
||||||
|
|
||||||
|
* [API Daemon] Improves the handling of "detect:" disk strings on newer systems by leveraging the "nvme" command
|
||||||
|
* [Client CLI] Update help text about "detect:" disk strings
|
||||||
|
* [Meta] Updates deprecation warnings and updates builder to only add this version for Debian 12 (Bookworm)
|
||||||
|
|
||||||
###### [v0.9.99](https://github.com/parallelvirtualcluster/pvc/releases/tag/v0.9.99)
|
###### [v0.9.99](https://github.com/parallelvirtualcluster/pvc/releases/tag/v0.9.99)
|
||||||
|
|
||||||
**Deprecation Warning**: `pvc vm backup` commands are now deprecated and will be removed in **0.9.100**. Use `pvc vm snapshot` commands instead.
|
**Deprecation Warning**: `pvc vm backup` commands are now deprecated and will be removed in a future version. Use `pvc vm snapshot` commands instead.
|
||||||
**Breaking Change**: The on-disk format of VM snapshot exports differs from backup exports, and the PVC autobackup system now leverages these. It is recommended to start fresh with a new tree of backups for `pvc autobackup` for maximum compatibility.
|
**Breaking Change**: The on-disk format of VM snapshot exports differs from backup exports, and the PVC autobackup system now leverages these. It is recommended to start fresh with a new tree of backups for `pvc autobackup` for maximum compatibility.
|
||||||
**Breaking Change**: VM autobackups now run in `pvcworkerd` instead of the CLI client directly, allowing them to be triggerd from any node (or externally). It is important to apply the timer unit changes from the `pvc-ansible` role after upgrading to 0.9.99 to avoid duplicate runs.
|
**Breaking Change**: VM autobackups now run in `pvcworkerd` instead of the CLI client directly, allowing them to be triggerd from any node (or externally). It is important to apply the timer unit changes from the `pvc-ansible` role after upgrading to 0.9.99 to avoid duplicate runs.
|
||||||
**Usage Note**: VM snapshots are displayed in the `pvc vm list` and `pvc vm info` outputs, not in a unique "list" endpoint.
|
**Usage Note**: VM snapshots are displayed in the `pvc vm list` and `pvc vm info` outputs, not in a unique "list" endpoint.
|
||||||
|
@ -27,7 +27,7 @@ from distutils.util import strtobool as dustrtobool
|
|||||||
import daemon_lib.config as cfg
|
import daemon_lib.config as cfg
|
||||||
|
|
||||||
# Daemon version
|
# Daemon version
|
||||||
version = "0.9.99"
|
version = "0.9.100"
|
||||||
|
|
||||||
# API version
|
# API version
|
||||||
API_VERSION = 1.0
|
API_VERSION = 1.0
|
||||||
|
@ -2028,7 +2028,7 @@ def cli_vm_snapshot_import(
|
|||||||
)
|
)
|
||||||
def cli_vm_backup():
|
def cli_vm_backup():
|
||||||
"""
|
"""
|
||||||
DEPRECATED: Use 'pvc vm snapshot' commands instead. 'pvc vm backup' commands will be removed in PVC 0.9.100.
|
DEPRECATED: Use 'pvc vm snapshot' commands instead. 'pvc vm backup' commands will be removed in a future version.
|
||||||
|
|
||||||
Manage backups of VMs in a PVC cluster.
|
Manage backups of VMs in a PVC cluster.
|
||||||
"""
|
"""
|
||||||
@ -2059,7 +2059,7 @@ def cli_vm_backup():
|
|||||||
)
|
)
|
||||||
def cli_vm_backup_create(domain, backup_path, incremental_parent, retain_snapshot):
|
def cli_vm_backup_create(domain, backup_path, incremental_parent, retain_snapshot):
|
||||||
"""
|
"""
|
||||||
DEPRECATED: Use 'pvc vm snapshot' commands instead. 'pvc vm backup' commands will be removed in PVC 0.9.100.
|
DEPRECATED: Use 'pvc vm snapshot' commands instead. 'pvc vm backup' commands will be removed in a future version.
|
||||||
|
|
||||||
Create a backup of virtual machine DOMAIN to BACKUP_PATH on the cluster primary coordinator. DOMAIN may be a UUID or name.
|
Create a backup of virtual machine DOMAIN to BACKUP_PATH on the cluster primary coordinator. DOMAIN may be a UUID or name.
|
||||||
|
|
||||||
@ -2107,7 +2107,7 @@ def cli_vm_backup_create(domain, backup_path, incremental_parent, retain_snapsho
|
|||||||
)
|
)
|
||||||
def cli_vm_backup_restore(domain, backup_datestring, backup_path, retain_snapshot):
|
def cli_vm_backup_restore(domain, backup_datestring, backup_path, retain_snapshot):
|
||||||
"""
|
"""
|
||||||
DEPRECATED: Use 'pvc vm snapshot' commands instead. 'pvc vm backup' commands will be removed in PVC 0.9.100.
|
DEPRECATED: Use 'pvc vm snapshot' commands instead. 'pvc vm backup' commands will be removed in a future version.
|
||||||
|
|
||||||
Restore the backup BACKUP_DATESTRING of virtual machine DOMAIN stored in BACKUP_PATH on the cluster primary coordinator. DOMAIN may be a UUID or name.
|
Restore the backup BACKUP_DATESTRING of virtual machine DOMAIN stored in BACKUP_PATH on the cluster primary coordinator. DOMAIN may be a UUID or name.
|
||||||
|
|
||||||
@ -2147,7 +2147,7 @@ def cli_vm_backup_restore(domain, backup_datestring, backup_path, retain_snapsho
|
|||||||
@click.argument("backup_path")
|
@click.argument("backup_path")
|
||||||
def cli_vm_backup_remove(domain, backup_datestring, backup_path):
|
def cli_vm_backup_remove(domain, backup_datestring, backup_path):
|
||||||
"""
|
"""
|
||||||
DEPRECATED: Use 'pvc vm snapshot' commands instead. 'pvc vm backup' commands will be removed in PVC 0.9.100.
|
DEPRECATED: Use 'pvc vm snapshot' commands instead. 'pvc vm backup' commands will be removed in a future version.
|
||||||
|
|
||||||
Remove the backup BACKUP_DATESTRING, including snapshots, of virtual machine DOMAIN stored in BACKUP_PATH on the cluster primary coordinator. DOMAIN may be a UUID or name.
|
Remove the backup BACKUP_DATESTRING, including snapshots, of virtual machine DOMAIN stored in BACKUP_PATH on the cluster primary coordinator. DOMAIN may be a UUID or name.
|
||||||
|
|
||||||
@ -3866,8 +3866,6 @@ def cli_storage_osd_create_db_vg(node, device, wait_flag):
|
|||||||
Only one OSD database volume group on a single physical device, named "osd-db", is supported per node, so it must be fast and large enough to act as an effective OSD database device for all OSDs on the node. Attempting to add additional database volume groups after the first will result in an error.
|
Only one OSD database volume group on a single physical device, named "osd-db", is supported per node, so it must be fast and large enough to act as an effective OSD database device for all OSDs on the node. Attempting to add additional database volume groups after the first will result in an error.
|
||||||
|
|
||||||
WARNING: If the OSD database device fails, all OSDs on the node using it will be lost and must be recreated.
|
WARNING: If the OSD database device fails, all OSDs on the node using it will be lost and must be recreated.
|
||||||
|
|
||||||
A "detect" string is a string in the form "detect:<NAME>:<HUMAN-SIZE>:<ID>". Detect strings allow for automatic determination of Linux block device paths from known basic information about disks by leveraging "lsscsi" on the target host. The "NAME" should be some descriptive identifier, for instance the manufacturer (e.g. "INTEL"), the "HUMAN-SIZE" should be the labeled human-readable size of the device (e.g. "480GB", "1.92TB"), and "ID" specifies the Nth 0-indexed device which matches the "NAME" and "HUMAN-SIZE" values (e.g. "2" would match the third device with the corresponding "NAME" and "HUMAN-SIZE"). When matching against sizes, there is +/- 3% flexibility to account for base-1000 vs. base-1024 differences and rounding errors. The "NAME" may contain whitespace but if so the entire detect string should be quoted, and is case-insensitive. More information about detect strings can be found in the manual.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
retcode, retmsg = pvc.lib.storage.ceph_osd_db_vg_add(
|
retcode, retmsg = pvc.lib.storage.ceph_osd_db_vg_add(
|
||||||
@ -3936,7 +3934,7 @@ def cli_storage_osd_add(
|
|||||||
|
|
||||||
DEVICE must be a valid block device path (e.g. '/dev/nvme0n1', '/dev/disk/by-path/...') or a "detect" string. Partitions are NOT supported. A "detect" string is a string in the form "detect:<NAME>:<HUMAN-SIZE>:<ID>". The path or detect string must be valid on the current node housing the OSD.
|
DEVICE must be a valid block device path (e.g. '/dev/nvme0n1', '/dev/disk/by-path/...') or a "detect" string. Partitions are NOT supported. A "detect" string is a string in the form "detect:<NAME>:<HUMAN-SIZE>:<ID>". The path or detect string must be valid on the current node housing the OSD.
|
||||||
|
|
||||||
A "detect" string is a string in the form "detect:<NAME>:<HUMAN-SIZE>:<ID>". Detect strings allow for automatic determination of Linux block device paths from known basic information about disks by leveraging "lsscsi" on the target host. The "NAME" should be some descriptive identifier, for instance the manufacturer (e.g. "INTEL"), the "HUMAN-SIZE" should be the labeled human-readable size of the device (e.g. "480GB", "1.92TB"), and "ID" specifies the Nth 0-indexed device which matches the "NAME" and "HUMAN-SIZE" values (e.g. "2" would match the third device with the corresponding "NAME" and "HUMAN-SIZE"). When matching against sizes, there is +/- 3% flexibility to account for base-1000 vs. base-1024 differences and rounding errors. The "NAME" may contain whitespace but if so the entire detect string should be quoted, and is case-insensitive. More information about detect strings can be found in the pvcbootstrapd manual.
|
A "detect" string is a string in the form "detect:<NAME>:<HUMAN-SIZE>:<ID>". Detect strings allow for automatic determination of Linux block device paths from known basic information about disks by leveraging "lsscsi"/"nvme" on the target host. The "NAME" should be some descriptive identifier that would be part of the device's Model information, for instance the manufacturer (e.g. "INTEL") or a similar unique string (e.g. "BOSS" for Dell BOSS cards); the "HUMAN-SIZE" should be the labeled human-readable size of the device (e.g. "480GB", "1.92TB"); and "ID" specifies the Nth 0-indexed device which matches the "NAME" and "HUMAN-SIZE" values (e.g. "2" would match the third device with the corresponding "NAME" and "HUMAN-SIZE"). When matching against sizes, there is +/- 3% flexibility to account for base-1000 vs. base-1024 differences and rounding errors. The "NAME" may contain whitespace but if so the entire detect string should be quoted, and is case-insensitive. More information about detect strings can be found in the pvcbootstrapd manual.
|
||||||
|
|
||||||
The weight of an OSD should reflect the ratio of the size of the OSD to the other OSDs in the storage cluster. For example, with a 200GB disk and a 400GB disk in each node, the 400GB disk should have twice the weight as the 200GB disk. For more information about CRUSH weights, please see the Ceph documentation.
|
The weight of an OSD should reflect the ratio of the size of the OSD to the other OSDs in the storage cluster. For example, with a 200GB disk and a 400GB disk in each node, the 400GB disk should have twice the weight as the 200GB disk. For more information about CRUSH weights, please see the Ceph documentation.
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ from setuptools import setup
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="pvc",
|
name="pvc",
|
||||||
version="0.9.99",
|
version="0.9.100",
|
||||||
packages=["pvc.cli", "pvc.lib"],
|
packages=["pvc.cli", "pvc.lib"],
|
||||||
install_requires=[
|
install_requires=[
|
||||||
"Click",
|
"Click",
|
||||||
|
@ -26,6 +26,7 @@ import subprocess
|
|||||||
import signal
|
import signal
|
||||||
from json import loads
|
from json import loads
|
||||||
from re import match as re_match
|
from re import match as re_match
|
||||||
|
from re import search as re_search
|
||||||
from re import split as re_split
|
from re import split as re_split
|
||||||
from re import sub as re_sub
|
from re import sub as re_sub
|
||||||
from difflib import unified_diff
|
from difflib import unified_diff
|
||||||
@ -1073,7 +1074,7 @@ def sortInterfaceNames(interface_names):
|
|||||||
#
|
#
|
||||||
# Parse a "detect" device into a real block device name
|
# Parse a "detect" device into a real block device name
|
||||||
#
|
#
|
||||||
def get_detect_device(detect_string):
|
def get_detect_device_lsscsi(detect_string):
|
||||||
"""
|
"""
|
||||||
Parses a "detect:" string into a normalized block device path using lsscsi.
|
Parses a "detect:" string into a normalized block device path using lsscsi.
|
||||||
|
|
||||||
@ -1140,3 +1141,96 @@ def get_detect_device(detect_string):
|
|||||||
break
|
break
|
||||||
|
|
||||||
return blockdev
|
return blockdev
|
||||||
|
|
||||||
|
|
||||||
|
def get_detect_device_nvme(detect_string):
|
||||||
|
"""
|
||||||
|
Parses a "detect:" string into a normalized block device path using nvme.
|
||||||
|
|
||||||
|
A detect string is formatted "detect:<NAME>:<SIZE>:<ID>", where
|
||||||
|
NAME is some unique identifier in lsscsi, SIZE is a human-readable
|
||||||
|
size value to within +/- 3% of the real size of the device, and
|
||||||
|
ID is the Nth (0-indexed) matching entry of that NAME and SIZE.
|
||||||
|
"""
|
||||||
|
|
||||||
|
unit_map = {
|
||||||
|
"kB": 1000,
|
||||||
|
"MB": 1000 * 1000,
|
||||||
|
"GB": 1000 * 1000 * 1000,
|
||||||
|
"TB": 1000 * 1000 * 1000 * 1000,
|
||||||
|
"PB": 1000 * 1000 * 1000 * 1000 * 1000,
|
||||||
|
"EB": 1000 * 1000 * 1000 * 1000 * 1000 * 1000,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, name, _size, idd = detect_string.split(":")
|
||||||
|
if _ != "detect":
|
||||||
|
return None
|
||||||
|
|
||||||
|
size_re = re_search(r"([\d.]+)([kKMGTP]B)", _size)
|
||||||
|
size_val = float(size_re.group(1))
|
||||||
|
size_unit = size_re.group(2)
|
||||||
|
size_bytes = int(size_val * unit_map[size_unit])
|
||||||
|
|
||||||
|
retcode, stdout, stderr = run_os_command("nvme list --output-format json")
|
||||||
|
if retcode:
|
||||||
|
print(f"Failed to run nvme: {stderr}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Parse the output with json
|
||||||
|
nvme_data = loads(stdout).get("Devices", list())
|
||||||
|
|
||||||
|
# Handle size determination (+/- 3%)
|
||||||
|
size = None
|
||||||
|
nvme_sizes = set()
|
||||||
|
for entry in nvme_data:
|
||||||
|
nvme_sizes.add(entry["PhysicalSize"])
|
||||||
|
for l_size in nvme_sizes:
|
||||||
|
plusthreepct = size_bytes * 1.03
|
||||||
|
minusthreepct = size_bytes * 0.97
|
||||||
|
|
||||||
|
if l_size > minusthreepct and l_size < plusthreepct:
|
||||||
|
size = l_size
|
||||||
|
break
|
||||||
|
if size is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
blockdev = None
|
||||||
|
matches = list()
|
||||||
|
for entry in nvme_data:
|
||||||
|
# Skip if name is not contained in the line (case-insensitive)
|
||||||
|
if name.lower() not in entry["ModelNumber"].lower():
|
||||||
|
continue
|
||||||
|
# Skip if the size does not match
|
||||||
|
if size != entry["PhysicalSize"]:
|
||||||
|
continue
|
||||||
|
# Get our blockdev and append to the list
|
||||||
|
matches.append(entry["DevicePath"])
|
||||||
|
|
||||||
|
blockdev = None
|
||||||
|
# Find the blockdev at index {idd}
|
||||||
|
for idx, _blockdev in enumerate(matches):
|
||||||
|
if int(idx) == int(idd):
|
||||||
|
blockdev = _blockdev
|
||||||
|
break
|
||||||
|
|
||||||
|
return blockdev
|
||||||
|
|
||||||
|
|
||||||
|
def get_detect_device(detect_string):
|
||||||
|
"""
|
||||||
|
Parses a "detect:" string into a normalized block device path.
|
||||||
|
|
||||||
|
First tries to parse using "lsscsi" (get_detect_device_lsscsi). If this returns an invalid
|
||||||
|
block device name, then try to parse using "nvme" (get_detect_device_nvme). This works around
|
||||||
|
issues with more recent devices (e.g. the Dell R6615 series) not properly reporting block
|
||||||
|
device paths for NVMe devices with "lsscsi".
|
||||||
|
"""
|
||||||
|
|
||||||
|
device = get_detect_device_lsscsi(detect_string)
|
||||||
|
if device is None or not re_match(r"^/dev", device):
|
||||||
|
device = get_detect_device_nvme(detect_string)
|
||||||
|
|
||||||
|
if device is not None and re_match(r"^/dev", device):
|
||||||
|
return device
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
8
debian/changelog
vendored
8
debian/changelog
vendored
@ -1,3 +1,11 @@
|
|||||||
|
pvc (0.9.100-0) unstable; urgency=high
|
||||||
|
|
||||||
|
* [API Daemon] Improves the handling of "detect:" disk strings on newer systems by leveraging the "nvme" command
|
||||||
|
* [Client CLI] Update help text about "detect:" disk strings
|
||||||
|
* [Meta] Updates deprecation warnings and updates builder to only add this version for Debian 12 (Bookworm)
|
||||||
|
|
||||||
|
-- Joshua M. Boniface <joshua@boniface.me> Fri, 30 Aug 2024 11:03:33 -0400
|
||||||
|
|
||||||
pvc (0.9.99-0) unstable; urgency=high
|
pvc (0.9.99-0) unstable; urgency=high
|
||||||
|
|
||||||
**Deprecation Warning**: `pvc vm backup` commands are now deprecated and will be removed in **0.9.100**. Use `pvc vm snapshot` commands instead.
|
**Deprecation Warning**: `pvc vm backup` commands are now deprecated and will be removed in **0.9.100**. Use `pvc vm snapshot` commands instead.
|
||||||
|
@ -33,7 +33,7 @@ import os
|
|||||||
import signal
|
import signal
|
||||||
|
|
||||||
# Daemon version
|
# Daemon version
|
||||||
version = "0.9.99"
|
version = "0.9.100"
|
||||||
|
|
||||||
|
|
||||||
##########################################################
|
##########################################################
|
||||||
|
@ -49,7 +49,7 @@ import re
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
# Daemon version
|
# Daemon version
|
||||||
version = "0.9.99"
|
version = "0.9.100"
|
||||||
|
|
||||||
|
|
||||||
##########################################################
|
##########################################################
|
||||||
|
@ -52,7 +52,7 @@ from daemon_lib.autobackup import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Daemon version
|
# Daemon version
|
||||||
version = "0.9.99"
|
version = "0.9.100"
|
||||||
|
|
||||||
|
|
||||||
config = cfg.get_configuration()
|
config = cfg.get_configuration()
|
||||||
|
Reference in New Issue
Block a user