Merge pull request #215222 from dotlambda/nixos-imaginary-init

nixos/imaginary: init

Changed files
+131 -2
nixos
doc
manual
release-notes
modules
services
networking
pkgs
servers
imaginary
+2
nixos/doc/manual/release-notes/rl-2305.section.md
···
- [stevenblack-blocklist](https://github.com/StevenBlack/hosts), A unified hosts file with base extensions for blocking unwanted websites. Available as [networking.stevenblack](options.html#opt-networking.stevenblack.enable).
+
- [imaginary](https://github.com/h2non/imaginary), a microservice for high-level image processing that Nextcloud can use to generate previews. Available as [services.imaginary](#opt-services.imaginary.enable).
+
- [goeland](https://github.com/slurdge/goeland), an alternative to rss2email written in golang with many filters. Available as [services.goeland](#opt-services.goeland.enable).
- [atuin](https://github.com/ellie/atuin), a sync server for shell history. Available as [services.atuin](#opt-services.atuin.enable).
+1
nixos/modules/module-list.nix
···
./services/networking/i2pd.nix
./services/networking/icecream/daemon.nix
./services/networking/icecream/scheduler.nix
+
./services/networking/imaginary.nix
./services/networking/inspircd.nix
./services/networking/iodine.nix
./services/networking/iperf3.nix
+110
nixos/modules/services/networking/imaginary.nix
···
+
{ lib, config, pkgs, utils, ... }:
+
+
let
+
inherit (lib) mdDoc mkEnableOption mkIf mkOption types;
+
+
cfg = config.services.imaginary;
+
in {
+
options.services.imaginary = {
+
enable = mkEnableOption (mdDoc "imaginary image processing microservice");
+
+
address = mkOption {
+
type = types.str;
+
default = "";
+
description = mdDoc "Bind address. Corresponds to the `-a` flag.";
+
example = "localhost";
+
};
+
+
port = mkOption {
+
type = types.port;
+
default = 8088;
+
description = mdDoc "Bind port. Corresponds to the `-p` flag.";
+
};
+
+
settings = mkOption {
+
description = mdDoc ''
+
Command line arguments passed to the imaginary executable, stripped of
+
the prefix `-`. See upstream's
+
[README](https://github.com/h2non/imaginary#command-line-usage) for all
+
options.
+
'';
+
type = types.submodule {
+
freeformType = with types; attrsOf (oneOf [
+
bool
+
int
+
(nonEmptyListOf str)
+
str
+
]);
+
+
options = {
+
return-size = mkOption {
+
type = types.bool;
+
default = false;
+
description = mdDoc "Return the image size in the HTTP headers.";
+
};
+
};
+
};
+
};
+
};
+
+
config = mkIf cfg.enable {
+
assertions = [ {
+
assertion = ! lib.hasAttr "a" cfg.settings;
+
message = "Use services.imaginary.address to specify the -a flag.";
+
} {
+
assertion = ! lib.hasAttr "p" cfg.settings;
+
message = "Use services.imaginary.port to specify the -p flag.";
+
} ];
+
+
systemd.services.imaginary = {
+
after = [ "network.target" ];
+
wantedBy = [ "multi-user.target" ];
+
serviceConfig = rec {
+
ExecStart = let
+
args = lib.mapAttrsToList (key: val:
+
"-" + key + "=" + lib.concatStringsSep "," (map toString (lib.toList val))
+
) (cfg.settings // { a = cfg.address; p = cfg.port; });
+
in "${pkgs.imaginary}/bin/imaginary ${utils.escapeSystemdExecArgs args}";
+
ProtectProc = "invisible";
+
BindReadOnlyPaths = lib.optional (cfg.settings ? mount) cfg.settings.mount;
+
CapabilityBoundingSet = if cfg.port < 1024 then
+
[ "CAP_NET_BIND_SERVICE" ]
+
else
+
[ "" ];
+
AmbientCapabilities = CapabilityBoundingSet;
+
NoNewPrivileges = true;
+
DynamicUser = true;
+
ProtectSystem = "strict";
+
ProtectHome = true;
+
TemporaryFileSystem = [ "/:ro" ];
+
PrivateTmp = true;
+
PrivateDevices = true;
+
PrivateUsers = cfg.port >= 1024;
+
ProtectHostname = true;
+
ProtectClock = true;
+
ProtectKernelTunables = true;
+
ProtectKernelModules = true;
+
ProtectKernelLogs = true;
+
ProtectControlGroups = true;
+
RestrictAddressFamilies = [
+
"AF_INET"
+
"AF_INET6"
+
];
+
RestrictNamespaces = true;
+
LockPersonality = true;
+
MemoryDenyWriteExecute = true;
+
RestrictRealtime = true;
+
PrivateMounts = true;
+
SystemCallFilter = [
+
"@system-service"
+
"~@privileged"
+
];
+
DevicePolicy = "closed";
+
};
+
};
+
};
+
+
meta = {
+
maintainers = with lib.maintainers; [ dotlambda ];
+
};
+
}
+18 -2
pkgs/servers/imaginary/default.nix
···
-
{ lib, buildGoModule, fetchFromGitHub, pkg-config, vips }:
+
{ lib
+
, buildGoModule
+
, fetchFromGitHub
+
, fetchpatch
+
, pkg-config
+
, vips
+
}:
buildGoModule rec {
pname = "imaginary";
···
hash = "sha256-oEkFoZMaNNJPMisqpIneeLK/sA23gaTWJ4nqtDHkrwA=";
};
+
patches = [
+
# add -return-size flag recommend by Nextcloud
+
# https://github.com/h2non/imaginary/pull/382
+
(fetchpatch {
+
name = "return-width-and-height-of-generated-images.patch";
+
url = "https://github.com/h2non/imaginary/commit/cfbf8d724cd326e835dfcb01e7224397c46037d3.patch";
+
hash = "sha256-TwZ5WU5g9LXrenpfY52jYsc6KsEt2fjDq7cPz6ILlhA=";
+
})
+
];
+
vendorHash = "sha256-BluY6Fz4yAKJ/A9aFuPPsgQN9N/5yd8g8rDfIZeYz5U=";
buildInputs = [ vips ];
···
changelog = "https://github.com/h2non/${pname}/releases/tag/v${version}";
description = "Fast, simple, scalable, Docker-ready HTTP microservice for high-level image processing";
license = licenses.mit;
-
maintainers = with maintainers; [ urandom ];
+
maintainers = with maintainers; [ dotlambda urandom ];
};
}