Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
I just uploaded systemd 215-9 to unstable with two RC and some other fixes. I attach the full debdiff between 215-8 and -9, but as usual I also link to the individual commits on anonscm. Note that there are zero changes for the udebs (for d-i). Annotated changelog: | systemd (215-9) unstable; urgency=medium | | [ Didier Roche ] | * Add display managers autopkgtests. This is quite a delicate logic which got introduced in 215-8. This adds automatic tests. No impact at all on binary packages or on installations. http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=f72429642fd | * Reset display-manager symlink to match /e/X/d-d-m even if | display-manager.service was removed. Adapt the autopkgtests for it. This is a rather simple fix which fixes one corner case spotted by the tests. It has been in experimental and in Ubuntu for quite some time. http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=67417fc1 | [ Martin Pitt ] | * Prefer-etc-X11-default-display-manager-if-present.patch: Drop wrong | copy&paste'd comment, fix log strings. Thanks Adam D. Barratt. This came up in the unblock request for 215-8. It just fixes text in comments and two log warnings. http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=dc0a50b23 | * Log all members of cyclic dependencies (loops) even with quiet on the | kernel cmdline. (Closes: #770504) Non-RC bug, but trivial change and pre-approved by release team in #773183. http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=6f3e3ee | * Don't auto-clean PrivateTmp dir in /var/tmp; in Debian we don't want to | clean /var/tmp/ automatically. (Closes: #773313) Non-RC bug, but trivial change. Not pre-approved, but this brings systemd in line with Debian Policy wrt. /var/tmp/. http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=78d97ace0 | [ Michael Biebl ] | * sysv-generator: handle Provides: for non-virtual facility names. | (Closes: #774335) RC bug. http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=7024b5117a | * Fix systemd-remount-fs.service to not fail on remounting /usr if /usr | isn't mounted yet. This happens with initramfs-tools < 0.118 which we | might not get into Jessie any more. (Closes: #742048) RC bug. http://anonscm.debian.org/cgit/pkg-systemd/systemd.git/commit/?id=b9782ef44 Thanks for considering! Martin unblock systemd/215-9 -- Martin Pitt | http://www.piware.de Ubuntu Developer (www.ubuntu.com) | Debian Developer (www.debian.org)
diff --git a/debian/changelog b/debian/changelog index 2dd4744..61ef555 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,27 @@ +systemd (215-9) unstable; urgency=medium + + [ Didier Roche ] + * Add display managers autopkgtests. + * Reset display-manager symlink to match /e/X/d-d-m even if + display-manager.service was removed. Adapt the autopkgtests for it. + + [ Martin Pitt ] + * Prefer-etc-X11-default-display-manager-if-present.patch: Drop wrong + copy&paste'd comment, fix log strings. Thanks Adam D. Barratt. + * Log all members of cyclic dependencies (loops) even with quiet on the + kernel cmdline. (Closes: #770504) + * Don't auto-clean PrivateTmp dir in /var/tmp; in Debian we don't want to + clean /var/tmp/ automatically. (Closes: #773313) + + [ Michael Biebl ] + * sysv-generator: handle Provides: for non-virtual facility names. + (Closes: #774335) + * Fix systemd-remount-fs.service to not fail on remounting /usr if /usr + isn't mounted yet. This happens with initramfs-tools < 0.118 which we + might not get into Jessie any more. (Closes: #742048) + + -- Martin Pitt <mp...@debian.org> Tue, 13 Jan 2015 11:24:43 +0100 + systemd (215-8) unstable; urgency=medium [ Didier Roche ] diff --git a/debian/patches/Fix-usr-remount-failure-for-split-usr.patch b/debian/patches/Fix-usr-remount-failure-for-split-usr.patch new file mode 100644 index 0000000..6481b2c --- /dev/null +++ b/debian/patches/Fix-usr-remount-failure-for-split-usr.patch @@ -0,0 +1,64 @@ +From: Michael Biebl <bi...@debian.org> +Date: Tue, 13 Jan 2015 08:25:00 +0100 +Subject: Fix /usr remount failure for split /usr + +Fix systemd-remount-fs.service to not fail on remounting /usr if /usr isn't +mounted yet. This happens with initramfs-tools < 0.118 which we might not get +into Jessie any more. + +This can be dropped when /usr always gets mounted from initramfs. + +Bug-Debian: https://bugs.debian.org/742048 +--- + src/remount-fs/remount-fs.c | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/src/remount-fs/remount-fs.c b/src/remount-fs/remount-fs.c +index 847637a..82a1596 100644 +--- a/src/remount-fs/remount-fs.c ++++ b/src/remount-fs/remount-fs.c +@@ -34,6 +34,32 @@ + #include "mount-setup.h" + #include "exit-status.h" + ++static bool is_mounted(const char *dev_path) { ++ _cleanup_free_ char *parent_path = NULL; ++ struct stat st, pst; ++ int r; ++ ++ parent_path = strjoin(dev_path, "/..", NULL); ++ ++ r = stat(dev_path, &st); ++ if (r < 0) ++ return false; ++ ++ r = stat(parent_path, &pst); ++ if (r < 0) ++ return false; ++ ++ /* ++ * This code to check if a given path is a mountpoint is ++ * borrowed from util-linux' mountpoint tool. ++ */ ++ if ((st.st_dev != pst.st_dev) || ++ (st.st_dev == pst.st_dev && st.st_ino == pst.st_ino)) ++ return true; ++ ++ return false; ++} ++ + /* Goes through /etc/fstab and remounts all API file systems, applying + * options that are in /etc/fstab that systemd might not have + * respected */ +@@ -83,6 +109,11 @@ int main(int argc, char *argv[]) { + !path_equal(me->mnt_dir, "/usr")) + continue; + ++ /* Skip /usr if it hasn't been mounted by the initrd */ ++ if (path_equal(me->mnt_dir, "/usr") && ++ !is_mounted("/usr")) ++ continue; ++ + log_debug("Remounting %s", me->mnt_dir); + + pid = fork(); diff --git a/debian/patches/Prefer-etc-X11-default-display-manager-if-present.patch b/debian/patches/Prefer-etc-X11-default-display-manager-if-present.patch index b4bd19b..13a660b 100644 --- a/debian/patches/Prefer-etc-X11-default-display-manager-if-present.patch +++ b/debian/patches/Prefer-etc-X11-default-display-manager-if-present.patch @@ -6,17 +6,17 @@ Add a generator to ensure /etc/X11/default-display-manager is controlling which display-manager is started. --- Makefile.am | 11 ++- - src/default-display-manager-generator/Makefile | 28 ++++++ - .../default-display-manager-generator.c | 105 +++++++++++++++++++++ - 3 files changed, 143 insertions(+), 1 deletion(-) + src/default-display-manager-generator/Makefile | 24 +++++ + .../default-display-manager-generator.c | 103 +++++++++++++++++++++ + 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/default-display-manager-generator/Makefile create mode 100644 src/default-display-manager-generator/default-display-manager-generator.c diff --git a/Makefile.am b/Makefile.am -index ec5b871..b607a4a 100644 +index 6f4df22..9d83771 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -402,7 +402,8 @@ systemgenerator_PROGRAMS = \ +@@ -387,7 +387,8 @@ systemgenerator_PROGRAMS = \ systemd-getty-generator \ systemd-fstab-generator \ systemd-system-update-generator \ @@ -26,7 +26,7 @@ index ec5b871..b607a4a 100644 dist_bashcompletion_DATA = \ shell-completion/bash/busctl \ -@@ -2190,6 +2191,14 @@ systemd_delta_LDADD = \ +@@ -1965,6 +1966,14 @@ systemd_delta_LDADD = \ libsystemd-shared.la # ------------------------------------------------------------------------------ @@ -43,10 +43,10 @@ index ec5b871..b607a4a 100644 diff --git a/src/default-display-manager-generator/Makefile b/src/default-display-manager-generator/Makefile new file mode 100644 -index 0000000..b29b937 +index 0000000..3a4bbbe --- /dev/null +++ b/src/default-display-manager-generator/Makefile -@@ -0,0 +1,28 @@ +@@ -0,0 +1,24 @@ +# This file is part of systemd. +# +# Copyright 2014 Canonical @@ -64,10 +64,6 @@ index 0000000..b29b937 +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see <http://www.gnu.org/licenses/>. + -+# This file is a dirty trick to simplify compilation from within -+# emacs. This file is not intended to be distributed. So, don't touch -+# it, even better ignore it! -+ +all: + $(MAKE) -C .. + @@ -77,10 +73,10 @@ index 0000000..b29b937 +.PHONY: all clean diff --git a/src/default-display-manager-generator/default-display-manager-generator.c b/src/default-display-manager-generator/default-display-manager-generator.c new file mode 100644 -index 0000000..2fe9521 +index 0000000..930a67e --- /dev/null +++ b/src/default-display-manager-generator/default-display-manager-generator.c -@@ -0,0 +1,105 @@ +@@ -0,0 +1,103 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** @@ -136,10 +132,8 @@ index 0000000..2fe9521 + default_dm = strstrip(basename(default_dm_path)); + + r = readlink_value(dm_service_unit, &enabled_dm_unit); -+ if (r < 0) { -+ log_warning("No default display manager unit service enabled, setup is manual or a sysvinit file"); -+ return 0; -+ } ++ if (r < 0) ++ enabled_dm_unit = strdup(""); + + /* all is fine if the info matches */ + if (streq(strappenda(default_dm, ".service"), enabled_dm_unit)) @@ -149,10 +143,10 @@ index 0000000..2fe9521 + + /* we only create the alias symlink for non sysvinit services */ + if (access(target_unit_path, F_OK) < 0 && (errno == ENOENT)) { -+ log_warning("%s doesn't seem to be a system unit, we disable the systemd enabled display manager", target_unit_path); ++ log_warning("%s is not a systemd unit, we disable the systemd enabled display manager", target_unit_path); + target_unit_path = "/dev/null"; + } else { -+ log_warning("%s point at %s while the default systemd unit is %s. Reconfiguring %s as default.", ++ log_warning("%s points at %s while the default systemd unit is %s. Reconfiguring %s as default.", + default_dm_file, default_dm, enabled_dm_unit, default_dm); + } + diff --git a/debian/patches/Raise-level-of-Found-dependency.-lines.patch b/debian/patches/Raise-level-of-Found-dependency.-lines.patch new file mode 100644 index 0000000..8bbb0f6 --- /dev/null +++ b/debian/patches/Raise-level-of-Found-dependency.-lines.patch @@ -0,0 +1,38 @@ +From: =?utf-8?q?Zbigniew_J=C4=99drzejewski-Szmek?= <zbys...@in.waw.pl> +Date: Sun, 2 Nov 2014 12:10:42 -0500 +Subject: Raise level of 'Found dependency...' lines + +This way they always show up together with 'Found ordering cycle...'. +Ordering cycles are a serious error and a major pain to debug. If +quiet is enabled, only the first and the last line of output are +shown: + +systemd[1]: Found ordering cycle on basic.target/start +systemd[1]: Breaking ordering cycle by deleting job timers.target/start +systemd[1]: Job timers.target/start deleted to break ordering cycle starting with basic.target/start + +which isn't particularly enlightening. So just show the whole message +at the same level. + +https://bugzilla.redhat.com/show_bug.cgi?id=1158206 +--- + src/core/transaction.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/core/transaction.c b/src/core/transaction.c +index 805d40a..b9bbec2 100644 +--- a/src/core/transaction.c ++++ b/src/core/transaction.c +@@ -377,9 +377,9 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi + for (k = from; k; k = ((k->generation == generation && k->marker != k) ? k->marker : NULL)) { + + /* logging for j not k here here to provide consistent narrative */ +- log_info_unit(j->unit->id, +- "Found dependency on %s/%s", +- k->unit->id, job_type_to_string(k->type)); ++ log_warning_unit(j->unit->id, ++ "Found dependency on %s/%s", ++ k->unit->id, job_type_to_string(k->type)); + + if (!delete && hashmap_get(tr->jobs, k->unit) && + !unit_matters_to_anchor(k->unit, k)) { diff --git a/debian/patches/series b/debian/patches/series index fd1aacd..80256e6 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -122,6 +122,9 @@ shared-add-readlink_value.patch util-allow-strappenda-to-take-any-number-of-args.patch journal-do-server_vacuum-for-sigusr1.patch journalctl-correct-help-text-for-until.patch +Raise-level-of-Found-dependency.-lines.patch +systemd-tmpfiles-Fix-IGNORE_DIRECTORY_PATH-age-handl.patch +sysv-generator-handle-Provides-for-non-virtual-facil.patch ## Debian specific patches: Add-back-support-for-Debian-specific-config-files.patch @@ -173,3 +176,4 @@ sysv-generator-Avoid-wrong-dependencies-for-failing-.patch Prefer-etc-X11-default-display-manager-if-present.patch core-Fix-bind-error-message.patch core-Make-binding-notify-private-dbus-socket-more-ro.patch +Fix-usr-remount-failure-for-split-usr.patch diff --git a/debian/patches/systemd-tmpfiles-Fix-IGNORE_DIRECTORY_PATH-age-handl.patch b/debian/patches/systemd-tmpfiles-Fix-IGNORE_DIRECTORY_PATH-age-handl.patch new file mode 100644 index 0000000..859847d --- /dev/null +++ b/debian/patches/systemd-tmpfiles-Fix-IGNORE_DIRECTORY_PATH-age-handl.patch @@ -0,0 +1,39 @@ +From 9ed2a35e93f4a9e82585f860f54cdcbbdf3e1f86 Mon Sep 17 00:00:00 2001 +From: Richard Weinberger <rich...@nod.at> +Date: Tue, 9 Sep 2014 11:09:37 +0200 +Subject: [PATCH] systemd-tmpfiles: Fix IGNORE_DIRECTORY_PATH age handling + +If one has a config like: +d /tmp 1777 root root - +X /tmp/important_mount + +All files below /tmp/important_mount will be deleted as the +/tmp/important_mount item will spuriously inherit a max age of 0 +from /tmp. +/tmp has a max age of 0 but age_set is (of course) false. + +This affects also the PrivateTmp feature of systemd. +All tmp files of such services will be deleted unconditionally +and can cause service failures and data loss. + +Fix this by checking ->age_set in the IGNORE_DIRECTORY_PATH logic. +--- + src/tmpfiles/tmpfiles.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index f9830c4..7eafd6b 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -1576,7 +1576,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) { + candidate_item = j; + } + +- if (candidate_item) { ++ if (candidate_item && candidate_item->age_set) { + i->age = candidate_item->age; + i->age_set = true; + } +-- +2.1.3 + diff --git a/debian/patches/sysv-generator-handle-Provides-for-non-virtual-facil.patch b/debian/patches/sysv-generator-handle-Provides-for-non-virtual-facil.patch new file mode 100644 index 0000000..77c4c12 --- /dev/null +++ b/debian/patches/sysv-generator-handle-Provides-for-non-virtual-facil.patch @@ -0,0 +1,68 @@ +From: Michael Biebl <bi...@debian.org> +Date: Mon, 5 Jan 2015 09:49:44 +0100 +Subject: sysv-generator: handle Provides: for non-virtual facility names + +The list of provided facility names as specified via Provides: in the +LSB header was originally implemented by adding those facilities to the +Names= property via unit_add_name(). + +In commit 95ed3294c632f5606327149f10cef1eb34422862 the internal SysV +support was replaced by a generator and support for parsing the Names= +option had been removed from the unit file parsing in v186. +As a result, Provides: for non-virtual facility was dropped when +introducing the sysv-generator. + +Since quite a few SysV init scripts still use that functionality (at +least in distros like Debian which have a large body of SysV init +scripts), add back support by making those facility names available via +symlinks to the unit filename to ensure correct orderings between +SysV init scripts which use those facility names. + +Bug-Debian: https://bugs.debian.org/774335 +--- + src/sysv-generator/sysv-generator.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c +index da6b4f6..2f116fb 100644 +--- a/src/sysv-generator/sysv-generator.c ++++ b/src/sysv-generator/sysv-generator.c +@@ -118,6 +118,27 @@ static int add_symlink(const char *service, const char *where) { + return 1; + } + ++static int add_alias(const char *service, const char *alias) { ++ _cleanup_free_ char *link = NULL; ++ int r; ++ ++ assert(service); ++ assert(alias); ++ ++ link = strjoin(arg_dest, "/", alias, NULL); ++ if (!link) ++ return log_oom(); ++ ++ r = symlink(service, link); ++ if (r < 0) { ++ if (errno == EEXIST) ++ return 0; ++ return -errno; ++ } ++ ++ return 1; ++} ++ + static int generate_unit_file(SysvStub *s) { + char *unit; + char **p; +@@ -477,7 +498,9 @@ static int load_sysv(SysvStub *s) { + if (r == 0) + continue; + +- if (unit_name_to_type(m) != UNIT_SERVICE) { ++ if (unit_name_to_type(m) == UNIT_SERVICE) { ++ r = add_alias(s->name, m); ++ } else { + /* NB: SysV targets + * which are provided + * by a service are diff --git a/debian/tests/control b/debian/tests/control index 501052e..cd03367 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -11,3 +11,7 @@ Depends: python3-systemd Tests: boot-and-services Depends: lightdm, cron, network-manager, busybox-static Restrictions: needs-root, isolation-machine, needs-recommends, breaks-testbed + +Tests: display-managers +Depends: systemd, lightdm +Restrictions: needs-root, isolation-machine, needs-recommends, breaks-testbed diff --git a/debian/tests/display-managers b/debian/tests/display-managers new file mode 100755 index 0000000..d45b2b8 --- /dev/null +++ b/debian/tests/display-managers @@ -0,0 +1,302 @@ +#!/usr/bin/python3 +# autopkgtest check: Boot with systemd and check different dm configurations +# (C) 2014 Canonical Ltd. +# Author: Didier Roche <didro...@ubuntu.com> + +from contextlib import suppress +import fileinput +import os +import subprocess +import shutil +import sys +import unittest +from time import sleep + +DDM_CONFIG_PATH = "/etc/X11/default-display-manager" +SYSTEMD_DEFAULT_DM_PATH = "/etc/systemd/system/display-manager.service" +SYSTEMD_SYSTEM_UNIT_DIR = "/lib/systemd/system" +LIGHTDM_SYSTEMD_UNIT_PATH = os.path.join(SYSTEMD_SYSTEM_UNIT_DIR, 'lightdm.service') + + +class DisplayManagersTest(unittest.TestCase): + '''Check that multiple dm configurations are handled''' + + def setUp(self): + super().setUp() + with suppress(FileNotFoundError): + os.remove(SYSTEMD_DEFAULT_DM_PATH) + with suppress(FileNotFoundError): + os.remove(DDM_CONFIG_PATH) + subprocess.check_call('apt-get install -y --reinstall lightdm 2>&1', shell=True) + # Remove all Conditional ExecStartPre= as we want to check systemd logic, not unit + for line in fileinput.input([LIGHTDM_SYSTEMD_UNIT_PATH], inplace=True): + if not line.startswith('ExecStartPre='): + print(line) + self.files_to_clean = [] + + def tearDown(self): + for f in self.files_to_clean: + os.remove(f) + super().tearDown() + + def test_one_systemd(self): + '''one systemd dm is started''' + + self.reload_state() + + self.assertTrue(self.is_active_unit('lightdm')) + + def test_multiple_systemd(self): + '''only default systemd dm is started''' + + self.create_systemd_dm_unit("systemddm") + self.reload_state() + + self.assertTrue(self.is_active_unit('lightdm')) + self.assertFalse(self.is_active_unit('systemddm')) + + def test_multiple_systemd_ddmconfig_match(self): + '''display-manager symlink respect ddm config and starts right unit''' + + # lightdm was the default + self.create_systemd_dm_unit("systemddm", make_ddm_default="systemddm") + self.reload_state() + + self.assertFalse(self.is_active_unit('lightdm')) + self.assertTrue(self.is_active_unit('systemddm')) + + def test_multiple_systemd_ddmconfig_match_no_symlink(self): + '''create a display-manager symlink to matching systemd unit ddm config''' + + # lightdm was the default + self.create_systemd_dm_unit("systemddm", make_ddm_default="systemddm") + os.remove(SYSTEMD_DEFAULT_DM_PATH) + self.reload_state() + + self.assertFalse(self.is_active_unit('lightdm')) + self.assertTrue(self.is_active_unit('systemddm')) + + def test_one_systemd_no_ddmconfig(self): + '''without any ddm config, the default systemd unit via symlink is still the default''' + + os.remove(DDM_CONFIG_PATH) + self.reload_state() + + self.assertTrue(self.is_active_unit('lightdm')) + + def test_one_systemd_masked_symlink_with_ddmconfig(self): + '''a masked symlink will be updated to match systemd ddmconfig unit''' + + os.remove(SYSTEMD_DEFAULT_DM_PATH) + os.symlink("/dev/null", SYSTEMD_DEFAULT_DM_PATH) + self.reload_state() + + self.assertTrue(self.is_active_unit('lightdm')) + + def test_one_systemd_masked_symlink_no_ddmconfig(self): + '''without any ddm config, a masked symlinked will stayed masked''' + + os.remove(DDM_CONFIG_PATH) + os.remove(SYSTEMD_DEFAULT_DM_PATH) + os.symlink("/dev/null", SYSTEMD_DEFAULT_DM_PATH) + self.reload_state() + + self.assertFalse(self.is_active_unit('lightdm')) + + def test_multiple_systemd_wrong_ddmconfig(self): + '''ddm config matches no systemd unit, don't start any of them''' + + self.create_systemd_dm_unit("systemddm", make_ddm_default="systemddm_doesnt_match") + self.reload_state() + + self.assertFalse(self.is_active_unit('lightdm')) + self.assertFalse(self.is_active_unit('systemddm')) + + def test_one_init(self): + '''one init dm is started''' + + # fake removing lightdm (or we shoud remove all processes under lightdm) + os.remove(DDM_CONFIG_PATH) + os.remove(SYSTEMD_DEFAULT_DM_PATH) + os.remove(LIGHTDM_SYSTEMD_UNIT_PATH) + self.create_init_dm("initdm", make_ddm_default="initdm") + self.reload_state() + + self.assertTrue(self.is_active_unit('initdm')) + + def test_multiple_init(self): + '''all init dms are enabled, regardless of ddm''' + + # this enable to keep previous init behavior, + # especially when they don't support ddm config like nodm + os.remove(DDM_CONFIG_PATH) + os.remove(SYSTEMD_DEFAULT_DM_PATH) + os.remove(LIGHTDM_SYSTEMD_UNIT_PATH) + self.create_init_dm("initdm", make_ddm_default="initdm") + self.create_init_dm("otherinitdm") + self.reload_state() + + self.assertTrue(self.is_active_unit('initdm')) + self.assertTrue(self.is_active_unit('otherinitdm')) + + def test_multiple_init_no_ddm(self): + '''all init dms are enabled, without any ddm file''' + + os.remove(DDM_CONFIG_PATH) + os.remove(SYSTEMD_DEFAULT_DM_PATH) + os.remove(LIGHTDM_SYSTEMD_UNIT_PATH) + self.create_init_dm("initdm") + self.create_init_dm("otherinitdm") + self.reload_state() + + self.assertTrue(self.is_active_unit('initdm')) + self.assertTrue(self.is_active_unit('otherinitdm')) + + def test_systemd_matches_ddm_and_init(self): + '''default ddm config systemd is enabled as well as all inits''' + + # lightdm is the default + self.create_init_dm("initdm") + self.reload_state() + + self.assertTrue(self.is_active_unit('lightdm')) + self.assertTrue(self.is_active_unit('initdm')) + + def test_systemd_and_init_matches_ddm(self): + '''default ddm init prevents systemd units to start''' + + self.create_init_dm("initdm", make_ddm_default="initdm") + self.reload_state() + + self.assertFalse(self.is_active_unit('lightdm')) + self.assertTrue(self.is_active_unit('initdm')) + + def test_no_ddmconfig_multiple_systemd_and_init(self): + '''no ddm config let default systemd and all init dms enabled''' + + os.remove(DDM_CONFIG_PATH) + self.create_systemd_dm_unit("systemddm") + self.create_init_dm("initdm") + self.reload_state() + + self.assertTrue(self.is_active_unit('lightdm')) + self.assertTrue(self.is_active_unit('initdm')) + self.assertFalse(self.is_active_unit('systemddm')) + + def test_no_ddmconfig_no_default_systemd_and_init(self): + '''no ddm config default systemd unit will only have init dms enabled''' + + os.remove(DDM_CONFIG_PATH) + os.remove(SYSTEMD_DEFAULT_DM_PATH) + self.create_systemd_dm_unit("systemddm") + self.create_init_dm("initdm") + self.reload_state() + + self.assertFalse(self.is_active_unit('lightdm')) + self.assertTrue(self.is_active_unit('initdm')) + self.assertFalse(self.is_active_unit('systemddm')) + + # NOTE: I think init shouldn't start in that case + def test_one_systemd_one_init_masked_symlink_with_ddmconfig(self): + '''a masked symlink will be updated to match systemd ddmconfig systemd unit and init is started''' + + os.remove(SYSTEMD_DEFAULT_DM_PATH) + os.symlink("/dev/null", SYSTEMD_DEFAULT_DM_PATH) + self.create_init_dm("initdm") + self.reload_state() + + self.assertTrue(self.is_active_unit('lightdm')) + self.assertTrue(self.is_active_unit('initdm')) + + # NOTE: I think init shouldn't start in that case + def test_one_systemd_one_init_masked_symlink_no_ddmconfig(self): + '''without any ddm config, a masked symlinked will stayed masked, but init will be started''' + + os.remove(DDM_CONFIG_PATH) + os.remove(SYSTEMD_DEFAULT_DM_PATH) + os.symlink("/dev/null", SYSTEMD_DEFAULT_DM_PATH) + self.create_init_dm("initdm") + self.reload_state() + + self.assertFalse(self.is_active_unit('lightdm')) + self.assertTrue(self.is_active_unit('initdm')) + + # Helper methods + + def create_systemd_dm_unit(self, name, make_ddm_default=None): + dest_unit = "{}.service".format(os.path.join(SYSTEMD_SYSTEM_UNIT_DIR, name)) + shutil.copy(LIGHTDM_SYSTEMD_UNIT_PATH, dest_unit) + # remove BusName to avoid conflicts + for line in fileinput.input([LIGHTDM_SYSTEMD_UNIT_PATH], inplace=True): + if not line.startswith('BusName='): + print(line) + self.files_to_clean.append(dest_unit) + + if make_ddm_default: + self.make_ddm_default(make_ddm_default) + + def create_init_dm(self, name, make_ddm_default=None): + init_script = "/etc/init.d/{}".format(name) + with open(init_script, 'w') as f: + f.write('''#!/bin/sh +### BEGIN INIT INFO +# Provides: {service} +# Required-Start: $local_fs $remote_fs dbus +# Required-Stop: $local_fs $remote_fs dbus +# Should-Start: $named +# Should-Stop: $named +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start {service} +### END INIT INFO +exit 0'''.format(service=name)) + os.fchmod(f.fileno(), 0o755) + self.files_to_clean.append(init_script) + + rc2_link = "/etc/rc2.d/S05{}".format(name) + os.symlink("../init.d/{}".format(name), rc2_link) + self.files_to_clean.append(rc2_link) + + insserv_script = "/etc/insserv.conf.d/{}".format(name) + with open(insserv_script, 'w') as f: + f.write("$x-display-manager {}".format(name)) + self.files_to_clean.append(insserv_script) + if make_ddm_default: + self.make_ddm_default(make_ddm_default) + + def make_ddm_default(self, binary_name): + with open(DDM_CONFIG_PATH, 'w') as f: + f.write("/usr/bin/{}".format(binary_name)) + + def is_active_unit(self, unit): + '''Check that given unit is active''' + + if subprocess.call(['systemctl', '-q', 'is-active', unit]) != 0: + return False + return True + + def reload_state(self): + subprocess.check_call(['systemctl', 'daemon-reload']) + subprocess.check_call(['systemctl', 'default']) + sleep(2) # a more robust way would be to loop over remaining jobs to process + + +def boot_with_systemd(): + '''Reboot with systemd as init + + In case something else is currently running in the testbed + ''' + if subprocess.call(['systemctl', 'status'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) != 0: + print('Installing systemd-sysv and rebooting...') + subprocess.check_call('apt-get -y install systemd-sysv 2>&1', + shell=True) + subprocess.check_call(['autopkgtest-reboot', 'boot-systemd']) + + +if __name__ == '__main__': + if not os.getenv('ADT_REBOOT_MARK'): + boot_with_systemd() + + unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, + verbosity=2))
signature.asc
Description: Digital signature