/[soft]/draklive-install/trunk/draklive-install
ViewVC logotype

Annotation of /draklive-install/trunk/draklive-install

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4023 - (hide annotations) (download)
Wed Apr 11 22:33:04 2012 UTC (12 years ago) by blino
File size: 14583 byte(s)
fix breakage due to prepare_minimal_root() changes (from tmb)
1 dmorgan 792 #!/usr/bin/perl
2    
3     # Must be done as early as possible to avoid issues when displaying translated
4     # strings
5     BEGIN {
6     push @::textdomains, 'draklive-install';
7     }
8    
9     use lib qw(/usr/lib/libDrakX);
10     use standalone;
11     use interactive;
12     use fs;
13     use fs::any;
14     use fs::type;
15     use fs::partitioning;
16     use fs::partitioning_wizard;
17     use partition_table;
18     use MDK::Common;
19     use common;
20     use feature qw(state);
21    
22     ($::real_windowwidth, $::real_windowheight) = (600, 400);
23    
24     {
25     use diskdrake::interactive;
26     package diskdrake::interactive;
27     my $old = \&hd_possible_actions_base;
28     undef *hd_possible_actions_base;
29     *hd_possible_actions_base = sub {
30     #- for the partition wizard to show the auto-allocate option
31     local $::isInstall = 1;
32     &$old;
33     };
34     undef *Done;
35     #- skip the fstab/reboot checks
36     *Done = \&diskdrake_interactive_Done;
37     #- don't ask whether to Move/Hide old files
38     undef *need_migration;
39     *need_migration = sub { 'hide' };
40     }
41    
42     install_live();
43    
44     sub install_live() {
45     my $in = 'interactive'->vnew('su');
46     $in->{pop_wait_messages} = 0;
47    
48     $::isWizard = 1;
49     $::Wizard_no_previous = 1;
50 blino 816 $::Wizard_pix_up = "draklive-install";
51 dmorgan 792 any::set_wm_hints_if_needed($in);
52    
53     my $all_hds = {};
54     my $fstab = [];
55     $::prefix = '/mnt/install';
56    
57     my $system_file = '/etc/sysconfig/draklive-install';
58     my %settings = getVarsFromSh($system_file);
59    
60     my $copy_source = $settings{SOURCE} || '/';
61     my $live_media = '/live/media';
62    
63     display_start_message();
64     init_hds($in, $all_hds, $fstab, $live_media);
65     ask_partitions_loop($in, $all_hds, $fstab, $copy_source);
66     remove_unused_packages($in, $copy_source);
67     prepare_root($in, $all_hds);
68     copy_root($in, $copy_source);
69     complete_install($in, $all_hds);
70     setup_bootloader($in, $all_hds, $fstab);
71     finish_installation($fstab);
72     display_end_message($in);
73     $in->exit(0);
74     }
75    
76     sub umount_all {
77     my ($fstab) = @_;
78     #- make sure nothing is mounted in the new root
79     foreach (sort { $b cmp $a } grep { /^$::prefix/ } map { (split)[1] } cat_('/proc/mounts')) {
80     system('umount', $_);
81     }
82     #- make sure selected devices aren't mounted, and swap isn't used
83     foreach (grep { isSwap($_) } @$fstab) {
84     eval { fs::mount::swapoff($_->{device}) };
85     }
86     foreach (map { $_->{mntpoint} && !isSwap($_) ? "/dev/$_->{device}" : () } @$fstab) {
87     system('umount', $_);
88     }
89     }
90    
91     sub on_reboot_needed {
92     my ($in) = @_;
93     fs::partitioning_wizard::warn_reboot_needed($in);
94     $in->exit(0);
95     }
96    
97     sub display_start_message() {
98     require any;
99     my $has_running_wm = to_bool(any::running_window_manager());
100     local $::isStandalone = $has_running_wm; # center me if run in xsetup.d script
101     my $w = ugtk2->new(N("Mageia Live"));
102     ugtk2::gtkadd($w->{window},
103     ugtk2::gtkcreate_img("MageiaLive-install"),
104     ugtk2::gtknew('Label', height => 5),
105     N("This wizard will help you to install the live distribution."),
106     ugtk2::create_okcancel($w));
107     $w->{ok}->grab_focus;
108     $w->main;
109     }
110    
111     sub umount_first_pass() {
112     local $::prefix = undef;
113     my $all_hds = fsedit::get_hds();
114     fs::get_raw_hds('', $all_hds);
115     fs::get_info_from_fstab($all_hds);
116     my $fstab = [ fs::get::fstab($all_hds) ];
117     fs::merge_info_from_mtab($fstab);
118    
119     #- inlined from fs::mount::umount_all to go on when one umount fail
120     #- (maybe the sort function could be shared)
121     log::l("unmounting all filesystems");
122     foreach (sort { $b->{mntpoint} cmp $a->{mntpoint} }
123     grep { $_->{mntpoint} && !$_->{real_mntpoint} } @$fstab) {
124     eval { fs::mount::umount_part($_) };
125     log::l("error unmounting $_->{mntpoint}: $@") if $@;
126     }
127     }
128    
129     sub init_hds {
130     my ($in, $all_hds, $fstab, $live_media) = @_;
131     my $wait = $in->wait_message('', N("Please wait"));
132     umount_first_pass();
133     eval { fs::any::get_hds($all_hds, $fstab, [], {}, 'skip_mtab', $in) };
134    
135     #- fs::any::get_hds does not return mounts that are not in fstab
136     my @mounted = fs::read_fstab('', '/proc/mounts');
137     my $live_part = find { $_->{mntpoint} eq $live_media } @mounted;
138     my $live_device = $live_part && $live_part->{device};
139     #- remove live device from the detected hds, so that bootloader is not installed on it:
140     #- bootloader installation uses first device from detect_devices::get, which tries to list devices
141     #- by booting order, and our live system is likely to be here in first position
142     #- it can be either a partition (USB) or the full disk (Hybrid on USB)
143     @{$all_hds->{hds}} = grep {
144     $_->{device} ne $live_device &&
145     !member($live_device, map { $_->{device} } partition_table::get_normal_parts_and_holes($_));
146     } @{$all_hds->{hds}} if $live_device;
147    
148     my $err = $@;
149     umount_all($fstab);
150     if ($err) {
151     undef $wait;
152     $in->ask_warn(N("Error"), [ formatError($err) ]);
153     $in->exit(1);
154     }
155     }
156    
157     sub ask_partitions_loop {
158     my ($in, $all_hds, $fstab, $copy_source) = @_;
159    
160     while (1) {
161     eval { ask_partitions($in, $all_hds, $fstab, $copy_source) };
162     my $err = $@ or last;
163     $in->exit(1) if $err =~ /wizcancel/ ||
164     !$in->ask_warn(N("Error"), [ N("An error occurred"), formatError($err) ]);
165     }
166     }
167    
168     sub ask_partitions {
169     my ($in, $all_hds, $fstab, $copy_source) = @_;
170     fs::partitioning_wizard::main($in, $all_hds, $fstab, [], undef, {}, 'skip_mtab');
171    
172     mkdir_p($::prefix) or die "unable to create $::prefix";
173    
174     fs::any::write_hds($all_hds, $fstab, undef, sub { on_reboot_needed($in) }, {});
175     fs::any::check_hds_boot_and_root($all_hds, $fstab);
176     fs::partitioning::choose_partitions_to_format($in, $fstab);
177    
178     my $total = get_total_size($in, $copy_source);
179     my $available = fs::any::getAvailableSpace($fstab, 'skip_mounted');
180     die N("Not enough space available (%s available while %s are needed)",
181     formatXiB($available), formatXiB($total)) . "\n"
182     if $total > $available;
183    
184     umount_all($fstab);
185     fs::partitioning::format_mount_partitions($in, $all_hds, $fstab);
186     }
187    
188     sub remove_unused_packages {
189     my ($in, $o_prefix) = @_;
190     require pkgs;
191     #in remove_unused_packages, we want to get the locale from the currently
192     #running system, but we want to remove unused packages from the
193     #system based in $o_prefix, that's why we use an extra arg instead of
194     #directly using $::prefix
195     local $::prefix;
196     pkgs::remove_unused_packages($in, $in->do_pkgs, $o_prefix);
197     }
198    
199     sub prepare_root {
200     my ($in, $all_hds) = @_;
201     #- create required directories and devices (early to have a consistent root before calling other programs)
202     my $_wait = $in->wait_message('', N("Please wait"));
203 blino 4023 fs::any::prepare_minimal_root();
204 dmorgan 792 }
205    
206     sub build_copy_command {
207     my ($source, $dest) = @_;
208     join(' ',
209     'tar', 'c', '--one-file-system', '-C', $source, '.',
210     '|',
211     'tar', 'xvv', '-C', $dest,
212     );
213     }
214    
215     sub get_total_size {
216     my ($in, $source) = @_;
217     state %total;
218     return $total{$source} if $total{$source};
219     my $_wait = $in->wait_message('', N("Computing total size"));
220     $total{$source} = first(split(/\s+/, `du -sbx $source 2>/dev/null`));
221     }
222    
223     sub sync_logs() {
224     cp_af('/var/log', $::prefix . '/var');
225     }
226    
227     sub copy_root {
228     my ($in, $copy_source) = @_;
229     my $total = get_total_size($in, $copy_source);
230    
231     my ($wait, $update_progress) = copying_message_with_progress_bar($in, N("Copying in progress"));
232     open(my $OUTPUT, '-|', build_copy_command($copy_source, $::prefix));
233     {
234     local $_;
235     my $current = my $previous = 0;
236     while (<$OUTPUT>) {
237     (undef, undef, my $size) = split;
238     $current += $size;
239     if ($current <= $total && $current/$total > $previous/$total + 0.001) {
240     $update_progress->('', $current, $total);
241     $previous = $current;
242     }
243     }
244     }
245     if (!close($OUTPUT)) {
246     undef $wait;
247     undef $update_progress;
248     $in->ask_warn(N("Error"), N("Unable to copy files to new root"));
249     $in->exit(1);
250     }
251     sync_logs();
252     }
253    
254     sub clean_harddrake_hds {
255     my ($prefix) = @_;
256     #- remove harddisks from harddrake's config file, so that hardddisks
257     #- are automatically rediscovered at first boot
258     require Storable;
259     my $harddrake_file = $prefix . "/etc/sysconfig/harddrake2/previous_hw";
260     my $harddrake_conf = eval { Storable::retrieve($harddrake_file) };
261     if ($harddrake_conf) {
262     delete $harddrake_conf->{HARDDISK};
263     Storable::store($harddrake_conf, $harddrake_file);
264     }
265     }
266    
267    
268     sub complete_install {
269     my ($in, $all_hds) = @_;
270     my $_wait = $in->wait_message('', N("Please wait"));
271    
272     my $real_rpm_dir = "/tmp/rpm/real";
273     cp_f(glob($real_rpm_dir . "/*"), $::prefix . "/var/lib/rpm") if -d $real_rpm_dir;
274    
275     #- FIXME: maybe factorize with draklive, using draklive --clean-chroot ?
276     #- remove unwanted files and packages
277     my $live_user = chomp_(cat_('/etc/draklive-install.d/user'));
278     my $live_user_desktop = $live_user && chomp_(run_program::rooted_get_stdout($::prefix, "su - $live_user -c 'xdg-user-dir DESKTOP'"));
279     unlink(map { $::prefix . $_ } '/.autofsck',
280     chomp_(cat_(glob('/etc/draklive-install.d/remove.d/*'))),
281     if_($live_user_desktop,
282     $live_user_desktop . '/draklive-copy-wizard.desktop',
283     $live_user_desktop . '/draklive-install.desktop'),
284     );
285     {
286     #- do not allow update-menus to create home directory with invalid perms
287     local $ENV{HOME} = '/root';
288     system('chroot', $::prefix, 'rpm', '-e', 'draklive-install');
289     }
290    
291     foreach (glob('/etc/draklive-install.d/run.d/*')) {
292     run_program::rooted($::prefix, $_);
293     }
294    
295     #- copy sysconfig files for first boot
296     cp_f(glob('/etc/draklive-install.d/sysconfig/*'), $::prefix . '/etc/sysconfig');
297    
298     #- unselect live user in kdm
299     my $kdm_cfg = common::read_alternative('kdm4-config');
300     update_gnomekderc($::prefix . $kdm_cfg,
301     'X-:0-Greeter' => (PreselectUser => 'None', DefaultUser => '')) if -f $kdm_cfg;
302     my $autologin = any::get_autologin();
303     delete $autologin->{user};
304     any::set_autologin($in->do_pkgs, $autologin);
305    
306     #- allow to install doc in disk install
307     substInFile { undef $_ if /^\%_excludedocs/ } $::prefix . '/etc/rpm/macros';
308    
309     fs::write_fstab($all_hds, $::prefix);
310    
311     clean_harddrake_hds($::prefix);
312    
313     # enable back some disabled services
314     require services;
315     services::start_service_on_boot($_) foreach chomp_(cat_('/etc/draklive-install.d/services'));
316    
317     sync_logs();
318     }
319    
320     sub setup_bootloader {
321     my ($in, $all_hds, $fstab) = @_;
322     use bootloader;
323     my $bootloader = {};
324     any::setupBootloaderBeforeStandalone($in->do_pkgs, $bootloader, $all_hds, $fstab);
325     local $::Wizard_no_previous = 0;
326     any::setupBootloaderUntilInstalled($in, $bootloader, $all_hds, $fstab, $ENV{SECURE_LEVEL});
327     sync_logs();
328     }
329    
330     sub clean_live_system_hds() {
331     #- clean fstab and harddrake config in the live system
332     #- since partitions UUIDs of the installed system have been modified
333     #- (useful for persistent live systems)
334     local $::prefix = undef;
335     clean_harddrake_hds($::prefix);
336     my $all_hds = fs::get::empty_all_hds(); #- skip real harddisks
337     fs::get_raw_hds('', $all_hds);
338     fs::get_info_from_fstab($all_hds);
339     fs::write_fstab($all_hds, $::prefix);
340     }
341    
342     sub finish_installation {
343     my ($fstab) = @_;
344     sync_logs();
345     #- cleanly umount here, it will avoid fs journals to be corrupted after a hackish reboot
346     umount_all($fstab);
347     clean_live_system_hds();
348     }
349    
350     sub display_end_message {
351     my ($in) = @_;
352     $::Wizard_finished = 1;
353     $in->ask_okcancel(N("Congratulations"), N("Please halt your computer, remove your live system, and restart your computer."));
354     }
355    
356     ###
357     ### duplicate code
358     ###
359    
360     #- from disdrake::interactive
361     {
362     package diskdrake::interactive;
363     sub diskdrake_interactive_Done {
364     my ($in, $all_hds) = @_;
365     eval { raid::verify($all_hds->{raids}) };
366     if (my $err = $@) {
367     $::expert or die;
368     $in->ask_okcancel('', [ formatError($err), N("Continue anyway?") ]) or return;
369     }
370     foreach (@{$all_hds->{hds}}) {
371     if (!write_partitions($in, $_, 'skip_check_rebootNeeded')) {
372     return if !$::isStandalone;
373     $in->ask_yesorno(N("Quit without saving"), N("Quit without writing the partition table?"), 1) or return;
374     }
375     }
376     #- skip that fstab/reboot steps
377     if (!$::isInstall && 0) {
378     my $new = fs::fstab_to_string($all_hds);
379     if ($new ne $all_hds->{current_fstab} && $in->ask_yesorno('', N("Do you want to save /etc/fstab modifications"), 1)) {
380     $all_hds->{current_fstab} = $new;
381     fs::write_fstab($all_hds);
382     }
383     update_bootloader_for_renumbered_partitions($in, $all_hds);
384    
385     if (any { $_->{rebootNeeded} } @{$all_hds->{hds}}) {
386     $in->ask_warn('', N("You need to reboot for the partition table modifications to take place"));
387     tell_wm_and_reboot();
388     }
389     }
390     if (my $part = find { $_->{mntpoint} && !maybeFormatted($_) } fs::get::fstab($all_hds)) {
391     $in->ask_okcancel('', N("You should format partition %s.
392     Otherwise no entry for mount point %s will be written in fstab.
393     Quit anyway?", $part->{device}, $part->{mntpoint})) or return if $::isStandalone && 0; #- no, please
394     }
395     1;
396     }
397     }
398    
399     # forked from interactive::wait_message
400     sub copying_message {
401     my ($o, $title, $message, $b_temp) = @_;
402    
403     my $w = $o->wait_messageW($title, N("Copying in progress"), ugtk2::gtknew('VBox', padding => 5, children_tight => [
404     ugtk2::gtkcreate_img("MageiaLive-advert"),
405     $message,
406     ]));
407     push @tempory::objects, $w if $b_temp;
408     my $b = before_leaving { $o->wait_message_endW($w) };
409    
410     #- enable access through set
411     MDK::Common::Func::add_f4before_leaving(sub { $o->wait_message_nextW($_[1], $w) }, $b, 'set');
412     $b;
413     }
414    
415     # forked from interactive::gtk::wait_message_with_progress_bar
416     sub copying_message_with_progress_bar {
417     my ($in, $o_title) = @_;
418    
419     my $progress = Gtk2::ProgressBar->new;
420     my $w = copying_message($in, $o_title, $progress);
421     my $displayed;
422     $progress->signal_connect(expose_event => sub { $displayed = 1; 0 });
423     $w, sub {
424     my ($msg, $current, $total) = @_;
425     if ($msg) {
426     $w->set($msg);
427     }
428    
429     if ($total) {
430     $progress or internal_error('You must first give some text to display');
431     $progress->set_fraction($current / $total);
432     $progress->show;
433     $displayed = 0;
434     mygtk2::flush() while !$displayed;
435     } else {
436     $progress->hide if !$total;
437     }
438     };
439     }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.30