8 Commits
Author SHA1 Message Date
Andras BacsaiandClaude Opus 5.5 5ed8565edf fix(patches): show held back package updates apart from the updates
Phased Ubuntu updates, apt-mark holds, and apk version pins showed as
available updates that no update could install.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 12:53:20 +01:00
Andras BacsaiandClaude Opus 5.5 f9e4323839 fix(patches): turn on automatic updates with the time in the Maintenance window field
Turn on used the saved time and the confirmation showed the time from
page load, so an unsaved new time was ignored. Turn on now validates
and saves the time in the field, and the confirmation refers to the
field instead of a fixed time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 13:54:46 +02:00
Andras BacsaiandClaude Opus 5.5 3bc7e47a86 feat(patches): confirm before turning automatic security updates on or off
Automatic security updates now have their own "Turn on" / "Turn off"
action with a confirmation, instead of a field that the Save bar
applied. The confirmation explains what can stop:

- Docker from the operating system packages (docker.io, moby-engine)
  restarts on a security update, so all containers stop and start.
- Docker CE from the Docker repository is not updated: its repository
  has no security origin (apt) and no security advisories (dnf).
  Checked on Debian 12 (unattended-upgrade --dry-run skips docker-ce)
  and CentOS Stream 9.
- Services that use an updated library can restart; a new kernel is
  installed without a reboot.

The on/off state is locked, so only the confirmed action can change it.
A new maintenance window is applied to the server on Save only when the
updates are on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 13:51:21 +02:00
Andras BacsaiandClaude Opus 5.5 3c0c7cc93d refactor(patches): move schedule and automatic updates into the Server patching section
The check frequency, automatic security updates, and maintenance window
are now fields of the first section, in one row, instead of two extra
boxes. The "not supported" note moved into the existing callout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 13:43:31 +02:00
Andras BacsaiandClaude Opus 5.5 f32ecca44c feat(patches): record package updates, reboots, and auto-update changes in the audit log
- ui.server.packages_update_requested: user, server, packages (or all),
  package manager, and the activity of the update.
- ui.server.packages_update_finished: written when the remote process
  finishes (also when it fails), with the result and the exit code of
  the activity. The update gets a fresh type_uuid (an indexed activity
  property), so the listener finds exactly this activity. The actor
  comes from the request, because the listener runs in the queue.
- ui.server.reboot_requested with result started or failed.
- ui.server.auto_security_updates_updated (enabled, time, package
  manager, result) and ui.server.patch_settings_updated for a changed
  check frequency.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:44:03 +02:00
Andras BacsaiandClaude Opus 5.5 4ca0b4415c feat(patches): add automatic security updates per server
- New server settings: is_auto_security_updates_enabled and
  auto_security_updates_time (maintenance window, HH:MM in the time zone
  of the server). Both move with a server transfer.
- Debian/Ubuntu: install unattended-upgrades and write
  52coolify-unattended-upgrades. `#clear` drops the distro origin lists,
  so only the security origins stay (Debian <codename>-security, Ubuntu
  <codename>-security, and the Ubuntu Pro ESM security origins). A
  drop-in for apt-daily-upgrade.timer sets the time.
  https://manpages.debian.org/bookworm/apt/apt.conf.5.en.html
  https://github.com/mvo5/unattended-upgrades/blob/master/README.md
- RHEL family: install dnf-automatic (dnf5-plugin-automatic on dnf5),
  set upgrade_type = security and apply_updates = yes in
  /etc/dnf/automatic.conf, and add a drop-in for dnf-automatic.timer
  (dnf4) or dnf5-automatic.timer (dnf5).
  https://dnf.readthedocs.io/en/latest/automatic.html
  https://dnf5.readthedocs.io/en/latest/dnf5_plugins/automatic.8.html
- Off removes the Coolify files, so the operating system default comes
  back. Other package managers show "not supported".
- The schedule and the automatic updates share one form and one
  unsaved bar. The remote commands run only when the automatic update
  settings change; a failure keeps the old setting.
- Commands are written for non-root SSH users (tee and single sh -c
  scripts) and were run in Debian 12, Ubuntu 24.04, Rocky 9, and Fedora
  containers as root and as a sudo user.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:41:42 +02:00
Andras BacsaiandClaude Opus 5.5 3da85e2c07 feat(patches): mark security updates, reboot state, and risky packages
- Security updates: apt marks a package from a "-security" suite (Debian
  12 now reports oldstable-security). dnf reads `dnf updateinfo list
  --security` (dnf5 keeps updateinfo as an alias of advisory). zypper
  uses `zypper -x patch --dry-run --category security`, because
  `zypper -x list-patches` ignores --category and has no package names.
  pacman and apk cannot tell, so they show no security count.
  https://dnf5.readthedocs.io/en/latest/commands/advisory.8.html
  https://github.com/openSUSE/zypper/blob/master/doc/zypper.8.txt
- Reboot required: /var/run/reboot-required, `needrestart -b` (KSTA 2
  or 3), `dnf needs-restarting -r` (matched by text, because a missing
  plugin also exits 1), and `zypper needs-rebooting` (exit 102).
  https://github.com/liske/needrestart/blob/master/README.batch.md
  https://dnf-plugins-core.readthedocs.io/en/latest/needs_restarting.html
- An explicit risk list per package manager (Docker engine, kernels,
  libc/glibc/musl, systemd, dbus, openssh) replaces the "name contains
  docker/kernel" guess on the page and in every notification channel.
- The page shows security and reboot badges, a security count, and the
  risk of each package. "Reboot server" (with confirmation, update
  policy on the loaded server) schedules the reboot with systemd-run and
  checks the server again five minutes later. Archived (transferred)
  servers are never touched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:39:51 +02:00
Andras BacsaiandClaude Opus 5.5 6806ed31fa feat(patches): save check results and run checks in a queued job
- server_settings gets patch_check_result (JSON), patch_check_error,
  patch_checked_at, and patch_check_frequency.
- The patches page shows the saved result and "Last checked" on load.
  "Check for updates" queues ServerPatchCheckJob (manual) instead of
  running SSH in the Livewire request. The job saves the result and
  broadcasts ServerPatchCheckFinished on the server team channel; the
  page reloads the saved result (with a 10 s poll as a fallback).
- A finished package update (callEventOnFinish) queues a new check on
  the server side, so the page no longer depends on the browser.
  ServerPackageUpdated is removed.
- The check frequency is a server setting (cron or preset, at most once
  per hour). Empty keeps the staggered weekly default.
- The failure notification is sent only when the state changes from ok
  to error, not on every check.
- Page access needs viewSecurity and every action needs update on the
  loaded server; a member gets 403. Updates accept only a package from
  the saved result.
- Server transfer: the frequency moves, the last result stays on the
  source (runtime).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:28:51 +02:00