diff options
Diffstat (limited to 'modules/foundation/services.nix')
| -rw-r--r-- | modules/foundation/services.nix | 302 |
1 files changed, 0 insertions, 302 deletions
diff --git a/modules/foundation/services.nix b/modules/foundation/services.nix deleted file mode 100644 index bedceb1..0000000 --- a/modules/foundation/services.nix +++ /dev/null @@ -1,302 +0,0 @@ -{ - lib, - config, - pkgs, - ... -}: - -let - inherit (lib) mkOption types; - - serviceOptions = { - options = { - image = mkOption { - type = types.nullOr types.package; - default = null; - }; - - fullImage = mkOption { - type = with types; nullOr (submodule { - options = { - image = mkOption { type = str; }; - imageFile = mkOption { type = package; }; - base = mkOption { type = nullOr anything; }; - }; - }); - default = null; - }; - - ports = mkOption { - type = with types; listOf ( - oneOf [(listOf port) str port] - ); - default = [ ]; - }; - - volumes = mkOption { - type = with types; listOf (listOf str); - default = [ ]; - }; - - devices = mkOption { - type = with types; listOf str; - default = [ ]; - }; - - capabilities = mkOption { - type = with types; listOf str; - default = [ ]; - }; - - entrypoint = mkOption { - type = types.nullOr types.str; - default = null; - }; - - cmd = mkOption { - type = with types; listOf str; - default = [ ]; - }; - - workdir = mkOption { - type = types.nullOr types.str; - default = null; - }; - - environment = mkOption { - type = types.attrsOf types.str; - default = { }; - }; - - environmentFiles = mkOption { - type = types.listOf types.path; - default = [ ]; - }; - - customNetwork = mkOption { - type = types.nullOr types.str; - default = null; - }; - }; - }; - - cfg = config.foundation; - - mkName = - { - group, - name, - full ? false, - }: - let - isGroup = group != ""; - isDefault = name == "default" || name == group; - - shortName = if isGroup && isDefault then group else name; - - fullName = if isGroup then (if isDefault then group else "${group}-${name}") else name; - in - assert name != ""; - assert isDefault -> isGroup; - if full then fullName else shortName; - - processServices = - group: serviceSet: - lib.mapAttrsToList ( - name: c: - { - name = mkName { inherit name group; }; - fullName = mkName { - inherit name group; - full = true; - }; - inherit group; - } - // c - ) serviceSet; - - singleServices = processServices "" cfg.services; - - groupedServices = lib.mapAttrs ( - group: groupServices: processServices group groupServices - ) cfg.service; - - allServices = - let - allSingleServices = singleServices; - allGroupedServices = lib.flatten (lib.attrValues groupedServices); - in - allSingleServices ++ allGroupedServices; - - groupStructure = lib.mapAttrs ( - group: groupServices: lib.catAttrs "fullName" groupServices - ) groupedServices; -in -{ - options.foundation = { - service = mkOption { - type = with types; attrsOf (attrsOf (submodule serviceOptions)); - default = { }; - }; - - services = mkOption { - type = with types; attrsOf (submodule serviceOptions); - default = { }; - }; - }; - - config = lib.mkIf (cfg.service != { } || cfg.services != { }) { - virtualisation.oci-containers.containers = - let - mkOciPort = - portSetting: - if builtins.isList portSetting then - let - host = builtins.elemAt portSetting 0; - container = builtins.elemAt portSetting 1; - in - "127.0.0.1:${toString host}:${toString container}" - else if builtins.isInt portSetting then - "127.0.0.1:${toString portSetting}:${toString portSetting}" - else - portSetting; - - mkOciVolume = - volumeTuple: - let - hostPath = builtins.elemAt volumeTuple 0; - containerPath = builtins.elemAt volumeTuple 1; - in - "${hostPath}:${containerPath}"; - - mkImage = - { - oldImage, - imageStream, - }: - if oldImage != null then - { - inherit (oldImage) image imageFile; - } - else if imageStream != null then - { - inherit imageStream; - image = "${imageStream.imageName}:${imageStream.imageTag}"; - } - else - throw "can't use both `fullImage` and `image` together."; - - mkOciContainer = - { - name, - fullImage, - image, - ports, - volumes, - devices, - capabilities, - entrypoint ? null, - cmd ? null, - workdir ? null, - environment ? null, - environmentFiles ? null, - customNetwork ? null, - - group, - ... - }: - { - inherit - entrypoint - cmd - workdir - environment - environmentFiles - ; - ports = map mkOciPort ports; - volumes = map mkOciVolume volumes; - - extraOptions = let - mapOptions = optionName: values: - map (v: "--${optionName}=${v}") values; - - networkOptions = - if customNetwork != null then [ - "--network=${customNetwork}" - ] else if group != "" then [ - "--network-alias=${name}" - "--network=${group}" - ] else []; - - capabilityOptions = mapOptions "cap-add" capabilities; - - deviceOptions = mapOptions "device" devices; - in - networkOptions ++ capabilityOptions ++ deviceOptions; - } - // (mkImage { - oldImage = fullImage; - imageStream = image; - }); - in - builtins.listToAttrs (map (v: lib.nameValuePair v.fullName (mkOciContainer v)) allServices); - - systemd = - let - mkGroupRootTargetName = group: "docker-${group}-root"; - mkServiceName = fullName: "docker-${fullName}"; - mkNetworkServiceName = group: "docker-${group}-network"; - - genericContainerService = - group: - let - network = "${mkNetworkServiceName group}.service"; - root = "${mkGroupRootTargetName group}.target"; - in - { - serviceConfig = { - Restart = lib.mkOverride 90 "always"; - RestartMaxDelaySec = lib.mkOverride 90 "1m"; - RestartSec = lib.mkOverride 90 "100ms"; - RestartSteps = lib.mkOverride 90 9; - }; - after = [ network ]; - requires = [ network ]; - partOf = [ root ]; - wantedBy = [ root ]; - }; - - networkService = - group: - let - root = "${mkGroupRootTargetName group}.target"; - in - { - path = [ pkgs.docker ]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStop = "docker network rm -f ${group}"; - }; - script = '' - docker network inspect ${group} || docker network create ${group} --driver=bridge - ''; - partOf = [ root ]; - wantedBy = [ root ]; - }; - in - { - services = lib.concatMapAttrs ( - group: serviceNames: - { - ${mkNetworkServiceName group} = networkService group; - } - // lib.genAttrs (map mkServiceName serviceNames) (_v: genericContainerService group) - ) groupStructure; - - targets = lib.mapAttrs' ( - group: _v: lib.nameValuePair (mkGroupRootTargetName group) { wantedBy = [ "multi-user.target" ]; } - ) groupStructure; - }; - }; -} |
