chore(ci): consolidate openldap runner prep into a composite action (#36563)

This commit is contained in:
yasser khan
2026-05-14 14:28:51 +05:30
committed by GitHub
parent 323841e9c5
commit 47d4720ff4
6 changed files with 94 additions and 83 deletions
@@ -0,0 +1,44 @@
name: Runner prep for openldap
description: |
Disable the Ubuntu 24.04 AppArmor user-namespace restriction and ensure
docker-compose >= 2.36.0 before starting any stack that includes openldap.
Background: Ubuntu 24.04 sets kernel.apparmor_restrict_unprivileged_userns=1
by default. The osixia/openldap:1.4.0 init scripts rely on unprivileged
user namespaces; blocking them causes an immediate exit(1) with no useful
stderr ("dependency failed to start: container mmserver-openldap-1 exited (1)").
The container's own security_opt: apparmor:unconfined is insufficient — it
only unconfines the slapd process, not the entrypoint. The fix must be at
the host-kernel level.
docker-compose 2.35.1 (shipped on some ubuntu-24.04 runner images) also has
a known `up` regression that surfaces as spurious dependency-failed errors
under load. We upgrade to >= 2.36.0 when needed.
runs:
using: composite
steps:
- name: Disable AppArmor user-namespace restriction and ensure docker-compose >= 2.36.0
shell: bash
run: |
echo "Before: docker compose version"
docker compose version || true
# Disable the AppArmor user-namespace restriction. Idempotent;
# safe if the key doesn't exist (older kernel).
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
# If docker-compose is older than 2.36.0, install a newer one to
# the user's cli-plugins dir (takes precedence over the system copy).
CURRENT=$(docker compose version --short 2>/dev/null || echo "0.0.0")
NEED="2.36.0"
if [ "$(printf '%s\n' "$NEED" "$CURRENT" | sort -V | head -n1)" != "$NEED" ]; then
echo "Upgrading docker-compose from ${CURRENT} to 2.39.1"
mkdir -p "$HOME/.docker/cli-plugins"
curl -SL -o "$HOME/.docker/cli-plugins/docker-compose" \
"https://github.com/docker/compose/releases/download/v2.39.1/docker-compose-linux-x86_64"
chmod +x "$HOME/.docker/cli-plugins/docker-compose"
fi
echo "After: docker compose version"
docker compose version
+10 -38
View File
@@ -223,6 +223,16 @@ jobs:
ROLLING_RELEASE_COMMIT_SHA: "${{ inputs.ROLLING_RELEASE_commit_sha }}"
ROLLING_RELEASE_SERVER_IMAGE: "${{ inputs.ROLLING_RELEASE_SERVER_IMAGE }}"
steps:
- name: ci/checkout-actions
# Sparse-checkout just .github/actions from the triggering ref (master)
# so the composite action below is available before the full checkout
# overwrites the workspace with inputs.commit_sha.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout: .github/actions
sparse-checkout-cone-mode: true
- name: ci/runner-prep-for-openldap
uses: ./.github/actions/runner-prep-openldap
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
@@ -244,44 +254,6 @@ jobs:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: ${{ needs.generate-build-variables.outputs.node-cache-dependency-path }}
- name: ci/runner-prep-for-openldap
# Observed failure: "dependency failed to start: container
# mmserver-openldap-1 exited (1)" on ubuntu-24.04 runners — kills
# every LDAP spec on the affected shard.
#
# Ubuntu 24.04 introduced an AppArmor profile that restricts the
# creation of unprivileged user namespaces. The osixia/openldap
# image's internal init scripts rely on this capability; blocking
# it produces an immediate exit(1) with no useful stderr. The
# container's own security_opt: apparmor:unconfined is not
# sufficient — that only unconfines slapd, not the container's
# entrypoint process. The actual switch is at the host-kernel level.
#
# Also ensure docker-compose is >= 2.36.0 — the 2.35.1 shipped on
# some ubuntu-24.04 images has a known `up` regression that
# manifests as random dependency-failed errors under load.
run: |
echo "Before: docker compose version"
docker compose version || true
# Disable the AppArmor user-namespace restriction. Idempotent;
# safe if the key doesn't exist (older kernel).
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
# If docker-compose is older than 2.36.0, install a newer one to
# the user's cli-plugins dir (takes precedence over the system copy).
CURRENT=$(docker compose version --short 2>/dev/null || echo "0.0.0")
NEED="2.36.0"
if [ "$(printf '%s\n' "$NEED" "$CURRENT" | sort -V | head -n1)" != "$NEED" ]; then
echo "Upgrading docker-compose from ${CURRENT} to 2.39.1"
mkdir -p "$HOME/.docker/cli-plugins"
curl -SL -o "$HOME/.docker/cli-plugins/docker-compose" \
"https://github.com/docker/compose/releases/download/v2.39.1/docker-compose-linux-x86_64"
chmod +x "$HOME/.docker/cli-plugins/docker-compose"
fi
echo "After: docker compose version"
docker compose version
- name: ci/e2e-test
run: |
make cloud-init
@@ -259,6 +259,16 @@ jobs:
CWS_URL: "${{ secrets.CWS_URL }}"
CWS_EXTRA_HTTP_HEADERS: "${{ secrets.CWS_EXTRA_HTTP_HEADERS }}"
steps:
- name: ci/checkout-actions
# Sparse-checkout just .github/actions from the triggering ref (master)
# so the composite action below is available before the full checkout
# overwrites the workspace with inputs.commit_sha.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout: .github/actions
sparse-checkout-cone-mode: true
- name: ci/runner-prep-for-openldap
uses: ./.github/actions/runner-prep-openldap
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
@@ -213,6 +213,16 @@ jobs:
BUILD_ID: "${{ inputs.build_id }}"
CI_BASE_URL: "full-test-${{ matrix.worker_index }}"
steps:
- name: ci/checkout-actions
# Sparse-checkout just .github/actions from the triggering ref (master)
# so the composite action below is available before the full checkout
# overwrites the workspace with inputs.commit_sha.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout: .github/actions
sparse-checkout-cone-mode: true
- name: ci/runner-prep-for-openldap
uses: ./.github/actions/runner-prep-openldap
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
@@ -159,6 +159,16 @@ jobs:
BUILD_ID: "${{ inputs.build_id }}"
CI_BASE_URL: "${{ inputs.test_type }}-test-${{ matrix.worker_index }}"
steps:
- name: ci/checkout-actions
# Sparse-checkout just .github/actions from the triggering ref (master)
# so the composite action below is available before the full checkout
# overwrites the workspace with inputs.commit_sha.
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout: .github/actions
sparse-checkout-cone-mode: true
- name: ci/runner-prep-for-openldap
uses: ./.github/actions/runner-prep-openldap
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
@@ -173,45 +183,6 @@ jobs:
- name: ci/get-webapp-node-modules
working-directory: webapp
run: make node_modules
- name: ci/runner-prep-for-openldap
# Observed failure: "dependency failed to start: container
# mmserver-openldap-1 exited (1)" on ubuntu-24.04 runners — kills
# every ABAC/LDAP spec on the affected shard.
#
# Ubuntu 24.04 introduced an AppArmor profile that restricts the
# creation of unprivileged user namespaces. The osixia/openldap
# image's internal init scripts rely on this capability; blocking
# it produces an immediate exit(1) with no useful stderr. The
# container's own security_opt: apparmor:unconfined (already set
# in server/build/docker-compose.common.yml) isn't sufficient —
# that only unconfines slapd, not the container's entrypoint
# process. The actual switch is at the host-kernel level.
#
# Also ensure docker-compose is >= 2.36.0 — the 2.35.1 shipped on
# some ubuntu-24.04 images has a known `up` regression that
# manifests as random dependency-failed errors under load.
run: |
echo "Before: docker compose version"
docker compose version || true
# Disable the AppArmor user-namespace restriction. Idempotent;
# safe if the key doesn't exist (older kernel).
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
# If docker-compose is older than 2.36.0, install a newer one to
# the user's cli-plugins dir (takes precedence over the system copy).
CURRENT=$(docker compose version --short 2>/dev/null || echo "0.0.0")
NEED="2.36.0"
if [ "$(printf '%s\n' "$NEED" "$CURRENT" | sort -V | head -n1)" != "$NEED" ]; then
echo "Upgrading docker-compose from ${CURRENT} to 2.39.1"
mkdir -p "$HOME/.docker/cli-plugins"
curl -SL -o "$HOME/.docker/cli-plugins/docker-compose" \
"https://github.com/docker/compose/releases/download/v2.39.1/docker-compose-linux-x86_64"
chmod +x "$HOME/.docker/cli-plugins/docker-compose"
fi
echo "After: docker compose version"
docker compose version
- name: ci/restore-playwright-image-cache
# Cache the Playwright Docker image tar by the SHA of the files that pin
# its version. Cache busts automatically when either file is edited to bump
@@ -63,15 +63,19 @@ test('should open /dialog date and post submit confirmation after selecting date
// Click day 20 — reliably available in any month
await channelsPage.page.getByRole('grid').getByText('20', {exact: true}).click();
// 8. Select date and time using the Meeting Date & Time picker
await dialog
.getByRole('button', {name: /Date.*Today|Select a date/i})
.first()
.click();
// 8. Select date and time using the Meeting Date & Time picker.
// The datetime field renders via DateTimeInput which wraps its date part in
// <div class="dateTime__date"> — a class unique to DateTimeInput and absent
// from the date-only "Meeting Date" field (AppsFormDateField → DatePicker directly).
// Scoping by that wrapper is more reliable than accessible-name matching on the
// role="button" div, whose name includes a CSS icon-font glyph that browsers
// include in accname but which is invisible to textContent inspection.
await dialog.locator('.dateTime__date').getByRole('button').click();
await expect(channelsPage.page.getByRole('grid')).toBeVisible();
await channelsPage.page.getByRole('grid').getByText('22', {exact: true}).click();
// Select a time from the time picker
// Select a time from the time picker. The time button carries aria-label="Time"
// (set explicitly in DateTimeInput), so the name-based locator is reliable here.
await dialog
.getByRole('button', {name: /Time|Select a time/i})
.first()