Add configurable WORK_DIR instead of /tmp for temp files

Default: /usr/local/gniza/workdir (root) or ~/.local/state/gniza/workdir
(user). MySQL dumps and rclone temp configs now use WORK_DIR. Configurable
via gniza.conf or TUI Settings screen. Created during install.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shuki
2026-03-06 03:00:21 +02:00
parent 791584aa60
commit b3c055c9be
9 changed files with 37 additions and 6 deletions

View File

@@ -32,3 +32,7 @@ SSH_RETRIES=3
# Extra rsync options (careful: validated for safe characters) # Extra rsync options (careful: validated for safe characters)
RSYNC_EXTRA_OPTS="" RSYNC_EXTRA_OPTS=""
# Work directory for temporary files (MySQL dumps, rclone configs, etc.)
# Default: /usr/local/gniza/workdir (root) or ~/.local/state/gniza/workdir (user)
#WORK_DIR="/usr/local/gniza/workdir"

View File

@@ -55,6 +55,9 @@ load_config() {
SSH_RETRIES="${SSH_RETRIES:-$DEFAULT_SSH_RETRIES}" SSH_RETRIES="${SSH_RETRIES:-$DEFAULT_SSH_RETRIES}"
RSYNC_EXTRA_OPTS="${RSYNC_EXTRA_OPTS:-}" RSYNC_EXTRA_OPTS="${RSYNC_EXTRA_OPTS:-}"
# WORK_DIR can be overridden in config; re-export if changed
export WORK_DIR
# --debug flag overrides config # --debug flag overrides config
[[ "${GNIZA4LINUX_DEBUG:-false}" == "true" ]] && LOG_LEVEL="debug" [[ "${GNIZA4LINUX_DEBUG:-false}" == "true" ]] && LOG_LEVEL="debug"

View File

@@ -147,7 +147,7 @@ mysql_dump_databases() {
fi fi
# Create temp directory # Create temp directory
MYSQL_DUMP_DIR=$(mktemp -d "${TMPDIR:-/tmp}/gniza-mysql-XXXXXX") MYSQL_DUMP_DIR=$(mktemp -d "${WORK_DIR}/gniza-mysql-XXXXXX")
mkdir -p "$MYSQL_DUMP_DIR/_mysql" mkdir -p "$MYSQL_DUMP_DIR/_mysql"
# Parse extra opts into array # Parse extra opts into array

View File

@@ -17,7 +17,7 @@ _build_rclone_config() {
local old_umask local old_umask
old_umask=$(umask) old_umask=$(umask)
umask 077 umask 077
tmpfile=$(mktemp /tmp/gniza-rclone-XXXXXX.conf) || { tmpfile=$(mktemp "${WORK_DIR}/gniza-rclone-XXXXXX.conf") || {
umask "$old_umask" umask "$old_umask"
log_error "Failed to create temp rclone config" log_error "Failed to create temp rclone config"
return 1 return 1

View File

@@ -85,14 +85,16 @@ detect_mode() {
GNIZA_MODE="root" GNIZA_MODE="root"
CONFIG_DIR="/etc/gniza" CONFIG_DIR="/etc/gniza"
LOG_DIR="/var/log/gniza" LOG_DIR="/var/log/gniza"
WORK_DIR="/usr/local/gniza/workdir"
LOCK_FILE="/var/run/gniza.lock" LOCK_FILE="/var/run/gniza.lock"
else else
GNIZA_MODE="user" GNIZA_MODE="user"
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/gniza" CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/gniza"
LOG_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/gniza/log" LOG_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/gniza/log"
WORK_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/gniza/workdir"
LOCK_FILE="${XDG_RUNTIME_DIR:-/tmp}/gniza-${EUID}.lock" LOCK_FILE="${XDG_RUNTIME_DIR:-/tmp}/gniza-${EUID}.lock"
fi fi
export GNIZA_MODE CONFIG_DIR LOG_DIR LOCK_FILE export GNIZA_MODE CONFIG_DIR LOG_DIR WORK_DIR LOCK_FILE
} }
ensure_dirs() { ensure_dirs() {
@@ -101,4 +103,5 @@ ensure_dirs() {
mkdir -p "$CONFIG_DIR/remotes.d" || die "Cannot create remotes.d directory" mkdir -p "$CONFIG_DIR/remotes.d" || die "Cannot create remotes.d directory"
mkdir -p "$CONFIG_DIR/schedules.d" || die "Cannot create schedules.d directory" mkdir -p "$CONFIG_DIR/schedules.d" || die "Cannot create schedules.d directory"
mkdir -p "$LOG_DIR" || die "Cannot create log directory: $LOG_DIR" mkdir -p "$LOG_DIR" || die "Cannot create log directory: $LOG_DIR"
mkdir -p "$WORK_DIR" || die "Cannot create work directory: $WORK_DIR"
} }

View File

@@ -22,12 +22,14 @@ if [[ $EUID -eq 0 ]]; then
BIN_LINK="/usr/local/bin/gniza" BIN_LINK="/usr/local/bin/gniza"
CONFIG_DIR="/etc/gniza" CONFIG_DIR="/etc/gniza"
LOG_DIR="/var/log/gniza" LOG_DIR="/var/log/gniza"
WORK_DIR="/usr/local/gniza/workdir"
else else
MODE="user" MODE="user"
INSTALL_DIR="$HOME/.local/share/gniza" INSTALL_DIR="$HOME/.local/share/gniza"
BIN_LINK="$HOME/.local/bin/gniza" BIN_LINK="$HOME/.local/bin/gniza"
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/gniza" CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/gniza"
LOG_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/gniza/log" LOG_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/gniza/log"
WORK_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/gniza/workdir"
fi fi
info "Install mode: ${C_BOLD}${MODE}${C_RESET}" info "Install mode: ${C_BOLD}${MODE}${C_RESET}"
@@ -135,6 +137,10 @@ fi
info "Setting up log directory: $LOG_DIR" info "Setting up log directory: $LOG_DIR"
mkdir -p "$LOG_DIR" mkdir -p "$LOG_DIR"
# ── Create work directory ───────────────────────────────────
info "Setting up work directory: $WORK_DIR"
mkdir -p "$WORK_DIR"
# ── Copy example configs (if not already present) ──────────── # ── Copy example configs (if not already present) ────────────
if [[ ! -f "$CONFIG_DIR/gniza.conf" ]]; then if [[ ! -f "$CONFIG_DIR/gniza.conf" ]]; then
cp "$INSTALL_DIR/etc/gniza.conf.example" "$CONFIG_DIR/gniza.conf" cp "$INSTALL_DIR/etc/gniza.conf.example" "$CONFIG_DIR/gniza.conf"
@@ -153,9 +159,10 @@ done
echo "" echo ""
echo "${C_GREEN}${C_BOLD}Installation complete!${C_RESET}" echo "${C_GREEN}${C_BOLD}Installation complete!${C_RESET}"
echo "" echo ""
echo " Binary: $BIN_LINK" echo " Binary: $BIN_LINK"
echo " Config: $CONFIG_DIR/gniza.conf" echo " Config: $CONFIG_DIR/gniza.conf"
echo " Logs: $LOG_DIR" echo " Logs: $LOG_DIR"
echo " Work dir: $WORK_DIR"
echo "" echo ""
echo "Get started:" echo "Get started:"
echo " gniza --help Show CLI help" echo " gniza --help Show CLI help"

View File

@@ -20,8 +20,16 @@ def _get_log_dir() -> Path:
return Path(xdg) / "gniza" / "log" return Path(xdg) / "gniza" / "log"
def _get_work_dir() -> Path:
if os.geteuid() == 0:
return Path("/usr/local/gniza/workdir")
xdg = os.environ.get("XDG_STATE_HOME", os.path.expanduser("~/.local/state"))
return Path(xdg) / "gniza" / "workdir"
CONFIG_DIR = _get_config_dir() CONFIG_DIR = _get_config_dir()
LOG_DIR = _get_log_dir() LOG_DIR = _get_log_dir()
WORK_DIR = _get_work_dir()
def parse_conf(filepath: Path) -> dict[str, str]: def parse_conf(filepath: Path) -> dict[str, str]:

View File

@@ -199,6 +199,7 @@ class AppSettings:
ssh_timeout: str = "30" ssh_timeout: str = "30"
ssh_retries: str = "3" ssh_retries: str = "3"
rsync_extra_opts: str = "" rsync_extra_opts: str = ""
work_dir: str = "/usr/local/gniza/workdir"
@classmethod @classmethod
def from_conf(cls, data: dict[str, str]) -> "AppSettings": def from_conf(cls, data: dict[str, str]) -> "AppSettings":
@@ -219,6 +220,7 @@ class AppSettings:
ssh_timeout=data.get("SSH_TIMEOUT", "30"), ssh_timeout=data.get("SSH_TIMEOUT", "30"),
ssh_retries=data.get("SSH_RETRIES", "3"), ssh_retries=data.get("SSH_RETRIES", "3"),
rsync_extra_opts=data.get("RSYNC_EXTRA_OPTS", ""), rsync_extra_opts=data.get("RSYNC_EXTRA_OPTS", ""),
work_dir=data.get("WORK_DIR", "/usr/local/gniza/workdir"),
) )
def to_conf(self) -> dict[str, str]: def to_conf(self) -> dict[str, str]:
@@ -239,4 +241,5 @@ class AppSettings:
"SSH_TIMEOUT": self.ssh_timeout, "SSH_TIMEOUT": self.ssh_timeout,
"SSH_RETRIES": self.ssh_retries, "SSH_RETRIES": self.ssh_retries,
"RSYNC_EXTRA_OPTS": self.rsync_extra_opts, "RSYNC_EXTRA_OPTS": self.rsync_extra_opts,
"WORK_DIR": self.work_dir,
} }

View File

@@ -59,6 +59,8 @@ class SettingsScreen(Screen):
yield Input(value=settings.ssh_retries, id="set-sshretries") yield Input(value=settings.ssh_retries, id="set-sshretries")
yield Static("Extra rsync options:") yield Static("Extra rsync options:")
yield Input(value=settings.rsync_extra_opts, id="set-rsyncopts") yield Input(value=settings.rsync_extra_opts, id="set-rsyncopts")
yield Static("Work Directory:")
yield Input(value=settings.work_dir, placeholder="/usr/local/gniza/workdir", id="set-workdir")
with Horizontal(id="set-buttons"): with Horizontal(id="set-buttons"):
yield Button("Save", variant="primary", id="btn-save") yield Button("Save", variant="primary", id="btn-save")
yield Button("Back", id="btn-back") yield Button("Back", id="btn-back")
@@ -91,6 +93,7 @@ class SettingsScreen(Screen):
ssh_timeout=self.query_one("#set-sshtimeout", Input).value.strip() or "30", ssh_timeout=self.query_one("#set-sshtimeout", Input).value.strip() or "30",
ssh_retries=self.query_one("#set-sshretries", Input).value.strip() or "3", ssh_retries=self.query_one("#set-sshretries", Input).value.strip() or "3",
rsync_extra_opts=self.query_one("#set-rsyncopts", Input).value.strip(), rsync_extra_opts=self.query_one("#set-rsyncopts", Input).value.strip(),
work_dir=self.query_one("#set-workdir", Input).value.strip() or "/usr/local/gniza/workdir",
) )
conf_path = CONFIG_DIR / "gniza.conf" conf_path = CONFIG_DIR / "gniza.conf"
write_conf(conf_path, settings.to_conf()) write_conf(conf_path, settings.to_conf())