Compare commits
No commits in common. "firezone" and "master" have entirely different histories.
@ -100,5 +100,7 @@
|
|||||||
security.acme.defaults.email = "zuckerberg@neet.dev";
|
security.acme.defaults.email = "zuckerberg@neet.dev";
|
||||||
|
|
||||||
# Enable Desktop Environment if this is a PC (machine role is "personal")
|
# Enable Desktop Environment if this is a PC (machine role is "personal")
|
||||||
de.enable = lib.mkDefault (config.thisMachine.hasRole."personal");
|
de.enable = (
|
||||||
|
builtins.elem config.networking.hostName config.machines.roles.personal
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,20 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
machines = config.machines.hosts;
|
machines = config.machines.hosts;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./ssh.nix
|
||||||
|
./roles.nix
|
||||||
|
];
|
||||||
|
|
||||||
hostOptionsSubmoduleType = lib.types.submodule {
|
options.machines = {
|
||||||
|
|
||||||
|
hosts = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf
|
||||||
|
(lib.types.submodule {
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
hostNames = lib.mkOption {
|
hostNames = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
description = ''
|
description = ''
|
||||||
@ -15,18 +26,21 @@ let
|
|||||||
Used for automatically trusting hosts for ssh connections.
|
Used for automatically trusting hosts for ssh connections.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
arch = lib.mkOption {
|
arch = lib.mkOption {
|
||||||
type = lib.types.enum [ "x86_64-linux" "aarch64-linux" ];
|
type = lib.types.enum [ "x86_64-linux" "aarch64-linux" ];
|
||||||
description = ''
|
description = ''
|
||||||
The architecture of this machine.
|
The architecture of this machine.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
systemRoles = lib.mkOption {
|
systemRoles = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str; # TODO: maybe use an enum?
|
type = lib.types.listOf lib.types.str; # TODO: maybe use an enum?
|
||||||
description = ''
|
description = ''
|
||||||
The set of roles this machine holds. Affects secrets available. (TODO add service config as well using this info)
|
The set of roles this machine holds. Affects secrets available. (TODO add service config as well using this info)
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
hostKey = lib.mkOption {
|
hostKey = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
description = ''
|
description = ''
|
||||||
@ -34,6 +48,7 @@ let
|
|||||||
and for decrypting secrets with agenix.
|
and for decrypting secrets with agenix.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
remoteUnlock = lib.mkOption {
|
remoteUnlock = lib.mkOption {
|
||||||
default = null;
|
default = null;
|
||||||
type = lib.types.nullOr (lib.types.submodule {
|
type = lib.types.nullOr (lib.types.submodule {
|
||||||
@ -65,6 +80,7 @@ let
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
userKeys = lib.mkOption {
|
userKeys = lib.mkOption {
|
||||||
default = [ ];
|
default = [ ];
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
@ -74,6 +90,7 @@ let
|
|||||||
TODO: consider auto populating other programs that use ssh keys such as gitea
|
TODO: consider auto populating other programs that use ssh keys such as gitea
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
deployKeys = lib.mkOption {
|
deployKeys = lib.mkOption {
|
||||||
default = [ ];
|
default = [ ];
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
@ -81,30 +98,17 @@ let
|
|||||||
The list of deployment keys. Each key here can be used to log into all other systems as `root`.
|
The list of deployment keys. Each key here can be used to log into all other systems as `root`.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
configurationPath = lib.mkOption {
|
configurationPath = lib.mkOption {
|
||||||
type = lib.types.path;
|
type = lib.types.path;
|
||||||
description = ''
|
description = ''
|
||||||
The path to this machine's configuration directory.
|
The path to this machine's configuration directory.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
./ssh.nix
|
|
||||||
./roles.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
options.machines = {
|
|
||||||
hosts = lib.mkOption {
|
|
||||||
type = lib.types.attrsOf hostOptionsSubmoduleType;
|
|
||||||
};
|
};
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
options.thisMachine.config = lib.mkOption {
|
|
||||||
# For ease of use, a direct copy of the host config from machines.hosts.${hostName}
|
|
||||||
type = hostOptionsSubmoduleType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
@ -192,12 +196,5 @@ in
|
|||||||
builtins.map (p: { "${dirName p}" = p; }) propFiles;
|
builtins.map (p: { "${dirName p}" = p; }) propFiles;
|
||||||
in
|
in
|
||||||
properties ../../machines;
|
properties ../../machines;
|
||||||
|
|
||||||
# Don't try to evaluate "thisMachine" when reflecting using moduleless.nix.
|
|
||||||
# When evaluated by moduleless.nix this will fail due to networking.hostName not
|
|
||||||
# existing. This is because moduleless.nix is not intended for reflection from the
|
|
||||||
# perspective of a perticular machine but is instead intended for reflecting on
|
|
||||||
# the properties of all machines as a whole system.
|
|
||||||
thisMachine.config = config.machines.hosts.${config.networking.hostName};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,55 +1,19 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
# Maps roles to their hosts.
|
# Maps roles to their hosts
|
||||||
# machines.withRole = {
|
|
||||||
# personal = [
|
|
||||||
# "machine1" "machine3"
|
|
||||||
# ];
|
|
||||||
# cache = [
|
|
||||||
# "machine2"
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# A list of all possible roles
|
|
||||||
# machines.allRoles = [
|
|
||||||
# "personal"
|
|
||||||
# "cache"
|
|
||||||
# ];
|
|
||||||
#
|
|
||||||
# For each role has true or false if the current machine has that role
|
|
||||||
# thisMachine.hasRole = {
|
|
||||||
# personal = true;
|
|
||||||
# cache = false;
|
|
||||||
# };
|
|
||||||
|
|
||||||
{
|
{
|
||||||
options.machines.withRole = lib.mkOption {
|
options.machines.roles = lib.mkOption {
|
||||||
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
|
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
|
||||||
};
|
};
|
||||||
|
|
||||||
options.machines.allRoles = lib.mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
options.thisMachine.hasRole = lib.mkOption {
|
|
||||||
type = lib.types.attrsOf lib.types.bool;
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
machines.withRole = lib.zipAttrs
|
machines.roles = lib.zipAttrs
|
||||||
(lib.mapAttrsToList
|
(lib.mapAttrsToList
|
||||||
(host: cfg:
|
(host: cfg:
|
||||||
lib.foldl (lib.mergeAttrs) { }
|
lib.foldl (lib.mergeAttrs) { }
|
||||||
(builtins.map (role: { ${role} = host; })
|
(builtins.map (role: { ${role} = host; })
|
||||||
cfg.systemRoles))
|
cfg.systemRoles))
|
||||||
config.machines.hosts);
|
config.machines.hosts);
|
||||||
|
|
||||||
machines.allRoles = lib.attrNames config.machines.withRole;
|
|
||||||
|
|
||||||
thisMachine.hasRole = lib.mapAttrs
|
|
||||||
(role: cfg:
|
|
||||||
builtins.elem config.networking.hostName config.machines.withRole.${role}
|
|
||||||
)
|
|
||||||
config.machines.withRole;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,6 @@ in
|
|||||||
builtins.map
|
builtins.map
|
||||||
(host: machines.hosts.${host}.hostKey)
|
(host: machines.hosts.${host}.hostKey)
|
||||||
hosts)
|
hosts)
|
||||||
machines.withRole;
|
machines.roles;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
builderRole = "nix-builder";
|
||||||
builderUserName = "nix-builder";
|
builderUserName = "nix-builder";
|
||||||
|
|
||||||
builderRole = "nix-builder";
|
machinesByRole = role: lib.filterAttrs (hostname: cfg: builtins.elem role cfg.systemRoles) config.machines.hosts;
|
||||||
builders = config.machines.withRole.${builderRole};
|
otherMachinesByRole = role: lib.filterAttrs (hostname: cfg: hostname != config.networking.hostName) (machinesByRole role);
|
||||||
thisMachineIsABuilder = config.thisMachine.hasRole.${builderRole};
|
thisMachineHasRole = role: builtins.hasAttr config.networking.hostName (machinesByRole role);
|
||||||
|
|
||||||
|
builders = machinesByRole builderRole;
|
||||||
|
thisMachineIsABuilder = thisMachineHasRole builderRole;
|
||||||
|
|
||||||
# builders don't include themselves as a remote builder
|
# builders don't include themselves as a remote builder
|
||||||
otherBuilders = lib.filter (hostname: hostname != config.networking.hostName) builders;
|
otherBuilders = lib.filterAttrs (hostname: cfg: hostname != config.networking.hostName) builders;
|
||||||
in
|
in
|
||||||
lib.mkMerge [
|
lib.mkMerge [
|
||||||
# configure builder
|
# configure builder
|
||||||
@ -36,9 +40,9 @@ lib.mkMerge [
|
|||||||
nix.distributedBuilds = true;
|
nix.distributedBuilds = true;
|
||||||
|
|
||||||
nix.buildMachines = builtins.map
|
nix.buildMachines = builtins.map
|
||||||
(builderHostname: {
|
(builderCfg: {
|
||||||
hostName = builderHostname;
|
hostName = builtins.elemAt builderCfg.hostNames 0;
|
||||||
system = config.machines.hosts.${builderHostname}.arch;
|
system = builderCfg.arch;
|
||||||
protocol = "ssh-ng";
|
protocol = "ssh-ng";
|
||||||
sshUser = builderUserName;
|
sshUser = builderUserName;
|
||||||
sshKey = "/etc/ssh/ssh_host_ed25519_key";
|
sshKey = "/etc/ssh/ssh_host_ed25519_key";
|
||||||
@ -46,7 +50,7 @@ lib.mkMerge [
|
|||||||
speedFactor = 10;
|
speedFactor = 10;
|
||||||
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
|
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
|
||||||
})
|
})
|
||||||
otherBuilders;
|
(builtins.attrValues otherBuilders);
|
||||||
|
|
||||||
# It is very likely that the builder's internet is faster or just as fast
|
# It is very likely that the builder's internet is faster or just as fast
|
||||||
nix.extraOptions = ''
|
nix.extraOptions = ''
|
||||||
|
@ -1,16 +1,87 @@
|
|||||||
|
# Starting point:
|
||||||
|
# https://github.com/aldoborrero/mynixpkgs/commit/c501c1e32dba8f4462dcecb57eee4b9e52038e27
|
||||||
|
|
||||||
{ config, pkgs, lib, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.actual;
|
cfg = config.services.actual-server;
|
||||||
|
stateDir = "/var/lib/${cfg.stateDirName}";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
config = lib.mkIf cfg.enable {
|
options.services.actual-server = {
|
||||||
services.actual.settings = {
|
enable = lib.mkEnableOption "Actual Server";
|
||||||
port = 25448;
|
|
||||||
|
hostname = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "localhost";
|
||||||
|
description = "Hostname for the Actual Server.";
|
||||||
};
|
};
|
||||||
|
|
||||||
backup.group."actual-budget".paths = [
|
port = lib.mkOption {
|
||||||
"/var/lib/actual"
|
type = lib.types.int;
|
||||||
];
|
default = 25448;
|
||||||
|
description = "Port on which the Actual Server should listen.";
|
||||||
|
};
|
||||||
|
|
||||||
|
stateDirName = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "actual-server";
|
||||||
|
description = "Name of the directory under /var/lib holding the server's data.";
|
||||||
|
};
|
||||||
|
|
||||||
|
upload = {
|
||||||
|
fileSizeSyncLimitMB = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.int;
|
||||||
|
default = null;
|
||||||
|
description = "File size limit in MB for synchronized files.";
|
||||||
|
};
|
||||||
|
|
||||||
|
syncEncryptedFileSizeLimitMB = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.int;
|
||||||
|
default = null;
|
||||||
|
description = "File size limit in MB for synchronized encrypted files.";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSizeLimitMB = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.int;
|
||||||
|
default = null;
|
||||||
|
description = "File size limit in MB for file uploads.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
systemd.services.actual-server = {
|
||||||
|
description = "Actual Server";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${pkgs.actual-server}/bin/actual-server";
|
||||||
|
Restart = "always";
|
||||||
|
StateDirectory = cfg.stateDirName;
|
||||||
|
WorkingDirectory = stateDir;
|
||||||
|
DynamicUser = true;
|
||||||
|
UMask = "0007";
|
||||||
|
};
|
||||||
|
environment = {
|
||||||
|
NODE_ENV = "production";
|
||||||
|
ACTUAL_PORT = toString cfg.port;
|
||||||
|
|
||||||
|
# Actual is actually very bad at configuring it's own paths despite that information being readily available
|
||||||
|
ACTUAL_USER_FILES = "${stateDir}/user-files";
|
||||||
|
ACTUAL_SERVER_FILES = "${stateDir}/server-files";
|
||||||
|
ACTUAL_DATA_DIR = stateDir;
|
||||||
|
|
||||||
|
ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB = toString (cfg.upload.fileSizeSyncLimitMB or "");
|
||||||
|
ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SIZE_LIMIT_MB = toString (cfg.upload.syncEncryptedFileSizeLimitMB or "");
|
||||||
|
ACTUAL_UPLOAD_FILE_SIZE_LIMIT_MB = toString (cfg.upload.fileSizeLimitMB or "");
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts.${cfg.hostname} = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/".proxyPass = "http://localhost:${toString cfg.port}";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,10 @@
|
|||||||
# TODO: skipping running inside of nixos container for now because of issues getting docker/podman running
|
# TODO: skipping running inside of nixos container for now because of issues getting docker/podman running
|
||||||
|
|
||||||
let
|
let
|
||||||
thisMachineIsARunner = config.thisMachine.hasRole."gitea-actions-runner";
|
runnerRole = "gitea-actions-runner";
|
||||||
|
runners = config.machines.roles.${runnerRole};
|
||||||
|
thisMachineIsARunner = builtins.elem config.networking.hostName runners;
|
||||||
|
|
||||||
containerName = "gitea-runner";
|
containerName = "gitea-runner";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
11
flake.nix
11
flake.nix
@ -84,11 +84,13 @@
|
|||||||
|
|
||||||
outputs = { self, nixpkgs, ... }@inputs:
|
outputs = { self, nixpkgs, ... }@inputs:
|
||||||
let
|
let
|
||||||
machineHosts = (import ./common/machine-info/moduleless.nix
|
machines = (import ./common/machine-info/moduleless.nix
|
||||||
{
|
{
|
||||||
inherit nixpkgs;
|
inherit nixpkgs;
|
||||||
assertionsModule = "${nixpkgs}/nixos/modules/misc/assertions.nix";
|
assertionsModule = "${nixpkgs}/nixos/modules/misc/assertions.nix";
|
||||||
}).machines.hosts;
|
}).machines;
|
||||||
|
machineHosts = machines.hosts;
|
||||||
|
machineRoles = machines.roles;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
nixosConfigurations =
|
nixosConfigurations =
|
||||||
@ -113,7 +115,10 @@
|
|||||||
|
|
||||||
home-manager.useGlobalPkgs = true;
|
home-manager.useGlobalPkgs = true;
|
||||||
home-manager.useUserPackages = true;
|
home-manager.useUserPackages = true;
|
||||||
home-manager.users.googlebot = import ./home/googlebot.nix;
|
home-manager.users.googlebot = import ./home/googlebot.nix {
|
||||||
|
inherit hostname;
|
||||||
|
inherit machineRoles;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# because nixos specialArgs doesn't work for containers... need to pass in inputs a different way
|
# because nixos specialArgs doesn't work for containers... need to pass in inputs a different way
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
{ config, lib, pkgs, osConfig, ... }:
|
{ hostname, machineRoles }:
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
# Check if the current machine has the role "personal"
|
# Check if the current machine has the role "personal"
|
||||||
thisMachineIsPersonal = osConfig.thisMachine.hasRole."personal";
|
thisMachineIsPersonal = builtins.elem hostname machineRoles.personal;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
home.username = "googlebot";
|
home.username = "googlebot";
|
||||||
|
@ -9,20 +9,4 @@
|
|||||||
nix.distributedBuilds = lib.mkForce false;
|
nix.distributedBuilds = lib.mkForce false;
|
||||||
|
|
||||||
nix.gc.automatic = lib.mkForce false;
|
nix.gc.automatic = lib.mkForce false;
|
||||||
|
|
||||||
services.resolved.enable = true;
|
|
||||||
|
|
||||||
# services.firezone.headless-client = {
|
|
||||||
# enable = true;
|
|
||||||
# name = config.networking.hostName;
|
|
||||||
# apiUrl = "wss://api.firezone.dev/";
|
|
||||||
# tokenFile = "/run/agenix/firezone-token";
|
|
||||||
# };
|
|
||||||
# age.secrets.firezone-token.file = ../../secrets/firezone-token.age;
|
|
||||||
|
|
||||||
# services.firezone.gui-client = {
|
|
||||||
# enable = true;
|
|
||||||
# name = config.networking.hostName;
|
|
||||||
# allowedUsers = [ "googlebot" ];
|
|
||||||
# };
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
systemRoles = [
|
systemRoles = [
|
||||||
"personal"
|
"personal"
|
||||||
"firezone"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEQi3q8jU6vRruExAL60J7GFO1gS8HsmXVJuKRT4ljrG";
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEQi3q8jU6vRruExAL60J7GFO1gS8HsmXVJuKRT4ljrG";
|
||||||
|
@ -149,4 +149,7 @@
|
|||||||
# librechat
|
# librechat
|
||||||
services.librechat.enable = true;
|
services.librechat.enable = true;
|
||||||
services.librechat.host = "chat.neet.dev";
|
services.librechat.host = "chat.neet.dev";
|
||||||
|
|
||||||
|
services.actual-server.enable = true;
|
||||||
|
services.actual-server.hostname = "actual.runyan.org";
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
"dailybot"
|
"dailybot"
|
||||||
"gitea"
|
"gitea"
|
||||||
"librechat"
|
"librechat"
|
||||||
"firezone"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMBBlTAIp38RhErU1wNNV5MBeb+WGH0mhF/dxh5RsAXN";
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMBBlTAIp38RhErU1wNNV5MBeb+WGH0mhF/dxh5RsAXN";
|
||||||
|
@ -222,7 +222,6 @@
|
|||||||
(mkVirtualHost "vacuum.s0.neet.dev" "http://192.168.1.125") # valetudo
|
(mkVirtualHost "vacuum.s0.neet.dev" "http://192.168.1.125") # valetudo
|
||||||
(mkVirtualHost "sandman.s0.neet.dev" "http://192.168.9.14:3000") # es
|
(mkVirtualHost "sandman.s0.neet.dev" "http://192.168.9.14:3000") # es
|
||||||
(mkVirtualHost "todo.s0.neet.dev" "http://localhost:${toString config.services.vikunja.port}")
|
(mkVirtualHost "todo.s0.neet.dev" "http://localhost:${toString config.services.vikunja.port}")
|
||||||
(mkVirtualHost "budget.s0.neet.dev" "http://localhost:${toString config.services.actual.settings.port}") # actual budget
|
|
||||||
];
|
];
|
||||||
|
|
||||||
tailscaleAuth = {
|
tailscaleAuth = {
|
||||||
@ -271,6 +270,7 @@
|
|||||||
openMinimalFirewall = true;
|
openMinimalFirewall = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# TODO: setup backup
|
||||||
services.vikunja = {
|
services.vikunja = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 61473;
|
port = 61473;
|
||||||
@ -284,7 +284,5 @@
|
|||||||
"/var/lib/vikunja"
|
"/var/lib/vikunja"
|
||||||
];
|
];
|
||||||
|
|
||||||
services.actual.enable = true;
|
|
||||||
|
|
||||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" "armv7l-linux" ];
|
boot.binfmt.emulatedSystems = [ "aarch64-linux" "armv7l-linux" ];
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
hostNames = [
|
hostNames = [
|
||||||
"s0"
|
"s0"
|
||||||
"s0.neet.dev"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
arch = "x86_64-linux";
|
arch = "x86_64-linux";
|
||||||
@ -14,15 +13,12 @@
|
|||||||
"gitea-actions-runner"
|
"gitea-actions-runner"
|
||||||
"frigate"
|
"frigate"
|
||||||
"zigbee"
|
"zigbee"
|
||||||
"firezone"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAwiXcUFtAvZCayhu4+AIcF+Ktrdgv9ee/mXSIhJbp4q";
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAwiXcUFtAvZCayhu4+AIcF+Ktrdgv9ee/mXSIhJbp4q";
|
||||||
|
|
||||||
remoteUnlock = {
|
remoteUnlock = {
|
||||||
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNiceeFMos5ZXcYem4yFxh8PiZNNnuvhlyLbQLrgIZH";
|
hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNiceeFMos5ZXcYem4yFxh8PiZNNnuvhlyLbQLrgIZH";
|
||||||
|
|
||||||
clearnetHost = "192.168.1.2";
|
|
||||||
onionHost = "r3zvf7f2ppaeithzswigma46pajt3hqytmkg3rshgknbl3jbni455fqd.onion";
|
onionHost = "r3zvf7f2ppaeithzswigma46pajt3hqytmkg3rshgknbl3jbni455fqd.onion";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
39
overlays/actualbudget/default.nix
Normal file
39
overlays/actualbudget/default.nix
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{ lib
|
||||||
|
, buildNpmPackage
|
||||||
|
, fetchFromGitHub
|
||||||
|
, python3
|
||||||
|
, nodejs
|
||||||
|
, runtimeShell
|
||||||
|
}:
|
||||||
|
buildNpmPackage rec {
|
||||||
|
pname = "actual-server";
|
||||||
|
version = "24.10.1";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "actualbudget";
|
||||||
|
repo = pname;
|
||||||
|
rev = "refs/tags/v${version}";
|
||||||
|
hash = "sha256-VJAD+lNamwuYmiPJLXkum6piGi5zLOHBp8cUeZagb4s=";
|
||||||
|
};
|
||||||
|
|
||||||
|
npmDepsHash = "sha256-Z2e4+JMhI/keLerT0F4WYdLnXHRQCqL7NjNyA9SFEF8=";
|
||||||
|
|
||||||
|
patches = [
|
||||||
|
./migrations-should-use-pkg-path.patch
|
||||||
|
];
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
cp ${./package-lock.json} package-lock.json
|
||||||
|
'';
|
||||||
|
|
||||||
|
dontNpmBuild = true;
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cat <<EOF > $out/bin/actual-server
|
||||||
|
#!${runtimeShell}
|
||||||
|
exec ${nodejs}/bin/node $out/lib/node_modules/actual-sync/app.js "\$@"
|
||||||
|
EOF
|
||||||
|
chmod +x $out/bin/actual-server
|
||||||
|
'';
|
||||||
|
}
|
48
overlays/actualbudget/migrations-should-use-pkg-path.patch
Normal file
48
overlays/actualbudget/migrations-should-use-pkg-path.patch
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
diff --git a/src/load-config.js b/src/load-config.js
|
||||||
|
index d99ce42..42d1351 100644
|
||||||
|
--- a/src/load-config.js
|
||||||
|
+++ b/src/load-config.js
|
||||||
|
@@ -3,7 +3,8 @@ import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import createDebug from 'debug';
|
||||||
|
|
||||||
|
-const debug = createDebug('actual:config');
|
||||||
|
+// const debug = createDebug('actual:config');
|
||||||
|
+const debug = console.log;
|
||||||
|
const debugSensitive = createDebug('actual-sensitive:config');
|
||||||
|
|
||||||
|
const projectRoot = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
||||||
|
@@ -108,6 +109,7 @@ const finalConfig = {
|
||||||
|
serverFiles: process.env.ACTUAL_SERVER_FILES || config.serverFiles,
|
||||||
|
userFiles: process.env.ACTUAL_USER_FILES || config.userFiles,
|
||||||
|
webRoot: process.env.ACTUAL_WEB_ROOT || config.webRoot,
|
||||||
|
+ dataDir: process.env.ACTUAL_DATA_DIR || config.dataDir,
|
||||||
|
https:
|
||||||
|
process.env.ACTUAL_HTTPS_KEY && process.env.ACTUAL_HTTPS_CERT
|
||||||
|
? {
|
||||||
|
diff --git a/src/migrations.js b/src/migrations.js
|
||||||
|
index cba7db0..9983471 100644
|
||||||
|
--- a/src/migrations.js
|
||||||
|
+++ b/src/migrations.js
|
||||||
|
@@ -1,6 +1,12 @@
|
||||||
|
import migrate from 'migrate';
|
||||||
|
import path from 'node:path';
|
||||||
|
import config from './load-config.js';
|
||||||
|
+import { fileURLToPath } from 'url';
|
||||||
|
+
|
||||||
|
+const __filename = fileURLToPath(import.meta.url);
|
||||||
|
+const __dirname = path.dirname(__filename);
|
||||||
|
+const appRoot = path.dirname(__dirname);
|
||||||
|
+const migrationsDirectory = path.join(appRoot, "migrations");
|
||||||
|
|
||||||
|
export default function run(direction = 'up') {
|
||||||
|
console.log(
|
||||||
|
@@ -13,7 +19,7 @@ export default function run(direction = 'up') {
|
||||||
|
stateStore: `${path.join(config.dataDir, '.migrate')}${
|
||||||
|
config.mode === 'test' ? '-test' : ''
|
||||||
|
}`,
|
||||||
|
- migrationsDirectory: `${path.join(config.projectRoot, 'migrations')}`,
|
||||||
|
+ migrationsDirectory
|
||||||
|
},
|
||||||
|
(err, set) => {
|
||||||
|
if (err) {
|
8954
overlays/actualbudget/package-lock.json
generated
Normal file
8954
overlays/actualbudget/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,4 +4,10 @@ final: prev:
|
|||||||
let
|
let
|
||||||
system = prev.system;
|
system = prev.system;
|
||||||
in
|
in
|
||||||
{ }
|
{
|
||||||
|
actual-server = prev.callPackage ./actualbudget { };
|
||||||
|
|
||||||
|
# Copied entire package from nixpkgs to downgrade to python 3.11 since 3.12 is broken.
|
||||||
|
# See: https://github.com/Py-KMS-Organization/py-kms/issues/117
|
||||||
|
pykms = prev.callPackage ./pykms.nix { };
|
||||||
|
}
|
||||||
|
103
overlays/pykms.nix
Normal file
103
overlays/pykms.nix
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
{ lib
|
||||||
|
, fetchFromGitHub
|
||||||
|
, python311
|
||||||
|
, writeText
|
||||||
|
, writeShellScript
|
||||||
|
, sqlite
|
||||||
|
, nixosTests
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
pypkgs = python311.pkgs;
|
||||||
|
|
||||||
|
dbSql = writeText "create_pykms_db.sql" ''
|
||||||
|
CREATE TABLE clients(
|
||||||
|
clientMachineId TEXT,
|
||||||
|
machineName TEXT,
|
||||||
|
applicationId TEXT,
|
||||||
|
skuId TEXT,
|
||||||
|
licenseStatus TEXT,
|
||||||
|
lastRequestTime INTEGER,
|
||||||
|
kmsEpid TEXT,
|
||||||
|
requestCount INTEGER
|
||||||
|
);
|
||||||
|
'';
|
||||||
|
|
||||||
|
dbScript = writeShellScript "create_pykms_db.sh" ''
|
||||||
|
set -eEuo pipefail
|
||||||
|
|
||||||
|
db=''${1:-/var/lib/pykms/clients.db}
|
||||||
|
|
||||||
|
if [ ! -e $db ] ; then
|
||||||
|
${lib.getBin sqlite}/bin/sqlite3 $db < ${dbSql}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
in
|
||||||
|
pypkgs.buildPythonApplication rec {
|
||||||
|
pname = "pykms";
|
||||||
|
version = "unstable-2024-05-28";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "Py-KMS-Organization";
|
||||||
|
repo = "py-kms";
|
||||||
|
rev = "646f4766f4195dbea0695700a7ddaac70a3294f9";
|
||||||
|
hash = "sha256-YCqPo7WkCfXyuTjL4IYapdcUN/Vj465Jz6XhQessyz0=";
|
||||||
|
};
|
||||||
|
|
||||||
|
sourceRoot = "${src.name}/py-kms";
|
||||||
|
|
||||||
|
propagatedBuildInputs = with pypkgs; [
|
||||||
|
systemd
|
||||||
|
pytz
|
||||||
|
tzlocal
|
||||||
|
dnspython
|
||||||
|
];
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
siteDir=$out/${python311.sitePackages}
|
||||||
|
|
||||||
|
substituteInPlace pykms_DB2Dict.py \
|
||||||
|
--replace "'KmsDataBase.xml'" "'$siteDir/KmsDataBase.xml'"
|
||||||
|
'';
|
||||||
|
|
||||||
|
format = "other";
|
||||||
|
|
||||||
|
# there are no tests
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p $siteDir
|
||||||
|
|
||||||
|
PYTHONPATH="$PYTHONPATH:$siteDir"
|
||||||
|
|
||||||
|
mv * $siteDir
|
||||||
|
for b in Client Server ; do
|
||||||
|
makeWrapper ${python311.interpreter} $out/bin/''${b,,} \
|
||||||
|
--argv0 pykms-''${b,,} \
|
||||||
|
--add-flags $siteDir/pykms_$b.py \
|
||||||
|
--set PYTHONPATH $PYTHONPATH
|
||||||
|
done
|
||||||
|
|
||||||
|
install -Dm755 ${dbScript} $out/libexec/create_pykms_db.sh
|
||||||
|
|
||||||
|
install -Dm644 ../README.md -t $out/share/doc/pykms
|
||||||
|
|
||||||
|
${python311.interpreter} -m compileall $siteDir
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru.tests = { inherit (nixosTests) pykms; };
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Windows KMS (Key Management Service) server written in Python";
|
||||||
|
homepage = "https://github.com/Py-KMS-Organization/py-kms";
|
||||||
|
license = licenses.unlicense;
|
||||||
|
maintainers = with maintainers; [
|
||||||
|
peterhoeg
|
||||||
|
zopieux
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
Binary file not shown.
@ -60,7 +60,4 @@ with roles;
|
|||||||
|
|
||||||
# zigbee2mqtt secrets
|
# zigbee2mqtt secrets
|
||||||
"zigbee2mqtt.yaml.age".publicKeys = zigbee;
|
"zigbee2mqtt.yaml.age".publicKeys = zigbee;
|
||||||
|
|
||||||
# Firezone Token
|
|
||||||
"firezone-token.age".publicKeys = firezone;
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user