]> git.proxmox.com Git - aab.git/blobdiff - PVE/AAB.pm
mask systemd-journald-audit.socket
[aab.git] / PVE / AAB.pm
index 072a495ad3f6c981a7beecaf5aadbbdd2d86762f..14a65da98d9f46c942228638b37b39aaecdd39a7 100644 (file)
@@ -11,18 +11,19 @@ use IPC::Open2;
 use IPC::Open3;
 use UUID;
 use Cwd;
-
-my @BASE_PACKAGES = qw(base openssh);
-my @BASE_EXCLUDES = qw(e2fsprogs
-                       jfsutils
-                       linux
-                       linux-firmware
-                       lvm2
-                       mdadm
-                       netctl
-                       pcmciautils
-                       reiserfsprogs
-                       xfsprogs);
+my @BASE_PACKAGES = qw(base openssh vi nano);
+my @BASE_EXCLUDES = qw(
+    e2fsprogs
+    jfsutils
+    linux
+    linux-firmware
+    lvm2
+    mdadm
+    netctl
+    pcmciautils
+    reiserfsprogs
+    xfsprogs
+);
 
 my $PKGDIR = "/var/cache/pacman/pkg";
 
@@ -49,6 +50,17 @@ sub write_file {
     $fh->close;
 }
 
+sub read_file {
+    my ($filename) = @_;
+
+    my $fh = IO::File->new ("<$filename") or die "failed to read $filename - $!\n";
+    my $rec = '';
+    while (defined (my $line = <$fh>)) {
+       $rec .= $line;
+    };
+    return $rec;
+}
+
 sub copy_file {
     my ($a, $b) = @_;
     copy($a, $b) or die "failed to copy $a => $b: $!";
@@ -230,23 +242,36 @@ sub initialize {
        die "no sources/mirrors specified";
     }
 
+    $self->write_pacman_conf();
+
+    $self->logmsg("configured VE $self->{veid}\n");
+}
+
+sub write_pacman_conf {
+    my ($self, $config_fn, $siglevel) = @_;
+
+    my $config = $self->{config};
+
     $config->{source} //= [];
     $config->{mirror} //= [];
 
-    my $servers = "Server = "
-                . join("\nServer = ", @{$config->{source}}, @{$config->{mirror}})
-                . "\n";
+    $siglevel ||= "Never";
+    $config_fn ||= $self->{'pacman.conf'};
+
+    my $servers = "Server = ".join("\nServer = ", @{$config->{source}}, @{$config->{mirror}}) ."\n";
+
+    my $fh = IO::File->new($config_fn, O_WRONLY | O_CREAT | O_EXCL)
+        or die "unable to write pacman config file $self->{'pacman.conf'} - $!";
 
-    $fh = IO::File->new($self->{'pacman.conf'}, O_WRONLY|O_CREAT|O_EXCL) ||
-       die "unable to write pacman config file $self->{'pacman.conf'} - $!";
     my $arch = $config->{architecture};
     $arch = 'x86_64' if $arch eq 'amd64';
+
     print $fh <<"EOF";
 [options]
 HoldPkg = pacman glibc
 Architecture = $arch
 CheckSpace
-SigLevel = Never
+SigLevel = $siglevel
 
 [core]
 $servers
@@ -256,11 +281,9 @@ $servers
 $servers
 EOF
 
-    if ($config->{architecture} eq 'x86_64') {
-       print $fh "[multilib]\n$servers\n";
-    }
+    print $fh "[multilib]\n$servers\n" if $config->{architecture} eq 'x86_64';
 
-    $self->logmsg("configured VE $self->{veid}\n");
+    close($fh);
 }
 
 sub ve_status {
@@ -358,7 +381,7 @@ sub ve_exec {
 }
 
 sub run_command {
-    my ($self, $cmd, $input, $getoutput) = @_;
+    my ($self, $cmd, $input, $getoutput, $noerr) = @_;
 
     my $reader = IO::File->new();
     my $writer = IO::File->new();
@@ -419,9 +442,9 @@ sub run_command {
     waitpid ($pid, 0);
     my $ec = ($? >> 8);
 
-    die "command '$cmdstr' failed with exit code $ec\n" if $ec;
+    die "command '$cmdstr' failed with exit code $ec\n" if $ec && !$noerr;
 
-    return $res;
+    return wantarray ? ($res, $ec) : $res;
 }
 
 sub start_container {
@@ -438,21 +461,32 @@ sub stop_container {
 }
 
 sub pacman_command {
-    my ($self) = @_;
+    my ($self, $config_fn) = @_;
     my $root = $self->{rootfs};
-    return ('/usr/bin/pacman',
-            '--root', $root,
-            '--config', $self->{'pacman.conf'},
-            '--cachedir', $self->{pkgcache},
-            '--noconfirm');
+    return (
+        '/usr/bin/pacman',
+        '--root', $root,
+        '--config', $config_fn || $self->{'pacman.conf'},
+        '--cachedir', $self->{pkgcache},
+        '--noconfirm',
+    );
 }
 
 sub cache_packages {
     my ($self, $packages) = @_;
     my $root = $self->{rootfs};
 
-    my @pacman = $self->pacman_command();
-    $self->run_command([@pacman, '-Sw', '--', @$packages]);
+    $self->write_pacman_conf('pacman.caching.conf', "Optional");
+    my @pacman = $self->pacman_command('pacman.caching.conf');
+    my ($_res, $ec) = $self->run_command([@pacman, '-Sw', '--', @$packages], undef, undef, 1);
+    $self->logmsg("ignore bad exit $ec due to unavailable keyring, the CT will verify that later.\n")
+       if $ec;
+}
+
+sub mask_systemd_unit {
+    my ($self, $unit) = @_;
+    my $root = $self->{rootfs};
+    symln '/dev/null', "$root/etc/systemd/system/$unit";
 }
 
 sub bootstrap {
@@ -542,6 +576,11 @@ sub bootstrap {
 
     print "Installing packages...\n";
     $self->ve_command(['pacman', '-S', '--needed', '--noconfirm', '--', @$packages]);
+
+    print "Masking problematic systemd units...\n";
+    for  my $unit (qw(sys-kernel-config.mount sys-kernel-debug.mount systemd-journald-audit.socket)) {
+       $self->mask_systemd_unit($unit);
+    }
 }
 
 # devices needed for gnupg to function:
@@ -624,7 +663,19 @@ sub write_config {
 }
 
 sub finalize {
-    my ($self) = @_;
+    my ($self, $compressor) = @_;
+
+    my $use_zstd = 1;
+    if (defined($compressor)) {
+       if ($compressor =~ /^\s*--zstd?\s*$/) {
+           $use_zstd = 1;
+       } elsif ($compressor =~ /^\s*--(?:gz|gzip)\s*$/) {
+           $use_zstd = 0; # just boolean for now..
+       } else {
+           die "finalize: unknown compressor '$compressor'!\n";
+       }
+    }
+
     my $rootdir = $self->{rootfs};
 
     print "Stopping container...\n";
@@ -635,6 +686,11 @@ sub finalize {
     unlink $file;
     rename_file($file.'.aab_orig', $file);
 
+    # experienced user can change it anytime and others do well to start out with an updatable system..
+    my $mirrors = eval { read_file($file) } // '';
+    $mirrors = "\nServer = https://geo.mirror.pkgbuild.com/\$repo/os/\$arch\n\n" . $mirrors;
+    write_file($mirrors, $file, 0644);
+
     print "Removing weak temporary pacman keyring...\n";
     rmtree("$rootdir/etc/pacman.d/gnupg");
 
@@ -645,19 +701,30 @@ sub finalize {
     } else {
        die "unable to detect size\n";
     }
-    $self->logmsg ("$size MB\n");
+    $self->logmsg ("uncompressed size: $size MB\n");
 
     $self->write_config ("$rootdir/etc/appliance.info", $size);
 
     $self->logmsg ("creating final appliance archive\n");
 
+    my $compressor_ext = $use_zstd ? 'zst' : 'gz';
+
     my $target = "$self->{targetname}.tar";
     unlink $target;
-    unlink "$target.gz";
+    unlink "$target.$compressor_ext";
 
     $self->run_command ("tar cpf $target --numeric-owner -C '$rootdir' ./etc/appliance.info");
     $self->run_command ("tar rpf $target --numeric-owner -C '$rootdir' --exclude ./etc/appliance.info .");
-    $self->run_command ("gzip $target");
+
+    $self->logmsg ("compressing archive ($compressor_ext)\n");
+    if ($use_zstd) {
+       $self->run_command ("zstd -19 --rm $target");
+    } else {
+       $self->run_command ("gzip -9 $target");
+    }
+
+    my $target_size = int(-s "$target.$compressor_ext") >> 20;
+    $self->logmsg ("created '$target.$compressor_ext' with size: $target_size MB\n");
 }
 
 sub enter {
@@ -682,7 +749,7 @@ sub clean {
     my ($self, $all) = @_;
 
     unlink $self->{logfile};
-    unlink $self->{'pacman.conf'};
+    unlink $self->{'pacman.conf'}, 'pacman.caching.conf';
     $self->ve_destroy();
     unlink '.veid';
     unlink $self->{veconffile};