mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-05 21:03:40 +00:00
nixos/vinyl-cache: init module
This module is essentialy the same as services.varnish, but adapts to the changed project name. For the lifetime of NixOS 26.05, we still support Varnish to simplify the migration.
This commit is contained in:
@@ -1834,6 +1834,7 @@
|
||||
./services/web-servers/unit/default.nix
|
||||
./services/web-servers/uwsgi.nix
|
||||
./services/web-servers/varnish/default.nix
|
||||
./services/web-servers/vinyl-cache/default.nix
|
||||
./services/x11/clight.nix
|
||||
./services/x11/colord.nix
|
||||
./services/x11/desktop-managers/default.nix
|
||||
|
||||
240
nixos/modules/services/web-servers/vinyl-cache/default.nix
Normal file
240
nixos/modules/services/web-servers/vinyl-cache/default.nix
Normal file
@@ -0,0 +1,240 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
types
|
||||
mkOption
|
||||
hasPrefix
|
||||
concatMapStringsSep
|
||||
optionalString
|
||||
concatMap
|
||||
;
|
||||
|
||||
cfg = config.services.vinyl-cache;
|
||||
|
||||
# Vinyl Cache has very strong opinions and very complicated code around handling
|
||||
# the stateDir. After a lot of back and forth, we decided that we a)
|
||||
# do not want a configurable option here, as most of the handling depends
|
||||
# on the version and the compile time options. Putting everything into
|
||||
# /var/run (RAM backed) is absolutely recommended by Vinyl Cache anyways.
|
||||
# We do need to pay attention to the version-dependend variations, though!
|
||||
stateDir = "/var/run/vinyld";
|
||||
|
||||
# from --help:
|
||||
# -a [<name>=]address[:port][,proto] # HTTP listen address and port
|
||||
# [,user=<u>][,group=<g>] # Can be specified multiple times.
|
||||
# [,mode=<m>] # default: ":80,HTTP"
|
||||
# # Proto can be "PROXY" or "HTTP" (default)
|
||||
# # user, group and mode set permissions for
|
||||
# # a Unix domain socket.
|
||||
commandLineAddresses = (
|
||||
concatMapStringsSep " " (
|
||||
a:
|
||||
"-a "
|
||||
+ optionalString (!isNull a.name) "${a.name}="
|
||||
+ a.address
|
||||
+ optionalString (!isNull a.port) ":${toString a.port}"
|
||||
+ optionalString (!isNull a.proto) ",${a.proto}"
|
||||
+ optionalString (!isNull a.user) ",user=${a.user}"
|
||||
+ optionalString (!isNull a.group) ",group=${a.group}"
|
||||
+ optionalString (!isNull a.mode) ",mode=${a.mode}"
|
||||
) cfg.listen
|
||||
);
|
||||
|
||||
addressSubmodule = types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
description = "Name is referenced in logs. If name is not specified, 'a0', 'a1', etc. is used.";
|
||||
default = null;
|
||||
type = with types; nullOr str;
|
||||
};
|
||||
address = mkOption {
|
||||
description = ''
|
||||
If given an IP address, it can be a host name ("localhost"), an IPv4 dotted-quad
|
||||
("127.0.0.1") or an IPv6 address enclosed in square brackets ("[::1]").
|
||||
|
||||
(VCL4.1 and higher) If given an absolute Path ("/path/to/listen.sock") or "@"
|
||||
followed by the name of an abstract socket ("@myvinyld") accept connections
|
||||
on a Unix domain socket.
|
||||
|
||||
The user, group and mode sub-arguments may be used to specify the permissions
|
||||
of the socket file. These sub-arguments do not apply to abstract sockets.
|
||||
'';
|
||||
type = types.str;
|
||||
};
|
||||
port = mkOption {
|
||||
description = "The port to use for IP sockets. If port is not specified, port 80 (http) is used.";
|
||||
default = null;
|
||||
type = with types; nullOr port;
|
||||
};
|
||||
proto = mkOption {
|
||||
description = "PROTO can be 'HTTP' (the default) or 'PROXY'. Both version 1 and 2 of the proxy protocol can be used.";
|
||||
type = types.enum [
|
||||
"HTTP"
|
||||
"PROXY"
|
||||
];
|
||||
default = "HTTP";
|
||||
};
|
||||
user = mkOption {
|
||||
description = "User name who owns the socket file.";
|
||||
default = null;
|
||||
type = with lib.types; nullOr str;
|
||||
};
|
||||
group = mkOption {
|
||||
description = "Group name who owns the socket file.";
|
||||
default = null;
|
||||
type = with lib.types; nullOr str;
|
||||
};
|
||||
mode = mkOption {
|
||||
description = "Permission of the socket file (3-digit octal value).";
|
||||
default = null;
|
||||
type = with types; nullOr str;
|
||||
};
|
||||
};
|
||||
};
|
||||
checkedAddressModule = types.addCheck addressSubmodule (
|
||||
m:
|
||||
(
|
||||
if ((hasPrefix "@" m.address) || (hasPrefix "/" m.address)) then
|
||||
# this is a unix socket
|
||||
(m.port != null)
|
||||
else
|
||||
# this is not a path-based unix socket
|
||||
if !(hasPrefix "/" m.address) && (m.group != null) || (m.user != null) || (m.mode != null) then
|
||||
false
|
||||
else
|
||||
true
|
||||
)
|
||||
);
|
||||
commandLine =
|
||||
"-f ${pkgs.writeText "default.vcl" cfg.config}"
|
||||
+
|
||||
lib.optionalString (cfg.extraModules != [ ])
|
||||
" -p vmod_path='${
|
||||
lib.makeSearchPathOutput "lib" "lib/vinyl/vmods" ([ cfg.package ] ++ cfg.extraModules)
|
||||
}' -r vmod_path";
|
||||
in
|
||||
{
|
||||
meta.maintainers = [
|
||||
lib.maintainers.leona
|
||||
lib.maintainers.osnyx
|
||||
];
|
||||
options = {
|
||||
services.vinyl-cache = {
|
||||
enable = lib.mkEnableOption "Vinyl Cache";
|
||||
|
||||
enableConfigCheck = lib.mkEnableOption "checking the config during build time" // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
package = lib.mkPackageOption pkgs "vinyl-cache" { };
|
||||
|
||||
listen = lib.mkOption {
|
||||
description = "Accept for client requests on the specified listen addresses.";
|
||||
type = lib.types.listOf checkedAddressModule;
|
||||
defaultText = lib.literalExpression ''[ { address="*"; port=6081; } ]'';
|
||||
default = [
|
||||
{
|
||||
address = "*";
|
||||
port = 6081;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
config = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
description = ''
|
||||
Verbatim default.vcl configuration.
|
||||
'';
|
||||
};
|
||||
|
||||
extraModules = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.package;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Vinyl Cache modules (except 'std').
|
||||
'';
|
||||
};
|
||||
|
||||
extraCommandLine = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
example = "-s malloc,256M";
|
||||
description = ''
|
||||
Command line switches for vinyld (run 'vinyld -?' to get list of options)
|
||||
'';
|
||||
};
|
||||
|
||||
enableFileLogging = lib.mkEnableOption "file based logging";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf cfg.enable {
|
||||
systemd.services.vinyl-cache = {
|
||||
description = "Vinyl Cache";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${cfg.package}/bin/vinyld ${commandLineAddresses} -n ${stateDir} -F ${cfg.extraCommandLine} ${commandLine}";
|
||||
Restart = "always";
|
||||
RestartSec = "5s";
|
||||
User = "vinyl-cache";
|
||||
Group = "vinyl-cache";
|
||||
DynamicUser = true;
|
||||
RuntimeDirectory = lib.removePrefix "/var/run/" stateDir;
|
||||
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
||||
NoNewPrivileges = true;
|
||||
LimitNOFILE = 131072;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
# check .vcl syntax at compile time (e.g. before nixops deployment)
|
||||
system.checks = lib.mkIf cfg.enableConfigCheck [
|
||||
(pkgs.runCommand "check-vinyl-cache-syntax" { } ''
|
||||
${cfg.package}/bin/vinyld -C ${commandLine} 2> $out || (cat $out; exit 1)
|
||||
'')
|
||||
];
|
||||
|
||||
(lib.mkIf (cfg.enable && cfg.enableFileLogging) {
|
||||
systemd.services = {
|
||||
vinylncsa = {
|
||||
after = [ "vinyl-cache.service" ];
|
||||
requires = [ "vinyl-cache.service" ];
|
||||
description = "Vinyl Cache logging daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
# We want to reopen logs with HUP. vinylncsa must run in daemon mode for that.
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
Restart = "always";
|
||||
RuntimeDirectory = "vinylncsa";
|
||||
LogsDirectory = "vinyl-cache";
|
||||
PIDFile = "/run/vinylncsa/vinylncsa.pid";
|
||||
User = "vinyl-cache";
|
||||
Group = "vinyl-cache";
|
||||
ExecStart = "${cfg.package}/bin/vinylncsa -D -a -w /var/log/vinyl-cache/vinyl-cache.log -P /run/vinylncsa/vinylncsa.pid";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.logrotate.settings.vinyl-cache = lib.mapAttrs (_: lib.mkDefault) {
|
||||
files = [ "/var/log/vinyl-cache/*.log" ];
|
||||
frequency = "daily";
|
||||
rotate = 14;
|
||||
compress = true;
|
||||
delaycompress = true;
|
||||
postrotate = "systemctl reload vinylncsa";
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
||||
@@ -1743,6 +1743,10 @@ in
|
||||
victoriametrics = import ./victoriametrics { inherit runTest; };
|
||||
victoriatraces = import ./victoriatraces { inherit runTest; };
|
||||
vikunja = runTest ./vikunja.nix;
|
||||
vinyl-cache_9 = runTest {
|
||||
imports = [ ./vinyl-cache.nix ];
|
||||
_module.args.package = pkgs.vinyl-cache_9;
|
||||
};
|
||||
virtualbox = handleTestOn [ "x86_64-linux" ] ./virtualbox.nix { };
|
||||
vm-variant = handleTest ./vm-variant.nix { };
|
||||
vscode-remote-ssh = handleTestOn [ "x86_64-linux" ] ./vscode-remote-ssh.nix { };
|
||||
|
||||
126
nixos/tests/vinyl-cache.nix
Normal file
126
nixos/tests/vinyl-cache.nix
Normal file
@@ -0,0 +1,126 @@
|
||||
{
|
||||
pkgs,
|
||||
package,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
testPath = pkgs.hello;
|
||||
in
|
||||
{
|
||||
name = "vinyl";
|
||||
meta = {
|
||||
maintainers = [
|
||||
lib.maintainers.leona
|
||||
lib.maintainers.osnyx
|
||||
];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
vinyl =
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
services.nix-serve = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
services.vinyl-cache = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
enableFileLogging = true;
|
||||
listen = [
|
||||
{
|
||||
address = "0.0.0.0";
|
||||
port = 80;
|
||||
proto = "HTTP";
|
||||
}
|
||||
{
|
||||
name = "proxyport";
|
||||
address = "0.0.0.0";
|
||||
port = 8080;
|
||||
proto = "PROXY";
|
||||
}
|
||||
{
|
||||
address = "/var/run/vinyld/client.http.sock";
|
||||
user = "vinyl-cache";
|
||||
group = "vinyl-cache";
|
||||
mode = "660";
|
||||
}
|
||||
]
|
||||
++ lib.optionals (lib.versionAtLeast package.version "7.3") [
|
||||
# Support added in 7.3.0
|
||||
{ address = "@asdf"; }
|
||||
];
|
||||
config = ''
|
||||
vcl 4.1;
|
||||
|
||||
backend nix-serve {
|
||||
.host = "127.0.0.1";
|
||||
.port = "${toString config.services.nix-serve.port}";
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 ];
|
||||
system.extraDependencies = [ testPath ];
|
||||
|
||||
assertions =
|
||||
let
|
||||
cmdline = config.systemd.services.vinyl-cache.serviceConfig.ExecStart;
|
||||
in
|
||||
map
|
||||
(pattern: {
|
||||
assertion = lib.hasInfix pattern cmdline;
|
||||
message = "Address argument `${pattern}` missing in commandline `${cmdline}`.";
|
||||
})
|
||||
(
|
||||
[
|
||||
" -a 0.0.0.0:80,HTTP "
|
||||
" -a proxyport=0.0.0.0:8080,PROXY "
|
||||
" -a /var/run/vinyld/client.http.sock,HTTP,user=vinyl-cache,group=vinyl-cache,mode=660 "
|
||||
]
|
||||
++ lib.optionals (lib.versionAtLeast package.version "7.3") [
|
||||
" -a @asdf,HTTP "
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
client =
|
||||
{ lib, ... }:
|
||||
{
|
||||
nix.settings = {
|
||||
require-sigs = false;
|
||||
substituters = lib.mkForce [ "http://vinyl" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
start_all()
|
||||
vinyl.wait_for_open_port(80)
|
||||
vinyl.wait_for_unit("vinylncsa")
|
||||
|
||||
client.wait_until_succeeds("curl -f http://vinyl/nix-cache-info");
|
||||
|
||||
client.wait_until_succeeds("nix-store -r ${testPath}")
|
||||
client.succeed("${testPath}/bin/hello")
|
||||
|
||||
output = vinyl.succeed("vinyladm status")
|
||||
print(output)
|
||||
assert "Child in state running" in output, "Unexpected vinyladm response"
|
||||
|
||||
vinyl.copy_from_machine("/var/log/vinyl-cache/vinyl-cache.log")
|
||||
|
||||
out_dir = os.environ.get("out", os.getcwd())
|
||||
vinyl_log = (Path(out_dir) / "vinyl-cache.log").read_text()
|
||||
assert "http://vinyl/nix-cache-info" in vinyl_log
|
||||
'';
|
||||
}
|
||||
@@ -108,6 +108,7 @@ let
|
||||
|
||||
passthru = {
|
||||
python = python3;
|
||||
tests = nixosTests."vinyl-cache_${lib.versions.major version}";
|
||||
};
|
||||
|
||||
meta = {
|
||||
|
||||
Reference in New Issue
Block a user