Add a systemd-generator script that puts anaconda on the correct console tty, then puts shells on tty2 and the first virtualization console (unless we're using it for anaconda).
Adding "TTYPath" to the systemd services means systemd takes care of setting up all the terminal stuff - picking the right TERM value, setting the keyboard mode to K_UNICODE, and all that esoteric weirdness.
Also, move anaconda's dependencies into anaconda.target, and make anaconda start *after* anaconda.target, just so we can be sure that e.g. NetworkManager is active before anaconda starts.
(as a bonus, it also shuts off plymouth correctly, just in case we ever want to have a anaconda-specific bootsplash) --- anaconda.spec.in | 1 + data/systemd/Makefile.am | 4 +++- data/systemd/anaconda-generator | 34 ++++++++++++++++++++++++++++++++++ data/systemd/anaconda-shell@.service | 5 ++--- data/systemd/anaconda.service | 13 ------------- data/systemd/anaconda.target | 12 ++++++++---- data/systemd/anaconda@.service | 13 +++++++++++++ 7 files changed, 61 insertions(+), 21 deletions(-) create mode 100755 data/systemd/anaconda-generator delete mode 100644 data/systemd/anaconda.service create mode 100644 data/systemd/anaconda@.service
diff --git a/anaconda.spec.in b/anaconda.spec.in index 31ea1e2..84882c2 100644 --- a/anaconda.spec.in +++ b/anaconda.spec.in @@ -225,6 +225,7 @@ update-desktop-database &> /dev/null || : %doc docs/install-methods.txt %doc docs/mediacheck.txt /lib/systemd/system/* +/lib/systemd/system-generators/* /lib/udev/rules.d/70-anaconda.rules %{_bindir}/instperf %{_sbindir}/anaconda diff --git a/data/systemd/Makefile.am b/data/systemd/Makefile.am index 589854c..ae89c18 100644 --- a/data/systemd/Makefile.am +++ b/data/systemd/Makefile.am @@ -18,5 +18,7 @@ # Author: Chris Lumens clumens@redhat.com
systemddir = /lib/systemd/system -dist_systemd_DATA = anaconda-shell@.service anaconda.target anaconda.service instperf.service +generatordir = /lib/systemd/system-generators +dist_systemd_DATA = anaconda-shell@.service anaconda.target anaconda@.service instperf.service +dist_generator_SCRIPTS = anaconda-generator MAINTAINERCLEANFILES = Makefile.in diff --git a/data/systemd/anaconda-generator b/data/systemd/anaconda-generator new file mode 100755 index 0000000..6545572 --- /dev/null +++ b/data/systemd/anaconda-generator @@ -0,0 +1,34 @@ +#!/bin/bash +# anaconda-generator: generate services needed for anaconda operation + +# set up dirs +systemd_dir=/lib/systemd/system +target_dir=$systemd_dir/anaconda.target.wants +mkdir -p $target_dir + +# create symlink anaconda.target.wants/SERVICE@TTY.service +service_on_tty() { + local service="$1" tty="$2" + local service_instance="${service/@.service/@$tty.service}" + ln -sf $systemd_dir/$service $target_dir/$service_instance +} + +# find the real tty for /dev/console +tty="console" +while [ -f /sys/class/tty/$tty/active ]; do + tty=$(< /sys/class/tty/$tty/active) + tty=${tty##* } # last item in the list +done +consoletty="$tty" + +# put anaconda on the real console +service_on_tty anaconda@.service $consoletty + +# put a shell on tty2 and the first virtualization console we find +for tty in tty2 hvc0 hvc1 xvc0 hvsi0 hvsi1 hvsi2; do + [ "$tty" = "$consoletty" ] && continue + if [ -d /sys/class/tty/$tty ]; then + service_on_tty anaconda-shell@.service $tty + [ "$tty" != "tty2" ] && break + fi +done diff --git a/data/systemd/anaconda-shell@.service b/data/systemd/anaconda-shell@.service index ad2141e..52bed74 100644 --- a/data/systemd/anaconda-shell@.service +++ b/data/systemd/anaconda-shell@.service @@ -6,14 +6,13 @@ BindTo=dev-%i.device After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service
[Service] -Environment=TERM=linux WorkingDirectory=/ ExecStart=-/sbin/agetty -n -l /bin/bash -o '--login' %I 38400 Restart=always RestartSec=0 -TimeoutSec=0 -TTYPath=/dev/%i +TTYPath=/dev/%I TTYReset=yes TTYVHangup=yes TTYVTDisallocate=yes +KillMode=process KillSignal=SIGHUP diff --git a/data/systemd/anaconda.service b/data/systemd/anaconda.service deleted file mode 100644 index 45061cc..0000000 --- a/data/systemd/anaconda.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=the anaconda installation program -Wants=instperf.service rsyslog.service udev-settle.service NetworkManager.service -After=instperf.service rsyslog.service udev-settle.service NetworkManager.service - -[Service] -Environment=HOME=/root MALLOC_CHECK_=2 MALLOC_PERTURB_=204 PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin PYTHONPATH=/tmp/updates -Type=oneshot -WorkingDirectory=/root -ExecStart=/usr/sbin/anaconda -StandardInput=tty-force -TTYReset=yes -TimeoutSec=0 diff --git a/data/systemd/anaconda.target b/data/systemd/anaconda.target index 9f7f3be..983ff3b 100644 --- a/data/systemd/anaconda.target +++ b/data/systemd/anaconda.target @@ -1,7 +1,11 @@ [Unit] -Description=The anaconda installation program +Description=Anaconda System Services Requires=basic.target -Conflicts=rescue.service rescue.target -After=basic.target rescue.service rescue.target +After=basic.target AllowIsolate=yes -Wants=anaconda.service anaconda-shell@tty2.service anaconda-shell@hvc1.service fedora-import-state.service +Before=anaconda@.service +Wants=instperf.service +Wants=rsyslog.service +Wants=udev-settle.service +Wants=NetworkManager.service +Wants=plymouth-quit.service plymouth-quit-wait.service diff --git a/data/systemd/anaconda@.service b/data/systemd/anaconda@.service new file mode 100644 index 0000000..903df7a --- /dev/null +++ b/data/systemd/anaconda@.service @@ -0,0 +1,13 @@ +[Unit] +Description=Anaconda +After=anaconda.target + +[Service] +Environment=HOME=/root MALLOC_CHECK_=2 MALLOC_PERTURB_=204 PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin PYTHONPATH=/tmp/updates +Type=oneshot +WorkingDirectory=/root +ExecStart=/usr/sbin/anaconda +StandardInput=tty-force +TTYPath=/dev/%I +TTYReset=yes +TimeoutSec=0
It doesn't matter why we brought up the interface - we want to hand the info over to NM regardless. So save the netinfo for all onlined interfaces. --- dracut/anaconda-netroot.sh | 3 --- dracut/fetch-kickstart-net.sh | 3 --- dracut/parse-anaconda-options.sh | 3 +++ 3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/dracut/anaconda-netroot.sh b/dracut/anaconda-netroot.sh index 6be34a7..2486e30 100755 --- a/dracut/anaconda-netroot.sh +++ b/dracut/anaconda-netroot.sh @@ -51,6 +51,3 @@ case $repo in return 1 ;; esac - -# save the ifcfg file / dhcp lease for NetworkManager -save_netinfo $netif diff --git a/dracut/fetch-kickstart-net.sh b/dracut/fetch-kickstart-net.sh index 4dd7454..d871eae 100755 --- a/dracut/fetch-kickstart-net.sh +++ b/dracut/fetch-kickstart-net.sh @@ -47,6 +47,3 @@ if fetch_url "$kickstart" /tmp/ks.cfg; then else warn "failed to fetch kickstart from $kickstart" fi - -# save the ifcfg file / dhcp lease for NetworkManager -save_netinfo $netif diff --git a/dracut/parse-anaconda-options.sh b/dracut/parse-anaconda-options.sh index 755c33f..cd041f4 100755 --- a/dracut/parse-anaconda-options.sh +++ b/dracut/parse-anaconda-options.sh @@ -100,5 +100,8 @@ if [ -n "$updates" ]; then echo "live.updates=$updates" >> /etc/cmdline.d/75anaconda-options.conf fi
+# make sure we get ifcfg for every interface that comes up +echo "save_netinfo $netif" > $hookdir/initqueue/online/anaconda-ifcfg.sh + # re-read the commandline args unset CMDLINE
Loader used to create a default ifcfg-* file for each unused network interface, containing DEVICE, HWADDR, UUID, BOOTPROTO=dhcp, etc.
Network.update() populated self.netdevices by reading those files, *skipping any interface that lacked that file*, which caused the vnc traceback in bug #804504.
And without BOOTPROTO=dhcp, "ifup $dev" didn't work post-install, which caused #804716.
(Personally I think "ifup" should fall back to the same defaults as NetworkManager rather than making us write the defaults to a file, but we'll save that for later.) --- pyanaconda/network.py | 28 +++++++++++++++++++++++++--- 1 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/network.py b/pyanaconda/network.py index 067f3b1..40026a9 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -242,6 +242,28 @@ class NetworkDevice(IfcfgFile):
return s
+ # anaconda doesn't actually need this configuration, but if we don't write + # it to the installed system then 'ifup' doesn't work after install. + # FIXME: make 'ifup' use its own defaults! + def setDefaultConfig(self): + ifcfglog.debug("NetworkDevice %s: setDefaultConfig()" % self.iface) + self.set(("DEVICE", self.iface), + ("BOOTPROTO", "dhcp"), + ("ONBOOT", "no")) # for "security", or something + + try: + mac = open("/sys/class/net/%s/address" % self.iface).read().strip() + self.set(("HWADDR", mac.upper())) + except IOError as e: + ifcfglog.warning("HWADDR: %s" % str(e)) + + try: + uuid = open("/proc/sys/kernel/random/uuid").read().strip() + self.set(("UUID", uuid)) + except IOError as e: + ifcfglog.warning("UUID: %s" % str(e)) + + self.writeIfcfgFile()
def loadIfcfgFile(self): ifcfglog.debug("%s:\n%s" % (self.path, self.fileContent())) @@ -311,6 +333,8 @@ class NetworkDevice(IfcfgFile): shutil.move(newifcfg, keyfile)
def fileContent(self): + if not os.path.exists(self.path): + return "" f = open(self.path, 'r') content = f.read() f.close() @@ -422,9 +446,7 @@ class Network: if os.access(device.path, os.R_OK): device.loadIfcfgFile() else: - log.info("Network.update(): %s file not found" % - device.path) - continue + device.setDefaultConfig()
# TODORV - the last iface in loop wins, might be ok, # not worthy of special juggling
We're not quite ready for the switch yet, so suppress these messages. --- anaconda | 8 +++++--- dracut/parse-anaconda-options.sh | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/anaconda b/anaconda index ae23d4f..273d2a0 100755 --- a/anaconda +++ b/anaconda @@ -621,9 +621,11 @@ if __name__ == "__main__":
log.info("%s %s" % (sys.argv[0], getAnacondaVersion()))
- for arg in depr: - stdoutLog.warn("Boot argument '%s' is deprecated. " - "In the future, use 'inst.%s'.", arg, arg) + # TODO: uncomment this when we're sure that we're doing the right thing + # with flags.cmdline *everywhere* it appears... + #for arg in depr: + # stdoutLog.warn("Boot argument '%s' is deprecated. " + # "In the future, use 'inst.%s'.", arg, arg)
# pull this in to get product name and versioning from pyanaconda import product diff --git a/dracut/parse-anaconda-options.sh b/dracut/parse-anaconda-options.sh index cd041f4..10ebebd 100755 --- a/dracut/parse-anaconda-options.sh +++ b/dracut/parse-anaconda-options.sh @@ -47,6 +47,8 @@ warn_renamed_arg() { arg="$(getarg $1)" && warn "'$1=$arg'" && warn "$1 has been renamed to $2" }
+warn_renamed_arg() { :; } # XXX REMOVE WHEN WE'RE READY FOR THE NEW NAMES. + # check for deprecated arg, warn user, and write new arg to /etc/cmdline check_depr_arg() { local arg="" quiet="" newval="" @@ -80,11 +82,11 @@ getarg asknetwork && warn "'asknetwork' is deprecated and has been removed." &&\ warn "Use an appropriate 'ip=' argument instead."
# lang & keymap -check_depr_arg "lang=" "locale.LANG=%s" -check_depr_arg "keymap=" "vconsole.keymap=%s" +warn_renamed_arg "lang" "inst.lang" +warn_renamed_arg "keymap" "inst.keymap"
# repo -check_depr_arg "method=" "inst.repo=%s" +check_depr_arg "method=" "repo=%s" warn_renamed_arg "repo" "inst.repo"
# kickstart
Ack to all of these. In #4 you changed inst.repo to repo and I wonder why, but either should work.
On Wed, 2012-03-21 at 17:20 -0700, Brian C. Lane wrote:
Ack to all of these. In #4 you changed inst.repo to repo and I wonder why, but either should work.
Ah - mostly because I don't want us to be suggesting the 'inst.XXX' forms of the arguments to users until we're sure anaconda's ready to accept them.
-w
anaconda-devel@lists.stg.fedoraproject.org