From db2bf12bf8b76e650f43b66328ae8995a38183cc Mon Sep 17 00:00:00 2001 From: Yousaf Nabi Date: Thu, 5 Sep 2024 22:28:31 +0100 Subject: [PATCH] feat: support linux musl --- .github/workflows/test.yml | 6 +++++- Dockerfile.alpine | 10 ++++++++++ Dockerfile => Dockerfile.debian | 0 Makefile | 11 +++++++---- installer/installer.go | 27 ++++++++++++++------------- installer/installer_test.go | 29 +++++++++++++++++++++++++---- 6 files changed, 61 insertions(+), 22 deletions(-) create mode 100644 Dockerfile.alpine rename Dockerfile => Dockerfile.debian (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 928ece2ac..de31ab60c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -68,11 +68,14 @@ jobs: test-containers: runs-on: ubuntu-latest - name: ${{ matrix.go-version }}-test-container + name: ${{ matrix.variant }}-${{ matrix.go-version }}-test-container strategy: fail-fast: false matrix: go-version: ["1.21", "1.22"] + variant: + - debian + - alpine steps: - uses: actions/checkout@v4 @@ -80,6 +83,7 @@ jobs: run: make docker_test_all env: GO_VERSION: ${{ matrix.go-version }} + IMAGE_VARIANT: ${{ matrix.variant }} finish: needs: [test,test-containers] diff --git a/Dockerfile.alpine b/Dockerfile.alpine new file mode 100644 index 000000000..6723ba712 --- /dev/null +++ b/Dockerfile.alpine @@ -0,0 +1,10 @@ +ARG VERSION=1.22 +FROM golang:${VERSION}-alpine + +RUN apk add --no-cache curl gcc musl-dev gzip openjdk17-jre bash protoc protobuf-dev make file + +COPY . /go/src/github.com/pact-foundation/pact-go + +WORKDIR /go/src/github.com/pact-foundation/pact-go + +CMD ["make", "test"] \ No newline at end of file diff --git a/Dockerfile b/Dockerfile.debian similarity index 100% rename from Dockerfile rename to Dockerfile.debian diff --git a/Makefile b/Makefile index 7f90ddbb2..cf6b63386 100755 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ PLUGIN_PACT_MATT_VERSION=0.1.1 PLUGIN_PACT_AVRO_VERSION=0.0.6 GO_VERSION?=1.22 +IMAGE_VARIANT?=debian ci:: docker deps clean bin test pact PACT_DOWNLOAD_DIR=/tmp ifeq ($(OS),Windows_NT) @@ -37,24 +38,26 @@ docker: docker compose up -d docker_build: - docker build -f Dockerfile --build-arg GO_VERSION=${GO_VERSION} -t pactfoundation/pact-go-test . + docker build -f Dockerfile.$(IMAGE_VARIANT) --build-arg GO_VERSION=${GO_VERSION} -t pactfoundation/pact-go-test-$(IMAGE_VARIANT) . + docker_test: docker_build docker run \ -e LOG_LEVEL=INFO \ --rm \ - pactfoundation/pact-go-test \ + -it \ + pactfoundation/pact-go-test-$(IMAGE_VARIANT) \ /bin/sh -c "make test" docker_pact: docker_build docker run \ -e LOG_LEVEL=INFO \ --rm \ - pactfoundation/pact-go-test \ + pactfoundation/pact-go-test-$(IMAGE_VARIANT) \ /bin/sh -c "make pact_local" docker_test_all: docker_build docker run \ -e LOG_LEVEL=INFO \ --rm \ - pactfoundation/pact-go-test \ + pactfoundation/pact-go-test-$(IMAGE_VARIANT) \ /bin/sh -c "make test && make pact_local" bin: diff --git a/installer/installer.go b/installer/installer.go index 3f59f2944..0687548e4 100644 --- a/installer/installer.go +++ b/installer/installer.go @@ -80,14 +80,6 @@ func NewInstaller(opts ...installerConfig) (*Installer, error) { log.Println("[WARN] amd64 architecture not detected, defaulting to x86_64. Behaviour may be undefined") } - // Only perform a check if current OS is linux - if runtime.GOOS == "linux" { - err := i.checkMusl() - if err != nil { - log.Println("[DEBUG] unable to check for presence musl library due to error:", err) - } - } - return i, nil } @@ -260,7 +252,13 @@ func (i *Installer) getDownloadURLForPackage(pkg string) (string, error) { return "", fmt.Errorf("unable to find package details for package: %s", pkg) } - return fmt.Sprintf(downloadTemplate, pkg, pkgInfo.version, osToLibName[i.os], i.os, i.arch, osToExtension[i.os]), nil + if checkMusl() && i.os == linux { + return fmt.Sprintf(downloadTemplate, pkg, pkgInfo.version, osToLibName[i.os], i.os, i.arch+"-musl", osToExtension[i.os]), nil + } else { + return fmt.Sprintf(downloadTemplate, pkg, pkgInfo.version, osToLibName[i.os], i.os, i.arch, osToExtension[i.os]), nil + + } + } func (i *Installer) getLibDstForPackage(pkg string) (string, error) { @@ -331,20 +329,23 @@ func checkVersion(lib, version, versionRange string) error { } // checkMusl checks if the OS uses musl library instead of glibc -func (i *Installer) checkMusl() error { +func checkMusl() bool { lddPath, err := exec.LookPath("ldd") if err != nil { - return fmt.Errorf("could not find ldd in environment path") + return false } cmd := exec.Command(lddPath, "/bin/echo") out, err := cmd.CombinedOutput() + if err != nil { + return false + } if strings.Contains(string(out), "musl") { - log.Println("[WARN] Usage of musl library is known to cause problems, prefer using glibc instead.") + return true } - return err + return false } // download template structure: "https://github.com/pact-foundation/pact-reference/releases/download/PACKAGE-vVERSION/LIBNAME-OS-ARCH.EXTENSION.gz" diff --git a/installer/installer_test.go b/installer/installer_test.go index b492af492..dd6c85492 100644 --- a/installer/installer_test.go +++ b/installer/installer_test.go @@ -35,16 +35,37 @@ func TestInstallerDownloader(t *testing.T) { test Installer }{ { - name: "ffi lib - linux x86", + name: "ffi lib - linux x86_64", pkg: FFIPackage, - want: fmt.Sprintf("https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v%s/libpact_ffi-linux-x86_64.so.gz", packages[FFIPackage].version), + want: func() string { + if checkMusl() { + return fmt.Sprintf("https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v%s/libpact_ffi-linux-x86_64-musl.so.gz", packages[FFIPackage].version) + } else { + return fmt.Sprintf("https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v%s/libpact_ffi-linux-x86_64.so.gz", packages[FFIPackage].version) + } + }(), test: Installer{ os: linux, arch: x86_64, }, }, { - name: "ffi lib - macos x86", + name: "ffi lib - linux aarch64", + pkg: FFIPackage, + want: func() string { + if checkMusl() { + return fmt.Sprintf("https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v%s/libpact_ffi-linux-aarch64-musl.so.gz", packages[FFIPackage].version) + } else { + return fmt.Sprintf("https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v%s/libpact_ffi-linux-aarch64.so.gz", packages[FFIPackage].version) + } + }(), + test: Installer{ + os: linux, + arch: aarch64, + }, + }, + { + name: "ffi lib - macos x86_64", pkg: FFIPackage, want: fmt.Sprintf("https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v%s/libpact_ffi-macos-x86_64.dylib.gz", packages[FFIPackage].version), test: Installer{ @@ -62,7 +83,7 @@ func TestInstallerDownloader(t *testing.T) { }, }, { - name: "ffi lib - windows x86", + name: "ffi lib - windows x86_64", pkg: FFIPackage, want: fmt.Sprintf("https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v%s/pact_ffi-windows-x86_64.dll.gz", packages[FFIPackage].version), test: Installer{