diff options
| author | Sergio <sergiotarxz@posteo.net> | 2026-08-16 10:34:45 +0000 |
|---|---|---|
| committer | Sergio <sergiotarxz@posteo.net> | 2026-08-16 10:34:45 +0000 |
| commit | fc00e92c28f22ff6cb56e2ab0a4998991e7b4910 (patch) | |
| tree | ff89f76948b98f3139a9facba7fdf003ea2747e8 | |
| parent | a7f8d6adfbd94b711eea7c5ea4d72748d7bb9cb2 (diff) | |
draft installation.
| -rw-r--r-- | lib/AlgaOS/Installer.xs | 67 | ||||
| -rw-r--r-- | lib/AlgaOS/Installer/GUI.pm | 181 | ||||
| -rw-r--r-- | lib/AlgaOS/Installer/Parents.pm | 52 | ||||
| -rw-r--r-- | scripts/installer.pl | 53 |
4 files changed, 268 insertions, 85 deletions
diff --git a/lib/AlgaOS/Installer.xs b/lib/AlgaOS/Installer.xs index 632b32d..270c98b 100644 --- a/lib/AlgaOS/Installer.xs +++ b/lib/AlgaOS/Installer.xs @@ -15,6 +15,54 @@ typedef struct { SV *to; } BindingUserdata; +static void +gtk_alert_dialog_choose_callback( + GObject *source_object, + GAsyncResult *result, + gpointer user_data +) +{ + dSP; + + SV *callback = (SV *)user_data; + GError *error = NULL; + + int response = gtk_alert_dialog_choose_finish( + GTK_ALERT_DIALOG(source_object), + result, + &error + ); + + if (error != NULL) { + Perl_croak("%s", error->message); + } + + ENTER; + SAVETMPS; + + PUSHMARK(SP); + + XPUSHs(sv_2mortal(newSViv(response))); + + PUTBACK; + + call_sv(callback, G_DISCARD | G_EVAL); + + SPAGAIN; + + if (SvTRUE(ERRSV)) { + Perl_warn("Perl binding callback failed: %s", + SvPV_nolen(ERRSV)); + + sv_setsv(ERRSV, &PL_sv_undef); + } + + FREETMPS; + LEAVE; + + SvREFCNT_dec(callback); +} + static gboolean perl_timeout_func(gpointer userdata) { SV *callback = (SV *)userdata; @@ -359,10 +407,27 @@ new(SV *class, char *title, char *detail) RETVAL void +make_yes_no(Gtk::AlertDialog self) + CODE: + const char *buttons[] = { + "Cancel", + "Ok", + NULL + }; + gtk_alert_dialog_set_buttons(self, buttons); + gtk_alert_dialog_set_default_button(self, 1); + +void show(Gtk::AlertDialog self, Gtk::Window parent) CODE: gtk_alert_dialog_show(self, parent); +void +choose(Gtk::AlertDialog self, Gtk::Window window, SV *callback) + CODE: + SvREFCNT_inc(callback); + gtk_alert_dialog_choose(self, window, NULL, gtk_alert_dialog_choose_callback, callback); + MODULE = AlgaOS::Installer PACKAGE = Gtk::Overlay Gtk::Overlay @@ -527,7 +592,7 @@ selected_text(Gtk::Dropdown self) OUTPUT: RETVAL -guint +unsigned int selected(Gtk::Dropdown self) CODE: RETVAL = gtk_drop_down_get_selected(self); diff --git a/lib/AlgaOS/Installer/GUI.pm b/lib/AlgaOS/Installer/GUI.pm index c461e88..099e649 100644 --- a/lib/AlgaOS/Installer/GUI.pm +++ b/lib/AlgaOS/Installer/GUI.pm @@ -9,6 +9,13 @@ use AlgaOS::Installer; use AlgaOS::Installer::Util; use List::Util; use JSON; +use POSIX qw/WNOHANG/; + +BEGIN { + *CORE::GLOBAL::exit = sub { + POSIX::_exit($_[0] // 0); + }; +} has app => ( is => 'lazy' ); has win => ( is => 'rw' ); @@ -22,6 +29,10 @@ has _username_entry => ( is => 'rw' ); has _password_entry => ( is => 'rw' ); has _start_installation_button => ( is => 'rw' ); has _proxy_others => ( is => 'rw' ); +has _dropdown_timezones => ( is => 'rw' ); +has _dropdown_locale => ( is => 'rw' ); +has _dropdown_block_devices => ( is => 'rw' ); +has _scroll => ( is => 'rw' ); sub call_and_increment_grid_row( $self, $coderef ) { $coderef->(); @@ -36,6 +47,29 @@ sub _build_app { return Gtk::Application->new( "me.sergiotarxz.hola", 0 ); } +sub _create_install_grid($self, $desc) { + my $grid = Gtk::Grid->new; + my $const = $self->const; + $grid->add_css_class('transparent_background'); + $self->_grid_row(0); + $self->call_and_increment_grid_row( + sub { + my $label = Gtk::Label->new('Install AlgaOS'); + $label->add_css_class('title-1'); + $grid->attach( $label, 0, $self->_grid_row, 3, 1 ); + } + ); + $self->call_and_increment_grid_row( + sub { + my $label = Gtk::Label->new($desc); + $grid->attach( $label, 0, $self->_grid_row, 3, 1 ); + } + ); + $grid->set_valign( $const->GTK_ALIGN_CENTER ); + $grid->set_halign( $const->GTK_ALIGN_CENTER ); + return $grid; +} + sub _create_main_grid($self) { my $const = $self->const; my $grid = Gtk::Grid->new; @@ -94,6 +128,7 @@ sub _create_main_grid($self) { || $a cmp $b; } @timezones; my $dropdown = Gtk::Dropdown->new( [@timezones] ); + $self->_dropdown_timezones($dropdown); $grid->attach( $dropdown, 1, $self->_grid_row, 1, 1 ); } ); @@ -124,6 +159,7 @@ sub _create_main_grid($self) { || $a cmp $b; } @locales; my $dropdown = Gtk::Dropdown->new( [@locales] ); + $self->_dropdown_locale($dropdown); $grid->attach( $dropdown, 1, $self->_grid_row, 1, 1 ); } ); @@ -131,15 +167,17 @@ sub _create_main_grid($self) { sub { $grid->attach( Gtk::Label->new('Set the installation destination'), 0, $self->_grid_row, 1, 1 ); - my $block_devices = JSON::from_json(`lsblk --json -d -o NAME,SIZE,MODEL,TYPE,TRAN`); - my @block_devices = map { - join "\t", @$_{qw/name model size type tran/}; - } $block_devices->{blockdevices}->@*; + my $block_devices = + JSON::from_json(`lsblk --json -d -o NAME,SIZE,MODEL,TYPE,TRAN`); + my @block_devices = + map { join "\t", @$_{qw/name model size type tran/}; } + $block_devices->{blockdevices}->@*; @block_devices = grep { defined $_ } @block_devices; my $dropdown = Gtk::Dropdown->new( [@block_devices] ); + $self->_dropdown_block_devices($dropdown); $grid->attach( $dropdown, 1, $self->_grid_row, 1, 1 ); } - ); + ); $self->call_and_increment_grid_row( sub { @@ -149,6 +187,19 @@ sub _create_main_grid($self) { ); $self->_start_installation_button->connect( clicked => sub { + my $dialog = Gtk::AlertDialog->new( + "Your data in that storage media will be lost", + "Ready to format?" ); + $dialog->make_yes_no(); + $dialog->choose( + $self->win, + sub($button) { + if ( $button != 1 ) { + return; + } + $self->_install; + } + ); } ); @@ -157,6 +208,125 @@ sub _create_main_grid($self) { return $grid; } +sub excfailexit { + my @command = @_; + my $command_string = join ', ', map { "'$_'"} @command; + say "system $command_string"; + my $return_code = system @command; + if ($return_code) { + system 'sudo umount -R /mnt/gentoo'; + say "system $command_string: failed"; + exit $return_code; + } +} + +sub _failed_install { + my $self = shift; + say 'Failure'; + $self->_scroll->set_child( $self->_create_install_grid('The installation failed') ); +} + +sub _succesful_install { + my $self = shift; + say 'Success'; + $self->_scroll->set_child( $self->_create_install_grid('The installation went well reboot and unplug the booting media use it') ); +} + +sub _install { + my $self = shift; + $self->_scroll->set_child( $self->_create_install_grid('The system is now being installed') ); + my ($block_name) = split /\t+/, + $self->_dropdown_block_devices->selected_text; + my $block = "/dev/$block_name"; + my $pid = fork; + if (!$pid) { + local $SIG{INT} = sub { + system 'sudo umount -R /mnt/gentoo'; + }; +# excfailexit qw{sudo sgdisk -Z}, $block; +# excfailexit qw{sudo sgdisk -n 1::+1G}, $block; +# excfailexit qw{sudo sgdisk -t 1:ef00}, $block; +# excfailexit qw{sudo sgdisk -c}, "1:AlgaOSEFI", $block; +# excfailexit qw{sudo sgdisk -n 2::+1G}, $block; +# excfailexit qw{sudo sgdisk -t 2:ef02}, $block; +# excfailexit qw{sudo sgdisk -c}, "2:AlgaOSBIOSBoot", $block; +# excfailexit qw{sudo sgdisk -n 3::+20G}, $block; +# excfailexit qw{sudo sgdisk -c}, "3:AlgaOSRecovery", $block; +# excfailexit qw{sudo sgdisk -N 4}, $block; +# excfailexit qw{sudo sgdisk -c}, "4:AlgaOSRoot", $block; +# excfailexit qw{sudo dd if=/dev/zero bs=5M count=10}, "of=${block}1"; +# excfailexit qw{sudo dd if=/dev/zero bs=5M count=10}, "of=${block}3"; +# excfailexit qw{sudo dd if=/dev/zero bs=5M count=10}, "of=${block}4"; +# excfailexit qw{sudo mkfs.vfat}, "${block}1"; +# excfailexit qw{sudo mkfs.ext4}, "${block}3"; +# excfailexit qw{sudo mkfs.ext4}, "${block}4"; + excfailexit qw{sudo mkdir -pv /mnt/gentoo/}; + excfailexit qw{sudo mount}, "${block}4", '/mnt/gentoo'; + excfailexit qw{sudo mkdir -pv}, '/mnt/gentoo/recovery'; + excfailexit qw{sudo mount}, "${block}3", '/mnt/gentoo/recovery'; + excfailexit qw{sudo mkdir -pv}, '/mnt/gentoo/boot/efi'; + excfailexit qw{sudo mount}, "${block}1", '/mnt/gentoo/boot/efi'; + excfailexit + qw{sudo perl -Mblib -e AlgaOS::Installer::GUI::chroot_install_commands(@ARGV)}, + $self->_hostname_entry->get_text, $self->_username_entry->get_text, + $self->_password_entry->get_text, + $self->_dropdown_timezones->selected_text, + $self->_dropdown_locale->selected_text, + $self->_dropdown_block_devices->selected_text; +# excfailexit 'sudo tar -C /mnt/gentoo -xvpf /stage3-algaos-latest.tar.xz --numeric-owner --xattrs-include="*.*"'; + system 'sudo umount -R /mnt/gentoo'; + say "Finish $$"; + exit 0; + } + $self->app->timeout_add(1000, sub { + my $waitpid_result = waitpid($pid, WNOHANG); + say $pid; + say $waitpid_result; + if ($waitpid_result == -1) { + $self->_failed_install; + return 0; + } + if ($waitpid_result == 0) { + return 1; + } + if ($waitpid_result == $pid) { + if ($? != 0) { + $self->_failed_install; + return 0; + } + $self->_succesful_install; + return 0; + } + return 0; + }); +} + +sub chroot_install_commands { + my ($hostname, $username, $password, $timezone, $locale, $block_devices) = @ARGV; + chroot '/mnt/gentoo'; + chdir '/'; + excfailexit qw{systemd-machine-id-setup}; + excfailexit qw{systemctl preset-all}; + excfailexit qw{systemctl enable gdm}; + excfailexit qw{systemctl enable NetworkManager}; + excfailexit qw{systemctl enable cronie}; + excfailexit qw{systemctl enable bluetooth}; + excfailexit qw{useradd -m}, $username, qw{-s /bin/bash}; + open my $fh, '|-', qw{passwd --stdin}, $username; + say $fh $password; + close $fh; + if ($? != 0) { + excfailexit "forcing-a-fail-because-passwd-failed-and-iam-lazy"; + } + my $sudoers_dir = '/etc/sudoers.d'; + excfailexit qw{mkdir -pv}, $sudoers_dir; + open $fh, '>', qw{mkdir -pv}, "$sudoers_dir/algaos"; + say $fh "user ALL=(ALL) NOPASSWD: ALL"; + close $fh; + excfailexit "rsync -a --mkpath /boot/kernel* /boot/initramfs* /boot/recovery/"; + exit 0; +} + sub activate($self) { my $const = $self->const; my $win = Gtk::ApplicationWindow->new( $self->app ); @@ -186,6 +356,7 @@ sub activate($self) { $self->_password_entry($password_entry); my $scroll = Gtk::ScrolledWindow->new; $scroll->set_child( $self->_create_main_grid ); + $self->_scroll($scroll); $overlay->add_overlay($scroll); $win->set_child($overlay); $win->present; diff --git a/lib/AlgaOS/Installer/Parents.pm b/lib/AlgaOS/Installer/Parents.pm index 2fac331..d48f860 100644 --- a/lib/AlgaOS/Installer/Parents.pm +++ b/lib/AlgaOS/Installer/Parents.pm @@ -1,19 +1,23 @@ -package Gtk::Entry; +package Gtk::Widget; use v5.38.0; use vars qw/@ISA/; -our @ISA = qw/Gtk::Widget Gtk::Editable/; -package Gtk::Overlay; +our @ISA = qw/G::Object/; +package Gtk::Grid; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/Gtk::Widget/; -package Gtk::Window; +package Gtk::Box; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/Gtk::Widget/; -package Gio::Application; +package G::File; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/G::Object/; +package Gtk::ApplicationWindow; +use v5.38.0; +use vars qw/@ISA/; +our @ISA = qw/Gtk::Window/; package Gtk::AlertDialog; use v5.38.0; use vars qw/@ISA/; @@ -22,59 +26,55 @@ package Gtk::Picture; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/Gtk::Widget/; -package Gtk::Dropdown; +package Gtk::Label; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/Gtk::Widget/; -package Gtk::ApplicationWindow; +package Gdk::Texture; use v5.38.0; use vars qw/@ISA/; -our @ISA = qw/Gtk::Window/; -package Gdk::Texture; +our @ISA = qw/G::Object/; +package Gdk::Display; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/G::Object/; -package Gtk::ScrolledWindow; +package Gtk::Button; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/Gtk::Widget/; +package Gtk::CssProvider; +use v5.38.0; +use vars qw/@ISA/; +our @ISA = qw/G::Object/; package Gtk::Application; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/Gio::Application/; -package Gtk::Widget; +package Gtk::Dropdown; use v5.38.0; use vars qw/@ISA/; -our @ISA = qw/G::Object/; -package G::File; +our @ISA = qw/Gtk::Widget/; +package Gtk::Entry; use v5.38.0; use vars qw/@ISA/; -our @ISA = qw/G::Object/; +our @ISA = qw/Gtk::Widget Gtk::Editable/; package Gtk::CheckButton; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/Gtk::Widget/; -package Gtk::Button; +package Gtk::ScrolledWindow; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/Gtk::Widget/; -package Gtk::Label; +package Gtk::Overlay; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/Gtk::Widget/; -package Gtk::CssProvider; -use v5.38.0; -use vars qw/@ISA/; -our @ISA = qw/G::Object/; -package Gdk::Display; +package Gio::Application; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/G::Object/; -package Gtk::Box; -use v5.38.0; -use vars qw/@ISA/; -our @ISA = qw/Gtk::Widget/; -package Gtk::Grid; +package Gtk::Window; use v5.38.0; use vars qw/@ISA/; our @ISA = qw/Gtk::Widget/; diff --git a/scripts/installer.pl b/scripts/installer.pl index 1b38b9c..9bf653e 100644 --- a/scripts/installer.pl +++ b/scripts/installer.pl @@ -47,56 +47,3 @@ sub run($self) { } __PACKAGE__->new->run; - -#for my $ip (qw/192.168.1.96 192.168.2.38/) { -# my $devs = PCAP::If->find_all_devs(); -# my $handle = $devs->open_live( $ip, 65535, 1, 10 ); -# my $program = $handle->compile( -#'udp and (dst host 192.168.2.38 or dst host 255.255.255.255 or dst host 192.168.1.96) and (src port 3659 or dst port 3659 or src port 3658 or src port 3656 or dst port 3658 or dst port 3656)', -# 1 -# ); -# $handle->set_filter($program); -# say $handle->datalink; -# next if fork; -# $handle->loop( -# sub ($packet) { -#use IO::Socket::INET; -## say $packet->src_ip . ':' . $packet->src_port; -## say $packet->dst_ip . ':' . $packet->dst_port; -# -# state %sockets; -# if ( $packet->dst_ip eq '192.168.2.38' || $packet->dst_ip eq '255.255.255.255' || $packet->dst_ip eq '192.168.1.96') { -# if ($ip eq '192.168.2.38') { -## say 'VPN'; -# my $sock = $sockets{$packet->src_ip.'.'.$packet->src_port} // IO::Socket::INET->new( -# Proto => 'udp', -# PeerAddr => '192.168.1.89', -# PeerPort => $packet->dst_port, -# LocalAddr => '192.168.1.96', -# LocalPort => $packet->src_port, -# ReusePort => 1 -# ) or die "$!"; -# $sock->blocking(0); -# $sockets{$packet->src_ip.'.'.$packet->src_port} = $sock; -# $sock->send($packet->payload); -# } else { -## say 'ETH'; -# my $sock = $sockets{$packet->src_ip.'.'.$packet->src_port} // IO::Socket::INET->new( -# Proto => 'udp', -# PeerAddr => '192.168.2.1', -# PeerPort => $packet->dst_port, -# LocalAddr => '192.168.2.38', -# LocalPort => $packet->src_port, -# ReusePort => 1 -# ) or die "$!"; -# #say 'hola'; -# $sock->blocking(0); -# $sockets{$packet->src_ip.'.'.$packet->src_port} = $sock; -# $sock->send($packet->payload); -# } -# } -# } -# ); -# exit 0; -#} -#<>; |
