Skip to content

Commit 97b63f4

Browse files
committed
Revert: Spikes A, B, C, D, E
1 parent e1fe0ef commit 97b63f4

5 files changed

Lines changed: 1248 additions & 3 deletions

File tree

.github/microshift-ci/Dockerfile

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# syntax=docker/dockerfile:1
2+
#
3+
# MicroShift in a privileged container for CI.
4+
#
5+
# This image bundles upstream MicroShift on top of CentOS Stream 9 and
6+
# runs systemd as PID 1. Intended to be launched with:
7+
#
8+
# docker run -d --privileged --cgroupns=host \
9+
# -v /sys/fs/cgroup:/sys/fs/cgroup:rw \
10+
# -v /lib/modules:/lib/modules:ro \
11+
# --tmpfs /run --tmpfs /tmp \
12+
# -p 6443:6443 -p 80:80 -p 443:443 \
13+
# microshift-ci:local
14+
#
15+
# See .github/microshift-ci/start.sh for the host-side wrapper used in CI.
16+
#
17+
# Notes from Spike A runs 1–7 (2026-04-29):
18+
# - The `@redhat-et/microshift` Copr is dead (last build 2021).
19+
# - The `@microshift/` Copr group on Fedora Copr is empty (no projects,
20+
# no builds), so any `@microshift/microshift-X.Y` reference fails at
21+
# `dnf copr enable`.
22+
# - The verified working RPM source is the official OpenShift mirror
23+
# at `mirror.openshift.com`, which serves the same MicroShift bits
24+
# Red Hat ships under subscription, on two anonymous yum repos.
25+
# No GPG keys are published alongside, so `gpgcheck=0` is required.
26+
# - Reproducibility: pin to a specific RC tag (e.g. `4.18.0-rc.10`),
27+
# NOT the moving `latest-4.18` symlink.
28+
# - microshift shells out to `/bin/hostname` at startup; the package
29+
# must be installed explicitly because it is not in the minimal
30+
# base nor pulled transitively by any microshift-* dep.
31+
# - cri-o reads `/etc/crio/openshift-pull-secret` to authenticate to
32+
# `quay.io/openshift-release-dev/ocp-v4.0-art-dev`. The path is
33+
# bind-mounted from the runner by `start.sh`; without it the
34+
# OVN/DNS/router pods fail to pull and the node never goes Ready.
35+
# - Docker's default `private` mount propagation on `/` blocks the
36+
# `rshared` bind mounts that OVN-Kubernetes (and other openshift-*
37+
# system pods) need. We wrap /sbin/init with entrypoint.sh which
38+
# runs `mount --make-rshared /` first.
39+
# - The runner's Docker mounts `/run` as tmpfs with `noexec`. cri-o
40+
# validates a CNI config by exec'ing the plugin binary; OVN drops
41+
# `/run/cni/bin/ovn-k8s-cni-overlay` there, the exec returns
42+
# EACCES, and cri-o falls back to crio-bridge + loopback (node
43+
# never goes Ready). entrypoint.sh remounts /run with `exec` to
44+
# fix this.
45+
46+
ARG BASE_IMAGE=quay.io/centos/centos:stream9
47+
# MicroShift release tag to pin (e.g. 4.18.0-rc.10). Browse
48+
# https://mirror.openshift.com/pub/openshift-v4/x86_64/microshift/ocp/
49+
# for available RC directories. There are no GA dirs in the public
50+
# mirror; only `*-rc.*` and (in `…/ocp-dev-preview/…`) `*-ec.*`.
51+
ARG MICROSHIFT_RELEASE=4.18.0-rc.10
52+
# Minor line corresponding to MICROSHIFT_RELEASE. Used both in the local
53+
# repo `[id]` and in the dependencies-repo URL.
54+
ARG MICROSHIFT_LINE=4.18
55+
56+
FROM ${BASE_IMAGE}
57+
58+
ARG MICROSHIFT_RELEASE
59+
ARG MICROSHIFT_LINE
60+
61+
# Base packages: systemd as PID 1, plus userspace required by
62+
# microshift's startup checks.
63+
#
64+
# - `hostname` is mandatory (Spike A run 3 lesson): microshift shells
65+
# out to /bin/hostname during config defaulting; without it the
66+
# daemon dies in <1 s. The package is NOT in CentOS Stream 9's
67+
# minimal base image and is NOT pulled transitively by any
68+
# microshift-* dep.
69+
# - `iputils`, `iproute`, `procps-ng` are listed explicitly even
70+
# though they happen to be pulled by microshift-networking today.
71+
# Same class of silent breakage as `hostname` if a future minor
72+
# changes its deps; cheap to defend against.
73+
RUN dnf -y install \
74+
systemd \
75+
ca-certificates \
76+
hostname \
77+
iputils \
78+
iproute \
79+
procps-ng && \
80+
dnf clean all
81+
82+
# Mask units that are not relevant inside a container and tend to fail
83+
# noisily, polluting `journalctl` output. Validated working in
84+
# Spike A runs 1–7.
85+
RUN systemctl mask \
86+
systemd-firstboot.service \
87+
systemd-udevd.service \
88+
systemd-udev-trigger.service \
89+
systemd-hwdb-update.service \
90+
systemd-tmpfiles-setup.service \
91+
systemd-tmpfiles-setup-dev.service \
92+
systemd-tmpfiles-clean.service \
93+
systemd-tmpfiles-clean.timer \
94+
getty.target \
95+
getty@.service \
96+
console-getty.service
97+
98+
# Configure the two anonymous mirror.openshift.com yum repos that ship
99+
# MicroShift and its dependencies (cri-o, openshift-clients, openvswitch3,
100+
# etc.). Shell-level `:=` defaults guard against an empty `--build-arg`
101+
# from the workflow (defense in depth — with literal mirror URLs an
102+
# empty value would surface as a 404, but pinning is too important to
103+
# rely on that alone).
104+
RUN : "${MICROSHIFT_RELEASE:=4.18.0-rc.10}" && \
105+
: "${MICROSHIFT_LINE:=4.18}" && \
106+
cat > /etc/yum.repos.d/microshift.repo <<EOF
107+
[microshift-${MICROSHIFT_LINE}]
108+
name=MicroShift ${MICROSHIFT_LINE}
109+
baseurl=https://mirror.openshift.com/pub/openshift-v4/x86_64/microshift/ocp/${MICROSHIFT_RELEASE}/el9/os/
110+
enabled=1
111+
gpgcheck=0
112+
113+
[microshift-${MICROSHIFT_LINE}-deps]
114+
name=MicroShift ${MICROSHIFT_LINE} Dependencies
115+
baseurl=https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rpms/${MICROSHIFT_LINE}-el9-beta/
116+
enabled=1
117+
gpgcheck=0
118+
EOF
119+
120+
# Install MicroShift, CRI-O, and the openshift-clients package (oc CLI).
121+
# `skopeo` is bundled in the same dependencies repo and is required by
122+
# Spike C's registry-free image hand-off (`docker save | skopeo copy
123+
# docker-archive:- containers-storage:...`).
124+
RUN dnf -y install \
125+
cri-o cri-tools \
126+
microshift microshift-networking microshift-greenboot \
127+
microshift-release-info microshift-selinux \
128+
openshift-clients \
129+
skopeo && \
130+
dnf clean all
131+
132+
# Enable services so they start under PID-1 systemd.
133+
RUN systemctl enable crio.service microshift.service
134+
135+
ENV KUBECONFIG=/var/lib/microshift/resources/kubeadmin/kubeconfig
136+
137+
# systemd uses SIGRTMIN+3 for clean container shutdown.
138+
STOPSIGNAL SIGRTMIN+3
139+
140+
EXPOSE 6443 80 443
141+
142+
# Wrap /sbin/init in entrypoint.sh which makes two filesystem fixes
143+
# that MUST happen before any nested container runs:
144+
# - `mount --make-rshared /` for OVN-Kubernetes rshared bind mounts
145+
# (Spike A run 5 lesson)
146+
# - `mount -o remount,exec /run` so cri-o can exec the OVN CNI
147+
# plugin binary (Spike A run 7 lesson)
148+
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
149+
RUN chmod +x /usr/local/bin/entrypoint.sh
150+
CMD ["/usr/local/bin/entrypoint.sh"]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
#
3+
# Container entrypoint for the MicroShift CI image.
4+
#
5+
# Two filesystem fixes are needed BEFORE systemd/microshift/ovn start,
6+
# because once nested containers are running it is too late.
7+
#
8+
# 1. Mount-propagation (Spike A run 5)
9+
#
10+
# Docker mounts the container's root filesystem as `private` propagation
11+
# by default, even with `--privileged`. Several OpenShift system pods
12+
# (notably ovnkube-master, but also the OVS-aware bits of multus and
13+
# the ingress router) bind-mount the host root with `rshared`
14+
# propagation so they can publish OVS sockets and netns mounts visible
15+
# to peer pods. Linux refuses an `rshared` child of a `private`
16+
# parent and runc fails with:
17+
#
18+
# path "/" is mounted on "/" but it is not a shared or slave mount
19+
#
20+
# Remounting / as rshared once at PID-1 startup fixes this for every
21+
# nested container started afterwards. Same workaround `kind` and
22+
# `k3s-in-docker` apply.
23+
#
24+
# 2. /run must allow exec (Spike A run 7)
25+
#
26+
# OVN-Kubernetes drops its CNI plugin binary at
27+
# /run/cni/bin/ovn-k8s-cni-overlay; cri-o validates the CNI config by
28+
# exec'ing that binary. The runner's Docker mounts /run as tmpfs with
29+
# `noexec` by default, so the exec returns EACCES, cri-o silently
30+
# discards the OVN network in favour of crio-bridge + loopback, and
31+
# kubelet reports "no CNI configuration file" -- confusing because
32+
# the file IS there; it just can't be loaded. Remounting /run with
33+
# exec is idempotent if it already permits exec.
34+
set -e
35+
36+
mount --make-rshared /
37+
mount -o remount,exec /run
38+
39+
exec /sbin/init

0 commit comments

Comments
 (0)