Skip to content

Commit c193c38

Browse files
committed
Add Linux aarch64 support for bioconda-utils
Signed-off-by: Yikun Jiang <yikunkero@gmail.com>
1 parent b6b674c commit c193c38

File tree

6 files changed

+130
-15
lines changed

6 files changed

+130
-15
lines changed

.github/workflows/build-image.yml

+17-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,15 @@ jobs:
1414
build:
1515
name: Build image
1616
runs-on: ubuntu-20.04
17-
17+
strategy:
18+
matrix:
19+
include:
20+
- dockerfile: Dockerfile.aarch64
21+
arch: arm64
22+
image: bioconda-utils-build-env-cos7-aarch64
23+
- dockerfile: Dockerfile
24+
arch: amd64
25+
image: bioconda-utils-build-env-cos7
1826
steps:
1927
- uses: actions/checkout@v3
2028
with:
@@ -28,16 +36,22 @@ jobs:
2836
# printf %s "::set-output name=tag::${tag#v}"
2937
printf %s "tag=${tag#v}" >> $GITHUB_OUTPUT
3038
39+
- name: Install qemu dependency
40+
run: |
41+
sudo apt-get update
42+
sudo apt-get install -y qemu-user-static
43+
3144
- name: Build image
3245
id: buildah-build
3346
uses: redhat-actions/buildah-build@v2
3447
with:
35-
image: bioconda-utils-build-env-cos7
48+
image: ${{ matrix.image }}
49+
arch: ${{ matrix.arch }}
3650
tags: >-
3751
latest
3852
${{ steps.get-tag.outputs.tag }}
3953
dockerfiles: |
40-
./Dockerfile
54+
./${{ matrix.dockerfile }}
4155
4256
- name: Test built image
4357
run: |

.github/workflows/release-please.yml

+17-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ name: release-please
88
jobs:
99
release-please:
1010
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
include:
14+
- dockerfile: Dockerfile.aarch64
15+
arch: arm64
16+
image: bioconda-utils-build-env-cos7-aarch64
17+
- dockerfile: Dockerfile
18+
arch: amd64
19+
image: bioconda-utils-build-env-cos7
1120
steps:
1221

1322
- uses: GoogleCloudPlatform/release-please-action@v2
@@ -28,17 +37,23 @@ jobs:
2837
tag=${{ steps.release.outputs.tag_name }}
2938
printf %s "::set-output name=tag::${tag#v}"
3039
40+
- name: Install qemu dependency
41+
run: |
42+
sudo apt-get update
43+
sudo apt-get install -y qemu-user-static
44+
3145
- name: Build Image
3246
if: ${{ steps.release.outputs.release_created }}
3347
id: buildah-build
3448
uses: redhat-actions/buildah-build@v2
3549
with:
36-
image: bioconda-utils-build-env-cos7
50+
image: ${{ matrix.image }}
51+
arch: ${{ matrix.arch }}
3752
tags: >-
3853
latest
3954
${{ steps.get-tag.outputs.tag }}
4055
dockerfiles: |
41-
./Dockerfile
56+
./${{ matrix.dockerfile }}
4257
4358
- name: Test Built Image
4459
if: ${{ steps.release.outputs.release_created }}

Dockerfile.aarch64

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Specify the base image to support multi-arch images, such as
2+
# - 'quay.io/condaforge/linux-anvil-aarch64' for Linux aarch64
3+
# - 'quay.io/condaforge/linux-anvil-cos7-x86_64' for Linux x86_64
4+
ARG BASE_IMAGE=quay.io/condaforge/linux-anvil-aarch64
5+
6+
FROM quay.io/condaforge/linux-anvil-aarch64 as base
7+
8+
# Copy over C.UTF-8 locale from our base image to make it consistently available during build.
9+
COPY --from=quay.io/bioconda/base-glibc-busybox-bash /usr/lib/locale/C.UTF-8 /usr/lib/locale/C.UTF-8
10+
11+
# Provide system deps unconditionally until we are able to offer per-recipe installs.
12+
# (Addresses, e.g., "ImportError: libGL.so.1" in tests directly invoked by conda-build.)
13+
# Also install packages that have been installed historically (openssh-client).
14+
RUN yum install -y mesa-libGL-devel \
15+
&& \
16+
yum install -y openssh-clients \
17+
&& \
18+
yum clean all && \
19+
rm -rf /var/cache/yum/*
20+
21+
# This changes root's .condarc which ENTRYPOINT copies to /home/conda/.condarc later.
22+
RUN . /opt/conda/etc/profile.d/conda.sh && \
23+
conda config \
24+
--prepend channels defaults \
25+
--prepend channels bioconda \
26+
--prepend channels conda-forge \
27+
&& \
28+
{ conda config --remove repodata_fns current_repodata.json 2> /dev/null || true ; } && \
29+
conda config --prepend repodata_fns repodata.json && \
30+
conda config --set channel_priority flexible && \
31+
conda config --set auto_update_conda False
32+
33+
FROM base as build
34+
WORKDIR /tmp/repo
35+
COPY . ./
36+
RUN . /opt/conda/etc/profile.d/conda.sh && conda list
37+
RUN . /opt/conda/etc/profile.d/conda.sh && conda activate base && \
38+
pip wheel . && \
39+
mkdir - /opt/bioconda-utils && \
40+
cp ./bioconda_utils-*.whl \
41+
./bioconda_utils/bioconda_utils-requirements.txt \
42+
/opt/bioconda-utils/ \
43+
&& \
44+
chgrp -R lucky /opt/bioconda-utils && \
45+
chmod -R g=u /opt/bioconda-utils
46+
47+
# It's for multi-arch support. We do runtime involucro build here to solve
48+
# the chicken-and-egg conundrum. See also:
49+
# https://github.com/bioconda/bioconda-recipes/pull/40144
50+
FROM golang as involucro_build
51+
RUN wget https://github.com/involucro/involucro/archive/v1.1.2.tar.gz && \
52+
tar -zxvf v1.1.2.tar.gz && \
53+
mkdir -p src/github.com/involucro/ && \
54+
mv involucro-1.1.2/ src/github.com/involucro/involucro && \
55+
module_path="$( go env GOPATH )"/src/github.com/involucro/involucro/cmd/involucro && \
56+
GO111MODULE=auto GOBIN="$( go env GOBIN )" go build -o ./bin/involucro -ldflags="-s -X github.com/involucro/involucro/app.version=1.1.2" "${module_path}"
57+
58+
FROM base
59+
COPY --from=build /opt/bioconda-utils /opt/bioconda-utils
60+
COPY --from=involucro_build /go/bin/involucro /opt/conda/bin/
61+
RUN . /opt/conda/etc/profile.d/conda.sh && conda activate base && \
62+
# Make sure we get the (working) conda we want before installing the rest.
63+
sed -nE \
64+
'/^conda([><!=~ ].+)?$/p' \
65+
/opt/bioconda-utils/bioconda_utils-requirements.txt \
66+
| xargs -r conda install --yes && \
67+
# Remove involucro line, build it in involucro_build stage
68+
sed -i '/^involucro/d' /opt/bioconda-utils/bioconda_utils-requirements.txt && \
69+
conda install --yes --file /opt/bioconda-utils/bioconda_utils-requirements.txt && \
70+
pip install --no-deps --find-links /opt/bioconda-utils bioconda_utils && \
71+
conda clean --yes --index --tarballs && \
72+
# Find files that are not already in group "lucky" and change their group and mode.
73+
find /opt/conda \
74+
\! -group lucky \
75+
-exec chgrp --no-dereference lucky {} + \
76+
\! -type l \
77+
-exec chmod g=u {} +
78+

bioconda_utils/bioconda_utils-requirements.txt

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ boa=0.9.*
99
conda-build=3.21.8
1010
conda-verify=3.1.*
1111
argh=0.26.* # CLI
12-
colorlog=3.1.* # Logging
12+
colorlog=4.8.* # Logging
1313
tqdm>=4.26 # Progress monitor
1414
ruamel_yaml=0.15.* # Recipe YAML parsing
1515
pyaml=17.12.* # Faster YAML parser (deprecate?)
1616
networkx=2.*
17-
pandas=0.23.*
17+
pandas=1.2.*
1818
numpy=1.19.* # Avoid breaking pandas on OSX
1919
libblas=*=*openblas # Avoid large mkl package (pulled in by pandas)
2020
boltons=18.*
21-
jsonschema=2.6.* # JSON schema verification
21+
jsonschema=3.2.* # JSON schema verification
2222
simplejson # Used by bioconda bot worker (NEEDED?)
2323
pyopenssl>=22.1 # Stay compatible with cryptography
2424

@@ -28,11 +28,11 @@ conda-forge-pinning=2022.08.25.15.20.42
2828
# tools
2929
anaconda-client=1.6.* # anaconda_upload
3030
involucro=1.1.* # mulled test and container build
31-
skopeo=0.1.35 # docker upload
31+
skopeo=1.11.* # docker upload
3232
git=2.* # well - git
3333

3434
# hosters - special regex not supported by RE
35-
regex=2018.08.29
35+
regex=2022.7.9
3636

3737
# asyncio
3838
aiohttp=3.8.* # HTTP lib
@@ -51,7 +51,7 @@ gidgethub=3.0.* # githubhandler
5151
pyjwt>=2.4.0 # githubhandler (JWT signing), needs >=2.4.0, CVE-2022-29217
5252

5353
# unknown
54-
beautifulsoup4=4.6.*
54+
beautifulsoup4=4.8.*
5555
galaxy-lib>=18.9.1
5656
jinja2>=2.10.1,<3
5757
markupsafe<2.1 # markupsafe 2.1 breaks jinja2

bioconda_utils/cli.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -423,12 +423,15 @@ def do_lint(recipe_folder, config, packages="*", cache=None, list_checks=False,
423423
than one worker, then make sure to give each a different offset!''')
424424
@arg('--keep-old-work', action='store_true', help='''Do not remove anything
425425
from environment, even after successful build and test.''')
426+
@arg('--docker-base-image', help='''Name of base image that can be used in\
427+
**dockerfile_template**.''')
426428
@enable_logging()
427429
def build(recipe_folder, config, packages="*", git_range=None, testonly=False,
428430
force=False, docker=None, mulled_test=False, build_script_template=None,
429431
pkg_dir=None, anaconda_upload=False, mulled_upload_target=None,
430432
build_image=False, keep_image=False, lint=False, lint_exclude=None,
431-
check_channels=None, n_workers=1, worker_offset=0, keep_old_work=False):
433+
check_channels=None, n_workers=1, worker_offset=0, keep_old_work=False,
434+
docker_base_image='quay.io/bioconda/bioconda-utils-build-env-cos7:{}'.format(VERSION.replace('+', '_'))):
432435
cfg = utils.load_config(config)
433436
setup = cfg.get('setup', None)
434437
if setup:
@@ -454,6 +457,7 @@ def build(recipe_folder, config, packages="*", git_range=None, testonly=False,
454457
use_host_conda_bld=use_host_conda_bld,
455458
keep_image=keep_image,
456459
build_image=build_image,
460+
docker_base_image=docker_base_image
457461
)
458462
else:
459463
docker_builder = None

bioconda_utils/docker_utils.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
import conda
6161
import conda_build
6262

63+
from conda import exports as conda_exports
64+
6365
from . import utils
6466
from . import __version__
6567

@@ -90,9 +92,10 @@
9092
#
9193
# Note that if the directory didn't exist on the host, then the staging area
9294
# will exist in the container but will be empty. Channels expect at least
93-
# a linux-64 and noarch directory within that directory, so we make sure it
94-
# exists before adding the channel.
95+
# a linux-64/linux-aarch64 and noarch directory within that directory, so we
96+
# make sure it exists before adding the channel.
9597
mkdir -p {self.container_staging}/linux-64
98+
mkdir -p {self.container_staging}/linux-aarch64
9699
mkdir -p {self.container_staging}/noarch
97100
touch {self.container_staging}/noarch/repodata.json
98101
conda config --add channels file://{self.container_staging} 2> >(
@@ -442,8 +445,9 @@ def build_recipe(self, recipe_dir, build_args, env, noarch=False):
442445

443446
# Write build script to tempfile
444447
build_dir = os.path.realpath(tempfile.mkdtemp())
448+
# conda_exports.subdir is {platform}-{arch} like: 'linux-64' 'linux-aarch64'
445449
script = self.build_script_template.format(
446-
self=self, arch='noarch' if noarch else 'linux-64')
450+
self=self, arch='noarch' if noarch else conda_exports.subdir)
447451
with open(os.path.join(build_dir, 'build_script.bash'), 'w') as fout:
448452
fout.write(script)
449453
build_script = fout.name

0 commit comments

Comments
 (0)