diff options
author | Will Woods <wwoods@redhat.com> | 2012-02-15 15:37:31 -0500 |
---|---|---|
committer | Will Woods <wwoods@redhat.com> | 2012-02-15 15:45:03 -0500 |
commit | 4e26256d931c41ed1469f456e4f05378d1f3a119 (patch) | |
tree | 3bbf85750a373fc94dbbcf2888651fcd465b332f | |
parent | 62a04d333268cbf117e8f1803b7f6e331961e688 (diff) | |
download | anaconda-4e26256d931c41ed1469f456e4f05378d1f3a119.tar.gz anaconda-4e26256d931c41ed1469f456e4f05378d1f3a119.tar.xz anaconda-4e26256d931c41ed1469f456e4f05378d1f3a119.zip |
Add anaconda dracut module [WIP!]
This adds the dracut directory and anaconda-dracut subpackage.
The 'anaconda' dracut module replaces loader. It should handle all the
tasks that loader used to handle in the first stage of the boot process.
It's a work in progress, but it currently supports repo={http,ftp,nfs}
and most anacaconda network options.
Kickstart parsing is handled using a python interpreter and pykickstart,
which (surprisingly) only adds ~600k to the initramfs.
Driver disks are not yet supported.
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | anaconda.spec.in | 19 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | dracut/Makefile.am | 35 | ||||
-rwxr-xr-x | dracut/anaconda-copy-ks.sh | 3 | ||||
-rwxr-xr-x | dracut/anaconda-hdroot | 22 | ||||
-rwxr-xr-x | dracut/anaconda-nfsroot | 24 | ||||
-rwxr-xr-x | dracut/fetch-kickstart | 44 | ||||
-rwxr-xr-x | dracut/module-setup.sh | 38 | ||||
-rwxr-xr-x | dracut/parse-anaconda-kickstart.sh | 63 | ||||
-rwxr-xr-x | dracut/parse-anaconda-options.sh | 94 | ||||
-rwxr-xr-x | dracut/parse-anaconda-repo.sh | 46 | ||||
-rwxr-xr-x | dracut/parse-kickstart | 192 | ||||
-rwxr-xr-x | dracut/pythondeps.sh | 32 | ||||
-rwxr-xr-x | dracut/repo-genrules.sh | 19 |
15 files changed, 633 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index b4a2d12f6..5f2113849 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,7 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = pyanaconda 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 b018a3aa3..03f6e1976 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 +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. This includes driver disks, kickstarts, and finding the anaconda +runtime on NFS/HTTP/FTP servers or local disks. + %prep %setup -q @@ -233,6 +248,10 @@ update-desktop-database &> /dev/null || : %{_datadir}/icons/hicolor/* %endif +%files dracut +%dir %{_datadir}/dracut/modules.d/80%{name} +%{_datadir}/dracut/modules.d/80%{name}/* + %changelog * Thu Feb 09 2012 Brian C. Lane <bcl@redhat.com> - 18.0-1 - Set ONBOOT=yes for FCoE devices (#755147) (rvykydal) diff --git a/configure.ac b/configure.ac index 0a814507f..ef182a23b 100644 --- a/configure.ac +++ b/configure.ac @@ -256,6 +256,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 000000000..152108de8 --- /dev/null +++ b/dracut/Makefile.am @@ -0,0 +1,35 @@ +# 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@redhat.com> + +dracutdir = $(datadir)/dracut/modules.d/80$(PACKAGE_NAME) +dist_dracut_DATA = module-setup.sh \ + pythondeps.sh \ + anaconda-lib.sh \ + parse-anaconda-options.sh \ + parse-anaconda-repo.sh \ + parse-anaconda-kickstart.sh \ + repo-genrules.sh \ + anaconda-nfsroot \ + anaconda-hdroot \ + anaconda-copy-ks.sh \ + fetch-kickstart \ + parse-kickstart + + +MAINTAINERCLEANFILES = Makefile.in diff --git a/dracut/anaconda-copy-ks.sh b/dracut/anaconda-copy-ks.sh new file mode 100755 index 000000000..86c2724a0 --- /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-hdroot b/dracut/anaconda-hdroot new file mode 100755 index 000000000..e96ab583a --- /dev/null +++ b/dracut/anaconda-hdroot @@ -0,0 +1,22 @@ +#!/bin/bash +# hdroot script for anaconda + +. /lib/anaconda-lib.sh + +[ -f /tmp/root.info ] && . /tmp/root.info + +dev="$1" +path="$2" +mount "$dev" "$repodir" || die "Couldn't mount $root" +img=$(find_runtime $repodir$path) +if [ -z "$img" ]; then + iso=$(check_isodir $repodir$path) + if [ -n "$iso" ]; then + mount --move $repodir $isodir + iso=${isodir}${iso#$repodir} + mount -o loop,ro $iso $repodir + img=$(find_runtime $repodir) + fi +fi +[ -e "$img" ] && exec /sbin/dmsquash-live-root $img +die "Couldn't find a suitable image or tree in $path on $dev diff --git a/dracut/anaconda-nfsroot b/dracut/anaconda-nfsroot new file mode 100755 index 000000000..68052d366 --- /dev/null +++ b/dracut/anaconda-nfsroot @@ -0,0 +1,24 @@ +#!/bin/bash +# nfsroot script for anaconda + +. /lib/nfs-lib.sh +. /lib/anaconda-lib.sh + +[ -f /tmp/root.info ] && . /tmp/root.info + +netif="$1" +netroot="${2#anaconda-nfs:}" +info "mounting installer repo $netroot" +mount_nfs "$netroot" "$repodir" "$netif" || warn "Couldn't mount $netroot" +img=$(find_runtime $repodir$path) +if [ -z "$img" ]; then + iso=$(check_isodir $repodir$path) + if [ -n "$iso" ]; then + mount --move $repodir $isodir + iso=${isodir}${iso#$repodir} + mount -o loop,ro $iso $repodir + img=$(find_runtime $repodir) + fi +fi +[ -e "$img" ] && exec /sbin/dmsquash-live-root $img +warn "Couldn't find a suitable image or tree in $netroot" diff --git a/dracut/fetch-kickstart b/dracut/fetch-kickstart new file mode 100755 index 000000000..8031f588b --- /dev/null +++ b/dracut/fetch-kickstart @@ -0,0 +1,44 @@ +#!/bin/bash +# fetch-kickstart - fetch kickstart file + +. /lib/url-lib.sh + +kickstart="$1" +outfile="$2" +ksdevice="$3" + +if [ "$kickstart" = "nfs:auto" ]; then + # construct kickstart URL from dhcp info + # server is next_server, or the dhcp server itself if missing + . /tmp/net.$ksdevice.dhcpopts + server="${new_dhcp_next_server:-$new_dhcp_server_identifier}" + # filename is dhcp 'filename' option, or '/kickstart/' if missing + filename="/kickstart/" + # read the dhcp lease file and see if we can find 'filename' + { while read line; do + val="${line#filename }" + if [ "$val" != "$line" ]; then + eval "filename=$val" # drop quoting and semicolon + fi + done + } < /tmp/net.$ksdevice.lease + # filename is appended with '$IP_ADDR-kickstart' if ending in '/' + if [ "${filename%/}" != "$filename" ]; then + filename="${filename}${new_ip_address}-kickstart" + fi + kickstart="nfs:$server:$filename" +fi + +case "$kickstart" in + http:*|https:*|ftp:*|nfs:*) fetch_url "$kickstart" /tmp/ks.cfg ;; + bd:*) warn "FIXME: inst.ks=bd:.. is not yet supported." ;; + hd:*) warn "FIXME: inst.ks=hd:.. is not yet supported." ;; + file:*) cp "${kickstart#file:}" /tmp/ks.cfg ;; + *) warn "Don't know how to handle kickstart path '$kickstart'"; exit;; +esac + +parse-kickstart /tmp/ks.cfg >> /etc/cmdline.d/80kickstart.conf +# FIXME: do driverdisk if needed +# FIXME: if there's updates to be fetched, add them to the list +# FIXME: figure out which network devices to ifup +# FIXME: if there's a repo, run the appropriate anaconda-*root or dmsquash diff --git a/dracut/module-setup.sh b/dracut/module-setup.sh new file mode 100755 index 000000000..6fdc54d55 --- /dev/null +++ b/dracut/module-setup.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# module-setup.sh for anaconda + +check() { + [[ $hostonly ]] && return 1 + return 255 # this module is optional +} + +depends() { + echo livenet nfs img-lib + return 0 +} + +install() { + # anaconda + inst "$moddir/anaconda-lib.sh" "/lib/anaconda-lib.sh" + inst_hook cmdline 25 "$moddir/parse-anaconda-options.sh" + inst_hook cmdline 26 "$moddir/parse-anaconda-kickstart.sh" + inst_hook cmdline 27 "$moddir/parse-anaconda-repo.sh" + inst_hook pre-udev 40 "$moddir/repo-genrules.sh" + inst "$moddir/anaconda-nfsroot" "/sbin/anaconda-nfsroot" + inst "$moddir/anaconda-hdroot" "/sbin/anaconda-hdroot" + inst_hook pre-pivot 99 "$moddir/anaconda-copy-ks.sh" + # binaries we need sometimes + dracut_install -o dmidecode + # kickstart parsing, WOOOO + inst "$moddir/fetch-kickstart" "/sbin/fetch-kickstart" + inst "$moddir/parse-kickstart" "/sbin/parse-kickstart" + # python deps for parse-kickstart. DOUBLE WOOOO + $moddir/pythondeps.sh $moddir/parse-kickstart | while read dep; do + case "$dep" in + *.so) inst_library $dep ;; + *.py) inst_simple $dep ;; + *) inst $dep ;; + esac + done +} + diff --git a/dracut/parse-anaconda-kickstart.sh b/dracut/parse-anaconda-kickstart.sh new file mode 100755 index 000000000..916f49c80 --- /dev/null +++ b/dracut/parse-anaconda-kickstart.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# parse-kickstart-options.sh: check to see if we need to get a kickstart + +warn_renamed_arg "ks" "inst.ks" + +kickstart="$(getarg ks= inst.ks=)" +if [ -z "$kickstart" ]; then + getargbool 0 ks inst.ks && kickstart='nfs:auto' +fi + +ksdev="$(getarg ksdevice= inst.ks.dev= inst.ks.device=)" + +warn_renamed_arg "kssendmac" "inst.ks.sendmac" +if getargbool 0 kssendmac inst.ks.sendmac; then + ifnum=0 + for ifname in /sys/class/net/*; do + mac=$(cat $ifname/address) + ifname=${ifname#/sys/class/net/} + # TODO: might need to choose devices better + if [ "$ifname" != "lo" ] && [ -n "$mac" ]; then + set_http_header "X-RHN-Provisioning-MAC-$ifnum" "$ifname $mac" + ifnum=$(($ifnum+1)) + fi + done +fi + +warn_renamed_arg "kssendsn" "inst.ks.sendsn" +if getargbool 0 kssendsn inst.ks.sendsn; then + if ! command -v dmidecode; then + warn "inst.ks.sendsn: can't find serial number (dmidecode missing)" + else + system_serial=$(dmidecode -s system-serial-number) + set_http_header "X-System-Serial-Number" "$system_serial" + fi +fi + +splitsep ":" "$kickstart" kstype ksdev ksfile +case "$kstype" in + file|path) + # It's already here! Parse away! + if [ "$kstype" = "path" ]; then + warn "inst.ks='$kickstart'" + warn "'path:...' is deprecated; please use 'file:...' instead" + fi + ksfile=ksdev + if [ -f "$ksfile" ]; then + /sbin/parse-kickstart $ksfile >> /etc/cmdline.d/80kickstart.conf + else + warn "inst.ks='$kickstart': can't find $ksfile!" + fi + ;; + cdrom|hd) + # FIXME: mount and parse-kickstart once dev appears + ;; + http|https|ftp|nfs|nfs4) + [ -z "$netroot" ] && netroot="skip" + # FIXME: schedule fetch-kickstart when network dev comes up + ;; + bd) warn "can't get kickstart: biospart isn't supported yet." ;; +esac + +# no root? the kickstart will probably tell us what our root device is. Onward! +[ "$kickstart" ] && [ -z "$root" ] && root="kickstart" && rootok=1 diff --git a/dracut/parse-anaconda-options.sh b/dracut/parse-anaconda-options.sh new file mode 100755 index 000000000..2d9c424d7 --- /dev/null +++ b/dracut/parse-anaconda-options.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# parse-anaconda-options.sh - parse installer-specific options + +. /lib/anaconda-lib.sh +. /lib/url-lib.sh + +# THIS! IS! ANACONDA!!! +udevproperty ANACONDA=1 +# (used in udev rules to keep stuff like mdadm, multipath, etc. out of our way) + +# create the repodir and isodir that anaconda will look for +mkdir -p $repodir $isodir + +# get some info from .buildstamp +if [ ! -f /.buildstamp ]; then + warn ".buildstamp missing" +else + product=$(config_get Main Product < /.buildstamp) + version=$(config_get Main Version < /.buildstamp) + # TODO: this is silly. There should be an "Arch" item in there.. + uuid=$(config_get Main UUID < /.buildstamp) + strstr "$uuid" "." && arch=${uuid##*.} +fi +[ -z "$arch" ] && arch=$(uname -m) + +# set HTTP headers so server(s) will recognize us +set_http_header "X-Anaconda-Architecture" "$arch" +set_http_header "X-Anaconda-System-Release" "$product" + +# convenience function to warn the user about old argument names. +warn_renamed_arg() { + local arg="" + arg="$(getarg $1)" && warn "'$1=$arg'" && warn "$1 has been renamed to $2" +} + +# check for deprecated arg, warn user, and write new arg to /etc/cmdline +check_depr_arg() { + local arg="" quiet="" newval="" + if [ "$1" == "--quiet" ]; then quiet=1; shift; fi + arg="$(getarg $1)" + [ "$arg" ] || return 1 + newval=$(printf "$2" "$arg") + [ "$quiet" ] || warn "'$1' is deprecated. Using '$newval' instead." + echo "$newval" >> /etc/cmdline.d/75anaconda-options.conf +} +check_depr_args() { + local q="" + for i in $(getargs $1); do check_depr_arg $q "$i" "$2" && q="--quiet"; done +} + +check_depr_arg "serial" "console=ttyS0" +check_depr_arg "stage2=" "root=live:%s" +check_depr_args "blacklist=" "inst.blacklist=%s" +check_depr_arg "nofirewire" "inst.blacklist=firewire_ohci" + +# USB is built-in and can't be disabled anymore. DEAL WITH IT. +getarg nousb && warn "'nousb' is deprecated. USB drivers can't be disabled." +getarg ethtool && warn "'ethtool' is deprecated and has been removed." + +# interactive junk in initramfs +# (maybe we'll bring it back someday?) +getarg askmethod && warn "'askmethod' is deprecated and has been removed." && \ + warn "Use an appropriate 'inst.repo=' argument instead." +getarg asknetwork && warn "'asknetwork' is deprecated and has been removed." &&\ + warn "Use an appropriate 'ip=' argument instead." + +check_depr_arg "lang=" "locale.LANG=%s" +check_depr_arg "keymap=" "vconsole.keymap=%s" + +# FIXME: if we have ksdevice or multiple ip lines, we'll need interface names +check_depr_arg "dns" "nameserver=%s" +check_depr_arg "ipv6=auto" "ip=auto6" +check_depr_arg "ipv6=dhcp" "ip=dhcp6" +check_depr_arg "ipv6=" "ip=[%s]" # XXX is this right? + +check_depr_ip_args() { + local ip="$(getarg ip=)" + [ -z "$ip" ] && return # no ip? no problem + [ "$ip" = "dhcp" ] && return # this is fine as-is + strstr "$ip" ":" && return # PXE/dracut style. this is also fine. + + local nm="$(getarg netmask=)" gw="$(getarg gateway=)" fail="" + [ -z "$gw" ] && warn "ip=<ip> missing gateway=<gw>!" && fail="yes" + [ -z "$nm" ] && warn "ip=<ip> missing netmask=<nm>!" && fail="yes" + [ "$fail" ] && return + warn "'ip=<ip> gateway=<gw> netmask=<nm>' is deprecated." + warn "Use 'ip=<ip>::<gw>:<nm>' instead." + strstr "$gw" ":" && gw="[$gw]" # ipv6 addr (XXX: did anaconda allow this?) + echo "ip=$ip::$gw:$nm" >> /etc/cmdline.d/75anaconda-options.conf +} +check_depr_ip_args + +# re-read the commandline args +unset CMDLINE diff --git a/dracut/parse-anaconda-repo.sh b/dracut/parse-anaconda-repo.sh new file mode 100755 index 000000000..0155dbfe3 --- /dev/null +++ b/dracut/parse-anaconda-repo.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# parse-repo-options.sh: parse the repo= arg (and set root=) + +check_depr_arg "method=" "inst.repo=%s" +warn_renamed_arg "repo" "inst.repo" +unset CMDLINE + +repo="$(getarg repo= inst.repo=)" + +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 +} + +case "$repo" in + "") ;; # no repo, no action needed + cdrom:*) + root="live:${repo#cdrom:}" ;; + http:*|https:*|ftp:*) + treeinfo=$(fetch_url $repo/.treeinfo) && \ + stage2=$(config_get stage2 mainimage < $treeinfo) + root="live:$repo/${stage2:-images/install.img}" ;; + nfs:*|nfsiso:*) + root="anaconda-nfs" # root must be set + repo=nfs:${repo#nfs*:} + netroot="anaconda-nfs:$repo" + wait_for_dev /dev/root ;; + hd:*) + splitsep ":" "$repo" f dev path + root="anaconda.hdiso:$(resolve_disk $dev):$path" ;; + *) + warn "Invalid value for 'inst.repo': $repo" + [ -z "$root" ] && warn "No root= arg either! Will look for media.." ;; +esac + +if [ -z "$root" ]; then + # FIXME: script to watch for valid installer media + root=live:/dev/sr0 +fi + +# okay we've got some kind of root thingy to deal with. onward! +rootok=1 diff --git a/dracut/parse-kickstart b/dracut/parse-kickstart new file mode 100755 index 000000000..af2229769 --- /dev/null +++ b/dracut/parse-kickstart @@ -0,0 +1,192 @@ +#!/usr/bin/python +#vim: set fileencoding=utf8 +# parse-kickstart - read a kickstart file and emit equivalent dracut boot args. +# +# Copyright © 2012 Red Hat, Inc. +# BLAH BLAH GPL BLAH. +# +# Designed to run inside the dracut initramfs environment. +# Requires python 2.7 or later. +# +# Authors: +# Will Woods <wwoods@redhat.com> + +import sys, os +import logging +from pykickstart.parser import KickstartParser, preprocessKickstart +from pykickstart.version import returnClassForVersion +from pykickstart.errors import KickstartParseError +from pykickstart.constants import * +from pykickstart import commands +from collections import OrderedDict + +# Default logging: none +log = logging.getLogger('parse-kickstart').addHandler(logging.NullHandler()) + +# Here are the kickstart commands we care about: + +class Method(commands.method.F14_Method): + '''install methods: cdrom, harddrive, nfs, url''' + def dracut_args(self, args, lineno, obj): + if self.method == "cdrom": + method="/dev/sr0" + elif self.method == "harddrive": + if self.biospart: + dev = biospart_to_dev(self.biospart, args, lineno) + if dev: + method="hd:%s:%s" % (dev, self.dir) + method="hd:%s:%s" % (self.partition, self.dir) + elif self.method == "nfs": + method="nfs:%s:%s" % (self.server, self.dir) + if self.opts: + method += ":%s" % opts + elif self.method == "url": + # FIXME: self.proxy, self.noverifyssl + method = self.url + return "inst.repo=%s" % method + +class Updates(commands.updates.F7_Updates): + def dracut_args(self, args, lineno, obj): + if self.url == "floppy": + return "inst.updates=/dev/fd0" + elif self.url: + return "inst.updates=%s" % self.url + +class MediaCheck(commands.mediacheck.FC4_MediaCheck): + def dracut_args(self, args, lineno, obj): + if self.mediacheck: + return "rd.live.check" + +class DriverDisk(commands.driverdisk.F14_DriverDisk): + def dracut_args(self, args, lineno, obj): + dd = self.driverdiskList[-1] + if dd.biospart: + location = biospart_to_dev(dd.biospart, args, lineno) + else: + location = dd.partition or dd.source + if location: + return "inst.driverdisk=%s" % location + +class Network(commands.network.F16_Network): + def dracut_args(self, args, lineno, net): + if len(self.network) == 1: # first network line gets special treatment + net.activate = True # activate by default + if not net.device: # --device is optional, defaults to.. + net.device = "ksdev" # whatever the kickstart device was + if not net.device: + log.error("'%s': missing --device", " ".join(args)) + elif net.activate: # we only care about activated devices + return ksnet_to_dracut(args, lineno, net) + +# TODO: keymap, lang... device? upgrade? + +dracutCmds = { + 'cdrom': Method, + 'harddrive': Method, + 'nfs': Method, + 'url': Method, + 'updates': Updates, + 'mediacheck': MediaCheck, + 'driverdisk': DriverDisk, + 'network': Network, +} +handlerclass = returnClassForVersion() +class DracutHandler(handlerclass): + def __init__(self): + handlerclass.__init__(self, commandUpdates=dracutCmds) + self.output = [] + def dispatcher(self, args, lineno): + obj = handlerclass.dispatcher(self, args, lineno) + # and execute any specified dracut_args + cmd = args[0] + command = self.commands[cmd] + if hasattr(command, "dracut_args"): + log.debug("kickstart line %u: handling %s", lineno, cmd) + line = " ".join(args) + self.output.append(command.dracut_args(args, lineno, obj)) + return obj + +# set up logging +class KmsgFormatter(logging.Formatter): + '''Formats log output for /dev/kmsg like dracut does.''' + def format(self, record): + if record.levelno <= logging.INFO: tag = "<30>" + elif record.levelno <= logging.WARNING: tag = "<28>" + else: tag = "<24>" + return tag + logging.Formatter.format(self, record) +def init_logger(): + logfmt = "%(name)s %(levelname)s: %(message)s" + stderr = logging.StreamHandler() + stderr.setFormatter(logging.Formatter(logfmt)) + logger = logging.getLogger('parse-kickstart') + logger.setLevel(logging.WARNING) + logger.addHandler(stderr) + try: + kmsg = logging.FileHandler("/dev/kmsg", "w") + kmsg.setFormatter(KmsgFormatter(logfmt)) + logger.addHandler(kmsg) + except IOError: + pass + return logger + +def biospart_to_dev(biospart, args, lineno): + if not os.path.isdir("/sys/firmware/edd"): + log.error("'%s': --biospart unavailable (no EDD support)", " ".join(args)) + return + log.error("'%s': biospart is not yet supported", " ".join(args), lineno) + +def ksnet_to_dracut(args, lineno, net): + '''Translate the kickstart network data into dracut network data.''' + line = [] + dev = net.device + if net.bootProto == BOOTPROTO_DHCP: + line.append("ip=%s:dhcp" % dev if dev else "ip=dhcp") + elif net.bootProto == BOOTPROTO_IBFT: + line.append("ip=%s:ibft" % dev if dev else "ip=ibft") + elif net.bootProto == BOOTPROTO_BOOTP: # NOTE: no dracut support yet... + line.append("ip=%s:bootp" % dev if dev else "ip=bootp") + elif net.bootProto == BOOTPROTO_QUERY: + log.error("'%s': --bootproto=query is deprecated", " ".join(args)) + elif net.bootProto == BOOTPROTO_STATIC: + req = ("gateway", "netmask", "nameserver", "ip") + missing = ", ".join("--%s" % i for i in req if not hasattr(net, i)) + if missing: + log.warn("line %u: network missing %s", lineno, missing) + else: + line.append("ip={0.ip}::{0.gateway}:{0.netmask}:" \ + "{0.hostname}:{0.device}".format(net)) + for ns in net.nameserver.split(","): + line.append("nameserver=%s" % ns) + if net.ipv6 == "auto": + line.append("ip=%s:auto6" % dev if dev else "ip=auto6") + elif net.ipv6 == "dhcp": + line.append("ip=%s:dhcp6" % dev if dev else "ip=dhcp6") + elif net.ipv6: + line.append("ip=[{0.ipv6}]::{0.gateway}:{0.netmask}:" \ + "{0.hostname}:{0.device}".format(net)) + if net.mtu: + # XXX NOTE: dracut doesn't support mtu= (yet) so this arg might change + mtuarg = "mtu=%s:" % dev if dev else "mtu=" + line.append(mtustr+str(mtu)) + # TODO FIXME: nodns, nodefroute, noipv4, noipv6, dhcpclass, ethtool + if net.essid or net.wepkey or net.wpakey: + # TODO: make dracut support wireless? (do we care?) + log.error("'%s': dracut doesn't support wireless networks", " ".join(args)) + return " ".join(line) + +def process_kickstart(ksfile): + handler = DracutHandler() + parser = KickstartParser(handler) + processed_file = preprocessKickstart(ksfile) + try: + parser.readKickstart(processed_file) + except KickstartParseError as e: + log.error(str(e)) + return handler.output + +if __name__ == '__main__': + log = init_logger() + for path in sys.argv[1:]: + output = process_kickstart(path) + for line in filter(None, output): + print line diff --git a/dracut/pythondeps.sh b/dracut/pythondeps.sh new file mode 100755 index 000000000..2f7b06fc2 --- /dev/null +++ b/dracut/pythondeps.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +python="python" + +eval $($python << _EOT_ +from distutils.sysconfig import * +print 'makefile=' + get_makefile_filename() +print 'config_h=' + get_config_h_filename() +print 'sitedir=' + get_python_lib() +_EOT_ +) +libdir=${makefile%/config/Makefile} + +pydeps() { + echo $makefile + echo $config_h + while [ $# -gt 0 ]; do + $python -v $1 2>&1 | sed -ne 's/^import.* from //p' + shift + done +} + +# basedir /path/top/module/sub/filename.py /path/top -> /path/top/module +basedir() { mod=${1#$2/}; mod=${mod%%/*}; echo $2/$mod; } + +pydeps "$@" | sed 's/\.py[coO]$/.py/' | sort -u | while read dep; do + case "$dep" in + $sitedir/*/*.py) find "$(basedir $dep $sitedir)" -type f ;; + $libdir/*/*.py) find "$(basedir $dep $libdir)" -type f ;; + *) echo $dep ;; + esac +done | grep -v '\.py[coO]' | sort -u diff --git a/dracut/repo-genrules.sh b/dracut/repo-genrules.sh new file mode 100755 index 000000000..50fe3f988 --- /dev/null +++ b/dracut/repo-genrules.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +when_dev_appears() { + local dev="${1#/dev/}"; shift + { + printf 'KERNEL=="%s", ' "$dev" + printf 'RUN="/sbin/initqueue --settled --onetime --unique %s"\n' "$*" + printf 'SYMLINK=="%s", ' "$dev" + printf 'RUN="/sbin/initqueue --settled --onetime --unique %s"\n' "$*" + } >> /etc/udev/rules.d/99-anaconda.rules + wait_for_dev "$dev" +} + +splitsep ":" "$root" repotype dev path + +if [ "$repotype" = "anaconda.hdiso" ]; then + when_dev_appears "$dev" "/sbin/anaconda-hdroot $dev $path" + wait_for_mount $repodir +fi |