Skip to content

fix(garm): build openstack provider as static binary - #269

Merged
cbartz merged 2 commits into
mainfrom
fix/garm-provider-static-build
Jul 8, 2026
Merged

fix(garm): build openstack provider as static binary#269
cbartz merged 2 commits into
mainfrom
fix/garm-provider-static-build

Conversation

@cbartz

@cbartz cbartz commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

Builds the garm-provider-openstack binary in the GARM rock with CGO_ENABLED=0 so it is a fully static, pure-Go binary, and drops the ineffective -extldflags -static ldflag.

Why we need it

On the deployed garm charm, runner consolidation failed with:

provider binary /usr/local/bin/garm-provider-openstack ... fork/exec: no such file or directory

The binary was present but dynamically linked: with cgo enabled (default) and the net package imported, Go links glibc's NSS resolvers dynamically via its internal linker, which never invokes the external linker — so the existing -extldflags -static was silently ignored. The rock uses a bare base with no dynamic loader/libc, so GARM could not exec it and no runners were spawned — while the charm still reported active (the charm doesn't scrape GARM's runtime logs). The garm binary avoids this via its osusergo,netgo tags; the provider had neither those nor CGO_ENABLED=0.

Test plan

  • Reproduced the original build locally (go build -ldflags "-extldflags -static", cgo default) → dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2.
  • Verified the fix (CGO_ENABLED=0 go build) → statically linked, no ELF interpreter.
  • Rebuilt the rock end-to-end (build-garm-rock.sh), extracted the provider from the OCI layer → confirmed statically linked, no interp.

Review focus

  • Chose CGO_ENABLED=0 over adding osusergo,netgo tags: the OpenStack provider is pure Go with no cgo dependency (unlike garm's sqlite), so disabling cgo outright is the simplest guarantee and removes any reliance on the external linker honouring -static.

Potential breaking changes / new dependencies

None. Build-only change; no new modules, APIs, or workflow changes.

Checklist

  • Changes comply with the project's coding standards and guidelines (see CONTRIBUTING.md and STYLE.md)
  • CONTRIBUTING.md has been updated upon changes to the contribution/development process (e.g. changes to the way tests are run) — N/A
  • Technical author has been assigned to review the PR in case of documentation changes (usually *.md files) — N/A, only a changelog entry
  • I updated docs/changelog.md with user-relevant changes
  • I used AI to assist with preparing this PR
  • I added or updated tests as needed (unit and integration) — N/A; static-linking is a rock build property with no charm-level test surface
  • If integration test modules are used: I updated the workflow configuration — N/A
  • If this PR involves a Grafana dashboard: I added a screenshot of the dashboard — N/A
  • If this PR involves Terraform: terraform fmt passes and tflint reports no errors — N/A
  • If this PR involves Rockcraft: I updated the version — the garm rock version is static at 0.1 and prior rock fixes (e.g. fix(garm): add CA trust store to bare rock so GARM can verify TLS #257) did not bump it; left unchanged for consistency
  • If this PR adds/removes a charm, or changes a charm's base class, conventions, tooling, or repo structure: I updated the relevant AGENTS.md — N/A
  • If this PR changes .copilot-collections.yaml or .github/instructions/: I re-checked whether the AGENTS.md "12-factor divergences" guidance still matches the upstream copilot-collections guidance — N/A

The garm-provider-openstack binary in the bare-base rock was built
dynamically linked: with cgo enabled and the net package imported,
Go links glibc's NSS resolvers dynamically via the internal linker,
which ignores -extldflags -static. On a bare rock there is no dynamic
loader, so GARM failed to exec it with 'fork/exec ...: no such file or
directory' during runner consolidation and never spawned runners --
while the charm still reported active.

Build the provider with CGO_ENABLED=0 to force a fully static, pure-Go
binary, matching how the garm part avoids the same issue.

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 adjusts the GARM rock build so the garm-provider-openstack binary is built as a fully static (pure-Go) executable by forcing CGO_ENABLED=0, addressing runtime failures on the bare base where dynamically linked binaries cannot be exec’d due to the missing ELF interpreter.

Changes:

  • Set CGO_ENABLED=0 for the garm-provider-openstack part and remove the ineffective -extldflags -static usage for that binary.
  • Add a changelog entry documenting the runner provisioning fix and the root cause.

Reviewed changes

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

File Description
garm-rockcraft.yaml Forces a pure-Go, static build of garm-provider-openstack suitable for base: bare and removes an ldflag that was not achieving static linking.
docs/changelog.md Documents the user-visible impact and the build change that fixes provider execution.

@cbartz
cbartz marked this pull request as ready for review July 8, 2026 12:12
@cbartz
cbartz enabled auto-merge (squash) July 8, 2026 12:20
@cbartz
cbartz merged commit 2f68b08 into main Jul 8, 2026
58 checks passed
@cbartz
cbartz deleted the fix/garm-provider-static-build branch July 8, 2026 12:46
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