nixpkgs/nixos/modules/services/misc/memos.nix
Samuel Dionne-Riel 43eca5c08d maintainer-list: Fix M0ustach3 maintainer entry
Two different PRs, two different issues.

The first PR, chronologically-merged-in, #426687 introduced a new
module, and while reviewers “reviewed” the `meta.maintainers` entry,
they did not notice the maintainer was not in the maintainers list file.

 - https://github.com/NixOS/nixpkgs/pull/426687#discussion_r2311053832

Then, in #437310, merged a few days later, another new module was added
with M0ustach3 as a maintainer. At the very least, an attempt was made
in de66c73a19 to add the maintainer to the
list, but an unfortunate typo (or two?) in the maintainers list entry
means the two intended usage of the new entry still don't work.

The issue here is not from the contributors. The reviewers and
committers could have done better, but it's not even truly their fault.
The issue is the meta information in NixOS modules was never checked. In
any way AFAICT. Otherwise this would have been caught immediately, and
not four months later.

Anyway, the intent clearly is that the entry should matche the GitHub
username.
2026-01-26 20:05:33 -05:00

199 lines
5.4 KiB
Nix

{
config,
options,
pkgs,
lib,
...
}:
let
cfg = config.services.memos;
opt = options.services.memos;
envFileFormat = pkgs.formats.keyValue { };
in
{
options.services.memos = {
enable = lib.mkEnableOption "Memos note-taking";
package = lib.mkPackageOption pkgs "Memos" {
default = "memos";
};
openFirewall = lib.mkEnableOption "opening the ports in the firewall";
user = lib.mkOption {
type = lib.types.str;
description = ''
The user to run Memos as.
::: {.note}
If changing the default value, **you** are responsible of creating the corresponding user with [{option}`users.users`](#opt-users.users).
:::
'';
default = "memos";
};
group = lib.mkOption {
type = lib.types.str;
description = ''
The group to run Memos as.
::: {.note}
If changing the default value, **you** are responsible of creating the corresponding group with [{option}`users.groups`](#opt-users.groups).
:::
'';
default = "memos";
};
dataDir = lib.mkOption {
default = "/var/lib/memos/";
type = lib.types.path;
description = ''
Specifies the directory where Memos will store its data.
::: {.note}
It will be automatically created with the permissions of [{option}`services.memos.user`](#opt-services.memos.user) and [{option}`services.memos.group`](#opt-services.memos.group).
:::
'';
};
settings = lib.mkOption {
type = envFileFormat.type;
description = ''
The environment variables to configure Memos.
::: {.note}
At time of writing, there is no clear documentation about possible values.
It's possible to convert CLI flags into these variables.
Example : CLI flag "--unix-sock" converts to {env}`MEMOS_UNIX_SOCK`.
:::
'';
default = {
MEMOS_MODE = "prod";
MEMOS_ADDR = "127.0.0.1";
MEMOS_PORT = "5230";
MEMOS_DATA = cfg.dataDir;
MEMOS_DRIVER = "sqlite";
MEMOS_INSTANCE_URL = "http://localhost:5230";
};
defaultText = lib.literalExpression ''
{
MEMOS_MODE = "prod";
MEMOS_ADDR = "127.0.0.1";
MEMOS_PORT = "5230";
MEMOS_DATA = config.${opt.dataDir};
MEMOS_DRIVER = "sqlite";
MEMOS_INSTANCE_URL = "http://localhost:5230";
}
'';
};
environmentFile = lib.mkOption {
type = lib.types.path;
description = ''
The environment file to use when starting Memos.
::: {.note}
By default, generated from [](opt-${opt.settings}).
:::
'';
example = "/var/lib/memos/memos.env";
default = envFileFormat.generate "memos.env" cfg.settings;
defaultText = lib.literalMD ''
generated from {option}`${opt.settings}`
'';
};
};
config = lib.mkIf cfg.enable {
users.users = lib.mkIf (cfg.user == "memos") {
${cfg.user} = {
description = lib.mkDefault "Memos service user";
isSystemUser = true;
group = cfg.group;
};
};
users.groups = lib.mkIf (cfg.group == "memos") {
${cfg.group} = { };
};
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [
cfg.port
];
systemd.tmpfiles.settings."10-memos" = {
"${cfg.dataDir}" = {
d = {
mode = "0750";
user = cfg.user;
group = cfg.group;
};
};
};
systemd.services.memos = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
wants = [ "network.target" ];
description = "Memos, a privacy-first, lightweight note-taking solution";
serviceConfig = {
User = cfg.user;
Group = cfg.group;
Type = "simple";
RestartSec = 60;
LimitNOFILE = 65536;
NoNewPrivileges = true;
LockPersonality = true;
RemoveIPC = true;
ReadWritePaths = [
cfg.dataDir
];
ProtectSystem = "strict";
PrivateUsers = true;
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectHostname = true;
ProtectClock = true;
UMask = "0077";
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectControlGroups = true;
ProtectProc = "invisible";
SystemCallFilter = [
" " # This is needed to clear the SystemCallFilter existing definitions
"~@reboot"
"~@swap"
"~@obsolete"
"~@mount"
"~@module"
"~@debug"
"~@cpu-emulation"
"~@clock"
"~@raw-io"
"~@privileged"
"~@resources"
];
CapabilityBoundingSet = [
" " # Reset all capabilities to an empty set
];
RestrictAddressFamilies = [
" " # This is needed to clear the RestrictAddressFamilies existing definitions
"none" # Remove all addresses families
"AF_UNIX"
"AF_INET"
"AF_INET6"
];
DevicePolicy = "closed";
ProtectKernelLogs = true;
SystemCallArchitectures = "native";
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
EnvironmentFile = cfg.environmentFile;
ExecStart = lib.getExe cfg.package;
};
};
};
meta.maintainers = [ lib.maintainers.M0ustach3 ];
}