feat: add nix package, module, and container

Signed-off-by: seth <getchoo@tuta.io>
This commit is contained in:
seth 2023-12-03 04:14:20 -05:00
parent 45403e9d9b
commit e928eb67df
No known key found for this signature in database
GPG key ID: D31BD0D494BBEE86
7 changed files with 497 additions and 67 deletions

150
flake.lock generated
View file

@ -1,5 +1,26 @@
{
"nodes": {
"fenix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1701498074,
"narHash": "sha256-UNYTZtBYa/4G5+dRzNNXNcEi1RVm6yOUQNHYkcRag2Q=",
"owner": "nix-community",
"repo": "fenix",
"rev": "ce8747b0d8d6605264651f9ab5c84db6d7a56728",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
@ -16,21 +37,18 @@
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"flake-root": {
"locked": {
"lastModified": 1696343447,
"narHash": "sha256-B2xAZKLkkeRFG5XcHHSXXcP7To9Xzr59KXeZiRf4vdQ=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c9afaba3dfa4085dbd2ccb38dfade5141e33d9d4",
"lastModified": 1692742795,
"narHash": "sha256-f+Y0YhVCIJ06LemO+3Xx00lIcqQxSKJHXT/yk1RTKxw=",
"owner": "srid",
"repo": "flake-root",
"rev": "d9a70d9c7a5fd7f3258ccf48da9335e9b47c3937",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"owner": "srid",
"repo": "flake-root",
"type": "github"
}
},
@ -73,13 +91,33 @@
"type": "github"
}
},
"naersk": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1698420672,
"narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=",
"owner": "nix-community",
"repo": "naersk",
"rev": "aeb58d5e8faead8980a807c840232697982d47b9",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "naersk",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1696757521,
"narHash": "sha256-cfgtLNCBLFx2qOzRLI6DHfqTdfWI+UbvsKYa3b3fvaA=",
"lastModified": 1701336116,
"narHash": "sha256-kEmpezCR/FpITc6yMbAh4WrOCiT2zg5pSjnKrq51h5Y=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "2646b294a146df2781b1ca49092450e8a32814e1",
"rev": "f5c27c6136db4d76c30e533c20517df6864c46ee",
"type": "github"
},
"original": {
@ -89,24 +127,6 @@
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"dir": "lib",
"lastModified": 1696019113,
"narHash": "sha256-X3+DKYWJm93DRSdC5M6K5hLqzSya9BjibtBsuARoPco=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f5892ddac112a1e9b3612c39af1b72987ee5783a",
"type": "github"
},
"original": {
"dir": "lib",
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1685801374,
@ -123,6 +143,26 @@
"type": "github"
}
},
"parts": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1701473968,
"narHash": "sha256-YcVE5emp1qQ8ieHUnxt1wCZCC3ZfAS+SRRWZ2TMda7E=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "34fed993f1674c8d06d58b37ce1e0fe5eebcb9f5",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
@ -134,11 +174,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1696846637,
"narHash": "sha256-0hv4kbXxci2+pxhuXlVgftj/Jq79VSmtAyvfabCCtYk=",
"lastModified": 1700922917,
"narHash": "sha256-ej2fch/T584b5K9sk1UhmZF7W6wEfDHuoUYpFN8dtvM=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "42e1b6095ef80a51f79595d9951eb38e91c4e6ca",
"rev": "e5ee5c5f3844550c01d2131096c7271cec5e9b78",
"type": "github"
},
"original": {
@ -147,11 +187,47 @@
"type": "github"
}
},
"proc-flake": {
"locked": {
"lastModified": 1692742849,
"narHash": "sha256-Nv8SOX+O6twFfPnA9BfubbPLZpqc+UeK6JvIWnWkdb0=",
"owner": "srid",
"repo": "proc-flake",
"rev": "25291b6e3074ad5dd573c1cb7d96110a9591e10f",
"type": "github"
},
"original": {
"owner": "srid",
"repo": "proc-flake",
"type": "github"
}
},
"root": {
"inputs": {
"flake-parts": "flake-parts",
"fenix": "fenix",
"flake-root": "flake-root",
"naersk": "naersk",
"nixpkgs": "nixpkgs",
"pre-commit-hooks": "pre-commit-hooks"
"parts": "parts",
"pre-commit-hooks": "pre-commit-hooks",
"proc-flake": "proc-flake"
}
},
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1701447636,
"narHash": "sha256-WaCcxLNAqo/FAK0QtYqweKCUVTGcbKpFIHClc+k2YlI=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "e402c494b7c7d94a37c6d789a216187aaf9ccd3e",
"type": "github"
},
"original": {
"owner": "rust-lang",
"ref": "nightly",
"repo": "rust-analyzer",
"type": "github"
}
},
"systems": {

View file

@ -3,44 +3,41 @@
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
naersk = {
url = "github:nix-community/naersk";
inputs.nixpkgs.follows = "nixpkgs";
};
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
pre-commit-hooks = {
url = "github:cachix/pre-commit-hooks.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-root.url = "github:srid/flake-root";
proc-flake.url = "github:srid/proc-flake";
};
outputs = {
flake-parts,
pre-commit-hooks,
...
} @ inputs:
flake-parts.lib.mkFlake {inherit inputs;} {
outputs = {parts, ...} @ inputs:
parts.lib.mkFlake {inherit inputs;} {
imports = [
pre-commit-hooks.flakeModule
];
./nix/dev.nix
./nix/packages.nix
./nix/deployment.nix
perSystem = {
config,
lib,
pkgs,
...
}: {
pre-commit.settings.hooks = {
alejandra.enable = true;
prettier = {
enable = true;
excludes = ["flake.lock" "pnpm-lock.yaml"];
};
};
devShells.default = pkgs.mkShell {
shellHook = ''
${config.pre-commit.installationScript}
'';
packages = with pkgs; [nodePackages.pnpm redis];
};
formatter = pkgs.alejandra;
};
inputs.pre-commit-hooks.flakeModule
inputs.flake-root.flakeModule
inputs.proc-flake.flakeModule
];
systems = [
"x86_64-linux"

84
nix/deployment.nix Normal file
View file

@ -0,0 +1,84 @@
{
inputs,
self,
...
}: {
flake.nixosModules.default = import ./module.nix self;
perSystem = {
lib,
pkgs,
system,
config,
inputs',
...
}: let
crossPkgsFor = lib.fix (finalAttrs: {
"x86_64-linux" = {
"x86_64" = pkgs.pkgsStatic;
"aarch64" = pkgs.pkgsCross.aarch64-multiplatform.pkgsStatic;
};
"aarch64-linux" = {
"x86_64" = pkgs.pkgsCross.musl64;
"aarch64" = pkgs.pkgsStatic;
};
"x86_64-darwin" = {
"x86_64" = pkgs.pkgsCross.musl64;
"aarch64" = pkgs.pkgsCross.aarch64-multiplatform.pkgsStatic;
};
"aarch64-darwin" = finalAttrs."x86_64-darwin";
});
exeFor = arch: let
target = "${arch}-unknown-linux-musl";
target' = builtins.replaceStrings ["-"] ["_"] target;
targetUpper = lib.toUpper target';
toolchain = with inputs'.fenix.packages;
combine [
minimal.cargo
minimal.rustc
targets.${target}.latest.rust-std
];
naersk' = inputs.naersk.lib.${system}.override {
cargo = toolchain;
rustc = toolchain;
};
refraction = config.packages.refraction.override {
naersk = naersk';
optimizeSize = true;
};
inherit (crossPkgsFor.${system}.${arch}.stdenv) cc;
in
lib.getExe (
refraction.overrideAttrs (_:
lib.fix (finalAttrs: {
CARGO_BUILD_TARGET = target;
"CC_${target'}" = "${cc}/bin/${cc.targetPrefix}cc";
"CARGO_TARGET_${targetUpper}_RUSTFLAGS" = "-C target-feature=+crt-static";
"CARGO_TARGET_${targetUpper}_LINKER" = finalAttrs."CC_${target'}";
}))
);
containerFor = arch:
pkgs.dockerTools.buildLayeredImage {
name = "refraction";
tag = "latest-${arch}";
contents = [pkgs.dockerTools.caCertificates];
config.Cmd = [(exeFor arch)];
architecture = crossPkgsFor.${system}.${arch}.go.GOARCH;
};
in {
legacyPackages = {
container-x86_64 = containerFor "x86_64";
container-aarch64 = containerFor "aarch64";
};
};
}

51
nix/derivation.nix Normal file
View file

@ -0,0 +1,51 @@
{
lib,
stdenv,
naersk,
CoreFoundation,
Security,
SystemConfiguration,
version,
optimizeSize ? false,
}: let
filter = path: type: let
path' = toString path;
base = baseNameOf path';
dirBlocklist = ["nix"];
matches = lib.any (suffix: lib.hasSuffix suffix base) [".rs"];
isCargo = base == "Cargo.lock" || base == "Cargo.toml";
isAllowedDir = !(builtins.elem base dirBlocklist);
in
(type == "directory" && isAllowedDir) || matches || isCargo;
filterSource = src:
lib.cleanSourceWith {
src = lib.cleanSource src;
inherit filter;
};
in
naersk.buildPackage {
pname = "refraction";
inherit version;
src = filterSource ../.;
buildInputs = lib.optionals stdenv.hostPlatform.isDarwin [
CoreFoundation
Security
SystemConfiguration
];
RUSTFLAGS = lib.optionalString optimizeSize "-C codegen-units=1 -C strip=symbols -C opt-level=z";
meta = with lib; {
mainProgram = "refraction";
description = "Discord bot for Prism Launcher";
homepage = "https://github.com/PrismLauncher/refraction";
license = licenses.gpl3Plus;
platforms = with platforms; linux ++ darwin;
maintainers = with maintainers; [getchoo Scrumplex];
};
}

50
nix/dev.nix Normal file
View file

@ -0,0 +1,50 @@
{
perSystem = {
lib,
pkgs,
config,
...
}: {
pre-commit.settings.hooks = {
actionlint.enable = true;
alejandra.enable = true;
rustfmt.enable = true;
nil.enable = true;
prettier = {
enable = true;
excludes = ["flake.lock"];
};
};
proc.groups.daemons.processes = {
redis.command = "${lib.getExe' pkgs.redis "redis-server"}";
};
devShells.default = pkgs.mkShell {
shellHook = ''
${config.pre-commit.installationScript}
'';
packages = with pkgs; [
# general
actionlint
config.proc.groups.daemons.package
# rust
cargo
rustc
clippy
rustfmt
rust-analyzer
# nix
config.formatter
nil
];
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
};
formatter = pkgs.alejandra;
};
}

143
nix/module.nix Normal file
View file

@ -0,0 +1,143 @@
self: {
config,
lib,
pkgs,
...
}: let
cfg = config.services.refraction;
defaultUser = "refraction";
inherit
(lib)
getExe
literalExpression
mdDoc
mkEnableOption
mkIf
mkOption
mkPackageOption
optionals
types
;
in {
options.services.refraction = {
enable = mkEnableOption "refraction";
package = mkPackageOption self.packages.${pkgs.stdenv.hostPlatform.system} "refraction" {};
user = mkOption {
description = mdDoc ''
User under which the service should run. If this is the default value,
the user will be created, with the specified group as the primary
group.
'';
type = types.str;
default = defaultUser;
example = literalExpression ''
"bob"
'';
};
group = mkOption {
description = mdDoc ''
Group under which the service should run. If this is the default value,
the group will be created.
'';
type = types.str;
default = defaultUser;
example = literalExpression ''
"discordbots"
'';
};
redisUrl = mkOption {
description = mdDoc ''
Connection to a redis server. If this needs to include credentials
that shouldn't be world-readable in the Nix store, set environmentFile
and override the `REDIS_URL` entry.
Pass the string `local` to setup a local Redis database.
'';
type = types.str;
default = "local";
example = literalExpression ''
"redis://localhost/"
'';
};
environmentFile = mkOption {
description = mdDoc ''
Environment file as defined in {manpage}`systemd.exec(5)`
'';
type = types.nullOr types.path;
default = null;
example = literalExpression ''
"/run/agenix.d/1/refraction"
'';
};
};
config = mkIf cfg.enable {
services.redis.servers.refraction = mkIf (cfg.redisUrl == "local") {
enable = true;
inherit (cfg) user;
port = 0; # disable tcp listener
};
systemd.services."refraction" = {
enable = true;
wantedBy = ["multi-user.target"];
after =
["network.target"]
++ optionals (cfg.redisUrl == "local") ["redis-refraction.service"];
script = ''
${getExe cfg.package}
'';
environment = {
REDIS_URL =
if cfg.redisUrl == "local"
then "unix:${config.services.redis.servers.refraction.unixSocket}"
else cfg.redisUrl;
};
serviceConfig = {
Type = "simple";
Restart = "always";
EnvironmentFile = mkIf (cfg.environmentFile != null) cfg.environmentFile;
User = cfg.user;
Group = cfg.group;
# hardening
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
RestrictNamespaces = "uts ipc pid user cgroup";
RestrictSUIDSGID = true;
};
};
users = {
users = mkIf (cfg.user == defaultUser) {
${defaultUser} = {
isSystemUser = true;
inherit (cfg) group;
};
};
groups = mkIf (cfg.group == defaultUser) {
${defaultUser} = {};
};
};
};
}

29
nix/packages.nix Normal file
View file

@ -0,0 +1,29 @@
{
self,
inputs,
...
}: {
perSystem = {
pkgs,
system,
config,
...
}: {
packages = {
refraction = pkgs.callPackage ./derivation.nix {
version = builtins.substring 0 8 self.lastModifiedDate or "dirty";
inherit
(pkgs.darwin.apple_sdk.frameworks)
CoreFoundation
Security
SystemConfiguration
;
naersk = inputs.naersk.lib.${system};
};
default = config.packages.refraction;
};
};
}