diff --git a/.dockerignore b/.dockerignore index ee995cd..1ca6a33 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,11 @@ -/bin/ -/vendor/ +.DS_Store +.idea/ +.vscode/ + +vendor/ +bin/ + +moby-ryuk +moby-ryuk.exe + +Dockerfile diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 47e8a3d..208ec7d 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -1,40 +1,87 @@ name: Build multi-arch Docker Image on: + release: + types: [ published ] push: - branches: [main] + branches: [ main ] pull_request: +env: + RYUK_VERSION: ${{ github.event.release.tag_name || github.sha }} + IS_RELEASE: ${{ (github.event_name == 'release' && github.event.action == 'published' && 'yes') || 'no' }} + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: '1.18' - - run: go version - - - name: Verify project - run: make verify - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v2 - - - name: Docker info - run: docker info - - name: Buildx inspect - run: docker buildx inspect - - - name: Build image - uses: docker/build-push-action@v3 - with: - context: . - file: ./Dockerfile - platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x - push: false - # Use a 'temp' tag, that won't be pushed, for non-release builds - tags: testcontainers/ryuk:${{ github.event.release.tag_name || 'temp' }} + - uses: actions/checkout@v3 + + - uses: actions/setup-go@v3 + with: + go-version: '1.18' + - run: go version + + - name: modVerify + run: go mod verify + + - name: modTidy + run: go mod tidy + + - name: ensure compilation + env: + GOOS: linux + run: go build + + - name: Test + run: go test -v ./... + + - name: Login to Docker Hub + if: ${{ github.event_name == 'release' && github.event.action == 'published' }} + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # Setup for buildx + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + + - name: Docker info + run: docker info + - name: Buildx inspect + run: docker buildx inspect + + # In case linux/s390x fails with tls issues: + # see https://github.com/testcontainers/moby-ryuk/pull/26 + # and https://github.com/testcontainers/moby-ryuk/pull/40 + - name: Cross Build for Linux and Windows + run: | + ./build-multiarch.sh testcontainers/ryuk:${RYUK_VERSION} ${IS_RELEASE} + + run-images: + if: ${{ github.event_name == 'release' && github.event.action == 'published' }} + needs: build + strategy: + fail-fast: false + matrix: + os: [ubuntu-22.04, windows-2022] + + runs-on: ${{ matrix.os }} + + steps: + - name: Pull Ryuk + run: docker pull testcontainers/ryuk:${RYUK_VERSION} + + - name: Run Ryuk on Linux + if: ${{ matrix.os == 'ubuntu-22.04' }} + run: docker run -v /var/run/docker.sock:/var/run/docker.sock testcontainers/ryuk:${RYUK_VERSION} + + - name: Run Ryuk on Windows + if: ${{ matrix.os == 'windows-2022' }} + run: docker run -v //./pipe/docker_engine://./pipe/docker_engine testcontainers/ryuk:${RYUK_VERSION} + continue-on-error: true diff --git a/.github/workflows/publish-docker-image.yml b/.github/workflows/publish-docker-image.yml deleted file mode 100644 index 17c6f0b..0000000 --- a/.github/workflows/publish-docker-image.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Release multi-arch Docker Image - -on: - release: - types: [published] - -jobs: - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-go@v3 - with: - go-version: '1.18' - - run: go version - - - name: Login to Docker Hub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Verify project - run: make verify - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v2 - - - name: Docker info - run: docker info - - name: Buildx inspect - run: docker buildx inspect - - - name: Build and push image - uses: docker/build-push-action@v3 - with: - context: . - file: ./Dockerfile - platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x - # Only push if we are publishing a release - push: true - tags: testcontainers/ryuk:${{ github.event.release.tag_name }} diff --git a/.gitignore b/.gitignore index dce3433..8b7aacf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ vendor/ bin/ + +moby-ryuk +moby-ryuk.exe diff --git a/Dockerfile b/Dockerfile index 67910b4..32321e1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,24 @@ -FROM golang:1.18 as workspace +ARG BASE_IMAGE + +FROM --platform=${BUILDPLATFORM} golang:1.18 AS workspace +LABEL builder=true + +ENV CGO_ENABLED=0 +ENV GOOS=${TARGETOS} +ENV GOARCH=${TARGETARCH} + WORKDIR /go/src/github.com/testcontainers/moby-ryuk COPY go.mod go.sum ./ RUN go mod download COPY . ./ -RUN make build +RUN cd /go/src/github.com/testcontainers/moby-ryuk && go get -d \ + && if [ "$TARGETARCH" = "arm" ]; then export GOARM="${TARGETVARIANT//v}"; fi; \ + go build -v -a \ + -ldflags "-s -w -extldflags \"-static\"" \ + -o /bin/moby-ryuk main.go; \ + chmod +x /bin/moby-ryuk -FROM alpine:3.13.6 +FROM ${BASE_IMAGE} RUN apk --no-cache add ca-certificates -COPY --from=workspace /go/src/github.com/testcontainers/moby-ryuk/bin/moby-ryuk /app -CMD ["/app"] +CMD ["/moby-ryuk"] +COPY --from=workspace /bin/moby-ryuk /moby-ryuk diff --git a/Dockerfile.windows b/Dockerfile.windows new file mode 100644 index 0000000..869b6af --- /dev/null +++ b/Dockerfile.windows @@ -0,0 +1,24 @@ +ARG BASE_IMAGE + +FROM --platform=${BUILDPLATFORM} golang:1.18 AS workspace +LABEL builder=true + +ENV CGO_ENABLED=0 +ENV GOOS=windows +ENV GOARCH=amd64 + +WORKDIR /go/src/github.com/testcontainers/moby-ryuk +COPY go.mod go.sum ./ +RUN go mod download +COPY . ./ +RUN echo $GOOS +RUN echo $GOARCH + +RUN go build -v -a \ + -ldflags "-s -w -extldflags \"-static\"" \ + -o /bin/moby-ryuk main.go; \ + chmod +x /bin/moby-ryuk + +FROM ${BASE_IMAGE} +CMD ["/moby-ryuk.exe"] +COPY --from=workspace /bin/moby-ryuk /moby-ryuk.exe diff --git a/Makefile b/Makefile deleted file mode 100644 index 847c2cb..0000000 --- a/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -.PHONY: compile build build_all fmt lint test vet - -SOURCE_FOLDER := . - -BINARY_PATH ?= ./bin/moby-ryuk - -GOARCH ?= amd64 - -ifdef GOOS -BINARY_PATH :=$(BINARY_PATH).$(GOOS)-$(GOARCH) -endif - -default: build - -build_all: vet fmt - for GOOS in darwin linux windows; do \ - $(MAKE) compile GOOS=$$GOOS GOARCH=amd64 ; \ - done - -compile: - CGO_ENABLED=0 go build -v -ldflags '-s' -o $(BINARY_PATH) $(SOURCE_FOLDER)/ - -run: - go run $(SOURCE_FOLDER)/main.go - -build: vet fmt compile - -fmt: - go fmt $(SOURCE_FOLDER)/... - -vet: - go vet $(SOURCE_FOLDER)/... - -lint: - go lint $(SOURCE_FOLDER)/... - -test: - go test $(SOURCE_FOLDER)/... - -verify: fmt vet test diff --git a/README.md b/README.md index 5a4ef5c..ce188a1 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ This project helps you to remove containers/networks/volumes/images by given fil $ ./bin/moby-ryuk -p 8080 $ # You can also run it with Docker - $ docker run -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 quay.io/testcontainers/ryuk + $ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 testcontainers/ryuk + $ # Example for Windows + $ docker run --rm -v //./pipe/docker_engine://./pipe/docker_engine -p 8080:8080 testcontainers/ryuk 1. Connect via TCP: diff --git a/build-multiarch.sh b/build-multiarch.sh new file mode 100755 index 0000000..2b7641f --- /dev/null +++ b/build-multiarch.sh @@ -0,0 +1,67 @@ +TARGETIMAGE=${1:-target/image:ci} +IS_RELEASE=${2:-no} +LINUXBASE="alpine:3.16.1" +WINBASE="mcr.microsoft.com/windows/nanoserver" +OSVERSIONS=("ltsc2019" "ltsc2022") +MANIFESTLIST="" +BUILDX_PUSH="" + +if [ "${IS_RELEASE}" = "yes" ]; then + export BUILDX_PUSH="--push"; +fi; + +echo "Building for Linux" +docker buildx build \ + --platform linux/amd64,linux/arm64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6 \ + ${BUILDX_PUSH} \ + --pull \ + --build-arg BASE_IMAGE=${LINUXBASE} \ + --label "org.opencontainers.image.base.name=${LINUXBASE}" \ + -t ${TARGETIMAGE} \ + -f Dockerfile \ + . + +for VERSION in ${OSVERSIONS[*]} +do + echo "Building Windows ${VERSION}" + docker buildx build \ + --platform windows/amd64 \ + ${BUILDX_PUSH} \ + --pull \ + --build-arg BASE_IMAGE=${WINBASE}:${VERSION} \ + --label "org.opencontainers.image.base.name=${WINBASE}:${VERSION}" \ + -t "${TARGETIMAGE}-${VERSION}" \ + -f Dockerfile.windows \ + . + MANIFESTLIST+="${TARGETIMAGE}-${VERSION} " +done + +# Get images from Linux manifest list, append and annotate Windows images and overwrite in registry +# Not sure the remove of the manifest is needed +docker manifest rm ${TARGETIMAGE} > /dev/null 2>&1 +# if you push the Docker images the manifest is not locally +docker pull ${TARGETIMAGE} +lin_images=$(docker manifest inspect ${TARGETIMAGE} | jq -r '.manifests[].digest') + +echo "Creating Linux manifest: ${lin_images}" +docker manifest create ${TARGETIMAGE} ${MANIFESTLIST} ${lin_images//sha256:/${TARGETIMAGE%%:*}@sha256:} + +for VERSION in ${OSVERSIONS[*]} +do + # Not sure the remove of the manifest is needed + echo "Annotating Windows platforms to the manifest: ${WINBASE}:${VERSION}" + docker manifest rm ${WINBASE}:${VERSION} > /dev/null 2>&1 + # if you push the Docker images the manifest is not locally + docker pull ${WINBASE}:${VERSION} + full_version=$(docker manifest inspect ${WINBASE}:${VERSION} |jq -r '.manifests[]|.platform|."os.version"'| sed 's@.*:@@') || true; + docker manifest annotate \ + --os-version ${full_version} \ + --os windows \ + --arch amd64 \ + ${TARGETIMAGE} "${TARGETIMAGE}-${VERSION}" +done + +if [ "${IS_RELEASE}" = "yes" ]; then + echo "Pushing manifest to ${TARGETIMAGE}" + docker manifest push ${TARGETIMAGE} +fi