From f08ddab0dfd2978136b311e2ed368e6b380899ca Mon Sep 17 00:00:00 2001 From: Brian Fjeldstad Date: Fri, 30 Oct 2026 21:32:36 +0000 Subject: [PATCH 1/6] fix(acl): wait for Node registration before starting TAA Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 84294fd5-1096-4b5a-a33e-b5d4730445e3 --- .../acl/trident-acl-agent-override.conf | 20 +++++++ .../artifacts/trident_acl_agent_spec.sh | 55 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100755 spec/parts/linux/cloud-init/artifacts/trident_acl_agent_spec.sh diff --git a/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf b/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf index 0f5daca5659..69e5d5b4539 100644 --- a/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf +++ b/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf @@ -42,3 +42,23 @@ ExecStartPre=-/usr/bin/sh -c '\ for p in /var/lib/kubelet/kubeconfig /run/trident/trident.sock; do \ [ -e "$p" ] && echo "trident-acl-agent preflight: present $p" || echo "trident-acl-agent preflight: MISSING $p"; \ done' + +# A kubeconfig can exist before its Node. Require two successful checks a +# second apart before starting older agents that exit on a missing Node. +TimeoutStartSec=400s +ExecStartPre=/usr/bin/sh -c '\ +node="$$(hostname)"; \ +node_seen=false; \ +for i in $$(seq 1 60); do \ + if /opt/bin/kubectl --kubeconfig /var/lib/kubelet/kubeconfig --request-timeout=5s get node "$$node" >/dev/null 2>&1; then \ + if [ "$$node_seen" = true ]; then \ + echo "trident-acl-agent preflight: Node $$node registered after $$i check(s)"; exit 0; \ + fi; \ + node_seen=true; \ + else \ + node_seen=false; \ + fi; \ + sleep 1; \ +done; \ +echo "trident-acl-agent preflight: Node $$node not consistently available after 60 checks" >&2; \ +exit 1' diff --git a/spec/parts/linux/cloud-init/artifacts/trident_acl_agent_spec.sh b/spec/parts/linux/cloud-init/artifacts/trident_acl_agent_spec.sh new file mode 100755 index 00000000000..dc091de995d --- /dev/null +++ b/spec/parts/linux/cloud-init/artifacts/trident_acl_agent_spec.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# shellcheck disable=SC2016,SC2034 + +Describe 'Trident ACL Agent Node preflight' + run_preflight() ( + checks=0 + hostname() { printf '%s\n' test-node; } + sleep() { :; } + kubectl() { + checks=$((checks + 1)) + case "$1" in + --kubeconfig) ;; + *) return 2 ;; + esac + case "$availability" in + registered) return 0 ;; + delayed) [ "$checks" -gt 3 ] ;; + interrupted) [ "$checks" -ne 2 ] ;; + absent) return 1 ;; + esac + } + script="$(sed -n '/^ExecStartPre=\/usr\/bin\/sh -c /,$p' \ + parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf | + sed '1d; $s/'\''$//; s/\\$//; s/\$\$/\$/g; s|/opt/bin/kubectl|kubectl|g')" + eval "$script" + ) + + It 'requires two successful checks for an existing Node' + availability=registered + When run run_preflight + The status should be success + The output should eq 'trident-acl-agent preflight: Node test-node registered after 2 check(s)' + End + + It 'waits for delayed registration' + availability=delayed + When run run_preflight + The status should be success + The output should eq 'trident-acl-agent preflight: Node test-node registered after 5 check(s)' + End + + It 'requires consecutive successes after an interrupted check' + availability=interrupted + When run run_preflight + The status should be success + The output should eq 'trident-acl-agent preflight: Node test-node registered after 4 check(s)' + End + + It 'fails instead of starting the agent when the Node remains unavailable' + availability=absent + When run run_preflight + The status should be failure + The stderr should eq 'trident-acl-agent preflight: Node test-node not consistently available after 60 checks' + End +End From 85740f03b64f9bdf22e5219bf2fdc82e14d65e80 Mon Sep 17 00:00:00 2001 From: Brian Fjeldstad Date: Fri, 30 Oct 2026 21:36:24 +0000 Subject: [PATCH 2/6] test(acl): remove Node preflight spec Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 84294fd5-1096-4b5a-a33e-b5d4730445e3 --- .../artifacts/trident_acl_agent_spec.sh | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100755 spec/parts/linux/cloud-init/artifacts/trident_acl_agent_spec.sh diff --git a/spec/parts/linux/cloud-init/artifacts/trident_acl_agent_spec.sh b/spec/parts/linux/cloud-init/artifacts/trident_acl_agent_spec.sh deleted file mode 100755 index dc091de995d..00000000000 --- a/spec/parts/linux/cloud-init/artifacts/trident_acl_agent_spec.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC2016,SC2034 - -Describe 'Trident ACL Agent Node preflight' - run_preflight() ( - checks=0 - hostname() { printf '%s\n' test-node; } - sleep() { :; } - kubectl() { - checks=$((checks + 1)) - case "$1" in - --kubeconfig) ;; - *) return 2 ;; - esac - case "$availability" in - registered) return 0 ;; - delayed) [ "$checks" -gt 3 ] ;; - interrupted) [ "$checks" -ne 2 ] ;; - absent) return 1 ;; - esac - } - script="$(sed -n '/^ExecStartPre=\/usr\/bin\/sh -c /,$p' \ - parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf | - sed '1d; $s/'\''$//; s/\\$//; s/\$\$/\$/g; s|/opt/bin/kubectl|kubectl|g')" - eval "$script" - ) - - It 'requires two successful checks for an existing Node' - availability=registered - When run run_preflight - The status should be success - The output should eq 'trident-acl-agent preflight: Node test-node registered after 2 check(s)' - End - - It 'waits for delayed registration' - availability=delayed - When run run_preflight - The status should be success - The output should eq 'trident-acl-agent preflight: Node test-node registered after 5 check(s)' - End - - It 'requires consecutive successes after an interrupted check' - availability=interrupted - When run run_preflight - The status should be success - The output should eq 'trident-acl-agent preflight: Node test-node registered after 4 check(s)' - End - - It 'fails instead of starting the agent when the Node remains unavailable' - availability=absent - When run run_preflight - The status should be failure - The stderr should eq 'trident-acl-agent preflight: Node test-node not consistently available after 60 checks' - End -End From 86ecad24096927808fc0a7f61dd7db9f4c8fe6b6 Mon Sep 17 00:00:00 2001 From: Brian Fjeldstad Date: Fri, 30 Oct 2026 21:38:05 +0000 Subject: [PATCH 3/6] docs(acl): simplify TAA preflight comment Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 84294fd5-1096-4b5a-a33e-b5d4730445e3 --- .../cloud-init/artifacts/acl/trident-acl-agent-override.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf b/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf index 69e5d5b4539..68b90153c7a 100644 --- a/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf +++ b/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf @@ -44,7 +44,7 @@ for p in /var/lib/kubelet/kubeconfig /run/trident/trident.sock; do \ done' # A kubeconfig can exist before its Node. Require two successful checks a -# second apart before starting older agents that exit on a missing Node. +# second apart before starting trident-acl-agent. TimeoutStartSec=400s ExecStartPre=/usr/bin/sh -c '\ node="$$(hostname)"; \ From 59bd8cee1853c57976ee958e7780fb917d8c3751 Mon Sep 17 00:00:00 2001 From: Brian Fjeldstad Date: Fri, 30 Oct 2026 22:15:56 +0000 Subject: [PATCH 4/6] fix(acl): lowercase the Node preflight hostname Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 84294fd5-1096-4b5a-a33e-b5d4730445e3 --- .../cloud-init/artifacts/acl/trident-acl-agent-override.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf b/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf index 68b90153c7a..f50e7e89483 100644 --- a/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf +++ b/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf @@ -47,7 +47,7 @@ done' # second apart before starting trident-acl-agent. TimeoutStartSec=400s ExecStartPre=/usr/bin/sh -c '\ -node="$$(hostname)"; \ +node="$$(hostname | tr "[:upper:]" "[:lower:]")"; \ node_seen=false; \ for i in $$(seq 1 60); do \ if /opt/bin/kubectl --kubeconfig /var/lib/kubelet/kubeconfig --request-timeout=5s get node "$$node" >/dev/null 2>&1; then \ From 9afb465d544c71856997dfdb284cacde1fa2955b Mon Sep 17 00:00:00 2001 From: Brian Fjeldstad Date: Mon, 2 Nov 2026 17:30:58 +0000 Subject: [PATCH 5/6] fix(acl): wait for local kubelet TLS bootstrap Replace Node API polling with kubeconfig and valid client-certificate symlink checks. Keep the 60-check bound and allow 90 seconds for startup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7e4e6982-b33d-4adb-bfa0-a86447c2f3f2 --- .../acl/trident-acl-agent-override.conf | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf b/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf index f50e7e89483..15565b14f8e 100644 --- a/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf +++ b/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf @@ -43,22 +43,15 @@ for p in /var/lib/kubelet/kubeconfig /run/trident/trident.sock; do \ [ -e "$p" ] && echo "trident-acl-agent preflight: present $p" || echo "trident-acl-agent preflight: MISSING $p"; \ done' -# A kubeconfig can exist before its Node. Require two successful checks a -# second apart before starting trident-acl-agent. -TimeoutStartSec=400s +# Wait for kubelet TLS bootstrapping without polling the API server. +TimeoutStartSec=90s ExecStartPre=/usr/bin/sh -c '\ -node="$$(hostname | tr "[:upper:]" "[:lower:]")"; \ -node_seen=false; \ +cert=/var/lib/kubelet/pki/kubelet-client-current.pem; \ for i in $$(seq 1 60); do \ - if /opt/bin/kubectl --kubeconfig /var/lib/kubelet/kubeconfig --request-timeout=5s get node "$$node" >/dev/null 2>&1; then \ - if [ "$$node_seen" = true ]; then \ - echo "trident-acl-agent preflight: Node $$node registered after $$i check(s)"; exit 0; \ - fi; \ - node_seen=true; \ - else \ - node_seen=false; \ + if [ -f /var/lib/kubelet/kubeconfig ] && [ -L "$$cert" ] && [ -f "$$cert" ]; then \ + echo "trident-acl-agent preflight: kubelet TLS bootstrapping complete after $$i check(s)"; exit 0; \ fi; \ sleep 1; \ done; \ -echo "trident-acl-agent preflight: Node $$node not consistently available after 60 checks" >&2; \ +echo "trident-acl-agent preflight: kubelet TLS bootstrapping incomplete after 60 checks" >&2; \ exit 1' From fd3ca08db8e45ad6f91114582ca021e266108e58 Mon Sep 17 00:00:00 2001 From: Brian Fjeldstad Date: Mon, 2 Nov 2026 19:49:15 +0000 Subject: [PATCH 6/6] fix(acl): confirm Node registration after kubelet bootstrap Wait for the current boot kubelet registration log, pause one second, then confirm the Node with a single bounded GET. Keep the existing preflights and allow 150 seconds for startup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7e4e6982-b33d-4adb-bfa0-a86447c2f3f2 --- .../artifacts/acl/trident-acl-agent-override.conf | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf b/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf index 15565b14f8e..6db0d7d8d83 100644 --- a/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf +++ b/parts/linux/cloud-init/artifacts/acl/trident-acl-agent-override.conf @@ -44,7 +44,7 @@ for p in /var/lib/kubelet/kubeconfig /run/trident/trident.sock; do \ done' # Wait for kubelet TLS bootstrapping without polling the API server. -TimeoutStartSec=90s +TimeoutStartSec=150s ExecStartPre=/usr/bin/sh -c '\ cert=/var/lib/kubelet/pki/kubelet-client-current.pem; \ for i in $$(seq 1 60); do \ @@ -55,3 +55,16 @@ for i in $$(seq 1 60); do \ done; \ echo "trident-acl-agent preflight: kubelet TLS bootstrapping incomplete after 60 checks" >&2; \ exit 1' + +# TLS bootstrapping can finish before Node registration. Wait locally, then +# confirm the Node exists with one API request. +ExecStartPre=/usr/bin/timeout 60s /usr/bin/sh -ec '\ +until journalctl -b -u kubelet.service --no-pager -q -o cat \ + --grep="Successfully registered node" -n 1 | grep -q .; do \ + sleep 1; \ +done; \ +sleep 1; \ +node="$$(hostname | tr "[:upper:]" "[:lower:]")"; \ +/opt/bin/kubectl --kubeconfig /var/lib/kubelet/kubeconfig \ + --request-timeout=5s get node "$$node" >/dev/null; \ +echo "trident-acl-agent preflight: Node $$node registration confirmed"'