Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

urbackup-server: init at 2.5.33; nixos/urbackup: init module #374743

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -125,6 +125,8 @@

- [PowerStation](https://github.com/ShadowBlip/PowerStation/), an open source TDP control and performance daemon with DBus interface for Linux. Available as [services.powerstation](#opt-services.powerstation.enable).

- [Urbackup Server](https://www.urbackup.org/index.html), an easy to setup Open Source client/server backup system. Available as [services.urbackup](#opt-services.urbackup.enable).

- [echoip](https://github.com/mpolden/echoip), a simple service for looking up your IP address. Available as [services.echoip](#opt-services.echoip.enable).

- [Buffyboard](https://gitlab.postmarketos.org/postmarketOS/buffybox/-/tree/master/buffyboard), a framebuffer on-screen keyboard. Available as [services.buffyboard](option.html#opt-services.buffyboard).
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 @@ -434,6 +434,7 @@
./services/backup/syncoid.nix
./services/backup/tarsnap.nix
./services/backup/tsm.nix
./services/backup/urbackup.nix
./services/backup/zfs-replication.nix
./services/backup/znapzend.nix
./services/backup/zrepl.nix
Expand Down
238 changes: 238 additions & 0 deletions nixos/modules/services/backup/urbackup.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.urbackup;

urbackup = cfg.package.override {
withMountVhd = cfg.mountVhd.enable;
};

urbackupsrvWrapper = pkgs.writeShellScriptBin "urbackupsrv" ''
exec systemd-run \
--quiet \
--pipe \
--pty \
--wait \
--collect \
--property=User=${cfg.user} \
--property=StateDirectory=urbackup \
--property=DynamicUser=yes \
--property=SystemCallFilter=~@setuid \
--service-type=exec \
${urbackup}/bin/urbackupsrv "$@"
'';
in
{
options = {
services.urbackup = {
enable = lib.mkEnableOption "UrBackup, an easy to setup Open Source client/server backup system";

mountVhd.enable = lib.mkEnableOption "Enable mounting of VHD files via fuse";

package = lib.mkPackageOption pkgs "urbackup-server" { };

fastcgiPort = lib.mkOption {
type = lib.types.port;
default = 55413;
description = "Port for FastCGI requests";
};

enableHttpServer = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Enable internal HTTP server.
Required for serving web interface without FastCGI
and for websocket connections from client.
'';
};

httpPort = lib.mkOption {
type = lib.types.port;
default = 55414;
description = "Port for the web interface (if internal HTTP server is enabled)";
};

httpLocalhostOnly = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Bind HTTP server to localhost only";
};

internetLocalhostOnly = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Bind Internet port to localhost only";
};

logFile = lib.mkOption {
type = lib.types.path;
default = "/var/log/urbackup/urbackup.log";
description = "Path to the log file";
};

logLevel = lib.mkOption {
type = lib.types.enum [
"debug"
"warn"
"info"
"error"
];
default = "warn";
description = "Logging level (either debug, warn, info or error)";
};

daemonTmpDir = lib.mkOption {
type = lib.types.path;
default = "/tmp";
description = ''
Temporary file directory.
This may get very large depending on the advanced settings.
'';
};

sqliteTmpDir = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
Tmp file directory for sqlite temporary tables.
You might want to put the databases on another filesystem than the other temporary files.
Defaults to the same as daemonTmpDir if not specified.
'';
};

broadcastInterfaces = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
Interfaces from which to send broadcasts.
Empty list means all interfaces.
Example: ["eth0" "eth1"]
'';
};

allowUserEnumeration = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable better error messages if a user cannot be found during login";
};

user = lib.mkOption {
type = lib.types.str;
default = "urbackup";
description = "User the urbackupsrv process runs as";
};

backupStoragePath = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
Absolute path to backup storage location. This path must exist.
Note: By default, the service will be restricted to access this path only.
'';
};
};
};

config = lib.mkIf cfg.enable {
environment.etc."urbackup/backupfolder" = lib.mkIf (cfg.backupStoragePath != null) {
text = cfg.backupStoragePath;
};

environment.etc."urbackup/urbackupsrv".text = ''
#Port for FastCGI requests
FASTCGI_PORT=${toString cfg.fastcgiPort}

#Enable internal HTTP server
#Required for serving web interface without FastCGI
#and for websocket connections from client
HTTP_SERVER="${if cfg.enableHttpServer then "true" else "false"}"

#Port for the web interface
#(if internal HTTP server is enabled)
HTTP_PORT=${toString cfg.httpPort}

#Bind HTTP server to localhost only
HTTP_LOCALHOST_ONLY=${if cfg.httpLocalhostOnly then "true" else "false"}

#Bind Internet port to localhost only
INTERNET_LOCALHOST_ONLY=${if cfg.internetLocalhostOnly then "true" else "false"}

#log file name
LOGFILE="${cfg.logFile}"

#Either debug,warn,info or error
LOGLEVEL="${cfg.logLevel}"

#Temporary file directory
DAEMON_TMPDIR="${cfg.daemonTmpDir}"

#Tmp file directory for sqlite temporary tables.
#You might want to put the databases on another filesystem than the other temporary files.
#Default is the same as DAEMON_TMPDIR
SQLITE_TMPDIR="${if cfg.sqliteTmpDir == null then "" else cfg.sqliteTmpDir}"

#Interfaces from which to send broadcasts. (Default: all).
#Comma separated -- e.g. "eth0,eth1"
BROADCAST_INTERFACES="${lib.concatStringsSep "," cfg.broadcastInterfaces}"

# Enable better error messages if a user cannot be found during login
ALLOW_USER_ENUMERATION="${if cfg.allowUserEnumeration then "true" else "false"}"

#User the urbackupsrv process runs as
USER="${cfg.user}"
'';

users = {
users = lib.mkIf (cfg.user == "urbackup") {
urbackup = {
group = "urbackup";
isSystemUser = true;
};
};
groups = {
urbackup = { };
};
};

security.wrappers.urbackup_mount_helper = {
setuid = true;
owner = cfg.user;
group = "urbackup";
source = "${urbackup}/bin/urbackup_mount_helper";
};

environment.systemPackages = [
urbackupsrvWrapper
] ++ lib.optionals (cfg.mountVhd.enable) [ pkgs.libguestfs ];

systemd.services.urbackup-server = {
description = "UrBackup Client/Server Network Backup System";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
StateDirectory = "urbackup";
LogsDirectory = "urbackup";
ReadWritePaths =
[
cfg.backupStoragePath
]
++ lib.optionals (cfg.sqliteTmpDir != null) [ cfg.sqliteTmpDir ]
++ lib.optionals (cfg.daemonTmpDir != "/tmp") [ cfg.daemonTmpDir ]
++ lib.optionals (cfg.logFile != "/var/log/urbackup/urbackup.log") [ cfg.logFile ];
ExecStart = "${urbackup}/bin/urbackupsrv run --config /etc/urbackup/urbackupsrv --no-consoletime";
User = cfg.user;
DynamicUser = true;
AmbientCapabilities = "CAP_SYS_NICE";
TasksMax = "infinity";
SystemCallFilter = [
"~@setuid"
];
};
};
};
}
59 changes: 59 additions & 0 deletions pkgs/by-name/ur/urbackup-server/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
cryptopp,
curl,
fetchzip,
fuse,
lib,
pkg-config,
sqlite,
stdenv,
withMountVhd ? false,
zlib,
}:

stdenv.mkDerivation rec {
pname = "urbackup-server";
version = "2.5.33";

src = fetchzip {
url = "https://hndl.urbackup.org/Server/${version}/urbackup-server-${version}.tar.gz";
hash = "sha256-XfVQaeenNvQwf0WsWSnUKR5SrdsSGho7UhhXmoHWoYU=";
};

nativeBuildInputs = [
pkg-config
];

buildInputs = [
cryptopp
curl
sqlite
zlib
] ++ lib.optionals (withMountVhd) [ fuse ];

configureFlags = [
"--with-crypto-prefix=${cryptopp.dev}"
"--enable-packaging"
] ++ lib.optionals (withMountVhd) [ "--with-mountvhd" ];

enableParallelBuilding = true;

postPatch = ''
# prevent chmod failure. setuid is set in the service.
substituteInPlace Makefile.in \
--replace-fail "chmod +s" "# chmod +s"

# Adjust statedir at compile time for systemd service.
substituteInPlace Makefile.in \
--replace-fail "-DVARDIR='\"\$(localstatedir)\"'" "-DVARDIR='\"/var/lib\"'"
'';

meta = {
description = "Easy to setup Open Source client/server backup system";
longDescription = "An easy to setup Open Source client/server backup system, that through a combination of image and file backups accomplishes both data safety and a fast restoration time";
homepage = "https://www.urbackup.org/index.html";
license = lib.licenses.agpl3Plus;
platforms = lib.platforms.linux;
maintainers = with lib.maintainers; [ quincepie ];
};
}