CI: make work with aarch64 possibly. nixdirfmt

This commit is contained in:
kat witch 2021-09-02 06:46:31 +01:00
parent f3d9d61e80
commit ff5c0846ef
No known key found for this signature in database
GPG key ID: 1B477797DCA5EC72
25 changed files with 390 additions and 216 deletions

View file

@ -5,6 +5,15 @@ env:
CI_PLATFORM: gh-actions CI_PLATFORM: gh-actions
OPENSSH_PRIVATE_KEY: ${{ secrets.OPENSSH_PRIVATE_KEY }} OPENSSH_PRIVATE_KEY: ${{ secrets.OPENSSH_PRIVATE_KEY }}
jobs: jobs:
ci:
name: ci
runs-on: ubuntu-latest
steps:
- id: aarch64
name: prepare for aarch64 builds
run: 'sudo aarch64binfmt
'
ci-check: ci-check:
name: niv-update check name: niv-update check
runs-on: ubuntu-latest runs-on: ubuntu-latest

View file

@ -117,6 +117,15 @@ jobs:
command: ci-build-cache command: ci-build-cache
quiet: false quiet: false
stdin: ${{ runner.temp }}/ci.build.cache stdin: ${{ runner.temp }}/ci.build.cache
ci:
name: ci
runs-on: ubuntu-latest
steps:
- id: aarch64
name: prepare for aarch64 builds
run: 'sudo aarch64binfmt
'
ci-check: ci-check:
name: nodes check name: nodes check
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -142,6 +151,63 @@ jobs:
args: -u .github/workflows/nodes.yml .ci/workflow.yml args: -u .github/workflows/nodes.yml .ci/workflow.yml
attrs: nixpkgs.diffutils attrs: nixpkgs.diffutils
command: diff command: diff
daiyousei:
name: nodes-daiyousei
runs-on: ubuntu-latest
steps:
- id: checkout
name: git clone
uses: actions/checkout@v1
with:
submodules: false
- id: nix-install
name: nix install
uses: arcnmx/ci/actions/nix/install@master
- id: ci-setup
name: nix setup
uses: arcnmx/ci/actions/nix/run@master
with:
attrs: ci.job.daiyousei.run.bootstrap
quiet: false
- id: ci-dirty
name: nix test dirty
uses: arcnmx/ci/actions/nix/run@master
with:
attrs: ci.job.daiyousei.run.test
command: ci-build-dirty
quiet: false
stdout: ${{ runner.temp }}/ci.build.dirty
- id: ci-test
name: nix test build
uses: arcnmx/ci/actions/nix/run@master
with:
attrs: ci.job.daiyousei.run.test
command: ci-build-realise
ignore-exit-code: true
quiet: false
stdin: ${{ runner.temp }}/ci.build.dirty
- env:
CI_EXIT_CODE: ${{ steps.ci-test.outputs.exit-code }}
id: ci-summary
name: nix test results
uses: arcnmx/ci/actions/nix/run@master
with:
attrs: ci.job.daiyousei.run.test
command: ci-build-summarise
quiet: false
stdin: ${{ runner.temp }}/ci.build.dirty
stdout: ${{ runner.temp }}/ci.build.cache
- env:
CACHIX_SIGNING_KEY: ${{ secrets.CACHIX_SIGNING_KEY }}
id: ci-cache
if: always()
name: nix test cache
uses: arcnmx/ci/actions/nix/run@master
with:
attrs: ci.job.daiyousei.run.test
command: ci-build-cache
quiet: false
stdin: ${{ runner.temp }}/ci.build.cache
ostara: ostara:
name: nodes-ostara name: nodes-ostara
runs-on: ubuntu-latest runs-on: ubuntu-latest

View file

@ -4,9 +4,31 @@ with lib; {
ci.gh-actions.enable = true; ci.gh-actions.enable = true;
ci.gh-actions.export = true; ci.gh-actions.export = true;
nix.config.extraPlatforms = "aarch64-linux";
gh-actions.env.OPENSSH_PRIVATE_KEY = "\${{ secrets.OPENSSH_PRIVATE_KEY }}"; gh-actions.env.OPENSSH_PRIVATE_KEY = "\${{ secrets.OPENSSH_PRIVATE_KEY }}";
gh-actions.env.CACHIX_SIGNING_KEY = "\${{ secrets.CACHIX_SIGNING_KEY }}"; gh-actions.env.CACHIX_SIGNING_KEY = "\${{ secrets.CACHIX_SIGNING_KEY }}";
# ensure sources are fetched and available in the local store before evaluating host configs
environment.bootstrap = {
aarch64binfmt =
let
makeQemuWrapper = name: ''
mkdir -f /run/binfmt
rm -f /run/binfmt/${name}
cat > /run/binfmt/${name} << 'EOF'
#!${channels.cipkgs.bash}/bin/sh
exec -- ${channels.cipkgs.qemu}/bin/qemu-${name} "$@"
EOF
chmod +x /run/binfmt/${name}
''; in
channels.cipkgs.writeShellScriptBin "aarch64binfmt" ''
${makeQemuWrapper "aarch64"}
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
echo ':aarch64-linux:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\x00\xff\xfe\xff\xff\xff:/run/binfmt/aarch64:' > /proc/sys/fs/binfmt_misc/register
'';
};
gh-actions = { gh-actions = {
on = on =
let let
@ -27,6 +49,13 @@ with lib; {
cron = "0 0 * * *"; cron = "0 0 * * *";
}]; }];
}; };
jobs.ci.step.aarch64 = {
order = 201;
name = "prepare for aarch64 builds";
run = ''
sudo aarch64binfmt
'';
};
}; };
channels = { channels = {

View file

@ -1,11 +1,39 @@
{ lib, channels, env, ... }: with lib; { { lib, config, channels, env, ... }: with lib; {
name = "nodes"; name = "nodes";
ci.gh-actions.enable = true; ci.gh-actions.enable = true;
ci.gh-actions.export = true; ci.gh-actions.export = true;
channels.nixfiles.path = ../.; channels.nixfiles.path = ../.;
nix.config.extraPlatforms = "aarch64-linux";
gh-actions = {
jobs.ci.step.aarch64 = {
order = 201;
name = "prepare for aarch64 builds";
run = ''
sudo aarch64binfmt
'';
};
};
# ensure sources are fetched and available in the local store before evaluating host configs # ensure sources are fetched and available in the local store before evaluating host configs
environment.bootstrap = { environment.bootstrap = {
aarch64binfmt =
let
makeQemuWrapper = name: ''
mkdir -f /run/binfmt
rm -f /run/binfmt/${name}
cat > /run/binfmt/${name} << 'EOF'
#!${channels.cipkgs.bash}/bin/sh
exec -- ${channels.cipkgs.qemu}/bin/qemu-${name} "$@"
EOF
chmod +x /run/binfmt/${name}
''; in
channels.cipkgs.writeShellScriptBin "aarch64binfmt" ''
${makeQemuWrapper "aarch64"}
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
echo ':aarch64-linux:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\x00\xff\xfe\xff\xff\xff:/run/binfmt/aarch64:' > /proc/sys/fs/binfmt_misc/register
'';
sourceCache = channels.cipkgs.runCommand "sources" sourceCache = channels.cipkgs.runCommand "sources"
{ {
srcs = attrNames channels.nixfiles.sourceCache.local; srcs = attrNames channels.nixfiles.sourceCache.local;

View file

@ -12,7 +12,7 @@ in
services.nginx services.nginx
]; ];
deploy.tf.providers.local = {}; deploy.tf.providers.local = { };
nixpkgs.localSystem = systems.examples.aarch64-multiplatform // { nixpkgs.localSystem = systems.examples.aarch64-multiplatform // {
system = "aarch64-linux"; system = "aarch64-linux";

View file

@ -29,11 +29,11 @@ in
secrets = { secrets = {
variables = mkOption { variables = mkOption {
type = types.attrsOf secretType; type = types.attrsOf secretType;
default = {}; default = { };
}; };
repo = mkOption { repo = mkOption {
type = types.attrsOf repoSecretType; type = types.attrsOf repoSecretType;
default = {}; default = { };
}; };
}; };
}; };

View file

@ -31,12 +31,14 @@ with lib;
config = { config = {
nixpkgs = { nixpkgs = {
system = mkDefault pkgs.system; system = mkDefault pkgs.system;
pkgs = let pkgs =
pkgsReval = import pkgs.path { let
inherit (config.nixpkgs) localSystem crossSystem; pkgsReval = import pkgs.path {
inherit (pkgs) overlays config; inherit (config.nixpkgs) localSystem crossSystem;
}; inherit (pkgs) overlays config;
in mkDefault (if config.nixpkgs.config == pkgs.config && config.nixpkgs.localSystem.system == pkgs.targetPlatform.system then pkgs else pkgsReval); };
in
mkDefault (if config.nixpkgs.config == pkgs.config && config.nixpkgs.localSystem.system == pkgs.targetPlatform.system then pkgs else pkgsReval);
}; };
}; };
}; };

View file

@ -32,11 +32,11 @@ in
}; };
variables = mkOption { variables = mkOption {
type = types.attrsOf secretType; type = types.attrsOf secretType;
default = {}; default = { };
}; };
repo = mkOption { repo = mkOption {
type = types.attrsOf repoSecretType; type = types.attrsOf repoSecretType;
default = {}; default = { };
}; };
}; };
}; };
@ -44,14 +44,16 @@ in
{ {
kw.secrets.variables = lib.mkMerge (mapAttrsToList (username: user: user.kw.secrets.variables) config.home-manager.users); kw.secrets.variables = lib.mkMerge (mapAttrsToList (username: user: user.kw.secrets.variables) config.home-manager.users);
} }
(mkIf (cfg.variables != {}) { (mkIf (cfg.variables != { }) {
deploy.tf.variables = mapAttrs' (name: content: deploy.tf.variables = mapAttrs'
nameValuePair name ({ (name: content:
value.shellCommand = "${cfg.command} ${content.path}" + optionalString (content.field != "") " -f ${content.field}"; nameValuePair name ({
type = "string"; value.shellCommand = "${cfg.command} ${content.path}" + optionalString (content.field != "") " -f ${content.field}";
sensitive = true; type = "string";
}) sensitive = true;
) cfg.variables; })
)
cfg.variables;
}) })
]; ];
} }

View file

@ -4,10 +4,11 @@ with lib;
let let
cfg = config.network.yggdrasil; cfg = config.network.yggdrasil;
calcAddr = pubkey: lib.readFile (pkgs.runCommandNoCC "calcaddr-${pubkey}" {} '' calcAddr = pubkey: lib.readFile (pkgs.runCommandNoCC "calcaddr-${pubkey}" { } ''
echo '{ EncryptionPublicKey: "${pubkey}" }' | ${config.services.yggdrasil.package}/bin/yggdrasil -useconf -address | tr -d '\n' > $out echo '{ EncryptionPublicKey: "${pubkey}" }' | ${config.services.yggdrasil.package}/bin/yggdrasil -useconf -address | tr -d '\n' > $out
'').outPath; '').outPath;
in { in
{
options.network.yggdrasil = { options.network.yggdrasil = {
enable = mkEnableOption "Enable the yggdrasil-based private hexnet"; enable = mkEnableOption "Enable the yggdrasil-based private hexnet";
pubkey = mkOption { pubkey = mkOption {
@ -32,7 +33,7 @@ in {
listen.endpoints = mkOption { listen.endpoints = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
description = "Endpoints to listen on"; description = "Endpoints to listen on";
default = []; default = [ ];
}; };
dns.enable = mkOption { dns.enable = mkOption {
type = types.bool; type = types.bool;
@ -52,27 +53,27 @@ in {
tunnel.localV6 = mkOption { tunnel.localV6 = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
description = "v6 subnets to expose"; description = "v6 subnets to expose";
default = []; default = [ ];
}; };
tunnel.localV4 = mkOption { tunnel.localV4 = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
description = "v4 subnets to expose"; description = "v4 subnets to expose";
default = []; default = [ ];
}; };
tunnel.remoteV6 = mkOption { tunnel.remoteV6 = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
description = "Extra v6 subnets to route"; description = "Extra v6 subnets to route";
default = {}; default = { };
}; };
tunnel.remoteV4 = mkOption { tunnel.remoteV4 = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
description = "Extra v4 subnets to route"; description = "Extra v4 subnets to route";
default = {}; default = { };
}; };
extra.pubkeys = mkOption { extra.pubkeys = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
description = "Additional hosts to allow into the network. Keys won't be added to definition host."; description = "Additional hosts to allow into the network. Keys won't be added to definition host.";
default = {}; default = { };
example = { host = "0000000000000000000000000000000000000000000000000000000000000000"; }; example = { host = "0000000000000000000000000000000000000000000000000000000000000000"; };
}; };
extra.addresses = mkOption { extra.addresses = mkOption {
@ -83,73 +84,84 @@ in {
extra.localV6 = mkOption { extra.localV6 = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
description = "v6 subnets to expose, but not route"; description = "v6 subnets to expose, but not route";
default = []; default = [ ];
}; };
extra.localV4 = mkOption { extra.localV4 = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
description = "v4 subnets to expose, but not route"; description = "v4 subnets to expose, but not route";
default = []; default = [ ];
}; };
}; };
config = mkIf cfg.enable (let config = mkIf cfg.enable (
yggConfigs = filter ( let
c: c.enable && (cfg.pubkey != c.pubkey) yggConfigs = filter
) ( (
mapAttrsToList (_: node: node.network.yggdrasil or { enable = false; pubkey = null; }) meta.network.nodes c: c.enable && (cfg.pubkey != c.pubkey)
); )
pubkeys = flatten (map (c: [ c.pubkey ] ++ (attrValues c.extra.pubkeys)) yggConfigs); (
in { mapAttrsToList (_: node: node.network.yggdrasil or { enable = false; pubkey = null; }) meta.network.nodes
assertions = [ );
{ pubkeys = flatten (map (c: [ c.pubkey ] ++ (attrValues c.extra.pubkeys)) yggConfigs);
assertion = !(cfg.listen.enable && (cfg.listen.endpoints == [])); in
message = "Specify network.yggdrasil.listen.endpoints"; {
} assertions = [
]; {
assertion = !(cfg.listen.enable && (cfg.listen.endpoints == [ ]));
message = "Specify network.yggdrasil.listen.endpoints";
}
];
networking.firewall.trustedInterfaces = mkIf cfg.trust [ "yggdrasil" ]; networking.firewall.trustedInterfaces = mkIf cfg.trust [ "yggdrasil" ];
services.yggdrasil = { services.yggdrasil = {
enable = true; enable = true;
persistentKeys = true; persistentKeys = true;
config = { config = {
AllowedEncryptionPublicKeys = pubkeys; AllowedEncryptionPublicKeys = pubkeys;
IfName = "yggdrasil"; IfName = "yggdrasil";
Listen = cfg.listen.endpoints; Listen = cfg.listen.endpoints;
Peers = lib.flatten (map (c: c.listen.endpoints) (filter (c: c.listen.enable) yggConfigs)); Peers = lib.flatten (map (c: c.listen.endpoints) (filter (c: c.listen.enable) yggConfigs));
SessionFirewall = { SessionFirewall = {
Enable = true; Enable = true;
AllowFromRemote = false; AllowFromRemote = false;
WhitelistEncryptionPublicKeys = pubkeys; WhitelistEncryptionPublicKeys = pubkeys;
}; };
TunnelRouting = let TunnelRouting =
subnets = v: ( let
listToAttrs (flatten (map (c: map (net: nameValuePair net c.pubkey) c.tunnel."localV${toString v}") yggConfigs)) subnets = v: (
) // cfg.tunnel."remoteV${toString v}"; listToAttrs (flatten (map (c: map (net: nameValuePair net c.pubkey) c.tunnel."localV${toString v}") yggConfigs))
in { ) // cfg.tunnel."remoteV${toString v}";
Enable = true; in
IPv4LocalSubnets = cfg.tunnel.localV4 ++ cfg.extra.localV4; {
IPv6LocalSubnets = cfg.tunnel.localV6 ++ cfg.extra.localV6; Enable = true;
IPv4RemoteSubnets = subnets 4; IPv4LocalSubnets = cfg.tunnel.localV4 ++ cfg.extra.localV4;
IPv6RemoteSubnets = subnets 6; IPv6LocalSubnets = cfg.tunnel.localV6 ++ cfg.extra.localV6;
IPv4RemoteSubnets = subnets 4;
IPv6RemoteSubnets = subnets 6;
};
}; };
}; };
};
systemd.services.yggdrasil.postStart = let systemd.services.yggdrasil.postStart =
yggTun = config.services.yggdrasil.config.TunnelRouting; let
addNets = v: nets: concatMapStringsSep "\n" (net: "${pkgs.iproute}/bin/ip -${toString v} route add ${net} dev yggdrasil") (attrNames nets); yggTun = config.services.yggdrasil.config.TunnelRouting;
in "sleep 1\n" + (concatMapStringsSep "\n" (v: addNets v yggTun."IPv${toString v}RemoteSubnets") [ 4 6 ]); addNets = v: nets: concatMapStringsSep "\n" (net: "${pkgs.iproute}/bin/ip -${toString v} route add ${net} dev yggdrasil") (attrNames nets);
in
"sleep 1\n" + (concatMapStringsSep "\n" (v: addNets v yggTun."IPv${toString v}RemoteSubnets") [ 4 6 ]);
system.build.yggdrasilTemplate = let system.build.yggdrasilTemplate =
json = builtins.toJSON { let
inherit (config.services.yggdrasil.config) Peers SessionFirewall TunnelRouting; json = builtins.toJSON {
EncryptionPublicKey = ""; inherit (config.services.yggdrasil.config) Peers SessionFirewall TunnelRouting;
EncryptionPrivateKey = ""; EncryptionPublicKey = "";
SigningPublicKey = ""; EncryptionPrivateKey = "";
SigningPrivateKey = ""; SigningPublicKey = "";
}; SigningPrivateKey = "";
in pkgs.runCommandNoCC "yggdrasil-template.json" {} };
"echo '${json}' | ${config.services.yggdrasil.package}/bin/yggdrasil -useconf -normaliseconf > $out"; in
}); pkgs.runCommandNoCC "yggdrasil-template.json" { }
"echo '${json}' | ${config.services.yggdrasil.package}/bin/yggdrasil -useconf -normaliseconf > $out";
}
);
} }

View file

@ -7,7 +7,9 @@
external = true; external = true;
}; };
kw.secrets.command = let kw.secrets.command =
bitw = pkgs.writeShellScriptBin "bitw" ''${pkgs.rbw-bitw}/bin/bitw -p gpg://${config.kw.secrets.repo.bitw.source} "$@"''; let
in "${bitw}/bin/bitw get"; bitw = pkgs.writeShellScriptBin "bitw" ''${pkgs.rbw-bitw}/bin/bitw -p gpg://${config.kw.secrets.repo.bitw.source} "$@"'';
in
"${bitw}/bin/bitw get";
} }

View file

@ -1,11 +1,10 @@
{ pkgs, config, lib, ... }: with lib; { { pkgs, config, lib, ... }: with lib; {
boot.binfmt = { boot.binfmt = {
emulatedSystems = [ "aarch64-linux" ]; emulatedSystems = [ "aarch64-linux" ];
/* /*
registrations.aarch64-linux = { registrations.aarch64-linux = {
interpreter = mkForce "${pkgs.qemu-vfio or pkgs.qemu}/bin/qemu-aarch64"; interpreter = mkForce "${pkgs.qemu-vfio or pkgs.qemu}/bin/qemu-aarch64";
}; };
*/ */
}; };
} }

View file

@ -1,6 +1,6 @@
{ config, ... }: { { config, ... }: {
nix = { nix = {
binaryCaches = [ "https://arm.cachix.org/" ]; binaryCaches = [ "https://arm.cachix.org/" ];
binaryCachePublicKeys = [ "arm.cachix.org-1:5BZ2kjoL1q6nWhlnrbAl+G7ThY7+HaBRD9PZzqZkbnM=" ]; binaryCachePublicKeys = [ "arm.cachix.org-1:5BZ2kjoL1q6nWhlnrbAl+G7ThY7+HaBRD9PZzqZkbnM=" ];
}; };
} }

View file

@ -39,7 +39,7 @@ in
type = with types; nullOr int; type = with types; nullOr int;
default = null; default = null;
}; };
publicV6 = mkOption { publicV6 = mkOption {
type = with types; nullOr int; type = with types; nullOr int;
default = null; default = null;
}; };
@ -168,8 +168,8 @@ in
}; };
lifecycle.ignoreChanges = [ lifecycle.ignoreChanges = [
"source_details[0].source_id" "source_details[0].source_id"
]; ];
connection = { connection = {
type = "ssh"; type = "ssh";
user = "root"; user = "root";
host = tf.lib.tf.terraformSelf "public_ip"; host = tf.lib.tf.terraformSelf "public_ip";
@ -186,31 +186,31 @@ in
}; };
}; };
} }
( (
let let
protoValues = { protoValues = {
TCP = 6; TCP = 6;
UDP = 17; UDP = 17;
}; };
inherit (config.networking) firewall; inherit (config.networking) firewall;
ipv4 = "0.0.0.0/0"; ipv4 = "0.0.0.0/0";
ipv6 = "::/0"; ipv6 = "::/0";
mapPort = source: protocol: port: { mapPort = source: protocol: port: {
provider = "oci"; provider = "oci";
type = "core_network_security_group_security_rule"; type = "core_network_security_group_security_rule";
inputs = { inputs = {
network_security_group_id = tf.resources.firewall_group.refAttr "id"; network_security_group_id = tf.resources.firewall_group.refAttr "id";
inherit protocol source; inherit protocol source;
direction = "INGRESS"; direction = "INGRESS";
${if protocol == protoValues.TCP then "tcp_options" else "udp_options"} = { ${if protocol == protoValues.TCP then "tcp_options" else "udp_options"} = {
destination_port_range = destination_port_range =
if isAttrs port then { if isAttrs port then {
min = port.from; min = port.from;
max = port.to; max = port.to;
} else { } else {
min = port; min = port;
max = port; max = port;
}; };
}; };
}; };
}; };
@ -221,11 +221,11 @@ in
types = [ "Ports" "PortRanges" ]; types = [ "Ports" "PortRanges" ];
in in
interface: concatMap (type: concatMap (proto: (concatMap (port: (mapAll protoValues.${proto}) port) interface."allowed${proto}${type}")) protos) types; interface: concatMap (type: concatMap (proto: (concatMap (port: (mapAll protoValues.${proto}) port) interface."allowed${proto}${type}")) protos) types;
rules = concatMap mapAllForInterface ([ firewall ] ++ map (interface: firewall.interfaces.${interface}) config.network.firewall.public.interfaces); rules = concatMap mapAllForInterface ([ firewall ] ++ map (interface: firewall.interfaces.${interface}) config.network.firewall.public.interfaces);
# TODO: use `count` and index into a fancy json or something? # TODO: use `count` and index into a fancy json or something?
in in
listToAttrs (imap0 (i: rule: nameValuePair "firewall${toString i}" rule) rules) listToAttrs (imap0 (i: rule: nameValuePair "firewall${toString i}" rule) rules)
)]; )];
};
}; };
} };
}

View file

@ -7,11 +7,12 @@
cname = { inherit (config.network.addresses.private) target; }; cname = { inherit (config.network.addresses.private) target; };
}; };
kw.secrets.variables = mapListToAttrs (field: kw.secrets.variables = mapListToAttrs
nameValuePair "fusionpbx-${field}" { (field:
path = "services/fusionpbx"; nameValuePair "fusionpbx-${field}" {
inherit field; path = "services/fusionpbx";
}) ["username" "password"]; inherit field;
}) [ "username" "password" ];
secrets.files.fusionpbx_env = { secrets.files.fusionpbx_env = {
text = '' text = ''

View file

@ -13,7 +13,7 @@
udp.ports = [ 53 ]; udp.ports = [ 53 ];
}; };
/* environment.etc."katdns/zones/dork.dev.zone".text = let /* environment.etc."katdns/zones/dork.dev.zone".text = let
dns = pkgs.dns; dns = pkgs.dns;
in dns.lib.toString "dork.dev" (import ./dork.dev.nix { inherit dns lib; }); */ in dns.lib.toString "dork.dev" (import ./dork.dev.nix { inherit dns lib; }); */

View file

@ -4,48 +4,56 @@ with lib;
let let
domains = [ "kittywitch" "dork" ]; domains = [ "kittywitch" "dork" ];
in { in
{
imports = [ sources.nixos-mailserver.outPath ]; imports = [ sources.nixos-mailserver.outPath ];
kw.secrets.variables = listToAttrs (map (field: kw.secrets.variables = listToAttrs (map
nameValuePair "mail-${field}-hash" { (field:
path = "secrets/mail-kittywitch"; nameValuePair "mail-${field}-hash" {
field = "${field}-hash"; path = "secrets/mail-kittywitch";
}) ["gitea" "kat"] field = "${field}-hash";
++ map (domain: }) [ "gitea" "kat" ]
++ map
(domain:
nameValuePair "mail-domainkey-${domain}" { nameValuePair "mail-domainkey-${domain}" {
path = "secrets/mail-${domain}"; path = "secrets/mail-${domain}";
field = "notes"; field = "notes";
}) domains); })
domains);
deploy.tf.dns.records = lib.mkMerge (map (domain: let deploy.tf.dns.records = lib.mkMerge (map
zoneGet = domain: if domain == "dork" then "dork.dev." else config.network.dns.zone; (domain:
in { let
"services_mail_${domain}_mx" = { zoneGet = domain: if domain == "dork" then "dork.dev." else config.network.dns.zone;
zone = zoneGet domain; in
mx = { {
priority = 10; "services_mail_${domain}_mx" = {
target = "${config.network.addresses.public.domain}."; zone = zoneGet domain;
mx = {
priority = 10;
target = "${config.network.addresses.public.domain}.";
};
}; };
};
"services_mail_${domain}_spf" = { "services_mail_${domain}_spf" = {
zone = zoneGet domain; zone = zoneGet domain;
txt.value = "v=spf1 ip4:${config.network.addresses.public.nixos.ipv4.address} ip6:${config.network.addresses.public.nixos.ipv6.address} -all"; txt.value = "v=spf1 ip4:${config.network.addresses.public.nixos.ipv4.address} ip6:${config.network.addresses.public.nixos.ipv6.address} -all";
}; };
"services_mail_${domain}_dmarc" = { "services_mail_${domain}_dmarc" = {
zone = zoneGet domain; zone = zoneGet domain;
domain = "_dmarc"; domain = "_dmarc";
txt.value = "v=DMARC1; p=none"; txt.value = "v=DMARC1; p=none";
}; };
"services_mail_${domain}_domainkey" = { "services_mail_${domain}_domainkey" = {
zone = zoneGet domain; zone = zoneGet domain;
domain = "mail._domainkey"; domain = "mail._domainkey";
txt.value = tf.variables."mail-domainkey-${domain}".ref; txt.value = tf.variables."mail-domainkey-${domain}".ref;
}; };
}) domains); })
domains);
secrets.files = { secrets.files = {
mail-kat-hash = { mail-kat-hash = {

View file

@ -13,14 +13,17 @@ with lib;
LC_CTYPE = "C"; LC_CTYPE = "C";
''; '';
kw.secrets.variables = (mapListToAttrs (field: kw.secrets.variables = (mapListToAttrs
nameValuePair "mautrix-telegram-${field}" { (field:
path = "secrets/mautrix-telegram"; nameValuePair "mautrix-telegram-${field}" {
inherit field; path = "secrets/mautrix-telegram";
}) ["api-hash" "api-id" "as-token" "hs-token"] inherit field;
// { matrix-registration = { }) [ "api-hash" "api-id" "as-token" "hs-token" ]
// {
matrix-registration = {
path = "secrets/matrix-registration"; path = "secrets/matrix-registration";
}; }); };
});
secrets.files.mautrix-telegram-env = { secrets.files.mautrix-telegram-env = {
text = '' text = ''

View file

@ -4,13 +4,16 @@ with lib;
{ {
kw.secrets.variables = let kw.secrets.variables =
fieldAdapt = field: if field == "pass" then "password" else field; let
in mapListToAttrs (field: fieldAdapt = field: if field == "pass" then "password" else field;
nameValuePair "syncplay-${field}" { in
path = "services/media/syncplay"; mapListToAttrs
field = fieldAdapt field; (field:
}) ["pass" "salt"]; nameValuePair "syncplay-${field}" {
path = "services/media/syncplay";
field = fieldAdapt field;
}) [ "pass" "salt" ];
users.users.syncplay = { isSystemUser = true; }; users.users.syncplay = { isSystemUser = true; };

View file

@ -50,25 +50,30 @@ in
{ {
network.firewall.public.tcp.ports = singleton 5001; network.firewall.public.tcp.ports = singleton 5001;
kw.secrets.variables = let kw.secrets.variables =
fieldAdapt = field: if field == "cert" then "notes" else if field == "pass" then "password" else field; let
in listToAttrs (concatMap (network: fieldAdapt = field: if field == "cert" then "notes" else if field == "pass" then "password" else field;
map (field: in
nameValuePair "znc-${network}-${field}" { listToAttrs (concatMap
path = "social/irc/${network}"; (network:
field = fieldAdapt field; map
}) ["cert" "pass"] (field:
) ["liberachat" "espernet"] nameValuePair "znc-${network}-${field}" {
++ map (field: path = "social/irc/${network}";
nameValuePair "znc-softnet-${field}" { field = fieldAdapt field;
path = "social/irc/softnet"; }) [ "cert" "pass" ]
field = fieldAdapt field; ) [ "liberachat" "espernet" ]
}) ["cert" "address"] ++ map
++ singleton (nameValuePair "znc-savebuff-pass" { (field:
nameValuePair "znc-softnet-${field}" {
path = "social/irc/softnet";
field = fieldAdapt field;
}) [ "cert" "address" ]
++ singleton (nameValuePair "znc-savebuff-pass" {
path = "social/irc/znc"; path = "social/irc/znc";
field = "savebuff"; field = "savebuff";
}) })
); );
secrets.files.softnet-cert = { secrets.files.softnet-cert = {
text = tf.variables.znc-softnet-cert.ref; text = tf.variables.znc-softnet-cert.ref;

View file

@ -27,7 +27,7 @@
}; };
}; };
dns.zones = genAttrs ["kittywit.ch." "dork.dev."] (_: { dns.zones = genAttrs [ "kittywit.ch." "dork.dev." ] (_: {
provider = "dns.katdns"; provider = "dns.katdns";
}); });
} }

View file

@ -1,6 +1,7 @@
{ config, ... }: { config, ... }:
let rinnosuke = config.network.nodes.rinnosuke; in { let rinnosuke = config.network.nodes.rinnosuke; in
{
deploy.targets.rinnosuke-domains.tf = { deploy.targets.rinnosuke-domains.tf = {
dns.records = { dns.records = {
node_public_rinnosuke_v4 = { node_public_rinnosuke_v4 = {

View file

@ -3,13 +3,16 @@
with lib; with lib;
{ {
kw.secrets.variables = let kw.secrets.variables =
fieldAdapt = field: if field == "key" then "notes" else field; let
in mapListToAttrs (field: fieldAdapt = field: if field == "key" then "notes" else field;
nameValuePair "taskwarrior-${field}" { in
path = "services/taskwarrior"; mapListToAttrs
field = fieldAdapt field; (field:
}) ["key" "credentials"]; nameValuePair "taskwarrior-${field}" {
path = "services/taskwarrior";
field = fieldAdapt field;
}) [ "key" "credentials" ];
secrets.files = { secrets.files = {
taskw_key = { taskw_key = {

View file

@ -17,10 +17,10 @@
"homepage": null, "homepage": null,
"owner": "arcnmx", "owner": "arcnmx",
"repo": "nixexprs", "repo": "nixexprs",
"rev": "c294222dc0cfeb77fc1ee281e21121581b831e08", "rev": "5bf9fb9e07b6dfefd0134c57db667c7c75ed0119",
"sha256": "06z5ql2sfwh4526pgwnx93firyaaa4l2xsqxivkm2diyhmr1jm65", "sha256": "0pvz1swflmyyyzx5yzfflr1llsfw38pax03vac83pc8y0r78f84h",
"type": "tarball", "type": "tarball",
"url": "https://github.com/arcnmx/nixexprs/archive/c294222dc0cfeb77fc1ee281e21121581b831e08.tar.gz", "url": "https://github.com/arcnmx/nixexprs/archive/5bf9fb9e07b6dfefd0134c57db667c7c75ed0119.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"ci": { "ci": {
@ -41,10 +41,10 @@
"homepage": "", "homepage": "",
"owner": "nix-community", "owner": "nix-community",
"repo": "emacs-overlay", "repo": "emacs-overlay",
"rev": "9f17ba1ed9c8b2012c0a1a41edf3d02936aa4def", "rev": "3475b81d1c14509c9ebfae1e53366b28acaa2b6b",
"sha256": "1qsgzswm04c7wnkk7d0ik7dahgxyxm1c0kpv8yhjk9g1gikwnxbz", "sha256": "0amksnxwk86pbb8w2zab7sycijyn0d3636877dfhdbdqkzck233g",
"type": "tarball", "type": "tarball",
"url": "https://github.com/nix-community/emacs-overlay/archive/9f17ba1ed9c8b2012c0a1a41edf3d02936aa4def.tar.gz", "url": "https://github.com/nix-community/emacs-overlay/archive/3475b81d1c14509c9ebfae1e53366b28acaa2b6b.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"hexchen": { "hexchen": {
@ -159,10 +159,10 @@
"homepage": "https://nur.nix-community.org/", "homepage": "https://nur.nix-community.org/",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "45f8470f72f1c8989ae5fe23c6cc343ae3463a97", "rev": "d2cdb44f12b82d9d207b6e6596cc9d2a2e1361eb",
"sha256": "0py76bjfiqncvxvald35gjgvhlg304d1yhmk0qvc22ar8k3dqckm", "sha256": "01gs4vvhq4i71l9q7xlb3py4kadq2s7acdndkvdk2lk3l8d13qm1",
"type": "tarball", "type": "tarball",
"url": "https://github.com/nix-community/NUR/archive/45f8470f72f1c8989ae5fe23c6cc343ae3463a97.tar.gz", "url": "https://github.com/nix-community/NUR/archive/d2cdb44f12b82d9d207b6e6596cc9d2a2e1361eb.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"tf-nix": { "tf-nix": {
@ -171,10 +171,10 @@
"homepage": null, "homepage": null,
"owner": "arcnmx", "owner": "arcnmx",
"repo": "tf-nix", "repo": "tf-nix",
"rev": "509bdbb0768e033fc1d8b7a4bc7b2ec8e141806a", "rev": "d57b4335aa35781420b7d064d3d77141004c44e9",
"sha256": "1h48lh55j8jpknl4zica6b6q402r5nj816sz1k7dqy607y0pfcrb", "sha256": "0xfl305yaz6xlgaz2jxp4qpibqsyh2hjgibvyxbqqcx0frs9bvya",
"type": "tarball", "type": "tarball",
"url": "https://github.com/arcnmx/tf-nix/archive/509bdbb0768e033fc1d8b7a4bc7b2ec8e141806a.tar.gz", "url": "https://github.com/arcnmx/tf-nix/archive/d57b4335aa35781420b7d064d3d77141004c44e9.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
} }
} }

@ -1 +1 @@
Subproject commit 68a371ce344cd66e646d58dd3658fc7c0615f768 Subproject commit a78026175487423769ac2667e618a896af63c5b0

View file

@ -70,6 +70,7 @@ pkgs.mkShell {
shellHook = '' shellHook = ''
export HOME_HOSTNAME=$(hostname -s) export HOME_HOSTNAME=$(hostname -s)
export HOME_UID=$(id -u) export HOME_UID=$(id -u)
export CI_PLATFORM="impure"
export NIX_PATH="$NIX_PATH:home=${toString ./.}" export NIX_PATH="$NIX_PATH:home=${toString ./.}"
''; '';
} }