diff --git a/default.nix b/default.nix index fd1c357..1e064a6 100644 --- a/default.nix +++ b/default.nix @@ -25,7 +25,13 @@ let eval = evalModules { modules = [ - { + ({ lib, pkgs, ... }: { + _module.args = { + utils = import "${nixpkgs}/nixos/lib/utils.nix" { + inherit lib pkgs; + config.systemd.globalEnvironment = {}; + }; + }; nixpkgs = { source = nixpkgs; overlays = [ overlay ]; @@ -33,7 +39,7 @@ let "python-2.7.18.8" ]; }; - } + }) device.module liminix-config ]; @@ -57,7 +63,7 @@ let ]; }).config.system; in { - inherit evalModules; + inherit evalModules config; outputs = config.system.outputs // { default = config.system.outputs.${config.hardware.defaultOutput}; diff --git a/lib/eval-config.nix b/lib/eval-config.nix index 4c3c009..986e9d5 100644 --- a/lib/eval-config.nix +++ b/lib/eval-config.nix @@ -14,7 +14,7 @@ in "${modulesPath}/busybox.nix" "${modulesPath}/hostname.nix" "${modulesPath}/kernel" - "${modulesPath}/s6" + "${modulesPath}/systemd" "${modulesPath}/users.nix" "${modulesPath}/outputs.nix" "${modulesPath}/nixpkgs.nix" diff --git a/modules/base.nix b/modules/base.nix index 5107e1e..a12cd6e 100644 --- a/modules/base.nix +++ b/modules/base.nix @@ -2,7 +2,7 @@ ## ============ -{ lib, pkgs, config, ...}: +{ lib, pkgs, utils, config, ...}: let inherit (lib) mkEnableOption mkOption types isDerivation hasAttr concatStringsSep mapAttrsToList; inherit (pkgs.pseudofile) dir symlink; @@ -43,9 +43,12 @@ in { ''; }; }; + + # deprecated services = mkOption { type = types.attrsOf type_service; }; + system.callService = mkOption { type = types.functionTo (types.functionTo types.anything); }; @@ -129,10 +132,12 @@ in { # By default, we enable cross-compilation support. nixpkgs.buildPlatform = lib.mkDefault builtins.currentSystem; - defaultProfile.packages = with pkgs; - [ s6 s6-init-bin execline s6-linux-init s6-rc ]; # Set the useful PS1 prompt by default. defaultProfile.environmentVariables.PS1 = lib.mkDefault config.defaultProfile.prompt; + defaultProfile.packages = with pkgs; [ + # execline + systemd + ]; boot.commandLine = [ "panic=10 oops=panic init=/bin/init loglevel=8" diff --git a/modules/busybox.nix b/modules/busybox.nix index 718cafd..d22a8c3 100644 --- a/modules/busybox.nix +++ b/modules/busybox.nix @@ -51,7 +51,7 @@ let in { options = { programs.busybox = { - applets = mkOption { + applets = mkOption { type = types.listOf types.str; description = "Applets required"; default = []; @@ -62,13 +62,19 @@ in { # other strings are also used description = "Other busybox config flags that do not map directly to applet names (often prefixed FEATURE_)"; type = types.attrsOf types.nonEmptyStr; - default = { }; - example = { FEATURE_DD_IBS_OBS = "y"; }; + default = { }; + example = { FEATURE_DD_IBS_OBS = "y"; }; + }; + package = mkOption { + type = types.package; + readOnly = true; + internal = true; }; }; }; config = { programs.busybox = { + package = busybox; applets = minimalApplets; options = { ASH_ECHO = "y"; diff --git a/modules/s6/default.nix b/modules/s6/default.nix index e1ce9c8..376d4ce 100644 --- a/modules/s6/default.nix +++ b/modules/s6/default.nix @@ -186,8 +186,11 @@ in { }; }; }; + # bin = dir { + # init = symlink "${s6-init-bin}/bin/init"; + # }; bin = dir { - init = symlink "${s6-init-bin}/bin/init"; + init = symlink "${pkgs.systemd}/bin/init"; }; }; }; diff --git a/modules/s6/scripts/rc.shutdown b/modules/s6/scripts/rc.shutdown deleted file mode 100755 index 81fac67..0000000 --- a/modules/s6/scripts/rc.shutdown +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - - -### Things to do before hardware halt/reboot/poweroff. -### Ideally, it should be a single call to the service manager, -### telling it to bring all the services down. - -### If your s6-linux-init-maker invocation was made with the -1 -### option, messages from rc.shutdown will appear on /dev/console -### as well as be logged by the catch-all logger. -### If your s6-linux-init-maker invocation did NOT include the -1 -### option, messages from rc.shutdown will only be logged by the -### catch-all logger and will NOT appear on /dev/console. In order -### to print them to /dev/console instead, you may want to -### uncomment the following line: -exec >/dev/console 2>&1 - -### If your services are managed by s6-rc: -exec s6-rc -v2 -bDa change diff --git a/modules/s6/scripts/rc.shutdown.final b/modules/s6/scripts/rc.shutdown.final deleted file mode 100755 index 5344b7a..0000000 --- a/modules/s6/scripts/rc.shutdown.final +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -e - -## s6-linux-init-shutdownd never tells s6-svscan to exit, so if -## you're running s6-linux-init, it's normal that your -## .s6-svscan/finish script is not executed. - -## The place where you want to hack things is /etc/rc.shutdown.final, -## which is run by the stage 4 script right before the hard reboot. -## So you can do dirty stuff [...] which should clean up the -## s6-supervise and the foreground, and give control to -## .s6-svscan/finish. - -## -- Laurent Bercot on skaware mailing list, -## https://skarnet.org/lists/skaware/1913.html - -exec >/dev/console 2>&1 - -# down, exit supervisor, wait, stay down -s6-svc -dxwD /run/service/s6-linux-init-shutdownd -# HUP, exit supervisor, wait, down -s6-svc -hxwd /run/service/s6-svscan-log -s6-svscanctl -b /run/service # abort diff --git a/modules/s6/scripts/runlevel b/modules/s6/scripts/runlevel deleted file mode 100755 index 3c2cfcd..0000000 --- a/modules/s6/scripts/runlevel +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -e - -### This script is called once at boot time by rc.init, and is -### also called by the runleveld service every time the user -### requests a machine state change via telinit. -### Ideally, it should just be a call to the service manager. - -test "$#" -gt 0 || { echo 'runlevel: fatal: too few arguments' 1>&2 ; exit 100 ; } - - -### If your services are managed by s6-rc: -exec s6-rc -v2 -up change "$1" diff --git a/modules/systemd/default.nix b/modules/systemd/default.nix new file mode 100644 index 0000000..6dfdc3a --- /dev/null +++ b/modules/systemd/default.nix @@ -0,0 +1,150 @@ +{ + pkgs, + lib, + config, + utils, + ... +}: +let + inherit (lib) + mapAttrs' + nameValuePair + mkMerge + mapAttrsToList + mkOption + ; + inherit (pkgs.pseudofile) dir symlink; + inherit (utils.systemdUtils.lib) + targetToUnit + serviceToUnit + ; + + systemd-types = import ./types.nix { inherit pkgs utils lib; busybox = config.programs.busybox.package; }; + + units-texts = mapAttrs' ( + _: unit: + nameValuePair unit.name { + file = unit.text; + mode = "0644"; + } + ) config.systemd.units; + units-aliases = mkMerge ( + mapAttrsToList ( + _: unit: + mkMerge ( + map (aka: { + ${aka} = symlink "${unit.name}"; + }) (unit.aliases or [ ]) + ) + ) config.systemd.units + ); + units-extraWants = mkMerge ( + mapAttrsToList ( + _: unit: + mkMerge ( + map (unit2: { + "${unit2}.wants" = dir { + ${unit.name} = symlink "../${unit.name}"; + }; + }) (unit.wantedBy or [ ]) + ) + ) config.systemd.units + ); + units-extraUpholds = mkMerge ( + mapAttrsToList ( + _: unit: + mkMerge ( + map (unit2: { + "${unit2}.upholds" = dir { + ${unit.name} = symlink "../${unit.name}"; + }; + }) (unit.upheldBy or [ ]) + ) + ) config.systemd.units + ); + units-extraRequires = mkMerge ( + mapAttrsToList ( + _: unit: + mkMerge ( + map (unit2: { + "${unit2}.requires" = dir { + ${unit.name} = symlink "../${unit.name}"; + }; + }) (unit.requiredBy or [ ]) + ) + ) config.systemd.units + ); +in +{ + options = { + systemd = { + units = mkOption { + type = systemd-types.units; + }; + services = mkOption { + type = systemd-types.services; + }; + targets = mkOption { + type = systemd-types.targets; + }; + }; + }; + config = { + systemd = { + units = mkMerge [ + (mapAttrs' (_: service: nameValuePair service.name (serviceToUnit service)) config.systemd.services) + (mapAttrs' (_: target: nameValuePair target.name (targetToUnit target)) config.systemd.targets) + ]; + services = { + getty = { + wantedBy = [ "default.target" ]; + unitConfig = { + Description = "Serial Shell"; + Before = [ "default.target" ]; + }; + script = '' + # . /etc/profile + exec /bin/ash < /dev/ttyS0 > /dev/ttyS0 2> /dev/ttyS0 + ''; + }; + }; + targets = { + default = { }; + sysinit = { }; + }; + }; + + kernel.config = { + CGROUPS = "y"; + DEVTMPFS = "y"; + INOTIFY_USER = "y"; + SIGNALFD = "y"; + TIMERFD = "y"; + EPOLL = "y"; + UNIX = "y"; + SYSFS = "y"; + PROC_FS = "y"; + FHANDLE = "y"; + }; + boot.commandLine = [ + "systemd.log_level=7" + #"systemd.crash_shell=true" + ]; + filesystem = dir { + etc = dir { + systemd = dir { + system = dir (mkMerge [ + units-texts + units-aliases + units-extraWants + units-extraUpholds + units-extraRequires + ]); + }; + }; + bin = dir { + init = symlink "${pkgs.systemd}/bin/init"; + }; + }; + }; +} diff --git a/modules/systemd/types.nix b/modules/systemd/types.nix new file mode 100644 index 0000000..30ca1fe --- /dev/null +++ b/modules/systemd/types.nix @@ -0,0 +1,30 @@ +{ + pkgs, + lib, + utils, + busybox +}: +let + inherit (utils.systemdUtils.lib) serviceConfig unitConfig; + inherit (utils.systemdUtils.unitOptions) stage2ServiceOptions; + stage2ServiceConfig = { + imports = [ serviceConfig ]; + # Default path for systemd services. Should be quite minimal. + config.path = lib.mkAfter [ + busybox + # pkgs.coreutils + # pkgs.gnugrep + # pkgs.gnused + pkgs.systemd + ]; + }; +in +{ + inherit (utils.systemdUtils.types) units targets; + services = lib.types.attrsOf (lib.types.submodule [ + { enableStrictShellChecks = false; } + unitConfig + stage2ServiceOptions + stage2ServiceConfig + ]); +} diff --git a/overlay.nix b/overlay.nix index 891e9a0..c79866c 100644 --- a/overlay.nix +++ b/overlay.nix @@ -259,7 +259,12 @@ extraPkgs // { patches = o.patches ++ [ ./pkgs/qemu/arm-image-friendly-load-addr.patch ]; - }); in q.override { nixosTestRunner = true; sdlSupport = false; }; + }); in q.override { + vde2 = null; + nixosTestRunner = true; + sdlSupport = false; + hostCpuTargets = [ "mips-softmmu" ]; + }; rsyncSmall = let r = prev.rsync.overrideAttrs(o: { @@ -284,6 +289,192 @@ extraPkgs // { strace = prev.strace.override { libunwind = null; }; + getent = + prev.callPackage ({ + lib, + stdenv, + fetchFromGitHub, + }: + + stdenv.mkDerivation rec { + pname = "musl-utils"; + version = "1.1.12-r7"; + + src = fetchFromGitHub { + owner = "boltlinux"; + repo = "musl-utils"; + rev = version; + hash = "sha256-q9CbOyK0Psw3YJnIT3yPRWuwr40nxLZt4RexuOHAUuw="; + }; + + nativeBuildInputs = [ + prev.autoconf + prev.automake + ]; + + preConfigure = '' + autoreconf -i + ''; + + buildPhase = '' + make -C src getent + ''; + + installPhase = '' + mkdir -p $out/bin/ + cp src/getent $out/bin/ + ''; + + meta = { + description = "Alpine Linux' getconf, getent and iconv implementations"; + homepage = "https://github.com/boltlinux/musl-utils"; + license = lib.licenses.free; # FIXME: nix-init did not find a license + maintainers = with lib.maintainers; [ ]; + mainProgram = "musl-utils"; + platforms = lib.platforms.all; + }; + }) { }; + + writeShellScriptBin = name: text: + final.writeTextFile { + inherit name; + executable = true; + destination = "/bin/${name}"; + text = '' + #!/bin/ash + ${text} + ''; + checkPhase = '' + ${final.stdenv.shellDryRun} "$target" + ''; + meta.mainProgram = name; + }; + + systemd = + let base = prev.systemd.override { + kbd = ""; + coreutils = ""; + bash = null; + bashInteractive = ""; + + withAcl = false; + withAnalyze = false; + withApparmor = false; + withAudit = false; + withBootloader = false; + withCompression = false; + withCoredump = false; + withCryptsetup = false; + withRepart = false; + withDocumentation = false; + withEfi = false; + withFido2 = false; + withHomed = false; + withHostnamed = false; + withHwdb = false; + withImportd = false; + withIptables = false; + withKmod = false; + withLibBPF = false; + withLibidn2 = false; + withLocaled = false; + withLogind = false; + withMachined = false; + withNetworkd = false; + withNss = false; + withOomd = false; + withPam = false; + withPasswordQuality = false; + withPCRE2 = false; + withPolkit = false; + withPortabled = false; + withQrencode = false; + withRemote = false; + withResolved = false; + withShellCompletions = false; + withSysusers = false; + withSysupdate = false; + withTimedated = false; + withTimesyncd = false; + withTpm2Tss = false; + withUkify = false; + withUserDb = false; + withUtmp = false; + withVmspawn = false; + withKernelInstall = false; + withLibarchive = false; + }; + in base.overrideAttrs (o: { + mesonFlags = o.mesonFlags ++ [ + # "--optimization=s" + "--default-library=static" + "--buildtype=minsize" + # (final.lib.mesonBool "static-libsystemd" true) + # (final.lib.mesonBool "standalone-binaries" true) + + # (final.lib.mesonBool "link-udev-shared" false) + # (final.lib.mesonBool "link-executor-shared" false) + # (final.lib.mesonBool "link-systemctl-shared" false) + # (final.lib.mesonBool "link-networkd-shared" false) + # (final.lib.mesonBool "link-timesyncd-shared" false) + # (final.lib.mesonBool "link-journalctl-shared" false) + # (final.lib.mesonBool "link-boot-shared" false) + # (final.lib.mesonBool "link-portabled-shared" false) + ]; + postInstall = o.postInstall + '' + rm -rf $out/share + rm $out/lib/libudev.so* + rm -rf $out/lib/systemd/catalog + rm -rf $out/lib/systemd/system-generators + rm $out/lib/systemd/systemd-backlight + rm $out/lib/systemd/systemd-battery-check + rm $out/lib/systemd/systemd-hibernate-resume + rm $out/lib/systemd/systemd-makefs + rm $out/lib/systemd/systemd-nsresourced + rm $out/lib/systemd/systemd-nsresourcework + rm $out/lib/systemd/systemd-shutdown + rm $out/lib/systemd/systemd-sleep + rm $out/lib/systemd/systemd-binfmt + rm $out/lib/systemd/systemd-growfs + rm $out/lib/systemd/systemd-mountfsd + rm $out/lib/systemd/systemd-mountwork + rm $out/lib/systemd/systemd-network-generator + rm $out/lib/systemd/systemd-pstore + rm $out/lib/systemd/systemd-remount-fs + rm $out/lib/systemd/systemd-reply-password + rm $out/lib/systemd/systemd-rfkill + rm $out/lib/systemd/systemd-socket-proxyd + rm $out/lib/systemd/systemd-ssh-proxy + rm $out/lib/systemd/systemd-storagetm + rm $out/lib/systemd/systemd-volatile-root + rm $out/lib/systemd/systemd-xdg-autostart-condition + rm -rf $out/example + rm $out/bin/bootctl + rm $out/bin/systemd-nspawn + rm $out/bin/systemd-ac-power + rm $out/bin/systemd-dissect + rm $out/bin/systemd-ask-password + rm $out/bin/systemd-cgls + rm $out/bin/systemd-cgtop + rm $out/bin/systemd-creds + rm $out/bin/systemd-delta + rm $out/bin/systemd-detect-virt + rm $out/bin/systemd-escape + rm $out/bin/systemd-id128 + rm $out/bin/systemd-machine-id-setup + rm $out/bin/systemd-path + rm $out/bin/systemd-run + rm $out/bin/systemd-socket-activate + rm $out/bin/systemd-stdio-bridge + rm $out/bin/systemd-sysext + rm $out/bin/systemd-tty-ask-password-agent + rm $out/bin/systemd-vpick + + # rm $out/lib/libsystemd.a + # rm $out/lib/systemd/libsystemd-shared-256.so + ''; + }); + ubootQemuAarch64 = final.buildUBoot { defconfig = "qemu_arm64_defconfig"; extraMeta.platforms = ["aarch64-linux"];