Skip to content

Enable unattended upgrades on Kubernetes nodes - #3167

Merged
claytono merged 1 commit into
mainfrom
unattended-upgrades
Oct 9, 2026
Merged

claytono merged 1 commit into
mainfrom
unattended-upgrades

Conversation

@claytono

@claytono claytono commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

The Kubernetes nodes never installed updates on their own. apt's daily timers ran, but the installer had preset automatic upgrades off, so security fixes waited for a manual dist-upgrade. This adds an unattended_upgrades role for k1-k5 that installs Debian's security updates and stable point releases each morning and never reboots; reboots are left to Kured later.

The role writes its own apt.conf.d file instead of editing the package's ucf-managed ones, and sets the APT::Periodic keys itself so it does not depend on how the installer answered.

k4 and k5 install updates as soon as they appear. k1, k2 and k3 read Debian's main archive from snapshot.debian.org as it was seven days earlier, so a bad point release reaches the canaries a week before the control plane and the GPU node. Security updates stay live everywhere. A script run before each apt-daily update advances the snapshot, and saves the new ID only once every list for it has downloaded, since the ID is part of each source URL. trixie-updates' Release file expires seven days after publication, so validity is extended for the Debian label alone. A delayed host takes its first snapshot before the periodic settings are written, so a failure there leaves it without automatic upgrades rather than on live ones.

apt_info.py from node-exporter-textfile-collector-scripts exports apt metrics through node_exporter. It is vendored unmodified, so the ruff hooks skip it. Its timer runs as node_exporter, which owns the textfile directory, so the root account never writes into a path another account controls. New alerts cover Debian upgrades pending for more than 10 days, package lists more than 3 days old for a full day (so a newly set up host, whose lists report a zero timestamp until its first daily refresh, does not alert), and a reboot pending for more than 10 days. Failed runs are mailed to root.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T15:49:46.861247Z 6f48d0d New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4183fd7c-760d-4a12-b94c-2e72f0f90146

📥 Commits

Reviewing files that changed from the base of the PR and between 466ae92 and 6f48d0d.


📒 Files selected for processing (1)
  • ansible/roles/unattended_upgrades/templates/apt-info-textfile.service.j2

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.



Walkthrough

The change adds an Ansible role for unattended upgrades and optional APT snapshots. When node exporter is enabled, the role publishes APT metrics. Prometheus rules alert on pending upgrades, stale package lists, and required reboots.

Changes

APT upgrades and monitoring

Layer / File(s) Summary
Configure unattended upgrades and snapshots
ansible/roles/unattended_upgrades/defaults/main.yaml, ansible/host_vars/k*.yaml, ansible/site.yaml, ansible/roles/unattended_upgrades/tasks/main.yaml, ansible/roles/unattended_upgrades/templates/apt-snapshot-advance.j2, ansible/roles/unattended_upgrades/templates/52unattended-upgrades-local.j2, ansible/roles/unattended_upgrades/handlers/main.yaml
The role installs and configures unattended upgrades for Kubernetes hosts. Positive snapshot delays install and run a snapshot-advance script before apt-daily; zero or negative delays remove the snapshot configuration, systemd drop-in, and script.
Publish APT metrics
ansible/roles/unattended_upgrades/tasks/main.yaml, ansible/roles/unattended_upgrades/files/apt_info.py, ansible/roles/unattended_upgrades/templates/apt-info-textfile.service.j2, ansible/roles/unattended_upgrades/templates/apt-info-textfile.timer.j2, .pre-commit-config.yaml
When node exporter is enabled, the role installs the exporter and configures a systemd timer and service to write metrics to the textfile collector. The Ruff hooks exclude the vendored exporter file.
Alert on APT metrics
kubernetes/prometheus/config/rules.yml
Prometheus rules alert on pending Debian-origin upgrades, package-list timestamps older than three days, and reboot-required status lasting 10 days.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant AptTimer as apt-info timer
  participant AptService as apt-info service
  participant AptInfo as apt_info.py
  participant Textfile as node_exporter textfile collector
  AptTimer->>AptService: Start on schedule
  AptService->>AptInfo: Run exporter
  AptInfo->>AptService: Return metrics
  AptService->>Textfile: Write apt.prom after success
Loading

Merge Risk: ⚪ Minimal · up to 6f48d

No actionable merge-blocking issue is established for the APT metrics service.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 1 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description clearly explains the unattended-upgrades role, snapshot behavior, metrics, alerts, and target Kubernetes nodes. It directly matches the changeset.
Title check Passed The title clearly and concisely describes the main change: enabling unattended upgrades on Kubernetes nodes.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 1 files. (1 skipped: 1 unsupported.)



  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR


  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ba2acc0d68

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ansible/roles/unattended_upgrades/templates/apt-snapshot-advance.j2 Outdated
@claytono
claytono force-pushed the unattended-upgrades branch from ba2acc0 to 80fb01c Compare October 9, 2026 01:42

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 80fb01c6fe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ansible/roles/unattended_upgrades/files/apt_info.py
@claytono
claytono force-pushed the unattended-upgrades branch from 80fb01c to 466ae92 Compare October 9, 2026 14:40

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 466ae925de

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread kubernetes/prometheus/config/rules.yml
@claytono
claytono force-pushed the unattended-upgrades branch from 466ae92 to e836664 Compare October 9, 2026 15:32

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e836664413

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ansible/roles/unattended_upgrades/templates/apt-snapshot-advance.j2
Comment thread ansible/roles/unattended_upgrades/files/apt_info.py
The Kubernetes nodes never installed updates on their own. apt's daily
timers ran, but the installer had preset automatic upgrades off, so
security fixes waited for a manual dist-upgrade. This adds an
unattended_upgrades role for k1-k5 that installs Debian's security
updates and stable point releases each morning and never reboots;
reboots are left to Kured later.

The role writes its own apt.conf.d file instead of editing the
package's ucf-managed ones, and sets the APT::Periodic keys itself so
it does not depend on how the installer answered.

k4 and k5 install updates as soon as they appear. k1, k2 and k3 read
Debian's main archive from snapshot.debian.org as it was seven days
earlier, so a bad point release reaches the canaries a week before the
control plane and the GPU node. Security updates stay live everywhere. A
script run before each apt-daily update advances the snapshot, and saves
the new ID only once every list for it has downloaded, since the ID is
part of each source URL. trixie-updates' Release file expires seven days
after publication, so validity is extended for the Debian label alone. A
delayed host takes its first snapshot before the periodic settings are
written, so a failure there leaves it without automatic upgrades rather
than on live ones.

apt_info.py from node-exporter-textfile-collector-scripts exports apt
metrics through node_exporter. It is vendored unmodified, so the ruff
hooks skip it. Its timer runs as node_exporter, which owns the textfile
directory, so the root account never writes into a path another account
controls. New alerts cover Debian upgrades pending for more than 10
days, package lists more than 3 days old for a full day (so a newly set
up host, whose lists report a zero timestamp until its first daily
refresh, does not alert), and a reboot pending for more than 10 days.
Failed runs are mailed to root.
@claytono
claytono force-pushed the unattended-upgrades branch from e836664 to 6f48d0d Compare October 9, 2026 15:47
@claytono
claytono merged commit 4a5fb09 into main Oct 9, 2026
17 checks passed
@claytono
claytono deleted the unattended-upgrades branch October 9, 2026 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant