diff options
Diffstat (limited to 'zarb-ml/mageia-sysadm/attachments/20110203/978af990/attachment-0001.html')
-rw-r--r-- | zarb-ml/mageia-sysadm/attachments/20110203/978af990/attachment-0001.html | 4462 |
1 files changed, 4462 insertions, 0 deletions
diff --git a/zarb-ml/mageia-sysadm/attachments/20110203/978af990/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110203/978af990/attachment-0001.html new file mode 100644 index 000000000..af0108c9f --- /dev/null +++ b/zarb-ml/mageia-sysadm/attachments/20110203/978af990/attachment-0001.html @@ -0,0 +1,4462 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" +"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /> +<title>[397] Import cleaned draklive</title> +</head> +<body> + +<style type="text/css"><!-- +#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; } +#msg dl.meta dt { float: left; width: 6em; font-weight: bold; } +#msg dt:after { content:':';} +#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; } +#msg dl a { font-weight: bold} +#msg dl a:link { color:#fc3; } +#msg dl a:active { color:#ff0; } +#msg dl a:visited { color:#cc6; } +h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; } +#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; } +#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; } +#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; } +#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; } +#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; } +#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; } +#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; } +#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; } +#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; } +#logmsg pre { background: #eee; padding: 1em; } +#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;} +#logmsg dl { margin: 0; } +#logmsg dt { font-weight: bold; } +#logmsg dd { margin: 0; padding: 0 0 0.5em 0; } +#logmsg dd:before { content:'\00bb';} +#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; } +#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; } +#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; } +#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; } +#logmsg table th.Corner { text-align: left; } +#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; } +#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; } +#patch { width: 100%; } +--></style> +<div id="msg"> +<dl class="meta"> +<dt>Revision</dt> <dd>397</dd> +<dt>Author</dt> <dd>dmorgan</dd> +<dt>Date</dt> <dd>2011-02-03 18:53:54 +0100 (Thu, 03 Feb 2011)</dd> +</dl> + +<h3>Log Message</h3> +<pre>Import cleaned draklive</pre> + +<h3>Added Paths</h3> +<ul> +<li>draklive/</li> +<li><a href="#drakliveCLEANUP_PROGRESStxt">draklive/CLEANUP_PROGRESS.txt</a></li> +<li>draklive/trunk/</li> +<li><a href="#draklivetrunkperl_checker">draklive/trunk/.perl_checker</a></li> +<li><a href="#draklivetrunkChangeLog">draklive/trunk/ChangeLog</a></li> +<li><a href="#draklivetrunkMakefile">draklive/trunk/Makefile</a></li> +<li><a href="#draklivetrunkNEWS">draklive/trunk/NEWS</a></li> +<li><a href="#draklivetrunkdraklive">draklive/trunk/draklive</a></li> +<li><a href="#draklivetrunkdraklivecopywizarddesktop">draklive/trunk/draklive-copy-wizard.desktop</a></li> +<li>draklive/trunk/kmod/</li> +<li><a href="#draklivetrunkkmodreadlogc">draklive/trunk/kmod/readlog.c</a></li> +<li>draklive/trunk/lib/</li> +<li>draklive/trunk/lib/MDV/</li> +<li>draklive/trunk/lib/MDV/Draklive/</li> +<li><a href="#draklivetrunklibMDVDrakliveConfigpm">draklive/trunk/lib/MDV/Draklive/Config.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveCustomMediapm">draklive/trunk/lib/MDV/Draklive/CustomMedia.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveInitrdpm">draklive/trunk/lib/MDV/Draklive/Initrd.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveLivepm">draklive/trunk/lib/MDV/Draklive/Live.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveLoopbackpm">draklive/trunk/lib/MDV/Draklive/Loopback.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveMediapm">draklive/trunk/lib/MDV/Draklive/Media.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveMountspm">draklive/trunk/lib/MDV/Draklive/Mounts.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveOverlaypm">draklive/trunk/lib/MDV/Draklive/Overlay.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveProgresspm">draklive/trunk/lib/MDV/Draklive/Progress.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveStoragepm">draklive/trunk/lib/MDV/Draklive/Storage.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveStorageFSpm">draklive/trunk/lib/MDV/Draklive/StorageFS.pm</a></li> +<li><a href="#draklivetrunklibMDVDrakliveUtilspm">draklive/trunk/lib/MDV/Draklive/Utils.pm</a></li> +<li><a href="#draklivetrunkmkinitrddraklive">draklive/trunk/mkinitrd-draklive</a></li> +<li><a href="#draklivetrunkwrite_flashsh">draklive/trunk/write_flash.sh</a></li> +</ul> + +</div> +<div id="patch"><pre> +<a id="drakliveCLEANUP_PROGRESStxt">Added: draklive/CLEANUP_PROGRESS.txt</a> +=================================================================== +--- draklive/CLEANUP_PROGRESS.txt (rev 0) ++++ draklive/CLEANUP_PROGRESS.txt 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,3 @@ ++- License is GPLv2+ according to the copyright header ++- Change one occurance of "Mandriva" to "Mageia" in draklive as it'll be visible to ++ users + + +Property changes on: draklive/CLEANUP_PROGRESS.txt +___________________________________________________________________ +<a id="svneolstyle">Added: svn:eol-style</a> + + native + +<a id="draklivetrunkperl_checker">Added: draklive/trunk/.perl_checker</a> +=================================================================== +--- draklive/trunk/.perl_checker (rev 0) ++++ draklive/trunk/.perl_checker 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,27 @@ ++constant ++AutoLoader ++Carp::Heavy ++Compress::Zlib ++Cwd ++Date::Manip ++Digest::MD5 ++Encode ++encoding ++File::Find ++File::FnMatch ++File::GlobMapper ++File::Path ++File::Temp ++Gtk2::Gdk::Keysyms ++IO::Compress::Gzip ++IO::Uncompress::Gunzip ++IO::Handle ++IO::Pipe ++Pod::Usage ++Scalar::Util ++String::ShellQuote ++Symbol ++Text::ParseWords ++Term::ReadKey ++urpm::media ++urpm::parallel + +<a id="draklivetrunkChangeLog">Added: draklive/trunk/ChangeLog</a> +=================================================================== +--- draklive/trunk/ChangeLog (rev 0) ++++ draklive/trunk/ChangeLog 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,437 @@ ++2007-09-29 15:57 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: do not run service_harddrake stop anymore, it does not ++ exist in 2008.0 ++ ++2007-09-25 15:20 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix typo ++ ++2007-09-25 14:05 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: add newlines in die messages, not to trigger the ++ infamous drakbug ++ ++2007-09-25 13:55 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: print usage if no option is specified ++ ++2007-09-25 10:31 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix division by zero /o\ ++ ++2007-09-19 14:53 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: copy additional modules after plain modules, so that ++ they can overwrite them ++ ++2007-09-19 14:53 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix additional modules copy ++ ++2007-09-03 08:44 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: please perl_checker ++ ++2007-09-03 08:42 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: don't check symlinks when looking for kernels (fix ++ matching vmlinuz-tmb-desktop586) ++ ++2007-09-03 08:41 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: simplify ++ ++2007-08-28 08:52 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: allow to copy per-fs files in mkinitrd ++ ++2007-08-28 08:50 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: move mount actions in a storage_fs hash ++ ++2007-08-28 08:49 Olivier Blin <oblin at mandriva.com> ++ ++ * .perl_checker: supplement perl_checker blacklist ++ ++2007-08-28 08:41 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: run mkdevices to create nodes for existing devices ++ ++2007-08-28 08:40 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix typo ++ ++2007-08-28 08:39 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: move modules mount point in new root ++ ++2007-08-28 08:39 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: cosmetics ++ ++2007-08-28 08:38 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: remove more dirs ++ ++2007-08-28 08:35 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: add a new is_loopback variable to better list selected ++ loopbacks ++ ++2007-08-28 08:33 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: create less loop devices by default ++ ++2007-08-28 08:23 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: allow to specify ro unionfs branches ++ ++2007-08-28 08:19 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: make bootloader timeout configurable ++ ++2007-08-28 08:16 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix unionfs branches list by removing trailing colon ++ (for unionfs2) ++ ++2007-08-28 08:15 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: make boot and loopbacks read-only ++ ++2007-08-28 08:15 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: mark hidden files hidden only ++ ++2007-07-16 12:56 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix vfat check... ++ ++2007-06-12 09:47 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: oops, I really meant vfat when stripping labels for ++ nash ++ ++2007-06-11 15:26 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: add a get_media_source_for_nash functions that formats ++ ext2 labels accordingly ++ ++2007-06-07 16:33 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: do not select modules directory together with loopbacks ++ ++2007-06-07 14:43 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: hidden_files is a better name ++ ++2007-06-07 14:42 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: hide more autorun files ++ ++2007-06-07 09:47 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: remove multi squash union, better replaced with modules ++ ++2007-06-07 09:47 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: use modules in volatile_squash_union mounts ++ ++2007-06-07 09:41 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix extra files selection in cdrom master ++ ++2007-06-05 18:57 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: perl_checker fixes ++ ++2007-06-05 18:57 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: only run mattrib for vfat ++ ++2007-06-05 18:55 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: also hide autorun.inf (yes, hardcode it) ++ ++2007-06-05 18:54 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: hide all files begining with a dot on USB media ++ ++2007-06-05 11:54 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: do not copy extra media files in boot images ++ ++2007-06-05 07:17 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: add a glob wrapper that dotglob behavior and expand ++ only if needed ++ ++2007-06-05 01:12 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: protect rm_rf from die ++ ++2007-06-04 15:48 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: run mattrib with MTOOLS_SKIP_CHECK ++ ++2007-06-04 15:48 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: create mtools_run_ ++ ++2007-06-04 14:49 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: use glob_ to match dot files (since File::Glob does not ++ provide a dotglob option) ++ ++2007-05-31 15:14 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: revert to initrd + pivot_root (or else unionfs panicks ++ in unionfs_file_revalidate when using unionctl in new root) ++ ++2007-05-31 13:39 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: modify custom nfs syntax ++ ++2007-05-31 13:38 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: oops, add back mountpoint ++ ++2007-05-31 13:36 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: use modules source for squash_union ++ ++2007-05-31 13:35 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: add modules source type ++ ++2007-05-31 13:19 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: allow to get loopbacks list from a file ++ ++2007-05-31 13:16 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: allow to delay mount of specific loopbacks ++ ++2007-05-31 12:29 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: try to get interactive debug shell ++ ++2007-05-31 12:08 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: allow to specify module options in ++ $live->{system}{module_options} ++ ++2007-05-31 12:06 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: allow to use real glob patterns in ++ live->{system}{remove_files} ++ ++2007-05-31 12:05 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix directory creation when dest is a dir in ++ copy_files_to ++ ++2007-05-31 12:04 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: clean build files before creating new ones ++ ++2007-05-29 16:39 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: pre-create devfsd compatibility loop devices (since ++ busybox is still built with devfsd support) ++ ++2007-05-29 16:37 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: pre-create more loop devices ++ ++2007-05-26 17:39 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: modify loopback modules syntax to be compatible with ++ file list expansion ++ ++2007-05-26 17:38 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: copy resolv.conf in chroot for urpmi to work (and clean ++ it at end of post-install) ++ ++2007-05-25 16:32 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix excluded loopback path ++ ++2007-05-21 13:14 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: pass opts when formatting ++ ++2007-05-21 13:13 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix typo... ++ ++2007-05-21 13:12 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: make optional device usage more consistent ++ ++2007-05-21 13:05 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: remove extra media support ++ ++2007-05-21 13:02 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix some typos ++ ++2007-05-21 13:02 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: remove optional media support ++ ++2007-05-17 22:07 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: move new root mount point in /sysroot, so that live dir ++ can be properly removed from initramfs ++ ++2007-05-16 22:07 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: remove more initrd relics ++ ++2007-05-16 22:06 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: use busybox's mkdir since nash's "mkdir -p" does not ++ have the standard behavior ++ ++2007-05-16 21:02 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: fix silly typo ++ ++2007-05-16 20:48 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: allow to include loopback modules in master images by ++ defining modules sets in live->{packs} and selecting them from ++ live->{settings}{pack} ++ ++2007-05-16 20:42 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: define /modules in prefix hash ++ ++2007-05-16 20:40 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: make directory path prefixed by / (to make subpath ++ usage easier) ++ ++2007-05-16 20:38 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: rename directory "location" field as "path" ++ ++2007-05-16 20:31 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: allow to create loopback modules from ++ live->{loopbacks}{modules} (to be used for separate i18n ++ loopbacks) ++ ++2007-05-16 20:25 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: archive excluded files list as loopback type defined by ++ live->{loopbacks}{exclude}{type}} instead of tarball ++ ++2007-05-16 20:23 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: use hardlink_filtered to build excluded files tarball ++ ++2007-05-16 20:18 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: add hardlink_filtered function to hardlink recursively ++ file list to a directory (using rsync --files-from --link-dest) ++ ++2007-05-16 20:14 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: allow to use glob when expand file list ++ ++2007-05-16 20:14 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: protect deref ++ ++2007-05-16 20:13 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: rename live->{loopbacks}{exclude_files} as ++ live->{loopbacks}{exclude}{files} ++ ++2007-05-16 20:12 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: transform list_excluded_files as more generic ++ expand_file_list ++ ++2007-05-16 20:10 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: pass excluded files list in loopback directory hash to ++ allow refined exclusion ++ ++2007-05-16 20:03 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: really set bootlogo variable (and simplify) ++ ++2007-05-16 19:56 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: add extension for some loopback types ++ ++2007-05-16 19:42 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: add list_selected_loopbacks() function ++ ++2007-05-16 19:35 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: copy only selected loopbacks in master image ++ ++2007-05-16 19:29 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: allow to build squashfs with prefix different from ++ chroot ++ ++2007-05-16 19:26 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: differentiate squashfs source and prefix to be able to ++ build from sources != '/' ++ ++2007-05-16 19:23 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: create loopbacks directory in indivual build functions ++ and not on top directory (they may have to create subdirs anyway) ++ ++2007-05-16 19:20 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: really use $dir variable and not indefinite $_ ++ ++2007-05-16 19:17 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: rename directory "source" field as "location" ++ ++2007-05-16 19:01 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: use initramfs instead of initrd ++ ++2007-05-16 18:57 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: rename create_initrd_linuxrc as create_initrd_scriptlet ++ ++2007-05-02 11:56 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: pre-create tarballs directory ++ ++2007-05-02 09:48 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: perl_checker fix ++ ++2007-05-02 09:47 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: include media files on CD as well ++ ++2007-05-02 09:46 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: move media files copy in post-install step ++ ++2007-05-02 09:45 Olivier Blin <oblin at mandriva.com> ++ ++ * draklive: move umask restoration at end of post-install ++ ++2007-05-02 09:23 Olivier Blin <oblin at mandriva.com> ++ ++ * ., .perl_checker, Makefile, NEWS, draklive, ++ draklive-copy-wizard.desktop: reimport draklive in SVN ++ + +<a id="draklivetrunkMakefile">Added: draklive/trunk/Makefile</a> +=================================================================== +--- draklive/trunk/Makefile (rev 0) ++++ draklive/trunk/Makefile 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,40 @@ ++NAME = draklive ++VERSION = 0.9 ++ ++check: ++ perl -cw -I./lib $(NAME) ++ ++clean: ++ find -name '*~' -exec rm {} \; ++ ++dist: dis ++dis: clean ++ rm -f ../$(NAME)-$(VERSION)*.tar* ++ @if [ -e ".svn" ]; then \ ++ $(MAKE) dist-svn; \ ++ elif [ -e ".git" ]; then \ ++ $(MAKE) dist-git; \ ++ else \ ++ echo "Unknown SCM (not SVN nor GIT)";\ ++ exit 1; \ ++ fi; ++ $(info $(NAME)-$(VERSION).tar.xz is ready) ++ ++dist-svn: ++ rm -rf $(NAME)-$(VERSION) ++ svn export -q -rBASE . $(NAME)-$(VERSION) ++ tar cfJ ../$(NAME)-$(VERSION).tar.xz $(NAME)-$(VERSION) ++ rm -rf $(NAME)-$(VERSION) ++ ++dist-git: ++ @git archive --prefix=$(NAME)-$(VERSION)/ HEAD | xz >../$(NAME)-$(VERSION).tar.xz; ++ ++.PHONY: ChangeLog log changelog ++ ++log: ChangeLog ++ ++changelog: ChangeLog ++ ++ChangeLog: ++ svn2cl --accum --authors ../../soft/common/username.xml ++ rm -f *.bak + + +Property changes on: draklive/trunk/Makefile +___________________________________________________________________ +Added: svn:eol-style + + native + +<a id="draklivetrunkNEWS">Added: draklive/trunk/NEWS</a> +=================================================================== +--- draklive/trunk/NEWS (rev 0) ++++ draklive/trunk/NEWS 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,508 @@ ++0.9: ++ ++* config ++- automatically export draklive settings to DRAKLIVE_ environment variables for install ++- allow to specify mount options in fstab in media->{mount_options} ++- make it possible to specify mount options for tmpfs mounts ++- allow to skip writing fstab with live->{system}{skip_fstab} ++- allow to skip writing bootloader config with live->{system}{skip_bootloader_config} ++- allow to skip bootloader install with live->{system}{skip_bootloader_install} ++- allow not to create initrd with live->{system}{no_initrd} ++- allow to select which settings fields are used to build name, in live->{name_fields} ++ ++* install ++- generate lst.names files list ++- make sure zh_TW and zh_CN will be included in language list ++- clean resolv.conf later (so that network can be used in post) ++ ++* initrd ++- dropped splashy support, added plymouth support ++ (using bootloader::add_boot_splash) ++- don't mount /dev/pts since this causes huge slowdowns ++- mount tmpfs partitions with 0755 perms (#51565): ++ When using the obsolete --attach-to-session plymouth option, /dev/pts ++ has to be mounted. But for some reason, nash interacts badly with ++ mounted /dev/pts and freezes for dozen of seconds when running a builtin ++ command. Remote --attach-to-session from plymouth which lets us get rid ++ of /dev/pts mounting. ++- add hack to use modules list from chroot ++ (to handle different IDE modules name in build and target environments) ++- detect some modules as built-in and do not wrongly abort ++- do not create initrd symlink or append splash if no initrd has been created ++- make sure /proc and /sys are available when building initrd (useful ++ to see error messages at least, from Paulo Ricardo Zanoni) ++- use bootloader module to build initrd and create kernel symlinks ++ (Gdium friendly) ++ ++* bootloader ++- default to grub bootloader for harddisk storage ++- fix installing grub to separate /boot partition ++- use per-media additional boot_entries ++- do not add default boot entry if media->{boot_entries} is specified ++ (to allow having a custom default entry) ++- fix installing grub to hidden /boot in master image ++- set LD_LIBRARY_PATH to chroot libraries when running grub ++- die in bootloader step if selected kernel does not exist ++- do not add initrd in grub menu if it does not exist ++- allow to install bootloader on separate /boot partition ++- make sure the grub install script is executable ++- do not overwrite grub conf for "classical" boot when installing ++ bootloader ++- use same bootloader install code for disks and USB masters ++- remove hardcoded splashy code and use back bootloader::add_boot_splash ++- run switch-themes -u ++- use bootloader module to find kernel (Gdium friendly) ++- update gfxboot theme before copying gfxboot files ++- fix getting bootsplash theme (fixes gfxboot theme) ++- do not add vga mode on kernel command line if forced in append ++ (for drakx-based replicator) ++- fix setting splash for classical bootloader ++- create media specific gfxmenu if needed only ++- always copy gfxmenu in build boot dir (needed for replicator) ++- do not create bootloader files if bootloader install is to be skipped ++- fix writing media specific boot for disk masters ++ ++* master ++- use -fatfirst option when hybridifying an image ++- use DrakX partitioning/formatting code ++- run udevsettle, like done in diskdrake::interactive::write_partitions ++- allow to set custom media geometry in media->{geom} ++- allow to format disk devices ++- add ext4 and swap support in mkfs ++- use ext4 by default for harddisk ++- set label at mkfs time ++- fix setting label on fat ++- fix setting label for USB devices ++- add default label for harddisk storage ++- always compute master size from pre-computed partition sizes ++- use apparent size when computing loopbacks size (system loopback can be sparse) ++- supplement / partition label with default one if needed ++- allow to add an OEM rescue partition in the master (quite hackish, using live->{oem_rescue}) ++- preset fs_type for OEM_RESCUE partition too ++- allow to set inode size in media->{inode_size} for ext2/ext3 file systems ++- preserve timestamps when copying files ++ ++* image ++- allow to compress master images as gzip instead of bzip2 by setting ++ compression_method=gzip in settings.cfg (from Paulo Ricardo Zanoni) ++ ++* vm-image ++- create vmdk virtual machine images (for VMware, VirtualBox, qemu) ++ ++* replicator ++- copy syslinux dir for replicator too ++- always create syslinux msg files (useful for cdrom replicator) ++- allow drakx-based replicator ++ (by setting live->{settings}{replicator_type} to "drakx") ++- write image size in master list file ++- write bootloader config for replicator media ++ ++* record ++- use full disk device when recording harddisk/oem_rescue/replicator/USB masters ++- allow to mount multiple partitions before recording target master ++- do not try to use configured media source when it is not a label, it ++ could be a device (/dev/sda1) that should not be touched on the ++ build machine, force it to be passed as an option ++ ++ ++0.8: ++ ++* loop ++- use lzma by default (should be an option) ++- use legacy mksquashfs3 instead of the new mksquashfs ++- use 1MB squashfs blocks, this gives us about 10% better compression ++- fix loopback extension in /etc/sysconfig/draklive-resize ++ ++* bootloader ++- remove unneeded locale files from gfxboot bootlogo file (causes boot issues ++ on some machines) ++- add 'harddrive' boot entry to chainload to the harddrive bootloader ++- use latest syslinux + gfxboot COM module ++- do not crash if there is no gfxmenu file ++- use live->{system}{append} ++- specify root in bootloader append for harddisk installs ++- create "classical" bootloader files (grub menu and gfxmenu) ++- upper-case FAT labels again (we switched to blkid in nash) ++- fix installing probe-modules for x86_64 (spotted by imr) ++ ++* master ++- allow to create harddisk masters (for OEM images) ++- hybridify generated ISOs so that they can be dumped on USB keys ++- create bigger vfat and disk masters ++- setup loop device with its real size (so that mkfs does not make a too large fs) ++- write a /boot/grub/install.sh script when installing grub, and run ++ grub in chroot (requires to bind-mount the image inside its mount point) ++- use again du --apparent-size for some sparse files ++ ++* images ++- build compressed harddisk image (for now bzipped, could be extracted ++ through partimage later) ++ ++* replicator ++- allow to create replicator images (cdrom and USB) ++ using stage1 and restore scripts to dump OEM master on final systems ++- add --replicator to build replicator image ++- allow to customize replicator append in live->{replicator}{append} ++ ++* initrd ++- splashy support ++- generate "classical" initrd (for harddisk installs) ++- handle non-gzipped additional modules ++- fix checking missing modules (do it after parsing additional modules) ++- mount /dev as tmpfs after pivot_root, so that finit's /dev/initctl ++ does not get forgotten when start_udev remounts /dev ++- remove deprecated mkdevices call ++- do not use nash-mount to mount tmpfs (run by busybox when using fallback) ++- do not include nls modules for ext2/ext3 filesystems ++- add support for external pre-pivot-root command in initrd ++ (live->{system}{initrd_pre_pivot}) ++- skip non-dirs when mount moving to new root (avoid error messages) ++ ++* config ++- allow to split version out of name (to follow name-product-version naming) ++ ++* chroot ++- use media source instead of /dev/root in fstab, since the later ++ confuses mkinitrd ++- write live->{system}{files} with no_install option in ++ /etc/draklive-install.d/remove.d/draklive ++ ++* code architecture ++- split code and MDV::Draklive submodules ++- add initial mkinitrd-draklive prototype ++ (to allow rebuilding live initrd on installed system) ++- add a default mount (for harddisk master) ++- extract predefined and custom mounts/fs in MDV::Draklive::Mounts and ++ MDV::Draklive::CustomMedia modules (breaks config files compatibility) ++ ++ ++0.7: ++ ++* initrd ++- do not copy and load twice additional modules if they were listed in ++ extra modules ++- use nash-mount instead of mount ++- create /etc/blkid and use "showlabels --removable" to get CD-Rom ++ labels in blkid cache ++- adapt to new probe-modules syntax for storage bus ++- use stage1's probe-modules instead of dropped nash's insmod ++- move initrd modules in /lib/modules/`uname -r` ++- gzip initrd modules ++- use depmod to generate modules.dep ++- do not print excluding modules warning if not needed ++- check that there is enough space left in initrd ++- umount /proc/bus/usb before pivot_root in initrd ++- add firewire controllers (bus and disk) in CDROM live (#31356) ++- use libraries from /lib instead of /lib/i686 (#38649) and /lib/tls ++ (#21683) to be able to boot on processors without cmov ++ ++* bootloader ++- remove hardcoded fastboot option (new initscripts do not fsck rw /) ++ ++* master ++- handle genisoimage progress more nicely ++- insert mkcd checksum before computing md5/sha1 checksums ++- hide mkcd output ++ ++* dist ++- rename "images" directory as "dist" ++- create packages lst in dist ++- write a .langs file with human-readable langs list ++- write full list of rpm packages and list of rpm leaves, sorted by package size ++ ++* misc ++- do not try to use consolehelper to display "must be root" message, ++ it's broken outside of X ++ ++ ++0.6: ++ ++* config ++- use config and additional files from live->{settings}{config_root}, ++ defaulting to current directory, or to /etc/draklive if no config file ++ is present in current directory ++- allow to configure files root directory with --config-root ++- use /var/lib/draklive/build as default build dir and ++ /var/lib/draklive/chroot as default chroot dir ++ ++* bootloader ++- improve gfxboot support by copying files from both Mandriva and ++ system-chosen theme ++- install gfxboot files in /isolinux on CD image ++- gfxboot support for grub ++- drop unused F1 binding when gfxboot is used ++- use livecd mode in gfxboot (thanks Pixel \o/) ++- copy gfxmenu instead of moving it (#31879) ++- enable gfxboot only if live->{system}{gfxboot} is set ++- remove extra media support ++- remove optional media support ++- allow to specify bootloader timeout in ++ live->{media}{bootloader_timeout} ++ ++* initrd ++- rename debug command line option as initrd_debug not to conflict ++ with kernel option ++- handle module names with underscores, using new module dependencies ++ functions from list_modules (such as modname2path) ++- add and use probe-modules helper from stage1 to load modules ++- drop useless ide-generic hack, probe-modules will load it as ++ fallback only ++- drop usb-storage hack, done by probe-modules ++- do not explicitely load storage module in linuxrc ++ (done by probe-modules helper) ++- add modules.dep, modules.description, modules.alias, ldetect-lst ++ tables, pci.ids and fallback-modules.alias for probe-modules ++- add .ko.gz symlinks to .ko files (used by probe-modules, gzopen ++ transparently opens uncompressed files) ++- load dependencies of extra modules only ++- install modules in /modules instead of /lib in initrd ++- add partition "loop" type to be able to mount partitions in initrd ++- create empty fstab and mtab for fsck programs not to complain ++- run fsck when mounting ext2 partition ++- move mount actions in a storage_fs hash ++- be less verbose when compressing modules ++- be less verbose when printing skipped modules ++- allow to exclude modules from initrd in ++ live->{system}{exclude_modules} ++- use busybox's mkdir since nash's "mkdir -p" does not have the ++ standard behavior ++- pre-create devfsd compatibility loop devices (since busybox is still ++ built with devfsd support) ++- pre-create more loop devices ++- allow to specify module options in live->{system}{module_options} ++- allow to delay mount of specific loopbacks ++- do not add disk/raw category for cdrom media ++- allow to specify ro unionfs branches ++- fix unionfs branches list by removing trailing colon (for unionfs2) ++- don't check symlinks when looking for kernels ++ (fix matching vmlinuz-tmb-desktop586) ++- run mkdevices to create nodes for existing devices ++- move modules mount point in new root ++- do not mess / tree if no live modules are used ++- allow to copy per-fs files in initrd ++- copy additional modules after plain modules, so that they can overwrite them ++- do not uppercase label anymore for vfat partitions, nash with vol_id ++ seems to handle it fine ++ ++* chroot ++- be less verbose when running patch dry runs ++- don't hardcode list of files to be removed in chroot, they must be ++ listed in live->{system}{remove_files} now (dbus/modprobe/udev files ++ for example) ++- allow to use real glob patterns in live->{system}{remove_files} ++- copy resolv.conf in chroot for urpmi to work (and clean it at end of ++ post-install) ++- do not run service_harddrake stop anymore, it does not exist in 2008.0 ++- run postInstall after copying packages ++ ++* loopbacks ++- allow to create loopback modules from live->{loopbacks}{modules} ++ (to be used for separate i18n loopbacks) ++- allow to include loopback modules in master images by defining ++ modules sets in live->{packs} and selecting them from live->{settings}{pack} ++- write a loopbacks/excluded.tar.bz2 tarball containing files that ++ have been excluded from other loopbacks ++- write excluded.tar.bz2 in /tarballs, so that it does not get ++ included in final ISO image ++- remove multi squash union, better replaced with modules ++- add "modules" source type, and use it for squash_union and ++ volatile_squash_union mounts (which are now custom mounts) ++- allow to exclude files in loopbacks with live->{system}{exclude_files} ++- pass -no-progress option to mksquashfs, draklive handles its own ++ progress bar ++- fix division by zero in progress code /o\ ++ ++* master ++- drop some genisoimage verbosity ++- do not allow to create USB master, it is not correctly implemented yet ++- name images after live name instead of live.iso/live.img ++- compute md5sum and sha1sum for ISO images ++ (in addition to the mkcd checksum) ++- do not copy extra media files in boot images ++- fix extra files selection in cdrom master ++- compute media dirs on the fly instead of hardcoding at start ++ (to support CD-Rom boot images with non-hidden media directories) ++ ++* record ++- make device option used for boot-only as well ++- do not set label if boot-only ++- use bootloader setting from optional media if specified ++- umount usb device if loopback copy fails ++- unlink list file if loopbacks copy fails as well ++- mark as read-only boot and loopbacks on vfat USB media ++- mark as hidden files beginning with a dot, autorun files, boot and ++ loopbacks read-only on vfat USB media ++- only run mattrib for vfat ++- run mattrib with MTOOLS_SKIP_CHECK (like mlabel) ++ ++* misc ++- print usage if no option is specified ++- log files copy ++- add newlines in die messages, not to trigger the infamous drakbug ++- make warn messages less verbose ++- use live->{settings}{name/product/media/desktop/region} in ++ build/chroot names ++- write a packages.lst file containing the installed packages list ++- add a glob wrapper with dotglob behavior, and expand only if needed ++- custom NFS is now in custom{fs} instead of custom{mounts} ++- reorder init so that arch is set before calling get_builddir and ++ get_system_root (#35105) ++- chomp arch returned by rpm to fix directory names when arch is not ++ in settings.cfg (#35105) ++ ++ ++0.5: ++ ++* chroot ++- use glob() instead of glob_() to support again non-wildcarded ++ filenames in live->{system}{files} and live->{media}{files} ++ ++* loopbacks ++- use noappend option in mksquashfs to overwrite previous loopbacks ++ ++ ++0.4: ++ ++* config ++- make loopback fs configurable ++- allow to define fallbacks directories ++ (will be mounted only if the mountpoint is not already mounted) ++- XiB are now used instead of XB when specified fs size is expanded ++- allow to specify min_size in custom squash_union helper ++- introduce "plain" mount type (instead of empty mount type) ++- split build/media prefixes ++- allow to specify additional mount options for storage media ++ (such as umask=...) ++- add live-{system}{hide_media_dirs} and live->{media}{files} ++ (see details in "master" section) ++- allow to use glob patterns in live->{system}{files} and ++ live->{media}{files} ++ ++* bootloader ++- use grub-install and grub files from chroot, and make it use custom ++ boot directory ++ ++* chroot ++- create draklive-resize configuration file and do not build loopback ++ fs if min_size is specified ++ ++* loopbacks ++- use tmpfs as fallback if the ext2 loopback can not be mounted ++- repair loopbacks non-interactively ++ ++* master ++- set MTOOLS_SKIP_CHECK to 1 when running mlabel (some USB pens are ++ misdetected by mtools) ++- allow to hide media dirs by adding '.' in prefixes when ++ live-{system}{hide_media_dirs} is set ++- use mattrib to hide media dirs from windows ++- install grub on both master device and partition (fix boot on buggy ++ Intel BIOS) ++- allow to copy files directly to the final image/media using ++ live->{media}{files} (implemented for USB only) ++ ++ ++0.3: ++ ++* interface ++- make --boot-only copy only boot files (instead of using boot media) ++- add --boot-image option to create a boot image for the selected ++ method ++- make string command line options mandatory ++- add --dump-config option ++- allow to load settings from command line using --define options ++- drop --region option (use --define region=) ++ ++* config ++- make the system.loop size configurable ++- handle GigaBytes for loopback sizes ++- rename live->{post} as live->{system}{initrd_post} ++- export region as DRAKLIVE_REGION for auto_install ++- allow to provide stage2 updates with live->{system}{stage2_updates} ++- allow to make the initrd reread a device partition table using ++ live->{media}{rereadpt} ++ (useful if USB partition changes after some PIN input) ++- allow to customize bootloader title in live->{media}{title} ++- default to config/live.cfg config path ++- allow to load live->{settings} from a file and default to ++ config/settings.cfg ++- use region/repository/root/workdir variables from live->{settings} ++- rename "workdir" setting as "builddir" ++- rename "root" setting as "chroot" ++- automatically add arch to specified repository ++ ++* chroot installation ++- remove /etc/dbus-1/machine-id ++- really don't apply patches if they look already applied ++- workaround buggy installation of directories that are not owned by ++ any packages (using 022 umask) ++- do not try to install packages if the additional media is only aimed ++ at adding extra sources (warly) ++- remove urpmi media before starting additional media installation ++- install additional media just before they are required ++- get drakx-in-chroot from the repository ++- run install/rpm commands for targetted architecture ++ ++* bootloader ++- unlink grub device map so that grub rechecks the map ++- die when grub or rsync fail ++- don't install bootloader on non-block device ++- partial gfxboot support (#26430) ++- build bootloader files for boot methods listed in ++ media->{extra_boot} ++- display help file if not bootlogo is available ++- add missing newlines in syslinux/grub configuration files ++ ++* loopbacks ++- don't use sort file if it doesn't exist ++- adapt mksquashfs output parsing to latest release ++- die if mksquashfs fails ++- don't pass float to mkfs.vfat ++- run fsck on rw loopback files before mounting them ++- don't reserv blocks on ext2/3 filesystems, we don't create root fs ++- compute an approximative size for USB master images ++ ++* master/record ++- don't use a timeout for rsync copy (should fix USB mastering) ++- pass -F option to mke2fs only for non-block devices ++- use genisoimage ++- die if genisoimage can not be run ++- use wodim instead of cdrecord ++ ++* copy wizard ++- don't create a master for onthefly USB recording ++- don't show Previous button in copy wizard (#25868) ++- allow to select a master image in the copy wizard ++- update progress during live USB recording ++- add an end step ++- warn if an error occurs during live copy ++- use 788 as default vga mode ++ ++* misc: ++- don't add splash/vga settings on cmdline if no vga mode is defined ++- umount any nfs volume in /mnt (warly) ++- use the 'never' timeout value instead of hardcoded values ++- automatically select storage type if only one is available ++- define directory mounts in their mount order, and reverse the order ++ when mounting unionfs ++- guess arch using rpm _target_cpu macro ++- add arch in chroot and builddir paths ++- include desktop in builddir/chroot name if specified ++ ++ ++0.2: ++ ++- remove modprobe.preload.d files ++- remove /etc/udev/rules.d/61-*_config.rules files ++- use patch batch mode (-t) not to apply already applied patches and die if a patch can't be applied ++- run shell in initrd when the "debug" option is on cmdline ++- allow to add additionnal boot entries ++- umount filesystem which could stay mounted in the chroot before cleaning (warly) ++- default splash image is now splash.xpm.gz for grub ++- rename draklive.desktop as draklive-copy-wizard.desktop ++ ++ ++0.1: ++ ++- use system's mount to mount NFS loopbacks ++- sort squashfs loopback if a config/distrib.sort file is present + +<a id="draklivetrunkdraklive">Added: draklive/trunk/draklive</a> +=================================================================== +--- draklive/trunk/draklive (rev 0) ++++ draklive/trunk/draklive 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,1800 @@ ++#!/usr/bin/perl ++ ++# draklive $Id: draklive 150793 2007-04-05 12:08:47Z blino $ ++ ++# Copyright (C) 2005 Mandriva ++# Olivier Blin <oblin@mandriva.com> ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2, or (at your option) ++# any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++use lib qw(/usr/lib/libDrakX); ++use strict; ++use MDK::Common; ++use common; ++use fs; ++use modules; ++use run_program; ++use Getopt::Long; ++use Pod::Usage; ++use File::Temp; ++use IO::Handle; #- autoflush ++use POSIX; ++use MDV::Draklive::Utils; ++use MDV::Draklive::Live; ++use MDV::Draklive::Progress; ++use MDV::Draklive::Loopback; ++use MDV::Draklive::Initrd; ++use MDV::Draklive::Config; ++use MDV::Draklive::Storage; ++ ++sub get_syslinux_path { ++ my ($media, $opts) = @_; ++ '/' . $media->{storage} . '/syslinux' . ($opts->{boot} && '-boot-' . $opts->{boot}) . '.cfg'; ++} ++ ++sub need_media_specific_boot { ++ my ($live) = @_; ++ to_bool(list_selected_loopbacks($live)); ++} ++ ++sub get_default_append { ++ my ($live, $opts) = @_; ++ my $append = $opts->{append} || $live->{system}{append}; ++ join(' ', ++ if_(!need_media_specific_boot($live), ++ 'root=' . $live->{media}->get_media_source_for_nash), ++ if_($live->{system}{vga_mode} && $append !~ /\bvga=\b/, ++ 'splash=silent', ++ 'vga=' . $live->{system}{vga_mode}), ++ if_($append, $append), ++ ); ++} ++ ++sub get_bootloader_timeout { ++ my ($live) = @_; ++ defined $live->{media}{bootloader_timeout} ? $live->{media}{bootloader_timeout} : 4; ++} ++ ++my @syslinux_boot_files = qw(/vmlinuz /syslinux/bootlogo /help.msg); ++ ++sub build_syslinux_cfg { ++ my ($live, $media, $opts) = @_; ++ my $append = get_default_append($live, $opts); ++ #- syslinux wants files at root (used with vfat fs) ++ my $to_root = $media->get_boot_setting('fs', $opts) eq 'vfat'; ++ my $boot = $live->get_media_prefix('boot', $opts->{boot}); ++ my ($initrd, $kernel, $bootlogo, $help) = map { $to_root ? basename($_) : $_ } ++ map { $boot . $_ } $media->get_initrd_path, @syslinux_boot_files; ++ my $has_bootlogo = $live->{system}{gfxboot} && ++ -e ($live->get_builddir . $live->{prefix}{build}{boot} . '/syslinux/bootlogo'); ++ my $timeout = get_bootloader_timeout($live) * 10; ++ my $title = $media->{title} || $live->{media}{title}; ++ join("\n", ++ "default $title", ++ "prompt 1", ++ "timeout $timeout", ++ "display $help", ++ if_($has_bootlogo, "ui gfxboot.com $bootlogo"), ++ (map { ++ my ($name, $cmdline) = @$_; ++ $name =~ s/\s/_/g; ++ if ($name eq "harddisk") { ++ "label " . $name, ++ " localboot 0x80"; ++ } else { ++ "label " . ($name || $title), ++ " kernel $kernel", ++ " append initrd=$initrd $append $cmdline"; ++ } ++ } group_by2(@{$media->{boot_entries}})), ++ "", ++ ); ++} ++ ++sub build_grub_cfg { ++ my ($live, $media, $opts, $device) = @_; ++ #- FIXME? first partition is hardcoded for loopback (master images) ++ #- FIXME? use find_partition_index ++ my ($part_nb) = $device =~ m!/dev/loop! ? 1 : $device =~ /(\d+)$/; ++ my $part_idx = $part_nb - 1; ++ my $initrd = $media->get_initrd_path; ++ build_grub_cfg_raw($live, $media, $initrd, $opts, $part_idx); ++} ++ ++sub build_grub_cfg_raw { ++ my ($live, $media, $initrd, $opts, $part_idx) = @_; ++ #- FIXME: use the bootloader module from drakx ++ my $grub_part = "(hd0" . (defined $part_idx ? "," . $part_idx : "") . ")"; ++ my $boot = $live->get_media_prefix('boot'); #- FIXME handle boot media ++ #- remove prefix if installing bootloader on separate /boot partition ++ $media->{partitions}[$part_idx]{mntpoint} eq $boot and $boot = ""; ++ ++ my $title = $media->{title} || $live->{media}{title}; ++ ++ join("\n", ++ "timeout " . get_bootloader_timeout($live), ++ if_($live->{system}{gfxboot}, "gfxmenu $grub_part" . $boot . "/gfxmenu"), ++ "default 0", ++ (map { ++ my ($name, $cmdline) = @$_; ++ "title " . $title . if_($name, " ($name)"), ++ "kernel $grub_part" . $boot . "/vmlinuz " . get_default_append($live, $opts) . if_($cmdline, " $cmdline"), ++ if_($initrd, "initrd " . $boot . $initrd); ++ } group_by2(@{$media->{boot_entries}})), ++ ($live->{oem_rescue} && defined $opts->{oem_rescue_idx} ? ( ++ #- FIXME: factorize with above, build_grub_cfg_entry($media) ++ "title " . $live->{oem_rescue}{media}{title}, ++ "kernel (hd0,$opts->{oem_rescue_idx})" . $boot . "/vmlinuz " . $live->{oem_rescue}{append}, ++ "initrd (hd0,$opts->{oem_rescue_idx})" . $boot . $media->get_initrd_path, ++ ) : ()), ++ "", ++ ); ++} ++ ++sub get_langs { ++ my ($live) = @_; ++ uniq( ++ (ref $live->{regions} ? @{$live->{regions}{$live->{settings}{region}}} : ()), ++ @{$live->{system}{langs_always}} ++ ); ++} ++ ++sub install_system { ++ my ($live) = @_; ++ ++ my $repository = $live->{settings}{repository} . '/' . $live->{settings}{arch}; ++ ++ my $drakx_in_chroot = $repository . '/misc/drakx-in-chroot'; ++ my $remote_repository = $repository =~ m!^(ftp|http)://! && $1; ++ if ($remote_repository) { ++ my $local_drakx_in_chroot = $live->get_builddir . $live->{prefix}{build}{scripts} . '/drakx-in-chroot'; ++ mkdir_p(dirname($local_drakx_in_chroot)); ++ run_('curl', '--silent', '-o', $local_drakx_in_chroot, $drakx_in_chroot) ++ or die "unable to get drakx-in-chroot from remote repository\n"; ++ $drakx_in_chroot = $local_drakx_in_chroot; ++ } ++ ++ local %ENV = ( ++ %ENV, ++ (map { "DRAKLIVE_". uc($_->[0]) => $_->[1] } group_by2(%{$live->{settings}})), ++ %{$live->{system}{install_env}}, ++ ); ++ $ENV{DRAKLIVE_LANGS} = join(':', get_langs($live)); ++ run_({ targetarch => $live->{settings}{arch} }, ++ 'perl', $drakx_in_chroot, ++ $repository, ++ $live->get_system_root, ++ if_($live->{system}{auto_install}, '--auto_install', $live->{settings}{config_root} . '/' . $live->{system}{auto_install}), ++ if_($live->{system}{patch_install}, '--defcfg', $live->{settings}{config_root} . '/' . $live->{system}{patch_install}), ++ if_($live->{system}{rpmsrate}, '--rpmsrate', $live->{settings}{config_root} . '/' . $live->{system}{rpmsrate}), ++ ($live->{system}{stage2_updates} ? (map { ('--stage2-update', $live->{settings}{config_root} . '/' . $_->[0], $_->[1]) } @{$live->{system}{stage2_updates}}) : ()), ++ ) or die "unable to install system chroot\n"; ++ post_install_system($live); ++} ++ ++sub configure_draklive_resize { ++ my ($live) = @_; ++ ++ my $resizable_loopback = find { $_->{min_size} } @{$live->{mount}{dirs} || []}; ++ if ($resizable_loopback) { ++ my $media_loopbacks = $live->get_media_prefix('loopbacks'); ++ my $ext = $loop_types{$resizable_loopback->{type}}{extension}; ++ output($live->get_system_root . '/etc/sysconfig/draklive-resize', <<EOF); ++DRAKLIVE_RESIZE=yes ++LOOPBACK=$live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}${media_loopbacks}$resizable_loopback->{path}$ext ++TYPE=$resizable_loopback->{fs} ++MIN_SIZE=$resizable_loopback->{min_size} ++MOUNT=$live->{prefix}{live}{mnt}$resizable_loopback->{mountpoint}_resized ++OLD_MOUNT=$live->{prefix}{live}{mnt}$resizable_loopback->{mountpoint} ++UNION=/ ++EOF ++ } ++} ++ ++sub copy_files_to { ++ my ($live, $files, $root) = @_; ++ foreach (@$files) { ++ my ($source, $dest, $o_opts) = @$_; ++ $dest = $root . '/' . $dest; ++ mkdir_p($dest =~ m|/$| ? $dest : dirname($dest)); ++ my @sources = MDV::Draklive::Utils::glob__($live->{settings}{config_root} . '/' . $source); ++ print STDERR "copying @sources to $dest\n"; ++ cp_af(@sources, $dest); ++ my $o_perm = $o_opts && $o_opts->{mode}; ++ chmod $o_perm, $dest if $o_perm; ++ } ++} ++ ++sub join_lists { ++ my ($separator, $head, @lists) = @_; ++ @{$head || []}, map { $separator, @$_ } @lists; ++} ++ ++sub remove_files_from { ++ my ($files, $root) = @_; ++ run_('find', $root, '(', join_lists('-o', map { [ '-name', $_ ] } @$files), ')', '-exec', 'rm', '-r', '{}', ';') ++ if $files && @$files; ++} ++ ++sub clean_system_conf_file { ++ my ($live, $file) = @_; ++ substInFile { undef $_ if /^[^#]/ } $live->get_system_root . $file; ++} ++ ++sub post_install_system { ++ my ($live) = @_; ++ ++ my $previous_umask = umask; ++ #- workaround buggy installation of directories that are not owned by any packages ++ umask 022; ++ ++ run_('mount', '-t', 'proc', '/proc', $live->get_system_root . '/proc'); ++ run_('mount', '-t', 'sysfs', '/sys', $live->get_system_root . '/sys'); ++ ++ #- copy resolv.conf for name resolution to work when adding media ++ cp_f("/etc/resolv.conf", $live->get_system_root . "/etc/"); ++ ++ #- remove previous draklive leftovers if needed ++ run_({ root => $live->get_system_root }, 'urpmi.removemedia', '-a'); ++ ++ foreach (@{$live->{system}{additional_media}}) { ++ run_({ root => $live->get_system_root }, 'urpmi.addmedia', if_($_->{distrib}, '--distrib'), $_->{name}, $_->{path}) ++ or die "unable to add media from $_->{path}\n"; ++ @{$_->{packages} || []} or next; ++ run_({ root => $live->get_system_root, targetarch => $live->{settings}{arch} }, ++ 'urpmi', '--auto', '--no-verify-rpm', if_(!$_->{distrib}, '--searchmedia', $_->{name}), @{$_->{packages}}) ++ or die "unable to install packages from $_->{path}\n"; ++ } ++ ++ #- additional rpms may have dependencies in additional media ++ if (@{$live->{system}{rpms} || []}) { ++ my $rpm_tmp_dir = '/tmp/draklive_rpms'; ++ mkdir_p($live->get_system_root . $rpm_tmp_dir); ++ cp_f((map { $live->{settings}{config_root} . '/' . $_ } @{$live->{system}{rpms}}), $live->get_system_root . $rpm_tmp_dir); ++ run_({ root => $live->get_system_root, targetarch => $live->{settings}{arch} }, ++ 'urpmi', '--auto', '--no-verify-rpm', ++ map { $rpm_tmp_dir . '/' . basename($_) } @{$live->{system}{rpms}}) ++ or die "unable to install additional system rpms\n"; ++ rm_rf($live->get_system_root . $rpm_tmp_dir); ++ } ++ ++ #- remove urpmi media added by drakx-in-chroot and additional media, they're unusable ++ run_({ root => $live->get_system_root }, 'urpmi.removemedia', '-a'); ++ ++ my $erase = join(' ', @{$live->{system}{erase_rpms} || []}); ++ run_({ root => $live->get_system_root, targetarch => $live->{settings}{arch} }, ++ 'sh', '-c', "rpm -qa $erase | xargs rpm -e ") if $erase; ++ ++ run_({ root => $live->get_system_root }, 'chkconfig', '--del', $_) foreach @{$live->{system}{disable_services}}; ++ ++ #- make sure harddrake is run: ++ #- if previous HW config file is empty, we assumes DrakX has just completed the installation ++ #- (do it in chroot, or else Storable from the build box may write an incompatible config file) ++ run_({ root => $live->get_system_root }, ++ 'perl', '-MStorable', '-e', qq(Storable::store({ UNKNOWN => {} }, '/etc/sysconfig/harddrake2/previous_hw'))); ++ ++ #- remove some build-machine specific configuration ++ clean_system_conf_file($live, $_) ++ foreach qw(/etc/mtab /etc/modprobe.conf /etc/modprobe.preload /etc/iftab /etc/shorewall/interfaces /etc/mdadm.conf), ++ if_(!$live->{system}{skip_fstab}, '/etc/fstab'); ++ unlink($_) foreach map { glob($live->get_system_root . $_) } @{$live->{system}{remove_files} || []}; ++ ++ if ($live->{system}{modules_conf}) { ++ local $::prefix = $live->get_system_root; ++ local *modules::write_preload_conf = sub {}; #- FIXME, make this an option ++ my $modules_conf = modules::any_conf->vnew; ++ put_in_hash($modules_conf, $live->{system}{modules_conf}); ++ $modules_conf->write; ++ } ++ ++ my $mount_options = $live->{media}->get_media_setting('mount_options') || "defaults"; ++ output_with_perm($live->get_system_root . '/etc/fstab', 0644, ++ $live->{mount}{overlay} ++ ? "none / $live->{mount}{overlay} $mount_options 0 0\n" ++ : $live->{media}->get_media_setting('source') . " / " . $live->{media}->get_media_setting('fs') . " $mount_options 1 1\n" ++ ) unless $live->{system}{skip_fstab}; ++ ++ #- interactive mode can lead to race in initscripts ++ #- (don't use addVarsInSh from MDK::Common, it breaks shell escapes) ++ substInFile { s/^PROMPT=.*/PROMPT=no/ } $live->get_system_root . '/etc/sysconfig/init'; ++ ++ configure_draklive_resize($live); ++ ++ if ($live->{system}{preselect_kdm_user}) { ++ #- preselect specified user in kdm ++ my $kdm_cfg = $live->get_system_root . '/etc/kde/kdm/kdmrc'; ++ update_gnomekderc($kdm_cfg, 'X-:0-Greeter' => (PreselectUser => 'Default', DefaultUser => $live->{system}{preselect_kdm_user})) if -f $kdm_cfg; ++ } ++ ++ #- apply patches and install files after the configuration is cleaned ++ #- to allow special configuration files (especially modprobe.preload) ++ foreach (@{$live->{system}{patches}}) { ++ my $patch = $live->{settings}{config_root} . '/' . $_; ++ my @args = ('-p0', '-d', $live->get_system_root, '-i', $patch); ++ run_program::run('patch', '>', '/dev/null', '--dry-run', '-f', '-R', @args) || run_('patch', @args) ++ or die "unable to apply patch " . $patch . "\n"; ++ } ++ ++ copy_files_to($live, $live->{system}{files}, $live->get_system_root); ++ my @no_install_files = map { $_->[1] } grep { $_->[2] && $_->[2]{no_install} } @{$live->{system}{files}}; ++ output_p($live->get_system_root . '/etc/draklive-install.d/remove.d/draklive', map { "$_\n" } @no_install_files); ++ ++ eval { rm_rf($live->get_builddir . $live->{prefix}{build}{files}) }; ++ mkdir_p($live->get_builddir . $live->{prefix}{build}{files}); ++ if ($live->{media}{files}) { ++ copy_files_to($live, $live->{media}{files}, $live->get_builddir . $live->{prefix}{build}{files}); ++ } ++ remove_files_from($live->{media}{remove_files}, $live->get_builddir . $live->{prefix}{build}{files}); ++ ++ run_({ targetarch => $live->{settings}{arch} }, ++ "chroot", $live->get_system_root, "bash", "-c", $live->{system}{postInstall}) if $live->{system}{postInstall}; ++ ++ clean_system_conf_file($live, "/etc/resolv.conf"); ++ write_dist_lists($live); ++ ++ run_('umount', $live->get_system_root . '/sys'); ++ run_('umount', $live->get_system_root . '/proc/bus/usb'); ++ run_('umount', $live->get_system_root . '/proc'); ++ ++ umask $previous_umask; ++} ++ ++sub write_dist_lists { ++ my ($live) = @_; ++ ++ my $lists_dir = $live->get_builddir . $live->{prefix}{build}{dist}; ++ mkdir_p($lists_dir); ++ ++ run_("chroot " . $live->get_system_root . " rpm -qa | sort > " . ++ $lists_dir . '/' . $live->get_name . '.lst'); ++ ++ run_("chroot " . $live->get_system_root . " rpm -qa --qf '%{name}\n' | sort > " . ++ $lists_dir . '/' . $live->get_name . '.lst.names'); ++ ++ run_("chroot " . $live->get_system_root . ++ qq( sh -c "rpm -qa --qf '%{size} \t%{name}\n' | sort -n" > ) . ++ $lists_dir . '/' . $live->get_name . '.lst.full'); ++ ++ run_("chroot " . $live->get_system_root . ++ qq( sh -c "urpmi_rpm-find-leaves | xargs rpm -q --qf '%{size} \t%{name}\n' | sort -n" > ) . ++ $lists_dir . '/' . $live->get_name . '.lst.leaves'); ++ ++ require lang; ++ my @live_langs = get_langs($live); ++ my @langs = grep { member($_, @live_langs) || member(lang::locale_to_main_locale($_), @live_langs) } lang::list_langs(); ++ my $langs_file = $lists_dir . '/' . $live->get_name . '.langs'; ++ output_p($langs_file, map { lang::l2name($_) . " (" . $_ . ")\n" } sort(@langs)); ++} ++ ++sub umount_external_filesystem { ++ my ($live) = @_; ++ my $mnt = $live->get_system_root . "/mnt/"; ++ eval { fs::mount::umount("$mnt/$_") } foreach all($mnt); ++} ++ ++sub expand_file_list { ++ my ($live, @files) = @_; ++ map { ++ $_->{path} ? ++ $_->{path} : ++ chomp_(cat_(glob(($_->{rooted} && $live->get_system_root) . $_->{source}))); ++ } @files; ++} ++ ++#- hardlink recursively file list to a directory ++sub hardlink_filtered { ++ my ($src, $dest, $files) = @_; ++ mkdir_p($dest); ++ my $pwd = $ENV{PWD}; ++ chdir($src); ++ my $list_file = tmpnam(); ++ output_p($list_file, map { "$_\n" } grep { -e $src . $_ } @$files); ++ #- cpio -pldm won't copy recursively, use rsync -r instead ++ system('rsync', '-ar', '--files-from=' . $list_file, '--link-dest=' . $src, $src, $dest); ++ unlink $list_file; ++ chdir($pwd); ++} ++ ++sub list_loopback_modules { ++ my ($live) = @_; ++ map { ++ my $l = $_; ++ map { ++ my $list = $_; ++ my $name = basename($list); ++ $name =~ s/\.[^.]+$//; ++ { type => $l->{type}, name => $name, files => [ expand_file_list($live, { source => $list }) ] }; ++ } glob(($_->{rooted} && $live->get_system_root) . $_->{source}); ++ } @{$live->{loopbacks}{modules}}; ++} ++ ++sub create_loopback_files { ++ my ($live) = @_; ++ # umount filesystem in the live before creating the loopback ++ umount_external_filesystem($live); ++ ++ my @excluded_files = expand_file_list($live, @{$live->{loopbacks}{exclude}{files} || []}); ++ my @modules_files = expand_file_list($live, @{$live->{loopbacks}{modules} || []}); ++ ++ foreach (grep { exists $loop_types{$_->{type}}{build} } @{$live->{mount}{dirs} || []}) { ++ local $_->{exclude} = [ @excluded_files, @modules_files ]; ++ $loop_types{$_->{type}}{build}->($live, $_); ++ } ++ ++ foreach my $module (list_loopback_modules($live)) { ++ my $copy_tree = $live->get_system_root . "/tmp/draklive/loop/$module->{name}"; ++ eval { rm_rf($copy_tree) }; ++ hardlink_filtered($live->get_system_root, $copy_tree, $module->{files}); ++ my $loop = $loop_types{$module->{type}}; ++ $loop->{build}->($live, { path => "$live->{prefix}{build}{modules}/$module->{name}", root => $copy_tree, exclude => \@excluded_files }); ++ eval { rm_rf($copy_tree) }; ++ } ++ ++ if (@excluded_files) { ++ my $excluded_tree = $live->get_system_root . "/tmp/draklive/excluded/all"; ++ eval { rm_rf($excluded_tree) }; ++ hardlink_filtered($live->get_system_root, $excluded_tree, \@excluded_files); ++ ++ foreach my $module (list_loopback_modules($live)) { ++ my $copy_tree = $live->get_system_root . "/tmp/draklive/excluded/$module->{name}"; ++ eval { rm_rf($copy_tree) }; ++ hardlink_filtered($excluded_tree, $copy_tree, $module->{files}); ++ my $loop = $loop_types{$module->{type}}; ++ $loop->{build}->($live, { path => "$live->{prefix}{build}{modules}/excluded-$module->{name}", root => $copy_tree }); ++ eval { rm_rf($copy_tree) }; ++ } ++ ++ my $loop = $loop_types{$live->{loopbacks}{exclude}{type}}; ++ $loop->{build}->($live, { path => "/excluded", root => $excluded_tree, exclude => \@modules_files }); ++ ++ eval { rm_rf($excluded_tree) }; ++ } ++} ++ ++sub list_selected_loopbacks { ++ my ($live) = @_; ++ my @pack = $live->{settings}{pack} ? @{$live->{packs}{$live->{settings}{pack}} || []} : (); ++ my @pack_modules = grep { member($_->{name}, @pack) } list_loopback_modules($live); ++ (map { $loop_types{$_->{type}}{is_loopback} && $_->{path} ? $_->{path} . $loop_types{$_->{type}}{extension} : () } @{$live->{mount}{dirs} || []}), ++ (map { $live->{prefix}{build}{modules} . '/' . $_->{name} . $loop_types{$_->{type}}{extension} } @pack_modules); ++} ++ ++sub get_media_device { ++ my ($live, $opts) = @_; ++ return $opts->{device} if $opts->{device}; ++ my $label = $live->{media}->get_media_label ++ or die "no device and no label"; ++ my $device = chomp_(`readlink -f /dev/disk/by-label/$label`) ++ or die "unable to find device for /dev/disk/by-label/$label\n"; ++ $device; ++} ++ ++sub prepare_bootloader { ++ my ($live) = @_; ++ create_initrd($live); ++ create_bootloader($live) if !($live->{system}{skip_bootloader_config} || $live->{system}{skip_bootloader_install}); ++} ++ ++sub create_initrd { ++ my ($live) = @_; ++ my $root = $live->get_system_root; ++ ++ run_('mount', '-t', 'proc', 'none', $root . '/proc'); ++ run_('mount', '-t', 'sysfs', 'none', $root . '/sys'); ++ ++ if (need_media_specific_boot($live)) { ++ MDV::Draklive::Initrd::create_media_initrd($live); ++ } else { ++ MDV::Draklive::Initrd::create_classical_initrd($live); ++ } ++ ++ run_('umount', $root . '/sys'); ++ run_('umount', $root . '/proc'); ++} ++ ++sub create_bootloader { ++ my ($live) = @_; ++ ++ my $root = $live->get_system_root; ++ my $kernel = $live->find_kernel->{version}; ++ my $vmlinuz_long = '/boot/vmlinuz-' . $kernel; ++ -e $root . $vmlinuz_long or die "can not find kernel $kernel\n"; ++ ++ if ($live->{system}{gfxboot}) { ++ run_('mount', '-t', 'proc', 'none', $root . '/proc'); ++ run_('mount', '-t', 'sysfs', 'none', $root . '/sys'); ++ ++ #- would be run by bootloader::add_boot_splash and make-boot-splash, but not called when we don't generate an initrd ++ run_({ root => $root }, '/usr/share/bootsplash/scripts/switch-themes', '-u'); ++ #- grub-gfxmenu would be run by bootloader::write_grub from DrakX ++ run_({ root => $root }, '/usr/sbin/grub-gfxmenu', '--update-gfxmenu'); ++ my $gfxmenu = $root . '/boot/gfxmenu'; ++ if (-e $gfxmenu) { ++ my $boot_dir = $live->get_builddir . $live->{prefix}{build}{boot}; ++ mkdir_p($boot_dir); ++ cp_f($gfxmenu, $boot_dir); ++ } else { ++ warn "no gfxmenu file\n"; ++ } ++ ++ run_('umount', $root . '/sys'); ++ run_('umount', $root . '/proc'); ++ } ++ ++ # this will copy (among other things) the gfxboot theme to the media ++ # so this must be done before the creating the bootloader since the code ++ # in there may check if a bootlogo is present or not ++ create_syslinux_msg_files($live); ++ ++ if (need_media_specific_boot($live)) { ++ create_media_bootloader($live); ++ } else { ++ create_classical_bootloader($live); ++ } ++} ++ ++sub remove_unneeded_bootlogo_locales { ++ use File::Temp; ++ use Cwd; ++ ++ my ($bootlogo, @locales) = @_; ++ ++ $bootlogo = Cwd::realpath($bootlogo); ++ -f $bootlogo or return; ++ ++ my $cwd = Cwd::getcwd(); ++ my $tempdir = File::Temp::tempdir("mdvgfxbootXXXX", CLEANUP => 1); ++ chdir $tempdir; ++ !system("cpio -id < $bootlogo") or return; ++ ++ # Make sure we include the en locale ++ push @locales, 'en'; ++ my @kept_locales; ++ foreach my $file (glob "*.tr") { ++ if (!any { $file =~ /^$_\.tr$/ } @locales) { ++ unlink $file; ++ } else { ++ my ($locale_name) = $file =~ /(.*)\.tr$/; ++ push @kept_locales, $locale_name; ++ } ++ } ++ system(qq(echo init 16x16.fnt *.tr |sed "s/ /\\n/g" |cpio -o >$bootlogo)); ++ chdir $cwd; ++ ++ print "gfxboot locales: " . join(" ", @kept_locales) . "\n"; ++ return @kept_locales; ++} ++ ++#- forked from bootsplash::themes_read_sysconfig ++sub get_bootsplash_theme() { ++ my $sysconfig_file = "/etc/sysconfig/bootsplash"; ++ local $_; ++ my %theme; ++ foreach (cat_($::prefix . $sysconfig_file)) { ++ /^THEME=(.*)/ and $theme{name} = $1; ++ } ++ \%theme; ++} ++ ++sub create_syslinux_msg_files { ++ my ($live) = @_; ++ my $syslinux_dir = $live->get_builddir . $live->{prefix}{build}{boot} . '/syslinux'; ++ mkdir_p($syslinux_dir); ++ ++ if ($live->{system}{gfxboot}) { ++ my $default_gfxboot_theme = "Mandriva"; ++ require bootsplash; ++ my $theme = do { ++ local $::prefix = $live->get_system_root; ++ get_bootsplash_theme(); ++ }; ++ print "copying $default_gfxboot_theme gfxboot theme\n"; ++ cp_f(glob_($live->get_system_root . "/usr/share/gfxboot/themes/$default_gfxboot_theme/install/*"), $syslinux_dir); ++ if ($theme->{name} ne $default_gfxboot_theme) { ++ print "copying $theme->{name} gfxboot theme\n"; ++ cp_f(glob_($live->get_system_root . "/usr/share/gfxboot/themes/$theme->{name}/*"), $syslinux_dir); ++ } ++ my $bootlogo = $syslinux_dir . '/bootlogo'; ++ warn "unable to find gfxboot splash ($bootlogo)\n" if ! -f $bootlogo; ++ my @locales = remove_unneeded_bootlogo_locales($bootlogo, get_langs($live)); ++ output_p($syslinux_dir . '/langs', join("\n", @locales) . "\n"); ++ output_p($syslinux_dir . '/gfxboot.cfg', join("\n", ++ "livecd=1", ++ "mainmenu.pos=210,235", ++ "mainmenu.bar.minwidth=400", ++ "panel.f-key.fg=0x33358c", ++ "", ++ )); ++ } ++ ++ output($live->get_builddir . $live->{prefix}{build}{boot} . '/help.msg', ++ pack("C*", 0x0E, 0x80, 0x03, 0x00, 0xC) . qq( ++Welcome to Mageia live! ++ ++The command line can be used to specify kernel options. ++ ++$live->{media}{title} <kernel options> ++ ++)); ++} ++ ++sub create_media_bootloader { ++ my ($live) = @_; ++ cp_f($live->get_system_root . '/boot/vmlinuz-' . $live->find_kernel->{version}, $live->get_builddir . $live->{prefix}{build}{boot} . '/vmlinuz'); ++ foreach my $boot ('', @{$live->{media}{extra_boot}}) { ++ my $opts = { boot => $boot }; ++ output($live->get_builddir . $live->{prefix}{build}{boot} . get_syslinux_path($live->{media}, $opts), ++ build_syslinux_cfg($live, $live->{media}, $opts)); ++ } ++} ++ ++sub create_classical_bootloader { ++ my ($live) = @_; ++ my $initrd_prefix = "/initrd.img"; ++ my $initrd = $live->get_system_root . $live->get_media_prefix('boot') . $initrd_prefix; ++ my $part_idx = $live->{media}->find_boot_partition_index; ++ my $oem_rescue_idx = $live->{media}->find_partition_index('OEM_RESCUE'); ++ output_p($live->get_system_root . '/boot/grub/menu.lst', build_grub_cfg_raw($live, $live->{media}, -e $initrd && $initrd_prefix, { oem_rescue_idx => $oem_rescue_idx }, $part_idx)); ++} ++ ++sub create_tarball { ++ my ($live) = @_; ++ run_("tar", "cjf", get_disk_master_prefix($live) . ".tar.bz2", $live->get_system_root); ++} ++ ++sub set_device_label { ++ my ($device, $type, $label) = @_; ++ if ($type eq 'vfat') { ++ MDV::Draklive::Utils::mtools_run_('mlabel', '-i', $device, '::' . $label); ++ } elsif (member($type, 'ext2', 'ext3')) { ++ run_('e2label', $device, $label); ++ } else { ++ die "unable to set label for unsupported media type $type\n"; ++ } ++} ++ ++sub get_cdrom_master_path { ++ my ($live, $opts) = @_; ++ $live->get_builddir . $live->{prefix}{build}{dist} . '/' . $live->get_name . ($opts->{boot} && "-boot-$opts->{boot}") . '.iso'; ++} ++ ++sub get_cdrom_replicator_path { ++ my ($live) = @_; ++ get_disk_replicator_prefix($live) . ".iso"; ++} ++ ++sub create_cdrom_master { ++ my ($live, $opts) = @_; ++ my $label = $live->{media}->get_media_label or die "the source device must be described by a label\n"; ++ my $dest; ++ unless ($opts->{onthefly}) { ++ $dest = get_cdrom_master_path($live, $opts); ++ mkdir_p(dirname($dest)); ++ } ++ build_iso_image( ++ $live, $opts, ++ $dest, ++ $live->get_builddir . $live->{prefix}{build}{boot} . get_syslinux_path($live->{media}, $opts), ++ $label, ++ $live->get_media_prefix('boot', $opts->{boot}) . '=' . $live->get_builddir . $live->{prefix}{build}{boot}, ++ if_(!$opts->{boot_only}, ++ (map { ++ $live->get_media_prefix('loopbacks', $opts->{boot}) . $_ . ++ '=' . ++ $live->get_builddir . $live->{prefix}{build}{loopbacks} . $_; ++ } list_selected_loopbacks($live)), ++ if_($live->{media}{files}, ++ map { ++ $_ . '=' . $live->get_builddir . $live->{prefix}{build}{files} . '/' . $_; ++ } all($live->get_builddir . $live->{prefix}{build}{files}) ++ ), ++ ), ++ ); ++} ++ ++sub build_iso_image { ++ my ($live, $opts, $dest, $isolinux_cfg, $label, @opts) = @_; ++ ++ my $progress = MDV::Draklive::Progress->new(100, time()); ++ my $in_progress; ++ autoflush STDOUT 1; ++ run_foreach(sub { ++ if (/^\s*([0-9.]+)%\s*done,/) { ++ $progress->{current} = int($1); ++ $progress->show(time()); ++ $in_progress = 1; ++ } else { ++ print "\n" if $in_progress; ++ print $_; ++ $in_progress = 0; ++ } ++ }, ++ 'genisoimage', '-pad', '-l', '-R', '-J', ++ '-V', $label, #'-A', $application, '-p', $preparer, '-P', $publisher, ++ '-b', 'isolinux/isolinux.bin', ++ '-c', 'isolinux/boot.cat', ++ '-hide-rr-moved', '-no-emul-boot', ++ '-boot-load-size', 4, '-boot-info-table', ++ '-graft-points', ++ if_($dest, '-o', $dest), ++ 'isolinux=' . $live->get_builddir . $live->{prefix}{build}{boot} . '/syslinux', ++ 'isolinux/isolinux.cfg=' . $isolinux_cfg, ++ 'isolinux/isolinux.bin=/usr/lib/syslinux/isolinux.bin', ++ 'isolinux/gfxboot.com=/usr/lib/syslinux/gfxboot.com', ++ @opts, ++ ) or die "unable to run genisoimage\n"; ++ autoflush STDOUT 0; ++ $progress->end; ++ if ($dest) { ++ my $dir = dirname($dest); ++ my $filename = basename($dest); ++ run_('isohybrid', '-fatfirst', $dest); ++ run_('mkcd', '>', '/dev/null', '2>', '/dev/null', '--addmd5', $dest); ++ run_({ chdir => $dir }, 'md5sum', '>', $dest . '.md5', $filename); ++ run_({ chdir => $dir }, 'sha1sum', '>', $dest . '.sha1', $filename); ++ } ++} ++ ++sub get_disk_master_prefix { ++ my ($live) = @_; ++ $live->get_builddir . $live->{prefix}{build}{dist} . '/' . $live->get_name; ++} ++ ++sub get_disk_master_path { ++ my ($live) = @_; ++ get_disk_master_prefix($live) . '.img'; ++} ++ ++sub get_partition_loop { ++ my ($hd, $part) = @_; ++ require devices; ++ my $loop = devices::find_free_loop(); ++ run_('losetup', '-o', $part->{start} * $common::SECTORSIZE, '-s', $part->{size} * $common::SECTORSIZE, $loop, $hd->{file}) ++ or die "unable to setup loop device"; ++ return $loop; ++} ++ ++sub get_harddisk_geometry { ++ my ($media) = @_; ++ my $geom = $media->{geom} || { ++ heads => 16, ++ sectors => 63, # sectors per track ++ }; ++} ++ ++sub get_hd_from_layout { ++ my ($media, $dest) = @_; ++ my $geom = get_harddisk_geometry($media); ++ my $required_sectors = fold_left { $::a + $::b } map { $_->{size} } @{$media->{partitions}}; ++ $required_sectors += $geom->{sectors}; # keep one more track ++ $geom->{cylinders} = POSIX::ceil($required_sectors / ($geom->{sectors} * $geom->{heads})); ++ my $total_sectors = $geom->{cylinders} * $geom->{heads} * $geom->{sectors}; ++ my $hd = bless { ++ totalsectors => $total_sectors, ++ geom => $geom, ++ file => $dest, ++ }, 'partition_table::dos'; ++} ++ ++sub get_hd_from_file { ++ my ($media, $file) = @_; ++ my $hd = bless { ++ geom => get_harddisk_geometry($media), ++ file => $file, ++ }, 'partition_table::dos'; ++ partition_table::read($hd); ++ return $hd; ++} ++ ++sub supplement_media_partitions { ++ my ($media, $hd) = @_; ++ #- try to find additional partition details (start, device) ++ #- by matching actual partition table and partitions list ++ my @all_parts = partition_table::get_normal_parts($hd); ++ foreach my $idx (0 .. $#all_parts) { ++ $media->{partitions}[$idx]{$_} = $all_parts[$idx]{$_} foreach qw(start device); ++ } ++} ++ ++sub set_part_real_device { ++ my ($hd, $part) = @_; ++ #- FIXME: find a better way to compute mmcblk device path ++ my $ext = $hd->{file} =~ m!^/dev/mmcblk! ? 'p' : ''; ++ $part->{real_device} = -f $hd->{file} ? get_partition_loop($hd, $part) : ($hd->{file} . $ext . $part->{device}); ++} ++ ++sub allocate_master { ++ my ($live, $media, $opts) = @_; ++ ++ $media->supplement_slash_size($opts->{slash_size}) if $opts->{slash_size}; ++ my $hd = get_hd_from_layout($media, $opts->{device}); ++ ++ mkdir_p(dirname($opts->{device})); ++ MDV::Draklive::Utils::device_allocate_file($opts->{device}, $hd->{totalsectors} * $common::SECTORSIZE); ++} ++ ++sub format_master { ++ my ($live, $media, $opts) = @_; ++ ++ $media->supplement_slash_size($opts->{slash_size}) if $opts->{slash_size}; ++ ++ my $hd = get_hd_from_layout($media, $opts->{device}); ++ partition_table::raw::zero_MBR($hd); ++ ++ #- FIXME: maybe use fsedit::allocatePartitions to factorize even more? ++ foreach my $part (@{$media->{partitions}}) { ++ my $hole = find { fs::type::isEmpty($_) && $_->{size} >= $part->{size} } partition_table::get_normal_parts_and_holes($hd) ++ or die "not enough room for $part->{mntpoint}"; ++ $part->{start} = $hole->{start}; ++ fs::type::set_fs_type($part, $part->{fs_type}); ++ partition_table::add($hd, $part, 'Primary'); ++ } ++ ++ print "writing partition table\n"; ++ partition_table::write($hd); ++ #- FIXME: move out from diskdrake::interactive::write_partitions to partition_table::write ? ++ run_program::run('udevadm', 'settle'); ++ ++ my $inode_size = $media->get_media_setting('inode_size'); ++ foreach my $part (@{$media->{partitions}}) { ++ set_part_real_device($hd, $part); ++ MDV::Draklive::Utils::device_mkfs($part->{real_device}, $part->{fs_type}, $part->{device_LABEL}, $inode_size) ++ or die "unable to format $part->{real_device} in $hd->{file}\n"; ++ devices::del_loop($part->{real_device}) if -f $hd->{file}; ++ } ++} ++ ++sub format_disk { ++ my ($live, $opts) = @_; ++ local $opts->{slash_size} = guess_disk_master_size($live); ++ format_master($live, $live->{media}, $opts); ++} ++ ++sub guess_disk_master_size { ++ my ($live) = @_; ++ ++ my $slash_size = @{$live->{mount}{dirs} || []} ? ++ (directory_usage($live->get_builddir . $live->{prefix}{build}{loopbacks}, 'apparent') + ++ directory_usage($live->get_builddir . $live->{prefix}{build}{boot}) + ++ directory_usage($live->get_builddir . $live->{prefix}{build}{files}) ++ ) : ++ directory_usage($live->get_system_root); ++} ++ ++sub create_disk_master { ++ my ($live, $opts) = @_; ++ local $opts->{slash_size} = guess_disk_master_size($live); ++ local $opts->{device} = get_disk_master_path($live); ++ allocate_master($live, $live->{media}, $opts); ++ format_master($live, $live->{media}, $opts); ++ record_master($live, $opts); ++} ++ ++#- $opts: ++#- media: alternate media ++#- onthefly : if true, the create function must output to stdout ++sub create_master { ++ my ($live, $opts) = @_; ++ ++ if (my $create = $live->{media}->get_boot_setting('create', $opts)) { ++ $create->($live, $opts); ++ } else { ++ warn "not implemented yet\n"; ++ } ++} ++ ++sub maybe_umount_device { ++ my ($device) = @_; ++ run_('umount', $device) if cat_('/proc/mounts') =~ m!^$device\s+!m; ++} ++ ++sub format_cdrom_device { ++ my ($live, $opts) = @_; ++ run_('wodim', '-v', 'dev=' . get_media_device($live, $opts), "blank=fast"); ++} ++ ++#- $opts: ++#- media: alternate media ++sub format_device { ++ my ($live, $opts) = @_; ++ ++ get_media_device($live, $opts) or die "no device defined in media configuration\n"; ++ if (my $format = $live->{media}->get_boot_setting('format', $opts)) { ++ $format->($live, $opts); ++ } else { ++ warn "not implemented yet\n"; ++ } ++} ++ ++sub record_cdrom_path { ++ my ($live, $path, $opts) = @_; ++ my $device = get_media_device($live, $opts) ++ or die "no device defined in media configuration\n"; ++ ++ #- CD-Rom images can be hybrid, thus handle recording on both CD-Rom and disks ++ my $_device = basename(expand_symlinks($device)); ++ my $sysfs_device = "/sys/block/$_device/capability"; ++ #- GENHD_FL_CD is 8 (include/linux/genhd.h) ++ my $is_cdrom = !-e $sysfs_device || hex(cat_($sysfs_device)) & 8; ++ ++ if ($is_cdrom) { ++ my $src = $opts->{onthefly} ? '-' : $path; ++ run_('wodim', '-v', 'dev=' . $device, $src); ++ } else { ++ run_('dd', if_(!$opts->{onthefly}, "if=$path"), "of=$device", "bs=2M"); ++ } ++} ++ ++sub record_cdrom_master { ++ my ($live, $opts) = @_; ++ record_cdrom_path($live, get_cdrom_master_path($live, $opts), $opts); ++} ++ ++sub record_cdrom_replicator { ++ my ($live, $opts) = @_; ++ record_cdrom_path($live, get_cdrom_replicator_path($live), $opts); ++} ++ ++sub rsync_delete_options { ++ my ($opts) = @_; ++ $opts->{keep_files} ? () : '--delete'; ++} ++ ++sub install_grub_to_image { ++ my ($live, $media, $img, $opts) = @_; ++ my $media_boot = $live->get_media_prefix('boot', $opts->{boot}); ++ my $grub_dir = "$media_boot/grub"; ++ my $grub_script = $grub_dir . "/install.sh"; ++ my $grub_src = first(glob_($live->get_system_root . "/lib/grub/*-mandriva")); ++ mkdir_p($live->{mnt} . $grub_dir); ++ cp_af(glob_("$grub_src/*"), $live->{mnt} . $grub_dir); ++ ++ my $part_idx = $media->find_boot_partition_index; ++ my $grub_prefix = $media->find_partition_index('/boot') ? "/grub" : $grub_dir; ++ ++ open(my $grub, "| /sbin/grub --batch --no-floppy"); ++ # using disk loopback fails, have to use image path ++ print $grub <<EOF; ++device (hd0) $img ++root (hd0,$part_idx) ++setup --prefix=$grub_prefix (hd0) ++quit ++EOF ++ close($grub) or die "unable to run grub\n"; ++ ++ output($live->{mnt} . $grub_script, <<EOG); ++grub --device-map=$media_boot/grub/device.map --batch <<EOF ++root (hd0,$part_idx) ++setup --stage2=$media_boot/grub/stage2 (hd0) ++quit ++EOF ++EOG ++ ++ chmod 0755, $live->{mnt} . $grub_script; ++} ++ ++sub install_disk_bootloader { ++ my ($live, $media, $boot_device, $opts) = @_; ++ ++ return if $live->{system}{skip_bootloader_install}; ++ ++ my $media_boot = $live->get_media_prefix('boot', $opts->{boot}); ++ my $device = get_media_device($live, $opts); ++ my $bootloader = $media->get_boot_setting('bootloader', $opts); ++ ++ member($bootloader, 'grub', 'syslinux') or die "no bootloader defined in media configuration\n"; ++ if ($bootloader eq 'syslinux') { ++ cp_f($live->get_builddir . $_, $live->{mnt}) foreach map { ++ $live->{prefix}{boot} . $_; ++ } get_syslinux_path($media, $opts), $media->get_initrd_path, @syslinux_boot_files; ++ } elsif ($bootloader eq 'grub') { ++ if (need_media_specific_boot($live) || $opts->{force_bootloader_config}) { ++ #- FIXME: add get_grub_path (when building boot configuration files) ++ # and get_bootloader_path (when copying) ++ mkdir_p($live->{mnt} . $media_boot . '/grub'); ++ cp_f($live->get_builddir . $live->{prefix}{build}{boot} . '/gfxmenu', $live->{mnt} . $media_boot) if $live->{system}{gfxboot}; ++ output_p($live->{mnt} . $media_boot . '/grub/menu.lst', build_grub_cfg($live, $media, $opts, $boot_device)); ++ } ++ } ++ ++ if (-b $boot_device) { ++ if ($bootloader eq 'syslinux') { ++ #- use syslinux -s, "safe, slow and stupid" version of SYSLINUX, unless specified otherwise ++ run_('syslinux', if_(!$media->{fast_syslinux}, '-s'), $boot_device) ++ or die "unable to run syslinux on $device\n"; ++ } elsif ($bootloader eq 'grub') { ++ install_grub_to_image($live, $media, $device, $opts); ++ } ++ } else { ++ warn "not running $bootloader on non block device $device\n"; ++ } ++} ++ ++sub record_usb_master { ++ my ($live, $opts) = @_; ++ my $media = $live->{media}; ++ my $media_boot = $live->get_media_prefix('boot', $opts->{boot}); ++ my $media_loopbacks = $live->get_media_prefix('loopbacks', $opts->{boot}); ++ ++ my $main_device = get_media_device($live, $opts) ++ or die "unable to find recording device (missing label? try with --device <device>)\n"; ++ ++ my $hd = get_hd_from_file($media, $main_device); ++ supplement_media_partitions($media, $hd); ++ ++ my $slash_idx = $media->find_partition_index('/'); ++ my $slash = $media->{partitions}[$slash_idx]; ++ set_part_real_device($hd, $slash); ++ ++ if (my $label = !$opts->{boot_only} && $media->get_media_label) { ++ set_device_label($slash->{real_device}, $media->get_media_setting('fs'), $label); ++ } ++ ++ mkdir_p($live->{mnt}); ++ run_('mount', $slash->{real_device}, $live->{mnt}) ++ or die "unable to mount $slash->{real_device}\n"; ++ ++ rm_rf($live->{mnt} . $media_boot) if -e $live->{mnt} . $media_boot; ++ cp_af($live->get_builddir . $live->{prefix}{build}{boot}, $live->{mnt} . $media_boot); ++ ++ install_disk_bootloader($live, $media, $slash->{real_device}, $opts); ++ ++ do { ++ my $loopbacks_source = $live->get_builddir . $live->{prefix}{build}{loopbacks} . '/'; ++ my $total = directory_usage($loopbacks_source); ++ my $list_file = tmpnam(); ++ output_p($list_file, map { ".$_\n" } list_selected_loopbacks($live)); ++ local $/ = "\r"; ++ my $r = run_foreach(update_progress_rsync($live, $total), ++ 'rsync', '-vdP', '--inplace', '--files-from=' . $list_file, rsync_delete_options($opts), ++ $loopbacks_source, $live->{mnt} . $media_loopbacks, ++ ); ++ unlink $list_file; ++ if (!$r) { ++ run_('umount', $slash->{real_device}); ++ maybe_umount_device($slash->{real_device}); ++ devices::del_loop($slash->{real_device}) if -f $hd->{file}; ++ die "unable to copy loopback files\n"; ++ } ++ ++ cp_af(glob_($live->get_builddir . $live->{prefix}{build}{files} . '/*'), $live->{mnt}); ++ } unless $opts->{boot_only}; ++ ++ my @hidden_files = map { basename($_) } glob_($live->{mnt} . "/.*"), glob_($live->{mnt} . "/autorun.*"); ++ ++ run_('umount', $slash->{real_device}); ++ maybe_umount_device($slash->{real_device}); ++ ++ if ($media->get_media_setting('fs') eq 'vfat') { ++ MDV::Draklive::Utils::mtools_run_('mattrib', '+h', '-i', $slash->{real_device}, '::' . $_) foreach @hidden_files; ++ MDV::Draklive::Utils::mtools_run_('mattrib', '+r', '+s', '-/', '-i', $slash->{real_device}, '::' . $_) ++ foreach $media_boot, $media_loopbacks; ++ } ++ ++ devices::del_loop($slash->{real_device}) if -f $hd->{file}; ++} ++ ++sub record_harddisk_master { ++ my ($live, $opts) = @_; ++ ++ my $media = $live->{media}; ++ my $media_boot = $live->get_media_prefix('boot', $opts->{boot}); ++ my $media_loopbacks = $live->get_media_prefix('loopbacks', $opts->{boot}); ++ ++ my $main_device = get_media_device($live, $opts) ++ or die "unable to find recording device (missing label? try with --device <device>)\n"; ++ ++ my $hd = get_hd_from_file($media, $main_device); ++ supplement_media_partitions($media, $hd); ++ my @partitions = grep { $_->{mntpoint} =~ m!^/! } @{$media->{partitions}}; ++ ++ mkdir_p($live->{mnt}); ++ foreach my $part (sort { $a->{mntpoint} cmp $b->{mntpoint} } @partitions) { ++ set_part_real_device($hd, $part); ++ my $mnt = $live->{mnt} . $part->{mntpoint}; ++ mkdir_p($mnt); ++ run_('mount', $part->{real_device}, $mnt) ++ or die "unable to mount $part->{real_device}\n"; ++ } ++ ++ my $r = 1; ++ do { ++ my $source = $live->get_system_root; ++ my $total = directory_usage($source); ++ local $/ = "\r"; ++ $r = run_foreach(update_progress_rsync($live, $total), 'rsync', rsync_delete_options($opts), '-a', $source . '/', $live->{mnt}) ++ or last; ++ } unless $opts->{boot_only}; ++ ++ my $boot_idx = $media->find_boot_partition_index; ++ my $boot_part = $media->{partitions}[$boot_idx]; ++ install_disk_bootloader($live, $media, $boot_part->{real_device}, $opts); ++ ++ foreach my $part (sort { $b->{mntpoint} cmp $a->{mntpoint} } @partitions) { ++ run_('umount', $part->{real_device}); ++ maybe_umount_device($part->{real_device}); ++ devices::del_loop($part->{real_device}) if -f $hd->{file}; ++ } ++ ++ $r or die "unable to copy system files\n"; ++ ++ record_oem_rescue($live, $opts) if $live->{oem_rescue}; ++} ++ ++#- $opts: ++#- onthefly : if true, the record function must read from stdin ++sub record_master { ++ my ($live, $opts) = @_; ++ ++ if (my $record = $live->{media}->get_boot_setting('record', $opts)) { ++ $record->($live, $opts); ++ } else { ++ warn "not implemented yet\n"; ++ } ++} ++ ++#- $opts: ++#- onthefly : if true, the record function must read from stdin ++sub record_replicator { ++ my ($live, $opts) = @_; ++ ++ my $replicator_media = $live->{replicator}{media} or die "no replicator media"; ++ if (my $record_replicator = $replicator_media->get_boot_setting('record_replicator', $opts)) { ++ $record_replicator->($live, $opts); ++ } else { ++ warn "not implemented yet\n"; ++ } ++} ++ ++sub pipe_subs { ++ my ($writer, $reader) = @_; ++ my ($r, $w) = POSIX::pipe; ++ if (my $pid = fork()) { ++ POSIX::close($w) or die "couldn't close: $!\n"; ++ my $stdin = POSIX::dup(0) or die "couldn't dup: $!\n"; ++ POSIX::dup2($r, 0) or die "couldn't dup2: $!\n"; ++ POSIX::close($r); ++ $reader->(); ++ POSIX::close(0) or warn "writer exited $?\n"; ++ POSIX::dup2($stdin, 0) or die "couldn't dup2: $!\n"; ++ waitpid($pid, 0); ++ } else { ++ POSIX::close($r) or die "couldn't close: $!\n"; ++ #- don't screw up reader ++ POSIX::dup2(POSIX::open('/dev/null', &POSIX::O_WRONLY), 2) or die "couldn't dup2: $!\n"; ++ POSIX::dup2($w, 1) or die "couldn't dup2: $!\n"; ++ POSIX::close($w); ++ $| = 1; #- autoflush write ++ exit !$writer->(); ++ } ++} ++ ++sub record_onthefly { ++ my ($live, $opts) = @_; ++ ++ my $record = $live->{media}->get_storage_setting('record'); ++ unless ($record) { ++ warn "not implemented yet\n"; ++ return; ++ } ++ if (my $create = $live->{media}->get_storage_setting('record_needs_master') && $live->{media}->get_storage_setting('create')) { ++ local $opts->{onthefly} = 1; ++ #- pipe creation step to recording step ++ pipe_subs(sub { $create->($live, $opts) }, ++ sub { $record->($live, $opts) }); ++ } else { ++ #- no creation step, record directly ++ $record->($live, $opts); ++ } ++} ++ ++sub need_compressed_image { ++ my ($live) = @_; ++ #- compress image if not having loopbacks already ++ !to_bool(list_selected_loopbacks($live)); ++} ++ ++sub get_disk_image_path { ++ my ($live) = @_; ++ if ($live->{settings}{compression_method} eq 'gzip') { ++ get_disk_master_path($live) . if_(need_compressed_image($live), '.gz'); ++ } ++ else { ++ get_disk_master_path($live) . if_(need_compressed_image($live), '.bz2'); ++ } ++} ++ ++sub create_disk_image { ++ my ($live) = @_; ++ if (!need_compressed_image($live)) { ++ warn "already using loopback: skipping image creation\n"; ++ return; ++ } ++ my $master = get_disk_master_path($live); ++ my $dest = get_disk_image_path($live); ++ mkdir_p(dirname($dest)); ++ ++ if ($live->{settings}{compression_method} eq 'gzip') { ++ run_('gzip', '>', $dest, '-f', '-c', '--fast', $master); ++ } ++ else { ++ run_('bzip2', '>', $dest, '-f', '-k', '-c', $master); ++ } ++} ++ ++sub create_image { ++ my ($live) = @_; ++ ++ if (my $create = $live->{media}->get_media_setting('image')) { ++ $create->($live); ++ } else { ++ warn "not implemented yet\n"; ++ } ++} ++ ++sub create_vm_image { ++ my ($live) = @_; ++ ++ my $vm_type = $live->{settings}{vm_type}; ++ if (!$vm_type) { ++ warn "no vm_type has been set in settings, skipping"; ++ return; ++ } ++ ++ if (!$live->{media}->get_media_setting('image')) { ++ warn "not implemented yet\n"; ++ return; ++ } ++ ++ my $master = get_disk_master_path($live); ++ if (!-f $master) { ++ warn "no master image, skipping\n"; ++ } ++ ++ my $vm_image = get_disk_master_prefix($live) . ".$vm_type"; ++ run_("qemu-img", "convert", "-O", $vm_type, $master, $vm_image); ++} ++ ++sub get_rescue_files { ++ my ($live, $rescue_opts, $extra_files) = @_; ++ my $media_boot = $live->get_media_prefix('boot'); ++ my $initrd = $media_boot . $rescue_opts->{media}->get_initrd_path; ++ my @stage2_files = $live->{settings}{replicator_type} eq 'drakx' ? ( ++ '/usr/lib/drakx-installer-stage2/install/stage2/mdkinst.sqfs', ++ $live->get_system_root . '/bin/dd', ++ ) : '/usr/lib/drakx-installer-rescue/rescue.sqfs'; ++ ( ++ '/usr/lib/drakx-installer-images/isolinux/alt0/vmlinuz' => $media_boot . '/vmlinuz', ++ '/usr/lib/drakx-installer-images/isolinux/alt0/all.rdz' => $initrd, ++ (map { $_ => '/install/stage2/' } @stage2_files), ++ @{$extra_files || []}, ++ #- FIXME: factorize with copy_files_to to handle glob ++ (map { $live->{settings}{config_root} . '/' . $_->[0] => '/' . $_->[1] } @{$rescue_opts->{files} || []}), ++ ); ++} ++ ++sub record_rescue_files { ++ my ($mnt, $device, $rescue_files) = @_; ++ my $failed; ++ foreach (group_by2(@$rescue_files)) { ++ my ($src, $dest) = @$_; ++ $dest = $mnt . $dest; ++ mkdir_p($dest =~ m!/$! ? $dest : dirname($dest)); ++ if (!run_('rsync', '-vdP', '--inplace', $src, $dest)) { ++ $failed = 1; ++ last; ++ } ++ } ++ ++ #- FIXME ++ chmod 0755, $mnt . '/' . 'oem-rescue.sh'; ++ ++ if ($failed) { ++ run_('umount', $mnt); ++ maybe_umount_device($device); ++ die "unable to copy rescue files\n"; ++ } ++} ++ ++sub record_oem_rescue { ++ my ($live, $opts) = @_; ++ ++ my $media = $live->{media}; ++ my $oem_rescue_idx = $media->find_partition_index('OEM_RESCUE'); ++ defined $oem_rescue_idx or die "no OEM_RESCUE partition"; ++ ++ my $main_device = get_media_device($live, $opts) ++ or die "unable to find recording device (missing label? try with --device <device>)\n"; ++ ++ my $hd = get_hd_from_file($media, $main_device); ++ supplement_media_partitions($media, $hd); ++ ++ my $oem_rescue = $media->{partitions}[$oem_rescue_idx]; ++ set_part_real_device($hd, $oem_rescue); ++ ++ mkdir_p($live->{mnt}); ++ run_('mount', $oem_rescue->{real_device}, $live->{mnt}) ++ or die "unable to mount $oem_rescue->{real_device}\n"; ++ ++ record_rescue_files($live->{mnt}, $oem_rescue->{real_device}, [ get_rescue_files($live, $live->{oem_rescue}) ]); ++ ++ run_('umount', $oem_rescue->{real_device}); ++ maybe_umount_device($oem_rescue->{real_device}); ++ devices::del_loop($oem_rescue->{real_device}) if -f $hd->{file}; ++} ++ ++sub get_disk_replicator_prefix { ++ my ($live) = @_; ++ $live->get_builddir . $live->{prefix}{build}{dist} . '/' . $live->get_name . '.rest'; ++} ++ ++sub get_disk_replicator_path { ++ my ($live) = @_; ++ get_disk_replicator_prefix($live) . ".img"; ++} ++ ++sub get_disk_replicator_files { ++ my ($live) = @_; ++ get_rescue_files($live, $live->{replicator}, [ get_disk_image_path($live) => '/images/' ]); ++} ++ ++sub get_disk_replicator_images_list { ++ my ($live) = @_; ++ my $master_path = get_disk_master_path($live); ++ my $master_size = (stat($master_path))[7]; ++ "EN,English," . basename(get_disk_image_path($live)) . ",on,$master_size\n"; ++} ++ ++sub create_usb_replicator { ++ my ($live, $opts) = @_; ++ my %files = get_disk_replicator_files($live); ++ local $opts->{slash_size} = fold_left { $::a + $::b } map { directory_usage($_, 'apparent') } keys(%files); ++ local $opts->{device} = get_disk_replicator_path($live); ++ allocate_master($live, $live->{replicator}{media}, $opts); ++ format_master($live, $live->{replicator}{media}, $opts); ++ record_usb_replicator($live, $opts); ++} ++ ++sub record_usb_replicator { ++ my ($live, $opts) = @_; ++ ++ my $media = $live->{replicator}{media}; ++ my $media_boot = $live->get_media_prefix('boot'); ++ ++ $opts->{append} ||= $live->{replicator}{append}; ++ my $main_device = get_media_device($live, $opts) ++ or die "unable to find recording device (missing label? try with --device <device>)\n"; ++ ++ my $hd = get_hd_from_file($media, $main_device); ++ supplement_media_partitions($media, $hd); ++ ++ my $slash_idx = $media->find_partition_index('/'); ++ my $slash = $media->{partitions}[$slash_idx]; ++ set_part_real_device($hd, $slash); ++ ++ mkdir_p($live->{mnt}); ++ run_('mount', $slash->{real_device}, $live->{mnt}) ++ or die "unable to mount $slash->{real_device}\n"; ++ rm_rf($live->{mnt} . $media_boot) if -e $live->{mnt} . $media_boot; ++ { ++ local $opts->{force_bootloader_config} = 1; ++ install_disk_bootloader($live, $media, $slash->{real_device}, $opts); ++ } ++ ++ record_rescue_files($live->{mnt}, $slash->{real_device}, [ get_disk_replicator_files($live) ]); ++ output_p($live->{mnt} . "/images/list", get_disk_replicator_images_list($live)); ++ ++ run_('umount', $slash->{real_device}); ++ maybe_umount_device($slash->{real_device}); ++ devices::del_loop($slash->{real_device}) if -f $hd->{file}; ++} ++ ++sub create_cdrom_replicator { ++ my ($live, $opts) = @_; ++ ++ # FIXME: factorize with usb replicator, write in builddir/replicator/images-list ++ my $images_list = "/tmp/images-replicator.list"; ++ output_p($images_list, get_disk_replicator_images_list($live)); ++ ++ # FIXME: write in builddir/replicator/syslinux.cfg ++ my $syslinux_cfg = "/tmp/syslinux-replicator.cfg"; ++ local $opts->{append} = $live->{replicator}{append}; ++ output_p($syslinux_cfg, build_syslinux_cfg($live, $live->{replicator}{media}, $opts)); ++ ++ my $label = $live->{replicator}{media}->get_media_label or die "the source device must be described by a label\n"; ++ my $dest = get_cdrom_replicator_path($live); ++ build_iso_image( ++ $live, $opts, ++ $dest, ++ $syslinux_cfg, ++ $label, ++ $live->get_media_prefix('boot', $opts->{boot}) . '/syslinux=' . $live->get_builddir . $live->{prefix}{build}{boot} . '/syslinux', ++ "/images/list=$images_list", ++ (map { ++ my ($src, $dest) = @$_; ++ my $dest_file = $dest =~ m!/$! ? $dest . basename($src) : $dest; ++ $dest_file . "=" . $src; ++ } group_by2(get_disk_replicator_files($live))), ++ ); ++} ++ ++sub create_replicator { ++ my ($live, $opts) = @_; ++ ++ if (my $create = $live->{replicator}{media} && $live->{replicator}{media}->get_media_setting('replicator')) { ++ $create->($live, $opts); ++ } else { ++ warn "not implemented yet\n"; ++ } ++} ++ ++sub update_progress_rsync { ++ my ($live, $total) = @_; ++ my $all_files = 0; ++ my $current_file = 0; ++ $live->{update_progress} ? sub { ++ if (/^\s*(\d+)\s+\d+%\s+/) { ++ $current_file = $1; ++ $live->{update_progress}->(undef, $all_files + $current_file, $total); ++ } ++ if (/(?:^|\n)\S+/) { ++ $all_files += $current_file; ++ $current_file = 0; ++ } ++ } : sub { print }; ++} ++ ++sub copy_wizard { ++ my ($live) = @_; ++ ++ MDV::Draklive::Config::complete_config($live); ++ $live->{system}{vga_mode} = 788 if !defined $live->{system}{vga_mode}; ++ my $live_media = $live->{prefix}{live}{mnt} . $live->{prefix}{media}{mnt}; ++ ++ require interactive; ++ require wizards; ++ my $in = 'interactive'->vnew('su'); ++ my (@available_storage, @available_devices); ++ my ($storage, $device, $format); ++ my %source_types = ( ++ live => N("Use current live system"), ++ file => N("Select a file"), ++ ); ++ my ($source_type, $source_path); ++ my $media_boot = $live->get_media_prefix('boot'); ++ my $media_loopbacks = $live->get_media_prefix('loopbacks'); ++ my $source_is_mounted = sub { -d ($live->{settings}{builddir} . $media_boot) }; ++ my $umount_source = sub { ++ if ($source_type ne 'live' && $source_is_mounted->()) { ++ run_('umount', $live->{settings}{builddir}); ++ rmdir($live->{settings}{builddir}); ++ } ++ }; ++ my $w; ++ $w = wizards->new({ ++ name => N("Live system copy wizard"), ++ pages => { ++ welcome => { ++ name => N("Welcome to the live system copy wizard"), ++ no_back => 1, ++ next => 'source', ++ }, ++ source => { ++ name => N("Which live system do you want to copy?"), ++ data => [ if_(-d ($live_media . $media_loopbacks), ++ { type => 'list', val => \$source_type, ++ list => sort(keys(%source_types)), ++ format => sub { $source_types{$_[0]} } }), ++ { type => 'file', val => \$source_path, ++ disabled => sub { $source_type eq 'live' } } ], ++ pre => $umount_source, ++ complete => sub { ++ if ($source_type eq 'live') { ++ $live->{settings}{builddir} = $live_media; ++ } else { ++ $live->{settings}{builddir} = File::Temp::tempdir(); ++ if (!run_('mount', '-o', 'loop', $source_path, $live->{settings}{builddir})) { ++ $in->ask_warn(N("Error"), N("Unable to use selected file")); ++ return 1; ++ } ++ } ++ 0; ++ }, ++ post => sub { ++ my $boot = $live->{settings}{builddir} . $media_boot; ++ @available_storage = sort(grep { -d "$boot/$_" && exists $MDV::Draklive::Storage::storage_types{$_}{detect} } all($boot)); ++ if (@available_storage == 1) { ++ $storage = $available_storage[0]; ++ return 'device'; ++ } ++ return 'storage'; ++ } ++ }, ++ storage => { ++ name => N("Please select the medium type"), ++ data => [ { type => 'list', allow_empty_list => 1, ++ val => \$storage, list => \@available_storage } ], ++ next => 'device', ++ }, ++ device => { ++ name => N("Please select the device that will contain the new live system"), ++ pre => sub { ++ my %devices = map { $_->{device} => $_ } $MDV::Draklive::Storage::storage_types{$storage}{detect}->(); ++ $_->{formatted_name} = $_->{usb_description} || $_->{info} || $_->{device} foreach values %devices; ++ @available_devices = (); ++ require fs::proc_partitions; ++ foreach (fs::proc_partitions::read([ values %devices ])) { ++ if ($_->{rootDevice} && exists $devices{$_->{rootDevice}}) { ++ my $description = $devices{$_->{rootDevice}}{usb_description} || $devices{$_->{rootDevice}}{info}; ++ $_->{formatted_name} = $description ? "$description ($_->{device})" : $_->{device}; ++ push @available_devices, $_; ++ } ++ } ++ delete $devices{$_->{rootDevice}} foreach @available_devices; ++ unshift @available_devices, map { $devices{$_} } sort keys %devices; ++ undef $device; ++ }, ++ data => [ { type => 'list', allow_empty_list => 1, ++ val => \$device, , list => \@available_devices, ++ format => sub { $_[0]{formatted_name} } }, ++ { text => N("Format selected device"), val => \$format, type => 'bool' } ], ++ complete => sub { ++ return 0 if defined $device; ++ $in->ask_warn(N("Error"), N("You must select a device!")); ++ 1; ++ }, ++ post => sub { ++ (my $_wait, $live->{update_progress}) = $in->wait_message_with_progress_bar; ++ do { ++ local $::isInstall = 1; # quick hack to embed the wait message ++ $live->{update_progress}->(N("Copying in progress")); ++ }; ++ eval { ++ my $opts = { media => { storage => $storage, device => '/dev/' . $device->{device} } }; ++ format_device($live, $opts) if $format; ++ record_onthefly($live, $opts); ++ }; ++ delete $live->{update_progress}; ++ if (my $error = $@) { ++ $in->ask_warn(N("Error"), $error); ++ $w->{pages}{device}{end} = 1; ++ } ++ return "end"; ++ }, ++ }, ++ end => { ++ name => N("Congratulations") . "\n\n" . N("Your live system is now copied."), ++ no_back => 1, ++ end => 1, ++ }, ++ } ++ }); ++ $w->process($in); ++ $umount_source->(); ++ $in->exit; ++} ++ ++sub clean { ++ my ($live) = @_; ++ # umount filesystem in the live before cleaning ++ umount_external_filesystem($live); ++ rm_rf($_) foreach grep { -e $_ } $live->get_builddir, $live->get_system_root; ++} ++ ++my @actions = ( ++ { name => 'dump-config', do => \&MDV::Draklive::Config::dump_config }, ++ { name => 'clean', do => \&clean }, ++ { name => 'install', do => \&install_system }, ++ { name => 'post-install', do => \&post_install_system }, ++ { name => 'initrd', do => \&create_initrd }, ++ { name => 'boot', do => \&prepare_bootloader }, ++ { name => 'tarball', do => \&create_tarball }, ++ { name => 'loop', do => \&create_loopback_files }, ++ { name => 'master', do => \&create_master }, ++ { name => 'image', do => \&create_image }, ++ { name => 'vm-image', do => \&create_vm_image }, ++ { name => 'replicator', do => \&create_replicator }, ++ { name => 'format', do => \&format_device }, ++ { name => 'record', do => \&record_master }, ++ { name => 'record-onthefly', do => \&record_onthefly }, ++ { name => 'record-replicator', do => \&record_replicator }, ++); ++my @all = qw(install boot loop master image vm-image replicator); ++ ++die "you must be root to run this program\n" if $>; ++ ++my $live_object = 'MDV::Draklive::Live'->new; ++my %opts; ++my $config_root = $MDV::Draklive::Config::default_config_root; ++my $config_path = $MDV::Draklive::Config::default_config_path; ++my $settings_path = $MDV::Draklive::Config::default_settings_path; ++GetOptions( ++ "help" => sub { Pod::Usage::pod2usage('-verbose' => 1) }, ++ "copy-wizard" => \$live_object->{copy_wizard}, ++ "keep-files" => \$opts{keep_files}, ++ "boot-only" => \$opts{boot_only}, ++ "boot-image=s" => sub { $opts{boot} = $_[1]; $opts{boot_only} = 1 }, ++ "all" => sub { $_->{to_run} = 1 foreach grep { member($_->{name}, @all) } @actions }, ++ (map { $_->{name} => \$_->{to_run} } @actions), ++ "device=s" => sub { $opts{device} = $_[1] }, ++ "all-regions" => sub { $live_object->{all_regions} = 1 }, ++ "config-root=s" => \$config_root, ++ "config=s" => \$config_path, ++ "settings=s" => \$settings_path, ++ "define=s" => \%{$live_object->{settings}}, ++) or Pod::Usage::pod2usage(); ++ ++require standalone; ++if ($live_object->{copy_wizard}) { ++ copy_wizard($live_object); ++} else { ++ every { !$_->{to_run} } @actions and Pod::Usage::pod2usage(); ++ MDV::Draklive::Config::read_config($live_object, $config_root, $config_path, $settings_path); ++ MDV::Draklive::Config::check_config($live_object); ++ MDV::Draklive::Config::complete_config($live_object); ++ foreach my $region ($live_object->{all_regions} ? sort(keys %{$live_object->{regions}}) : $live_object->{settings}{region}) { ++ $region and print qq(=== proceeding with region "$region"\n); ++ $live_object->{settings}{region} = $region; ++ foreach (grep { $_->{to_run} } @actions) { ++ print qq(* entering step "$_->{name}"\n); ++ $_->{do}->($live_object, \%opts); ++ print qq(* step "$_->{name}" done\n); ++ } ++ } ++} ++ ++__END__ ++ ++=head1 NAME ++ ++draklive - A live distribution mastering tool ++ ++=head1 SYNOPSIS ++ ++draklive [options] ++ ++ Options: ++ --help long help message ++ ++ --install install selected distribution in chroot ++ --boot prepare initrd and bootloader files ++ --tarball build chroot tarball ++ --loop build compressed loopback files ++ --master build master image ++ --image build compressed master image ++ --replicator build replicator image (to dump master on systems) ++ ++ --all run all steps, from installation to mastering ++ ++ --clean clean installation chroot and work directory ++ ++ --device <dev> use this device for live recording (not needed ++ if the device already has the required label) ++ --format format selected device ++ --record record live on selected media ++ --record-onthefly record live by creating master from loopback files ++ on the fly ++ --keep-files keep existing files on media when recording ++ --record-replicator ++ record replicator on selected media ++ ++ --initrd build initrd only ++ --post-install run post install only (rpms and patches installation) ++ ++ --config-root <dir> ++ root directory containing config files and additionnal files ++ defaults to current directory if it contains a configuration file ++ else, "/etc/draklive" is used ++ ++ --config <file> use this configuration file as live description ++ defaults to "config/live.cfg" ++ ++ --settings <file> use this file as live settings (key=value format) ++ defaults to "config/settings.cfg" ++ --define key=value ++ set setting "key" to "value" ++ takes precedence over values from a settings file ++ ++ --all-regions proceed with all configured regions ++ ++ --copy-wizard run the copy wizard ++ ++ --boot-only copy only boot files ++ (affects master/record steps) ++ ++ --boot-image <method> ++ create a boot image for the selected method ++ (affects master/record steps, implies --boot-only) ++ ++Examples: ++ ++ draklive --clean ++ ++ draklive --all ++ ++ draklive --record --device /dev/sdb1 ++ ++ draklive --config config/live.cfg --install ++ ++=head1 OPTIONS ++ ++=over 8 ++ ++=item B<--config> ++ ++Makes draklive use the next argument as a configuration file. ++This file should contain an hash describing the live distribution, ++meaning the system (chroot and boot), media (usb, cdrom, nfs), ++and mount type (simple R/W union, union with squash files). ++ ++Here's a configuration sample: ++ ++ { ++ settings { ++ repository => '/mnt/ken/2006.0', ++ root => '/chroot/live-move', ++ }, ++ system => { ++ kernel => '2.6.12-12mdk-i586-up-1GB', ++ auto_install => 'config/auto_inst.cfg.pl', ++ patch_install => 'config/patch-2006-live.pl', ++ rpmsrate => 'config/rpmsrate', ++ rpms => [ ++ 'rpms/unionfs-kernel-2.6.12-12mdk-i586-up-1GB-1.1.1.1.20051124.1mdk-1mdk.i586.rpm' ++ ], ++ patches => [ ++ 'patches/halt.loopfs.patch', ++ ], ++ vga_mode => 788, ++ no_initrd => 0, ++ }, ++ media => { ++ storage => 'cdrom', ++ }, ++ mount => $predefined{mounts}{squash_union} ++ }; ++ ++=item B<--settings> ++ ++Makes draklive load the next argument as a file in key=value format ++into the $live->{settings} hash ($live being the global live configuration hash). ++ ++Built-in keys: ++ arch: build architecture ++ builddir: directory hosting build files (initrd, loopbacks, images) ++ chroot: directory hosting chrooted installations ++ region: use the matching set of langs from the regions configuration hash ++ repository: path to the Mandriva distribution repository (ftp/http/local) ++ ++Example keys: ++ desktop ++ media ++ product ++ ++=back ++ ++=head1 DESCRIPTION ++ ++B<draklive> builds a live distribution according to a ++configuration file, creates a master image, ++and optionally installs it on a device. ++ ++See L<http://qa.mandriva.com/twiki/bin/view/Main/DrakLive> ++ ++=head1 AUTHOR ++ ++Olivier Blin <oblin@mandriva.com> ++ ++=cut + + +Property changes on: draklive/trunk/draklive +___________________________________________________________________ +<a id="svnexecutable">Added: svn:executable</a> + + * + +<a id="draklivetrunkdraklivecopywizarddesktop">Added: draklive/trunk/draklive-copy-wizard.desktop</a> +=================================================================== +--- draklive/trunk/draklive-copy-wizard.desktop (rev 0) ++++ draklive/trunk/draklive-copy-wizard.desktop 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,7 @@ ++[Desktop Entry] ++Encoding=UTF-8 ++Exec=/usr/sbin/draklive --copy-wizard ++Icon=MandrivaOne-copy-icon ++Terminal=false ++Type=Application ++Name=Live copy + +<a id="draklivetrunkkmodreadlogc">Added: draklive/trunk/kmod/readlog.c</a> +=================================================================== +--- draklive/trunk/kmod/readlog.c (rev 0) ++++ draklive/trunk/kmod/readlog.c 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,230 @@ ++#include <linux/init.h> ++#include <linux/module.h> ++ ++#include <linux/kernel.h> ++#include <linux/file.h> ++#include <linux/fs.h> ++#include <linux/sched.h> ++#include <linux/syscalls.h> ++#include <linux/time.h> ++ ++#include <asm/unistd.h> ++ ++#include <asm/current.h> ++#include <linux/debugfs.h> ++#include <linux/seq_file.h> ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Olivier Blin <blino@mandriva.com>"); ++ ++struct opened_file { ++ struct list_head s_list; ++ char *name; ++}; ++ ++unsigned long **sys_call_table; ++static struct dentry *dbg_dir; ++static struct dentry *dbg_file; ++struct opened_file bp; ++DECLARE_MUTEX(files_mutex); ++ ++ssize_t (*read)(int f, const void *buf, size_t n); ++long (*open)(const char __user *filename, int flags, int mode); ++ ++static void *profile_seq_start(struct seq_file *file, loff_t *pos) ++{ ++ struct list_head *p; ++ loff_t l = *pos; ++ down(&files_mutex); ++ list_for_each(p, &bp.s_list) ++ if (!l--) ++ return list_entry(p, struct opened_file, s_list); ++ return NULL; ++} ++ ++static void *profile_seq_next(struct seq_file *file, void *v, loff_t *pos) ++{ ++ struct list_head *p = ((struct opened_file *)v)->s_list.next; ++ (*pos)++; ++ return p == &bp.s_list ? NULL : list_entry(p, struct opened_file, s_list); ++} ++ ++static void profile_seq_stop(struct seq_file *file, void *v) ++{ ++ up(&files_mutex); ++} ++ ++static int profile_seq_show(struct seq_file *file, void *v) ++{ ++ seq_printf(file, ((struct opened_file *)v)->name); ++ seq_putc(file, '\n'); ++ return 0; ++} ++ ++static struct seq_operations profile_seq_ops = { ++ .start = profile_seq_start, ++ .next = profile_seq_next, ++ .stop = profile_seq_stop, ++ .show = profile_seq_show, ++}; ++ ++static int profile_open(struct inode *inode, struct file *file) ++{ ++ return seq_open(file, &profile_seq_ops); ++} ++ ++static struct file_operations profile_fops = { ++ .owner = THIS_MODULE, ++ .open = profile_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release ++}; ++ ++/* Borrowed from ++ * http://downloads.securityfocus.com/downloads/scprint.tar.gz ++ * http://www.gnome.org/~lcolitti/gnome-startup/linux-iolog/readlog.c ++ * http://kerneltrap.org/node/5793 ++ */ ++unsigned long **find_sys_call_table(void) { ++ unsigned long *p; ++ ++ for (p = (unsigned long *)((init_mm.end_code + 4) & 0xfffffffc); ++ p < (unsigned long *)init_mm.end_data; p++) { ++ if (p[__NR_close] == (unsigned long) sys_close){ ++ return (unsigned long **) p; ++ } ++ } ++ ++ return NULL; ++} ++ ++void addfilename(const char *filename) { ++ struct opened_file *f; ++ ++ f = kmalloc(sizeof(struct opened_file), GFP_KERNEL); ++ if (f == NULL) ++ return; ++ ++ f->name = kmalloc(strlen(filename) + 1, GFP_KERNEL); ++ if (f->name == NULL) ++ return; ++ strcpy(f->name, filename); ++ ++ INIT_LIST_HEAD(&f->s_list); ++ ++ printk(KERN_INFO "locking while adding: %s\n", filename); ++ ++ down(&files_mutex); ++ list_add_tail(&f->s_list, &bp.s_list); ++ up(&files_mutex); ++ ++ printk(KERN_INFO "unlocking after adding: %s\n", filename); ++} ++ ++long loggingopen(const char __user *filename, int flags, int mode) { ++ struct file *f = NULL; ++ long fd; ++ ++ fd = open(filename, flags, mode); ++ ++ printk(KERN_INFO "opening fd %ld for %s\n", fd, filename); ++ ++ if(fd > 0 && current) { ++ f = current->files->fd_array[fd]; ++ if(f && f->f_dentry && f->f_vfsmnt) { ++ char tmpname[PATH_MAX]; ++ char *name = d_path(f->f_dentry, f->f_vfsmnt, tmpname, sizeof(tmpname) - 1); ++ if (name) ++ addfilename(name); ++ } ++ } ++ ++ return fd; ++} ++ ++ ++ssize_t loggingread(int fd, const void *buf, size_t n) { ++ struct file *f = NULL; ++ char *name = NULL; ++ loff_t offset = 0; ++ struct timeval tv; ++ char tmpname[256]; ++ ++ do_gettimeofday(&tv); ++ ++ if(current) ++ f = current->files->fd_array[fd]; ++ ++ printk(KERN_DEBUG "READ: f: %p\n", f); ++ ++ ++ if(f) ++ offset = f->f_pos; ++ ++ if (f) ++ printk(KERN_DEBUG "READ: d_entry: %p, vfsmnt: %p\n", f->f_dentry, f->f_vfsmnt); ++ ++ if(f && f->f_dentry && f->f_vfsmnt) { ++ printk(KERN_DEBUG "READ: d_path\n"); ++ name = d_path(f->f_dentry, f->f_vfsmnt, tmpname, sizeof(tmpname) - 1); ++ if (name) ++ addfilename(name); ++ } ++ ++ printk(KERN_DEBUG "READ: %lu.%lu (%s/%d) %Lu %s\n", ++ tv.tv_sec, tv.tv_usec, ++ current ? current->comm : "?", ++ current ? current->pid : 0, ++ offset, ++ name ? name : "<no dentry>" ++ ); ++ ++ return read(fd, buf, n); ++} ++ ++static int __init readlog_init(void) { ++ sys_call_table = find_sys_call_table(); ++ /* compare with grep sys_call_table /boot/System.map */ ++ printk(KERN_INFO "Found sys_call_table at %p\n", sys_call_table); ++ ++ open = (void *) (sys_call_table[__NR_open]); ++ sys_call_table[__NR_open] = (void *) loggingopen; ++ ++ read = (void *) (sys_call_table[__NR_read]); ++ /* sys_call_table[__NR_read] = (void *) loggingread; */ ++ ++ dbg_dir = debugfs_create_dir("dmc", NULL); ++ if (IS_ERR(dbg_dir)) { ++ printk(KERN_NOTICE ": debugfs is not available\n"); ++ return -ENODEV; ++ } ++ if (dbg_dir == NULL) { ++ printk(KERN_NOTICE ": unable to create usbmon directory\n"); ++ return -ENODEV; ++ } ++ ++ dbg_file = debugfs_create_file("bp", 0600, dbg_dir, NULL, &profile_fops); ++ if (dbg_file == NULL) { ++ debugfs_remove(dbg_dir); ++ return -ENODEV; ++ } ++ ++ INIT_LIST_HEAD(&bp.s_list); ++ ++ return 0; ++} ++ ++static void __exit readlog_exit(void) { ++ debugfs_remove(dbg_file); ++ debugfs_remove(dbg_dir); ++ ++ sys_call_table[__NR_open] = (void *) open; ++ sys_call_table[__NR_read] = (void *) read; ++ ++ printk(KERN_INFO "sys_call_table restored\n"); ++ ++} ++ ++module_init(readlog_init); ++module_exit(readlog_exit); + + +Property changes on: draklive/trunk/kmod/readlog.c +___________________________________________________________________ +Added: svn:eol-style + + native + +<a id="draklivetrunklibMDVDrakliveConfigpm">Added: draklive/trunk/lib/MDV/Draklive/Config.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/Config.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/Config.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,97 @@ ++package MDV::Draklive::Config; ++ ++use MDK::Common; ++use Pod::Usage; ++use Cwd 'getcwd'; ++ ++#- we bless Media objects here ++use MDV::Draklive::Media; ++#- these modules can be used from config files ++use MDV::Draklive::Mounts; ++use MDV::Draklive::CustomMedia; ++ ++our $default_config_root = '/etc/draklive'; ++our $default_config_path = 'config/live.cfg'; ++our $default_settings_path = 'config/settings.cfg'; ++ ++sub read_config { ++ my ($live, $config_root, $config_path, $settings_path) = @_; ++ ++ if ($config_path && -e getcwd() . '/' . $config_path) { ++ $config_root = getcwd(); ++ } ++ print "using $config_root as directory root\n"; ++ ++ add2hash($live->{settings} ||= {}, { getVarsFromSh($config_root . '/' . $settings_path) }) if $settings_path; ++ if ($config_path) { ++ #- don't use do(), since it can't see lexicals in the enclosing scope ++ my $cfg = eval(cat_($config_root . '/' . $config_path)) or die "unable to load $config_path: $@\n"; ++ put_in_hash($live, $cfg); ++ print "loaded $config_path as config file\n"; ++ } ++ $live->{settings}{config_root} = $config_root; ++} ++ ++sub check_config { ++ my ($live) = @_; ++ unless (keys(%$live)) { ++ warn "no live definition\n"; ++ Pod::Usage::pod2usage(); ++ } ++ #- check for minimum requirements ++ ref $live->{media} && $live->{media}{storage} or die "no media storage definition\n"; ++ ref $live->{system} or die "no system definition\n"; ++} ++ ++sub complete_config { ++ my ($live) = @_; ++ ++ my $default_prefix = { ++ build => { ++ boot => '/boot', ++ files => '/files', ++ dist => '/dist', ++ initrd => '/initrd', ++ loopbacks => '/loopbacks', ++ modules => '/modules', ++ scripts => '/scripts', ++ }, ++ media => { ++ boot => '/boot', ++ hidden_boot => '/.boot', ++ loopbacks => '/loopbacks', ++ hidden_loopbacks => '/.loopbacks', ++ mnt => '/media', ++ }, ++ live => { ++ mnt => '/live', ++ }, ++ }; ++ ++ #- set unsupplied config dirs ++ add2hash($live->{prefix}{$_} ||= {}, $default_prefix->{$_}) foreach keys %$default_prefix; ++ ++ $live->{settings}{builddir} ||= '/var/lib/draklive/build'; ++ $live->{settings}{chroot} ||= '/var/lib/draklive/chroot'; ++ ++ $live->{settings}{arch} ||= chomp_(`rpm --eval '%{_target_cpu}'`); ++ $live->{media}{title} ||= "live"; ++ ++ $_ = MDV::Draklive::Media::new($_) foreach ( ++ $live->{media}, ++ ($live->{replicator} ? $live->{replicator}{media} : ()), ++ ($live->{oem_rescue} ? $live->{oem_rescue}{media} : ()), ++ ); ++ ++ mkdir_p($live->get_builddir); ++ mkdir_p($live->get_system_root); ++ $live->{mnt} ||= $live->get_builddir . "/mnt"; ++} ++ ++sub dump_config { ++ my ($live) = @_; ++ use Data::Dumper; ++ print Data::Dumper->Dump([ $live ], [ "live" ]); ++} ++ ++1; + +<a id="draklivetrunklibMDVDrakliveCustomMediapm">Added: draklive/trunk/lib/MDV/Draklive/CustomMedia.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/CustomMedia.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/CustomMedia.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,14 @@ ++package MDV::Draklive::CustomMedia; ++ ++sub nfs_media { ++ my ($module, $client, $path) = @_; ++ ( ++ fs => 'nfs', ++ modules => 'nfs', ++ extra_modules => [ $module ], ++ pre => "ifconfig eth0 $client up", ++ source => $path, ++ ); ++} ++ ++1; + +<a id="draklivetrunklibMDVDrakliveInitrdpm">Added: draklive/trunk/lib/MDV/Draklive/Initrd.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/Initrd.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/Initrd.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,314 @@ ++package MDV::Draklive::Initrd; ++ ++use MDK::Common; ++use common; ++use list_modules; ++use MDV::Draklive::Utils; ++use MDV::Draklive::StorageFS; ++use MDV::Draklive::Loopback; ++use MDV::Draklive::Overlay; ++use File::Basename; ++ ++my %module_to_config = ( ++ ext3 => 'EXT3_FS', ++ sd_mod => 'BLK_DEV_SD', ++); ++ ++sub require_list_modules_chroot { ++ my ($live) = @_; ++ my $chroot_list_modules = cat_($live->get_system_root . "/usr/lib/libDrakX/list_modules.pm"); ++ $chroot_list_modules =~ s/^package list_modules;\B/package list_modules_chroot;/; ++ my $tmp_list_modules = $live->get_system_root . "/tmp/list_modules_chroot.pm"; ++ output_p($tmp_list_modules, $chroot_list_modules); ++ require $tmp_list_modules; ++ unlink $tmp_list_modules; ++} ++ ++sub nls_modules { ++ my ($live) = @_; ++ my $fs = $live->{media}->get_media_setting('fs'); ++ if_($fs eq 'vfat', 'nls_cp437'), #- default FAT codepage ++ if_($fs !~ /^ext/, map { "nls_$_" } (map { "iso8859_$_" } 1..7, 9, 13..15), 'utf8'); ++} ++ ++sub create_media_initrd { ++ my ($live) = @_; ++ create_initrd_for_media($live, $live->{media}); ++ cp_f($live->get_builddir . $live->{prefix}{build}{boot} . $live->{media}->get_initrd_path, ++ $live->{copy_initrd}) if $live->{copy_initrd}; ++} ++ ++sub inst_initrd_file { ++ my ($root, $initrd_tree, $file) = @_; ++ if ($file =~ m|/s?bin/|) { ++ inst_initrd_bin($root, $initrd_tree, $file); ++ } else { ++ mkdir_p($initrd_tree . dirname($file)); ++ inst_initrd_dso_deps($root, $initrd_tree, $file) if $file =~ m|/lib[^/]*/|; ++ cp_f($root . $file, $initrd_tree . $file) or die "unable to copy $file from system chroot\n"; ++ } ++} ++ ++sub inst_initrd_dso_deps { ++ my ($root, $initrd_tree, $dso) = @_; ++ foreach my $file (`chroot $root ldd $dso | awk '/\\// {if(\$2 == "=>") {print \$3} else {print \$1}}'`) { ++ chomp $file; ++ $file =~ s!^(/lib[^/]*)/(?:i686|tls)!$1!; ++ my ($lib_prefix, $filename) = $file =~ m|(/lib[^/]*).*/([^/]+)$| or next; ++ my $dest = $initrd_tree . $lib_prefix . '/' . $filename; ++ mkdir_p($initrd_tree . $lib_prefix); ++ -f $dest || cp_f($root . $file, $dest) or die "unable to copy $filename from system chroot\n"; ++ } ++} ++sub inst_initrd_bin { ++ my ($root, $initrd_tree, $bin) = @_; ++ cp_f($root . $bin, $initrd_tree . '/bin/'); ++ inst_initrd_dso_deps($root, $initrd_tree, $bin); ++} ++ ++sub create_initrd_for_media { ++ my ($live, $media) = @_; ++ my $initrd = $live->get_builddir . $live->{prefix}{build}{boot} . $media->get_initrd_path; ++ create_media_specific_initrd($live, $media, $live->get_system_root, $initrd, $live->find_kernel->{version}); ++} ++ ++sub create_media_specific_initrd { ++ my ($live, $media, $root, $initrd, $kernel) = @_; ++ ++ require_list_modules_chroot($live); ++ ++ my $lib_prefix = $live->get_lib_prefix; ++ my $initrd_tree = $live->get_builddir . $live->{prefix}{build}{initrd} . '/' . $media->{storage}; ++ rm_rf($initrd_tree) if -e $initrd_tree; ++ ++ mkdir_p($initrd_tree . $_) foreach ++ qw(/bin /dev /proc /sys /tmp), ++ map { $live->{prefix}{live}{mnt} . $_ } ++ $live->{prefix}{media}{mnt}, ++ $live->{mount}{root}, ++ map { $_->{mountpoint} } grep { !$loop_types{$_->{type}}{skip_mkdir} } @{$live->{mount}{dirs} || []}; ++ ++ #- use nash with label support ++ inst_initrd_bin($root, $initrd_tree, '/sbin/nash'); ++ inst_initrd_bin($root, $initrd_tree, '/usr' . $lib_prefix . '/drakx-installer-binaries/probe-modules'); ++ inst_initrd_bin($root, $initrd_tree, '/sbin/blockdev') ++ if $media->get_media_setting('rereadpt'); ++ inst_initrd_bin($root, $initrd_tree, '/usr/bin/strace') ++ if $live->{debug}; ++ ++ #- busybox is required to: ++ #- detect usb-storage process (we need sh/while/ps/grep) ++ #- mount loopbacks read-only with losetup (useful over NFS) ++ my $busybox = '/usr/bin/busybox'; ++ my $busybox_static = '/bin/busybox.static'; ++ $busybox = $busybox_static if -e $root . $busybox_static; ++ ++ inst_initrd_bin($root, $initrd_tree, $busybox); ++ my @l = map { /functions:/ .. /^$/ ? do { s/\s//g; split /,/ } : () } run_program::rooted_get_stdout($root, $busybox); ++ shift @l; ++ symlink(basename($busybox), $initrd_tree . "/bin/$_") foreach @l; ++ ++ my $fs = $media->get_media_setting('fs'); ++ my @used_loop_types = uniq(map { $_->{type} } @{$live->{mount}{dirs}}); ++ inst_initrd_bin($root, $initrd_tree, $_) foreach ++ MDV::Draklive::StorageFS::get_files($fs), ++ (map { @{$loop_types{$_} && $loop_types{$_}{files} || []} } @used_loop_types); ++ ++ output_p($initrd_tree . '/etc/fstab', ''); ++ output_p($initrd_tree . '/etc/mtab', ''); ++ ++ my $loop_nb = 254; ++ my $rrpt_dev = $media->get_media_setting('rereadpt'); ++ require devices; ++ devices::make($initrd_tree . "/dev/$_") foreach ++ if_($rrpt_dev, $rrpt_dev), ++ qw(console initrd null ram systty tty tty1), ++ (map { "tty$_" } 0..8), ++ (map { "loop$_" } 0 .. $loop_nb); ++ syscall_('mknod', $initrd_tree . "/dev/ptmx", c::S_IFCHR(), makedev(5, 2)) or die "mknod failed (dev $_): $!"; ++ syscall_('mknod', $initrd_tree . "/dev/fb", c::S_IFCHR(), makedev(29, 0)) or die "mknod failed (dev $_): $!"; ++ #- pre-create devfsd compatibility loop devices (since busybox is still built with devfsd support) ++ mkdir_p($initrd_tree . "/dev/loop"); ++ cp_af($initrd_tree . "/dev/loop$_", $initrd_tree . "/dev/loop/$_") foreach 0 .. $loop_nb; ++ ++ print "using kernel $kernel\n"; ++ my $kernel_root = "/lib/modules/" . $kernel; ++ list_modules::load_dependencies($kernel_root . "/modules.dep", $root); ++ ++ my ($storage_modules, $skipped) = partition { list_modules::modname2filename($_) } ++ uniq(map { modules::cond_mapping_24_26($_) } list_modules_chroot::category2modules($media->get_media_setting('modules'))); ++ my ($extra_modules, $extra_missing) = partition { list_modules::modname2filename($_) } ++ list_modules_chroot::category2modules($media->get_media_setting('media_modules')), ++ nls_modules($live), ++ $media->get_media_fs_module, ++ @{$media->get_media_setting('extra_modules') || []}, ++ (map { MDV::Draklive::Loopback::get_loop_modules($live, $_) } uniq(map { $_->{type} } @{$live->{mount}{dirs} || []})), ++ ($live->{mount}{overlay} ? @{$MDV::Draklive::Overlay::overlay{$live->{mount}{overlay}}{modules} || []} : ()); ++ ++ my @additional_modules = map { if_(m!([^/]+)\.ko(?:\.gz)?!, list_modules::filename2modname($1)) } @{$live->{system}{additional_modules}}; ++ @$extra_modules = difference2($extra_modules, \@additional_modules); ++ if (@{$live->{system}{exclude_modules} || []}) { ++ print STDERR "excluding modules: " . join(' ', @{$live->{system}{exclude_modules}}) . "\n"; ++ @$_ = difference2($_, $live->{system}{exclude_modules}) foreach $storage_modules, $extra_modules, $extra_missing; ++ } ++ ++ my @missing = sort(difference2($extra_missing, \@additional_modules)); ++ if (@missing) { ++ my @config = map { if_(/^CONFIG_(.*)=y$/, $1) } cat_($root . "/boot/config-" . $kernel); ++ my @really_missing = grep { !member($module_to_config{$_}, @config) } @missing; ++ @really_missing and die "missing mandatory modules:\n" . join("\n", @really_missing, ''); ++ } ++ ++ mkdir_p($initrd_tree . $kernel_root . "/kernel"); ++ my @modules = (@$storage_modules, @$extra_modules); ++ my @modules_closure = uniq(map { list_modules::dependencies_closure($_) } @modules); ++ foreach my $m (@modules_closure) { ++ my $full = list_modules::modname2path($m); ++ mkdir_p(dirname($initrd_tree . $full)); ++ cp_f($root . $full, $initrd_tree . $full); ++ } ++ foreach my $f (@{$live->{system}{additional_modules}}) { ++ my $destdir = $initrd_tree . $kernel_root . "/kernel"; ++ if ($f =~ /.gz$/) { ++ cp_f($live->{settings}{config_root} . '/' . $f, $destdir); ++ } else { ++ my $m = basename($f); ++ run_program::run('gzip', '>', "$destdir/$m.gz", '-c', $live->{settings}{config_root} . '/' . $f); ++ } ++ } ++ run_('depmod', '-b', $initrd_tree, $kernel); ++ ++ mkdir_p($initrd_tree . "/etc/blkid"); #- for nash and showlabels cache ++ mkdir_p($initrd_tree . "/lib/module-init-tools"); ++ cp_f($root . "/lib/module-init-tools/ldetect-lst-modules.alias", $initrd_tree . "/lib/module-init-tools"); ++ mkdir_p($initrd_tree . "/usr/share/ldetect-lst"); ++ cp_f($root . "/usr/share/pci.ids", $initrd_tree . "/usr/share"); ++ cp_f($root . "/usr/share/ldetect-lst/" . $_, $initrd_tree . "/usr/share/ldetect-lst") ++ foreach qw(fallback-modules.alias pcitable.gz usbtable.gz); ++ ++ @$skipped and print STDERR "skipped modules: " . join(' ', sort(@$skipped)) . "\n"; ++ ++ my @extra_modules_closure = map { list_modules::modname2filename($_) } ++ uniq(map { list_modules::dependencies_closure($_) } @$extra_modules); ++ create_initrd_scriptlet($live, $media, @extra_modules_closure, @additional_modules); ++ ++ print "Compressing initrd\n"; ++ compress_initrd_tree($live, $initrd_tree, $initrd); ++ add_splash($live, $initrd); ++} ++ ++sub create_initrd_scriptlet { ++ my ($live, $media, @modules) = @_; ++ my $target = $live->{prefix}{live}{mnt} . ($live->{mount}{root} || $live->{prefix}{media}{mnt}); ++ my $pre = $media->get_media_setting('pre'); ++ my $fs = $media->get_media_setting('fs'); ++ my $rrpt_dev = $media->get_media_setting('rereadpt'); ++ my $debug_shell = "sh -c 'if grep -q initrd_debug /proc/cmdline; then plymouth --quit; exec sh </dev/console >/dev/console 2>/dev/console; fi'"; ++ my ($mount_first, $mount_last) = partition { !$loop_types{$_->{type}}{delay_mount} } ++ grep { exists $loop_types{$_->{type}}{mount} } @{$live->{mount}{dirs} || []}; ++ my $initrdroot = "/initrd"; ++ ++ output_with_perm($live->get_builddir . $live->{prefix}{build}{initrd} . '/' . $media->{storage} . '/linuxrc', 0755, ++ join("\n", ++ "#!/bin/nash", ++ #- required for labels and ps ++ "nash-mount -t proc /proc /proc", ++ #- required for cdrom labels ++ "nash-mount -t sysfs /sys /sys", ++ "/bin/plymouthd", ++ "plymouth --show-splash", ++ (map { join(" ", "probe-modules", list_modules::filename2modname($_), grep { $_ } $live->{system}{module_options}{$_}) } @modules), ++ "probe-modules --$media->{storage}", ++ if_($rrpt_dev, ++ "echo *** Waiting for new partitions on device ${rrpt_dev} ***", ++ "sh -c 'while ! ls /sys/block/${rrpt_dev}/${rrpt_dev}* >/dev/null 2>&1; do sleep 3; blockdev --rereadpt /dev/${rrpt_dev} >/dev/null 2>&1; done'"), ++ $debug_shell, ++ if_($pre, deref_array($pre)), ++ "showlabels --removable", ++ MDV::Draklive::StorageFS::get_mount($fs)->($live, $media), ++ (map { $loop_types{$_->{type}}{mount}->($live, $_) } @$mount_first, @$mount_last), ++ ($live->{mount}{overlay} ? $MDV::Draklive::Overlay::overlay{$live->{mount}{overlay}}{mount}->($live) : ()), ++ if_($live->{system}{initrd_pre_pivot}, deref_array($live->{system}{initrd_pre_pivot})), ++ "plymouth --newroot=$target", ++ "echo 0x0100 > /proc/sys/kernel/real-root-dev", ++ "umount /sys", ++ "sh -c 'umount /proc/bus/usb 2>/dev/null'", ++ "umount /proc", ++ "pivot_root $target $target$initrdroot", ++ if_($live->{mount}{root}, "sh -c 'rmdir $initrdroot$live->{prefix}{live}{mnt}$live->{mount}{root}'"), ++ (map { $loop_types{$_->{type}}{pivot_clean}->($live, $_, $initrdroot) } grep { $loop_types{$_->{type}}{pivot_clean} } @{$live->{mount}{dirs} || []}), ++ "sh -c 'cd $initrdroot$live->{prefix}{live}{mnt}; for i in `ls -1`; do [ -d \$i ] || continue; mkdir -p $live->{prefix}{live}{mnt}/\$i; mount -n --move \$i $live->{prefix}{live}{mnt}/\$i; rmdir \$i; done'", ++ "rmdir $initrdroot$live->{prefix}{live}{mnt}", ++ "nash-mount -o mode=0755 -t tmpfs /dev /dev", ++ "sh -c 'rm -rf /dev/loop'", #- not needed after initrd ++ "sh -c 'mv $initrdroot/dev/* /dev/'", ++ if_($live->{system}{initrd_post}, deref_array($live->{system}{initrd_post})), ++ "")); ++} ++ ++sub compress_initrd_tree { ++ my ($live, $initrd_tree, $initrd) = @_; ++ ++ my $size = chomp_(run_program::get_stdout("du -ks $initrd_tree | awk '{print \$1}'")); ++ my $inodes = chomp_(run_program::get_stdout("find $initrd_tree | wc -l")) + 100; ++ my $initrd_size = $size + 350 + int($inodes / 10); #- 10 inodes needs 1K ++ $initrd_size += 1000; # splashy ++ ++ $initrd =~ s/.gz$//; ++ ++ mkdir_p(dirname($initrd)); ++ run_('dd', 'if=/dev/zero', "of=$initrd", 'bs=1k', "count=$initrd_size"); ++ run_('mke2fs', '-q', '-m', 0, '-F', '-N', $inodes, '-s', 1, $initrd); ++ mkdir_p($live->{mnt}); ++ run_('mount', '-o', 'loop', '-t', 'ext2', $initrd, $live->{mnt}); ++ cp_af(glob("$initrd_tree/*"), $live->{mnt}); ++ rm_rf($live->{mnt} . "/lost+found"); ++ my $left = chomp_(run_program::get_stdout("df -Pk $live->{mnt} | tail -n 1 | awk '{ print \$4 }'")); ++ run_('umount', $live->{mnt}); ++ $left < 200 and die "not enough room to create initrd (only ${left}K left)\n"; ++ run_('gzip', '-f', '-9', $initrd); ++} ++ ++sub add_splash { ++ my ($live, $initrd) = @_; ++ if ($live->{system}{vga_mode} && $live->{system}{splash} ne 'no') { ++ my $chroot_initrd; ++ if ($initrd !~ m,^/boot/,) { ++ $chroot_initrd = '/tmp/initrd.gz'; ++ cp_f($initrd, $live->get_system_root . $chroot_initrd); ++ } else { ++ $chroot_initrd = $initrd; ++ } ++ ++ { ++ local $::prefix = $live->get_system_root; ++ #- also calls switch-themes -u (through make-boot-splash) ++ #- which will regenerate gfxboot current link ++ require bootloader; ++ bootloader::add_boot_splash($chroot_initrd, $live->{system}{vga_mode}); ++ } ++ ++ if ($chroot_initrd ne $initrd) { ++ cp_f($live->get_system_root . $chroot_initrd, $initrd); ++ unlink($live->get_system_root . $chroot_initrd); ++ } ++ } ++} ++ ++sub create_classical_initrd { ++ my ($live) = @_; ++ my $root = $live->get_system_root; ++ my $kernel = $live->find_kernel; ++ print "using kernel $kernel->{version}\n"; ++ ++ my $initrd_long = '/boot/initrd-'. $kernel . '.img'; ++ unlink($root . $initrd_long); ++ ++ { ++ my $bootloader = {}; ++ local $::prefix = $root; ++ bootloader::add_kernel($bootloader, $kernel, { label => 'linux', vga => $live->{system}{vga_mode} }, '', $live->{system}{no_initrd}); ++ } ++} ++ ++1; + +<a id="draklivetrunklibMDVDrakliveLivepm">Added: draklive/trunk/lib/MDV/Draklive/Live.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/Live.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/Live.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,52 @@ ++package MDV::Draklive::Live; ++ ++use MDK::Common; ++ ++sub new { ++ my ($class) = @_; ++ bless {}, $class; ++} ++ ++sub get_name { ++ my ($live) = @_; ++ my $fields = $live->{name_fields} || [ qw(name product version desktop region media arch) ]; ++ join('-', grep { $_ } @{$live->{settings}}{@$fields}); ++} ++ ++sub get_builddir { ++ my ($live) = @_; ++ $live->{settings}{builddir} . '/' . $live->get_name; ++} ++ ++sub get_system_root { ++ my ($live) = @_; ++ $live->{settings}{chroot} . '/' . $live->get_name; ++} ++ ++sub get_media_prefix { ++ my ($live, $setting, $o_boot) = @_; ++ my $hidden = $live->{system}{hide_media_dirs} && $live->{media}->get_boot_setting('can_hide', { boot => $o_boot }); ++ $live->{prefix}{media}{$hidden ? "hidden_$setting" : $setting}; ++} ++ ++sub find_kernel { ++ my ($live) = @_; ++ require bootloader; ++ local $::prefix = $live->get_system_root; ++ my @kernels = bootloader::get_kernels_and_labels(); ++ my $kernel; ++ if ($live->{system}{kernel}) { ++ $kernel = find { $_->{version} eq $live->{system}{kernel} } @kernels; ++ $kernel or die "kernel $live->{system}{kernel} can not be found\n"; ++ } ++ $kernel ||= first(@kernels) or die "no kernel can be found\n"; ++} ++ ++sub get_lib_prefix { ++ my ($live) = @_; ++ my $lib_prefix = find { glob($live->get_system_root . $_ . '/libc.so.*') } qw(/lib64 /lib); ++ $lib_prefix or die 'unable to find system libraries in /lib or /lib64'; ++ $lib_prefix; ++} ++ ++1; + +<a id="draklivetrunklibMDVDrakliveLoopbackpm">Added: draklive/trunk/lib/MDV/Draklive/Loopback.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/Loopback.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/Loopback.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,142 @@ ++package MDV::Draklive::Loopback; ++ ++use MDK::Common; ++use File::Temp; ++use MDV::Draklive::Progress; ++use MDV::Draklive::Utils; ++ ++use Exporter; ++our @ISA = qw(Exporter); ++our @EXPORT = qw(%loop_types); ++ ++my $loop_number = 0; ++our %loop_types; ++%loop_types = ( ++ squashfs => { ++ read_only => 1, ++ is_loopback => 1, ++ modules => sub { "loop", has_squashfs4_with_lzma($_[0]) ? "squashfs" : "squashfs_lzma" }, ++ extension => '-lzma.sqfs', ++ build => sub { ++ my ($live, $dir) = @_; ++ my $dest = $live->get_builddir . $live->{prefix}{build}{loopbacks} . $dir->{path} . $loop_types{squashfs}{extension}; ++ mkdir_p(dirname($dest)); ++ my $root = $dir->{root} || $live->get_system_root; ++ my $src = $root . $dir->{build_from}; ++ my $total = directory_usage($src); ++ print "have to process " . int($total/1000000) . " MB\n"; ++ my $progress = MDV::Draklive::Progress->new($total, time(), 6); ++ my $exclude_file = tmpnam(); ++ output_p($exclude_file, map { $root . "$_\n" } grep { -e $root . $_ } @{$dir->{exclude} || []}); ++ my $sort = $live->{settings}{config_root} . '/' . $dir->{sort}; ++ my $squashfs4 = has_squashfs4_with_lzma($live); ++ run_foreach(sub { ++ if (/^mksquashfs: file .*, uncompressed size (\d+) bytes\s*(?:DUPLICATE|LINK)?$/) { ++ $progress->{current} += $1; ++ $progress->show(time()); ++ } ++ }, ++ $squashfs4 ? 'mksquashfs' : 'mksquashfs3', $src, $dest, ++ $squashfs4 ? ('-comp', 'lzma') : '-lzma', ++ '-noappend', '-no-progress', '-info', '-b', '1048576', ++ #'-processors', 1, ++ '-ef', $exclude_file, ++ if_(-f $sort, '-sort', $sort), ++ ) or die "unable to run mksquashfs\n"; ++ $progress->end; ++ unlink $exclude_file; ++ }, ++ mount => sub { ++ my ($live, $dir) = @_; ++ $dir->{loop} = "/dev/loop" . $loop_number++; ++ my $media_loopbacks = $live->get_media_prefix('loopbacks'); ++ ( ++ "/bin/losetup $dir->{loop} $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}${media_loopbacks}$dir->{path}$loop_types{squashfs}{extension}", ++ "nash-mount -o ro -t squashfs $dir->{loop} $live->{prefix}{live}{mnt}$dir->{mountpoint}", ++ ); ++ }, ++ }, ++ modules => { ++ read_only => 1, ++ delay_mount => 1, ++ mount => sub { ++ my ($live, $dir) = @_; ++ my $media_loopbacks = $live->get_media_prefix('loopbacks'); ++ "sh -c 'modules=; for m in $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}${media_loopbacks}$dir->{path}/*; do n=\$(basename \$m); n=\${n%.sqfs}; d=$live->{prefix}{live}{mnt}$dir->{mountpoint}/\$n; mkdir -p \$d; mount -n -o loop,ro -t squashfs \$m \$d && modules=\$modules\$d=ro:; done; echo \$modules | sed -e s/:\$// > $live->{prefix}{live}{mnt}/$dir->{list}'"; ++ }, ++ pivot_clean => sub { ++ my ($live, $dir, $initrdroot) = @_; ++ ( ++ "sh -c 'cd $initrdroot$live->{prefix}{live}{mnt}$dir->{mountpoint}; for i in `ls -1`; do mkdir -p $live->{prefix}{live}{mnt}$dir->{mountpoint}/\$i; mount -n --move \$i $live->{prefix}{live}{mnt}$dir->{mountpoint}/\$i; rmdir \$i; done; rmdir $initrdroot$live->{prefix}{live}{mnt}$dir->{mountpoint}'", ++ "sh -c 'mv $initrdroot$live->{prefix}{live}{mnt}/$dir->{list} $live->{prefix}{live}{mnt}/'", ++ ); ++ }, ++ }, ++ loopfs => { ++ is_loopback => 1, ++ modules => [], ++ extension => '.loop', ++ build => sub { ++ my ($live, $dir) = @_; ++ my $dest = $live->get_builddir . $live->{prefix}{build}{loopbacks} . $dir->{path} . $loop_types{loopfs}{extension}; ++ mkdir_p(dirname($dest)); ++ MDV::Draklive::Utils::device_allocate_file($dest, $dir->{pre_allocate}); ++ MDV::Draklive::Utils::device_mkfs($dest, $dir->{fs}) if !defined $dir->{min_size}; ++ }, ++ mount => sub { ++ my ($live, $dir) = @_; ++ $dir->{loop} = "/dev/loop" . $loop_number++; ++ my $fsck = "chroot </dev/tty1 $live->{prefix}{live}{mnt}$dir_distrib_sqfs->{mountpoint} /sbin/fsck $dir->{loop}"; ++ my $media_loopbacks = $live->get_media_prefix('loopbacks'); ++ ( ++ "losetup $dir->{loop} $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}${media_loopbacks}$dir->{path}$loop_types{loopfs}{extension}", ++ qq(sh -c "$fsck -a || $fsck -y"), ++ "nash-mount -t $dir->{fs} $dir->{loop} $live->{prefix}{live}{mnt}$dir->{mountpoint}", ++ ); ++ }, ++ }, ++ plain => { ++ skip_mkdir => 1, ++ mount => sub { ++ my ($live, $dir) = @_; ++ qq(sh -c "mkdir -p $live->{prefix}{live}{mnt}$dir->{mountpoint}"); ++ }, ++ }, ++ partition => { ++ files => [ '/sbin/fsck', '/sbin/blkid' ], ++ mount => sub { ++ my ($live, $dir) = @_; ++ my $fsck = "/bin/fsck"; ++ ( ++ qq(sh -c 'dev=`blkid -l -t $dir->{path} -o device`; [ -z "\$dev" ] || $fsck -a \$dev || $fsck -y \$dev'), ++ "nash-mount -t $dir->{fs} $dir->{path} $live->{prefix}{live}{mnt}$dir->{mountpoint}", ++ ); ++ }, ++ }, ++ tmpfs => { ++ mount => sub { ++ my ($live, $dir) = @_; ++ my $mnt = $live->{prefix}{live}{mnt} . $dir->{mountpoint}; ++ my $mount_opts = $dir->{mount_opts}?"-o $dir->{mount_opts}":""; ++ my $cmd = "mount -t tmpfs $mount_opts $mnt $mnt"; ++ $dir->{fallback} ? qq(sh -c 'if ! grep -q " $mnt " /proc/mounts; then $cmd; fi') : $cmd; ++ }, ++ }, ++); ++ ++sub get_loop_modules { ++ my ($live, $type) = @_; ++ my $modules = $loop_types{$_}{modules}; ++ my $type = ref $modules; ++ return $type eq 'CODE' ? $modules->($live) : ++ $type eq 'ARRAY' ? @$modules : ++ (); ++} ++ ++sub has_squashfs4_with_lzma { ++ my ($live) = @_; ++ my $kernel = $live->find_kernel; ++ cat_($live->get_system_root . "/boot/config-" . $live->find_kernel->{version}) =~ /^CONFIG_DECOMPRESS_LZMA_NEEDED=y$/m; ++} ++ ++1; + +<a id="draklivetrunklibMDVDrakliveMediapm">Added: draklive/trunk/lib/MDV/Draklive/Media.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/Media.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/Media.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,88 @@ ++package MDV::Draklive::Media; ++ ++use MDK::Common; ++use MDV::Draklive::Storage; ++use POSIX; ++use common; ++ ++sub new { ++ my ($media) = @_; ++ ++ bless $media, 'MDV::Draklive::Media'; ++ ++ $media->{partitions} ||= [ { mntpoint => '/' } ]; ++ ++ for $mntpoint (qw(/ OEM_RESCUE)) { ++ my $part = find { $_->{mntpoint} eq $mntpoint } @{$media->{partitions}}; ++ $part->{fs_type} ||= $media->get_media_setting('fs'); ++ if (my $label = $mntpoint eq '/' && $media->get_media_label) { ++ $part->{device_LABEL} ||= $label; ++ } ++ } ++ ++ $media->{boot_entries} ||= [ '' => '' ]; ++ ++ $media; ++} ++ ++sub get_initrd_path { ++ my ($media) = @_; ++ '/' . $media->{storage} . '/initrd.gz'; ++} ++ ++#- mainly for storage-specific subroutines ++sub get_storage_setting { ++ my ($media, $setting) = @_; ++ $MDV::Draklive::Storage::storage_types{$media->{storage}}{$setting}; ++} ++ ++#- for actions that support an optional boot storage type ++sub get_boot_setting { ++ my ($media, $setting, $opts) = @_; ++ $opts->{boot} ? $MDV::Draklive::Storage::storage_types{$opts->{boot}}{$setting} : get_media_setting($media, $setting); ++} ++ ++#- for user-customisable media setting, that can override storage setting ++sub get_media_setting { ++ my ($media, $setting) = @_; ++ $media->{$setting} || $media->get_storage_setting($setting); ++} ++ ++sub get_media_fs_module { ++ my ($media) = @_; ++ my $fs = $media->get_media_setting('fs'); ++ $fs eq 'iso9660' ? 'isofs' : $fs eq 'ext2' ? @{[]} : $fs; ++} ++ ++sub get_media_label { ++ my ($media) = @_; ++ first($media->get_media_setting('source') =~ /^LABEL=(.*)$/); ++} ++ ++sub get_media_source_for_nash { ++ my ($media) = @_; ++ my $label = $media->get_media_label; ++ #- strip vfat labels to 11 chars and upper-case it ++ $label && $media->get_media_setting('fs') eq 'vfat' ? ++ 'LABEL=' . uc(substr($label, 0, 11)) : ++ $media->get_media_setting('source'); ++} ++ ++sub find_partition_index { ++ my ($media, $mntpoint) = @_; ++ eval { find_index { $_->{mntpoint} eq $mntpoint } @{$media->{partitions}} }; ++} ++ ++sub find_boot_partition_index { ++ my ($media) = @_; ++ $media->find_partition_index('/boot') || $media->find_partition_index('/'); ++} ++ ++sub supplement_slash_size { ++ my ($media, $total_size) = @_; ++ my $correction = 1.2; ++ my $slash = find { $_->{mntpoint} eq '/' } @{$media->{partitions}}; ++ $slash->{size} ||= POSIX::ceil($total_size * $correction / $common::SECTORSIZE); ++} ++ ++1; + +<a id="draklivetrunklibMDVDrakliveMountspm">Added: draklive/trunk/lib/MDV/Draklive/Mounts.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/Mounts.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/Mounts.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,93 @@ ++package MDV::Draklive::Mounts; ++ ++use MDK::Common; ++ ++my $_dir_distrib_sqfs = { ++ mountpoint => '/distrib', ++ type => 'squashfs', ++ path => '/distrib', ++ # perl -MMDK::Common -e 'print map_index { (32767 - $::i) . " $_" } grep { !m,^/(?:dev|proc|sys|live/distrib), } uniq(<>)' < bootlog.list > config/distrib.sort ++ sort => "config/distrib.sort", ++ build_from => '/', ++}; ++my $_dir_memory = { ++ mountpoint => '/memory', ++ type => 'tmpfs', ++ mount_opts => 'mode=755', ++}; ++ ++my $_dir_modules = { ++ mountpoint => '/modules', ++ type => 'modules', ++ path => '/modules', ++ list => 'modules.lst', ++}; ++ ++#- use distro default ++our $default = { ++ dirs => [], ++}; ++ ++our $simple_union = { ++ root => '/union', ++ overlay => 'unionfs', ++ dirs => [ ++ { ++ mountpoint => '/media', ++ type => 'plain', ++ }, ++ $_dir_memory, ++ ], ++ }; ++ ++our $squash_rw_union = { ++ root => '/union', ++ overlay => 'unionfs', ++ dirs => [ ++ $_dir_distrib_sqfs, ++ { ++ mountpoint => '/media/system', ++ type => 'plain', ++ }, ++ ], ++ }; ++ ++sub volatile_squash_union { ++ my ($o_modules) = @_; ++ { ++ root => '/union', ++ overlay => 'unionfs', ++ dirs => [ ++ $_dir_distrib_sqfs, ++ if_($o_modules, $_dir_modules), ++ $_dir_memory, ++ ], ++ }; ++} ++ ++sub squash_union { ++ my ($default_size, $o_min_size, $o_modules) = @_; ++ { ++ root => '/union', ++ overlay => 'unionfs', ++ dirs => [ ++ $_dir_distrib_sqfs, ++ if_($o_modules, $_dir_modules), ++ { ++ mountpoint => '/system', ++ type => 'loopfs', ++ pre_allocate => $default_size, ++ if_(defined $o_min_size, min_size => $o_min_size), ++ fs => 'ext2', ++ path => '/system' ++ }, ++ { ++ mountpoint => '/system', ++ type => 'tmpfs', ++ fallback => 1, ++ }, ++ ], ++ }; ++} ++ ++1; + +<a id="draklivetrunklibMDVDrakliveOverlaypm">Added: draklive/trunk/lib/MDV/Draklive/Overlay.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/Overlay.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/Overlay.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,22 @@ ++package MDV::Draklive::Overlay; ++ ++use MDV::Draklive::Loopback; ++ ++our %overlay = ( ++ unionfs => { ++ modules => [ qw(unionfs) ], ++ mount => sub { ++ my ($live) = @_; ++ #- build dirs list: "dir1=ro:dir2:ro:dir3=rw" ++ my $dirs = join(':', ++ map { ++ $_->{list} ? "\$(cat $live->{prefix}{live}{mnt}/$_->{list})" : ++ "$live->{prefix}{live}{mnt}$_->{mountpoint}=" . ++ (!$loop_types{$_->{type}}{read_only} && !$_->{read_only} ? 'rw' : 'ro'); ++ } reverse grep { !$_->{fallback} } @{$live->{mount}{dirs} || []}); ++ "sh -c 'mount -o dirs=$dirs -t unionfs unionfs $live->{prefix}{live}{mnt}$live->{mount}{root}'"; ++ }, ++ }, ++); ++ ++1; + +<a id="draklivetrunklibMDVDrakliveProgresspm">Added: draklive/trunk/lib/MDV/Draklive/Progress.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/Progress.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/Progress.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,31 @@ ++package MDV::Draklive::Progress; ++ ++use POSIX qw(strftime); ++ ++sub new { ++ my ($class, $total, $time, $o_exp_divide) = @_; ++ bless { ++ total => $total, ++ current => 0, ++ start_time => $time, ++ exp_divide => $o_exp_divide, ++ maxl => length($total) - $o_exp_divide, ++ }, $class; ++} ++ ++sub show { ++ my ($progress, $time) = @_; ++ my $elapsed_time = $time - $progress->{start_time}; ++ my $eta = $progress->{current} ? int($elapsed_time*$progress->{total}/$progress->{current}) : -1; ++ printf("\r%3d%% (%$progress->{maxl}s/%-$progress->{maxl}s), %8s/%8s (ETA)", ++ int(100*$progress->{current}/$progress->{total}), ++ (map { substr($_, 0, length($_)-$progress->{exp_divide}) } $progress->{current}, $progress->{total}), ++ (map { POSIX::strftime("%H:%M:%S", gmtime($_)) } $elapsed_time, $eta)); ++} ++ ++sub end { ++ my ($_progress) = @_; ++ print "\n"; ++} ++ ++1; + +<a id="draklivetrunklibMDVDrakliveStoragepm">Added: draklive/trunk/lib/MDV/Draklive/Storage.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/Storage.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/Storage.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,47 @@ ++package MDV::Draklive::Storage; ++ ++use detect_devices; ++ ++our %storage_types = ( ++ cdrom => { ++ modules => 'bus/firewire|usb disk/firewire|hardware_raid|ide|sata|scsi|usb', ++ media_modules => 'disk/cdrom', ++ fs => 'iso9660', ++ can_hide => 0, ++ source => 'LABEL=MDVCDROOT', ++ read_only => 1, ++ detect => \&detect_devices::burners, ++ create => \&main::create_cdrom_master, ++ format => \&main::format_cdrom_device, ++ record_needs_master => 1, ++ record => \&main::record_cdrom_master, ++ replicator => \&main::create_cdrom_replicator, ++ record_replicator => \&main::record_cdrom_replicator, ++ }, ++ usb => { ++ modules => 'bus/usb disk/usb', ++ media_modules => 'disk/raw', ++ fs => 'vfat', ++ can_hide => 1, ++ bootloader => 'grub', ++ source => 'LABEL=MDVUSBROOT', ++ detect => sub { grep { detect_devices::isKeyUsb($_) } detect_devices::get() }, ++ create => \&main::create_disk_master, ++ format => \&main::format_disk, ++ record => \&main::record_usb_master, ++ image => \&main::create_disk_image, ++ replicator => \&main::create_usb_replicator, ++ record_replicator => \&main::record_usb_replicator, ++ }, ++ harddisk => { ++ fs => 'ext4', ++ bootloader => 'grub', ++ source => 'LABEL=MDVROOT', ++ create => \&main::create_disk_master, ++ format => \&main::format_disk, ++ record => \&main::record_harddisk_master, ++ image => \&main::create_disk_image, ++ }, ++); ++ ++1; + +<a id="draklivetrunklibMDVDrakliveStorageFSpm">Added: draklive/trunk/lib/MDV/Draklive/StorageFS.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/StorageFS.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/StorageFS.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,56 @@ ++package MDV::Draklive::StorageFS; ++ ++use MDK::Common; ++ ++my %storage_fs; ++%storage_fs = ( ++ generic => { ++ mount => sub { ++ my ($live, $media) = @_; ++ my @mount_options = ( ++ if_($media->get_media_setting('read_only'), "ro"), ++ grep { $_ } $media->get_media_setting('mount_options'), ++ ); ++ 'nash-mount' . if_(@mount_options, " -o " . join(",", @mount_options)) . " -t " . $media->get_media_setting('fs') . ++ " " . $media->get_media_source_for_nash . " $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}"; ++ }, ++ }, ++ nfs => { ++ files => [ '/sbin/ifconfig', '/bin/mount' ], #- needed to mount NFS (with nolock) ++ mount => sub { ++ my ($live, $media) = @_; ++ '/bin/mount -n -o ro,nolock -t nfs ' . $media->get_media_source_for_nash . " $live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}"; ++ } ++ }, ++ ext2 => { ++ files => [ '/sbin/fsck.ext2' ], ++ mount => sub { ++ my ($live, $media) = @_; ++ my $fsck = "/bin/fsck.ext2"; ++ my $source = $media->get_media_setting('source'); ++ qq(sh -c '$fsck -a $source || $fsck -y $source'), ++ $storage_fs{generic}{mount}->($live, $media); ++ }, ++ }, ++ vfat => { ++ #files => [ '/sbin/dosfsck' ], ++ mount => sub { ++ my ($live, $media) = @_; ++ #$storage_fs{generic}{mount}->($live, $media), ++ #qq(awk '\$2 == "$live->{prefix}{live}{mnt}$live->{prefix}{media}{mnt}" { system("umount " \$1 "; mount; echo dosfsck -a " \$1 "; dosfsck -a " \$1) }' /proc/mounts), ++ $storage_fs{generic}{mount}->($live, $media); ++ }, ++ }, ++); ++ ++sub get_files { ++ my ($fs) = @_; ++ @{$storage_fs{$fs} && $storage_fs{$fs}{files} || []}; ++} ++ ++sub get_mount { ++ my ($fs) = @_; ++ $storage_fs{exists $storage_fs{$fs}{mount} ? $fs : 'generic'}{mount}; ++} ++ ++1; + +<a id="draklivetrunklibMDVDrakliveUtilspm">Added: draklive/trunk/lib/MDV/Draklive/Utils.pm</a> +=================================================================== +--- draklive/trunk/lib/MDV/Draklive/Utils.pm (rev 0) ++++ draklive/trunk/lib/MDV/Draklive/Utils.pm 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,85 @@ ++package MDV::Draklive::Utils; ++ ++use MDK::Common; ++use common; ++use run_program; ++use IPC::Open3; ++use IO::Select; ++ ++use Exporter; ++our @ISA = qw(Exporter); ++our @EXPORT = qw(directory_usage run_ run_foreach); ++ ++sub directory_usage { ++ my ($dir, $o_apparent) = @_; ++ my $apparent = $o_apparent && "--apparent-size"; ++ first(split /\s/, `du -s -B 1 $apparent $_[0]`); ++ } ++ ++#- expand only if the pattern contains '*' ++#- and matches dot characters (like shell dotglob) ++sub glob__ { ++ my ($pattern) = @_; ++ $pattern =~ /\*/ ? glob_($pattern) : $pattern; ++} ++ ++sub run_ { ++ my $options = ref $_[0] eq 'HASH' ? shift @_ : {}; ++ my @cmd = @_; ++ $options->{timeout} ||= 'never'; ++ if (arch() !~ /^arm/) { ++ my $targetarch = delete $options->{targetarch}; ++ unshift @cmd, 'setarch', $targetarch if $targetarch; ++ } ++ print STDERR "running " . (exists $options->{root} && "(in chroot) ") . join(' ', @cmd) . "\n"; ++ run_program::raw($options, @cmd); ++} ++ ++sub run_foreach { ++ my ($foreach, @command) = @_; ++ print STDERR "running " . join(' ', @command) . "\n"; ++ my $pid = open3(my $cmd_in, my $cmd_out, undef, @command); ++ my $selector = IO::Select->new($cmd_out); ++ while (my @ready = $selector->can_read) { ++ foreach my $fh (@ready) { ++ local $_ = scalar<$fh>; ++ return if /^open3:/; ++ $foreach->(); ++ $selector->remove($fh) if eof($fh); ++ } ++ } ++ close($cmd_out); ++ close($cmd_in); ++ return waitpid($pid, 0) > 0 && !($? >> 8); ++} ++ ++sub mtools_run_ { ++ local $ENV{MTOOLS_SKIP_CHECK} = 1; ++ &run_; ++} ++ ++sub device_allocate_file { ++ my ($device, $size) = @_; ++ run_('dd', "of=$device", 'count=0', 'bs=1', "seek=" . removeXiBSuffix($size)); ++} ++ ++#- format $device as type $type ++# FIXME: use fs::format ++sub device_mkfs { ++ my ($device, $type, $o_label, $o_inode_size) = @_; ++ if ($type eq 'vfat') { ++ run_('mkfs.vfat', if_(defined $o_label, '-n', $o_label), $device); ++ } elsif (member($type, 'ext2', 'ext3', 'ext4')) { ++ run_("mkfs.$type", "-m", 0, ++ if_(defined $o_label, '-L', $o_label), ++ if_($o_inode_size, '-I', $o_inode_size), ++ if_(!-b $device, '-F'), ++ $device); ++ } elsif ($type eq 'swap') { ++ run_('mkswap', if_(defined $o_label, '-L', $o_label), $device); ++ } else { ++ die "unable to mkfs for unsupported media type $type\n"; ++ } ++} ++ ++1; + +<a id="draklivetrunkmkinitrddraklive">Added: draklive/trunk/mkinitrd-draklive</a> +=================================================================== +--- draklive/trunk/mkinitrd-draklive (rev 0) ++++ draklive/trunk/mkinitrd-draklive 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,20 @@ ++#!/usr/bin/perl ++ ++use lib qw(/usr/lib/libDrakX); ++ ++use MDV::Draklive::Live; ++use MDV::Draklive::Config; ++use MDV::Draklive::Initrd; ++ ++my ($initrd, $kernel) = @ARGV; ++$initrd && $kernel or die "usage $0 <initrd> <kernel>\n"; ++ ++my $live = 'MDV::Draklive::Live'->new; ++MDV::Draklive::Config::read_config($live, ++ $MDV::Draklive::Config::default_config_root, ++ $MDV::Draklive::Config::default_config_path, ++ $MDV::Draklive::Config::default_settings_path); ++MDV::Draklive::Config::check_config($live); ++MDV::Draklive::Config::complete_config($live); ++ ++MDV::Draklive::Initrd::create_media_specific_initrd($live, $live->{media}, "/", $initrd, $kernel); + +<a id="draklivetrunkwrite_flashsh">Added: draklive/trunk/write_flash.sh</a> +=================================================================== +--- draklive/trunk/write_flash.sh (rev 0) ++++ draklive/trunk/write_flash.sh 2011-02-03 17:53:54 UTC (rev 397) +@@ -0,0 +1,95 @@ ++#!/bin/sh ++ ++source=mandriva-linux-flash-2010-KDE4-all-usb-i586.img ++dump_block_size=$((2*1024*1024)) ++ ++title="USB image dump" ++ ++image_size=$(stat -c %s $source) ++image_md5=$(awk '{ print $1 }' $source.md5) ++mbr_size=512 ++ ++image_blocks=$((image_size/dump_block_size)) ++image_remainder_bytes=$((image_size%dump_block_size)) ++image_remainder_skip=$((image_size-image_remainder_bytes)) ++ ++log() { ++ echo "$* (on $(date))" ++} ++ ++show_wait() { ++ log $* ++ zenity --progress --auto-kill --title "$title" --text "$*" & ++} ++ ++show_progress() { ++ log $* ++ zenity --progress --auto-kill --pulsate --title "$title" --text "$*" & ++} ++ ++show_error() { ++ log $* ++ zenity --error --title $title --text "$*" ++} ++ ++# forbid auto-mount on LXDE ++killall halevt ++ ++#mkdir -p /mnt/loop ++#mount -o offset=$((62*512)),ro $source /mnt/loop ++while true; do ++ show_wait "Please insert new key" ++ wait_pid=$! ++ while sleep 5; do ++ dev=$(grep 'sd[^a]$' /proc/partitions | awk '{ print $4 }') ++ if [ -n "$dev" ]; then ++ dest=/dev/$dev ++ break ++ fi ++ done ++ ++ sleep 2 ++ grep "^$dest" /proc/mounts | awk '{ print $1 }' | xargs -r umount ++ kill $wait_pid ++ ++ show_progress "Key found, writing image" ++ wait_pid=$! ++ ++ dd if=$source of=$dest bs=$dump_block_size ++ kill $wait_pid ++ if [ $? -ne 0 ]; then ++ show_error "Key dump failed" ++ exit 1 ++ fi ++ ++ #- more optimized write method, but harder to check ++ #dd if=$source of=$dest count=$mbr_size ++ #blockdev --rereadpt $dest ++ #mkdir -p /mnt/disk ++ #mount ${dest}1 /mnt/disk ++ #rsync -avP /mnt/loop /mnt/disk ++ #umount /mnt/disk ++ ++ show_progress "Key dumped, checking" ++ wait_pid=$! ++ sync ++ ++ dumped_md5=$((dd if=$dest bs=$dump_block_size count=$image_blocks; dd if=$dest bs=1 skip=$image_remainder_skip count=$image_remainder_bytes) | md5sum - | awk '{ print $1 }') ++ kill $wait_pid ++ ++ echo "md5: dumped = $dumped_md5" ++ echo "md5: source = $image_md5" ++ if [ "$dumped_md5" != "$image_md5" ]; then ++ show_error "Key has errors" ++ exit 1 ++ fi ++ show_wait "Key dumped and verified"$'\n'$'\n'"Please remove key" ++ wait_pid=$! ++ ++ while sleep 5; do ++ grep -q 'sd[^a]$' /proc/partitions || break ++ done ++ kill $wait_pid ++ echo "Key removed" ++done ++#umount /mnt/loop + + +Property changes on: draklive/trunk/write_flash.sh +___________________________________________________________________ +Added: svn:executable + + * +Added: svn:eol-style + + native + +</pre></div> + +</body> +</html>
\ No newline at end of file |