diff options
| author | sergio <sergiotarxz@posteo.net> | 2026-09-05 23:05:36 +0000 |
|---|---|---|
| committer | sergio <sergiotarxz@posteo.net> | 2026-09-05 23:05:36 +0000 |
| commit | ea594199551ac8e78e28d8cbe5d9fba0b6f288c8 (patch) | |
| tree | 7dd2ffb4e9a2f2880d482c365f90ce46aba01492 | |
| parent | 0e070db71fae60e74a36260a9bd2ccd20c6363fc (diff) | |
Fixing errors in live grub generator
Tested command: sudo update-grub --noprotect --noroot --norecovery --live --chroot test
| -rw-r--r-- | lib/AlgaOS/UpdateGrub.pm | 124 | ||||
| -rw-r--r-- | scripts/update-grub | 66 |
2 files changed, 107 insertions, 83 deletions
diff --git a/lib/AlgaOS/UpdateGrub.pm b/lib/AlgaOS/UpdateGrub.pm index 32ca1ef..af4d7de 100644 --- a/lib/AlgaOS/UpdateGrub.pm +++ b/lib/AlgaOS/UpdateGrub.pm @@ -10,37 +10,45 @@ use Crypt::URandom qw/urandom/; use PBKDF2::Tiny; # Boolean -has search_recovery => (is => 'ro'); +has search_recovery => ( is => 'ro' ); + # Boolean -has search_root => (is => 'ro'); +has search_root => ( is => 'ro' ); + # Boolean -has search_live_cd_rootfs => (is => 'ro'); +has search_live_cd_rootfs => ( is => 'ro' ); + # Boolean -has wants_pass_in_sensitive_options => (is => 'lazy'); +has wants_pass_in_sensitive_options => ( is => 'lazy' ); + # New pass if wanted will fail if not cached -has change_to_pass => (is => 'ro'); +has change_to_pass => ( is => 'ro' ); + # List of users -has user_list => (is => 'lazy'); +has user_list => ( is => 'lazy' ); + # Target storage device (/dev/sda for example) -has target_device => (is => 'lazy'); +has target_device => ( is => 'lazy' ); # What path to use as root -has root_dir => (is => 'lazy'); +has root_dir => ( is => 'lazy' ); sub _build_target_device { my $current_root_part = `findmnt -n -o SOURCE /`; - return '/dev/'.`lsblk -no PKNAME $current_root_part`; + die 'Programming error in cd handling' + if $current_root_part =~ /(?:loop|rootfs)/; + return '/dev/' . `lsblk -no PKNAME $current_root_part`; } sub _build_root_dir { return '/'; } -has _devices => (is => 'lazy'); +has _devices => ( is => 'lazy' ); sub _build__devices($self) { my $target_device = $self->target_device; - my $devices = `lsblk -o PARTLABEL,PARTUUID $target_device`; + my $devices = `lsblk -o PARTLABEL,PARTUUID $target_device`; my @devices = split /\n/, $devices; shift @devices; @@ -50,7 +58,6 @@ sub _build__devices($self) { return { ( map { ( split /\s+/, $_ ) } @devices ) }; } - sub _build_wants_pass_in_sensitive_options { return 1; } @@ -60,28 +67,32 @@ sub _build_user_list { } sub run($self) { - my $grub_dir = $self->root_dir.'/boot/grub'; + my $grub_dir = $self->root_dir . '/boot/grub'; system qw{mkdir -pv}, $grub_dir; - open $fh, '>', "$grub_dir/grub.cfg"; + open my $fh, '>', "$grub_dir/grub.cfg"; say $fh <<"EOF"; set timeout=5 set default=0 EOF my $really_wants_pass = 0; - if ( $self->wants_pass_in_sensitive_options || !$self->search_live_cd_rootfs ) { + if ( $self->wants_pass_in_sensitive_options + && !$self->search_live_cd_rootfs ) + { my $really_wants_pass = 1; - my $hash_complete = $self->_create_or_find_grub_hash; + my $hash_complete = $self->_create_or_find_grub_hash; say $fh <<"EOF"; set superusers="admin" password_pbkdf2 admin grub.pbkdf2.sha512.$hash_complete EOF } - my %devices = %{$self->_devices}; - if ($self->search_root) { - die "Live booting and root requested at once" if $self->search_live_cd_rootfs; + my %devices; + if ( $self->search_root ) { + %devices = %{ $self->_devices }; + die "Live booting and root requested at once" + if $self->search_live_cd_rootfs; die "No AlgaOSRoot in that device" if !$devices{AlgaOSRoot}; - for my $kver ( glob($self->root_dir."/boot/kernel-*") ) { + for my $kver ( glob( $self->root_dir . "/boot/kernel-*" ) ) { die "No kernel found in /boot\n" unless $kver; $kver =~ s{.*/kernel-}{}; @@ -94,38 +105,43 @@ menuentry "AlgaOS" $security_string { EOF } } - if ($self->search_recovery) { - die "Live booting and recovery requested at once" if $self->search_live_cd_rootfs; + if ( $self->search_recovery ) { + %devices = %{ $self->_devices }; + die "Live booting and recovery requested at once" + if $self->search_live_cd_rootfs; die "No AlgaOSRecovery in that device" if !$devices{AlgaOSRecovery}; - my $recovery_title = $self->search_root ? 'AlgaOS Recovery' : 'Install AlgaOS now'; - if (system qw{mount /recovery}) { + my $recovery_title = + $self->search_root ? 'AlgaOS Recovery' : 'Install AlgaOS now'; + if ( system qw{mount /recovery} ) { die 'Unable to mount /recovery'; } my @rootfs = glob '/recovery/*rootfs*.squashfs'; for my $rootfs (@rootfs) { - my $tmp_dir = '/tmp/rootfs-uncompression'; - system qw{rm -rf}, $tmp_dir; - system qw{mkdir -pv}, $tmp_dir; - system( - 'unsquashfs', - '-d', $dir, - $rootfs, - 'boot/kernel-*', - 'boot/initramfs-*', - ) == 0 or die "unsquashfs failed for $rootfs: $?"; - my ($kernel) = glob "$tmp_dir/kernel-*"; - my $kver = $kernel =~ s{.*/kernel-}{}r; - my $intramfs = "$tmp_dir/initramfs-$kver.img"; - if (system qw{cp}, $kernel, "/boot/recovery/kernel-$rootfs_ver") { - die 'Failed kernel copy'; - } - if (system qw{cp}, $initramfs, "/boot/recovery/initramfs-$rootfs_ver.img") { - die 'Failed initramfs copy'; - } + my $tmp_dir = '/tmp/rootfs-uncompression'; + system qw{rm -rf}, $tmp_dir; + system qw{mkdir -pv}, $tmp_dir; + system( 'unsquashfs', '-d', $tmp_dir, $rootfs, 'boot/kernel-*', + 'boot/initramfs-*', ) == 0 + or die "unsquashfs failed for $rootfs: $?"; + my ($kernel) = glob "$tmp_dir/kernel-*"; + my $kver = $kernel =~ s{.*/kernel-}{}r; + my $initramfs = "$tmp_dir/initramfs-$kver.img"; + my $rootfs_ver = $rootfs =~ s/\.squashfs$//r; - my $rootfs_ver = $rootfs =~ s/\.squashfs$//r; - $rootfs_ver = $rootfs_ver =~ s{^.*\/}{}r; - my $security_string = $really_wants_pass ? '--users '.(join ',', @{$self->user_list}) : ''; + if ( system qw{cp}, $kernel, "/boot/recovery/kernel-$rootfs_ver" ) { + die 'Failed kernel copy'; + } + if ( system qw{cp}, + $initramfs, "/boot/recovery/initramfs-$rootfs_ver.img" ) + { + die 'Failed initramfs copy'; + } + + $rootfs_ver = $rootfs_ver =~ s{^.*\/}{}r; + my $security_string = + $really_wants_pass + ? '--users ' . ( join ',', @{ $self->user_list } ) + : ''; say $fh <<"EOF"; menuentry "AlgaOS Recovery" $security_string { linux /boot/recovery/kernel-$rootfs_ver root=live:PARTUUID=$devices{AlgaOSRecovery} rd.live.dir=/ rd.live.squashimg=$rootfs_ver.squashfs rd.live.overlay.overlayfs=1 rd.live.debug=1 rd.systemd.show_status=1 rd.systemd.log_level=debug splash quiet @@ -134,24 +150,24 @@ menuentry "AlgaOS Recovery" $security_string { EOF } - if ($self->search_live_cd_rootfs) { + } + + if ( $self->search_live_cd_rootfs ) { my $boot_dir = $self->root_dir . '/boot'; my ($kernel) = glob "$boot_dir/kernel-*"; - my $kver = s/^.*kernel-//; -say $fh <<"EOF"; + my $kver = $kernel =~ s/^.*kernel-//; + say $fh <<"EOF"; menuentry "AlgaOS" { linux /boot/kernel-$kver root=live:LABEL=ALGAOS rd.live.dir=/ rd.live.squashimg=rootfs.squashfs rd.live.overlay.overlayfs=1 rd.live.debug=1 rd.systemd.show_status=1 rd.systemd.log_level=debug quiet splash initrd /boot/initramfs-$kver.img }; EOF - } - } } -sub _create_or_find_grub_hash { +sub _create_or_find_grub_hash($self) { if ( !$self->change_to_pass ) { - open $fh, '<', '/grub_hash'; + open my $fh, '<', '/grub_hash' or die 'No grub hash and no pass sent'; local $/ = undef; my $hash_complete = <$fh>; close $fh; @@ -167,7 +183,7 @@ sub _create_or_find_grub_hash { my $hash = PBKDF2::Tiny::derive_hex( 'SHA-512', $password, $salt, $iterations, 64 ); - $hash_complete = "$iterations.$salt_hex.$hash"; + my $hash_complete = "$iterations.$salt_hex.$hash"; open my $fh, '>', '/grub_hash'; print $fh $hash_complete; diff --git a/scripts/update-grub b/scripts/update-grub index b26ad17..cc7eeb9 100644 --- a/scripts/update-grub +++ b/scripts/update-grub @@ -8,75 +8,83 @@ use Getopt::Long; use AlgaOS::UpdateGrub; my $help; -my $recovery = 1; -my $root = 1; -my $live = 0; -my $protect = 1; +my $recovery = 1; +my $root = 1; +my $live = 0; +my $protect = 1; my $user_list = ['admin']; my $target_device; my $chroot; +my $new_pass; Getopt::Long::Configure( "bundling", "no_ignore_case" ); GetOptions( - 'help|h' => \$help, - 'recovery!' => \$recovery, - 'root!' => \$root, - 'live' => \$live, - 'protect!' => \$protect, - 'new-pass' => \$new_pass, - 'user=s@' => $user_list, + 'help|h' => \$help, + 'recovery!' => \$recovery, + 'root!' => \$root, + 'live' => \$live, + 'protect!' => \$protect, + 'new-pass' => \$new_pass, + 'user=s@' => $user_list, 'target-device=s' => \$target_device, - 'chroot=s' => \$chroot, + 'chroot=s' => \$chroot, ); +if ( $< ne 0 ) { + die 'Must be root'; + exit -1; +} + if ($help) { show_help(); exit 0; } -if ($live && !$chroot) { - say STDERR '--live without --chroot is non sense, do not continue if you do not know what you are doing'; +if ( $live && !$chroot ) { + say STDERR +'--live without --chroot is non sense, do not continue if you do not know what you are doing'; show_help(); exit -1; } -if ($root && !$protect && $recovery) { - say STDERR 'Not having password in grub and having recovery and root makes your data very easily accesible without even using an external device, giving you 10 seconds to think about it, press ctrl+c to interrupt if unsure'; +if ( $root && !$protect && $recovery ) { + say STDERR +'Not having password in grub and having recovery and root makes your data very easily accesible without even using an external device, giving you 10 seconds to think about it, press ctrl+c to interrupt if unsure'; sleep 10; } my $probable_root = `findmnt -n -o SOURCE /`; -if (!$target_device && $probable_root =~ /loop/) { - say STDERR 'You are not in the destination install, you need --target-device, also if you do not know what you are doing do not continue'; +if ( !$live && !$target_device && $probable_root =~ /(?:loop|rootfs)/ ) { + say STDERR +'You are not in the destination install, you need --target-device, also if you do not know what you are doing do not continue'; show_help(); exit -1; } +say $live; AlgaOS::UpdateGrub->new( - search_recovery => $recovery, - search_root => $root, - search_live_cd_rootfs => $livecd, + search_recovery => $recovery, + search_root => $root, + search_live_cd_rootfs => $live, wants_pass_in_sensitive_options => $protect, - user_list => $user_list, + user_list => $user_list, ( - defined $new_pass - ? ( change_to_pass => $new_pass ) + defined $new_pass ? ( change_to_pass => $new_pass ) : () ), ( - defined $chroot - ? (root_dir => $chroot) + defined $chroot ? ( root_dir => $chroot ) : () ), ( - defined $target_device - ? ( target_device => $target_device ) + defined $target_device ? ( target_device => $target_device ) : () ), )->run; sub show_help { - say STDERR "IF YOU DO NOT KNOW WHAT YOU ARE DOING DO NOT DIRECTLY RUN THIS COMMAND AND ASK FOR HELP INSTEAD. + say STDERR +"IF YOU DO NOT KNOW WHAT YOU ARE DOING DO NOT DIRECTLY RUN THIS COMMAND AND ASK FOR HELP INSTEAD. update-grub [--help|-h] [--norecovery] [--noroot] [--user foo --user bar] [--live] [--noprotect] [--new-pass <new password for grub sensitive fields>] [--target-device <path to disk>] [--chroot <New root to put grub on>] |
