From: "Brian C. Lane" <bcl@xxxxxxxxxx> This installs anaconda specific scripts used by dracut. Currently it adds the rd.luks=0 rd.md=0 rd.dm=0 rd.lvm=0 commandline arguments so that they don't need to be specified on the kernel cmdline. It also copies kickstart files from the inird over to the sysroot. Copied from noloader branch and removed unneeded scripts. --- Makefile.am | 2 +- anaconda.spec.in | 19 +++++ configure.ac | 1 + dracut/Makefile.am | 27 +++++++ dracut/anaconda-copy-ks.sh | 3 + dracut/anaconda-lib.sh | 145 ++++++++++++++++++++++++++++++++++++++ dracut/module-setup.sh | 20 +++++ dracut/parse-anaconda-options.sh | 19 +++++ dracut/python-deps | 56 +++++++++++++++ 9 files changed, 291 insertions(+), 1 deletions(-) create mode 100644 dracut/Makefile.am create mode 100755 dracut/anaconda-copy-ks.sh create mode 100755 dracut/anaconda-lib.sh create mode 100755 dracut/module-setup.sh create mode 100755 dracut/parse-anaconda-options.sh create mode 100755 dracut/python-deps diff --git a/Makefile.am b/Makefile.am index 34c3c20..5ddc4f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,7 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = pyanaconda loader gptsync po data \ - tests utils scripts docs + tests utils scripts docs dracut EXTRA_DIST = config.rpath COPYING \ anaconda.spec.in diff --git a/anaconda.spec.in b/anaconda.spec.in index 7a2f0cd..f28fbe4 100644 --- a/anaconda.spec.in +++ b/anaconda.spec.in @@ -169,6 +169,21 @@ Obsoletes: booty The anaconda package contains the program which was used to install your system. +%package dracut +Summary: The anaconda dracut module +BuildArch: noarch +Requires: dracut >= 16 +Requires: dracut-network +Requires: xz +Requires: pykickstart +%ifarch %{ix86} x86_64 +Requires: dmidecode +%endif + +%description dracut +The 'anaconda' dracut module handles installer-specific boot tasks and +options. + %prep %setup -q @@ -235,6 +250,10 @@ update-desktop-database &> /dev/null || : %{_datadir}/icons/hicolor/* %endif +%files dracut +%dir /usr/lib/dracut/modules.d/80%{name} +/usr/lib/dracut/modules.d/80%{name}/* + %changelog * Tue Mar 06 2012 Brian C. Lane <bcl@xxxxxxxxxx> - 17.12-1 - only allow GPT boot flag on EFI System partition (#746895) (bcl) diff --git a/configure.ac b/configure.ac index 740b87a..1e7f8ad 100644 --- a/configure.ac +++ b/configure.ac @@ -257,6 +257,7 @@ AC_CONFIG_FILES([Makefile data/bootdisk/x86_64/Makefile data/command-stubs/Makefile docs/Makefile + dracut/Makefile gptsync/Makefile pyanaconda/installclasses/Makefile pyanaconda/iw/Makefile diff --git a/dracut/Makefile.am b/dracut/Makefile.am new file mode 100644 index 0000000..3821912 --- /dev/null +++ b/dracut/Makefile.am @@ -0,0 +1,27 @@ +# dracut/Makefile.am for anaconda +# +# Copyright (C) 2012 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; either version 2.1 of the License, 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author: Will Woods <wwoods@xxxxxxxxxx> + +dracutdir = /usr/lib/dracut/modules.d/80$(PACKAGE_NAME) +dist_dracut_SCRIPTS = module-setup.sh \ + python-deps \ + anaconda-lib.sh \ + parse-anaconda-options.sh \ + anaconda-copy-ks.sh + +MAINTAINERCLEANFILES = Makefile.in diff --git a/dracut/anaconda-copy-ks.sh b/dracut/anaconda-copy-ks.sh new file mode 100755 index 0000000..86c2724 --- /dev/null +++ b/dracut/anaconda-copy-ks.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# Copy over kickstart files from the initrd to the sysroot before pivot +cp /*cfg /*ks /sysroot/ 2> /dev/null diff --git a/dracut/anaconda-lib.sh b/dracut/anaconda-lib.sh new file mode 100755 index 0000000..cdb1356 --- /dev/null +++ b/dracut/anaconda-lib.sh @@ -0,0 +1,145 @@ +#!/bin/bash + +# config_get SECTION KEY < FILE +# read an .ini-style config file, find the KEY in the given SECTION, and return +# the value provided for that key. +# ex: product=$(config_get Main Product < /.buildstamp) +config_get() { + local section="$1" key="$2" cursec="" k="" v="" + while read line; do + case "$line" in + \#*) continue ;; + \[*\]*) cursec="${line#[}"; cursec="${cursec%%]*}" ;; + *=*) k=$(echo ${line%%=*}); v=$(echo ${line#*=}) ;; + esac + if [ "$cursec" = "$section" ] && [ "$k" == "$key" ]; then + echo $v + break + fi + done +} + +find_iso() { + local f="" iso="" isodir="$1" tmpmnt=$(mkuniqdir /run/install tmpmnt) + for f in $isodir/*.iso; do + [ -e $f ] || continue + mount -o loop,ro $f $tmpmnt || continue + [ -e $tmpmnt/.discinfo ] && iso=$f + umount $tmpmnt + if [ "$iso" ]; then echo "$iso"; return 0; fi + done + return 1 +} + +find_runtime() { + local ti_img="" dir="$1$2" + [ -e $dir/.treeinfo ] && img=$(config_get stage2 mainimage < $dir/.treeinfo) + for f in $ti_img images/install.img LiveOS/squashfs.img; do + [ -e "$dir/$f" ] && echo "$dir/$f" && return + done +} + +repodir="/run/install/repo" +isodir="/run/install/isodir" +rulesfile="/etc/udev/rules.d/90-anaconda.rules" + +anaconda_live_root_dir() { + local img="" iso="" dir="$1" path="$2"; shift 2 + img=$(find_runtime $repodir$path) + if [ -n "$img" ]; then + info "anaconda: found $img" + else + iso=$(find_iso $repodir$path) + [ -n "$iso" ] || { warn "no suitable images"; return 1; } + info "anaconda: found $iso" + mount --move $repodir $isodir + iso=${isodir}${iso#$repodir} + mount -o loop,ro $iso $repodir + img=$(find_runtime $repodir) || { warn "$iso has no suitable runtime"; } + fi + [ -e "$img" ] && /sbin/dmsquash-live-root $img +} + +# These could probably be in dracut-lib or similar + +disk_to_dev_path() { + case "$1" in + CDLABEL=*|LABEL=*) echo "/dev/disk/by-label/${1#*LABEL=}" ;; + UUID=*) echo "/dev/disk/by-uuid/${1#UUID=}" ;; + /dev/*) echo "$1" ;; + *) echo "/dev/$1" ;; + esac +} + +when_diskdev_appears() { + local dev="${1#/dev/}" cmd=""; shift + cmd="/sbin/initqueue --settled --onetime $*" + { + printf 'SUBSYSTEM=="block", KERNEL=="%s", RUN+="%s"\n' "$dev" "$cmd" + printf 'SUBSYSTEM=="block", SYMLINK=="%s", RUN+="%s"\n' "$dev" "$cmd" + } >> $rulesfile +} + +set_neednet() { + if ! getargbool 0 rd.neednet; then + echo "rd.neednet=1" >> /etc/cmdline.d/anaconda-neednet.conf + fi + unset CMDLINE +} + +when_netdev_online() { + printf 'SUBSYSTEM=="net", ACTION=="online", RUN+="%s"\n' \ + "/sbin/initqueue --settled --onetime $@" >> $rulesfile +} + +# Kickstart parsing goes at the end 'cuz it might use the other stuff + +parse_kickstart() { + /sbin/parse-kickstart $1 > /etc/cmdline.d/80kickstart.conf + unset CMDLINE # re-read the commandline + . /tmp/ks.info # save the parsed kickstart + [ -e "$parsed_kickstart" ] && cp $parsed_kickstart /run/install/ks.cfg +} + +# This is where we actually run the kickstart. Whee! +# We can't just add udev rules (we'll miss devices that are already active), +# and we can't just run the scripts manually (we'll miss devices that aren't +# yet active - think driver disks!). +# +# So: we have to write out the rules and then retrigger them. +# +# Really what we want to do here is just start over from the "cmdline" +# phase, but since we can't do that, we'll kind of fake it. +run_kickstart() { + local triggers="" do_repo="" # TODO: do_dd, do_updates, any others? + + # figure out what to re-run + grep -q 'inst\.repo=' /etc/cmdline.d/80kickstart.conf && do_repo=1 + + # parse cmdline + source_hook cmdline + + # NOTE: this is deprecated and unnecessary in dracut 018 + [ -f /tmp/root.info ] && echo "root='$root'" >> /tmp/root.info + + # replay udev events to trigger actions + if [ $do_repo ]; then + case "$repotype" in + http*|ftp|nfs*) + udevadm trigger --action=online --subsystem-match=net + ;; + cdrom|hd|bd) + . $hookdir/pre-udev/*repo-genrules.sh + udevadm control --reload + udevadm trigger --action=change --subsystem-match=block + ;; + esac + fi + + # and that's it - we're back to the mainloop. + > /tmp/ks.cfg.done # let wait_for_kickstart know that we're done. +} + +wait_for_kickstart() { + echo "[ -e /tmp/ks.cfg.done ]" > $hookdir/initqueue/finished/kickstart.sh +} diff --git a/dracut/module-setup.sh b/dracut/module-setup.sh new file mode 100755 index 0000000..9cce3f4 --- /dev/null +++ b/dracut/module-setup.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# module-setup.sh for anaconda + +check() { + [[ $hostonly ]] && return 1 + return 255 # this module is optional +} + +depends() { + echo livenet nfs img-lib convertfs ifcfg + return 0 +} + +install() { + # anaconda + inst "$moddir/anaconda-lib.sh" "/lib/anaconda-lib.sh" + inst_hook cmdline 25 "$moddir/parse-anaconda-options.sh" + inst_hook pre-pivot 99 "$moddir/anaconda-copy-ks.sh" +} + diff --git a/dracut/parse-anaconda-options.sh b/dracut/parse-anaconda-options.sh new file mode 100755 index 0000000..7634377 --- /dev/null +++ b/dracut/parse-anaconda-options.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# parse-anaconda-options.sh - parse installer-specific options + +. /lib/anaconda-lib.sh + +# NOTE: anaconda historically activated all the fancy disk devices itself, +# and it would get very confused if they were already active when it started. +# F17 has some support for handling already-active devices, but it's still +# currently safer to disable these things and let anaconda activate them. +# TODO FIXME: remove this and make anaconda handle active devices! +{ + for t in dm md lvm luks; do + # disable unless specifically enabled + getargbool 0 rd.$t || echo rd.$t=0 + done +} > /etc/cmdline.d/99-anaconda-disable-disk-activation.conf + +# re-read the commandline args +unset CMDLINE diff --git a/dracut/python-deps b/dracut/python-deps new file mode 100755 index 0000000..be51e78 --- /dev/null +++ b/dracut/python-deps @@ -0,0 +1,56 @@ +#!/usr/bin/python +# python-deps - find the dependencies of a given python script. + +import os, sys +from modulefinder import ModuleFinder +from distutils.sysconfig import * + +sitedir = get_python_lib() +libdir = get_config_var('LIBDEST') + +# A couple helper functions... +def moduledir(pyfile): + '''Given a python file, return the module dir it belongs to, or None.''' + for topdir in sitedir, libdir: + relpath = os.path.relpath(pyfile, topdir) + if '/' not in relpath: continue + modname = relpath.split('/')[0] + if modname not in ('..', 'site-packages'): + return os.path.join(topdir, modname) + +def pyfiles(moddir): + '''basically, "find $moddir -type f -name "*.py"''' + for curdir, dirs, files in os.walk(moddir): + for f in files: + if f.endswith(".py"): + yield os.path.join(curdir, f) + +# OK. Use modulefinder to find all the modules etc. this script uses! + +finder = ModuleFinder() +finder.run_script(sys.argv[1]) # parse the script + +mods = [] +deps = [] + +for name, mod in finder.modules.iteritems(): + if not mod.__file__: # this module is builtin, so we can skip it + continue + + if mod.__file__ not in deps: # grab the file itself + deps.append(mod.__file__) + + moddir = moduledir(mod.__file__) # if it's part of a module... + if moddir and moddir not in mods: # + deps += list(pyfiles(moddir)) # ...get the whole module + mods.append(moddir) + +# Include some bits that the python install itself needs +print get_makefile_filename() +print get_config_h_filename() +print os.path.join(libdir,'site.py') +print os.path.join(libdir,'sysconfig.py') + +# And print the list of deps. +for d in deps: + print d -- 1.7.7.6 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list