Skip to content

feat: support localdns hosts plugin refresh override#8895

Open
saewoni wants to merge 2 commits into
mainfrom
sakwa/localdns-hosts-plugin-refresh-interval
Open

feat: support localdns hosts plugin refresh override#8895
saewoni wants to merge 2 commits into
mainfrom
sakwa/localdns-hosts-plugin-refresh-interval

Conversation

@saewoni

@saewoni saewoni commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

This change lets AgentBaker carry a LocalDNS hosts plugin refresh interval from node bootstrapping config down to provisioning, instead of relying on the hardcoded 15 minute timer cadence.

It adds the new LocalDNS field to the datamodel and aks-node-controller proto/parser paths, emits the value into both legacy CSE and scriptless env, and updates cse_config.sh to rewrite aks-localdns-hosts-setup.timer when a positive interval is provided. When the field is unset or invalid, provisioning keeps the existing default behavior.

This complements the corresponding AKS-RP change in PR 16401188.

Validation run:

  • make validate-shell
  • docker run --rm -v /home/sakwa/AgentBaker:/workspace -w /workspace shellspec-docker --shell bash --format d spec/parts/linux/cloud-init/artifacts/cse_config_spec.sh
  • go test ./pkg/agent/...
  • cd aks-node-controller && go test ./parser
  • ./hack/tools/bin/golangci-lint run ./pkg/agent/...
  • cd aks-node-controller && ../hack/tools/bin/golangci-lint run ./parser/...

Which issue(s) this PR fixes:

Fixes #

@github-actions

github-actions Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

The latest Buf updates on your PR. Results from workflow Buf CI / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedJul 13, 2026, 6:08 PM

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for configuring the AKS LocalDNS hosts plugin refresh interval end-to-end (datamodel → template/provisioning env → CSE behavior), replacing reliance on the fixed 15-minute systemd timer cadence when an explicit positive interval is provided.

Changes:

  • Extend the AgentBaker datamodel and template func map to carry hostsPluginRefreshIntervalInSeconds into provisioning.
  • Extend aks-node-controller proto + parser to emit LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS for scriptless provisioning.
  • Update Linux CSE (cse_config.sh) to rewrite aks-localdns-hosts-setup.timer OnUnitActiveSec when a valid positive interval is provided, with new/updated tests.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
spec/parts/linux/cloud-init/artifacts/cse_config_spec.sh Adds ShellSpec coverage for timer interval override behavior.
pkg/agent/datamodel/types.go Adds HostsPluginRefreshIntervalInSeconds to LocalDNSProfile JSON schema.
pkg/agent/baker.go Adds template function to render refresh interval into CSE templates.
pkg/agent/baker_test.go Unit tests for the new template function behavior (nil/invalid/valid).
parts/linux/cloud-init/artifacts/cse_config.sh Applies the provided interval by editing the systemd timer before enabling it.
parts/linux/cloud-init/artifacts/cse_cmd.sh Emits the new refresh interval env var for legacy CSE flow.
aks-node-controller/proto/aksnodeconfig/v1/localdns_config.proto Adds optional refresh interval field to LocalDNS proto.
aks-node-controller/pkg/gen/aksnodeconfig/v1/localdns_config.pb.go Regenerates protobuf bindings for the new field.
aks-node-controller/parser/parser.go Exposes the new interval as a CSE env var in scriptless mode.
aks-node-controller/parser/parser_test.go Validates env var emission in integration-style parser tests.
aks-node-controller/parser/helper.go Adds helper to stringify/validate refresh interval from proto config.
aks-node-controller/parser/helper_test.go Unit tests for the new helper’s nil/invalid/valid cases.
Files not reviewed (1)
  • aks-node-controller/pkg/gen/aksnodeconfig/v1/localdns_config.pb.go: Generated file

Copilot AI review requested due to automatic review settings July 11, 2026 06:53
@saewoni saewoni force-pushed the sakwa/localdns-hosts-plugin-refresh-interval branch from 38e6e82 to d03db7d Compare July 11, 2026 06:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • aks-node-controller/pkg/gen/aksnodeconfig/v1/localdns_config.pb.go: Generated file

;;
*)
if [ "${hosts_plugin_refresh_interval}" -gt 0 ]; then
sed -i "s/^OnUnitActiveSec=.*/OnUnitActiveSec=${hosts_plugin_refresh_interval}s/" "${hosts_setup_timer}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems very hacky. I would think that there would be some form of timer.template and then you render it either on agentbaker side or aks-node-controller side?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in commit 8366dcd.

Instead of rewriting the shipped timer unit in place, the refresh override now uses a systemd drop-in:

local hosts_plugin_refresh_interval="${LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS:-}"
local hosts_setup_timer_override="${hosts_setup_timer}.d/10-refresh-interval.conf"
local min_hosts_plugin_refresh_interval_in_seconds=5
if [ -z "${hosts_plugin_refresh_interval}" ]; then
removeAKSLocalDNSHostsSetupTimerOverride "${hosts_setup_timer_override}"
else
local should_override_refresh_interval="false"
case "${hosts_plugin_refresh_interval}" in
*[!0-9]*)
;;
*)
if [ "${hosts_plugin_refresh_interval}" -ge "${min_hosts_plugin_refresh_interval_in_seconds}" ]; then
should_override_refresh_interval="true"
fi
;;
esac
if [ "${should_override_refresh_interval}" = "true" ]; then
mkdir -p "$(dirname "${hosts_setup_timer_override}")"
cat > "${hosts_setup_timer_override}" <<EOF
[Timer]
OnUnitActiveSec=${hosts_plugin_refresh_interval}s
AccuracySec=1s
EOF

The base timer file stays generic/default-only here:

# Default refresh cadence. Provisioning may override this with a systemd drop-in
# when LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS is set. 15 minutes
# balances freshness against unnecessary DNS traffic — stale IPs would cause the
# hosts plugin to serve unreachable addresses until the next refresh.
OnUnitActiveSec=15min
# Default timer accuracy. Provisioning may lower this for shorter cadences.
AccuracySec=1min

@yewmsft yewmsft left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nice, right direction — configurable over the hardcoded 15min, additive optional field, empty preserves default. one blocking thing (AccuracySec, else sub-minute intervals silently don't fire) + a few asks inline.

;;
*)
if [ "${hosts_plugin_refresh_interval}" -gt 0 ]; then
sed -i "s/^OnUnitActiveSec=.*/OnUnitActiveSec=${hosts_plugin_refresh_interval}s/" "${hosts_setup_timer}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this only rewrites OnUnitActiveSec, but the shipped aks-localdns-hosts-setup.timer also has AccuracySec=1min. systemd won't fire more accurately than the accuracy window, so OnUnitActiveSec=5s gets coalesced to ~1min — sub-minute cadence won't actually happen. RP (16401188) is passing seconds, so this silently won't deliver. need to drop AccuracySec too:

sed -i "s/^AccuracySec=.*/AccuracySec=1s/" "${hosts_setup_timer}"

did you verify on a real node that a small value actually fires at that cadence? i don't think it does as-is.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in commit 8366dcd.

The override now uses a systemd drop-in and sets both OnUnitActiveSec and AccuracySec=1s here:

local hosts_plugin_refresh_interval="${LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS:-}"
local hosts_setup_timer_override="${hosts_setup_timer}.d/10-refresh-interval.conf"
local min_hosts_plugin_refresh_interval_in_seconds=5
if [ -z "${hosts_plugin_refresh_interval}" ]; then
removeAKSLocalDNSHostsSetupTimerOverride "${hosts_setup_timer_override}"
else
local should_override_refresh_interval="false"
case "${hosts_plugin_refresh_interval}" in
*[!0-9]*)
;;
*)
if [ "${hosts_plugin_refresh_interval}" -ge "${min_hosts_plugin_refresh_interval_in_seconds}" ]; then
should_override_refresh_interval="true"
fi
;;
esac
if [ "${should_override_refresh_interval}" = "true" ]; then
mkdir -p "$(dirname "${hosts_setup_timer_override}")"
cat > "${hosts_setup_timer_override}" <<EOF
[Timer]
OnUnitActiveSec=${hosts_plugin_refresh_interval}s
AccuracySec=1s
EOF

ShellSpec coverage for the generated override is here:

It 'should update the timer refresh interval when provided'
LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS="30"
When call enableAKSLocalDNSHostsSetup
The status should be success
The output should include "Configured aks-localdns-hosts-setup timer refresh interval to 30s."
The output should include "systemctl daemon-reload"
The contents of file "${AKS_LOCALDNS_HOSTS_SETUP_TIMER}.d/10-refresh-interval.conf" should include "OnUnitActiveSec=30s"
The contents of file "${AKS_LOCALDNS_HOSTS_SETUP_TIMER}.d/10-refresh-interval.conf" should include "AccuracySec=1s"
The contents of file "$AKS_LOCALDNS_HOSTS_SETUP_TIMER" should include "OnUnitActiveSec=15min"

I did not run a live-node cadence check in this branch; the validation here was ShellSpec/shellcheck rather than a real node.

echo "Warning: LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS must be a positive integer, got '${hosts_plugin_refresh_interval}'. Using default timer interval."
;;
*)
if [ "${hosts_plugin_refresh_interval}" -gt 0 ]; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is the only bound — RP validates >0, so 1 is legal and would hit live DNS every second on every localdns node. do we want a floor? at least call out a sane min.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in commit 8366dcd.

Added a 5s floor here:

local hosts_plugin_refresh_interval="${LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS:-}"
local hosts_setup_timer_override="${hosts_setup_timer}.d/10-refresh-interval.conf"
local min_hosts_plugin_refresh_interval_in_seconds=5
if [ -z "${hosts_plugin_refresh_interval}" ]; then
removeAKSLocalDNSHostsSetupTimerOverride "${hosts_setup_timer_override}"
else
local should_override_refresh_interval="false"
case "${hosts_plugin_refresh_interval}" in
*[!0-9]*)
;;
*)
if [ "${hosts_plugin_refresh_interval}" -ge "${min_hosts_plugin_refresh_interval_in_seconds}" ]; then
should_override_refresh_interval="true"
fi
;;
esac
if [ "${should_override_refresh_interval}" = "true" ]; then
mkdir -p "$(dirname "${hosts_setup_timer_override}")"
cat > "${hosts_setup_timer_override}" <<EOF
[Timer]
OnUnitActiveSec=${hosts_plugin_refresh_interval}s
AccuracySec=1s
EOF
chmod 0644 "${hosts_setup_timer_override}"
if grep -q "^OnUnitActiveSec=${hosts_plugin_refresh_interval}s$" "${hosts_setup_timer_override}" &&
grep -q "^AccuracySec=1s$" "${hosts_setup_timer_override}"; then
if systemctl daemon-reload; then
echo "Configured aks-localdns-hosts-setup timer refresh interval to ${hosts_plugin_refresh_interval}s."
else
echo "Warning: Failed to reload systemd after updating ${hosts_setup_timer_override}"
fi
else
echo "Warning: Failed to update ${hosts_setup_timer_override} with refresh interval ${hosts_plugin_refresh_interval}s"
fi
else
echo "Warning: LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS must be an integer >= ${min_hosts_plugin_refresh_interval_in_seconds}, got '${hosts_plugin_refresh_interval}'. Using default timer interval."
removeAKSLocalDNSHostsSetupTimerOverride "${hosts_setup_timer_override}"

Comment thread aks-node-controller/parser/helper.go Outdated
// getLocalDnsHostsPluginRefreshIntervalInSeconds returns the refresh interval in seconds
// for the LocalDNS hosts plugin timer. Empty string means use the default timer cadence.
func getLocalDnsHostsPluginRefreshIntervalInSeconds(config *aksnodeconfigv1.Configuration) string {
if config == nil || config.GetLocalDnsProfile() == nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

GetLocalDnsProfile() and GetHostsPluginRefreshIntervalInSeconds() are nil-safe on nil receivers. drop this guard and just call the getters:

refresh := config.GetLocalDnsProfile().GetHostsPluginRefreshIntervalInSeconds()
if refresh <= 0 {
    return ""
}

(baker.go is a plain datamodel struct, not proto — keep the nil checks there.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in commit 8366dcd.

Dropped the explicit nil guard and now rely on the proto getters nil-safe behavior here:

// getLocalDnsHostsPluginRefreshIntervalInSeconds returns the refresh interval in seconds
// for the LocalDNS hosts plugin timer. Empty string means use the default timer cadence.
func getLocalDnsHostsPluginRefreshIntervalInSeconds(config *aksnodeconfigv1.Configuration) string {
refreshIntervalInSeconds := config.GetLocalDnsProfile().GetHostsPluginRefreshIntervalInSeconds()
if refreshIntervalInSeconds <= 0 {
return ""
}
return strconv.FormatInt(int64(refreshIntervalInSeconds), 10)

The output should include "systemctlEnableAndStartNoBlock aks-localdns-hosts-setup.timer 30"
End

It 'should update the timer refresh interval when provided'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

only the happy path is covered. the *[!0-9]* warning branch and the empty/0 -> default-preserved path never run in test. add a bad-format case (e.g. "abc") asserting the timer stays 15min, and an unset case. otherwise would this short circuit your failure code path?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in commit 8366dcd.

Added coverage for the provided interval, unset/default-restore, invalid-format/default-preserved, and below-min/default-preserved cases here:

It 'should update the timer refresh interval when provided'
LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS="30"
When call enableAKSLocalDNSHostsSetup
The status should be success
The output should include "Configured aks-localdns-hosts-setup timer refresh interval to 30s."
The output should include "systemctl daemon-reload"
The contents of file "${AKS_LOCALDNS_HOSTS_SETUP_TIMER}.d/10-refresh-interval.conf" should include "OnUnitActiveSec=30s"
The contents of file "${AKS_LOCALDNS_HOSTS_SETUP_TIMER}.d/10-refresh-interval.conf" should include "AccuracySec=1s"
The contents of file "$AKS_LOCALDNS_HOSTS_SETUP_TIMER" should include "OnUnitActiveSec=15min"
End
It 'should restore the default timer when refresh interval is unset'
mkdir -p "${AKS_LOCALDNS_HOSTS_SETUP_TIMER}.d"
cat > "${AKS_LOCALDNS_HOSTS_SETUP_TIMER}.d/10-refresh-interval.conf" <<'OVERRIDE_EOF'
[Timer]
OnUnitActiveSec=30s
AccuracySec=1s
OVERRIDE_EOF
When call enableAKSLocalDNSHostsSetup
The status should be success
The output should include "Restored default aks-localdns-hosts-setup timer refresh interval."
The output should include "systemctl daemon-reload"
The contents of file "$AKS_LOCALDNS_HOSTS_SETUP_TIMER" should include "OnUnitActiveSec=15min"
The file "${AKS_LOCALDNS_HOSTS_SETUP_TIMER}.d/10-refresh-interval.conf" should not be exist
End
It 'should keep the default timer when refresh interval is invalid'
LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS="abc"
When call enableAKSLocalDNSHostsSetup
The status should be success
The output should include "must be an integer >= 5, got 'abc'. Using default timer interval."
The contents of file "$AKS_LOCALDNS_HOSTS_SETUP_TIMER" should include "OnUnitActiveSec=15min"
The file "${AKS_LOCALDNS_HOSTS_SETUP_TIMER}.d/10-refresh-interval.conf" should not be exist
End
It 'should keep the default timer when refresh interval is below minimum'
LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS="1"
When call enableAKSLocalDNSHostsSetup
The status should be success

LOCALDNS_COREFILE_WITH_HOSTS=${LOCALDNS_COREFILE_WITH_HOSTS:-}
SHOULD_ENABLE_HOSTS_PLUGIN=${SHOULD_ENABLE_HOSTS_PLUGIN:-false}
LOCALDNS_CRITICAL_FQDNS=${LOCALDNS_CRITICAL_FQDNS:-}
LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS=${LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS:-}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

who reads this? the interval only drives the timer rewrite at provision time — the periodic aks-localdns-hosts-setup service doesn't consume it. same for the write at L1799. if nobody reads them, drop both.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in commit 8366dcd.

The interval is no longer written into either localdns environment file. The generated localdns env now stops at LOCALDNS_CRITICAL_FQDNS here:

cat > "${LOCALDNS_ENV_FILE}" <<EOF
LOCALDNS_BASE64_ENCODED_COREFILE=${corefile_base}
LOCALDNS_COREFILE_BASE=${corefile_base}
LOCALDNS_COREFILE_WITH_HOSTS=${LOCALDNS_COREFILE_WITH_HOSTS:-}
SHOULD_ENABLE_HOSTS_PLUGIN=${SHOULD_ENABLE_HOSTS_PLUGIN:-false}
LOCALDNS_CRITICAL_FQDNS=${LOCALDNS_CRITICAL_FQDNS:-}
EOF

And the minimal hosts-setup env write is only:

# Write a minimal environment file so the systemd service (which reads from
# /etc/localdns/environment via EnvironmentFile=) has LOCALDNS_CRITICAL_FQDNS available.
# generateLocalDNSFiles() overwrites this later with the full content including corefiles.
local env_file="/etc/localdns/environment"
mkdir -p "$(dirname "${env_file}")"
cat > "${env_file}" <<EOF
LOCALDNS_CRITICAL_FQDNS=${LOCALDNS_CRITICAL_FQDNS}
EOF

The interval is only consumed at provisioning time for the timer drop-in here:

local hosts_plugin_refresh_interval="${LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS:-}"
local hosts_setup_timer_override="${hosts_setup_timer}.d/10-refresh-interval.conf"
local min_hosts_plugin_refresh_interval_in_seconds=5
if [ -z "${hosts_plugin_refresh_interval}" ]; then
removeAKSLocalDNSHostsSetupTimerOverride "${hosts_setup_timer_override}"
else
local should_override_refresh_interval="false"
case "${hosts_plugin_refresh_interval}" in
*[!0-9]*)
;;
*)
if [ "${hosts_plugin_refresh_interval}" -ge "${min_hosts_plugin_refresh_interval_in_seconds}" ]; then
should_override_refresh_interval="true"
fi
;;
esac
if [ "${should_override_refresh_interval}" = "true" ]; then
mkdir -p "$(dirname "${hosts_setup_timer_override}")"
cat > "${hosts_setup_timer_override}" <<EOF
[Timer]
OnUnitActiveSec=${hosts_plugin_refresh_interval}s
AccuracySec=1s
EOF

local hosts_plugin_refresh_interval="${LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS:-}"
if [ -n "${hosts_plugin_refresh_interval}" ]; then
case "${hosts_plugin_refresh_interval}" in
*[!0-9]*)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: this warning and the -gt 0 else below print the same message — collapse. also the "Refresh every 15 minutes..." comment in aks-localdns-hosts-setup.timer goes stale once you sed the value; make it generic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in commit 8366dcd.

The warning is collapsed to the single default-preserving branch here:

else
echo "Warning: LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS must be an integer >= ${min_hosts_plugin_refresh_interval_in_seconds}, got '${hosts_plugin_refresh_interval}'. Using default timer interval."
removeAKSLocalDNSHostsSetupTimerOverride "${hosts_setup_timer_override}"

And the shipped timer comments are generic/default-only here:

# Default refresh cadence. Provisioning may override this with a systemd drop-in
# when LOCALDNS_HOSTS_PLUGIN_REFRESH_INTERVAL_IN_SECONDS is set. 15 minutes
# balances freshness against unnecessary DNS traffic — stale IPs would cause the
# hosts plugin to serve unreachable addresses until the next refresh.
OnUnitActiveSec=15min
# Default timer accuracy. Provisioning may lower this for shorter cadences.
AccuracySec=1min

Copilot AI review requested due to automatic review settings July 13, 2026 18:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • aks-node-controller/pkg/gen/aksnodeconfig/v1/localdns_config.pb.go: Generated file

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.

4 participants