Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide linux/arm64 Docker images #79

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0dbd851
Provide linux/arm64 images for m1s
ianks Nov 13, 2022
223f50d
Merge branch 'master' into linux/arm64
ianks Dec 16, 2022
e4672bd
Use matrix
ianks Dec 16, 2022
0b130a7
Translate docker platform to manylinux image slug
ianks Dec 16, 2022
8fc03f4
Merge branch 'master' into linux/arm64
ianks Dec 16, 2022
a3e2954
s/DOCKER_PLATFORM/DOCKER_BUILD_PLATFORM
ianks Dec 16, 2022
d4857ff
Remove all refs to specific dpkg archs
ianks Dec 17, 2022
7bf3aa5
Prepare mingw32-ucrt before build
ianks Dec 17, 2022
079d0cb
Sorry 32bit, later
ianks Dec 17, 2022
67b3e12
More dkpg stuff
ianks Dec 17, 2022
a51486e
Fix typo
ianks Dec 17, 2022
0403fe6
Erbify
ianks Dec 17, 2022
19be52a
So many aliases
ianks Dec 17, 2022
b8c3992
Use x86-64 mingw deb pkg always
ianks Dec 17, 2022
8a26e13
[linux/arm64] Add tests to the matrix for docker platform
ianks Dec 17, 2022
1c0461b
[linux/arm64] [linux/amd64] Get the slash out of the extra tag
ianks Dec 17, 2022
d56306f
[linux/arm64] [linux/amd64] Use correct ref to commit message
ianks Dec 17, 2022
d572b34
[linux/arm64] [linux/amd64] Use correct ref to commit message
ianks Dec 17, 2022
581c626
[linux/arm64] [linux/amd64] Use correct ref to commit message
ianks Dec 17, 2022
63e23dd
[linux/arm64] Try fix upload container via commit
ianks Dec 17, 2022
191fdcb
[linux/arm64] Use own platform manifests
ianks Dec 17, 2022
2917d31
Merge branch 'master' into linux/arm64
ianks Dec 17, 2022
d2f3e60
[linux/arm64] Adjust mk_osxcross to reference generic archdir
ianks Dec 17, 2022
2558eb8
[linux/arm64] Host vs foreign arch
ianks Dec 17, 2022
034db51
[linux/arm64] Use debian multiarch, dunno how to do manylinux....
ianks Dec 17, 2022
fbe2f20
[linux/arm64] Cleanup multiarch stuff
ianks Dec 17, 2022
b489f4f
[linux/arm64] Cleanup multiarch stuff
ianks Dec 17, 2022
4cced66
[linux/arm64] Another guard
ianks Dec 17, 2022
ccfaa41
[linux/arm64] Install both types of pkgs
ianks Dec 17, 2022
41cae4e
[linux/arm64] Another guard
ianks Dec 17, 2022
7608813
[linux/arm64] Manipulate sources
ianks Dec 17, 2022
dfbedba
[linux/arm64] Derive lsb_relese
ianks Dec 17, 2022
44a653a
[linux/arm64] Only install multiarch when host is arm64
ianks Dec 17, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 55 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,37 +28,70 @@ jobs:
- x86-mingw32
- x64-mingw-ucrt
- x64-mingw32
- x86-linux
# - x86-linux
- x86_64-linux
- x86_64-darwin
- arm64-darwin
- arm-linux
- aarch64-linux
- jruby
docker-platform-cpu:
- amd64
- arm64

runs-on: ubuntu-latest
env:
PLATFORM: ${{ matrix.platform }}
DOCKER_BUILD_PLATFORM: linux/${{ matrix.docker-platform-cpu }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Cache Docker layers
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: tmp/build-cache
key: ${{ runner.os }}-${{ matrix.platform }}-buildx-${{ github.sha }}
key: ${{ runner.os }}-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}-buildx-${{ github.sha }}
# TODO: remove last key
restore-keys: |
${{ runner.os }}-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}-buildx
${{ runner.os }}-${{ matrix.platform }}-buildx

- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.0"
bundler-cache: true # runs 'bundle install' and caches installed gems automatically

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Build docker image
id: buildx
run: |
echo "::group::Preparing docker build"
docker buildx create --driver docker-container --use
bundle exec rake build:${PLATFORM} RCD_DOCKER_BUILD="docker buildx build --cache-from=type=local,src=tmp/build-cache --cache-to=type=local,dest=tmp/build-cache-new --load"
extra_tag="rcd-${PLATFORM}-${{ matrix.docker-platform-cpu }}-${{ github.sha }}"
docker_build="docker buildx build --platform=$DOCKER_BUILD_PLATFORM --cache-from=type=local,src=tmp/build-cache --cache-to=type=local,dest=tmp/build-cache-new --load -t $extra_tag"
if bundle exec rake -T | grep -q "prepare:${PLATFORM}"; then
echo "::info::Preparing docker image for ${PLATFORM}"
bundle exec rake prepare:${PLATFORM} RCD_DOCKER_BUILD="$docker_build"
fi
echo "::endgroup::"

bundle exec rake build:${PLATFORM} RCD_DOCKER_BUILD="$docker_build"

if [[ "${{ contains(github.event.head_commit.message, matrix.docker-platform-cpu) }}" == "true" ]]; then
echo "::info::Saving docker image $extra_tag"
docker save -o "tmp/${extra_tag}.tar" $extra_tag
echo "image-tarball=tmp/${extra_tag}.tar" >> $GITHUB_OUTPUT
fi

- name: Upload Docker image tarball
if: ${{ steps.buildx.outputs.image-tarball != '' }}
uses: actions/upload-artifact@v3
with:
name: docker-save-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}-${{ github.sha }}
path: ${{ steps.buildx.outputs.image-tarball }}
retention-days: 1

- name: Move build cache and remove outdated layers
run: |
Expand All @@ -77,7 +110,7 @@ jobs:
- name: Upload binary gem
uses: actions/upload-artifact@v2
with:
name: gem-${{ matrix.platform }}
name: gem-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}
path: test/rcd_test/pkg/*-*-*.gem

- if: matrix.platform == 'jruby'
Expand All @@ -103,11 +136,11 @@ jobs:
name: Upload static binary gem
uses: actions/upload-artifact@v2
with:
name: gem-${{ matrix.platform }}-static
name: gem-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}-static
path: test/rcd_test/pkg/*-*-*.gem

job_test_native:
name: Test (${{matrix.ruby}}, ${{matrix.platform}})
name: Test (${{matrix.ruby}}, ${{matrix.platform}}, ${{ matrix.docker-platform-cpu }})
needs: docker_build
strategy:
fail-fast: false
Expand Down Expand Up @@ -144,16 +177,16 @@ jobs:

runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- run: ruby --version
- name: Download gem-${{matrix.platform}}
- name: Download gem-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}
uses: actions/download-artifact@v2
with:
name: gem-${{ matrix.platform }}
- name: Install gem-${{matrix.platform}}
name: gem-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}
- name: Install gem-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}
run: gem install --local *.gem --verbose
- name: Run tests
run: |
Expand Down Expand Up @@ -188,16 +221,16 @@ jobs:

runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- run: ruby --version
- name: Download gem-${{matrix.platform}}-static
- name: Download gem-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}-static
uses: actions/download-artifact@v2
with:
name: gem-${{ matrix.platform }}-static
- name: Install gem-${{matrix.platform}}-static
name: gem-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}-static
- name: Install gem-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}-static
run: gem install --local *.gem --verbose
- name: Run tests
run: |
Expand Down Expand Up @@ -230,13 +263,14 @@ jobs:

runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Download gem-${{matrix.platform}}
- uses: actions/checkout@v3
- name: Download gem-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}
uses: actions/download-artifact@v2
with:
name: gem-${{ matrix.platform }}
name: gem-${{ matrix.platform }}-${{ matrix.docker-platform-cpu }}
- name: Build image and Run tests
run: |
docker buildx create --driver docker-container --use
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
docker build --rm --build-arg from_image=${{matrix.from_image}} -t ruby-test -f test/env/Dockerfile.${{matrix.dockerfile}} .
docker run --rm -t --network=host -v `pwd`:/build ruby-test
docker buildx build --platform=$DOCKER_BUILD_PLATFORM --rm --build-arg from_image=${{matrix.from_image}} -t ruby-test -f test/env/Dockerfile.${{matrix.dockerfile}} .
docker run --platform=$DOCKER_BUILD_PLATFORM --rm -t --network=host -v `pwd`:/build ruby-test
26 changes: 16 additions & 10 deletions Dockerfile.mri.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<%
image = case platform
when /x86_64-linux/ then "quay.io/pypa/manylinux2014_x86_64"
when /x86-linux/ then "quay.io/pypa/manylinux2014_i686"
else "ubuntu:20.04"
when /x86_64-linux/, /x86-linux/
manylinux_image
else
"ubuntu:20.04"
end

manylinux = !!(image =~ /manylinux/)
%>
FROM <%= image %>
Expand All @@ -21,9 +23,13 @@ RUN rm -f /usr/local/bin/sudo && \
echo "%sudo ALL=(ALL) ALL" >> /etc/sudoers
<% else %>
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -y update && \
apt-get install -y sudo wget autoconf cmake curl git-core pkg-config build-essential xz-utils unzip gnupg2 dirmngr zlib1g-dev libreadline-dev libsqlite0-dev libssl-dev libyaml-dev libffi-dev && \
rm -rf /var/lib/apt/lists/*

COPY ./build/apt_install_multiarch.sh /
RUN /apt_install_multiarch.sh <%= foreign_dpkg_arch %> zlib1g-dev libreadline-dev libsqlite0-dev libssl-dev libyaml-dev libffi-dev

RUN apt-get -y -qq update && \
apt-get -y -qq install sudo wget autoconf cmake curl git-core pkg-config build-essential xz-utils unzip gnupg2 dirmngr && \
rm -rf /var/lib/apt/lists/*;
<% end %>

# Add "rvm" as system group, to avoid conflicts with host GIDs typically starting with 1000
Expand Down Expand Up @@ -74,10 +80,10 @@ USER root

<% if platform=~/x64-mingw-ucrt/ %>
COPY --from=larskanis/mingw64-ucrt:20.04 \
/build/binutils-mingw-w64-x86-64_2.34-6ubuntu1.3+8.8_amd64.deb \
/build/g++-mingw-w64-x86-64_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_amd64.deb \
/build/gcc-mingw-w64-base_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_amd64.deb \
/build/gcc-mingw-w64-x86-64_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_amd64.deb \
/build/binutils-mingw-w64-x86-64_2.34-6ubuntu1.3+8.8_<%= host_dpkg_arch %>.deb \
/build/g++-mingw-w64-x86-64_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_<%= host_dpkg_arch %>.deb \
/build/gcc-mingw-w64-base_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_<%= host_dpkg_arch %>.deb \
/build/gcc-mingw-w64-x86-64_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_<%= host_dpkg_arch %>.deb \
/build/mingw-w64-common_7.0.0-2_all.deb \
/build/mingw-w64-x86-64-dev_7.0.0-2_all.deb \
/debs/
Expand Down
43 changes: 33 additions & 10 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,45 @@ DOCKERHUB_USER = ENV['DOCKERHUB_USER'] || "larskanis"
docker_build_cmd = Shellwords.split(ENV['RCD_DOCKER_BUILD'] || "docker build")

platforms = [
["x86-mingw32", "i686-w64-mingw32"],
["x64-mingw32", "x86_64-w64-mingw32"],
["x64-mingw-ucrt", "x86_64-w64-mingw32"],
["x86-linux", "i686-redhat-linux"],
["x86_64-linux", "x86_64-redhat-linux"],
["x86_64-darwin", "x86_64-apple-darwin"],
["arm64-darwin", "aarch64-apple-darwin"],
["arm-linux", "arm-linux-gnueabihf"],
["aarch64-linux", "aarch64-linux-gnu"],
["x86-mingw32", "i686-w64-mingw32", "i386"],
["x64-mingw32", "x86_64-w64-mingw32", "amd64"],
["x64-mingw-ucrt", "x86_64-w64-mingw32", "amd64"],
["x86-linux", "i686-redhat-linux", "i386"],
["x86_64-linux", "x86_64-redhat-linux", "amd64"],
["x86_64-darwin", "x86_64-apple-darwin", "amd64"],
["arm64-darwin", "aarch64-apple-darwin", "arm64"],
["arm-linux", "arm-linux-gnueabihf", "armhf"],
["aarch64-linux", "aarch64-linux-gnu", "arm64"],
]

namespace :build do

platforms.each do |platform, target|
platforms.each do |platform, target, foreign_dpkg_arch|
sdf = "Dockerfile.mri.#{platform}"

host_dpkg_arch = case ENV["DOCKER_BUILD_PLATFORM"]
when /arm64/
"arm64"
when /amd64/
"amd64"
else
if ENV["CI"]
raise "Couldnt infer dpkg arch for #{ENV["DOCKER_BUILD_PLATFORM"].inspect}"
else
"amd64"
end
end

# Native images to alleviate qemu slowness, and manylinux2014 provides per-arch
# images. But they are not yet conformant to the Docker platform spec (i.e.
# amd64/linux). We generate our own platformed manifests now (using
# scrip/remanifest-manylinux-multiplatform.sh), but you should be able to
# nuke that code soon, and rely on only the buildx `--platform` feature once
# manylinux finishes the feature.
#
# See: https://github.com/pypa/manylinux/issues/1306
manylinux_image = "rbsys/manylinux2014:2022-12-11-145d107"

desc "Build image for platform #{platform}"
task platform => sdf
task sdf do
Expand Down
39 changes: 39 additions & 0 deletions build/apt_install_multiarch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash

set -exuo pipefail
IFS=$'\n\t'

main() {
deb_host_arch="$(dpkg --print-architecture)"
lsb_release="$(grep VERSION_CODENAME < /etc/os-release | cut -d= -f2 | tr -d '"')"
deb_target_arch="$1"

shift

cross_packages=()
packages=("$@")

if [ "$deb_target_arch" != "$deb_host_arch" ] && [ "$deb_host_arch" = "arm64" ]; then
echo "Setting up multiarch support for $deb_target_arch" >&2
dpkg --add-architecture "$deb_target_arch"
cross_packages=("${packages[@]/%/:$deb_target_arch}")

# Qualify our current source lists to make sure debian doesn't infer stuff
sed -i "s/^deb http/deb [arch=$deb_host_arch] http/" /etc/apt/sources.list

# Add sources for ported target libs
echo "deb [arch=$deb_target_arch] http://ports.ubuntu.com/ubuntu-ports $lsb_release main universe restricted multiverse"
echo "deb [arch=$deb_target_arch] http://ports.ubuntu.com/ubuntu-ports $lsb_release-updates main universe restricted multiverse"
echo "deb [arch=$deb_target_arch] http://ports.ubuntu.com/ubuntu-ports $lsb_release-security main universe restricted multiverse"
else
echo "No need to set up multiarch support for $deb_target_arch"
fi

apt-get -qq -y update
apt-get -qq -y install "${packages[@]}" "${cross_packages[@]}"
rm -rf /var/lib/apt/lists/*

rm "$0"
}

main "$@"
2 changes: 1 addition & 1 deletion build/mk_osxcross.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ set -x
curl -L -o MacOSX11.1.sdk.tar.xz https://github.com/larskanis/MacOSX-SDKs/releases/download/11.1/MacOSX11.1.sdk.tar.xz
tar -xf MacOSX11.1.sdk.tar.xz -C .
cp -rf /usr/lib/llvm-10/include/c++ MacOSX11.1.sdk/usr/include/c++
cp -rf /usr/include/x86_64-linux-gnu/c++/9/bits/ MacOSX11.1.sdk/usr/include/c++/v1/bits
cp -rf /usr/include/"$(uname -m)"-linux-gnu/c++/9/bits/ MacOSX11.1.sdk/usr/include/c++/v1/bits
tar -cJf MacOSX11.1.sdk.tar.xz MacOSX11.1.sdk

set +x
Expand Down
3 changes: 2 additions & 1 deletion mingw64-ucrt/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

FROM ubuntu:20.04

ARG DEBIAN_FRONTEND=noninteractive
Expand Down Expand Up @@ -32,7 +33,7 @@ RUN cd mingw-w64-* && \

# Install UCRT enabled deb-packages
RUN dpkg -i mingw-w64-common_7.0.0-2_all.deb \
mingw-w64-tools_7.0.0-2_amd64.deb \
mingw-w64-tools_7.0.0-2_$(dpkg --print-architecture).deb \
mingw-w64-x86-64-dev_7.0.0-2_all.deb

# Download gcc-binutils sources for mingw
Expand Down
32 changes: 32 additions & 0 deletions script/remanifest-manylinux-multiplatform.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

set -euo pipefail
IFS=$'\n\t'

# A script to build and push a multi-arch image to Docker Hub, based on
# https://github.com/pypa/manylinux/issues/1306

repo="${DOCKERHUB_USER:-larskanis}"
tags=("latest" "2022-12-11-145d107")
base_images=("manylinux2014" "manylinux_2_24")

for base_image in "${base_images[@]}"; do
for tag in "${tags[@]}"; do
echo Re-manifesting "$base_image":"$tag" >&2

docker pull --quiet quay.io/pypa/"$base_image"_aarch64:"$tag"
docker pull --quiet quay.io/pypa/"$base_image"_x86_64:"$tag"

docker tag quay.io/pypa/"$base_image"_x86_64:"$tag" "$repo"/"$base_image"_x86_64:"$tag"
docker tag quay.io/pypa/"$base_image"_aarch64:"$tag" "$repo"/"$base_image"_aarch64:"$tag"

docker push --quiet "$repo"/"$base_image"_x86_64:"$tag"
docker push --quiet "$repo"/"$base_image"_aarch64:"$tag"

docker manifest create "$repo"/"$base_image":"$tag" \
--amend "$repo"/"$base_image"_x86_64:"$tag" \
--amend "$repo"/"$base_image"_aarch64:"$tag"

docker manifest push "$repo"/"$base_image":"$tag"
done
done