Skip to content

linode: attribute NodeBalancers by lke<id> label; tag volumes before every cluster delete - #1296

Merged
travagliad merged 3 commits into
mainfrom
claude/pmm-qa-hooks-permissions-verify-pt9u2v
Sep 2, 2026
Merged

linode: attribute NodeBalancers by lke<id> label; tag volumes before every cluster delete#1296
travagliad merged 3 commits into
mainfrom
claude/pmm-qa-hooks-permissions-verify-pt9u2v

Conversation

@travagliad

Copy link
Copy Markdown
Contributor

Problem

Follow-up to #1287. Auditing the live Linode account ~24h after that PR shipped turned up teardown leaks it still could not clean: 3 orphaned NodeBalancers and 32 orphaned Block Storage volumes the reaper was running past every 15 min but never deleting. Two distinct gaps in the positive-attribution model:

  1. NodeBalancers were attributed by a tag the CCM strips. create-lke stamped each cluster's NodeBalancer with its pmm-qa-run:<id> tag, but the Linode CCM reconciles a NodeBalancer's tags back to its defaults (["kubernetes"]) shortly after. So by teardown the tag is gone and prune-lke-orphans.sh matched no NodeBalancer, ever. (Confirmed on a torn-down test cluster whose NodeBalancer still existed 24h later with only ["kubernetes"].) This also means linode: delete orphaned account tags, volumes, and NodeBalancers on teardown #1287's teardown verification passed falsely — it checked immediately, before the CCM had stripped the tag.

  2. Volumes created after provisioning were never tagged. The provision-time pass only tags volumes attached when create-lke exits. A cluster grows PVCs afterwards (a scaled StatefulSet, backups), and those later volumes leaked untagged. Clusters provisioned before linode: delete orphaned account tags, volumes, and NodeBalancers on teardown #1287 (or before the token had Volumes R/W) are untagged entirely.

The 32 orphaned volumes were all from two clusters provisioned/destroyed a day before #1287 deployed — pure pre-fix backlog, cleared by hand.

Changes

  • prune-lke-orphans.sh — attribute NodeBalancers by their immutable lke<clusterid>- label (baked in by the CCM) instead of a tag. Delete one only when its cluster id is no longer in the live cluster list. Volume attribution (by pmm-qa-run: tag whose run has no live cluster) is unchanged.
  • tag-lke-resources.sh (new, shared) — tags a cluster's currently-attached volumes with its pmm-qa-run:<id>. Resolves the run from the cluster's own tag/label when the caller only knows the cluster id. NodeBalancers are deliberately not tagged (see above).
  • destroy-lke.sh and the relay reaper (relay.js) — call tag-lke-resources.sh right before deleting the cluster, while the nodes (and volume attachments) still exist, so post-provision and pre-fix volumes are attributed too.
  • create-lke-pmm-ha.sh — its EXIT-trap tagging now delegates to the shared script (no behaviour change).
  • SKILL.md — documents label-based NodeBalancer attribution and tag-before-delete.

Validation

  • shellcheck -S warning clean on all four scripts; node --check on relay.js.
  • Unit-tested the label→cluster-id parse and the keep-live/delete decision on sample data.
  • Live account audit drove the diagnosis: reaper confirmed running the merged code and sweeping every tick; live cluster PMM-13860 had 16/16 volumes correctly tagged (so volume tagging works and is durable), while the orphans carried no usable attribution.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DBhvZuEUQU8ym347Xat4Yy


Generated by Claude Code

…every delete

Follow-up to #1287. Two teardown-leak paths survived that PR, found by auditing
the live account 24h after deploy: 3 orphaned NodeBalancers and 32 orphaned
volumes the reaper could not attribute.

- NodeBalancers: the Linode CCM reconciles a NodeBalancer's tags back to its
  defaults, so the pmm-qa-run tag create-lke stamped on it does not survive --
  the sweep never matched any NodeBalancer. Attribute by the immutable
  lke<clusterid>- label instead (the CCM bakes the cluster id into it); delete
  one only when its cluster is no longer live.

- Volumes: provision-time tagging only covers volumes attached when create-lke
  exits. Clusters grow PVCs afterwards (scaled StatefulSet, backups), and those
  leak untagged. Tag the cluster's attached volumes again right before every
  cluster delete (destroy-lke and the reaper), while the nodes still exist, via
  a shared tag-lke-resources.sh -- also covers clusters provisioned before
  volume tagging shipped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DBhvZuEUQU8ym347Xat4Yy
@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 49 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: e6f36554-46a2-4143-b2d0-9407741f69d7

📥 Commits

Reviewing files that changed from the base of the PR and between d2d70d3 and 7929b47.

📒 Files selected for processing (4)
  • .claude/integrations/slack/relay/relay.js
  • .claude/skills/linode-ha-provisioning/scripts/destroy-lke.sh
  • .claude/skills/linode-ha-provisioning/scripts/prune-lke-orphans.sh
  • .claude/skills/linode-ha-provisioning/scripts/tag-lke-resources.sh

Walkthrough

The change adds tag-lke-resources.sh to tag attached cluster volumes. Provisioning, explicit destruction, and the Slack reaper invoke it before cluster deletion. Tagging failures do not stop deletion. Orphan pruning now attributes NodeBalancers by their immutable lke<clusterid>- labels and compares those IDs with live clusters. The provisioning documentation describes the updated volume and NodeBalancer attribution rules.

Merge Risk: 🟡 Moderate · up to d2d70

The volume-tagging change can miss volumes beyond the first API page and can remove unrelated volume tags, causing cleanup failures and metadata loss. These bounded correctness issues should be fixed before merging.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the two primary changes: label-based NodeBalancer attribution and volume tagging before cluster deletion.
Description check ✅ Passed The description directly explains the teardown leaks, the attribution changes, the new tagging utility, the affected scripts, and the validation performed.
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.

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: fb34483b-31d1-4c8b-bf8c-2d1fa9bf20ec

📥 Commits

Reviewing files that changed from the base of the PR and between 30eaf90 and d2d70d3.

📒 Files selected for processing (6)
  • .claude/integrations/slack/relay/relay.js
  • .claude/skills/linode-ha-provisioning/SKILL.md
  • .claude/skills/linode-ha-provisioning/scripts/create-lke-pmm-ha.sh
  • .claude/skills/linode-ha-provisioning/scripts/destroy-lke.sh
  • .claude/skills/linode-ha-provisioning/scripts/prune-lke-orphans.sh
  • .claude/skills/linode-ha-provisioning/scripts/tag-lke-resources.sh
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • percona/pmm-qa (manual)
  • percona/pmm (manual)

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

Comment thread .claude/skills/linode-ha-provisioning/scripts/tag-lke-resources.sh Outdated
Comment thread .claude/skills/linode-ha-provisioning/scripts/tag-lke-resources.sh Outdated
…sources

Address CodeRabbit review on #1296:
- Page through /volumes instead of reading only the first page, so a cluster's
  volumes are still found when the account holds more than one page.
- Merge our tags with each volume's existing tags (PUT replaces the whole list)
  so unrelated tags are not dropped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DBhvZuEUQU8ym347Xat4Yy
Comment thread .claude/skills/linode-ha-provisioning/scripts/prune-lke-orphans.sh
Comment thread .claude/skills/linode-ha-provisioning/scripts/tag-lke-resources.sh Outdated
Comment thread .claude/integrations/slack/relay/relay.js Outdated
Comment thread .claude/skills/linode-ha-provisioning/scripts/destroy-lke.sh Outdated
Comment thread .claude/skills/linode-ha-provisioning/scripts/prune-lke-orphans.sh Outdated
Comment thread .claude/skills/linode-ha-provisioning/scripts/tag-lke-resources.sh Outdated
@claude

claude Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Gate gap, for the record: the only check that touched this diff is Lint (shellcheck -S warning, green on d2d70d3) — relay.js has no eslint/type gate in lint-changed.sh, and no workflow exercises the Linode teardown scripts, so the NodeBalancer-label attribution and the tag-before-delete ordering rest entirely on the manual account audit in the body. The e2e checks on the head SHA are still queued/in-progress, and none of them cover these paths anyway. .claude/** also has no suite reference in the review skill, so only the generic checks were applied here.

…comments

Address review on #1296:
- prune-lke-orphans.sh: gate NodeBalancer deletion on the NB being idle (no
  backend node up) in addition to its lke<id> cluster being gone. The CCM lets a
  live cluster adopt another cluster's NodeBalancer (keeping the original cluster
  id in its label), so a label-only rule could delete a live cluster's load
  balancer. An orphan has zero backends up once its cluster is gone; a reused or
  still-serving NB does not. Fail safe: keep the NB if its configs are unreadable.
- Trim duplicated/inaccurate header and call-site comments across
  tag-lke-resources.sh, destroy-lke.sh, and relay.js.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DBhvZuEUQU8ym347Xat4Yy
@travagliad
travagliad merged commit 2e1c4ec into main Sep 2, 2026
37 checks passed
@travagliad
travagliad deleted the claude/pmm-qa-hooks-permissions-verify-pt9u2v branch September 2, 2026 17:14
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.

3 participants