mirror of
https://github.com/Blah-IM/blahrs.git
synced 2025-05-01 00:31:09 +00:00
Package with nix and add systemd unit example
This commit is contained in:
parent
a63d0df443
commit
e84b13c876
9 changed files with 287 additions and 3 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,3 +3,5 @@
|
||||||
*.key
|
*.key
|
||||||
|
|
||||||
config.toml
|
config.toml
|
||||||
|
result
|
||||||
|
result-*
|
||||||
|
|
|
@ -20,7 +20,9 @@ use tokio::runtime::Runtime;
|
||||||
/// NB. Sync with docs of [`User::url`].
|
/// NB. Sync with docs of [`User::url`].
|
||||||
const KEY_URL_SUBPATH: &str = "/.well-known/blah/key";
|
const KEY_URL_SUBPATH: &str = "/.well-known/blah/key";
|
||||||
|
|
||||||
|
/// Control or manage Blah Chat Server.
|
||||||
#[derive(Debug, clap::Parser)]
|
#[derive(Debug, clap::Parser)]
|
||||||
|
#[clap(about, version = option_env!("CFG_RELEASE").unwrap_or(env!("CARGO_PKG_VERSION")))]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Command,
|
command: Command,
|
||||||
|
|
46
blahd/blahd.example.service
Normal file
46
blahd/blahd.example.service
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Blah Chat Server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
ExecStart=/usr/bin/blahd serve --config ${CONFIGURATION_DIRECTORY}/blahd.toml
|
||||||
|
ConfigurationDirectory=blahd
|
||||||
|
StateDirectory=blahd
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
|
||||||
|
# Permission and capabilities
|
||||||
|
|
||||||
|
DynamicUser=yes
|
||||||
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||||
|
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||||
|
# 0640 / 0750
|
||||||
|
UMask=0027
|
||||||
|
|
||||||
|
# Sandboxing
|
||||||
|
# Mostly copied from: https://github.com/NixOS/nixpkgs/blob/6414ef7ca3bf18ec4f9628d09ccc1eb030276ee2/nixos/modules/services/web-servers/nginx/default.nix#L1246
|
||||||
|
|
||||||
|
LockPersonality=yes
|
||||||
|
MemoryDenyWriteExecute=yes
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
PrivateDevices=yes
|
||||||
|
PrivateMounts=yes
|
||||||
|
PrivateUsers=yes
|
||||||
|
ProcSubset=pid
|
||||||
|
ProtectClock=yes
|
||||||
|
ProtectControlGroups=yes
|
||||||
|
ProtectHome=yes
|
||||||
|
ProtectHostname=yes
|
||||||
|
ProtectHostname=yes
|
||||||
|
ProtectKernelLogs=yes
|
||||||
|
ProtectKernelModules=yes
|
||||||
|
ProtectKernelTunables=yes
|
||||||
|
ProtectProc=invisible
|
||||||
|
ProtectProc=invisible
|
||||||
|
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||||
|
RestrictNamespaces=yes
|
||||||
|
RestrictRealtime=yes
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
SystemCallFilter=@system-service
|
||||||
|
SystemCallFilter=~@privileged
|
|
@ -1,8 +1,12 @@
|
||||||
|
# The example configuration file, required options are documented as
|
||||||
|
# `(Required)`, other options are optional and the example value given here is
|
||||||
|
# the default value.
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
# (Required)
|
|
||||||
# The path to the main SQLite database.
|
# The path to the main SQLite database.
|
||||||
# It will be created and initialized if not exist.
|
# The file will be created and initialized if not exist, but missing directory
|
||||||
path = "/path/to/db.sqlite"
|
# will not.
|
||||||
|
path = "/var/lib/blahd/db.sqlite"
|
||||||
|
|
||||||
[server]
|
[server]
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,11 @@ pub struct Config {
|
||||||
pub server: ServerConfig,
|
pub server: ServerConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[serde_inline_default]
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct DatabaseConfig {
|
pub struct DatabaseConfig {
|
||||||
|
#[serde_inline_default("/var/lib/blahd/db.sqlite".into())]
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,9 @@ mod middleware;
|
||||||
mod config;
|
mod config;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
|
/// Blah Chat Server
|
||||||
#[derive(Debug, clap::Parser)]
|
#[derive(Debug, clap::Parser)]
|
||||||
|
#[clap(about, version = option_env!("CFG_RELEASE").unwrap_or(env!("CARGO_PKG_VERSION")))]
|
||||||
enum Cli {
|
enum Cli {
|
||||||
/// Run the server with given configuration.
|
/// Run the server with given configuration.
|
||||||
Serve {
|
Serve {
|
||||||
|
|
48
flake.lock
generated
Normal file
48
flake.lock
generated
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"naersk": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1721727458,
|
||||||
|
"narHash": "sha256-r/xppY958gmZ4oTfLiHN0ZGuQ+RSTijDblVgVLFi1mw=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"rev": "3fb418eaf352498f6b6c30592e3beb63df42ef11",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1724819573,
|
||||||
|
"narHash": "sha256-GnR7/ibgIH1vhoy8cYdmXE6iyZqKqFxQSVkFgosBh6w=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "71e91c409d1e654808b2621f28a327acfdad8dc2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"naersk": "naersk",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
80
flake.nix
Normal file
80
flake.nix
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
rec {
|
||||||
|
description = "Blah Chat Server";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
naersk = {
|
||||||
|
url = "github:nix-community/naersk";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
naersk,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (nixpkgs) lib;
|
||||||
|
eachSystem = lib.genAttrs lib.systems.flakeExposed;
|
||||||
|
|
||||||
|
rev = self.rev or (lib.warn "Git changes are not committed" (self.dirtyRev or "dirty"));
|
||||||
|
in
|
||||||
|
{
|
||||||
|
packages = eachSystem (
|
||||||
|
system:
|
||||||
|
let
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
naersk' = pkgs.callPackage naersk { };
|
||||||
|
in
|
||||||
|
rec {
|
||||||
|
default = blahd;
|
||||||
|
blahd = pkgs.callPackage (
|
||||||
|
{
|
||||||
|
pkg-config,
|
||||||
|
openssl,
|
||||||
|
sqlite,
|
||||||
|
}:
|
||||||
|
naersk'.buildPackage rec {
|
||||||
|
pname = "blahd";
|
||||||
|
src = ./.;
|
||||||
|
version = "git-${rev}";
|
||||||
|
CFG_RELEASE = version;
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkg-config
|
||||||
|
];
|
||||||
|
buildInputs = [
|
||||||
|
openssl
|
||||||
|
sqlite
|
||||||
|
];
|
||||||
|
|
||||||
|
cargoBuildOptions = opts: opts ++ [
|
||||||
|
"--package=blahd"
|
||||||
|
"--package=blahctl"
|
||||||
|
];
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
mkdir -p $out/etc/systemd/system
|
||||||
|
substitute ./blahd/blahd.example.service $out/etc/systemd/system/blahd.service \
|
||||||
|
--replace-fail '/usr/bin/blahd' "$out/bin/blahd"
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
inherit description;
|
||||||
|
homepage = "https://github.com/Blah-IM/blahrs";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
) { };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
nixosModules = rec {
|
||||||
|
default = blahd;
|
||||||
|
blahd = import ./nix/module.nix {
|
||||||
|
inherit self;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
98
nix/module.nix
Normal file
98
nix/module.nix
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
{ self }:
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
literalMD
|
||||||
|
mdDoc
|
||||||
|
mkEnableOption
|
||||||
|
mkIf
|
||||||
|
mkOption
|
||||||
|
types
|
||||||
|
;
|
||||||
|
|
||||||
|
cfg = config.services.blahd;
|
||||||
|
|
||||||
|
toml = pkgs.formats.toml { };
|
||||||
|
mkConfigFile =
|
||||||
|
name: config:
|
||||||
|
(toml.generate name config).overrideAttrs (old: {
|
||||||
|
buildCommand =
|
||||||
|
old.buildCommand
|
||||||
|
+ ''
|
||||||
|
${lib.getBin cfg.package}/bin/blahd validate --config $out
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
|
settingsType = types.submodule {
|
||||||
|
freeformType = toml.type;
|
||||||
|
|
||||||
|
# TODO: Auto-generate these options? Now only required options are documented.
|
||||||
|
options = {
|
||||||
|
database.path = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/blahd/db.sqlite";
|
||||||
|
};
|
||||||
|
|
||||||
|
server.listen = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "localhost:8080";
|
||||||
|
};
|
||||||
|
|
||||||
|
server.base_url = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "http://localhost:8080";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.blahd = {
|
||||||
|
enable = mkEnableOption "Blah Chat Server";
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
description = mdDoc "The blahd package to use.";
|
||||||
|
type = types.package;
|
||||||
|
default = self.packages.${pkgs.system}.blahd;
|
||||||
|
defaultText = literalMD "blahd package from its flake output";
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = mkOption {
|
||||||
|
description = ''
|
||||||
|
blahd configuration.
|
||||||
|
Will be ignored if `settingsFile` is non-null.
|
||||||
|
'';
|
||||||
|
type = settingsType;
|
||||||
|
};
|
||||||
|
|
||||||
|
settingsFile = mkOption {
|
||||||
|
description = ''
|
||||||
|
blahd configuration file path.
|
||||||
|
If non-null, this will be used and `settings` will be ignored.
|
||||||
|
'';
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
defaultText = literalMD "generated from `settings`";
|
||||||
|
default = mkConfigFile "blahd.toml" cfg.settings;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.packages = [ cfg.package ];
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
|
systemd.services."blahd" = {
|
||||||
|
overrideStrategy = "asDropin";
|
||||||
|
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
restartIfChanged = false;
|
||||||
|
stopIfChanged = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.etc."blahd/blahd.toml".source = cfg.settingsFile;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue