From 6228cfd535eb77849fa238686f433e93059d2e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zoran=20Peri=C4=8Di=C4=87?= Date: Wed, 12 Aug 2026 10:09:38 +0200 Subject: [PATCH] Initial package for pnpr 0.1.0-alpha.5 Native binary taken from the @pnpm/pnpr.linux-{x64,arm64} npm platform packages; systemd service with dynamic sysusers pnpr user. Storage in /var/lib/pnpr, disposable proxy cache split into /var/cache/pnpr via --cache. Default config proxies registry.npmjs.org; listen address and extra flags via /etc/pnpr/pnpr.env. --- .gitignore | 3 ++ pnpr.env | 13 ++++++ pnpr.service | 39 ++++++++++++++++++ pnpr.spec | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++ pnpr.sysusers | 1 + pnpr.yaml | 54 +++++++++++++++++++++++++ 6 files changed, 217 insertions(+) create mode 100644 .gitignore create mode 100644 pnpr.env create mode 100644 pnpr.service create mode 100644 pnpr.spec create mode 100644 pnpr.sysusers create mode 100644 pnpr.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee4e323 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Downloaded upstream binary tarballs (npm platform packages) +pnpr.linux-x64-*.tgz +pnpr.linux-arm64-*.tgz diff --git a/pnpr.env b/pnpr.env new file mode 100644 index 0000000..e547739 --- /dev/null +++ b/pnpr.env @@ -0,0 +1,13 @@ +# Environment for pnpr.service. Edit and restart: +# systemctl restart pnpr.service + +# Listen address. Loopback-only by default. To serve CI runner +# containers, bind a reachable address (e.g. 0.0.0.0:7677 or the podman +# bridge gateway) — see the addressing note in /etc/pnpr/pnpr.yaml. +PNPR_LISTEN=127.0.0.1:7677 + +# Extra pnpr flags (see pnpr --help). When PNPR_LISTEN is not loopback, +# set --public-url to the URL clients use, or dist.tarball URLs in +# served packuments are rewritten against the raw listen address: +# PNPR_OPTS=--public-url http://host.containers.internal:7677 +PNPR_OPTS= diff --git a/pnpr.service b/pnpr.service new file mode 100644 index 0000000..b257373 --- /dev/null +++ b/pnpr.service @@ -0,0 +1,39 @@ +[Unit] +Description=pnpr - pnpm-compatible npm registry server +Documentation=https://pnpm.io/pnpr +After=network-online.target +Wants=network-online.target +ConditionPathExists=/etc/pnpr/pnpr.yaml + +[Service] +Type=simple +User=pnpr +Group=pnpr + +# Hosted/published packages (config storage:) persist in /var/lib/pnpr; +# the disposable mirror of upstream registries goes to /var/cache/pnpr +# (--cache) and can be wiped at any time. +StateDirectory=pnpr +StateDirectoryMode=0750 +CacheDirectory=pnpr +CacheDirectoryMode=0750 + +EnvironmentFile=/etc/pnpr/pnpr.env +ExecStart=/usr/bin/pnpr -c /etc/pnpr/pnpr.yaml --cache /var/cache/pnpr --listen ${PNPR_LISTEN} $PNPR_OPTS + +Restart=on-failure +RestartSec=5s + +# Hardening +NoNewPrivileges=yes +ProtectSystem=strict +ProtectHome=yes +PrivateTmp=yes +PrivateDevices=yes +ProtectKernelTunables=yes +ProtectKernelModules=yes +ProtectControlGroups=yes +RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 + +[Install] +WantedBy=multi-user.target diff --git a/pnpr.spec b/pnpr.spec new file mode 100644 index 0000000..6f3759a --- /dev/null +++ b/pnpr.spec @@ -0,0 +1,107 @@ +# Upstream publishes prebuilt Rust binaries as npm platform packages +# (@pnpm/pnpr.linux-x64 / .linux-arm64); the tarball contains the stripped +# ELF binary, package.json and LICENSE. npm versions use a hyphenated +# pre-release (0.1.0-alpha.5) which maps to a tilde in the RPM version. +%global upstream_version 0.1.0-alpha.5 + +# Prebuilt stripped binary — nothing to extract debuginfo from. +%global debug_package %{nil} + +Name: pnpr +Version: 0.1.0~alpha.5 +Release: 1%{?dist} +Summary: pnpm-compatible npm registry server and caching proxy +# Docs (https://pnpm.io/pnpr) state PolyForm Shield 1.0.0 (source-available, +# self-hosting explicitly permitted); the binary tarballs ship pnpm's MIT text. +License: PolyForm-Shield-1.0.0 +Group: System Environment/Daemons +URL: https://pnpm.io/pnpr + +Source0: https://registry.npmjs.org/@pnpm/pnpr.linux-x64/-/pnpr.linux-x64-%{upstream_version}.tgz +Source1: https://registry.npmjs.org/@pnpm/pnpr.linux-arm64/-/pnpr.linux-arm64-%{upstream_version}.tgz +Source10: pnpr.service +Source11: pnpr.yaml +Source12: pnpr.env +Source13: pnpr.sysusers + +BuildRequires: systemd-rpm-macros +%{?systemd_requires} + +ExclusiveArch: x86_64 aarch64 + +%description +pnpr is a pnpm-compatible npm registry server written in Rust. It speaks +the npm registry protocol, so pnpm, npm and yarn can all use it as a +caching proxy for registry.npmjs.org, a private hosted registry, a +credential gateway, or an install accelerator (server-side dependency +resolution). + +This package runs pnpr as a systemd service under a dedicated user. +Published/hosted packages live in /var/lib/pnpr; the disposable proxy +cache lives in /var/cache/pnpr. Listens on 127.0.0.1:7677 by default — +see /etc/pnpr/pnpr.env to expose it to CI runners. + +%prep +%setup -q -c -T +%ifarch x86_64 +tar -xzf %{SOURCE0} +%endif +%ifarch aarch64 +tar -xzf %{SOURCE1} +%endif + +%install +%{__rm} -rf %{buildroot} + +install -D -m 755 package/pnpr %{buildroot}%{_bindir}/pnpr + +install -p -D -m 644 %{SOURCE10} %{buildroot}%{_unitdir}/pnpr.service +install -p -D -m 644 %{SOURCE13} %{buildroot}%{_sysusersdir}/pnpr.conf + +install -d -m 750 %{buildroot}%{_sysconfdir}/pnpr +install -m 640 %{SOURCE11} %{buildroot}%{_sysconfdir}/pnpr/pnpr.yaml +install -m 640 %{SOURCE12} %{buildroot}%{_sysconfdir}/pnpr/pnpr.env + +# storage (hosted/published packages) and disposable proxy cache +install -d -m 750 %{buildroot}%{_sharedstatedir}/pnpr +install -d -m 750 %{buildroot}%{_localstatedir}/cache/pnpr + +%pre +%sysusers_create_package pnpr %{SOURCE13} + +%post +%systemd_post pnpr.service + +%preun +%systemd_preun pnpr.service + +%postun +%systemd_postun_with_restart pnpr.service + +%clean +%{__rm} -rf %{buildroot} + +%files +%defattr(-,root,root,-) +%license package/LICENSE + +%{_bindir}/pnpr +%{_unitdir}/pnpr.service +%{_sysusersdir}/pnpr.conf + +%dir %attr(0750,root,pnpr) %{_sysconfdir}/pnpr +%config(noreplace) %attr(0640,root,pnpr) %{_sysconfdir}/pnpr/pnpr.yaml +%config(noreplace) %attr(0640,root,pnpr) %{_sysconfdir}/pnpr/pnpr.env + +%dir %attr(0750,pnpr,pnpr) %{_sharedstatedir}/pnpr +%dir %attr(0750,pnpr,pnpr) %{_localstatedir}/cache/pnpr + +%changelog +* Tue Aug 11 2026 Zoran Pericic - 0.1.0~alpha.5-1 +- Initial package for pnpr 0.1.0-alpha.5 (experimental upstream) +- Prebuilt binaries taken from the @pnpm/pnpr.linux-{x64,arm64} npm + platform packages +- systemd service with dynamic sysusers pnpr user; storage in + /var/lib/pnpr, proxy cache separated into /var/cache/pnpr via --cache +- Default config proxies registry.npmjs.org; listen address and extra + flags configurable via /etc/pnpr/pnpr.env diff --git a/pnpr.sysusers b/pnpr.sysusers new file mode 100644 index 0000000..a155b62 --- /dev/null +++ b/pnpr.sysusers @@ -0,0 +1 @@ +u pnpr - "pnpr npm registry server" /var/lib/pnpr /sbin/nologin diff --git a/pnpr.yaml b/pnpr.yaml new file mode 100644 index 0000000..3c0f9ce --- /dev/null +++ b/pnpr.yaml @@ -0,0 +1,54 @@ +# pnpr configuration — https://pnpm.io/pnpr +# +# pnpr is EXPERIMENTAL upstream; config keys may change between releases. +# The listen address and extra CLI flags are set in /etc/pnpr/pnpr.env, +# the proxy-cache path (/var/cache/pnpr) on the ExecStart line — this +# file defines storage, registries and (optionally) auth. +# +# Point clients at it, e.g. in a project's .npmrc: +# registry=http://127.0.0.1:7677/ +# A single registry can also be addressed directly: +# registry=http://127.0.0.1:7677/~npmjs/ +# +# Same-host rootless Podman runners (gitea-runner jobs): loopback is the +# container's own, and under pasta the host's LAN IP is carried by the +# container too — see the addressing note in +# /etc/gitea-runner/cache-server.yaml. Use a host /etc/hosts entry such as +# 10.88.0.1 host.containers.internal +# then set PNPR_LISTEN=0.0.0.0:7677 (or the bridge address) plus +# PNPR_OPTS=--public-url http://host.containers.internal:7677 in +# /etc/pnpr/pnpr.env, and use that URL in the runners' .npmrc. + +# Where hosted (published) packages live. Persistent; the disposable +# upstream mirror is kept separately under /var/cache/pnpr. +storage: /var/lib/pnpr + +registries: + # Caching proxy of the public npm registry. + npmjs: + type: upstream + url: https://registry.npmjs.org/ + public: true + + # Private hosted registry for own packages — uncomment to enable + # publishing (requires auth, see below). + #local: + # type: hosted + # packages: + # '@infomaos/*': + # publish: $authenticated + + # What clients see: first match wins across sources. + main: + type: router + sources: [npmjs] + #sources: [local, npmjs] + +defaultRegistry: main + +# htpasswd-backed authentication (needed for publishing to a hosted +# registry, or to require login for reads on non-public registries). +#auth: +# htpasswd: +# file: /var/lib/pnpr/htpasswd +# max_users: 1