Initial commit.
This commit is contained in:
commit
dc45472bcc
80
generate_system.pl
Normal file
80
generate_system.pl
Normal file
@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use v5.36.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
use GnuPG;
|
||||
|
||||
use Path::Tiny;
|
||||
use Mojo::UserAgent;
|
||||
|
||||
my $target_dir = shift @ARGV or die 'No target dir passed.';
|
||||
|
||||
my $gpg_temp_dir = Path::Tiny::tempdir;
|
||||
my $gpg_bin = 'gpg';
|
||||
my @args = ( '--command-fd', '0', '--homedir', $gpg_temp_dir );
|
||||
|
||||
my $gentoo_pk_id = '13EBBDBEDE7A12775DFDB1BABB572E0E2D182910';
|
||||
my $stage_destination = path('stage.tar.xz');
|
||||
my $stage_destination_asc = path($stage_destination . '.asc');
|
||||
|
||||
_doNothingIfTargetDirExists($target_dir);
|
||||
_fetchKey($gentoo_pk_id);
|
||||
_trustKey($gentoo_pk_id);
|
||||
_downloadGentooStage($stage_destination, $stage_destination_asc);
|
||||
_verifyStage($stage_destination_asc);
|
||||
_extractStageIntoTarget($target_dir, $stage_destination);
|
||||
|
||||
sub _extractStageIntoTarget($target, $stage) {
|
||||
system 'mkdir', $target;
|
||||
system 'sudo', 'tar', '-xpvf', $stage, '-C', $target, '--numeric-owner', q/--xattrs-include='*.*'/;
|
||||
}
|
||||
|
||||
sub _doNothingIfTargetDirExists($target) {
|
||||
if (-e $target) {
|
||||
die "$target exists, doing nothing.";
|
||||
}
|
||||
}
|
||||
|
||||
sub _verifyStage($stage_asc) {
|
||||
my $return_code = system $gpg_bin, @args, '--verify', $stage_asc;
|
||||
if ($return_code != 0) {
|
||||
die 'Signature is not valid, maybe someone is trying to eavesdrop your connection?';
|
||||
}
|
||||
}
|
||||
|
||||
sub _downloadGentooStage($stage, $stage_asc) {
|
||||
if (-e $stage && -e $stage_asc) {
|
||||
return;
|
||||
}
|
||||
my $ua = Mojo::UserAgent->new;
|
||||
my $dom = $ua->get('https://www.gentoo.org/downloads/')->result->dom;
|
||||
for my $h4 ($dom->find('h4')->each) {
|
||||
next if $h4->text !~ /Stage/;
|
||||
my @next_list_groups = $h4->following('div.list-group')->each;
|
||||
my $url = $next_list_groups[0]->at('a')->attr('href');
|
||||
$stage->spew_raw($ua->get($url)->result->body);
|
||||
$stage_asc->spew_raw($ua->get($url . '.asc')->result->body);
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
sub _fetchKey ($key) {
|
||||
my $return_code = system $gpg_bin, @args, '--recv-keys', $key;
|
||||
if ( $return_code != 0 ) {
|
||||
die 'Unable to fetch gentoo gpg key.';
|
||||
}
|
||||
}
|
||||
|
||||
sub _trustKey ($key) {
|
||||
open( my $fh, '|-', $gpg_bin, @args, '--edit-key', $key, 'trust' );
|
||||
say $fh 5;
|
||||
say $fh 'y';
|
||||
close $fh;
|
||||
my $return_code = $?;
|
||||
if ( $return_code != 0 ) {
|
||||
die 'Unable to trust gentoo gpg key.';
|
||||
}
|
||||
}
|
19
gentoo.conf
Normal file
19
gentoo.conf
Normal file
@ -0,0 +1,19 @@
|
||||
[DEFAULT]
|
||||
main-repo = gentoo
|
||||
|
||||
[gentoo]
|
||||
location = /var/db/repos/gentoo
|
||||
sync-type = rsync
|
||||
sync-uri = rsync://rsync.gentoo.org/gentoo-portage
|
||||
auto-sync = yes
|
||||
sync-rsync-verify-jobs = 1
|
||||
sync-rsync-verify-metamanifest = yes
|
||||
sync-rsync-verify-max-age = 24
|
||||
sync-openpgp-key-path = /usr/share/openpgp-keys/gentoo-release.asc
|
||||
sync-openpgp-keyserver = hkps://keys.gentoo.org
|
||||
sync-openpgp-key-refresh-retry-count = 40
|
||||
sync-openpgp-key-refresh-retry-overall-timeout = 1200
|
||||
sync-openpgp-key-refresh-retry-delay-exp-base = 2
|
||||
sync-openpgp-key-refresh-retry-delay-max = 60
|
||||
sync-openpgp-key-refresh-retry-delay-mult = 4
|
||||
sync-webrsync-verify-signature = yes
|
17
make.conf
Normal file
17
make.conf
Normal file
@ -0,0 +1,17 @@
|
||||
# These settings were set by the catalyst build script that automatically
|
||||
# built this stage.
|
||||
# Please consult /usr/share/portage/config/make.conf.example for a more
|
||||
# detailed example.
|
||||
COMMON_FLAGS="-O2 -pipe"
|
||||
CFLAGS="${COMMON_FLAGS}"
|
||||
CXXFLAGS="${COMMON_FLAGS}"
|
||||
FCFLAGS="${COMMON_FLAGS}"
|
||||
FFLAGS="${COMMON_FLAGS}"
|
||||
MAKEOPTS="-j12"
|
||||
FEATURES="buildpkg"
|
||||
|
||||
# NOTE: This stage was built with the bindist Use flag enabled
|
||||
|
||||
# This sets the language of build output to English.
|
||||
# Please keep this setting intact when reporting bugs.
|
||||
LC_MESSAGES=C.utf8
|
205
prepare_system.pl
Normal file
205
prepare_system.pl
Normal file
@ -0,0 +1,205 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use v5.36.0;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use utf8;
|
||||
|
||||
use Path::Tiny;
|
||||
|
||||
main();
|
||||
|
||||
sub main {
|
||||
die 'Must be superuser.' if $< != 0;
|
||||
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 $resolv_conf = path('/etc/resolv.conf');
|
||||
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);
|
||||
|
||||
_mountNecessaryFilesystems($target_dir);
|
||||
_webrsync($target_dir);
|
||||
if ($rebuild_bin && $package_use_changed || $make_conf_changed) {
|
||||
_rebuildBinaries($target_dir);
|
||||
}
|
||||
_installNeededPackages($target_dir, $packages);
|
||||
}
|
||||
|
||||
sub _rebuildBinaries($target) {
|
||||
_forkWait() or return;
|
||||
_chroot($target);
|
||||
my $return_code = system '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) {
|
||||
die 'Unable to rebuild binaries for world.';
|
||||
}
|
||||
}
|
||||
|
||||
sub _installNeededPackages($target, $packages) {
|
||||
_forkWait() or return;
|
||||
_chroot($target);
|
||||
my $return_code = system 'emerge', '--noreplace', @$packages;
|
||||
if ($return_code != 0) {
|
||||
exit $return_code;
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
sub _readPackagesToInstall {
|
||||
my @packages;
|
||||
open my $fh, '<', 'packages';
|
||||
while (my $line = <$fh>) {
|
||||
chomp $line;
|
||||
push @packages, $line;
|
||||
}
|
||||
close $fh;
|
||||
return \@packages;
|
||||
}
|
||||
|
||||
sub _forkWait {
|
||||
my $pid = fork;
|
||||
if ($pid) {
|
||||
wait;
|
||||
my $return_code = $?;
|
||||
if ($? != 0) {
|
||||
exit $?;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
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) {
|
||||
my $dest_proc = $target->child('proc');
|
||||
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);
|
||||
}
|
||||
|
||||
sub _checkMounted($fs) {
|
||||
$fs = $fs->realpath;
|
||||
my $return = index(_getMounts(), $fs) != -1;
|
||||
say "$fs is mounted." if $return;
|
||||
return $return;
|
||||
}
|
||||
|
||||
sub _mountRbind($source, $fs) {
|
||||
my $return_code = system 'sudo', 'mount', '--rbind', $source, $fs;
|
||||
if ($return_code != 0) {
|
||||
die "Unable to mount $fs.";
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $mounts;
|
||||
sub _getMounts {
|
||||
if (!defined $mounts) {
|
||||
open my $fh, '-|', 'sudo', 'mount';
|
||||
$mounts = join '', <$fh>;
|
||||
close $fh;
|
||||
}
|
||||
return $mounts;
|
||||
}
|
||||
}
|
||||
|
||||
sub _mountType($fs_type, $fs) {
|
||||
my $return_code = system 'sudo', 'mount', '-t', $fs_type, $fs_type, $fs;
|
||||
if ($return_code != 0) {
|
||||
die "Unable to mount $fs.";
|
||||
}
|
||||
}
|
||||
|
||||
sub _checkValidSystem ($target) {
|
||||
if ( !-d $target ) {
|
||||
die 'Target system not populated yet.';
|
||||
}
|
||||
}
|
||||
|
||||
sub _installResolvConf($target, $resolv_conf) {
|
||||
my $dest_resolv_conf = $target->child('etc/resolv.conf');
|
||||
_install($resolv_conf, $dest_resolv_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) {
|
||||
say "Unable to create $repos_conf.";
|
||||
}
|
||||
_install($gentoo_conf, $dest_gentoo_conf);
|
||||
}
|
||||
|
||||
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) {
|
||||
say "Unable to create $package_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);
|
||||
}
|
||||
|
||||
sub _install($source, $dest) {
|
||||
if ( -e $dest
|
||||
&& _getSha512SumFile($dest) eq _getSha512SumFile($source) )
|
||||
{
|
||||
say "$source is already installed, skipping.";
|
||||
return;
|
||||
}
|
||||
say "Target $source differs, installing...";
|
||||
my $return_code = system 'sudo', 'cp', '-L', $source, $dest;
|
||||
if ( $return_code != 0 ) {
|
||||
die "Unable to install $dest";
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _getSha512SumFile ($file) {
|
||||
open my $fh, '-|', 'sha512sum', $file;
|
||||
my $text = <$fh>;
|
||||
close $fh;
|
||||
|
||||
my ($sha512sum) = $text =~ /^(\S+)/;
|
||||
return $sha512sum;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user