Skip to content

chore(deps): bump Go to 1.26.0 and update all Docker base images - #2059

Merged
Quang Nguyen (nddq) merged 1 commit into
microsoft:mainfrom
nddq:chore/bump-go-images-1.26.0
Mar 4, 2026
Merged

chore(deps): bump Go to 1.26.0 and update all Docker base images#2059
Quang Nguyen (nddq) merged 1 commit into
microsoft:mainfrom
nddq:chore/bump-go-images-1.26.0

Conversation

@nddq

@nddq Quang Nguyen (nddq) commented Feb 13, 2026

Copy link
Copy Markdown
Member

Description

Bump Go to 1.26.0 and all Docker base images to their latest versions. This makes Retina FIPS-ready.

What changed

  • Go: 1.24.11 → 1.26.0 (azurelinux, windowsservercore, and plain variants)
  • AzureLinux base images: base/core:3.0 and distroless/minimal:3.0 to latest digests
  • Windows base images: nanoserver and servercore for ltsc2022 to latest digests
  • CLI Dockerfile: use azurelinux-core libs stage instead of copying from the full Go SDK image
  • Copy OpenSSL config (/etc/pki/tls/) into distroless images for FIPS support

Go 1.26.0 migration notes

Microsoft Go 1.26.0 enables GOEXPERIMENT=systemcrypto by default, which routes all crypto operations through the system's OpenSSL library via CGO. This requires:

  • CGO_ENABLED=1 (removed all CGO_ENABLED=0 from Dockerfiles)
  • Shared libraries (/lib/, /usr/lib/) copied into distroless final images for dynamic linking at runtime
  • OpenSSL config (/etc/pki/tls/) copied into distroless images so OpenSSL discovers the SymCrypt FIPS provider

FIPS readiness

The images are FIPS-ready and can be activated at deploy time by setting GOFIPS=1:

  • Binaries are built with microsoft_systemcrypto=1, routing crypto through OpenSSL
  • AzureLinux ships SymCrypt (libsymcrypt.so) as its FIPS 140-3 validated module
  • The symcryptprovider.so OpenSSL provider and openssl.cnf config are included

Image size impact (linux/amd64)

Compared against published v1.0.4 images:

docker image inspect <image> --format '{{.Size}}' | awk '{printf "%.1f MB\n", $1/1024/1024}'
Image v1.0.4 This PR Delta
retina-agent 691.5 MB 692.5 MB +0.9 MB (+0.1%)
retina-init 369.6 MB 370.2 MB +0.5 MB (+0.1%)
retina-operator 334.9 MB 333.2 MB -1.6 MB (-0.4%)
kubectl-retina 82.0 MB 146.7 MB +64.7 MB (+79%)

The kubectl-retina increase is expected — it was previously a static binary (CGO_ENABLED=0, 82 MB) and is now dynamically linked (108 MB binary + 42 MB system libraries) for FIPS/OpenSSL support.

Related Issue

N/A

Checklist

  • I have read the contributing documentation.
  • I signed and signed-off the commits (git commit -S -s ...). See this documentation on signing commits.
  • I have correctly attributed the author(s) of the code.
  • I have tested the changes locally.
  • I have followed the project's style guidelines.
  • I have updated the documentation, if necessary.
  • I have added tests, if applicable.

Screenshots (if applicable) or Testing Completed

  • Built all Linux amd64 images locally and verified image sizes
  • kubectl-retina version and kubectl-retina --help work correctly in the distroless image
  • Verified dynamically linked binary resolves all shared libraries from the azurelinux-core libs stage

Additional Notes

16 Dockerfiles updated across controller, operator, cli, shell, test, and hack/tools directories.

@nddq
Quang Nguyen (nddq) requested a review from a team as a code owner February 13, 2026 17:58
@nddq Quang Nguyen (nddq) linked an issue Feb 13, 2026 that may be closed by this pull request
@nddq
Quang Nguyen (nddq) force-pushed the chore/bump-go-images-1.26.0 branch 2 times, most recently from 1efd405 to 786cf43 Compare February 13, 2026 18:19
@nddq
Quang Nguyen (nddq) force-pushed the chore/bump-go-images-1.26.0 branch from 40c999f to 7b4df84 Compare February 17, 2026 19:08
@nddq Quang Nguyen (nddq) changed the title chore(deps): bump all Docker base images to latest chore(deps): bump Go to 1.26.0 and update all Docker base images Feb 17, 2026
@nddq
Quang Nguyen (nddq) force-pushed the chore/bump-go-images-1.26.0 branch from 7b4df84 to 49b7189 Compare February 17, 2026 19:19
- Bump Go builder from 1.24.11 to 1.26.0 (azurelinux 3.0)
- Update azurelinux/base/core and azurelinux/distroless/minimal to latest
- Update cbl-mariner/base/core:2.0 to azurelinux/base/core:3.0 for CLI shell target
- Copy OpenSSL config (/etc/pki/tls/) into distroless images for FIPS support
- Use azurelinux-core libs stage in CLI Dockerfile to avoid copying
  193 MB of unnecessary libraries from the full Go SDK image

Signed-off-by: Quang Nguyen <nguyenquang@microsoft.com>
@nddq
Quang Nguyen (nddq) force-pushed the chore/bump-go-images-1.26.0 branch from 49b7189 to a6c46c0 Compare March 4, 2026 03:27
@nddq
Quang Nguyen (nddq) added this pull request to the merge queue Mar 4, 2026
Merged via the queue into microsoft:main with commit cc74509 Mar 4, 2026
30 checks passed
@nddq
Quang Nguyen (nddq) deleted the chore/bump-go-images-1.26.0 branch March 4, 2026 18:39
Aanchal Khandelwal (aanchal22) pushed a commit to aanchal22/retina that referenced this pull request Mar 11, 2026
…rosoft#2059)

# Description

Bump Go to 1.26.0 and all Docker base images to their latest versions.
This makes Retina FIPS-ready.

### What changed

- **Go**: 1.24.11 → 1.26.0 (azurelinux, windowsservercore, and plain
variants)
- **AzureLinux base images**: `base/core:3.0` and
`distroless/minimal:3.0` to latest digests
- **Windows base images**: `nanoserver` and `servercore` for ltsc2022 to
latest digests
- **CLI Dockerfile**: use `azurelinux-core` libs stage instead of
copying from the full Go SDK image
- Copy OpenSSL config (`/etc/pki/tls/`) into distroless images for FIPS
support

### Go 1.26.0 migration notes

Microsoft Go 1.26.0 enables `GOEXPERIMENT=systemcrypto` by default,
which routes all crypto operations through the system's OpenSSL library
via CGO. This requires:

- **`CGO_ENABLED=1`** (removed all `CGO_ENABLED=0` from Dockerfiles)
- **Shared libraries** (`/lib/`, `/usr/lib/`) copied into distroless
final images for dynamic linking at runtime
- **OpenSSL config** (`/etc/pki/tls/`) copied into distroless images so
OpenSSL discovers the SymCrypt FIPS provider

### FIPS readiness

The images are FIPS-ready and can be activated at deploy time by setting
`GOFIPS=1`:
- Binaries are built with `microsoft_systemcrypto=1`, routing crypto
through OpenSSL
- AzureLinux ships SymCrypt (`libsymcrypt.so`) as its FIPS 140-3
validated module
- The `symcryptprovider.so` OpenSSL provider and `openssl.cnf` config
are included

### Image size impact (linux/amd64)

Compared against published v1.0.4 images:

```bash
docker image inspect <image> --format '{{.Size}}' | awk '{printf "%.1f MB\n", $1/1024/1024}'
```

| Image | v1.0.4 | This PR | Delta |
|-------|--------|---------|-------|
| retina-agent | 691.5 MB | 692.5 MB | +0.9 MB (+0.1%) |
| retina-init | 369.6 MB | 370.2 MB | +0.5 MB (+0.1%) |
| retina-operator | 334.9 MB | 333.2 MB | -1.6 MB (-0.4%) |
| kubectl-retina | 82.0 MB | 146.7 MB | +64.7 MB (+79%) |

The `kubectl-retina` increase is expected — it was previously a static
binary (`CGO_ENABLED=0`, 82 MB) and is now dynamically linked (108 MB
binary + 42 MB system libraries) for FIPS/OpenSSL support.

## Related Issue

N/A

## Checklist

- [x] I have read the [contributing
documentation](https://retina.sh/docs/Contributing/overview).
- [x] I signed and signed-off the commits (`git commit -S -s ...`). See
[this
documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)
on signing commits.
- [x] I have correctly attributed the author(s) of the code.
- [x] I have tested the changes locally.
- [x] I have followed the project's style guidelines.
- [ ] I have updated the documentation, if necessary.
- [ ] I have added tests, if applicable.

## Screenshots (if applicable) or Testing Completed

- Built all Linux amd64 images locally and verified image sizes
- `kubectl-retina version` and `kubectl-retina --help` work correctly in
the distroless image
- Verified dynamically linked binary resolves all shared libraries from
the `azurelinux-core` libs stage

## Additional Notes

16 Dockerfiles updated across controller, operator, cli, shell, test,
and hack/tools directories.

Signed-off-by: Quang Nguyen <nguyenquang@microsoft.com>
pull Bot pushed a commit to TheTechOddBug/retina that referenced this pull request Jul 16, 2026
# Description

This PR migrates all GH workflows using FIC to Azure Pipelines due to
internal policy changes regarding FIC in GH.
It adds 3 pipelines under `.azure-pipelines` that mirrors today's GH
workflows:

| ADO Pipeline | Mirrors |
| :--- | :--- |
| `ci.yml` | `images.yaml` (build + manifests + e2e + perf-basics +
perf-advanced on merge-queue) |
| `scale.yml` | `daily-scale-test.yaml` + `scale-test.yaml` (daily cron
+ manual) |
| `perf.yml` | `perf-schedule.yaml` + `perf-manual.yaml` +
`perf-template.yaml` (twice-daily cron + manual) |

Bash bodies inside each `AzureCLI@2` task are copied verbatim from the
existing GH workflows. Only the outer scaffolding is rewritten to ADO
YAML schema (different from GH Actions YAML)

Also added:
- `setup-go.yml`: parses the Go version from `go.mod` (ADO's `GoTool@0`
doesn't natively support `from go.mod` like GH's `setup-go@v6`).
- `free-disk-space.yml`: reclaims ~30GB of pre-installed toolchains on
agents (needed to avoid lack of space for large image builds).

> Nothing in `workflows` is deleted or disabled by this PR. Both
pipelines are available to run in parallel at this stage. A new PR will
be raised to remove old workflows.

### What this PR does NOT do (deferred to a follow-up PR)
- Branch protection changes. Required checks still point at the GH
workflows. Once ADO pipelines are validated, a subsequent admin action +
PR will:
  - Add workflows to required status checks.
  - Remove the corresponding GH Actions checks.
- Delete the FIC-using workflow files: `images.yaml`, `e2e.yaml`,
`perf-template.yaml`, `scale-test.yaml`, `daily-scale-test.yaml`,
`perf-manual.yaml`, `perf-schedule.yaml`.
- Secret / var cleanup.

### Behavior parity with today's GH workflows

The ADO pipelines match today's semantics exactly on all these axes:

- Triggers. `ci.yml` fires on merge-queue pushes
(`gh-readonly-queue/main/*`) and PRs targeting main. Scale/perf fire on
their existing crons.
- Merge-queue gating. ACR push, APP_INSIGHTS_ID embedding, and the
manifests/e2e/perf jobs only run when isMergeGroup=True (mirrors GH's
if: ${{ github.event_name == 'merge_group' }} gate). PR builds and
manual queues run as dry-run.
- Fork PRs. The three pipelines are configured with "Disable building
pull requests from forked GitHub repositories" — same fork-safety
posture as today's FIC-gated jobs (which never ran on fork PRs).
- Image tag. Both build and consumer use $(make version). The migration
proactively fixed a latent tag-mismatch bug (see below).

### Required side-effect changes to retina source

Because ADO doesn't have ARM64 agents, arm64 image builds have to
cross-compile from amd64 hosts. Retina's Dockerfiles have latent bugs /
assumptions that only surface on cross-compile (native ARM64 CI on GH
has always masked them since PR microsoft#2059 introduced systemcrypto/CGO). This
PR includes minimal fixes:

| Change | Reason |
| :--- | :--- | 
| `operator/Dockerfile`, `cli/Dockerfile`: dropped
`--platform=$BUILDPLATFORM` from final image stages | Otherwise
arm64-built binaries got copied into amd64 base images (wrong arch →
exec format error). |
| `operator/Dockerfile`, `cli/Dockerfile`, `controller/Dockerfile`:
added `ENV GOEXPERIMENT=ms_nocgo_opensslcrypto` in builder stages |
Microsoft Go's default `systemcrypto` requires `CGO_ENABLED=1`, but Go
auto-disables CGO when cross-compiling. This experiment (documented in
Microsoft Go MigrationGuide) enables the cgo-less OpenSSL backend so
systemcrypto works with `CGO_ENABLED=0`. Auto-selected in Go 1.27+; env
var can be removed then. |
| `operator/Dockerfile`: `RUN make manifests` wrapped in `env -u GOOS -u
GOARCH` | `make manifests` shells out to `controller-gen` — a build-time
host tool, not the target binary. Without unset, it cross-compiled to
arm64 and failed to `exec` on the amd64 builder. |
| `controller/Dockerfile`: split intermediate into two stages — new
`bpf-gen` at `$TARGETPLATFORM`, existing intermediate stays at
`$BUILDPLATFORM` | Retina's `//go:generate bpf2go -target ${GOARCH}`
directives require target-arch execution (bpf2go invokes clang; can't
cleanly cross-compile bpf2go itself). Split isolates that one
requirement to a small emulated stage while keeping the Go build fast at
$BUILDPLATFORM. Restores fast arm64 build without breaking bpf .o file
generation. |

> Impact on amd64 builds: zero — all these changes are inert when host
== target (CGO stays enabled, no cross-compile, bpf-gen runs natively).

### Tag consistency fix
The migration surfaced a pre-existing latent bug: `make retina-image` /
`make manifest` didn't have `TAG` set by CI, so the Makefile fell back
to `git describe --tags --always` (produces `v1.2.2-76-geade8685`),
while all consumers (`e2e`, `perf-*`, `scale`) used make version
(produces the 7-char SHA). Images were pushed under one tag, consumers
looked for another. GH masked it because actions/checkout defaults to
shallow (no tags, so git describe also falls back to short SHA); ADO
defaults to full-clone.

ADO pipelines now pass `TAG=$(make version)` explicitly to every `make`
invocation, ensuring builder and consumer speak the same tag string on
both platforms.

### Temporary items in this PR (will be reverted after cutover)

- `forceMergeGroup` pipeline parameter in `ci.yml`. Boolean checkbox in
the "Run pipeline" UI that treats a manual queue as if it were a
merge-queue event (push + telemetry + full test suite). Default `false`,
safe. Used during dark-launch to validate the full flow without needing
an actual merge-queue event. Revert once we've moved past validation.

### Verification
- manual run of pipelines completed successfully

## Checklist

- [ ] I have read the [contributing
documentation](https://retina.sh/docs/Contributing/overview).
- [ ] I signed and signed-off the commits (`git commit -S -s ...`). See
[this
documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)
on signing commits.
- [ ] I have correctly attributed the author(s) of the code.
- [ ] I have tested the changes locally.
- [ ] I have followed the project's style guidelines.
- [ ] I have updated the documentation, if necessary.
- [ ] I have added tests, if applicable.

## Screenshots (if applicable) or Testing Completed

Please add any relevant screenshots or GIFs to showcase the changes
made.

## Additional Notes

Add any additional notes or context about the pull request here.

---

Please refer to the [CONTRIBUTING.md](../CONTRIBUTING.md) file for more
information on how to contribute to this project.

---------

Signed-off-by: Alex Castilio dos Santos <alexsantos@microsoft.com>
Laksh (lakshk98) pushed a commit to lakshk98/retina that referenced this pull request Aug 4, 2026
…rosoft#2059)

# Description

Bump Go to 1.26.0 and all Docker base images to their latest versions.
This makes Retina FIPS-ready.

### What changed

- **Go**: 1.24.11 → 1.26.0 (azurelinux, windowsservercore, and plain
variants)
- **AzureLinux base images**: `base/core:3.0` and
`distroless/minimal:3.0` to latest digests
- **Windows base images**: `nanoserver` and `servercore` for ltsc2022 to
latest digests
- **CLI Dockerfile**: use `azurelinux-core` libs stage instead of
copying from the full Go SDK image
- Copy OpenSSL config (`/etc/pki/tls/`) into distroless images for FIPS
support

### Go 1.26.0 migration notes

Microsoft Go 1.26.0 enables `GOEXPERIMENT=systemcrypto` by default,
which routes all crypto operations through the system's OpenSSL library
via CGO. This requires:

- **`CGO_ENABLED=1`** (removed all `CGO_ENABLED=0` from Dockerfiles)
- **Shared libraries** (`/lib/`, `/usr/lib/`) copied into distroless
final images for dynamic linking at runtime
- **OpenSSL config** (`/etc/pki/tls/`) copied into distroless images so
OpenSSL discovers the SymCrypt FIPS provider

### FIPS readiness

The images are FIPS-ready and can be activated at deploy time by setting
`GOFIPS=1`:
- Binaries are built with `microsoft_systemcrypto=1`, routing crypto
through OpenSSL
- AzureLinux ships SymCrypt (`libsymcrypt.so`) as its FIPS 140-3
validated module
- The `symcryptprovider.so` OpenSSL provider and `openssl.cnf` config
are included

### Image size impact (linux/amd64)

Compared against published v1.0.4 images:

```bash
docker image inspect <image> --format '{{.Size}}' | awk '{printf "%.1f MB\n", $1/1024/1024}'
```

| Image | v1.0.4 | This PR | Delta |
|-------|--------|---------|-------|
| retina-agent | 691.5 MB | 692.5 MB | +0.9 MB (+0.1%) |
| retina-init | 369.6 MB | 370.2 MB | +0.5 MB (+0.1%) |
| retina-operator | 334.9 MB | 333.2 MB | -1.6 MB (-0.4%) |
| kubectl-retina | 82.0 MB | 146.7 MB | +64.7 MB (+79%) |

The `kubectl-retina` increase is expected — it was previously a static
binary (`CGO_ENABLED=0`, 82 MB) and is now dynamically linked (108 MB
binary + 42 MB system libraries) for FIPS/OpenSSL support.

## Related Issue

N/A

## Checklist

- [x] I have read the [contributing
documentation](https://retina.sh/docs/Contributing/overview).
- [x] I signed and signed-off the commits (`git commit -S -s ...`). See
[this
documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)
on signing commits.
- [x] I have correctly attributed the author(s) of the code.
- [x] I have tested the changes locally.
- [x] I have followed the project's style guidelines.
- [ ] I have updated the documentation, if necessary.
- [ ] I have added tests, if applicable.

## Screenshots (if applicable) or Testing Completed

- Built all Linux amd64 images locally and verified image sizes
- `kubectl-retina version` and `kubectl-retina --help` work correctly in
the distroless image
- Verified dynamically linked binary resolves all shared libraries from
the `azurelinux-core` libs stage

## Additional Notes

16 Dockerfiles updated across controller, operator, cli, shell, test,
and hack/tools directories.

Signed-off-by: Quang Nguyen <nguyenquang@microsoft.com>
Laksh (lakshk98) pushed a commit to lakshk98/retina that referenced this pull request Aug 4, 2026
# Description

This PR migrates all GH workflows using FIC to Azure Pipelines due to
internal policy changes regarding FIC in GH.
It adds 3 pipelines under `.azure-pipelines` that mirrors today's GH
workflows:

| ADO Pipeline | Mirrors |
| :--- | :--- |
| `ci.yml` | `images.yaml` (build + manifests + e2e + perf-basics +
perf-advanced on merge-queue) |
| `scale.yml` | `daily-scale-test.yaml` + `scale-test.yaml` (daily cron
+ manual) |
| `perf.yml` | `perf-schedule.yaml` + `perf-manual.yaml` +
`perf-template.yaml` (twice-daily cron + manual) |

Bash bodies inside each `AzureCLI@2` task are copied verbatim from the
existing GH workflows. Only the outer scaffolding is rewritten to ADO
YAML schema (different from GH Actions YAML)

Also added:
- `setup-go.yml`: parses the Go version from `go.mod` (ADO's `GoTool@0`
doesn't natively support `from go.mod` like GH's `setup-go@v6`).
- `free-disk-space.yml`: reclaims ~30GB of pre-installed toolchains on
agents (needed to avoid lack of space for large image builds).

> Nothing in `workflows` is deleted or disabled by this PR. Both
pipelines are available to run in parallel at this stage. A new PR will
be raised to remove old workflows.

### What this PR does NOT do (deferred to a follow-up PR)
- Branch protection changes. Required checks still point at the GH
workflows. Once ADO pipelines are validated, a subsequent admin action +
PR will:
  - Add workflows to required status checks.
  - Remove the corresponding GH Actions checks.
- Delete the FIC-using workflow files: `images.yaml`, `e2e.yaml`,
`perf-template.yaml`, `scale-test.yaml`, `daily-scale-test.yaml`,
`perf-manual.yaml`, `perf-schedule.yaml`.
- Secret / var cleanup.

### Behavior parity with today's GH workflows

The ADO pipelines match today's semantics exactly on all these axes:

- Triggers. `ci.yml` fires on merge-queue pushes
(`gh-readonly-queue/main/*`) and PRs targeting main. Scale/perf fire on
their existing crons.
- Merge-queue gating. ACR push, APP_INSIGHTS_ID embedding, and the
manifests/e2e/perf jobs only run when isMergeGroup=True (mirrors GH's
if: ${{ github.event_name == 'merge_group' }} gate). PR builds and
manual queues run as dry-run.
- Fork PRs. The three pipelines are configured with "Disable building
pull requests from forked GitHub repositories" — same fork-safety
posture as today's FIC-gated jobs (which never ran on fork PRs).
- Image tag. Both build and consumer use $(make version). The migration
proactively fixed a latent tag-mismatch bug (see below).

### Required side-effect changes to retina source

Because ADO doesn't have ARM64 agents, arm64 image builds have to
cross-compile from amd64 hosts. Retina's Dockerfiles have latent bugs /
assumptions that only surface on cross-compile (native ARM64 CI on GH
has always masked them since PR microsoft#2059 introduced systemcrypto/CGO). This
PR includes minimal fixes:

| Change | Reason |
| :--- | :--- | 
| `operator/Dockerfile`, `cli/Dockerfile`: dropped
`--platform=$BUILDPLATFORM` from final image stages | Otherwise
arm64-built binaries got copied into amd64 base images (wrong arch →
exec format error). |
| `operator/Dockerfile`, `cli/Dockerfile`, `controller/Dockerfile`:
added `ENV GOEXPERIMENT=ms_nocgo_opensslcrypto` in builder stages |
Microsoft Go's default `systemcrypto` requires `CGO_ENABLED=1`, but Go
auto-disables CGO when cross-compiling. This experiment (documented in
Microsoft Go MigrationGuide) enables the cgo-less OpenSSL backend so
systemcrypto works with `CGO_ENABLED=0`. Auto-selected in Go 1.27+; env
var can be removed then. |
| `operator/Dockerfile`: `RUN make manifests` wrapped in `env -u GOOS -u
GOARCH` | `make manifests` shells out to `controller-gen` — a build-time
host tool, not the target binary. Without unset, it cross-compiled to
arm64 and failed to `exec` on the amd64 builder. |
| `controller/Dockerfile`: split intermediate into two stages — new
`bpf-gen` at `$TARGETPLATFORM`, existing intermediate stays at
`$BUILDPLATFORM` | Retina's `//go:generate bpf2go -target ${GOARCH}`
directives require target-arch execution (bpf2go invokes clang; can't
cleanly cross-compile bpf2go itself). Split isolates that one
requirement to a small emulated stage while keeping the Go build fast at
$BUILDPLATFORM. Restores fast arm64 build without breaking bpf .o file
generation. |

> Impact on amd64 builds: zero — all these changes are inert when host
== target (CGO stays enabled, no cross-compile, bpf-gen runs natively).

### Tag consistency fix
The migration surfaced a pre-existing latent bug: `make retina-image` /
`make manifest` didn't have `TAG` set by CI, so the Makefile fell back
to `git describe --tags --always` (produces `v1.2.2-76-geade8685`),
while all consumers (`e2e`, `perf-*`, `scale`) used make version
(produces the 7-char SHA). Images were pushed under one tag, consumers
looked for another. GH masked it because actions/checkout defaults to
shallow (no tags, so git describe also falls back to short SHA); ADO
defaults to full-clone.

ADO pipelines now pass `TAG=$(make version)` explicitly to every `make`
invocation, ensuring builder and consumer speak the same tag string on
both platforms.

### Temporary items in this PR (will be reverted after cutover)

- `forceMergeGroup` pipeline parameter in `ci.yml`. Boolean checkbox in
the "Run pipeline" UI that treats a manual queue as if it were a
merge-queue event (push + telemetry + full test suite). Default `false`,
safe. Used during dark-launch to validate the full flow without needing
an actual merge-queue event. Revert once we've moved past validation.

### Verification
- manual run of pipelines completed successfully

## Checklist

- [ ] I have read the [contributing
documentation](https://retina.sh/docs/Contributing/overview).
- [ ] I signed and signed-off the commits (`git commit -S -s ...`). See
[this
documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)
on signing commits.
- [ ] I have correctly attributed the author(s) of the code.
- [ ] I have tested the changes locally.
- [ ] I have followed the project's style guidelines.
- [ ] I have updated the documentation, if necessary.
- [ ] I have added tests, if applicable.

## Screenshots (if applicable) or Testing Completed

Please add any relevant screenshots or GIFs to showcase the changes
made.

## Additional Notes

Add any additional notes or context about the pull request here.

---

Please refer to the [CONTRIBUTING.md](../CONTRIBUTING.md) file for more
information on how to contribute to this project.

---------

Signed-off-by: Alex Castilio dos Santos <alexsantos@microsoft.com>
Laksh (lakshk98) pushed a commit to lakshk98/retina that referenced this pull request Aug 4, 2026
…rosoft#2059)

# Description

Bump Go to 1.26.0 and all Docker base images to their latest versions.
This makes Retina FIPS-ready.

### What changed

- **Go**: 1.24.11 → 1.26.0 (azurelinux, windowsservercore, and plain
variants)
- **AzureLinux base images**: `base/core:3.0` and
`distroless/minimal:3.0` to latest digests
- **Windows base images**: `nanoserver` and `servercore` for ltsc2022 to
latest digests
- **CLI Dockerfile**: use `azurelinux-core` libs stage instead of
copying from the full Go SDK image
- Copy OpenSSL config (`/etc/pki/tls/`) into distroless images for FIPS
support

### Go 1.26.0 migration notes

Microsoft Go 1.26.0 enables `GOEXPERIMENT=systemcrypto` by default,
which routes all crypto operations through the system's OpenSSL library
via CGO. This requires:

- **`CGO_ENABLED=1`** (removed all `CGO_ENABLED=0` from Dockerfiles)
- **Shared libraries** (`/lib/`, `/usr/lib/`) copied into distroless
final images for dynamic linking at runtime
- **OpenSSL config** (`/etc/pki/tls/`) copied into distroless images so
OpenSSL discovers the SymCrypt FIPS provider

### FIPS readiness

The images are FIPS-ready and can be activated at deploy time by setting
`GOFIPS=1`:
- Binaries are built with `microsoft_systemcrypto=1`, routing crypto
through OpenSSL
- AzureLinux ships SymCrypt (`libsymcrypt.so`) as its FIPS 140-3
validated module
- The `symcryptprovider.so` OpenSSL provider and `openssl.cnf` config
are included

### Image size impact (linux/amd64)

Compared against published v1.0.4 images:

```bash
docker image inspect <image> --format '{{.Size}}' | awk '{printf "%.1f MB\n", $1/1024/1024}'
```

| Image | v1.0.4 | This PR | Delta |
|-------|--------|---------|-------|
| retina-agent | 691.5 MB | 692.5 MB | +0.9 MB (+0.1%) |
| retina-init | 369.6 MB | 370.2 MB | +0.5 MB (+0.1%) |
| retina-operator | 334.9 MB | 333.2 MB | -1.6 MB (-0.4%) |
| kubectl-retina | 82.0 MB | 146.7 MB | +64.7 MB (+79%) |

The `kubectl-retina` increase is expected — it was previously a static
binary (`CGO_ENABLED=0`, 82 MB) and is now dynamically linked (108 MB
binary + 42 MB system libraries) for FIPS/OpenSSL support.

## Related Issue

N/A

## Checklist

- [x] I have read the [contributing
documentation](https://retina.sh/docs/Contributing/overview).
- [x] I signed and signed-off the commits (`git commit -S -s ...`). See
[this
documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)
on signing commits.
- [x] I have correctly attributed the author(s) of the code.
- [x] I have tested the changes locally.
- [x] I have followed the project's style guidelines.
- [ ] I have updated the documentation, if necessary.
- [ ] I have added tests, if applicable.

## Screenshots (if applicable) or Testing Completed

- Built all Linux amd64 images locally and verified image sizes
- `kubectl-retina version` and `kubectl-retina --help` work correctly in
the distroless image
- Verified dynamically linked binary resolves all shared libraries from
the `azurelinux-core` libs stage

## Additional Notes

16 Dockerfiles updated across controller, operator, cli, shell, test,
and hack/tools directories.

Signed-off-by: Quang Nguyen <nguyenquang@microsoft.com>
Laksh (lakshk98) pushed a commit to lakshk98/retina that referenced this pull request Aug 4, 2026
# Description

This PR migrates all GH workflows using FIC to Azure Pipelines due to
internal policy changes regarding FIC in GH.
It adds 3 pipelines under `.azure-pipelines` that mirrors today's GH
workflows:

| ADO Pipeline | Mirrors |
| :--- | :--- |
| `ci.yml` | `images.yaml` (build + manifests + e2e + perf-basics +
perf-advanced on merge-queue) |
| `scale.yml` | `daily-scale-test.yaml` + `scale-test.yaml` (daily cron
+ manual) |
| `perf.yml` | `perf-schedule.yaml` + `perf-manual.yaml` +
`perf-template.yaml` (twice-daily cron + manual) |

Bash bodies inside each `AzureCLI@2` task are copied verbatim from the
existing GH workflows. Only the outer scaffolding is rewritten to ADO
YAML schema (different from GH Actions YAML)

Also added:
- `setup-go.yml`: parses the Go version from `go.mod` (ADO's `GoTool@0`
doesn't natively support `from go.mod` like GH's `setup-go@v6`).
- `free-disk-space.yml`: reclaims ~30GB of pre-installed toolchains on
agents (needed to avoid lack of space for large image builds).

> Nothing in `workflows` is deleted or disabled by this PR. Both
pipelines are available to run in parallel at this stage. A new PR will
be raised to remove old workflows.

### What this PR does NOT do (deferred to a follow-up PR)
- Branch protection changes. Required checks still point at the GH
workflows. Once ADO pipelines are validated, a subsequent admin action +
PR will:
  - Add workflows to required status checks.
  - Remove the corresponding GH Actions checks.
- Delete the FIC-using workflow files: `images.yaml`, `e2e.yaml`,
`perf-template.yaml`, `scale-test.yaml`, `daily-scale-test.yaml`,
`perf-manual.yaml`, `perf-schedule.yaml`.
- Secret / var cleanup.

### Behavior parity with today's GH workflows

The ADO pipelines match today's semantics exactly on all these axes:

- Triggers. `ci.yml` fires on merge-queue pushes
(`gh-readonly-queue/main/*`) and PRs targeting main. Scale/perf fire on
their existing crons.
- Merge-queue gating. ACR push, APP_INSIGHTS_ID embedding, and the
manifests/e2e/perf jobs only run when isMergeGroup=True (mirrors GH's
if: ${{ github.event_name == 'merge_group' }} gate). PR builds and
manual queues run as dry-run.
- Fork PRs. The three pipelines are configured with "Disable building
pull requests from forked GitHub repositories" — same fork-safety
posture as today's FIC-gated jobs (which never ran on fork PRs).
- Image tag. Both build and consumer use $(make version). The migration
proactively fixed a latent tag-mismatch bug (see below).

### Required side-effect changes to retina source

Because ADO doesn't have ARM64 agents, arm64 image builds have to
cross-compile from amd64 hosts. Retina's Dockerfiles have latent bugs /
assumptions that only surface on cross-compile (native ARM64 CI on GH
has always masked them since PR microsoft#2059 introduced systemcrypto/CGO). This
PR includes minimal fixes:

| Change | Reason |
| :--- | :--- | 
| `operator/Dockerfile`, `cli/Dockerfile`: dropped
`--platform=$BUILDPLATFORM` from final image stages | Otherwise
arm64-built binaries got copied into amd64 base images (wrong arch →
exec format error). |
| `operator/Dockerfile`, `cli/Dockerfile`, `controller/Dockerfile`:
added `ENV GOEXPERIMENT=ms_nocgo_opensslcrypto` in builder stages |
Microsoft Go's default `systemcrypto` requires `CGO_ENABLED=1`, but Go
auto-disables CGO when cross-compiling. This experiment (documented in
Microsoft Go MigrationGuide) enables the cgo-less OpenSSL backend so
systemcrypto works with `CGO_ENABLED=0`. Auto-selected in Go 1.27+; env
var can be removed then. |
| `operator/Dockerfile`: `RUN make manifests` wrapped in `env -u GOOS -u
GOARCH` | `make manifests` shells out to `controller-gen` — a build-time
host tool, not the target binary. Without unset, it cross-compiled to
arm64 and failed to `exec` on the amd64 builder. |
| `controller/Dockerfile`: split intermediate into two stages — new
`bpf-gen` at `$TARGETPLATFORM`, existing intermediate stays at
`$BUILDPLATFORM` | Retina's `//go:generate bpf2go -target ${GOARCH}`
directives require target-arch execution (bpf2go invokes clang; can't
cleanly cross-compile bpf2go itself). Split isolates that one
requirement to a small emulated stage while keeping the Go build fast at
$BUILDPLATFORM. Restores fast arm64 build without breaking bpf .o file
generation. |

> Impact on amd64 builds: zero — all these changes are inert when host
== target (CGO stays enabled, no cross-compile, bpf-gen runs natively).

### Tag consistency fix
The migration surfaced a pre-existing latent bug: `make retina-image` /
`make manifest` didn't have `TAG` set by CI, so the Makefile fell back
to `git describe --tags --always` (produces `v1.2.2-76-geade8685`),
while all consumers (`e2e`, `perf-*`, `scale`) used make version
(produces the 7-char SHA). Images were pushed under one tag, consumers
looked for another. GH masked it because actions/checkout defaults to
shallow (no tags, so git describe also falls back to short SHA); ADO
defaults to full-clone.

ADO pipelines now pass `TAG=$(make version)` explicitly to every `make`
invocation, ensuring builder and consumer speak the same tag string on
both platforms.

### Temporary items in this PR (will be reverted after cutover)

- `forceMergeGroup` pipeline parameter in `ci.yml`. Boolean checkbox in
the "Run pipeline" UI that treats a manual queue as if it were a
merge-queue event (push + telemetry + full test suite). Default `false`,
safe. Used during dark-launch to validate the full flow without needing
an actual merge-queue event. Revert once we've moved past validation.

### Verification
- manual run of pipelines completed successfully

## Checklist

- [ ] I have read the [contributing
documentation](https://retina.sh/docs/Contributing/overview).
- [ ] I signed and signed-off the commits (`git commit -S -s ...`). See
[this
documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)
on signing commits.
- [ ] I have correctly attributed the author(s) of the code.
- [ ] I have tested the changes locally.
- [ ] I have followed the project's style guidelines.
- [ ] I have updated the documentation, if necessary.
- [ ] I have added tests, if applicable.

## Screenshots (if applicable) or Testing Completed

Please add any relevant screenshots or GIFs to showcase the changes
made.

## Additional Notes

Add any additional notes or context about the pull request here.

---

Please refer to the [CONTRIBUTING.md](../CONTRIBUTING.md) file for more
information on how to contribute to this project.

---------

Signed-off-by: Alex Castilio dos Santos <alexsantos@microsoft.com>
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.

Golang 1.26 and Green Tea GC

2 participants