Compare commits
10 Commits
8ce79d86bb
...
7fcf6e29bf
| Author | SHA1 | Date | |
|---|---|---|---|
| 7fcf6e29bf | |||
| 6f49432acc | |||
| 28268eabaa | |||
| d11122d7f9 | |||
| 80770ef49e | |||
| 5001f03269 | |||
| bb958344ec | |||
| a52a1ef526 | |||
| 035a734463 | |||
| c45b9b430a |
25
debian/changelog
vendored
25
debian/changelog
vendored
@ -1,3 +1,28 @@
|
||||
libpve-storage-perl (9.1.0) trixie; urgency=medium
|
||||
|
||||
* import/export formats: fix regression for import/export of 'images'
|
||||
content. This affected offline migration of guest volumes.
|
||||
|
||||
* lvm plugin: fix hanging on the storage lock when doing a snapshot rollback
|
||||
through the CLI.
|
||||
|
||||
* fix #6900: accept all API tokens that are valid for Proxmox Backup Server,
|
||||
which is slightly more flexible than the implementation in Proxmox VE.
|
||||
|
||||
-- Proxmox Support Team <support@proxmox.com> Thu, 20 Nov 2025 14:59:42 +0100
|
||||
|
||||
libpve-storage-perl (9.0.18) trixie; urgency=medium
|
||||
|
||||
* api: OCI image download improvements:
|
||||
- use temporary file and only rename to real one if pulling the image
|
||||
finished successfully.
|
||||
- forbid to override existing files.
|
||||
- improve reference regex to allow more safe characters, like e.g. '-',
|
||||
in the image name.
|
||||
- allow one to override the target filename for the image.
|
||||
|
||||
-- Proxmox Support Team <support@proxmox.com> Mon, 17 Nov 2025 21:53:43 +0100
|
||||
|
||||
libpve-storage-perl (9.0.17) trixie; urgency=medium
|
||||
|
||||
* api: add endpoint to pull OCI images from a OCI registry directly to a
|
||||
|
||||
@ -977,8 +977,8 @@ __PACKAGE__->register_method({
|
||||
|
||||
local $SIG{INT} = sub {
|
||||
unlink "$path/$tmp_filename"
|
||||
or warn "could not cleanup temporary file: $!"
|
||||
if -e "$path/$tmp_filename";
|
||||
or $!{ENOENT}
|
||||
or warn "could not cleanup temporary file: $!";
|
||||
die "got interrupted by signal\n";
|
||||
};
|
||||
|
||||
|
||||
@ -561,10 +561,12 @@ sub get_disks {
|
||||
# - vdX virtIO block device
|
||||
# - xvdX: xen virtual block device
|
||||
# - nvmeXnY: nvme devices
|
||||
# - pmemXsY: pmem devices
|
||||
# - cciss!cXnY cciss devices
|
||||
return
|
||||
if $dev !~ m/^(h|s|x?v)d[a-z]+$/
|
||||
&& $dev !~ m/^nvme\d+n\d+$/
|
||||
&& $dev !~ m/^pmem\d+s\d+$/
|
||||
&& $dev !~ m/^cciss\!c\d+d\d+$/;
|
||||
|
||||
my $data = get_udev_info("/sys/block/$dev") // return;
|
||||
|
||||
@ -1117,23 +1117,17 @@ sub volume_rollback_is_possible {
|
||||
}
|
||||
|
||||
my sub volume_snapshot_rollback_locked {
|
||||
my ($class, $scfg, $storeid, $volname, $snap) = @_;
|
||||
my ($class, $scfg, $storeid, $volname, $snap, $cleanup_worker) = @_;
|
||||
|
||||
my $format = ($class->parse_volname($volname))[6];
|
||||
|
||||
die "can't rollback snapshot for '$format' volume\n" if $format ne 'qcow2';
|
||||
|
||||
my $cleanup_worker = eval { free_snap_image($class, $storeid, $scfg, $volname, 'current'); };
|
||||
$cleanup_worker->$* = eval { free_snap_image($class, $storeid, $scfg, $volname, 'current'); };
|
||||
die "error deleting snapshot $snap $@\n" if $@;
|
||||
|
||||
eval { alloc_snap_image($class, $storeid, $scfg, $volname, $snap) };
|
||||
my $alloc_err = $@;
|
||||
|
||||
fork_cleanup_worker($cleanup_worker);
|
||||
|
||||
if ($alloc_err) {
|
||||
die "can't allocate new volume $volname: $alloc_err\n";
|
||||
}
|
||||
die "can't allocate new volume $volname: $@\n" if $@;
|
||||
|
||||
return undef;
|
||||
}
|
||||
@ -1141,14 +1135,29 @@ my sub volume_snapshot_rollback_locked {
|
||||
sub volume_snapshot_rollback {
|
||||
my ($class, $scfg, $storeid, $volname, $snap) = @_;
|
||||
|
||||
return $class->cluster_lock_storage(
|
||||
$storeid,
|
||||
$scfg->{shared},
|
||||
undef,
|
||||
sub {
|
||||
return volume_snapshot_rollback_locked($class, $scfg, $storeid, $volname, $snap);
|
||||
},
|
||||
);
|
||||
my $cleanup_worker;
|
||||
|
||||
eval {
|
||||
$class->cluster_lock_storage(
|
||||
$storeid,
|
||||
$scfg->{shared},
|
||||
undef,
|
||||
sub {
|
||||
volume_snapshot_rollback_locked(
|
||||
$class, $scfg, $storeid, $volname, $snap, \$cleanup_worker,
|
||||
);
|
||||
},
|
||||
);
|
||||
};
|
||||
my $err = $@;
|
||||
|
||||
# Spawn outside of the locked section, because with 'saferemove', the cleanup worker also needs
|
||||
# to obtain the lock, and in CLI context, it will be awaited synchronously, see fork_worker().
|
||||
fork_cleanup_worker($cleanup_worker);
|
||||
|
||||
die $err if $err;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub volume_snapshot_delete {
|
||||
|
||||
@ -701,6 +701,20 @@ my sub snapshot_files_encrypted {
|
||||
return $any && $all;
|
||||
}
|
||||
|
||||
my sub auth_id_is_api_token {
|
||||
my ($auth_id) = @_;
|
||||
|
||||
# NOTE: We cannot use the PVE token regexes as we're stricter in PVE, so some tokens that would
|
||||
# be valid for PBS would get rejected. Adapt over the PBS ones from proxmox-auth-api types
|
||||
my $pbs_safe_id_regex = qr/(?:[A-Za-z0-9_][A-Za-z0-9\._\-]*)/;
|
||||
my $pbs_token_name_regex = $pbs_safe_id_regex;
|
||||
my $pbs_user_name_regex = qr/(?:[^\s:\/\p{PosixCntrl}]+)/;
|
||||
my $pbs_user_id_regex = qr/${pbs_user_name_regex}\@${pbs_safe_id_regex}/;
|
||||
my $pbs_apitoken_id_regex = qr/${pbs_user_id_regex}\!${pbs_token_name_regex}/;
|
||||
|
||||
return $auth_id =~ qr/^${pbs_apitoken_id_regex}$/;
|
||||
}
|
||||
|
||||
# TODO: use a client with native rust/proxmox-backup bindings to profit from
|
||||
# API schema checks and types
|
||||
my sub pbs_api_connect {
|
||||
@ -708,13 +722,13 @@ my sub pbs_api_connect {
|
||||
|
||||
my $params = {};
|
||||
|
||||
my $user = $scfg->{username} // 'root@pam';
|
||||
my $auth_id = $scfg->{username} // 'root@pam';
|
||||
|
||||
if (my $tokenid = PVE::AccessControl::pve_verify_tokenid($user, 1)) {
|
||||
$params->{apitoken} = "PBSAPIToken=${tokenid}:${password}";
|
||||
if (auth_id_is_api_token($auth_id)) {
|
||||
$params->{apitoken} = "PBSAPIToken=${auth_id}:${password}";
|
||||
} else {
|
||||
$params->{password} = $password;
|
||||
$params->{username} = $user;
|
||||
$params->{username} = $auth_id;
|
||||
}
|
||||
|
||||
if (my $fp = $scfg->{fingerprint}) {
|
||||
|
||||
@ -2164,7 +2164,7 @@ sub volume_export_formats {
|
||||
return ();
|
||||
}
|
||||
return ('tar+size') if $format eq 'subvol';
|
||||
return ('raw+size') if $vtype =~ /^(iso|snippets|vztmpl|import)$/;
|
||||
return ('raw+size') if $vtype =~ /^(images|iso|snippets|vztmpl|import)$/;
|
||||
}
|
||||
return ();
|
||||
}
|
||||
@ -2277,7 +2277,7 @@ sub volume_import_formats {
|
||||
return ();
|
||||
}
|
||||
return ('tar+size') if $format eq 'subvol';
|
||||
return ('raw+size') if $vtype =~ /^(iso|snippets|vztmpl|import)$/;
|
||||
return ('raw+size') if $vtype =~ /^(images|iso|snippets|vztmpl|import)$/;
|
||||
}
|
||||
return ();
|
||||
}
|
||||
|
||||
@ -48,6 +48,14 @@ my $tests = [
|
||||
#
|
||||
# container templates
|
||||
#
|
||||
{
|
||||
description => 'Container template tar',
|
||||
volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar',
|
||||
expected => [
|
||||
'vztmpl', 'debian-10.0-standard_10.0-1_amd64.tar', undef, undef, undef, undef,
|
||||
'raw',
|
||||
],
|
||||
},
|
||||
{
|
||||
description => 'Container template tar.gz',
|
||||
volname => 'vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz',
|
||||
|
||||
Reference in New Issue
Block a user