Browse Source

Services: apache2, getty and oci image export

Signed-off-by: Magic_RB <magic_rb@redalder.org>
master
Magic_RB 1 month ago
parent
commit
f913a13d3d
Signed by: Magic_RB GPG Key ID: 08D5287CC5DDCA0E
10 changed files with 278 additions and 58 deletions
  1. +6
    -2
      lib/make-bundle.nix
  2. +38
    -22
      lib/make-system.nix
  3. +20
    -0
      lib/write-substituted-shell-script.nix
  4. +21
    -2
      modules/init.nix
  5. +8
    -9
      modules/initrd/default.nix
  6. +61
    -23
      modules/runit/default.nix
  7. +1
    -0
      modules/runit/stage-1.sh
  8. +16
    -0
      modules/runit/stage-2.sh
  9. +62
    -0
      modules/services/apache2.nix
  10. +45
    -0
      modules/services/getty.nix

+ 6
- 2
lib/make-bundle.nix View File

@ -9,13 +9,17 @@ in
runCommandNoCC name
{}
''
set -x
shopt -s dotglob
mkdir $out
cp -r ${path}/* $out
for path in $(cat ${references}); do
test -f $path && ( mkdir -p $out/$(dirname $path) ; cp -r $path $out/$path )
test -d $path && ( mkdir -p $out/$path ; cp -r $path/* $out/$path )
if [[ -f $path ]]; then
mkdir -p $out/$(dirname $path) ; cp -r $path $out/$path
elif [[ -d $path ]]; then
mkdir -p $out/$path ; cp -r $path/* $out/$path
fi
done
''

+ 38
- 22
lib/make-system.nix View File

@ -1,8 +1,7 @@
{ pkgs, system
, runCommandNoCC, lib
{ pkgs, callPackage, system, dockerTools
, runCommandNoCC, lib, nglib
, busybox, bootloaderLinux
, config, name
, nglib
}:
let
@ -15,6 +14,8 @@ let
../modules/system.nix
../modules/assertions.nix
../modules/bootloader
../modules/services/apache2.nix
../modules/services/getty.nix
];
evaledModules = lib.evalModules
@ -43,35 +44,50 @@ let
(with configValid;
''
mkdir $out
${if activation.enable then
"ln -s ${activation.script} $out/activation"
else ""}
ln -s ${init.script} $out/init
${if initramfs.enable then
"ln -s ${initramfs.image} $out/initrd.img"
else ""}
${if bootloader.enable then
"ln -s ${bootloaderLinux} $out/bootloader"
else ""}
'');
# mkdir $out
# ${lib.optionalString activation.enable
# "# ln -s ${activation.script} $out/activation"}
# ${lib.optionalString initramfs.enable
# "ln -s ${initramfs.image} $out/initrd.img"}
# ${lib.optionalString bootloader.enable
# "ln -s ${nglib.makeBootloader { inherit (bootloader) kernelExtraConfig; }} $out/bootloader"}
systemBundle = nglib.makeBundle
{ name = "system";
{ name = "${name}-bundle";
path = systemPath;
};
initramfsImage = nglib.makeInitramfs
{ name = "initrd.img";
{ name = "${name}-initrd.img";
path = systemBundle;
};
qemu = {
run = pkgs.writeShellScript "qemu-run.sh" ''
${pkgs.qemu}/bin/qemu-system-x86_64 -kernel ${systemPath}/bootloader/bzImage -nographic -append "console=ttyS0" -initrd ${systemPath}/initrd.img -m 512
${pkgs.qemu}/bin/qemu-system-x86_64 -kernel ${systemPath}/bootloader -initrd ${systemPath}/initrd.img -nographic -append "console=ttyS0" -m 512
''; # /run/current-system/kernel
};
self = {
system = systemPath;
bundle = systemBundle;
initramfs = initramfsImage;
config = evaledModules.config;
iso = callPackage ./make-iso-image.nix { system = self; };
inherit qemu;
ociImage = dockerTools.buildLayeredImage {
inherit name;
tag = "latest";
contents = [ systemBundle ];
config = {
Entrypoint =
[ "/init"
];
};
};
};
in
{
system = systemPath;
bundle = systemBundle;
initramfs = initramfsImage;
inherit qemu;
}
self

+ 20
- 0
lib/write-substituted-shell-script.nix View File

@ -0,0 +1,20 @@
{ runCommandNoCCLocal
, runtimeShell
, busybox
}:
{
name
, file
, substitutes
}:
runCommandNoCCLocal name ({
nativeBuildInputs = [ busybox ];
} // substitutes)
''
TMPFILE=$(mktemp)
substituteAll ${file} $TMPFILE
touch $out
echo "#! ${runtimeShell}" > $out
cat $TMPFILE >> $out
chmod +x $out
''

+ 21
- 2
modules/init.nix View File

@ -17,9 +17,28 @@ in
description = "init script.";
type = types.path;
};
services = mkOption {
type = types.attrsOf (types.submodule {
options = {
dependencies = mkOption {
description = "Service dependencies";
type = types.listOf (types.str);
default = [];
};
script = mkOption {
description = "Service script";
type = types.path;
default = "";
};
};
});
description = "Service definitions";
default = {};
};
};
config = {
# TODO add assertions for this module
};
# TODO add assertions for this module
};
}

+ 8
- 9
modules/initrd/default.nix View File

@ -1,4 +1,4 @@
{ pkgs, lib, config, ... }:
{ pkgs, lib, config, nglib, ... }:
with lib;
let
cfg = config.initrd;
@ -14,14 +14,13 @@ in
}
(mkIf cfg.enable {
type = "initrd";
script = pkgs.runCommandNoCCLocal "init" (with pkgs; {
inherit eudev bash busybox;
nativeBuildInputs = [ pkgs.busybox ];
})
''
substituteAll ${pkgs.writeShellScript "init" (builtins.readFile ./init.sh)} $out
chmod +x $out
'';
script = nglib.writeSubstitutedShellScript {
name = "init";
file = ./init.sh;
substitutes = with pkgs; {
inherit eudev bash busybox;
};
};
})
];
}

+ 61
- 23
modules/runit/default.nix View File

@ -1,11 +1,17 @@
{ pkgs, lib, config, ... }:
{ pkgs, lib, config, nglib, ... }:
with lib;
let
cfg = config.runit;
cfgInit = config.init;
in
{
options.runit = {
enable = mkEnableOption "Enable runit";
runtimeServiceDirectory = mkOption {
description = "where runsvdir should create superwise and log directories for services";
type = types.path;
default = "/run/sv";
};
stages = mkOption {
description = "runit stages";
default = {};
@ -14,46 +20,78 @@ in
stage-1 = mkOption {
type = types.path;
description = "runit stage 1";
default = pkgs.writeShellScript "1"
''
${builtins.readFile ./stage-1.sh}
'';
default = nglib.writeSubstitutedShellScript {
name = "1";
file = ./stage-1.sh;
substitutes = {};
};
};
stage-2 = mkOption {
type = types.path;
description = "runit stage 2";
default = pkgs.writeShellScript "2"
''
${builtins.readFile ./stage-2.sh}
'';
default = nglib.writeSubstitutedShellScript {
name = "2";
file = ./stage-2.sh;
substitutes = {
inherit (pkgs) runit findutils busybox;
inherit (cfg) serviceDir runtimeServiceDirectory;
};
};
};
stage-3 = mkOption {
type = types.path;
description = "runit stage 3";
default = pkgs.writeShellScript "3"
''
${builtins.readFile ./stage-3.sh}
'';
default = nglib.writeSubstitutedShellScript {
name = "3";
file = ./stage-3.sh;
substitutes = {};
};
};
};
};
};
serviceDir = mkOption {
description = "Generated service directory";
type = types.path;
readOnly = true;
};
};
config.init = mkMerge [
{
availableInits = [ "runit" ];
}
(mkIf cfg.enable {
type = "runit";
script = pkgs.writeShellScript "init"
''
config = {
runit = let
serviceDir = pkgs.runCommandNoCCLocal "service-dir" {} ''
mkdir $out
${lib.concatStringsSep "\n" (mapAttrsToList (name: service:
assert service.dependencies == [];
''
mkdir $out/${name}
ln -s ${service.script} $out/${name}/run
''
) cfgInit.services)}
'';
in
{
inherit serviceDir;
};
init = mkMerge [
{
availableInits = [ "runit" ];
}
(mkIf cfg.enable {
type = "runit";
script = pkgs.writeShellScript "init"
''
export PATH=${pkgs.busybox}/bin
mkdir -p /etc/runit
ln -sf ${cfg.stages.stage-1} /etc/runit/1
ln -sf ${cfg.stages.stage-2} /etc/runit/2
ln -sf ${cfg.stages.stage-3} /etc/runit/3
exec ${pkgs.runit}/bin/runit
'';
})
];
})
];
};
}

+ 1
- 0
modules/runit/stage-1.sh View File

@ -0,0 +1 @@
mkdir /tmp

+ 16
- 0
modules/runit/stage-2.sh View File

@ -0,0 +1,16 @@
export PATH=@runit@/bin:@findutils@/bin:@busybox@/bin
mkdir -p @runtimeServiceDirectory@
function linkFarm() {
src="$1"
dst="$2"
find "$src" -mindepth 1 -type d -printf "%P\n" | xargs -I {} mkdir "$dst/{}"
find "$src" -mindepth 1 -type f -printf "%P\n" | xargs -I {} ln -s "$src/{}" "$dst/{}"
find "$src" -mindepth 1 -type l -printf "%P\n" | xargs -I {} cp "$src/{}" "$dst/{}"
}
linkFarm @serviceDir@ @runtimeServiceDirectory@
runsvdir @runtimeServiceDirectory@

+ 62
- 0
modules/services/apache2.nix View File

@ -0,0 +1,62 @@
{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.services.apache2;
configParser = config:
concatStringsSep "\n" (mapAttrsToList (name: value:
if isString value then
"${name} ${value}"
else if isInt value then
"${name} ${toString value}"
else if isStorePath value then
"${name} ${toString value}"
else if isList value then
if all (x: isString x) value then
"${name} ${concatStringsSep " " value}"
else if all (x: isInt x) value then
"${name} ${concatStringsSep " " (toString value)}"
else if all (x: isStorePath x) value then
"${name} ${concatStringsSep " " (toString value)}"
else if all (x: isList x) value then
concatStringsSep "\n"
(map (p: "${name} ${concatStringsSep " " p}") value)
else
abort "Unsupported type in ApacheHTTPD configuration attrset, the module system should have caught this!"
else if isAttrs value then
concatStringsSep "\n" (mapAttrsToList (an: av:
''
<${name} ${an}>
${configParser av}
</${name}>
'') value)
else
abort "Unsupported type in ApacheHTTPD configuration attrset, the module system should have caught this!"
) config);
in
{
options.services.apache2 = {
enable = mkEnableOption "Enable Apache2 http server";
configuration = mkOption rec {
description = "Apache2 configuration";
type = with types;
types.attrsOf (oneOf [
str
int
(listOf (oneOf [ str int (listOf (oneOf [ str int ])) ]))
(attrsOf type)
]);
};
};
config.init.services.apache2 = let
config = pkgs.writeText "apache.cfg" (configParser cfg.configuration);
in
mkIf cfg.enable
{
script = pkgs.writeShellScript "apache2-run"
''
${pkgs.apacheHttpd}/bin/httpd -f ${config} -DFOREGROUND 2>&1
'';
};
}

+ 45
- 0
modules/services/getty.nix View File

@ -0,0 +1,45 @@
{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.services.getty;
in
{
options.services.getty = mkOption {
description = "All of the agettys";
type = types.attrsOf (types.submodule {
options = {
baudRate = mkOption {
description = "TTY baud rate";
type = types.int;
};
termName = mkOption {
description = "TTY terminal name";
type = types.str;
default = "vt100";
};
assume8BitTty = mkOption {
description = "Whether to assume the tty is 8-bit";
type = types.bool;
default = true;
};
# TODO Local line -L
pkg = mkOption {
description = "getty package";
type = types.path;
default = "${pkgs.utillinuxMinimal}/bin/agetty";
};
};
});
default = {};
};
config.init.services = mapAttrs'
(name: getty: nameValuePair "getty-${name}"
{
script = with getty;
pkgs.writeShellScript "getty-${name}-run"
''
exec setsid ${pkg} ${optionalString assume8BitTty "-8"} "${name}" "${toString baudRate}" "${termName}"
'';
})
cfg;
}

Loading…
Cancel
Save