refactor initial device creation for pacman

`aab` installs `archlinux-keyring`, which in turn invokes `dirmngr` during
installation. `dirmngr` needs access (at least) to '/dev/null' (see [0]), which
`aab` only created afterwards (before populating the keyring). This lead to
`dirmngr` spinning (and filling the filesystem with a regular file
'${rootfs}/dev/null' containing error messages.

This patch changes the behavior of aab: it now creates the devices before
installing 'archlinux-keyring' and removes them after the keyring is populated.

In order to save one further `mkdir` call for the 'dev' directory, this was
appended to the `mkpath` invocation in ve_init.

[0] https://bbs.archlinux.org/viewtopic.php?id=222002

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
This commit is contained in:
Stoiko Ivanov 2019-04-25 19:53:57 +02:00 committed by Thomas Lamprecht
parent 149d977340
commit 01756eba20
1 changed files with 31 additions and 20 deletions

View File

@ -320,7 +320,7 @@ sub ve_init {
} }
rmtree $self->{rootfs}; rmtree $self->{rootfs};
mkpath $self->{rootfs}; mkpath "$self->{rootfs}/dev";
} }
sub ve_command { sub ve_command {
@ -516,6 +516,9 @@ sub bootstrap {
$self->cache_packages($packages); $self->cache_packages($packages);
#$self->copy_packages(); #$self->copy_packages();
print "Creating device nodes for package manager...\n";
$self->create_dev();
print "Installing package manager and essentials...\n"; print "Installing package manager and essentials...\n";
# inetutils for 'hostname' for our init # inetutils for 'hostname' for our init
$self->run_command([@pacman, '-S', 'pacman', 'inetutils', 'archlinux-keyring']); $self->run_command([@pacman, '-S', 'pacman', 'inetutils', 'archlinux-keyring']);
@ -531,6 +534,9 @@ sub bootstrap {
print "Populating keyring...\n"; print "Populating keyring...\n";
$self->populate_keyring(); $self->populate_keyring();
print "Removing device nodes...\n";
$self->cleanup_dev();
print "Starting container...\n"; print "Starting container...\n";
$self->start_container(); $self->start_container();
@ -538,32 +544,40 @@ sub bootstrap {
$self->ve_command(['pacman', '-S', '--needed', '--noconfirm', '--', @$packages]); $self->ve_command(['pacman', '-S', '--needed', '--noconfirm', '--', @$packages]);
} }
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 ($self) = @_;
my $root = $self->{rootfs}; my $root = $self->{rootfs};
# devices needed for gnupg to function: # remove temporary device files
my $devs = { unlink "${root}$_" foreach keys %$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'],
};
my $cleanup_dev = sub { sub create_dev {
# remove temporary device files my ($self) = @_;
unlink "${root}$_" foreach keys %$devs; my $root = $self->{rootfs};
};
local $SIG{INT} = $SIG{TERM} = $cleanup_dev;
# at least /dev/null exists as regular file after installing the filesystem package, local $SIG{INT} = $SIG{TERM} = sub { $self->cleanup_dev; };
# 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) { foreach my $dev (keys %$devs) {
my ($type, $major, $minor) = @{$devs->{$dev}}; my ($type, $major, $minor) = @{$devs->{$dev}};
system('mknod', "${root}${dev}", $type, $major, $minor); system('mknod', "${root}${dev}", $type, $major, $minor);
} }
}
sub populate_keyring {
my ($self) = @_;
my $root = $self->{rootfs};
# generate weak master key and populate the keyring # generate weak master key and populate the keyring
system('unshare', '--fork', '--pid', 'chroot', "$root", 'pacman-key', '--init') == 0 system('unshare', '--fork', '--pid', 'chroot', "$root", 'pacman-key', '--init') == 0
@ -571,9 +585,6 @@ sub populate_keyring {
system('unshare', '--fork', '--pid', 'chroot', "$root", 'pacman-key', '--populate') == 0 system('unshare', '--fork', '--pid', 'chroot', "$root", 'pacman-key', '--populate') == 0
or die "failed to populate keyring: $?"; or die "failed to populate keyring: $?";
&$cleanup_dev();
# reset to original state
system('touch', "$root/dev/null");
} }
sub install { sub install {