NVIDIA / container-canary

A tool for testing and validating container requirements against versioned manifests
Apache License 2.0
237 stars 15 forks source link

set CGO_ENABLED=0 when building release artifacts #60

Closed jameslamb closed 3 months ago

jameslamb commented 3 months ago

Description

This project's release artifacts are currently built in a VM using GitHub Actions' ubuntu-latest image.

https://github.com/NVIDIA/container-canary/blob/a4f5c799e64cdaec661d40b909d04ca505b3e191/.github/workflows/upload-release-assets.yaml#L11

As of today, that's Ubuntu 22.04 (actions/runner-images), which has glibc 2.35.

Those builds are dynamically linking to glibc, and using some symbols from new-ish versions. As a result, using them on a just-slightly-older Linux environment (e.g. Ubuntu 20.04, which has glibc 2.31), results in errors like the following:

/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by /opt/work/bin/canary_linux_amd64)
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /opt/work/bin/canary_linux_amd64)

This proposes setting CGO_ENABLED=0 when cross-compiling for Linux, so the artifact will statically link in what it needs and therefore be usable on systems with older glibc.

Notes for Reviewers

How I tested this

built with this setting on and off on Ubuntu 22.04, tested on Ubuntu 20.04 (click for details) Built inside an Ubuntu 22.04 image ```shell docker run \ --rm \ -v $(pwd):/opt/work \ -w /opt/work \ -it ubuntu:22.04 \ bash apt-get update apt-get install -y --no-install-recommends \ build-essential \ ca-certificates \ git \ golang-go git config --global --add safe.directory /opt/work # build with default settings make package mv bin bin-cgo # build with CGO off export CGO_ENABLED=0 make package mv bin bin-no-cgo ``` Tried using those on Ubuntu 20.04. The CGO-enabled one failed to run. ```shell docker run \ --rm \ -v $(pwd):/opt/work:ro \ -it ubuntu:20.04 \ /opt/work/bin-cgo/canary_linux_amd64 version # /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by /opt/work/bin-cgo/canary_linux_amd64) # /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /opt/work/bin-cgo/canary_linux_amd64) ``` But the no-cgo one worked! ```shell docker run \ --rm \ -v $(pwd):/opt/work:ro \ -it ubuntu:20.04 \ /opt/work/bin-no-cgo/canary_linux_amd64 version # Container Canary # Version: a4f5c79-dirty # Go Version: go1.18.1 # Commit: a4f5c79 # OS/Arch: linux/amd64 # Built: 2024-05-24T17:12:44Z ``` And the no-cgo one worked validating an image! Ran the following outside of Docker, on an Ubuntu 20.04 VM. ```shell bin-no-cgo/canary_linux_amd64 validate \ --file https://raw.githubusercontent.com/NVIDIA/container-canary/main/examples/kubeflow.yaml \ "ghcr.io/dask/dask-notebook" ``` ```text Validating ghcr.io/dask/dask-notebook against kubeflow πŸ†” User ID is 1000 [passed] 🏠 Home directory is /home/jovyan [passed] πŸ‘© User is jovyan [passed] 🌏 Exposes an HTTP interface on port 8888 [passed] πŸ”“ Sets 'Access-Control-Allow-Origin: *' header [passed] 🧭 Correctly routes the NB_PREFIX [passed] validation passed ```

Why not set this in the CI environment?

I chose to set this inline in the 2 Linux builds in make package so that if you run make package locally on a Linux system, it'll produce a similar artifact to the one produced in CI. To hopefully improve the chance of local tests catching issues.

But happy to change to any of these alternatives if someone has a compelling reason:

Won't statically linking make the binary bigger?

I didn't find any meaningful change in binary size as a result of doing this. With and without CGO_ENABLED, canary_linux_amd64 was about 21MB.

References

jacobtomlinson commented 3 months ago

I've just tagged v0.3.2 which will have statically linked linux binaries. Thanks!