diff --git a/lib/BaseUtils.pm b/lib/BaseUtils.pm new file mode 100644 index 0000000..6c63d3f --- /dev/null +++ b/lib/BaseUtils.pm @@ -0,0 +1,37 @@ +package BaseUtils; + +use v5.36.0; + +use strict; +use warnings; +use utf8; + +use Moo; + +sub forkWait($self) { + my $pid = fork; + if ($pid) { + return sub { + wait; + my $return_code = $?; + return $return_code; + }; + } + return; +} + +sub chroot($self, $target) { + chroot "$target"; + chdir '/'; +} + +sub execChroot($self, $target, @command) { + my $parent_subroutine = $self->forkWait(); + if (defined $parent_subroutine) { + return $parent_subroutine->(); + } + $self->chroot($target); + my $return_code = system @command; + exit $return_code; +} +1; diff --git a/prepare_system.pl b/prepare_system.pl index 34081ea..d9a6ccb 100644 --- a/prepare_system.pl +++ b/prepare_system.pl @@ -7,88 +7,82 @@ use warnings; use utf8; use Path::Tiny; +use lib path(__FILE__)->parent->child('lib') . ''; + +use BaseUtils; + +my $utils = BaseUtils->new; main(); sub main { die 'Must be superuser.' if $< != 0; - my $target_dir = shift @ARGV or die 'No target dir passed.'; + my $target_dir = shift @ARGV or die 'No target dir passed.'; my $rebuild_bin = shift @ARGV // 0; $target_dir = path($target_dir); my $gentoo_conf = path('gentoo.conf'); - my $make_conf = path('make.conf'); + my $make_conf = path('make.conf'); my $resolv_conf = path('/etc/resolv.conf'); - my $zz_use = path('zz-use'); - + my $zz_use = path('zz-use'); my $packages = _readPackagesToInstall(); _checkValidSystem($target_dir); - my $make_conf_changed = _installMakeConf( $target_dir, $make_conf ); - _installGentooConf($target_dir, $gentoo_conf); - _installResolvConf($target_dir,$resolv_conf); - my $package_use_changed = _installPackageUse($target_dir, $zz_use); + _installMakeConf( $target_dir, $make_conf ); + _installGentooConf( $target_dir, $gentoo_conf ); + _installResolvConf( $target_dir, $resolv_conf ); + _installPackageUse( $target_dir, $zz_use ); _mountNecessaryFilesystems($target_dir); _webrsync($target_dir); - if ($rebuild_bin && $package_use_changed || $make_conf_changed) { + if ( $rebuild_bin ) { _rebuildBinaries($target_dir); } _updateSystem($target_dir); _depclean($target_dir); - _installNeededPackages($target_dir, $packages); + _installNeededPackages( $target_dir, $packages ); } -sub _depclean($target) { - _forkWait() or return; - _chroot($target); - my $return_code = system 'emerge', '--depclean'; - if ($return_code != 0) { +sub _depclean ($target) { + my $return_code = $utils->execChroot( $target, 'emerge', '--depclean' ); + if ( $return_code != 0 ) { die 'Unable to depclean system.'; } - exit 0; } -sub _updateSystem($target) { - _forkWait() or return; - _chroot($target); - my $return_code = system 'emerge', '-uUDN', '@world'; - if ($return_code != 0) { +sub _updateSystem ($target) { + my $return_code = + $utils->execChroot( $target, 'emerge', '-uUDN', '@world' ); + if ( $return_code != 0 ) { die 'Unable to update the system.'; } - exit 0; } -sub _rebuildBinaries($target) { - _forkWait() or return; - _chroot($target); - my $return_code = system 'emerge', '-e', '@system'; - if ($return_code != 0) { +sub _rebuildBinaries ($target) { + my $return_code = $utils->execChroot( $target, 'emerge', '-e', '@system' ); + if ( $return_code != 0 ) { die 'Unable to rebuild binaries for system.'; } - my $return_code = system 'emerge', '-e', '@world'; - if ($return_code != 0) { + $return_code = $utils->execChroot( $target, 'emerge', '-e', '@world' ); + if ( $return_code != 0 ) { die 'Unable to rebuild binaries for world.'; } - exit 0; } -sub _installNeededPackages($target, $packages) { - _forkWait() or return; - _chroot($target); - my $return_code = system 'emerge', '--noreplace', @$packages; - if ($return_code != 0) { - exit $return_code; +sub _installNeededPackages ( $target, $packages ) { + my $return_code = + $utils->execChroot( $target, 'emerge', '--noreplace', @$packages ); + if ( $return_code != 0 ) { + die 'Unable to install needed packages.'; } - exit 0; } sub _readPackagesToInstall { my @packages; open my $fh, '<', 'packages'; - while (my $line = <$fh>) { + while ( my $line = <$fh> ) { chomp $line; push @packages, $line; } @@ -96,62 +90,42 @@ sub _readPackagesToInstall { return \@packages; } -sub _forkWait { - my $pid = fork; - if ($pid) { - wait; - my $return_code = $?; - if ($? != 0) { - exit $?; - } - return 0; +sub _webrsync ($target) { + my $return_code = $utils->execChroot( $target, 'emerge-webrsync' ); + if ( $return_code != 0 ) { + die 'Unable to webrsync.'; } - return 1; } -sub _webrsync($target) { - _forkWait() or return; - _chroot($target); - my $return_code = system 'emerge-webrsync'; - if ($return_code != 0) { - return $return_code; - } - exit 0; -} - -sub _chroot($target) { - chroot "$target"; - chdir '/'; -} - -sub _mountNecessaryFilesystems($target) { +sub _mountNecessaryFilesystems ($target) { my $dest_proc = $target->child('proc'); - my $dest_dev = $target->child('dev'); - my $dest_sys = $target->child('sys'); + my $dest_dev = $target->child('dev'); + my $dest_sys = $target->child('sys'); - _mountType('proc', $dest_proc) if !_checkMounted($dest_proc); - _mountType('sysfs', $dest_sys) if !_checkMounted($dest_sys); - _mountRbind('/dev', $dest_dev) if !_checkMounted($dest_dev); + _mountType( 'proc', $dest_proc ) if !_checkMounted($dest_proc); + _mountType( 'sysfs', $dest_sys ) if !_checkMounted($dest_sys); + _mountRbind( '/dev', $dest_dev ) if !_checkMounted($dest_dev); } -sub _checkMounted($fs) { +sub _checkMounted ($fs) { $fs = $fs->realpath; - my $return = index(_getMounts(), $fs) != -1; + my $return = index( _getMounts(), $fs ) != -1; say "$fs is mounted." if $return; return $return; } -sub _mountRbind($source, $fs) { +sub _mountRbind ( $source, $fs ) { my $return_code = system 'sudo', 'mount', '--rbind', $source, $fs; - if ($return_code != 0) { + if ( $return_code != 0 ) { die "Unable to mount $fs."; } } { my $mounts; + sub _getMounts { - if (!defined $mounts) { + if ( !defined $mounts ) { open my $fh, '-|', 'sudo', 'mount'; $mounts = join '', <$fh>; close $fh; @@ -160,9 +134,9 @@ sub _mountRbind($source, $fs) { } } -sub _mountType($fs_type, $fs) { +sub _mountType ( $fs_type, $fs ) { my $return_code = system 'sudo', 'mount', '-t', $fs_type, $fs_type, $fs; - if ($return_code != 0) { + if ( $return_code != 0 ) { die "Unable to mount $fs."; } } @@ -173,37 +147,37 @@ sub _checkValidSystem ($target) { } } -sub _installResolvConf($target, $resolv_conf) { +sub _installResolvConf ( $target, $resolv_conf ) { my $dest_resolv_conf = $target->child('etc/resolv.conf'); - _install($resolv_conf, $dest_resolv_conf); + _install( $resolv_conf, $dest_resolv_conf ); } -sub _installGentooConf($target, $gentoo_conf) { +sub _installGentooConf ( $target, $gentoo_conf ) { my $dest_gentoo_conf = $target->child('etc/portage/repos.conf/gentoo.conf'); - my $repos_conf = $dest_gentoo_conf->parent; - my $return_code = system 'sudo', 'mkdir', '-p', $repos_conf; - if ($return_code != 0) { + my $repos_conf = $dest_gentoo_conf->parent; + my $return_code = system 'sudo', 'mkdir', '-p', $repos_conf; + if ( $return_code != 0 ) { say "Unable to create $repos_conf."; } - _install($gentoo_conf, $dest_gentoo_conf); + _install( $gentoo_conf, $dest_gentoo_conf ); } -sub _installPackageUse($target, $zz_use) { +sub _installPackageUse ( $target, $zz_use ) { my $dest_zz_use = $target->child('etc/portage/package.use/zz-use'); my $package_use = $dest_zz_use->parent; my $return_code = system 'sudo', 'mkdir', '-p', $package_use; - if ($return_code != 0) { + if ( $return_code != 0 ) { say "Unable to create $package_use."; } - _install($zz_use, $dest_zz_use); + _install( $zz_use, $dest_zz_use ); } sub _installMakeConf ( $target, $make_conf ) { my $dest_make_conf = $target->child('etc/portage/make.conf'); - return _install($make_conf, $dest_make_conf); + return _install( $make_conf, $dest_make_conf ); } -sub _install($source, $dest) { +sub _install ( $source, $dest ) { if ( -e $dest && _getSha512SumFile($dest) eq _getSha512SumFile($source) ) {