]> git.proxmox.com Git - pve-installer.git/blob - proxmox-low-level-installer
low-level: write final installation config to /tmp
[pve-installer.git] / proxmox-low-level-installer
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use lib '.'; # FIXME
7
8 use File::Path qw(make_path);
9 use Getopt::Long;
10 use JSON;
11 use Time::HiRes qw(usleep);
12
13 {
14 my $test_image;
15 GetOptions(
16 'test-image|t=s' => \$test_image
17 ) or die "usage error\n";
18
19 Proxmox::Install::ISOEnv::set_test_image($test_image) if $test_image;
20 }
21
22 use Proxmox::Install::ISOEnv;
23 use Proxmox::Install::RunEnv;
24
25 use Proxmox::Sys::File qw(file_write_all);
26
27 use Proxmox::Log;
28 use Proxmox::Install;
29 use Proxmox::Install::Config;
30 use Proxmox::UI;
31
32 my $commands = {
33 'dump-env' => 'Dump the current ISO and Hardware environment to base the installer UI on.',
34 'start-session' => 'Start an installation session, with command and result transmitted via stdin/out',
35 'start-session-test' => 'Start an installation TEST session, with command and result transmitted via stdin/out',
36 'help' => 'Output this usage help.',
37 };
38
39 sub usage {
40 my ($cmd) = @_;
41
42 if (!$cmd) {
43 printf("ERROR: missing command\n\n");
44 } elsif (!exists($commands->{$cmd})) {
45 printf("ERROR: unknown command '$cmd'\n\n");
46 }
47
48 print "USAGE: $0 <cmd>\n";
49 for my $cmd (sort keys $commands->%*) {
50 printf(" %-20s - %s\n", $cmd, $commands->{$cmd});
51 }
52
53 exit($cmd ne 'help' ? 1 : 0);
54 }
55
56 sub read_and_merge_config {
57 my $config_raw;
58 while (my $line = <>) {
59 if ($line =~ /^\s*\{/) {
60 $config_raw = $line;
61 last;
62 }
63 }
64
65 my $config = eval { from_json($config_raw, { utf8 => 1 }) };
66 die "failed to parse config from stdin - $@\n" if $@;
67
68 Proxmox::Install::Config::merge($config);
69 log_info("got installation config: ". to_json(Proxmox::Install::Config::get(), { utf8 => 1, canonical => 1 }) ."\n");
70 file_write_all("/tmp/low-level-config.json", to_json(Proxmox::Install::Config::get()));
71 }
72
73 sub send_reboot_ui_message {
74 if (Proxmox::Install::Config::get_autoreboot()) {
75 my $secs = 5;
76 while ($secs > 0) {
77 Proxmox::UI::finished(1, "Installation finished - auto-rebooting in $secs seconds ..");
78 sleep 1;
79 $secs -= 1;
80 }
81 } else {
82 Proxmox::UI::finished(1, "Installation finished - reboot now?");
83 }
84 }
85
86 my $cmd = shift;
87 if (!$cmd || $cmd eq 'help' || !exists($commands->{$cmd})) {
88 usage($cmd // '');
89 }
90
91 Proxmox::Log::init("/tmp/install-low-level-${cmd}.log");
92
93 my $env = Proxmox::Install::ISOEnv::get();
94 if ($cmd eq 'dump-env') {
95 Proxmox::UI::init_stdio({}, $env);
96
97 my $out_dir = $env->{locations}->{run};
98 make_path($out_dir);
99 die "failed to create output directory '$out_dir'\n" if !-d $out_dir;
100
101 my $locales_serialized = to_json($env->{locales}, {canonical => 1, utf8 => 1}) ."\n";
102 file_write_all("$out_dir/locales.json", $locales_serialized);
103
104 my $iso_info = {
105 'iso-info' => $env->{iso},
106 'product' => $env->{product},
107 'product-cfg' => $env->{cfg},
108 'run-env-cache-file' => $env->{'run-env-cache-file'},
109 'locations' => $env->{locations},
110 };
111 my $iso_serialized = to_json($iso_info, {canonical => 1, utf8 => 1}) ."\n";
112 file_write_all("$out_dir/iso-info.json", $iso_serialized);
113
114 my $run_env_file = Proxmox::Install::ISOEnv::get('run-env-cache-file');
115
116 my $run_env = Proxmox::Install::RunEnv::query_installation_environment();
117 my $run_env_serialized = to_json($run_env, {canonical => 1, utf8 => 1}) ."\n";
118 file_write_all($run_env_file, $run_env_serialized);
119 } elsif ($cmd eq 'start-session') {
120 Proxmox::UI::init_stdio({}, $env);
121 read_and_merge_config();
122
123 eval { Proxmox::Install::extract_data() };
124 if (my $err = $@) {
125 # suppress "empty" error as we got some case where the user choose to abort on a prompt,
126 # there it doesn't make sense to show them an error again, they "caused" it after all.
127 if ($err ne "\n") {
128 warn "installation failed - $err\n";
129 log_error("installation failed: $err");
130 Proxmox::UI::finished(0, $err);
131 }
132 } else {
133 send_reboot_ui_message();
134 }
135 } elsif ($cmd eq 'start-session-test') {
136 Proxmox::UI::init_stdio({}, $env);
137 read_and_merge_config();
138
139 my $res = Proxmox::UI::prompt("Reply anything?") ? 'ok' : 'not ok';
140 Proxmox::UI::message("Test Message - got $res");
141
142 for (my $i = 1; $i <= 1000; $i += 3) {
143 Proxmox::UI::progress($i/100000, 0, 100, "foo $i");
144 if ($i > 500 && $i < 600) {
145 usleep(50 * 1000);
146 } else {
147 usleep(10 * 1000);
148 }
149 }
150
151 send_reboot_ui_message();
152 }
153
154 exit(0);