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 23 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
16 changes: 9 additions & 7 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 Down Expand Up @@ -74,10 +76,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_<%= dpkg_arch %>.deb \
/build/g++-mingw-w64-x86-64_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_<%= dpkg_arch %>.deb \
/build/gcc-mingw-w64-base_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_<%= dpkg_arch %>.deb \
/build/gcc-mingw-w64-x86-64_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_<%= 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
172 changes: 172 additions & 0 deletions Dockerfile.mri.x64-mingw-ucrt
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -y update && \
apt-get install -y curl git-core xz-utils build-essential zlib1g-dev libreadline-dev libssl-dev wget unzip sudo gnupg2 dirmngr cmake pkg-config autoconf && \
rm -rf /var/lib/apt/lists/*

# Add "rvm" as system group, to avoid conflicts with host GIDs typically starting with 1000
RUN groupadd -r rvm && useradd -r -g rvm -G sudo -p "" --create-home rvm

# Make sure rvm and later settings are available in interactive and non-interactive shells
RUN echo "source /etc/profile.d/rvm.sh" >> /etc/rubybashrc && \
echo "source /etc/rubybashrc" >> /etc/bashrc && \
echo "source /etc/rubybashrc" >> /etc/bash.bashrc
ENV BASH_ENV /etc/rubybashrc

USER rvm

RUN mkdir ~/.gnupg && \
chmod 700 ~/.gnupg && \
echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf

# install rvm, RVM 1.26.0+ has signed releases, source rvm for usage outside of package scripts
RUN gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB && \
(curl -L http://get.rvm.io | sudo bash) && \
bash -c " \
source /etc/rubybashrc && \
rvm autolibs disable && \
rvmsudo rvm cleanup all "

# Import patch files for ruby and gems
COPY build/patches /home/rvm/patches/

# install rubies and fix permissions on
ENV RVM_RUBIES 2.5.9 3.1.0
RUN bash -c " \
export CFLAGS='-s -O3 -fno-fast-math -fPIC' && \
for v in ${RVM_RUBIES} ; do \
rvm install \$v --patch \$(echo ~/patches/ruby-\$v/* | tr ' ' ','); \
done && \
rvm cleanup all && \
find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "

# Install rake-compiler and typical gems in all Rubies
# do not generate documentation for gems
# TODO: stop pinning rubygems to 3.3.20 once https://github.com/rake-compiler/rake-compiler/pull/209 is merged
RUN echo "gem: --no-ri --no-rdoc" >> ~/.gemrc && \
bash -c " \
rvm all do gem update --system=3.3.20 --no-document && \
rvm all do gem install --no-document bundler 'bundler:~>1.16' 'rake-compiler:1.1.6' hoe mini_portile rubygems-tasks mini_portile2 && \
find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "

# Install rake-compiler's cross rubies in global dir instead of /root
RUN sudo mkdir -p /usr/local/rake-compiler && \
sudo chown rvm.rvm /usr/local/rake-compiler && \
ln -s /usr/local/rake-compiler ~/.rake-compiler

# Add cross compilers for Windows and Linux
USER root

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/mingw-w64-common_7.0.0-2_all.deb \
/build/mingw-w64-x86-64-dev_7.0.0-2_all.deb \
/debs/
RUN dpkg -i /debs/*.deb


RUN bash -c " \
rvm alias create default 3.1.0 && \
rvm use default "



# Patch rake-compiler to build and install static libraries for Linux rubies
USER rvm
COPY build/patches2 /home/rvm/patches/
RUN bash -c " \
for v in ${RVM_RUBIES} ; do \
cd /usr/local/rvm/gems/ruby-\$v/gems/rake-compiler-1.1.6 && \
echo applying patches to ruby-\$v /home/rvm/patches/rake-compiler-1.1.6/*.patch && \
( git apply /home/rvm/patches/rake-compiler-1.1.6/*.patch || true ) \
done "

# Patch rubies for cross build
#USER root
#RUN bash -c " \
# for v in 2.7.0 3.0.0 3.1.0 ; do \
# curl -SL http://cache.ruby-lang.org/pub/ruby/\${v:0:3}/ruby-\$v.tar.xz | tar -xJC /root/ && \
# cd /root/ruby-\$v && \
# git apply /home/rvm/patches/ruby-\$v/*.patch && \
# cd .. && \
# mkdir -p /usr/local/rake-compiler/sources/ && \
# tar cjf /usr/local/rake-compiler/sources/ruby-\$v.tar.bz2 ruby-\$v && \
# chown rvm /usr/local/rake-compiler -R && \
# rm -rf /root/ruby-\$v ; \
# done "
#USER rvm

ENV XRUBIES 3.2.0-rc1
# Build xruby versions in parallel
# Then cleanup all build artifacts
RUN bash -c " \
rvm use 3.1.0 && \
export CPPFLAGS='-D__USE_MINGW_ANSI_STDIO=1' && \
export CFLAGS='-O1 -fno-omit-frame-pointer -fno-fast-math -fstack-protector-strong -s' && \
export LDFLAGS='-pipe -s' && \
export LIBS='-l:libssp.a' && \
\
export MAKE='make V=1 -j`nproc`' && \
rake-compiler cross-ruby VERSION=$XRUBIES HOST=x86_64-w64-mingw32 && \
rm -rf ~/.rake-compiler/builds ~/.rake-compiler/sources && \
find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "
ENV XRUBIES 3.1.0
# Build xruby versions in parallel
# Then cleanup all build artifacts
RUN bash -c " \
rvm use 3.1.0 && \
export CPPFLAGS='-D__USE_MINGW_ANSI_STDIO=1' && \
export CFLAGS='-O1 -fno-omit-frame-pointer -fno-fast-math -fstack-protector-strong -s' && \
export LDFLAGS='-pipe -s' && \
export LIBS='-l:libssp.a' && \
\
export MAKE='make V=1 -j`nproc`' && \
rake-compiler cross-ruby VERSION=$XRUBIES HOST=x86_64-w64-mingw32 && \
rm -rf ~/.rake-compiler/builds ~/.rake-compiler/sources && \
find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "


# RubyInstaller doesn't install libgcc -> link it static.
RUN find /usr/local/rake-compiler/ruby/*mingw*/ -name rbconfig.rb | while read f ; do sed -i 's/."LDFLAGS". = "/&-static-libgcc /' $f ; done
# Raise Windows-API to Vista (affects ruby < 2.6 only)
RUN find /usr/local/rake-compiler/ruby -name rbconfig.rb | while read f ; do sed -i 's/0x0501/0x0600/' $f ; done
# Don't link to static libruby
RUN find /usr/local/rake-compiler/ruby -name lib*-ruby*.dll.a | while read f ; do n=`echo $f | sed s/.dll//` ; mv $f $n ; done

USER root

# Fix paths in rake-compiler/config.yml
RUN sed -i -- "s:/root/.rake-compiler:/usr/local/rake-compiler:g" /usr/local/rake-compiler/config.yml


# Install wrappers for strip commands as a workaround for "Protocol error" in boot2docker.
COPY build/strip_wrapper /root/
RUN mv /usr/bin/x86_64-w64-mingw32-strip /usr/bin/x86_64-w64-mingw32-strip.bin && \
ln /root/strip_wrapper /usr/bin/x86_64-w64-mingw32-strip

# Use posix pthread for mingw so that C++ standard library for thread could be
# available such as std::thread, std::mutex, so on.
# https://sourceware.org/pthreads-win32/
RUN printf "1\n" | update-alternatives --config x86_64-w64-mingw32-gcc && \
printf "1\n" | update-alternatives --config x86_64-w64-mingw32-g++



# Install SIGINT forwarder
COPY build/sigfw.c /root/
RUN gcc $HOME/sigfw.c -o /usr/bin/sigfw

# Install user mapper
COPY build/runas /usr/bin/
COPY build/rcd-env.sh /etc/profile.d/
RUN echo "source /etc/profile.d/rcd-env.sh" >> /etc/rubybashrc

# Install sudoers configuration
COPY build/sudoers /etc/sudoers.d/rake-compiler-dock

ENV RUBY_CC_VERSION 3.2.0:3.1.0:3.0.0:2.7.0:2.6.0:2.5.0:2.4.0

CMD bash
23 changes: 23 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,29 @@ namespace :build do
platforms.each do |platform, target|
sdf = "Dockerfile.mri.#{platform}"

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
Loading