Skip to content

Commit

Permalink
Merge staging-next into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] authored Jan 3, 2025
2 parents 75ed7e6 + d51cbef commit f51e957
Show file tree
Hide file tree
Showing 18 changed files with 325 additions and 76 deletions.
6 changes: 6 additions & 0 deletions maintainers/maintainer-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10152,6 +10152,12 @@
githubId = 45084216;
keys = [ { fingerprint = "1BF9 8D10 E0D0 0B41 5723 5836 4C13 3A84 E646 9228"; } ];
};
jaculabilis = {
name = "Tim Van Baak";
email = "[email protected]";
github = "Jaculabilis";
githubId = 10787844;
};
jaduff = {
email = "[email protected]";
github = "jaduff";
Expand Down
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2505.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@

- [Actual Budget](https://actualbudget.org/), a local-first personal finance app. Available as [services.actual](#opt-services.actual.enable).

- [immich-public-proxy](https://github.com/alangrainger/immich-public-proxy), a proxy for sharing Immich albums without exposing the Immich API. Available as [services.immich-public-proxy](#opt-services.immich-public-proxy.enable).

- [mqtt-exporter](https://github.com/kpetremann/mqtt-exporter/), a Prometheus exporter for exposing messages from MQTT. Available as [services.prometheus.exporters.mqtt](#opt-services.prometheus.exporters.mqtt.enable).

- [nvidia-gpu](https://github.com/utkuozdemir/nvidia_gpu_exporter), a Prometheus exporter that scrapes `nvidia-smi` for GPU metrics. Available as [services.prometheus.exporters.nvidia-gpu](#opt-services.prometheus.exporters.nvidia-gpu.enable).
Expand Down
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,7 @@
./services/web-apps/icingaweb2/module-monitoring.nix
./services/web-apps/ifm.nix
./services/web-apps/immich.nix
./services/web-apps/immich-public-proxy.nix
./services/web-apps/invidious.nix
./services/web-apps/invoiceplane.nix
./services/web-apps/isso.nix
Expand Down
98 changes: 98 additions & 0 deletions nixos/modules/services/web-apps/immich-public-proxy.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.immich-public-proxy;
format = pkgs.formats.json { };
inherit (lib)
types
mkIf
mkOption
mkEnableOption
;
in
{
options.services.immich-public-proxy = {
enable = mkEnableOption "Immich Public Proxy";
package = lib.mkPackageOption pkgs "immich-public-proxy" { };

immichUrl = mkOption {
type = types.str;
description = "URL of the Immich instance";
};

port = mkOption {
type = types.port;
default = 3000;
description = "The port that IPP will listen on.";
};
openFirewall = mkOption {
type = types.bool;
default = false;
description = "Whether to open the IPP port in the firewall";
};

settings = mkOption {
type = types.submodule {
freeformType = format.type;
};
default = { };
description = ''
Configuration for IPP. See <https://github.com/alangrainger/immich-public-proxy/blob/main/README.md#additional-configuration> for options and defaults.
'';
};
};

config = mkIf cfg.enable {
systemd.services.immich-public-proxy = {
description = "Immich public proxy for sharing albums publicly without exposing your Immich instance";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment = {
IMMICH_URL = cfg.immichUrl;
IPP_PORT = builtins.toString cfg.port;
IPP_CONFIG = "${format.generate "config.json" cfg.settings}";
};
serviceConfig = {
ExecStart = lib.getExe cfg.package;
SyslogIdentifier = "ipp";
User = "ipp";
Group = "ipp";
DynamicUser = true;
Type = "simple";
Restart = "on-failure";
RestartSec = 3;

# Hardening
CapabilityBoundingSet = "";
NoNewPrivileges = true;
PrivateUsers = true;
PrivateTmp = true;
PrivateDevices = true;
PrivateMounts = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
};
};

networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];

meta.maintainers = with lib.maintainers; [ jaculabilis ];
};
}
1 change: 1 addition & 0 deletions nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ in {
ifm = handleTest ./ifm.nix {};
iftop = handleTest ./iftop.nix {};
immich = handleTest ./web-apps/immich.nix {};
immich-public-proxy = handleTest ./web-apps/immich-public-proxy.nix {};
incron = handleTest ./incron.nix {};
incus = pkgs.recurseIntoAttrs (handleTest ./incus { lts = false; inherit system pkgs; });
incus-lts = pkgs.recurseIntoAttrs (handleTest ./incus { inherit system pkgs; });
Expand Down
105 changes: 105 additions & 0 deletions nixos/tests/web-apps/immich-public-proxy.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import ../make-test-python.nix (
{ pkgs, lib, ... }:
{
name = "immich-public-proxy";

nodes.machine =
{ pkgs, ... }@args:
{
environment.systemPackages = [
pkgs.imagemagick
pkgs.immich-cli
];
services.immich = {
enable = true;
port = 2283;
# disable a lot of features that aren't needed for this test
machine-learning.enable = false;
settings = {
backup.database.enabled = false;
machineLearning.enabled = false;
map.enabled = false;
reverseGeocoding.enabled = false;
metadata.faces.import = false;
newVersionCheck.enabled = false;
notifications.smtp.enabled = false;
};
};
services.immich-public-proxy = {
enable = true;
immichUrl = "http://localhost:2283";
port = 8002;
settings.ipp.responseHeaders."X-NixOS" = "Rules";
};
};

testScript = ''
import json
machine.wait_for_unit("immich-server.service")
machine.wait_for_unit("immich-public-proxy.service")
machine.wait_for_open_port(2283)
machine.wait_for_open_port(8002)
# The proxy should be up
machine.succeed("curl -sf http://localhost:8002")
# Verify the static assets are served
machine.succeed("curl -sf http://localhost:8002/robots.txt")
machine.succeed("curl -sf http://localhost:8002/share/static/style.css")
# Check that the response header in the settings is sent
res = machine.succeed("""
curl -sD - http://localhost:8002 -o /dev/null
""")
assert "x-nixos: rules" in res.lower(), res
# Log in to Immich and create an access key
machine.succeed("""
curl -sf --json '{ "email": "[email protected]", "name": "Admin", "password": "admin" }' http://localhost:2283/api/auth/admin-sign-up
""")
res = machine.succeed("""
curl -sf --json '{ "email": "[email protected]", "password": "admin" }' http://localhost:2283/api/auth/login
""")
token = json.loads(res)['accessToken']
res = machine.succeed("""
curl -sf -H 'Cookie: immich_access_token=%s' --json '{ "name": "API Key", "permissions": ["all"] }' http://localhost:2283/api/api-keys
""" % token)
key = json.loads(res)['secret']
machine.succeed(f"immich login http://localhost:2283/api {key}")
res = machine.succeed("immich server-info")
print(res)
# Upload some blank images to a new album
# If there's only one image, the proxy serves the image directly
machine.succeed("magick -size 800x600 canvas:white /tmp/white.png")
machine.succeed("immich upload -A '✨ Reproducible Moments ✨' /tmp/white.png")
machine.succeed("magick -size 800x600 canvas:black /tmp/black.png")
machine.succeed("immich upload -A '✨ Reproducible Moments ✨' /tmp/black.png")
res = machine.succeed("immich server-info")
print(res)
# Get the new album id
res = machine.succeed("""
curl -sf -H 'Cookie: immich_access_token=%s' http://localhost:2283/api/albums
""" % token)
album_id = json.loads(res)[0]['id']
# Create a shared link
res = machine.succeed("""
curl -sf -H 'Cookie: immich_access_token=%s' --json '{ "albumId": "%s", "type": "ALBUM" }' http://localhost:2283/api/shared-links
""" % (token, album_id))
share_key = json.loads(res)['key']
# Access the share
machine.succeed("""
curl -sf http://localhost:2283/share/%s
""" % share_key)
# Access the share through the proxy
machine.succeed("""
curl -sf http://localhost:8002/share/%s
""" % share_key)
'';
}
)
3 changes: 2 additions & 1 deletion pkgs/by-name/el/element-web/package.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
lib,
stdenv,
jq,
element-web-unwrapped,
Expand All @@ -22,7 +23,7 @@ else
mkdir -p $out
ln -s ${element-web-unwrapped}/* $out
rm $out/config.json
jq -s '.[0] * $conf' "${element-web-unwrapped}/config.json" --argjson "conf" '${builtins.toJSON conf}' > "$out/config.json"
jq -s '.[0] * $conf' "${element-web-unwrapped}/config.json" --argjson "conf" ${lib.escapeShellArg (builtins.toJSON conf)} > "$out/config.json"
runHook postInstall
'';
Expand Down
75 changes: 39 additions & 36 deletions pkgs/by-name/fa/factorio/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -40,46 +40,46 @@ let

mods = args.mods or [ ];

helpMsg = ''
===FETCH FAILED===
Please ensure you have set the username and token with config.nix, or
/etc/nix/nixpkgs-config.nix if on NixOS.
Your token can be seen at https://factorio.com/profile (after logging in). It is
not as sensitive as your password, but should still be safeguarded. There is a
link on that page to revoke/invalidate the token, if you believe it has been
leaked or wish to take precautions.
Example:
{
packageOverrides = pkgs: {
factorio = pkgs.factorio.override {
username = "FactorioPlayer1654";
token = "d5ad5a8971267c895c0da598688761";
helpMsg =
{ dlName, storeName }:
''
===FETCH FAILED===
Please ensure you have set the username and token with config.nix, or
/etc/nix/nixpkgs-config.nix if on NixOS.
Your token can be seen at https://factorio.com/profile (after logging in).
Beware this will add the credentials to the Nix store, which is
world-readable on the local machine. It is not as sensitive as your
password, but should still be safeguarded. There is a link on that page to
revoke/invalidate the token, if you believe it has been leaked or wish to
take precautions.
Example:
{
packageOverrides = pkgs: {
factorio = pkgs.factorio.override {
username = "FactorioPlayer1654";
token = "d5ad5a8971267c895c0da598688761";
};
};
};
}
}
Alternatively, instead of providing the username+token, you may manually
download the release through https://factorio.com/download , then add it to
the store using e.g.:
Alternatively, instead of providing the username+token, you may manually
download the release through https://factorio.com/download , then add it to
the store using e.g.:
releaseType=alpha
version=0.17.74
nix-prefetch-url file://\''$HOME/Downloads/factorio_\''${releaseType}_x64_\''${version}.tar.xz --name factorio_\''${releaseType}_x64-\''${version}.tar.xz
nix-prefetch-url file://\''$HOME/Downloads/${dlName} --name ${storeName}
Note the ultimate "_" is replaced with "-" in the --name arg!
If you go this route you might want to tell Nix to explicitly hold on to the
source tarball. Otherwise it could get GC'd from the Nix store and you'd
have to redownload it next time the package wants to rebuild to use a newer
dependency. E.g. if you're using NixOS:
If you go this route you might want to tell Nix to explicitly hold on to the
source tarball. Otherwise it could get GC'd from the Nix store and you'd
have to redownload it next time the package wants to rebuild to use a newer
dependency. E.g. if you're using NixOS:
system.extraDependencies = [
factorio.src
];
'';
system.extraDependencies = [
factorio.src
];
'';

desktopItem = makeDesktopItem {
name = "factorio";
Expand Down Expand Up @@ -155,7 +155,10 @@ let
'';
failureHook = ''
cat <<EOF
${helpMsg}
${helpMsg {
dlName = if candidateHashFilenames != [ ] then builtins.head candidateHashFilenames else name;
storeName = name;
}}
EOF
'';
})
Expand Down
File renamed without changes.
Loading

0 comments on commit f51e957

Please sign in to comment.