add new deploy script and cutting out pip as the installer

This commit is contained in:
2026-02-03 22:39:13 +01:00
parent f30d37632b
commit 7caaf46588
3 changed files with 152 additions and 70 deletions

View File

@@ -8,7 +8,7 @@ import yaml
from ..errors import InstallError
from ..paths import PobsyncPaths
from ..util import ensure_dir, is_absolute_non_root
from ..util import ensure_dir, is_absolute_non_root, write_text_atomic
DEFAULT_EXCLUDES = [
@@ -42,21 +42,16 @@ DEFAULT_RSYNC_ARGS = [
]
# NOTE: This wrapper exists so cron can reliably call /opt/pobsync/bin/pobsync.
# It forwards to the "real" pobsync on PATH when possible, and falls back to python -m pobsync.
# Canonical entrypoint: always run code from /opt/pobsync/lib (or the given prefix).
WRAPPER_SH_TEMPLATE = """#!/bin/sh
# managed-by=pobsync
# managed-by=pobsync install
set -eu
SELF="{self_path}"
REAL="$(command -v pobsync || true)"
PREFIX="{prefix}"
export PYTHONPATH="${{PREFIX}}/lib"
export PYTHONUNBUFFERED=1
# Avoid recursion if PATH includes /opt/pobsync/bin
if [ -n "${{REAL}}" ] && [ "${{REAL}}" != "${{SELF}}" ]; then
exec "${{REAL}}" "$@"
fi
exec python3 -m pobsync "$@"
exec /usr/bin/python3 -m pobsync "$@"
"""
@@ -118,29 +113,7 @@ def write_yaml(path: Path, data: dict[str, Any], dry_run: bool, force: bool) ->
return f"write {path}"
def _write_text_file(path: Path, content: str, dry_run: bool, force: bool) -> str:
"""
Write a plain text file with optional backup behavior similar to write_yaml().
"""
if path.exists() and not force:
return f"skip existing {path}"
if path.exists() and force:
bak = path.with_suffix(path.suffix + ".bak")
if not dry_run:
bak.write_text(path.read_text(encoding="utf-8"), encoding="utf-8")
if not dry_run:
path.write_text(content, encoding="utf-8")
return f"overwrite {path} (backup {bak})"
if not dry_run:
path.write_text(content, encoding="utf-8")
return f"write {path}"
def _install_wrapper(prefix: Path, dry_run: bool, force: bool) -> list[str]:
"""
Ensure prefix/bin/pobsync exists so cron entries can use it.
"""
def _install_wrapper(prefix: Path, dry_run: bool) -> list[str]:
actions: list[str] = []
bin_dir = prefix / "bin"
@@ -149,21 +122,18 @@ def _install_wrapper(prefix: Path, dry_run: bool, force: bool) -> list[str]:
ensure_dir(bin_dir)
wrapper_path = bin_dir / "pobsync"
content = WRAPPER_SH_TEMPLATE.format(self_path=str(wrapper_path))
actions.append(_write_text_file(wrapper_path, content, dry_run=dry_run, force=force))
content = WRAPPER_SH_TEMPLATE.format(prefix=str(prefix))
actions.append(f"chmod 0755 {wrapper_path}")
actions.append(f"write {wrapper_path}")
if not dry_run:
write_text_atomic(wrapper_path, content)
os.chmod(wrapper_path, 0o755)
actions.append(f"chmod 0755 {wrapper_path}")
return actions
def _ensure_system_log_dir(dry_run: bool) -> list[str]:
"""
Best-effort: create /var/log/pobsync to match cron redirection.
Not fatal if it fails (e.g., insufficient permissions in a non-root install attempt).
"""
actions: list[str] = []
log_dir = Path("/var/log/pobsync")
actions.append(f"mkdir -p {log_dir}")
@@ -194,8 +164,10 @@ def run_install(
global_cfg = build_default_global_config(paths.home, backup_root=backup_root, retention=retention)
actions.append(write_yaml(paths.global_config_path, global_cfg, dry_run=dry_run, force=force))
# Install polish: make cron-compatible wrapper path and cron log directory.
actions.extend(_install_wrapper(prefix, dry_run=dry_run, force=force))
# Option A canonical install support:
# - Provide a stable entrypoint at /opt/pobsync/bin/pobsync (or prefix/bin/pobsync)
# - Ensure /var/log/pobsync exists for cron redirection
actions.extend(_install_wrapper(prefix, dry_run=dry_run))
actions.extend(_ensure_system_log_dir(dry_run=dry_run))
return {