]> git.proxmox.com Git - aab.git/blobdiff - PVE/AAB.pm
split out writing (host-side) pacman.conf
[aab.git] / PVE / AAB.pm
index 77410adf6bd2b4d59fc6e97d39b64ca8fa1f66ab..ccac7f2e00ea50a90b8412feab5777031c567aee 100644 (file)
@@ -11,17 +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
-                       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";
 
@@ -229,17 +231,27 @@ sub initialize {
        die "no sources/mirrors specified";
     }
 
+    $self->write_pacman_conf();
+
+    $self->logmsg("configured VE $self->{veid}\n");
+}
+
+sub write_pacman_conf {
+    my ($self) = @_;
+
+    my $config = $self->{config};
+
     $config->{source} //= [];
     $config->{mirror} //= [];
 
-    my $servers = "Server = "
-                . join("\nServer = ", @{$config->{source}}, @{$config->{mirror}})
-                . "\n";
+    my $servers = "Server = ".join("\nServer = ", @{$config->{source}}, @{$config->{mirror}}) ."\n";
+
+    my $fh = IO::File->new($self->{'pacman.conf'}, 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
@@ -255,13 +267,9 @@ $servers
 $servers
 EOF
 
-    if ($config->{architecture} eq 'x86_64') {
-       print $fh "[multilib]\n$servers\n";
-    }
-
-    mkdir $self->{rootfs} || die "unable to create rootfs - $!";
+    print $fh "[multilib]\n$servers\n" if $config->{architecture} eq 'x86_64';
 
-    $self->logmsg("configured VE $self->{veid}\n");
+    close($fh);
 }
 
 sub ve_status {
@@ -321,7 +329,7 @@ sub ve_init {
     }
 
     rmtree $self->{rootfs};
-    mkpath $self->{rootfs};
+    mkpath "$self->{rootfs}/dev";
 }
 
 sub ve_command {
@@ -456,6 +464,12 @@ sub cache_packages {
     $self->run_command([@pacman, '-Sw', '--', @$packages]);
 }
 
+sub mask_systemd_unit {
+    my ($self, $unit) = @_;
+    my $root = $self->{rootfs};
+    symln '/dev/null', "$root/etc/systemd/system/$unit";
+}
+
 sub bootstrap {
     my ($self, $include, $exclude) = @_;
     my $root = $self->{rootfs};
@@ -517,6 +531,9 @@ sub bootstrap {
     $self->cache_packages($packages);
     #$self->copy_packages();
 
+    print "Creating device nodes for package manager...\n";
+    $self->create_dev();
+
     print "Installing package manager and essentials...\n";
     # inetutils for 'hostname' for our init
     $self->run_command([@pacman, '-S', 'pacman', 'inetutils', 'archlinux-keyring']);
@@ -532,39 +549,55 @@ sub bootstrap {
     print "Populating keyring...\n";
     $self->populate_keyring();
 
+    print "Removing device nodes...\n";
+    $self->cleanup_dev();
+
     print "Starting container...\n";
     $self->start_container();
 
     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)) {
+       $self->mask_systemd_unit($unit);
+    }
 }
 
-sub populate_keyring {
+# devices needed for gnupg to function:
+my $devs = {
+    '/dev/null'    => ['c', '1', '3'],
+    '/dev/random'  => ['c', '1', '9'], # fake /dev/random (really urandom)
+    '/dev/urandom' => ['c', '1', '9'],
+    '/dev/tty'     => ['c', '5', '0'],
+};
+
+sub cleanup_dev {
     my ($self) = @_;
     my $root = $self->{rootfs};
 
-    # devices needed for gnupg to function:
-    my $devs = {
-       '/dev/null'    => ['c', '1', '3'],
-       '/dev/random'  => ['c', '1', '9'], # fake /dev/random (really urandom)
-       '/dev/urandom' => ['c', '1', '9'],
-       '/dev/tty'     => ['c', '5', '0'],
-    };
+    # remove temporary device files
+    unlink "${root}$_" foreach keys %$devs;
+}
 
-    my $cleanup_dev = sub {
-       # remove temporary device files
-       unlink "${root}$_" foreach keys %$devs;
-    };
-    local $SIG{INT} = $SIG{TERM} = $cleanup_dev;
+sub create_dev {
+    my ($self) = @_;
+    my $root = $self->{rootfs};
+
+    local $SIG{INT} = $SIG{TERM} = sub { $self->cleanup_dev; };
 
-    # at least /dev/null exists as regular file after installing the filesystem package,
-    # and we want to replace /dev/random, so delete devices first
-    &$cleanup_dev();
+    # we want to replace /dev/random, so delete devices first
+    $self->cleanup_dev();
 
     foreach my $dev (keys %$devs) {
        my ($type, $major, $minor) = @{$devs->{$dev}};
        system('mknod', "${root}${dev}", $type, $major, $minor);
     }
+}
+
+sub populate_keyring {
+    my ($self) = @_;
+    my $root = $self->{rootfs};
 
     # generate weak master key and populate the keyring
     system('unshare', '--fork', '--pid', 'chroot', "$root", 'pacman-key', '--init') == 0
@@ -572,9 +605,6 @@ sub populate_keyring {
     system('unshare', '--fork', '--pid', 'chroot', "$root", 'pacman-key', '--populate') == 0
        or die "failed to populate keyring: $?";
 
-    &$cleanup_dev();
-    # reset to original state
-    system('touch', "$root/dev/null");
 }
 
 sub install {
@@ -614,7 +644,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 "unkown compressor '$compressor'!\n";
+       }
+    }
+
     my $rootdir = $self->{rootfs};
 
     print "Stopping container...\n";
@@ -635,19 +677,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 {
@@ -675,6 +728,8 @@ sub clean {
     unlink $self->{'pacman.conf'};
     $self->ve_destroy();
     unlink '.veid';
+    unlink $self->{veconffile};
+
     rmtree $self->{pkgcache} if $all;
 }