On Wed, Jul 09, 2025 at 02:34:21PM +0200, Filip Schauer wrote: > This aims to add basic support for the Open Container Initiative image > format according to the specification. [0] > > [0] https://github.com/opencontainers/image-spec/blob/main/spec.md > > Signed-off-by: Filip Schauer <f.scha...@proxmox.com> > --- > This patch depends on changes made to proxmox-perl-rs in patch 03/13. > Meaning that proxmox-perl-rs needs to be bumped and a dependency & build > dependency to libpve-rs-perl needs to be added to debian/control. > > Changed since v2: > * rebase onto newest master (5a8b3f962f16) and re-format with > proxmox-perltidy > * check whether archive is an OCI image before trying to parse it as one > > Changed since v1: > * fix entrypoint command missing Cmd > * set lxc.signal.halt according to StopSignal (Fixes container shutdown) > > src/PVE/API2/LXC.pm | 96 ++++++++++++++++++++++++++++++++++++++++----- > 1 file changed, 86 insertions(+), 10 deletions(-) > > diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm > index 28f7fdd..45c5cef 100644 > --- a/src/PVE/API2/LXC.pm > +++ b/src/PVE/API2/LXC.pm > @@ -19,9 +19,11 @@ use PVE::Storage; > use PVE::RESTHandler; > use PVE::RPCEnvironment; > use PVE::ReplicationConfig; > +use PVE::RS::OCI; > use PVE::LXC; > use PVE::LXC::Create; > use PVE::LXC::Migrate; > +use PVE::LXC::Namespaces; > use PVE::GuestHelpers; > use PVE::VZDump::Plugin; > use PVE::API2::LXC::Config; > @@ -523,19 +525,93 @@ __PACKAGE__->register_method({ > > eval { > my $rootdir = PVE::LXC::mount_all($vmid, $storage_cfg, > $conf, 1); > + my $archivepath = > PVE::Storage::abs_filesystem_path($storage_cfg, $archive);
^ This should probably not happen when $archive is '-'. > $bwlimit = PVE::Storage::get_bandwidth_limit( > 'restore', [keys %used_storages], $bwlimit, > ); > - print "restoring '$archive' now..\n" > - if $restore && $archive ne '-'; > - PVE::LXC::Create::restore_archive( > - $storage_cfg, > - $archive, > - $rootdir, > - $conf, > - $ignore_unpack_errors, > - $bwlimit, > - ); > + my $is_oci = 0; > + > + if ($restore && $archive ne '-') { > + print "restoring '$archive' now..\n"; > + } elsif ($archivepath =~ /\.tar$/) { > + # Check whether archive is an OCI image > + my $has_oci_layout = 0; > + my $has_index_json = 0; > + my $has_blobs = 0; > + PVE::Tools::run_command( > + ['tar', '-tf', $archivepath], > + outfunc => sub { > + my $line = shift; > + $has_oci_layout = 1 if $line =~ > /^oci-layout$/m; > + $has_index_json = 1 if $line =~ > /^index\.json$/m; ^ The above 2 comparisons can just use `eq` instead of regexes. > + $has_blobs = 1 if $line =~ /^blobs\//m; > + }, > + ); > + > + $is_oci = 1 if $has_oci_layout && $has_index_json && > $has_blobs; > + } > + > + if ($is_oci) { > + # Extract the OCI image > + my ($id_map, undef, undef) = > PVE::LXC::parse_id_maps($conf); > + my $oci_config = PVE::LXC::Namespaces::run_in_userns( > + sub { > + PVE::RS::OCI::parse_and_extract_image( > + $archivepath, $rootdir, > + ); > + }, > + $id_map, > + ); > + > + # Set the entrypoint and arguments if specified by > the OCI image > + my @init_cmd = (); > + push(@init_cmd, @{ $oci_config->{Entrypoint} }) > + if $oci_config->{Entrypoint}; > + push(@init_cmd, @{ $oci_config->{Cmd} }) if > $oci_config->{Cmd}; > + if (@init_cmd) { > + my $init_cmd_str = shift(@init_cmd); > + if (@init_cmd) { > + $init_cmd_str .= ' '; > + $init_cmd_str .= join( > + ' ', > + map { > + my $s = $_; > + $s =~ s/"/\\"/g; > + qq{"$_"} > + } @init_cmd, > + ); > + } > + if ($init_cmd_str ne '/sbin/init') { > + push @{ $conf->{lxc} }, ['lxc.init.cmd', > $init_cmd_str]; > + > + # An entrypoint other than /sbin/init breaks > the tty console mode. > + # This is fixed by setting cmode: console > + $conf->{cmode} = 'console'; > + } > + } > + > + push @{ $conf->{lxc} }, ['lxc.init.cwd', > $oci_config->{WorkingDir}] > + if ($oci_config->{WorkingDir}); > + > + if (my $envs = $oci_config->{Env}) { > + for my $env (@{$envs}) { > + push @{ $conf->{lxc} }, ['lxc.environment', > $env]; ^ As mentioned in the lxcfs patch - we cannot do this. We could copy a small statically linked executable which reads environment and init.cmd from a file, uses `setenv(3)` for each variable before running `execv(3) (place them in the container as /.pve.init and /.pve.env for example) > + } > + } > + > + my $stop_signal = $oci_config->{StopSignal} // > "SIGTERM"; > + push @{ $conf->{lxc} }, ['lxc.signal.halt', > $stop_signal]; > + } else { > + # Not an OCI image, so restore it as an LXC image > instead > + PVE::LXC::Create::restore_archive( > + $storage_cfg, > + $archive, > + $rootdir, > + $conf, > + $ignore_unpack_errors, > + $bwlimit, > + ); > + } > > if ($restore) { > print "merging backed-up and given > configuration..\n"; > -- > 2.47.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel