mirror of
https://github.com/webmin/webmin.git
synced 2026-06-04 20:30:22 +01:00
148 lines
4.2 KiB
Perl
Executable File
148 lines
4.2 KiB
Perl
Executable File
#!/usr/local/bin/perl
|
|
# Install the GRUB 2 boot loader with progress output.
|
|
|
|
use strict;
|
|
use warnings;
|
|
require './grub2-lib.pl'; ## no critic
|
|
|
|
our (%in, %text);
|
|
|
|
&ReadParse();
|
|
&error_setup($text{'install_err'});
|
|
my %access = &get_module_acl();
|
|
&error("$text{'eacl_np'} $text{'eacl_pinstall'}") if (!$access{'install'});
|
|
|
|
# Trim text fields before validation so shell arguments are deterministic.
|
|
foreach my $field (qw(target efi_dir platform directory boot_directory
|
|
bootloader_id)) {
|
|
$in{$field} = "" if (!defined($in{$field}));
|
|
$in{$field} =~ s/^\s+|\s+\z//g;
|
|
}
|
|
&error($text{'install_eboot_directory_required'})
|
|
if ($in{'use_boot_directory'} && $in{'boot_directory'} eq '');
|
|
my %opts = (
|
|
'target' => $in{'target'},
|
|
'efi_dir' => $in{'efi_dir'},
|
|
'platform' => $in{'platform'} || &grub2_default_platform_target(),
|
|
'directory' => $in{'directory'},
|
|
'boot_directory' => $in{'use_boot_directory'} ? $in{'boot_directory'} : '',
|
|
'bootloader_id' => $in{'bootloader_id'},
|
|
'recheck' => $in{'recheck'} ? 1 : 0,
|
|
'removable' => $in{'removable'} ? 1 : 0,
|
|
'no_nvram' => $in{'no_nvram'} ? 1 : 0,
|
|
'force' => $in{'force'} ? 1 : 0,
|
|
);
|
|
$in{'confirm'} || &error($text{'install_econfirm'});
|
|
&grub2_command('install_cmd') || &error($text{'install_ecmd'});
|
|
# Validate all paths and identifiers before any progress output is started.
|
|
my $precheck = &grub2_validate_install_options(\%opts);
|
|
&error($precheck) if ($precheck);
|
|
|
|
my ($pre_open, $current_step, $failed_printed, $captured_output) =
|
|
(0, '', 0, '');
|
|
|
|
&ui_print_unbuffered_header(undef, $text{'install_progress_title'}, "");
|
|
|
|
my $callback = sub {
|
|
my ($event, $value) = @_;
|
|
if ($event eq 'command') {
|
|
# The first event opens the visible command transcript.
|
|
$current_step = 'command';
|
|
&print_step_start($text{'install_installing'});
|
|
print &ui_tag_start('pre', { 'style' => 'margin-left: 10px;' });
|
|
$pre_open = 1;
|
|
print &html_escape($value)."\n";
|
|
return;
|
|
}
|
|
if ($event eq 'output') {
|
|
# Some commands emit output before command_done; keep one pre open.
|
|
if (!$pre_open) {
|
|
print &ui_tag_start('pre',
|
|
{ 'style' => 'margin-left: 10px;' });
|
|
$pre_open = 1;
|
|
}
|
|
$captured_output .= $value;
|
|
print &html_escape($value);
|
|
return;
|
|
}
|
|
if ($event eq 'command_done') {
|
|
# Close the transcript before printing the final status marker.
|
|
&close_output(\$pre_open);
|
|
&print_step_done(\$current_step);
|
|
return;
|
|
}
|
|
if ($event eq 'command_failed') {
|
|
# Print only one failure line even if the caller also returns an error.
|
|
&close_output(\$pre_open);
|
|
&print_step_failed(\$current_step, \$failed_printed);
|
|
return;
|
|
}
|
|
};
|
|
|
|
my $err = &grub2_install_bootloader(\%opts, $callback);
|
|
&close_output(\$pre_open);
|
|
if ($err) {
|
|
# Avoid duplicating the same error when it was already in command output.
|
|
&print_step_failed(\$current_step, \$failed_printed)
|
|
if ($current_step);
|
|
my $shown = $captured_output || '';
|
|
$shown =~ s/^\s+|\s+\z//g;
|
|
print &ui_tag('pre', &html_escape($err),
|
|
{ 'style' => 'margin-left: 10px;' })
|
|
if ($err ne $shown);
|
|
}
|
|
else {
|
|
&webmin_log("install", undef, &grub2_install_log_target(\%opts));
|
|
}
|
|
|
|
&ui_print_footer("index.cgi", $text{'install_return'});
|
|
|
|
# close_output(&open-flag)
|
|
# Closes the command output block when it is currently being printed.
|
|
sub close_output
|
|
{
|
|
my ($open) = @_;
|
|
if ($$open) {
|
|
print &ui_tag_end('pre');
|
|
$$open = 0;
|
|
}
|
|
return;
|
|
}
|
|
|
|
# print_step_start(text)
|
|
# Prints the first progress line for the installation step.
|
|
sub print_step_start
|
|
{
|
|
my ($msg) = @_;
|
|
print &ui_tag('span', &html_escape($msg." .."),
|
|
{ 'data-first-print' => undef });
|
|
print "<br>\n";
|
|
return;
|
|
}
|
|
|
|
# print_step_done(¤t-step)
|
|
# Prints a successful progress line and clears the active step.
|
|
sub print_step_done
|
|
{
|
|
my ($current) = @_;
|
|
print &ui_tag('span', &html_escape(".. ".$text{'install_done'}),
|
|
{ 'data-second-print' => undef });
|
|
print "<br><div data-x-br=\"\"></div>\n";
|
|
$$current = '';
|
|
return;
|
|
}
|
|
|
|
# print_step_failed(¤t-step, &printed-flag)
|
|
# Prints a failed progress line once and clears the active step.
|
|
sub print_step_failed
|
|
{
|
|
my ($current, $printed) = @_;
|
|
return if ($$printed);
|
|
print &ui_tag('span', &html_escape(".. ".$text{'install_failed_status'}),
|
|
{ 'data-second-print' => undef });
|
|
print "<br><div data-x-br=\"\"></div>\n";
|
|
$$current = '';
|
|
$$printed = 1;
|
|
return;
|
|
}
|