@mateusbmp/backup-manager 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -145,6 +145,11 @@ journalctl --user -u bkm -f # scheduler and job log
145
145
  boot and keep running after you log out. On most systems this needs no root. If your
146
146
  system refuses it, the install still succeeds, with a warning that the service only runs
147
147
  while you are logged in.
148
+ - **No user session (`su`, `sudo -u`, some SSH setups):** `systemctl --user` needs
149
+ `XDG_RUNTIME_DIR`. If it is missing, bkm takes it (and the D-Bus address) from
150
+ `/run/user/<uid>` itself. If no user manager is running at all, the error says so: log in
151
+ as that user directly (`ssh user@host`), or have an administrator run
152
+ `sudo loginctl enable-linger <user>` once, then retry.
148
153
  - **Upgrades:** the unit stores absolute paths to `node` and `bkm`. If either one moves
149
154
  (an nvm upgrade or a reinstall), `bkm doctor` and the UI flag the unit as **outdated**.
150
155
  Choose **Install / update** on the Service screen to rewrite it.
@@ -467,7 +472,7 @@ JSON config validated by zod. npm.
467
472
  - Backups: `core/backup/pipeline.ts` (one env; `.tmp-<id>` → manifest → rename; auto-prune), `mariadb.ts`, `archive.ts`, `catalog.ts`, `retention.ts` (pure), `prune.ts`, `lock.ts`.
468
473
  - Jobs: `core/jobs/store.ts` (JSON status), `events.ts` (NDJSON), `runner.ts` (`startJob` spawns `bkm __job`: detached from the UI, a normal child from the daemon; `executeJob` runs it).
469
474
  - Daemon: `core/daemon/` (scheduler, catch-up via `schedule.json`, reload on file change or SIGHUP, graceful stop) + `src/api/server.ts`.
470
- - systemd: `core/service/` — every systemctl/journalctl/loginctl call goes through the injectable `CommandRunner` in `systemctl.ts`, always `--user`, never sudo, never a shell.
475
+ - systemd: `core/service/` — every systemctl/journalctl/loginctl call goes through the injectable `CommandRunner` in `systemctl.ts`, always `--user`, never sudo, never a shell; `execRunner` fills a missing `XDG_RUNTIME_DIR`/`DBUS_SESSION_BUS_ADDRESS` from `/run/user/<uid>` (`userBusEnv`).
471
476
  - UI: `src/ui/App.tsx` (frame, routing, global keys, toasts, modals), `screens/`, `components/` (Form, TextField, ScrollList/ScrollView, Panel), `hooks/` (usePolling, useJobEvents). `ui/print/` renders doctor output for the CLI.
472
477
 
473
478
  ## Conventions
package/dist/cli.js CHANGED
@@ -6458,11 +6458,24 @@ import path18 from "path";
6458
6458
 
6459
6459
  // src/core/service/systemctl.ts
6460
6460
  import { execFile } from "child_process";
6461
+ import { existsSync } from "fs";
6462
+ function userBusEnv(env = process.env, uid = process.getuid?.() ?? null, exists = existsSync) {
6463
+ const out = { ...env };
6464
+ if (!out.XDG_RUNTIME_DIR && uid !== null) {
6465
+ const dir = `/run/user/${uid}`;
6466
+ if (exists(dir)) out.XDG_RUNTIME_DIR = dir;
6467
+ }
6468
+ if (!out.DBUS_SESSION_BUS_ADDRESS && out.XDG_RUNTIME_DIR) {
6469
+ const bus = `${out.XDG_RUNTIME_DIR}/bus`;
6470
+ if (exists(bus)) out.DBUS_SESSION_BUS_ADDRESS = `unix:path=${bus}`;
6471
+ }
6472
+ return out;
6473
+ }
6461
6474
  var execRunner = (command, args) => new Promise((resolve) => {
6462
6475
  execFile(
6463
6476
  command,
6464
6477
  args,
6465
- { timeout: 3e4, maxBuffer: 4 * 1024 * 1024 },
6478
+ { timeout: 3e4, maxBuffer: 4 * 1024 * 1024, env: userBusEnv() },
6466
6479
  (error, stdout, stderr) => {
6467
6480
  const err = error;
6468
6481
  if (err && err.code === "ENOENT") {
@@ -6548,6 +6561,10 @@ function renderUnit({ command, configPath }) {
6548
6561
  }
6549
6562
 
6550
6563
  // src/core/service/manager.ts
6564
+ function busHint(message, user) {
6565
+ if (!/Failed to connect to bus|XDG_RUNTIME_DIR not defined/i.test(message)) return message;
6566
+ return `${message} \u2014 no systemd user session for ${user}: log in as ${user} directly (e.g. \`ssh ${user}@host\`, not \`su\`/\`sudo -u\`), or have an administrator run \`loginctl enable-linger ${user}\` once, then retry`;
6567
+ }
6551
6568
  var ServiceError = class extends Error {
6552
6569
  name = "ServiceError";
6553
6570
  };
@@ -6599,7 +6616,10 @@ var ServiceManager = class {
6599
6616
  if (show.code !== 0) {
6600
6617
  return {
6601
6618
  ...base,
6602
- error: (show.stderr || show.stdout).trim() || `systemctl exited with ${show.code}`
6619
+ error: busHint(
6620
+ (show.stderr || show.stdout).trim() || `systemctl exited with ${show.code}`,
6621
+ this.user
6622
+ )
6603
6623
  };
6604
6624
  }
6605
6625
  const p = parseProperties(show.stdout);