1.2.1.1-beta: notification + LXC + post-install fixes

- flask_notification_routes: PVE webhook X-Webhook-Secret written in
  standard base64 so PVE can decode it (GH #198)
- notification_channels: Gmail SMTP App Password handling — normalize
  tls_mode (None/empty → starttls), reject creds without host (false-
  positive sendmail delivery), surface "AUTH not advertised" hint
- notification_events: is_vzdump_active_on_host() reads /var/log/pve/
  tasks/active directly so backup_start fallback and vm_shutdown
  suppression survive a Monitor restart mid-backup
- notification_templates: extract --storage flag from vzdump log →
  "PBS-Cloud: vm/104/…" instead of generic "PBS:" prefix when multiple
  PBS endpoints exist
- health_monitor: pve_storage_capacity + zfs_pool_capacity respect
  per-item dismiss (don't keep category WARNING/CRITICAL after user
  dismisses); updates_check cache invalidated when /var/log/apt/
  history.log mtime advances
- lxc_mount_points: PVE volume size from subvol quota (df via
  /proc/<host_pid>/root/<target> + lxc.conf size=NNNG fallback);
  host_source_state detects "host detached" zombie binds; per-mount
  subprocess work parallelised via ThreadPoolExecutor so a CT with
  many bind mounts doesn't trip the Caddy 3s reverse-proxy timeout
- virtual-machines: "host detached" badge on bind mounts whose host
  source path disappeared
- auto/customizable_post_install: log2ram FUNC_VERSION 1.1 → 1.2; new
  log2ram-check.sh vacuums journal + truncates non-rotating logs
  (pveproxy/access.log, pveam.log) instead of only calling
  `log2ram write` (which leaves the tmpfs full); auto flow gains the
  missing SystemMaxUse in /etc/systemd/journald.conf

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MacRimi
2026-05-19 00:06:49 +02:00
parent 81844fa456
commit 6eb1312c61
11 changed files with 548 additions and 92 deletions
+24 -4
View File
@@ -223,14 +223,28 @@ def _parse_vzdump_message(message: str) -> Optional[Dict[str, Any]]:
else:
total_time = f"{secs}s"
# ── Extract the storage target name (PBS, PBS-Cloud, local, …) ──
# PVE logs the full command on the first line:
# "INFO: starting new backup job: vzdump 104 105 --storage PBS-Cloud --mode stop"
# We surface it so the notification body can say "PBS-Cloud: vm/104/…"
# instead of the generic "PBS:" prefix when multiple PBS endpoints
# are configured. Reported by JC Miñarro 18/05.
storage_name = ''
for line in lines:
m_storage = re.search(r'--storage\s+(\S+)', line)
if m_storage:
storage_name = m_storage.group(1).strip()
break
if not vms and not total_size:
return None
return {
'vms': vms,
'total_time': total_time,
'total_size': total_size,
'vm_count': len(vms),
'storage_name': storage_name,
}
@@ -277,13 +291,19 @@ def _format_vzdump_body(parsed: Dict[str, Any], is_success: bool) -> str:
if detail_line:
parts.append(' | '.join(detail_line))
# PBS/File on separate line with icon
# PBS/File on separate line with icon. When we know the
# storage name (e.g. "PBS-Cloud", "PBS-Office") prefix it so
# the user can tell which destination this archive lives in \u2014
# critical when there are multiple PBS endpoints configured.
if vm.get('filename'):
fname = vm['filename']
storage_name = parsed.get('storage_name', '') or ''
if re.match(r'^(?:ct|vm)/\d+/', fname):
parts.append(f"\U0001F5C4\uFE0F PBS: {fname}")
label = storage_name if storage_name else 'PBS'
parts.append(f"\U0001F5C4\uFE0F {label}: {fname}")
else:
parts.append(f"\U0001F4C1 File: {fname}")
label = storage_name if storage_name else 'File'
parts.append(f"\U0001F4C1 {label}: {fname}")
# Error reason if failed
if status != 'ok' and vm.get('error'):