aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergio <sergiotarxz@posteo.net>2026-08-16 10:34:45 +0000
committerSergio <sergiotarxz@posteo.net>2026-08-16 10:34:45 +0000
commitfc00e92c28f22ff6cb56e2ab0a4998991e7b4910 (patch)
treeff89f76948b98f3139a9facba7fdf003ea2747e8
parenta7f8d6adfbd94b711eea7c5ea4d72748d7bb9cb2 (diff)
draft installation.
-rw-r--r--lib/AlgaOS/Installer.xs67
-rw-r--r--lib/AlgaOS/Installer/GUI.pm181
-rw-r--r--lib/AlgaOS/Installer/Parents.pm52
-rw-r--r--scripts/installer.pl53
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;
-#}
-#<>;