mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 04:19:19 -08:00
feat(esphome): working
This commit is contained in:
parent
d266bdb450
commit
4b986433a3
9 changed files with 130 additions and 50 deletions
|
|
@ -1,10 +1,11 @@
|
||||||
{ config, ... }: {
|
{ config, target, ... }: {
|
||||||
|
esphome = {
|
||||||
|
platform = "esp8266";
|
||||||
|
board = "d1_mini";
|
||||||
|
};
|
||||||
api = {
|
api = {
|
||||||
password = "!secret api_password";
|
password = "!secret api_password";
|
||||||
};
|
};
|
||||||
esp8266 = {
|
|
||||||
board = "d1_mini";
|
|
||||||
};
|
|
||||||
wifi = {
|
wifi = {
|
||||||
ssid = "Gensokyo";
|
ssid = "Gensokyo";
|
||||||
password = "!secret wifi_password";
|
password = "!secret wifi_password";
|
||||||
|
|
@ -24,7 +25,7 @@
|
||||||
sensor = [
|
sensor = [
|
||||||
{
|
{
|
||||||
platform = "dht";
|
platform = "dht";
|
||||||
model = "dht22";
|
model = "DHT22";
|
||||||
update_interval = "60s";
|
update_interval = "60s";
|
||||||
pin = "D0";
|
pin = "D0";
|
||||||
temperature = {
|
temperature = {
|
||||||
|
|
|
||||||
86
modules/esphome/deploy.nix
Normal file
86
modules/esphome/deploy.nix
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
{ tf, target, name, meta, config, lib, ... }:
|
||||||
|
|
||||||
|
/*
|
||||||
|
This module:
|
||||||
|
* aliases <hostname>.system.build.toplevel to <hostname>.deploy.system for ease of use.
|
||||||
|
* marries meta config to NixOS configs for each host.
|
||||||
|
* provides in-scope TF config in NixOS and home-manager, instead of only as a part of meta config.
|
||||||
|
*/
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.deploy;
|
||||||
|
unmergedValues = types.mkOptionType {
|
||||||
|
name = "unmergedValues";
|
||||||
|
merge = loc: defs: map (def: def.value) defs;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.deploy.tf = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
inherit (unmerged) freeformType;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
triggers = mkOption {
|
||||||
|
type = types.attrsOf types.unspecified;
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
import = mkOption {
|
||||||
|
type = types.attrsOf types.unspecified;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
imports = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
description = "Other targets to depend on";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
attrs = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
out.set = mkOption { type = types.unspecified; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = let
|
||||||
|
functionlessConfig = lib.removeAttrs config ["out" "_module" "platform" "deploy"];
|
||||||
|
mutatedConfig = functionlessConfig // (optionalAttrs (config.platform != {}) {
|
||||||
|
${functionlessConfig.esphome.platform} = config.platform;
|
||||||
|
});
|
||||||
|
jsonConfig = builtins.toJSON mutatedConfig;
|
||||||
|
closureConfig = pkgs.writeText "${functionlessConfig.esphome.name}.json" jsonConfig;
|
||||||
|
closure-upload = pkgs.writeShellScriptBin "${functionlessConfig.esphome.name}-upload" ''
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
deploy.tf = {
|
||||||
|
attrs = [ "import" "imports" "out" "attrs" "triggers" ];
|
||||||
|
import = genAttrs cfg.tf.imports (target: meta.deploy.targets.${target}.tf);
|
||||||
|
out.set = removeAttrs cfg.tf cfg.tf.attrs;
|
||||||
|
triggers = {
|
||||||
|
compile = {
|
||||||
|
system = config.out;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
resources = {
|
||||||
|
"${name}-upload" = {
|
||||||
|
provider = "null";
|
||||||
|
type = "resource";
|
||||||
|
inputs.triggers = cfg.tf.triggers.compile;
|
||||||
|
provisioners = [
|
||||||
|
{
|
||||||
|
type = "local-exec";
|
||||||
|
local-exec.command = ''
|
||||||
|
${pkgs.esphome}/bin/esphome upload ${closureConfig}
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
_module.args.tf = mapNullable (target: target.tf) target;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,2 +1,10 @@
|
||||||
{ config, ... }: {
|
{ name, config, meta, pkgs, lib, ... }: with lib;
|
||||||
}
|
{
|
||||||
|
options = {
|
||||||
|
} // genAttrs [ "esphome" "api" "platform" "wifi" "i2c" "logger" "ota" "sensor" ] (key:
|
||||||
|
mkOption {
|
||||||
|
type = types.unspecified;
|
||||||
|
default = {};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,8 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
continue.envVar = "TF_NIX_CONTINUE_${replaceStrings [ "-" ] [ "_" ] config.name}";
|
continue.envVar = "TF_NIX_CONTINUE_${replaceStrings [ "-" ] [ "_" ] config.name}";
|
||||||
}) ++ map (nodeName: mapAttrs (_: mkMerge) meta.network.nodes.nixos.${nodeName}.deploy.tf.out.set) config.nodeNames);
|
}) ++ map (nodeName: mapAttrs (_: mkMerge) meta.network.nodes.nixos.${nodeName}.deploy.tf.out.set) config.nodeNames
|
||||||
|
++ (optionals (config.name == "home") (mapAttrsToList (node: config: (mapAttrs (_: mkMerge) config.deploy.tf.out.set)) meta.network.nodes.esphome)));
|
||||||
});
|
});
|
||||||
in
|
in
|
||||||
mkOption {
|
mkOption {
|
||||||
|
|
|
||||||
|
|
@ -49,32 +49,13 @@ with lib;
|
||||||
default = { };
|
default = { };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
union = mkOption {
|
nodes.all = mkOption {
|
||||||
type = types.attrsOf types.unspecified;
|
type = types.attrsOf types.unspecified;
|
||||||
default = config.network.nodes.nixos // config.network.nodes.darwin // config.network.nodes.esphome;
|
default = config.network.nodes.nixos // config.network.nodes.darwin // config.network.nodes.esphome;
|
||||||
};
|
};
|
||||||
nodes.esphome = let
|
nodes.esphome = let
|
||||||
esphomeModule = { name, config, meta, lib, ... }: with lib;
|
|
||||||
let
|
|
||||||
settings = config.settings;
|
|
||||||
closureConfig = pkgs.writeText "${settings.esphome.name}.json" builtins.toJSON settings;
|
|
||||||
closure = pkgs.runCommand "${settings.esphome.name}" {} ''
|
|
||||||
${pkgs.esphome}/bin/esphome compile ${closureConfig}
|
|
||||||
mv .esphome/build/${settings.esphome.name}/.pioenvs/${settings.esphome.name}/firmware.bin $out
|
|
||||||
'';
|
|
||||||
in {
|
|
||||||
options.out = mkOption {
|
|
||||||
type = types.unspecified;
|
|
||||||
default = closure;
|
|
||||||
};
|
|
||||||
options.settings = mkOption {
|
|
||||||
type = types.unspecified;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
esphomeType = types.submoduleWith {
|
esphomeType = types.submoduleWith {
|
||||||
modules = [
|
modules = [ { _module.args.pkgs = pkgs; } ] ++ config.network.esphome.extraModules;
|
||||||
esphomeModule
|
|
||||||
] ++ config.network.esphome.extraModules;
|
|
||||||
inherit (config.network.esphome) specialArgs;
|
inherit (config.network.esphome) specialArgs;
|
||||||
};
|
};
|
||||||
in mkOption {
|
in mkOption {
|
||||||
|
|
@ -158,8 +139,10 @@ with lib;
|
||||||
config.network = {
|
config.network = {
|
||||||
esphome = {
|
esphome = {
|
||||||
extraModules = [
|
extraModules = [
|
||||||
|
meta.modules.esphome
|
||||||
];
|
];
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
|
target = config.deploy.targets.home;
|
||||||
inherit (config.network) nodes;
|
inherit (config.network) nodes;
|
||||||
inherit inputs meta;
|
inherit inputs meta;
|
||||||
};
|
};
|
||||||
|
|
@ -186,7 +169,7 @@ with lib;
|
||||||
];
|
];
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit (config.network) nodes;
|
inherit (config.network) nodes;
|
||||||
inherit inputs meta;
|
inherit inputs meta pkgs;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -289,20 +289,6 @@
|
||||||
acme = let
|
acme = let
|
||||||
home = meta.deploy.targets.home.tf;
|
home = meta.deploy.targets.home.tf;
|
||||||
in {
|
in {
|
||||||
enable = true;
|
|
||||||
account = {
|
|
||||||
emailAddress = "kat@inskip.me";
|
|
||||||
accountKeyPem = home.resources.acme_private_key.importAttr "private_key_pem";
|
|
||||||
};
|
|
||||||
challenge = {
|
|
||||||
defaultProvider = "rfc2136";
|
|
||||||
configs.rfc2136 = {
|
|
||||||
RFC2136_NAMESERVER = tf.variables.katdns-address.ref;
|
|
||||||
RFC2136_TSIG_KEY = tf.variables.katdns-name.ref;
|
|
||||||
RFC2136_TSIG_SECRET = tf.variables.katdns-key.ref;
|
|
||||||
RFC2136_TSIG_ALGORITHM = "hmac-sha512";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
certs = let
|
certs = let
|
||||||
nvP = network: settings: nameValuePair settings.uqdn {
|
nvP = network: settings: nameValuePair settings.uqdn {
|
||||||
keyType = "4096";
|
keyType = "4096";
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@
|
||||||
};
|
};
|
||||||
"modules/darwin".functor.enable = true;
|
"modules/darwin".functor.enable = true;
|
||||||
"modules/system".functor.enable = true;
|
"modules/system".functor.enable = true;
|
||||||
|
"modules/esphome".functor.enable = true;
|
||||||
"modules/meta".functor.enable = true;
|
"modules/meta".functor.enable = true;
|
||||||
"nixos/systems".functor.enable = false;
|
"nixos/systems".functor.enable = false;
|
||||||
"darwin/systems".functor.enable = false;
|
"darwin/systems".functor.enable = false;
|
||||||
|
|
@ -125,11 +126,9 @@
|
||||||
esphomeNodes = (map
|
esphomeNodes = (map
|
||||||
(node: {
|
(node: {
|
||||||
network.nodes.esphome.${node} = {
|
network.nodes.esphome.${node} = {
|
||||||
settings = {
|
imports = config.lib.kw.esphomeImport node;
|
||||||
imports = config.lib.kw.esphomeImport node;
|
esphome = {
|
||||||
esphome = {
|
name = node;
|
||||||
name = node;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
|
||||||
2
tf
2
tf
|
|
@ -1 +1 @@
|
||||||
Subproject commit 856827e23fd7f1ef1d07dea9c5be26c0a0f7dee8
|
Subproject commit 19085b061685d726090c2b5fdc3afe536ad43dd7
|
||||||
16
tf.nix
16
tf.nix
|
|
@ -18,6 +18,22 @@
|
||||||
type = "string";
|
type = "string";
|
||||||
sensitive = true;
|
sensitive = true;
|
||||||
};
|
};
|
||||||
|
acme = {
|
||||||
|
enable = true;
|
||||||
|
account = {
|
||||||
|
emailAddress = "kat@inskip.me";
|
||||||
|
accountKeyPem = home.resources.acme_private_key.importAttr "private_key_pem";
|
||||||
|
};
|
||||||
|
challenge = {
|
||||||
|
defaultProvider = "rfc2136";
|
||||||
|
configs.rfc2136 = {
|
||||||
|
RFC2136_NAMESERVER = tf.variables.katdns-address.ref;
|
||||||
|
RFC2136_TSIG_KEY = tf.variables.katdns-name.ref;
|
||||||
|
RFC2136_TSIG_SECRET = tf.variables.katdns-key.ref;
|
||||||
|
RFC2136_TSIG_ALGORITHM = "hmac-sha512";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
providers.katdns = {
|
providers.katdns = {
|
||||||
type = "dns";
|
type = "dns";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue