|
| 1 | +ARG DISTRO=bookworm |
| 2 | +ARG LINSTOR_VERSION |
| 3 | + |
| 4 | +# ------------------------------------------------------------------------------ |
| 5 | +# Build linstor-server from source |
| 6 | +FROM debian:bookworm AS builder |
| 7 | + |
| 8 | +ARG LINSTOR_VERSION |
| 9 | +ARG VERSION=${LINSTOR_VERSION} |
| 10 | +ARG DISTRO |
| 11 | + |
| 12 | +ENV DEBIAN_FRONTEND=noninteractive |
| 13 | +RUN apt-get update \ |
| 14 | + && apt-get -y upgrade \ |
| 15 | + && apt-get -y install build-essential git default-jdk-headless python3-all debhelper wget unzip && \ |
| 16 | + wget https://services.gradle.org/distributions/gradle-8.9-bin.zip -O /tmp/gradle.zip && \ |
| 17 | + unzip -d /opt /tmp/gradle.zip && \ |
| 18 | + rm /tmp/gradle.zip && \ |
| 19 | + ln -s /opt/gradle-8.9/bin/gradle /usr/local/bin/gradle |
| 20 | + |
| 21 | +RUN git clone https://github.com/LINBIT/linstor-server.git /linstor-server |
| 22 | +WORKDIR /linstor-server |
| 23 | +RUN git checkout v${VERSION} |
| 24 | + |
| 25 | +# Apply patches |
| 26 | +COPY patches /patches |
| 27 | +RUN git apply /patches/*.diff && \ |
| 28 | + git config user.email "[email protected]" && \ |
| 29 | + git config user.name "Cozystack Builder" && \ |
| 30 | + git add -A && \ |
| 31 | + git commit -m "Apply patches" |
| 32 | + |
| 33 | +# Initialize git submodules |
| 34 | +RUN git submodule update --init --recursive || make check-submods |
| 35 | + |
| 36 | +# Pre-download ALL dependencies before make tarball |
| 37 | +# This ensures all transitive dependencies are cached, including optional ones like AWS SDK |
| 38 | +RUN ./gradlew getProtoc |
| 39 | +RUN ./gradlew generateJava |
| 40 | +RUN ./gradlew --no-daemon --gradle-user-home .gradlehome downloadDependencies |
| 41 | + |
| 42 | +# Manually create tarball without removing caches |
| 43 | +# make tarball removes .gradlehome/caches/[0-9]* which deletes dependencies |
| 44 | +# So we'll do the steps manually but keep the caches |
| 45 | +RUN make check-submods versioninfo gen-java FORCE=1 VERSION=${VERSION} |
| 46 | +RUN make server/jar.deps controller/jar.deps satellite/jar.deps jclcrypto/jar.deps FORCE=1 VERSION=${VERSION} |
| 47 | +RUN make .filelist FORCE=1 VERSION=${VERSION} PRESERVE_DEBIAN=1 |
| 48 | +# Don't remove caches - we need them for offline build |
| 49 | +RUN rm -Rf .gradlehome/wrapper .gradlehome/native .gradlehome/.tmp || true |
| 50 | +RUN mkdir -p ./libs |
| 51 | +RUN make tgz VERSION=${VERSION} |
| 52 | + |
| 53 | +# Extract tarball and build DEB packages from it |
| 54 | +RUN mv linstor-server-${VERSION}.tar.gz /linstor-server_${VERSION}.orig.tar.gz \ |
| 55 | + && tar -C / -xvf /linstor-server_${VERSION}.orig.tar.gz |
| 56 | + |
| 57 | +WORKDIR /linstor-server-${VERSION} |
| 58 | +# Verify .gradlehome is present in extracted tarball |
| 59 | +RUN test -d .gradlehome && echo ".gradlehome found in tarball" || (echo ".gradlehome not found in tarball!" && exit 1) |
| 60 | + |
| 61 | +# Build DEB packages from tarball |
| 62 | +# Override GRADLE_FLAGS to remove --offline flag, allowing Gradle to download missing dependencies |
| 63 | +RUN sed -i 's/GRADLE_FLAGS = --offline/GRADLE_FLAGS =/' debian/rules || true |
| 64 | +RUN LD_LIBRARY_PATH='' dpkg-buildpackage -rfakeroot -b -uc |
| 65 | + |
| 66 | +# Copy built .deb packages to a location accessible from final image |
| 67 | +# dpkg-buildpackage creates packages in parent directory |
| 68 | +RUN mkdir -p /packages-output && \ |
| 69 | + find .. -maxdepth 1 -name "linstor-*.deb" -exec cp {} /packages-output/ \; && \ |
| 70 | + test -n "$(ls -A /packages-output)" || (echo "ERROR: No linstor .deb packages found after build." && exit 1) |
| 71 | + |
| 72 | +# ------------------------------------------------------------------------------ |
| 73 | +# Final image |
| 74 | +FROM debian:${DISTRO} |
| 75 | + |
| 76 | +LABEL maintainer= "Roland Kammerer <[email protected]>" |
| 77 | + |
| 78 | +ARG LINSTOR_VERSION |
| 79 | +ARG DISTRO |
| 80 | + |
| 81 | +# Copy built .deb packages from builder stage |
| 82 | +# dpkg-buildpackage creates packages in parent directory, we copied them to /packages-output |
| 83 | +COPY --from=builder /packages-output/ /packages/ |
| 84 | + |
| 85 | +RUN { echo 'APT::Install-Recommends "false";' ; echo 'APT::Install-Suggests "false";' ; } > /etc/apt/apt.conf.d/99_piraeus |
| 86 | + |
| 87 | +RUN --mount=type=cache,target=/var/cache,sharing=private \ |
| 88 | + --mount=type=cache,target=/var/lib/apt/lists,sharing=private \ |
| 89 | + --mount=type=tmpfs,target=/var/log \ |
| 90 | + # Install wget first for downloading keyring |
| 91 | + apt-get update && apt-get install -y wget ca-certificates && \ |
| 92 | + # Enable contrib repos for zfsutils \ |
| 93 | + . /etc/os-release && \ |
| 94 | + sed -i -r 's/^Components: (.*)$/Components: \1 contrib/' /etc/apt/sources.list.d/debian.sources && \ |
| 95 | + echo "deb http://deb.debian.org/debian $VERSION_CODENAME-backports contrib" > /etc/apt/sources.list.d/backports.list && \ |
| 96 | + wget https://packages.linbit.com/public/linbit-keyring.deb -O /var/cache/linbit-keyring.deb && \ |
| 97 | + dpkg -i /var/cache/linbit-keyring.deb && \ |
| 98 | + echo "deb http://packages.linbit.com/public $VERSION_CODENAME misc" > /etc/apt/sources.list.d/linbit.list && \ |
| 99 | + apt-get update && \ |
| 100 | + # Install useful utilities and general dependencies |
| 101 | + apt-get install -y udev drbd-utils jq net-tools iputils-ping iproute2 dnsutils netcat-traditional sysstat curl util-linux && \ |
| 102 | + # Install dependencies for optional features \ |
| 103 | + apt-get install -y \ |
| 104 | + # cryptsetup: luks layer |
| 105 | + cryptsetup \ |
| 106 | + # e2fsprogs: LINSTOR can create file systems \ |
| 107 | + e2fsprogs \ |
| 108 | + # lsscsi: exos layer \ |
| 109 | + lsscsi \ |
| 110 | + # lvm2: manage lvm storage pools \ |
| 111 | + lvm2 \ |
| 112 | + # multipath-tools: exos layer \ |
| 113 | + multipath-tools \ |
| 114 | + # nvme-cli: nvme layer |
| 115 | + nvme-cli \ |
| 116 | + # procps: used by LINSTOR to find orphaned send/receive processes \ |
| 117 | + procps \ |
| 118 | + # socat: used with thin-send-recv to send snapshots to another LINSTOR cluster |
| 119 | + socat \ |
| 120 | + # thin-send-recv: used to send/receive snapshots of LVM thin volumes \ |
| 121 | + thin-send-recv \ |
| 122 | + # xfsprogs: LINSTOR can create file systems; xfs deps \ |
| 123 | + xfsprogs \ |
| 124 | + # zstd: used with thin-send-recv to send snapshots to another LINSTOR cluster \ |
| 125 | + zstd \ |
| 126 | + # zfsutils-linux: for zfs storage pools \ |
| 127 | + zfsutils-linux/$VERSION_CODENAME-backports \ |
| 128 | + && \ |
| 129 | + # remove udev, no need for it in the container \ |
| 130 | + apt-get remove -y udev && \ |
| 131 | + # Install linstor packages from built .deb files and linstor-client from repository |
| 132 | + apt-get install -y default-jre-headless python3-all python3-natsort linstor-client \ |
| 133 | + && ls packages/*.deb >/dev/null && (dpkg -i packages/*.deb || apt-get install -f -y) \ |
| 134 | + && rm -rf /packages \ |
| 135 | + && sed -i 's/"-Djdk.tls.acknowledgeCloseNotify=true"//g' /usr/share/linstor-server/bin/Controller \ |
| 136 | + && apt-get clean |
| 137 | + |
| 138 | +# Log directory need to be group writable. OpenShift assigns random UID and GID, without extra RBAC changes we can only influence the GID. |
| 139 | +RUN mkdir /var/log/linstor-controller && \ |
| 140 | + chown 0:1000 /var/log/linstor-controller && \ |
| 141 | + chmod -R 0775 /var/log/linstor-controller && \ |
| 142 | + # Ensure we log to files in containers, otherwise SOS reports won't show any logs at all |
| 143 | + sed -i 's#<!-- <appender-ref ref="FILE" /> -->#<appender-ref ref="FILE" />#' /usr/share/linstor-server/lib/conf/logback.xml |
| 144 | + |
| 145 | + |
| 146 | +RUN lvmconfig --type current --mergedconfig --config 'activation { udev_sync = 0 udev_rules = 0 monitoring = 0 } devices { global_filter = [ "r|^/dev/drbd|" ] obtain_device_list_from_udev = 0}' > /etc/lvm/lvm.conf.new && mv /etc/lvm/lvm.conf.new /etc/lvm/lvm.conf |
| 147 | +RUN echo 'global { usage-count no; }' > /etc/drbd.d/global_common.conf |
| 148 | + |
| 149 | +# controller |
| 150 | +EXPOSE 3376/tcp 3377/tcp 3370/tcp 3371/tcp |
| 151 | + |
| 152 | +# satellite |
| 153 | +EXPOSE 3366/tcp 3367/tcp |
| 154 | + |
| 155 | +RUN wget https://raw.githubusercontent.com/piraeusdatastore/piraeus/refs/heads/master/dockerfiles/piraeus-server/entry.sh -O /usr/bin/piraeus-entry.sh \ |
| 156 | + && chmod +x /usr/bin/piraeus-entry.sh |
| 157 | + |
| 158 | +ARG K8S_AWAIT_ELECTION_VERSION=v0.4.2 |
| 159 | +# TARGETARCH is a docker special variable: https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope |
| 160 | +ARG TARGETARCH |
| 161 | + |
| 162 | +RUN wget https://github.com/LINBIT/k8s-await-election/releases/download/${K8S_AWAIT_ELECTION_VERSION}/k8s-await-election-${K8S_AWAIT_ELECTION_VERSION}-linux-${TARGETARCH}.tar.gz -O - | tar -xvz -C /usr/bin/ |
| 163 | + |
| 164 | +ARG LOSETUP_CONTAINER_VERSION=v1.0.1 |
| 165 | +RUN wget "https://github.com/LINBIT/losetup-container/releases/download/${LOSETUP_CONTAINER_VERSION}/losetup-container-$(uname -m)-unknown-linux-gnu.tar.gz" -O - | tar -xvz -C /usr/local/sbin && \ |
| 166 | + printf '#!/bin/sh\nLOSETUP_CONTAINER_ORIGINAL_LOSETUP=%s exec /usr/local/sbin/losetup-container "$@"\n' $(command -v losetup) > /usr/local/sbin/losetup && \ |
| 167 | + chmod +x /usr/local/sbin/losetup |
| 168 | + |
| 169 | +RUN wget "https://dl.k8s.io/$(wget -O - https://dl.k8s.io/release/stable.txt)/bin/linux/${TARGETARCH}/kubectl" -O /usr/local/bin/kubectl && chmod +x /usr/local/bin/kubectl |
| 170 | + |
| 171 | +CMD ["startSatellite"] |
| 172 | +ENTRYPOINT ["/usr/bin/k8s-await-election", "/usr/bin/piraeus-entry.sh"] |
0 commit comments