Skip to content

Commit d9930cc

Browse files
authored
Merge branch 'main' into chore/spark-update-hadoop-version
2 parents 5c52e48 + 3ffeae8 commit d9930cc

10 files changed

Lines changed: 927 additions & 66 deletions

File tree

.github/workflows/mirror.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ on:
1616
- registry.k8s.io/git-sync/git-sync
1717
- registry-1.docker.io/library/golang
1818
- registry-1.docker.io/dxflrs/garage
19+
- ghcr.io/astral-sh/uv
1920
image-index-manifest-tag:
2021
description: |
2122
The image index manifest tag, like 1.0.14 or v1.0.14

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file.
1717
- superset: Add `6.1.0` ([#1514]).
1818
- zookeeper: Add `3.9.5` ([#1515]).
1919
- hadoop: Add `3.5.0` and `3.4.3` ([#1511]).
20+
- airflow: Add `3.2.1` ([#1519]).
2021

2122
### Changed
2223

@@ -64,6 +65,7 @@ All notable changes to this project will be documented in this file.
6465
[#1514]: https://github.com/stackabletech/docker-images/pull/1514
6566
[#1515]: https://github.com/stackabletech/docker-images/pull/1515
6667
[#1518]: https://github.com/stackabletech/docker-images/pull/1518
68+
[#1519]: https://github.com/stackabletech/docker-images/pull/1519
6769
[#1520]: https://github.com/stackabletech/docker-images/pull/1520
6870
[#1521]: https://github.com/stackabletech/docker-images/pull/1521
6971
[#1525]: https://github.com/stackabletech/docker-images/pull/1525

airflow/Dockerfile

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,29 @@
44
# - SecretsUsedInArgOrEnv : OPA_AUTH_MANAGER is a false positive and breaks the build.
55

66
ARG GIT_SYNC_VERSION
7+
ARG UV_VERSION
78

89
# For updated versions check https://github.com/kubernetes/git-sync/releases
910
# which should contain a image location (e.g. registry.k8s.io/git-sync/git-sync:v3.6.8)
1011
FROM oci.stackable.tech/sdp/git-sync/git-sync:${GIT_SYNC_VERSION} AS gitsync-image
1112

13+
FROM oci.stackable.tech/stackable/astral-sh/uv:${UV_VERSION} AS uv-image
14+
1215
FROM local-image/shared/statsd-exporter AS statsd_exporter-builder
1316

1417
FROM local-image/vector AS opa-auth-manager-builder
1518

1619
ARG OPA_AUTH_MANAGER
1720
ARG PYTHON_VERSION
18-
ARG UV_VERSION
21+
ARG STACKABLE_USER_UID
1922

2023
COPY airflow/opa-auth-manager/${OPA_AUTH_MANAGER} /tmp/opa-auth-manager
2124

2225
WORKDIR /tmp/opa-auth-manager
2326

24-
RUN <<EOF
25-
microdnf update
26-
microdnf install python${PYTHON_VERSION}-pip
27-
microdnf clean all
27+
COPY --from=uv-image --chown=${STACKABLE_USER_UID}:0 /uv /uvx /bin/
2828

29-
pip${PYTHON_VERSION} install --no-cache-dir uv==${UV_VERSION}
29+
RUN <<EOF
3030

3131
# This folder is required by the tests to set up an sqlite database
3232
mkdir /root/airflow
@@ -46,7 +46,6 @@ ARG STACKABLE_USER_UID
4646
ARG NODEJS_VERSION
4747
ARG S3FS_VERSION
4848
ARG CYCLONEDX_BOM_VERSION
49-
ARG UV_VERSION
5049

5150
# Airflow "extras" packages are listed here: https://airflow.apache.org/docs/apache-airflow/stable/extra-packages-ref.html
5251
# They evolve over time and thus belong to the version-specific arguments.
@@ -62,6 +61,8 @@ ARG AIRFLOW_EXTRAS_EXTERNAL_SERVICES=""
6261
ARG AIRFLOW_EXTRAS_LOCALLY_INSTALLED_SOFTWARE=""
6362
ARG AIRFLOW_EXTRAS_OTHER=""
6463

64+
COPY --from=uv-image --chown=${STACKABLE_USER_UID}:0 /uv /uvx /bin/
65+
6566
RUN microdnf module enable -y nodejs:${NODEJS_VERSION} && \
6667
microdnf update && \
6768
microdnf install \
@@ -78,10 +79,6 @@ RUN microdnf module enable -y nodejs:${NODEJS_VERSION} && \
7879
libpq-devel \
7980
openldap-devel \
8081
openssl-devel \
81-
python${PYTHON_VERSION} \
82-
python${PYTHON_VERSION}-devel \
83-
python${PYTHON_VERSION}-pip \
84-
python${PYTHON_VERSION}-wheel \
8582
# The airflow odbc provider can compile without the development files (headers and libraries) (see https://github.com/stackabletech/docker-images/pull/683)
8683
unixODBC \
8784
# Needed for Airflow UI assets
@@ -103,23 +100,29 @@ COPY --chown=${STACKABLE_USER_UID}:0 airflow/stackable/patches/${PRODUCT_VERSION
103100

104101
WORKDIR /stackable
105102

106-
RUN <<EOF
103+
# Set a cache directory so we can mount the cache for layers that use it.
104+
ENV UV_CACHE_DIR=/var/cache/uv
105+
# Don't use links because they won't work after `COPY --from` in the final stage.
106+
ENV UV_LINK_MODE=copy
107+
# Store the uv-managed Python inside /stackable/ so it gets included in the
108+
# COPY --from=airflow-build-image step. Without this, the venv symlinks would
109+
# point to /usr/local/share/uv/python/... which is not copied to the final image.
110+
ENV UV_PYTHON_INSTALL_DIR=/stackable/python
111+
112+
# This installs the Python runtime
113+
RUN uv venv --python "${PYTHON_VERSION}" --system-site-packages /stackable/app
114+
115+
# Instead of activating the environment each time
116+
ENV VIRTUAL_ENV=/stackable/app
117+
118+
RUN --mount=type=cache,target=/var/cache/uv <<EOF
107119

108120
# Compose comma-delimited AIRFLOW_EXTRAS
109121
AIRFLOW_EXTRAS="$AIRFLOW_EXTRAS_CORE,$AIRFLOW_EXTRAS_META,$AIRFLOW_EXTRAS_PROVIDER_APACHE,$AIRFLOW_EXTRAS_EXTERNAL_SERVICES,$AIRFLOW_EXTRAS_LOCALLY_INSTALLED_SOFTWARE,$AIRFLOW_EXTRAS_OTHER"
110122

111123
# Removing duplicates
112124
AIRFLOW_EXTRAS=$(echo "$AIRFLOW_EXTRAS" | tr ',' '\n' | awk 'NF > 0 {if (!seen[$0]++) print $0}' | tr '\n' ',' | sed 's/,$//')
113125

114-
python${PYTHON_VERSION} -m venv --system-site-packages /stackable/app
115-
116-
source /stackable/app/bin/activate
117-
118-
# Upgrade pip to the latest version
119-
# Also install uv to get support for build constraints
120-
pip install --no-cache-dir --upgrade pip
121-
pip install --no-cache-dir uv==${UV_VERSION}
122-
123126
# Pin virtualenv due to a breaking change in 21.0.0 which is pulled
124127
# in by hatch.
125128
# See https://github.com/pypa/hatch/issues/2193
@@ -134,6 +137,7 @@ if [ -d "./airflow-core" ]; then
134137
cd airflow-core/src/airflow/ui
135138

136139
# build front-end assets
140+
# TODO: Consider making the pnpm version an ARG
137141
npm install -g pnpm@10.18.2
138142
pnpm install --frozen-lockfile
139143
pnpm run build
@@ -143,13 +147,14 @@ if [ -d "./airflow-core" ]; then
143147
cd ../../..
144148
/root/.local/bin/hatch build -t wheel
145149
# First install the full apache-airflow package to get all dependencies including database drivers
146-
uv pip install --no-cache-dir apache-airflow[${AIRFLOW_EXTRAS}]==${PRODUCT_VERSION} --constraint /tmp/constraints.txt --build-constraints /tmp/build-constraints.txt
150+
uv pip install --python ${VIRTUAL_ENV}/bin/python apache-airflow[${AIRFLOW_EXTRAS}]==${PRODUCT_VERSION} --constraint /tmp/constraints.txt --build-constraints /tmp/build-constraints.txt
147151
# Then install the locally built core wheel to override the core package
148-
uv pip install --no-cache-dir dist/apache_airflow_core-${PRODUCT_VERSION}-py3-none-any.whl[${AIRFLOW_EXTRAS}] --constraint /tmp/constraints.txt --build-constraints /tmp/build-constraints.txt
152+
uv pip install --python ${VIRTUAL_ENV}/bin/python dist/apache_airflow_core-${PRODUCT_VERSION}-py3-none-any.whl[${AIRFLOW_EXTRAS}] --constraint /tmp/constraints.txt --build-constraints /tmp/build-constraints.txt
149153
else
150154
# Airflow 2.x
151155
# build front-end assets
152156
cd airflow/www
157+
# TODO: Consider making the yarn version an ARG
153158
npm install -g yarn@1.22.22
154159
yarn install --frozen-lockfile
155160
yarn run build
@@ -158,25 +163,22 @@ else
158163
cd ../..
159164
/root/.local/bin/hatch build -t wheel
160165
# First install the full apache-airflow package to get all dependencies including database drivers
161-
uv pip install --no-cache-dir apache-airflow[${AIRFLOW_EXTRAS}]==${PRODUCT_VERSION} --constraint /tmp/constraints.txt --build-constraints /tmp/build-constraints.txt
166+
uv pip install --python ${VIRTUAL_ENV}/bin/python apache-airflow[${AIRFLOW_EXTRAS}]==${PRODUCT_VERSION} --constraint /tmp/constraints.txt --build-constraints /tmp/build-constraints.txt
162167
# Then install the locally built wheel to override with patched version
163-
uv pip install --no-cache-dir dist/apache_airflow-${PRODUCT_VERSION}-py3-none-any.whl[${AIRFLOW_EXTRAS}] --constraint /tmp/constraints.txt --build-constraints /tmp/build-constraints.txt
168+
uv pip install --python ${VIRTUAL_ENV}/bin/python dist/apache_airflow-${PRODUCT_VERSION}-py3-none-any.whl[${AIRFLOW_EXTRAS}] --constraint /tmp/constraints.txt --build-constraints /tmp/build-constraints.txt
164169
fi
165170

166171
# Needed for pandas S3 integration to e.g. write and read csv and parquet files to/from S3
167-
uv pip install --no-cache-dir s3fs==${S3FS_VERSION} cyclonedx-bom==${CYCLONEDX_BOM_VERSION}
172+
# TODO: s3fs may already be installed via the s3fs extra and constraints. Check if this explicit install is still needed.
173+
uv pip install --python ${VIRTUAL_ENV}/bin/python s3fs==${S3FS_VERSION} cyclonedx-bom==${CYCLONEDX_BOM_VERSION}
168174
# Needed for OIDC
169-
uv pip install --no-cache-dir Flask_OIDC==2.2.0 Flask-OpenID==1.3.1
175+
uv pip install --python ${VIRTUAL_ENV}/bin/python Flask_OIDC==2.2.0 Flask-OpenID==1.3.1
170176

171-
uv pip install --no-cache-dir /tmp/opa_auth_manager-0.1.0-py3-none-any.whl
177+
uv pip install --python ${VIRTUAL_ENV}/bin/python /tmp/opa_auth_manager-0.1.0-py3-none-any.whl
172178

173179
# Create the SBOM for Airflow
174180
# Important: All `pip install` commands must be above this line, otherwise the SBOM will be incomplete
175-
if [ "$PRODUCT_VERSION" == "2.9.3" ] || [ "$PRODUCT_VERSION" == "3.0.6" ]; then
176-
cyclonedx-py environment --schema-version 1.5 --outfile /tmp/sbom.json
177-
else
178-
cyclonedx-py environment --spec-version 1.5 --output-file /tmp/sbom.json
179-
fi
181+
${VIRTUAL_ENV}/bin/cyclonedx-py environment --spec-version 1.5 --output-file /tmp/sbom.json
180182
uv pip uninstall cyclonedx-bom
181183

182184
# Break circular dependencies by removing the apache-airflow dependency from the providers
@@ -218,8 +220,9 @@ LABEL name="Apache Airflow" \
218220
description="This image is deployed by the Stackable Operator for Apache Airflow."
219221

220222
ENV HOME=/stackable
221-
ENV AIRFLOW_USER_HOME_DIR=/stackable
222-
ENV PATH=$PATH:/bin:$HOME/app/bin
223+
ENV VIRTUAL_ENV=$HOME/app
224+
ENV AIRFLOW_USER_HOME_DIR=$HOME
225+
ENV PATH=$HOME/app/bin:$PATH:/bin
223226
ENV AIRFLOW_HOME=$HOME/airflow
224227

225228
COPY --from=airflow-build-image --chown=${STACKABLE_USER_UID}:0 /stackable/ ${HOME}/
@@ -233,14 +236,15 @@ COPY --from=gitsync-image --chown=${STACKABLE_USER_UID}:0 /git-sync ${HOME}/git-
233236

234237
COPY airflow/licenses /licenses
235238

239+
COPY --from=uv-image --chown=${STACKABLE_USER_UID}:0 /uv /uvx /bin/
240+
236241
# Update image and install needed packages
237242
RUN <<EOF
238243
microdnf update
239244

240245
# git: Needed for the gitsync functionality
241246
# openldap: Needed for authentication of clients against LDAP servers
242247
# openssh-clients: We need the openssh libs for the gitsync functionality (the clone target could be e.g. git@github.com:org/repo.git)
243-
# python: Airflow needs Python
244248
microdnf install \
245249
ca-certificates \
246250
cyrus-sasl \
@@ -251,7 +255,6 @@ microdnf install \
251255
openssh-clients \
252256
openssl-libs \
253257
openssl-pkcs11 \
254-
python${PYTHON_VERSION} \
255258
socat \
256259
unixODBC
257260
microdnf clean all

0 commit comments

Comments
 (0)