Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
Nix
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525# Test configuration switching.{ lib, pkgs, ... }:
let
# Simple service that can either be socket-activated or that will # listen on port 1234 if not socket-activated. # A connection to the socket causes 'hello' to be written to the client. socketTest = pkgs.writeScript "socket-test.py" # python '' #!${pkgs.python3}/bin/python3
from socketserver import TCPServer, StreamRequestHandler import socket import os
class Handler(StreamRequestHandler): def handle(self): self.wfile.write("hello".encode("utf-8"))
class Server(TCPServer): def __init__(self, server_address, handler_cls): listenFds = os.getenv('LISTEN_FDS') if listenFds is None or int(listenFds) < 1: print(f'Binding to {server_address}') TCPServer.__init__( self, server_address, handler_cls, bind_and_activate=True) else: TCPServer.__init__( self, server_address, handler_cls, bind_and_activate=False) # Override socket print(f'Got activated by {os.getenv("LISTEN_FDNAMES")} ' f'with {listenFds} FDs') self.socket = socket.fromfd(3, self.address_family, self.socket_type)
if __name__ == "__main__": server = Server(("localhost", 1234), Handler) server.serve_forever() '';
in{ name = "switch-test"; meta = with pkgs.lib.maintainers; { maintainers = [ gleber das_j ]; };
nodes = { machine = { pkgs, lib, ... }: { environment.systemPackages = [ pkgs.socat ]; # for the socket activation stuff users.mutableUsers = false;
# Test that no boot loader still switches, e.g. in the ISO boot.loader.grub.enable = false;
specialisation = rec { brokenInitInterface.configuration.config.system.extraSystemBuilderCmds = '' echo "systemd 0" > $out/init-interface-version '';
modifiedSystemConf.configuration.systemd.settings.Manager = { DefaultEnvironment = "XXX_SYSTEM=foo"; };
addedMount.configuration.virtualisation.fileSystems."/test" = { device = "tmpfs"; fsType = "tmpfs"; };
addedMountOptsModified.configuration = { imports = [ addedMount.configuration ]; virtualisation.fileSystems."/test".options = [ "x-test" ]; };
addedMountDevModified.configuration = { imports = [ addedMountOptsModified.configuration ]; virtualisation.fileSystems."/test".device = lib.mkForce "ramfs"; };
storeMountModified.configuration = { virtualisation.fileSystems."/".device = lib.mkForce "auto"; };
swap.configuration.swapDevices = lib.mkVMOverride [ { device = "/swapfile"; size = 1; } ];
simpleService.configuration = { systemd.services.test = { wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${pkgs.coreutils}/bin/true"; ExecReload = "${pkgs.coreutils}/bin/true"; }; }; };
simpleServiceSeparateActivationScript.configuration = { system.activatable = false; systemd.services.test = { wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${pkgs.coreutils}/bin/true"; ExecReload = "${pkgs.coreutils}/bin/true"; }; }; };
simpleServiceDifferentDescription.configuration = { imports = [ simpleService.configuration ]; systemd.services.test.description = "Test unit"; };
simpleServiceModified.configuration = { imports = [ simpleService.configuration ]; systemd.services.test.serviceConfig.X-Test = true; };
simpleServiceNostop.configuration = { imports = [ simpleService.configuration ]; systemd.services.test.stopIfChanged = false; };
simpleServiceReload.configuration = { imports = [ simpleService.configuration ]; systemd.services.test = { reloadIfChanged = true; serviceConfig.ExecReload = "${pkgs.coreutils}/bin/true"; }; };
simpleServiceNorestart.configuration = { imports = [ simpleService.configuration ]; systemd.services.test.restartIfChanged = false; };
simpleServiceFailing.configuration = { imports = [ simpleServiceModified.configuration ]; systemd.services.test.serviceConfig.ExecStart = lib.mkForce "${pkgs.coreutils}/bin/false"; };
autorestartService.configuration = { # A service that immediately goes into restarting (but without failing) systemd.services.autorestart = { wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "simple"; Restart = "always"; RestartSec = "20y"; # Should be long enough ExecStart = "${pkgs.coreutils}/bin/true"; }; }; };
autorestartServiceFailing.configuration = { imports = [ autorestartService.configuration ]; systemd.services.autorestart.serviceConfig = { ExecStart = lib.mkForce "${pkgs.coreutils}/bin/false"; }; };
simpleServiceWithExtraSection.configuration = { imports = [ simpleServiceNostop.configuration ]; systemd.packages = [ (pkgs.writeTextFile { name = "systemd-extra-section"; destination = "/etc/systemd/system/test.service"; text = '' [X-Test] X-Test-Value=a ''; }) ]; };
simpleServiceWithExtraSectionOtherName.configuration = { imports = [ simpleServiceNostop.configuration ]; systemd.packages = [ (pkgs.writeTextFile { name = "systemd-extra-section"; destination = "/etc/systemd/system/test.service"; text = '' [X-Test2] X-Test-Value=a ''; }) ]; };
simpleServiceWithInstallSection.configuration = { imports = [ simpleServiceNostop.configuration ]; systemd.packages = [ (pkgs.writeTextFile { name = "systemd-extra-section"; destination = "/etc/systemd/system/test.service"; text = '' [Install] WantedBy=multi-user.target ''; }) ]; };
simpleServiceWithExtraKey.configuration = { imports = [ simpleServiceNostop.configuration ]; systemd.services.test.serviceConfig."X-Test" = "test"; };
simpleServiceWithExtraKeyOtherValue.configuration = { imports = [ simpleServiceNostop.configuration ]; systemd.services.test.serviceConfig."X-Test" = "test2"; };
simpleServiceWithExtraKeyOtherName.configuration = { imports = [ simpleServiceNostop.configuration ]; systemd.services.test.serviceConfig."X-Test2" = "test"; };
simpleServiceReloadTrigger.configuration = { imports = [ simpleServiceNostop.configuration ]; systemd.services.test.reloadTriggers = [ "/dev/null" ]; };
simpleServiceReloadTriggerModified.configuration = { imports = [ simpleServiceNostop.configuration ]; systemd.services.test.reloadTriggers = [ "/dev/zero" ]; };
simpleServiceReloadTriggerModifiedAndSomethingElse.configuration = { imports = [ simpleServiceNostop.configuration ]; systemd.services.test = { reloadTriggers = [ "/dev/zero" ]; serviceConfig."X-Test" = "test"; }; };
simpleServiceReloadTriggerModifiedSomethingElse.configuration = { imports = [ simpleServiceNostop.configuration ]; systemd.services.test.serviceConfig."X-Test" = "test"; };
unitWithBackslash.configuration = { systemd.services."escaped\\x2ddash" = { wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${pkgs.coreutils}/bin/true"; ExecReload = "${pkgs.coreutils}/bin/true"; }; }; };
unitWithBackslashModified.configuration = { imports = [ unitWithBackslash.configuration ]; systemd.services."escaped\\x2ddash".serviceConfig.X-Test = "test"; };
unitWithMultilineValue.configuration = { systemd.services.test.serviceConfig.ExecStart = '' ${pkgs.coreutils}/bin/true \ # ignored ; ignored blah blah ''; };
unitStartingWithDash.configuration = { systemd.services."-" = { wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${pkgs.coreutils}/bin/true"; }; }; };
unitStartingWithDashModified.configuration = { imports = [ unitStartingWithDash.configuration ]; systemd.services."-" = { reloadIfChanged = true; serviceConfig.ExecReload = "${pkgs.coreutils}/bin/true"; }; };
unitWithRequirement.configuration = { systemd.services.required-service = { wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${pkgs.coreutils}/bin/true"; ExecReload = "${pkgs.coreutils}/bin/true"; }; }; systemd.services.test-service = { wantedBy = [ "multi-user.target" ]; requires = [ "required-service.service" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${pkgs.coreutils}/bin/true"; ExecReload = "${pkgs.coreutils}/bin/true"; }; }; };
unitWithRequirementModified.configuration = { imports = [ unitWithRequirement.configuration ]; systemd.services.required-service.serviceConfig.X-Test = "test"; systemd.services.test-service.reloadTriggers = [ "test" ]; };
unitWithRequirementModifiedNostart.configuration = { imports = [ unitWithRequirement.configuration ]; systemd.services.test-service.unitConfig.RefuseManualStart = true; };
unitWithTemplate.configuration = { systemd.services."instantiated@".serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${pkgs.coreutils}/bin/true"; ExecReload = "${pkgs.coreutils}/bin/true"; }; systemd.services."instantiated@one" = { wantedBy = [ "multi-user.target" ]; overrideStrategy = "asDropin"; }; systemd.services."instantiated@two" = { wantedBy = [ "multi-user.target" ]; overrideStrategy = "asDropin"; }; };
unitWithTemplateModified.configuration = { imports = [ unitWithTemplate.configuration ]; systemd.services."instantiated@".serviceConfig.X-Test = "test"; };
restart-and-reload-by-activation-script.configuration = { systemd.services = rec { simple-service = { # No wantedBy so we can check if the activation script restart triggers them serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${pkgs.coreutils}/bin/true"; ExecReload = "${pkgs.coreutils}/bin/true"; }; }; "templated-simple-service@" = simple-service; "templated-simple-service@instance".overrideStrategy = "asDropin";
simple-restart-service = simple-service // { stopIfChanged = false; }; "templated-simple-restart-service@" = simple-restart-service; "templated-simple-restart-service@instance".overrideStrategy = "asDropin";
simple-reload-service = simple-service // { reloadIfChanged = true; }; "templated-simple-reload-service@" = simple-reload-service; "templated-simple-reload-service@instance".overrideStrategy = "asDropin";
no-restart-service = simple-service // { restartIfChanged = false; }; "templated-no-restart-service@" = no-restart-service; "templated-no-restart-service@instance".overrideStrategy = "asDropin";
reload-triggers = simple-service // { wantedBy = [ "multi-user.target" ]; }; "templated-reload-triggers@" = simple-service; "templated-reload-triggers@instance" = { overrideStrategy = "asDropin"; wantedBy = [ "multi-user.target" ]; };
reload-triggers-and-restart-by-as = simple-service; "templated-reload-triggers-and-restart-by-as@" = reload-triggers-and-restart-by-as; "templated-reload-triggers-and-restart-by-as@instance".overrideStrategy = "asDropin";
reload-triggers-and-restart = simple-service // { stopIfChanged = false; # easier to check for this wantedBy = [ "multi-user.target" ]; }; "templated-reload-triggers-and-restart@" = simple-service; "templated-reload-triggers-and-restart@instance" = { overrideStrategy = "asDropin"; stopIfChanged = false; # easier to check for this wantedBy = [ "multi-user.target" ]; }; };
system.activationScripts.restart-and-reload-test = { supportsDryActivation = true; deps = [ ]; text = '' if [ "$NIXOS_ACTION" = dry-activate ]; then f=/run/nixos/dry-activation-restart-list g=/run/nixos/dry-activation-reload-list else f=/run/nixos/activation-restart-list g=/run/nixos/activation-reload-list fi cat <<EOF >> "$f" simple-service.service simple-restart-service.service simple-reload-service.service no-restart-service.service reload-triggers-and-restart-by-as.service templated-simple-service@instance.service templated-simple-restart-service@instance.service templated-simple-reload-service@instance.service templated-no-restart-service@instance.service templated-reload-triggers-and-restart-by-as@instance.service EOF
cat <<EOF >> "$g" reload-triggers.service reload-triggers-and-restart-by-as.service reload-triggers-and-restart.service templated-reload-triggers@instance.service templated-reload-triggers-and-restart-by-as@instance.service templated-reload-triggers-and-restart@instance.service EOF ''; }; };
restart-and-reload-by-activation-script-modified.configuration = { imports = [ restart-and-reload-by-activation-script.configuration ]; systemd.services.reload-triggers-and-restart.serviceConfig.X-Modified = "test"; systemd.services."templated-reload-triggers-and-restart@instance" = { overrideStrategy = "asDropin"; serviceConfig.X-Modified = "test"; }; };
simple-socket.configuration = { systemd.services.socket-activated = { description = "A socket-activated service"; stopIfChanged = lib.mkDefault false; serviceConfig = { ExecStart = socketTest; ExecReload = "${pkgs.coreutils}/bin/true"; }; }; systemd.sockets.socket-activated = { wantedBy = [ "sockets.target" ]; listenStreams = [ "/run/test.sock" ]; socketConfig.SocketMode = lib.mkDefault "0777"; }; };
simple-socket-service-modified.configuration = { imports = [ simple-socket.configuration ]; systemd.services.socket-activated.serviceConfig.X-Test = "test"; };
simple-socket-stop-if-changed.configuration = { imports = [ simple-socket.configuration ]; systemd.services.socket-activated.stopIfChanged = true; };
simple-socket-stop-if-changed-and-reloadtrigger.configuration = { imports = [ simple-socket.configuration ]; systemd.services.socket-activated = { stopIfChanged = true; reloadTriggers = [ "test" ]; }; };
mount.configuration = { systemd.mounts = [ { description = "Testmount"; what = "tmpfs"; type = "tmpfs"; where = "/testmount"; options = "size=1M"; wantedBy = [ "local-fs.target" ]; } ]; };
mountOptionsModified.configuration = { systemd.mounts = [ { description = "Testmount"; what = "tmpfs"; type = "tmpfs"; where = "/testmount"; options = "size=10M"; wantedBy = [ "local-fs.target" ]; } ]; };
mountModified.configuration = { systemd.mounts = [ { description = "Testmount"; what = "ramfs"; type = "ramfs"; where = "/testmount"; options = "size=10M"; wantedBy = [ "local-fs.target" ]; } ]; };
timer.configuration = { systemd.timers.test-timer = { wantedBy = [ "timers.target" ]; timerConfig.OnCalendar = "@1395716396"; # chosen by fair dice roll }; systemd.services.test-timer = { serviceConfig = { Type = "oneshot"; ExecStart = "${pkgs.coreutils}/bin/true"; }; }; };
timerModified.configuration = { imports = [ timer.configuration ]; systemd.timers.test-timer.timerConfig.OnCalendar = lib.mkForce "Fri 2012-11-23 16:00:00"; };
hybridSleepModified.configuration = { systemd.targets.hybrid-sleep.unitConfig.X-Test = true; };
target.configuration = { systemd.targets.test-target.wantedBy = [ "multi-user.target" ]; # We use this service to figure out whether the target was modified. # This is the only way because targets are filtered and therefore not # printed when they are started/stopped. systemd.services.test-service = { bindsTo = [ "test-target.target" ]; serviceConfig.ExecStart = "${pkgs.coreutils}/bin/sleep infinity"; }; };
targetModified.configuration = { imports = [ target.configuration ]; systemd.targets.test-target.unitConfig.X-Test = true; };
targetModifiedStopOnReconfig.configuration = { imports = [ target.configuration ]; systemd.targets.test-target.unitConfig.X-StopOnReconfiguration = true; };
path.configuration = { systemd.paths.test-watch = { wantedBy = [ "paths.target" ]; pathConfig.PathExists = "/testpath"; }; systemd.services.test-watch = { serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${pkgs.coreutils}/bin/touch /testpath-modified"; }; }; };
pathModified.configuration = { imports = [ path.configuration ]; systemd.paths.test-watch.pathConfig.PathExists = lib.mkForce "/testpath2"; };
slice.configuration = { systemd.slices.testslice.sliceConfig.MemoryMax = "1"; # don't allow memory allocation systemd.services.testservice = { serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${pkgs.coreutils}/bin/true"; Slice = "testslice.slice"; }; }; };
sliceModified.configuration = { imports = [ slice.configuration ]; systemd.slices.testslice.sliceConfig.MemoryMax = lib.mkForce null; };
dbusReload.configuration = { config, ... }: let dbusService = { "dbus" = "dbus"; "broker" = "dbus-broker"; } .${config.services.dbus.implementation}; in { # We want to make sure that stc catches this as a reload, # not a restart. systemd.services.${dbusService}.restartTriggers = [ (pkgs.writeText "dbus-reload-dummy" "dbus reload dummy") ]; }; }; };
other = { system.switch.enable = true; users.mutableUsers = true; system.preSwitchChecks.succeeds = '' config="$1" action="$2" echo "this should succeed (config: $config, action: $action)" [ "$action" == "check" ] || [ "$action" == "test" ] ''; specialisation.failingCheck.configuration.system.preSwitchChecks.failEveryTime = '' echo this will fail false ''; }; };
testScript = { nodes, ... }: let originalSystem = nodes.machine.system.build.toplevel; otherSystem = nodes.other.system.build.toplevel; machine = nodes.machine.system.build.toplevel;
# Ensures failures pass through using pipefail, otherwise failing to # switch-to-configuration is hidden by the success of `tee`. stderrRunner = pkgs.writeScript "stderr-runner" '' #! ${pkgs.runtimeShell} set -e set -o pipefail exec env -i "$@" | tee /dev/stderr '';
# Returns a comma separated representation of the given list in sorted # order, that matches the output format of switch-to-configuration sortedUnits = xs: lib.concatStringsSep ", " (builtins.sort builtins.lessThan xs);
dbusService = { "dbus" = "dbus.service"; "broker" = "dbus-broker.service"; } .${nodes.machine.services.dbus.implementation}; in # python '' def switch_to_specialisation(system, name, action="test", fail=False): if name == "": switcher = f"{system}/bin/switch-to-configuration" else: switcher = f"{system}/specialisation/{name}/bin/switch-to-configuration" return run_switch(switcher, action, fail)
# like above but stc = switcher def run_switch(switcher, action="test", fail=False): out = machine.fail(f"{switcher} {action} 2>&1") if fail \ else machine.succeed(f"{switcher} {action} 2>&1") assert_lacks(out, "switch-to-configuration line") # Perl warnings return out
def assert_contains(haystack, needle): if needle not in haystack: print("The haystack that will cause the following exception is:") print("---") print(haystack) print("---") raise Exception(f"Expected string '{needle}' was not found")
def assert_lacks(haystack, needle): if needle in haystack: print("The haystack that will cause the following exception is:") print("---") print(haystack, end="") print("---") raise Exception(f"Unexpected string '{needle}' was found")
machine.wait_for_unit("multi-user.target")
machine.succeed( "${stderrRunner} ${originalSystem}/bin/switch-to-configuration test" ) # This tests whether the /etc/os-release parser works which is a fallback # when /etc/NIXOS is missing. If the parser does not work, switch-to-configuration # would fail. machine.succeed("rm /etc/NIXOS") machine.succeed( "${stderrRunner} ${otherSystem}/bin/switch-to-configuration test" )
boot_loader_text = "Warning: do not know how to make this configuration bootable; please enable a boot loader."
with subtest("pre-switch checks"): machine.succeed("${stderrRunner} ${otherSystem}/bin/switch-to-configuration check") out = switch_to_specialisation("${otherSystem}", "failingCheck", action="check", fail=True) assert_contains(out, "this will fail")
with subtest("actions"): # boot action out = switch_to_specialisation("${machine}", "simpleService", action="boot") assert_contains(out, boot_loader_text) assert_lacks(out, "activating the configuration...") # good indicator of a system activation
# switch action out = switch_to_specialisation("${machine}", "", action="switch") assert_contains(out, boot_loader_text) assert_contains(out, "activating the configuration...") # good indicator of a system activation
# test and dry-activate actions are tested further down below
# invalid action fails the script switch_to_specialisation("${machine}", "", action="broken-action", fail=True) # no action fails the script assert "Usage:" in machine.fail("${machine}/bin/switch-to-configuration 2>&1")
with subtest("init interface version"): # Do not try to switch to an invalid init interface version assert "incompatible" in switch_to_specialisation("${machine}", "brokenInitInterface", fail=True)
with subtest("systemd restarts"): # systemd is restarted when its system.conf changes out = switch_to_specialisation("${machine}", "modifiedSystemConf") assert_contains(out, "restarting systemd...")
with subtest("continuing from an aborted switch"): # An aborted switch will write into a file what it tried to start # and a second switch should continue from this machine.succeed("echo ${dbusService} > /run/nixos/start-list") out = switch_to_specialisation("${machine}", "modifiedSystemConf") assert_contains(out, "starting the following units: ${dbusService}\n")
with subtest("aborts on already locked lock file"): (exitcode, _) = machine.execute( 'flock -x --nb /run/nixos/switch-to-configuration.lock -c "${otherSystem}/bin/switch-to-configuration test"', timeout=5 ) # See man timeout, exit codes above 124 come from the timeout command # We want to make sure that stc actually exited with an error code, # if instead we hit the timeout, then it means that stc hangs, which is # what we don't want # TODO: We cannot match on the exact exit code since it's not consistent between # stc and stc-ng, since errno/last_os_error is not a very stable interface, # we should probably get rid of that in stc-ng once we got rid of the # perl implementation assert exitcode < 124, \ "switch-to-configuration did not abort as expected, " + \ f"probably it timed out instead (exit code: {exitcode}), 124 means timeout"
with subtest("fstab mounts"): switch_to_specialisation("${machine}", "") # add a mountpoint out = switch_to_specialisation("${machine}", "addedMount") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: test.mount\n") # modify the mountpoint's options out = switch_to_specialisation("${machine}", "addedMountOptsModified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_contains(out, "reloading the following units: test.mount\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") # modify the device out = switch_to_specialisation("${machine}", "addedMountDevModified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.mount\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") # modify both out = switch_to_specialisation("${machine}", "addedMount") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.mount\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") # remove the mount out = switch_to_specialisation("${machine}", "") assert_contains(out, "stopping the following units: test.mount\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") # change something about the / mount out = switch_to_specialisation("${machine}", "storeMountModified") assert_lacks(out, "stopping the following units:") assert_contains(out, "NOT restarting the following changed units: -.mount") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
with subtest("swaps"): switch_to_specialisation("${machine}", "") # add a swap out = switch_to_specialisation("${machine}", "swap") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: swapfile.swap") # remove it out = switch_to_specialisation("${machine}", "") assert_contains(out, "stopping swap device: /swapfile") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
with subtest("services"): switch_to_specialisation("${machine}", "") # Nothing happens when nothing is changed out = switch_to_specialisation("${machine}", "") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Start a simple service out = switch_to_specialisation("${machine}", "simpleService") assert_lacks(out, boot_loader_text) # test does not install a bootloader assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: test.service\n")
# Not changing anything doesn't do anything out = switch_to_specialisation("${machine}", "simpleService") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Only changing the description does nothing out = switch_to_specialisation("${machine}", "simpleServiceDifferentDescription") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Restart the simple service out = switch_to_specialisation("${machine}", "simpleServiceModified") assert_contains(out, "stopping the following units: test.service\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_contains(out, "\nstarting the following units: test.service\n") assert_lacks(out, "the following new units were started:")
# Restart the service with stopIfChanged=false out = switch_to_specialisation("${machine}", "simpleServiceNostop") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.service\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Reload the service with reloadIfChanged=true out = switch_to_specialisation("${machine}", "simpleServiceReload") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_contains(out, "reloading the following units: test.service\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Nothing happens when restartIfChanged=false out = switch_to_specialisation("${machine}", "simpleServiceNorestart") assert_lacks(out, "stopping the following units:") assert_contains(out, "NOT restarting the following changed units: test.service\n") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Dry mode shows different messages out = switch_to_specialisation("${machine}", "simpleService", action="dry-activate") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") assert_contains(out, "would start the following units: test.service\n")
out = switch_to_specialisation("${machine}", "", action="test")
# Ensure the service can be started when the activation script isn't in toplevel # This is a lot like "Start a simple service", except activation-only deps could be gc-ed out = run_switch("${nodes.machine.specialisation.simpleServiceSeparateActivationScript.configuration.system.build.separateActivationScript}/bin/switch-to-configuration"); assert_lacks(out, boot_loader_text) # test does not install a bootloader assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: test.service\n") machine.succeed("! test -e /run/current-system/activate") machine.succeed("! test -e /run/current-system/dry-activate") machine.succeed("! test -e /run/current-system/bin/switch-to-configuration")
# Ensure units with multiline values work out = switch_to_specialisation("${machine}", "unitWithMultilineValue") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "restarting the following units:") assert_lacks(out, "the following new units were started:") assert_contains(out, "starting the following units: test.service")
# Ensure \ works in unit names out = switch_to_specialisation("${machine}", "unitWithBackslash") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: escaped\\x2ddash.service\n")
out = switch_to_specialisation("${machine}", "unitWithBackslashModified") assert_contains(out, "stopping the following units: escaped\\x2ddash.service\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_contains(out, "\nstarting the following units: escaped\\x2ddash.service\n") assert_lacks(out, "the following new units were started:")
# Ensure units can start with a dash out = switch_to_specialisation("${machine}", "unitStartingWithDash") assert_contains(out, "stopping the following units: escaped\\x2ddash.service\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: -.service\n")
# The regression only occurs when reloading units out = switch_to_specialisation("${machine}", "unitStartingWithDashModified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_contains(out, "reloading the following units: -.service") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Ensure units that require changed units are properly reloaded out = switch_to_specialisation("${machine}", "unitWithRequirement") assert_contains(out, "stopping the following units: -.service\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: required-service.service, test-service.service\n")
out = switch_to_specialisation("${machine}", "unitWithRequirementModified") assert_contains(out, "stopping the following units: required-service.service\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_contains(out, "\nstarting the following units: required-service.service, test-service.service\n") assert_lacks(out, "the following new units were started:")
# Unless the unit asks to be not restarted out = switch_to_specialisation("${machine}", "unitWithRequirementModifiedNostart") assert_contains(out, "stopping the following units: required-service.service\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_contains(out, "\nstarting the following units: required-service.service\n") assert_lacks(out, "the following new units were started:")
# Ensure templated units are restarted when the base unit changes switch_to_specialisation("${machine}", "unitWithTemplate") out = switch_to_specialisation("${machine}", "unitWithTemplateModified") assert_contains(out, "stopping the following units: instantiated@one.service, instantiated@two.service\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_contains(out, "\nstarting the following units: instantiated@one.service, instantiated@two.service\n") assert_lacks(out, "the following new units were started:")
with subtest("failing units"): # Let the simple service fail switch_to_specialisation("${machine}", "simpleServiceModified") out = switch_to_specialisation("${machine}", "simpleServiceFailing", fail=True) assert_contains(out, "stopping the following units: test.service\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_contains(out, "\nstarting the following units: test.service\n") assert_lacks(out, "the following new units were started:") assert_contains(out, "warning: the following units failed: test.service\n") assert_contains(out, "Main PID:") # output of systemctl
# A unit that gets into autorestart without failing is not treated as failed out = switch_to_specialisation("${machine}", "autorestartService") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: autorestart.service\n") machine.systemctl('stop autorestart.service') # cancel the 20y timer
# Switching to the same system should do nothing (especially not treat the unit as failed) out = switch_to_specialisation("${machine}", "autorestartService") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: autorestart.service\n") machine.systemctl('stop autorestart.service') # cancel the 20y timer
# If systemd thinks the unit has failed and is in autorestart, we should show it as failed out = switch_to_specialisation("${machine}", "autorestartServiceFailing", fail=True) assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") assert_contains(out, "warning: the following units failed: autorestart.service\n") assert_contains(out, "Main PID:") # output of systemctl
with subtest("unit file parser"): # Switch to a well-known state switch_to_specialisation("${machine}", "simpleServiceNostop")
# Add a section out = switch_to_specialisation("${machine}", "simpleServiceWithExtraSection") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.service\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Rename it out = switch_to_specialisation("${machine}", "simpleServiceWithExtraSectionOtherName") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.service\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Remove it out = switch_to_specialisation("${machine}", "simpleServiceNostop") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.service\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# [Install] section is ignored out = switch_to_specialisation("${machine}", "simpleServiceWithInstallSection") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Add a key out = switch_to_specialisation("${machine}", "simpleServiceWithExtraKey") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.service\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Change its value out = switch_to_specialisation("${machine}", "simpleServiceWithExtraKeyOtherValue") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.service\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Rename it out = switch_to_specialisation("${machine}", "simpleServiceWithExtraKeyOtherName") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.service\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Remove it out = switch_to_specialisation("${machine}", "simpleServiceNostop") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.service\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Add a reload trigger out = switch_to_specialisation("${machine}", "simpleServiceReloadTrigger") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_contains(out, "reloading the following units: test.service\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Modify the reload trigger out = switch_to_specialisation("${machine}", "simpleServiceReloadTriggerModified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_contains(out, "reloading the following units: test.service\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Modify the reload trigger and something else out = switch_to_specialisation("${machine}", "simpleServiceReloadTriggerModifiedAndSomethingElse") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test.service\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Remove the reload trigger out = switch_to_specialisation("${machine}", "simpleServiceReloadTriggerModifiedSomethingElse") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
with subtest("restart and reload by activation script"): switch_to_specialisation("${machine}", "simpleServiceNorestart") out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script") assert_contains(out, "stopping the following units: test.service\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "restarting the following units:") assert_contains(out, "\nstarting the following units: ${ sortedUnits [ "no-restart-service.service" "reload-triggers-and-restart-by-as.service" "simple-reload-service.service" "simple-restart-service.service" "simple-service.service" "templated-no-restart-service@instance.service" "templated-reload-triggers-and-restart-by-as@instance.service" "templated-simple-reload-service@instance.service" "templated-simple-restart-service@instance.service" "templated-simple-service@instance.service" ] }\n") assert_contains(out, "the following new units were started: ${ sortedUnits [ "no-restart-service.service" "reload-triggers-and-restart-by-as.service" "reload-triggers-and-restart.service" "reload-triggers.service" "simple-reload-service.service" "simple-restart-service.service" "simple-service.service" "system-templated\\\\x2dno\\\\x2drestart\\\\x2dservice.slice" "system-templated\\\\x2dreload\\\\x2dtriggers.slice" "system-templated\\\\x2dreload\\\\x2dtriggers\\\\x2dand\\\\x2drestart.slice" "system-templated\\\\x2dreload\\\\x2dtriggers\\\\x2dand\\\\x2drestart\\\\x2dby\\\\x2das.slice" "system-templated\\\\x2dsimple\\\\x2dreload\\\\x2dservice.slice" "system-templated\\\\x2dsimple\\\\x2drestart\\\\x2dservice.slice" "system-templated\\\\x2dsimple\\\\x2dservice.slice" "templated-no-restart-service@instance.service" "templated-reload-triggers-and-restart-by-as@instance.service" "templated-reload-triggers-and-restart@instance.service" "templated-reload-triggers@instance.service" "templated-simple-reload-service@instance.service" "templated-simple-restart-service@instance.service" "templated-simple-service@instance.service" ] }\n") # Switch to the same system where the example services get restarted # and reloaded by the activation script out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_contains(out, "reloading the following units: ${ sortedUnits [ "reload-triggers-and-restart.service" "reload-triggers.service" "simple-reload-service.service" "templated-reload-triggers-and-restart@instance.service" "templated-reload-triggers@instance.service" "templated-simple-reload-service@instance.service" ] }\n") assert_contains(out, "restarting the following units: ${ sortedUnits [ "reload-triggers-and-restart-by-as.service" "simple-restart-service.service" "simple-service.service" "templated-reload-triggers-and-restart-by-as@instance.service" "templated-simple-restart-service@instance.service" "templated-simple-service@instance.service" ] }\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") # Switch to the same system and see if the service gets restarted when it's modified # while the fact that it's supposed to be reloaded by the activation script is ignored. out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script-modified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_contains(out, "reloading the following units: ${ sortedUnits [ "reload-triggers.service" "simple-reload-service.service" "templated-reload-triggers@instance.service" "templated-simple-reload-service@instance.service" ] }\n") assert_contains(out, "restarting the following units: ${ sortedUnits [ "reload-triggers-and-restart-by-as.service" "reload-triggers-and-restart.service" "simple-restart-service.service" "simple-service.service" "templated-reload-triggers-and-restart-by-as@instance.service" "templated-reload-triggers-and-restart@instance.service" "templated-simple-restart-service@instance.service" "templated-simple-service@instance.service" ] }\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") # The same, but in dry mode out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script", action="dry-activate") assert_lacks(out, "would stop the following units:") assert_lacks(out, "would NOT stop the following changed units:") assert_contains(out, "would reload the following units: ${ sortedUnits [ "reload-triggers.service" "simple-reload-service.service" "templated-reload-triggers@instance.service" "templated-simple-reload-service@instance.service" ] }\n") assert_contains(out, "would restart the following units: ${ sortedUnits [ "reload-triggers-and-restart-by-as.service" "reload-triggers-and-restart.service" "simple-restart-service.service" "simple-service.service" "templated-reload-triggers-and-restart-by-as@instance.service" "templated-reload-triggers-and-restart@instance.service" "templated-simple-restart-service@instance.service" "templated-simple-service@instance.service" ] }\n") assert_lacks(out, "\nwould start the following units:")
with subtest("socket-activated services"): # Socket-activated services don't get started, just the socket machine.fail("[ -S /run/test.sock ]") out = switch_to_specialisation("${machine}", "simple-socket") # assert_lacks(out, "stopping the following units:") not relevant assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: socket-activated.socket\n") machine.succeed("[ -S /run/test.sock ]")
# Changing a non-activated service does nothing out = switch_to_specialisation("${machine}", "simple-socket-service-modified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") machine.succeed("[ -S /run/test.sock ]") # The unit is properly activated when the socket is accessed if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello": raise Exception("Socket was not properly activated") # idk how that would happen tbh
# Changing an activated service with stopIfChanged=false restarts the service out = switch_to_specialisation("${machine}", "simple-socket") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: socket-activated.service\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") machine.succeed("[ -S /run/test.sock ]") # Socket-activation of the unit still works if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello": raise Exception("Socket was not properly activated after the service was restarted")
# Changing an activated service with stopIfChanged=true stops the service and # socket and starts the socket out = switch_to_specialisation("${machine}", "simple-socket-stop-if-changed") assert_contains(out, "stopping the following units: socket-activated.service, socket-activated.socket\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_contains(out, "\nstarting the following units: socket-activated.socket\n") assert_lacks(out, "the following new units were started:") machine.succeed("[ -S /run/test.sock ]") # Socket-activation of the unit still works if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello": raise Exception("Socket was not properly activated after the service was restarted")
# Changing a reload trigger of a socket-activated unit only reloads it out = switch_to_specialisation("${machine}", "simple-socket-stop-if-changed-and-reloadtrigger") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_contains(out, "reloading the following units: socket-activated.service\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units: socket-activated.socket") assert_lacks(out, "the following new units were started:") machine.succeed("[ -S /run/test.sock ]") # Socket-activation of the unit still works if machine.succeed("socat - UNIX-CONNECT:/run/test.sock") != "hello": raise Exception("Socket was not properly activated after the service was restarted")
with subtest("mounts"): switch_to_specialisation("${machine}", "mount") out = machine.succeed("mount | grep 'on /testmount'") assert_contains(out, "size=1024k") # Changing options reloads the unit out = switch_to_specialisation("${machine}", "mountOptionsModified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_contains(out, "reloading the following units: testmount.mount\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") # It changed out = machine.succeed("mount | grep 'on /testmount'") assert_contains(out, "size=10240k") # Changing anything but `Options=` restarts the unit out = switch_to_specialisation("${machine}", "mountModified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: testmount.mount\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") # It changed out = machine.succeed("mount | grep 'on /testmount'") assert_contains(out, "ramfs")
with subtest("timers"): switch_to_specialisation("${machine}", "timer") out = machine.succeed("systemctl show test-timer.timer") assert_contains(out, "OnCalendar=2014-03-25 02:59:56 UTC") out = switch_to_specialisation("${machine}", "timerModified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following units:") assert_lacks(out, "reloading the following units:") assert_contains(out, "\nrestarting the following units: test-timer.timer\n") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") # It changed out = machine.succeed("systemctl show test-timer.timer") assert_contains(out, "OnCalendar=Fri 2012-11-23 16:00:00")
with subtest("targets"): # Modifying some special targets like hybrid-sleep.target does nothing out = switch_to_specialisation("${machine}", "hybridSleepModified") assert_contains(out, "stopping the following units: test-timer.timer\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:")
# Adding a new target starts it out = switch_to_specialisation("${machine}", "target") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: test-target.target\n")
# Changing a target doesn't print anything because the unit is filtered machine.systemctl("start test-service.service") out = switch_to_specialisation("${machine}", "targetModified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") machine.succeed("systemctl is-active test-service.service") # target was not restarted
# With X-StopOnReconfiguration, the target gets stopped and started out = switch_to_specialisation("${machine}", "targetModifiedStopOnReconfig") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") machine.fail("systemctl is-active test-service.servce") # target was restarted
# Remove the target by switching to the old specialisation out = switch_to_specialisation("${machine}", "timerModified") assert_contains(out, "stopping the following units: test-target.target\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: test-timer.timer\n")
with subtest("paths"): out = switch_to_specialisation("${machine}", "path") assert_contains(out, "stopping the following units: test-timer.timer\n") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: test-watch.path\n") machine.fail("test -f /testpath-modified")
# touch the file, unit should be triggered machine.succeed("touch /testpath") machine.wait_until_succeeds("test -f /testpath-modified") machine.succeed("rm /testpath /testpath-modified") machine.systemctl("stop test-watch.service") switch_to_specialisation("${machine}", "pathModified") machine.succeed("touch /testpath") machine.fail("test -f /testpath-modified") machine.succeed("touch /testpath2") machine.wait_until_succeeds("test -f /testpath-modified")
# This test ensures that changes to slice configuration get applied. # We test this by having a slice that allows no memory allocation at # all and starting a service within it. If the service crashes, the slice # is applied and if we modify the slice to allow memory allocation, the # service should successfully start. with subtest("slices"): machine.succeed("echo 0 > /proc/sys/vm/panic_on_oom") # allow OOMing out = switch_to_specialisation("${machine}", "slice") # assert_lacks(out, "stopping the following units:") not relevant assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") machine.fail("systemctl start testservice.service")
out = switch_to_specialisation("${machine}", "sliceModified") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_lacks(out, "reloading the following units:") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") machine.succeed("systemctl start testservice.service") machine.succeed("echo 1 > /proc/sys/vm/panic_on_oom") # disallow OOMing
with subtest("dbus reloads"): out = switch_to_specialisation("${machine}", "") out = switch_to_specialisation("${machine}", "dbusReload") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") assert_contains(out, "reloading the following units: ${dbusService}\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") '';}