From: Filip Schauer <f.schauer@proxmox.com>
To: copystring <copystring@gmail.com>, pve-devel@lists.proxmox.com
Subject: Re: SPAM: [RFC PATCH 1/4] lxc: create: add isolated OCI rootfs preparation
Date: Wed, 15 Jul 2026 14:02:01 +0200 [thread overview]
Message-ID: <517f5e19-4dd5-4b43-af7f-44183ca94c98@proxmox.com> (raw)
In-Reply-To: <20260706194059.280257-2-copystring@gmail.com>
On 09/07/2026 10:21, copystring wrote:
> +my sub oci_rootfs_size_to_gb {
> + my ($size) = @_;
> +
> + my $size_mib = int(($size + 1024 * 1024 - 1) / (1024 * 1024));
> + my $size_gb = sprintf('%.6f', $size_mib / 1024);
> + $size_gb =~ s/0+$//;
> + $size_gb =~ s/\.$//;
> +
> + return $size_gb;
> +}
This looks like a generic utility, not specific to OCI.
> +sub create_oci_rootfs {
> + my ($storage_cfg, $vmid, $archive, $storage, $size, $conf, $rootdir_base) = @_;
> +
> + die "archive '$archive' is not an OCI image archive\n"
> + if !archive_is_oci_format($storage_cfg, $archive);
> +
> + my $size_gb = oci_rootfs_size_to_gb($size);
> + my $rootfs = PVE::LXC::Config->parse_volume('rootfs', $conf->{rootfs});
> + my $new_rootfs_config = {
> + %$rootfs,
> + volume => "$storage:$size_gb",
> + };
> + delete $new_rootfs_config->{type};
> + delete $new_rootfs_config->{size};
> +
> + my $settings = {
> + rootfs => PVE::LXC::Config->print_ct_mountpoint($new_rootfs_config, 1),
> + };
> + my $new_conf = {
> + lxc => oci_config_lxc_copy($conf),
> + };
> + $new_conf->{unprivileged} = $conf->{unprivileged} if exists($conf->{unprivileged});
> +
> + $rootdir_base //= "/var/lib/lxc/$vmid";
> + File::Path::make_path($rootdir_base);
> + my $rootdir = "$rootdir_base/.oci-replace-rootfs";
> +
> + my $vollist = PVE::LXC::create_disks($storage_cfg, $vmid, $settings, $new_conf);
> + my $new_rootfs = PVE::LXC::Config->parse_volume('rootfs', $new_conf->{rootfs});
> + my $new_volid = $new_rootfs->{volume};
> +
> + eval {
> + my (undef, $root_uid, $root_gid) = PVE::LXC::parse_id_maps($conf);
> +
> + $new_conf = PVE::LXC::run_unshared(sub {
> + die "temporary OCI rootfs path '$rootdir' already exists\n" if -e $rootdir;
> +
> + my @mounted;
> + eval {
> + mkdir $rootdir
> + or die "failed to create temporary OCI rootfs path '$rootdir': $!\n";
> +
> + my $mountpoint = { %$new_rootfs, mp => '/', ro => 0 };
> + PVE::LXC::mountpoint_mount(
> + $mountpoint, $rootdir, $storage_cfg, undef, $root_uid, $root_gid,
> + );
> + push @mounted, $rootdir;
> +
> + restore_oci_archive($storage_cfg, $archive, $rootdir, $new_conf);
> + PVE::LXC::Setup->new($new_conf, $rootdir); # detect OS and architecture
> + };
> + my $err = $@;
> + my $cleanup_err = '';
> +
> + foreach my $mount (reverse @mounted) {
> + eval {
> + PVE::Tools::run_command(['/bin/umount', $mount], errfunc => sub { });
> + };
> + $cleanup_err .= "can't unmount temporary OCI rootfs path '$mount': $@\n" if $@;
> + }
> +
> + $cleanup_err .= "failed to remove temporary OCI rootfs path '$rootdir': $!\n"
> + if -d $rootdir && !rmdir $rootdir;
> +
> + die $err if $err;
> + die $cleanup_err if $cleanup_err;
> +
> + return $new_conf;
> + });
> + };
> + if (my $err = $@) {
> + PVE::LXC::destroy_disks($storage_cfg, $vollist);
> + die $err;
> + }
> +
> + return ($new_conf->{rootfs}, $new_volid, $new_conf);
> +}
This looks very similar to PVE::LXC::copy_volume.
> diff --git a/src/test/Makefile b/src/test/Makefile
> index 91ae6ff..8da35ee 100644
> --- a/src/test/Makefile
> +++ b/src/test/Makefile
> @@ -2,7 +2,7 @@ RUN_USERNS := lxc-usernsexec -m "u:0:`id -u`:1" -m "g:0:`id -g`:1" --
>
> all: test
>
> -test: test_setup test_snapshot test_bindmount test_idmap
> +test: test_setup test_snapshot test_bindmount test_idmap test_oci_rootfs_replace
>
> test_setup: run_setup_tests.pl
> if test -e /run/lock/sbuild; then \
> @@ -24,5 +24,7 @@ test_bindmount: bindmount_test.pl
> test_idmap: run_idmap_tests.pl
> ./run_idmap_tests.pl
>
> +test_oci_rootfs_replace: run_oci_rootfs_replace_tests.pl
> + ./run_oci_rootfs_replace_tests.pl
> clean:
> rm -rf tmprootfs
Tests should be factored out into a separate patch.
next prev parent reply other threads:[~2026-07-15 12:02 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-06 19:40 SPAM: [RFC PATCH 0/4] lxc: add safe OCI rootfs replacement copystring
2026-07-06 19:40 ` SPAM: [RFC PATCH 1/4] lxc: create: add isolated OCI rootfs preparation copystring
2026-07-15 12:02 ` Filip Schauer [this message]
2026-07-06 19:40 ` SPAM: [RFC PATCH 2/4] api: lxc: add OCI rootfs replacement endpoint copystring
2026-07-06 19:40 ` SPAM: [RFC PATCH 3/4] pct: add OCI rootfs replacement command copystring
2026-07-06 19:40 ` SPAM: [RFC PATCH 4/4] test: cover OCI rootfs replacement API transaction copystring
2026-07-06 19:40 ` SPAM: [RFC PATCH pve-manager] lxc: add OCI rootfs replacement window copystring
2026-07-06 19:40 ` SPAM: [RFC PATCH pve-docs] pct: document OCI rootfs replacement semantics copystring
2026-07-14 13:23 ` [RFC PATCH 0/4] lxc: add safe OCI rootfs replacement Filip Schauer
-- strict thread matches above, loose matches on Subject: below --
2026-07-06 19:39 SPAM: " copystring
2026-07-06 19:39 ` SPAM: [RFC PATCH 1/4] lxc: create: add isolated OCI rootfs preparation copystring
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=517f5e19-4dd5-4b43-af7f-44183ca94c98@proxmox.com \
--to=f.schauer@proxmox.com \
--cc=copystring@gmail.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.