Skip to content
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: 1 addition & 1 deletion frontend/src/pages/DashboardPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link, useNavigate } from "react-router-dom"
import { useNavigate } from "react-router-dom"
import { useState, useEffect } from "react"
import { api, Job, Tape } from "../lib/api"
import RestoreWizard from "@/components/RestoreWizard"
Expand Down
1 change: 0 additions & 1 deletion frontend/src/pages/JobsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useState, useEffect } from "react"
import { Link } from "react-router-dom"
import { cn } from "@/lib/utils"
import { useDemoMode } from "@/lib/demoMode"
import { api, Job, Tape } from "@/lib/api"
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/SettingsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react"
import { useState, useEffect } from "react"
import { useSearchParams } from "react-router-dom"
import { cn } from "@/lib/utils"
import { useDemoMode } from "@/lib/demoMode"
Expand Down
41 changes: 41 additions & 0 deletions packaging/fossilsafe.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[Unit]
Description=FossilSafe LTO Backup Appliance
Documentation=https://fossilsafe.io
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User={{SERVICE_USER}}
Group={{SERVICE_USER}}
SupplementaryGroups={{TAPE_GROUP}}
WorkingDirectory={{INSTALL_DIR}}
Environment=FOSSILSAFE_CONFIG_PATH={{CONFIG_PATH}}
Environment=FOSSILSAFE_DATA_DIR={{DATA_DIR}}
Environment=FOSSILSAFE_BACKEND_BIND={{BACKEND_BIND}}
Environment=FOSSILSAFE_BACKEND_PORT={{BACKEND_PORT}}
Environment=PYTHONUNBUFFERED=1
# Create mount/data dirs before ProtectSystem=strict kicks in (+ = root)
ExecStartPre=+/bin/mkdir -p {{DATA_DIR}} /var/log/fossilsafe /mnt/fossilsafe/nfs /mnt/fossilsafe/smb /mnt/fossilsafe/external /mnt/ltfs
ExecStart={{VENV_DIR}}/bin/gunicorn -c {{INSTALL_DIR}}/gunicorn.conf.py backend.lto_backend_main:app
Restart=on-failure
RestartSec=5
TimeoutStopSec=60

NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
LockPersonality=true
RestrictRealtime=true
ReadWritePaths={{DATA_DIR}} {{INSTALL_DIR}} /var/log/fossilsafe /mnt/fossilsafe /mnt/ltfs /etc/fossilsafe
DeviceAllow=/dev/fuse rw
DeviceAllow=char-scsi_generic rw
DeviceAllow=char-scsi_tape rw

[Install]
WantedBy=multi-user.target
17 changes: 14 additions & 3 deletions scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2110,7 +2110,6 @@ SYSTEM_PACKAGES=(
coreutils
curl
fuse3
libfuse3-3
gzip
lsscsi
mt-st
Expand All @@ -2124,6 +2123,7 @@ SYSTEM_PACKAGES=(
tar
util-linux
nodejs
npm
certbot
python3-certbot-nginx
)
Expand All @@ -2134,7 +2134,6 @@ if [[ "${HEADLESS}" -eq 1 ]]; then
coreutils
curl
fuse3
libfuse3-3
gzip
lsscsi
mt-st
Expand All @@ -2149,6 +2148,15 @@ if [[ "${HEADLESS}" -eq 1 ]]; then
)
fi

# Debian 12 ships libfuse3-3; Debian 13+ ships libfuse3-4.
if apt_package_available "libfuse3-4"; then
SYSTEM_PACKAGES+=(libfuse3-4)
elif apt_package_available "libfuse3-3"; then
SYSTEM_PACKAGES+=(libfuse3-3)
else
warn "No libfuse3 runtime package found in apt; FUSE/LTFS may not work."
fi

if [[ "${CHANGER_REQUIRED}" -eq 1 ]]; then
SYSTEM_PACKAGES+=(mtx)
fi
Expand Down Expand Up @@ -2372,12 +2380,15 @@ step_header "[8/${STEP_TOTAL}] Installing FossilSafe files" \
if command -v rsync >/dev/null; then
rsync -a --delete "${SOURCE_ROOT}/backend" "${INSTALL_DIR}/"
rsync -a --delete "${SOURCE_ROOT}/frontend" "${INSTALL_DIR}/"
rsync -a --delete "${SOURCE_ROOT}/packaging" "${INSTALL_DIR}/"
rsync -a "${SOURCE_ROOT}/gunicorn.conf.py" "${INSTALL_DIR}/gunicorn.conf.py"
rsync -a "${SOURCE_ROOT}/scripts/fossilsafe_cli.py" "${INSTALL_DIR}/fsafe-cli.py"
rsync -a "${SOURCE_REQUIREMENTS}" "${INSTALL_DIR}/requirements.txt"
else
rm -rf "${INSTALL_DIR}/backend" "${INSTALL_DIR}/frontend"
rm -rf "${INSTALL_DIR}/backend" "${INSTALL_DIR}/frontend" "${INSTALL_DIR}/packaging"
cp -a "${SOURCE_ROOT}/backend" "${INSTALL_DIR}/backend"
cp -a "${SOURCE_ROOT}/frontend" "${INSTALL_DIR}/frontend"
cp -a "${SOURCE_ROOT}/packaging" "${INSTALL_DIR}/packaging"
cp -a "${SOURCE_ROOT}/gunicorn.conf.py" "${INSTALL_DIR}/gunicorn.conf.py"
cp -a "${SOURCE_ROOT}/scripts/fossilsafe_cli.py" "${INSTALL_DIR}/fsafe-cli.py"
cp -a "${SOURCE_REQUIREMENTS}" "${INSTALL_DIR}/requirements.txt"
Expand Down
13 changes: 11 additions & 2 deletions scripts/setup/install-service.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ BIND_ADDRESS="${FOSSILSAFE_BACKEND_BIND:-0.0.0.0}"
BIND_PORT="${FOSSILSAFE_BACKEND_PORT:-5000}"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMPLATE="${SCRIPT_DIR}/../packaging/fossilsafe.service"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
TEMPLATE="${REPO_ROOT}/packaging/fossilsafe.service"
OUTPUT="/etc/systemd/system/fossilsafe.service"

usage() {
Expand Down Expand Up @@ -84,15 +85,23 @@ chmod 750 "$DATA_DIR"

# Generate unit file
echo "Generating systemd unit file..."
VENV_DIR="${INSTALL_DIR}/venv"
# CONFIG_PATH may be a dir (/etc/fossilsafe) or the config.json file itself
if [[ -d "${CONFIG_PATH}" ]]; then
CONFIG_FILE="${CONFIG_PATH%/}/config.json"
else
CONFIG_FILE="${CONFIG_PATH}"
fi
sed \
-e "s|{{INSTALL_DIR}}|$INSTALL_DIR|g" \
-e "s|{{SERVICE_USER}}|$SERVICE_USER|g" \
-e "s|{{SERVICE_GROUP}}|$SERVICE_GROUP|g" \
-e "s|{{TAPE_GROUP}}|$TAPE_GROUP|g" \
-e "s|{{CONFIG_PATH}}|$CONFIG_PATH|g" \
-e "s|{{CONFIG_PATH}}|$CONFIG_FILE|g" \
-e "s|{{DATA_DIR}}|$DATA_DIR|g" \
-e "s|{{BACKEND_BIND}}|$BIND_ADDRESS|g" \
-e "s|{{BACKEND_PORT}}|$BIND_PORT|g" \
-e "s|{{VENV_DIR}}|$VENV_DIR|g" \
"$TEMPLATE" > "$OUTPUT"

chmod 644 "$OUTPUT"
Expand Down