Merge #6490: ci: container improvements
Some checks failed
CI / Build Image (push) Failing after 2m9s
CI / Build Dependencies (arm-linux, arm-linux-gnueabihf) (push) Has been skipped
CI / Build Dependencies (linux64, x86_64-pc-linux-gnu) (push) Has been skipped
CI / Build (arm-linux, arm-linux, arm-linux-gnueabihf) (push) Has been skipped
CI / Build (linux64, linux64, x86_64-pc-linux-gnu) (push) Has been skipped
CI / Build (linux64_cxx20, linux64, x86_64-pc-linux-gnu) (push) Has been skipped
CI / Build (linux64_fuzz, linux64, x86_64-pc-linux-gnu) (push) Has been skipped
CI / Build (linux64_nowallet, linux64, x86_64-pc-linux-gnu) (push) Has been skipped
CI / Build (linux64_sqlite, linux64, x86_64-pc-linux-gnu) (push) Has been skipped
CI / Build (linux64_tsan, linux64, x86_64-pc-linux-gnu) (push) Has been skipped
CI / Build (linux64_ubsan, linux64, x86_64-pc-linux-gnu) (push) Has been skipped
Label Merge Conflicts / main (push) Failing after 2m49s
Check Merge Fast-Forward Only / check_merge (push) Successful in 1m51s
Guix Build / build-image (push) Failing after 6m6s
Guix Build / build (aarch64-linux-gnu) (push) Has been skipped
Guix Build / build (arm-linux-gnueabihf) (push) Has been skipped
Guix Build / build (arm64-apple-darwin) (push) Has been skipped
Guix Build / build (x86_64-apple-darwin) (push) Has been skipped
Guix Build / build (powerpc64-linux-gnu) (push) Has been skipped
Guix Build / build (x86_64-linux-gnu) (push) Has been skipped
Guix Build / build (riscv64-linux-gnu) (push) Has been skipped
Guix Build / build (x86_64-w64-mingw32) (push) Has been skipped

04ce1fea52 ci: deduplicate macOS SDK setup logic (Kittywhiskers Van Gogh)
8dd0db7de9 ci: fix "LC_ALL: cannot change locale (en_US.UTF-8)" in Guix container (Kittywhiskers Van Gogh)
187fe17650 ci: don't stage packages in `/tmp`, reduce layers for `cppcheck` build (Kittywhiskers Van Gogh)
eef863554a ci: install `i386` packages only if host is `amd64`, merge layers (Kittywhiskers Van Gogh)
e7702292d1 ci: purge package manager cache after each interaction (Kittywhiskers Van Gogh)
b7099eed47 ci: remove redundant `version` attribute, avoid `lldb` personality error (Kittywhiskers Van Gogh)
64cdc42130 ci: add LLVM library path to `LD_LIBRARY_PATH` and GDB allowlist (Kittywhiskers Van Gogh)
440fd3fe21 ci: drop distro LLVM packages, move Clang install up, set defaults (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * This pull request pulls container-specific changes from [dash#6387](https://github.com/dashpay/dash/pull/6387), [dash#6400](https://github.com/dashpay/dash/pull/6400) and [dash#6421](https://github.com/dashpay/dash/pull/6421)

  * The `HOST` check before running `setup_sdk.sh` isn't a part of the script itself as the script is written to be independent of external variables set. The caller is expected to know the conditions needed to run `setup_sdk.sh` as the script is _relatively_ agnostic to its environment.

  * The `version` attribute in the [`develop`](a8e2316d6f/contrib/containers/develop/docker-compose.yml) and [`guix`](a8e2316d6f/contrib/containers/guix/docker-compose.yml) container's `docker-compose.yml` has been dropped as the attribute has been deprecated in the compose spec ([source](65ef9f4a5d/spec.md (version-top-level-element-obsolete))).

  * Using `LD_LIBRARY_PATH` to point to LLVM's libraries are acceptable and will not interfere with executing binaries built using the distro's packaged compiler as it will eventually search default paths and find the libraries shipped with the distro ([source](https://man7.org/linux/man-pages/man8/ld.so.8.html)).

  * Currently, running LLDB will result in a "personality set failed: Operation not permitted" error ([source](https://discourse.llvm.org/t/running-lldb-in-a-container/76801)). This is caused by its attempt at disabling ASLR for debugging.

    To work around this error, the container will now operate under relaxed restrictions (`seccomp=unconfined`). As disabling ASLR is valuable when debugging and the container is meant for developers (i.e. it isn't used for CI), we have opted to relax restrictions instead of skipping ASLR disablement.

  * As of `develop` (a8e2316d6f), packages built by the container are stored in `/tmp`, which is inadvisable as it is the same directory used to store functional test runs and it's not too difficult to delete `/tmp`'s contents to save space in a long running [`develop`](a8e2316d6f/contrib/containers/develop/docker-compose.yml) container and then realize that both `shellcheck` and `cppcheck` are stored there and now you have to ditch the container you're working in and restart it.
    * To remedy this, packages are now built and stored in `/opt` in accordance with the FHS ([source](https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s13.html)). `/usr/local` was a contender but it's pre-populated, meanwhile `ls /opt` would give you a very quick picture of what's built for the container.

    * `/tmp` will not be entirely empty because [pypa/pip#10753](https://github.com/pypa/pip/issues/10753) results in residual `.pem` files leaking into `/tmp` and `pyenv` stores its build log there and keeping it around has some debug value.

  ## Breaking Changes

  None expected.

  ## Checklist:

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas
  - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)**
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    ACK 04ce1fea52
  PastaPastaPasta:
    utACK 04ce1fea52

Tree-SHA512: 5442ae06cb73b9bc4eec908803548195ae8fd9150422789e5f98578ad01a303b5361f9ba42fe8faee27ac91e38328b7771e4ba42b296dfa70ecbbfc7d10436b6
This commit is contained in:
pasta 2024-12-16 22:29:03 -06:00
commit 7530f3d245
No known key found for this signature in database
GPG Key ID: 5255B86F912A614A
8 changed files with 125 additions and 102 deletions

View File

@ -40,26 +40,11 @@ builder-image:
needs:
- builder-image
image: $CI_REGISTRY_IMAGE:builder-$CI_COMMIT_REF_SLUG
variables:
SDK_URL: https://bitcoincore.org/depends-sources/sdks
XCODE_VERSION: "15.0"
XCODE_BUILD_ID: 15A240d
before_script:
- echo HOST=$HOST
- |
if [ "$HOST" = "x86_64-apple-darwin" ]; then
mkdir -p depends/SDKs
mkdir -p depends/sdk-sources
OSX_SDK_BASENAME="Xcode-${XCODE_VERSION}-${XCODE_BUILD_ID}-extracted-SDK-with-libcxx-headers.tar.gz"
OSX_SDK_PATH="depends/sdk-sources/${OSX_SDK_BASENAME}"
if [ ! -f "$OSX_SDK_PATH" ]; then
echo "Downloading MacOS SDK"
curl --location --fail "${SDK_URL}/${OSX_SDK_BASENAME}" -o "$OSX_SDK_PATH"
fi
if [ -f "$OSX_SDK_PATH" ]; then
echo "Extracting MacOS SDK"
tar -C depends/SDKs -xf "$OSX_SDK_PATH"
fi
echo HOST=${HOST}
if [[ "${HOST}" == "x86_64-apple-darwin" ]]; then
./contrib/containers/guix/scripts/setup-sdk
fi
script:
- make -j$(nproc) -C depends HOST=$HOST $DEP_OPTS

View File

@ -20,17 +20,8 @@ mkdir -p $CACHE_DIR/sdk-sources
ln -s $CACHE_DIR/depends ${DEPENDS_DIR}/built
ln -s $CACHE_DIR/sdk-sources ${DEPENDS_DIR}/sdk-sources
mkdir -p ${DEPENDS_DIR}/SDKs
if [ -n "$XCODE_VERSION" ]; then
OSX_SDK_BASENAME="Xcode-${XCODE_VERSION}-${XCODE_BUILD_ID}-extracted-SDK-with-libcxx-headers.tar.gz"
OSX_SDK_PATH="${DEPENDS_DIR}/sdk-sources/${OSX_SDK_BASENAME}"
if [ ! -f "$OSX_SDK_PATH" ]; then
curl --location --fail "${SDK_URL}/${OSX_SDK_BASENAME}" -o "$OSX_SDK_PATH"
fi
if [ -f "$OSX_SDK_PATH" ]; then
tar -C ${DEPENDS_DIR}/SDKs -xf "$OSX_SDK_PATH"
fi
if [[ "${HOST}" == "x86_64-apple-darwin" ]]; then
./contrib/containers/guix/scripts/setup-sdk
fi
make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS

View File

@ -7,14 +7,17 @@ ENV DEBIAN_FRONTEND="noninteractive" TZ="Europe/London"
# (zlib1g-dev is needed for the Qt host binary builds, but should not be used by target binaries)
ENV APT_ARGS="-y --no-install-recommends --no-upgrade"
# Install packages for i386; disabled on aarch64 and arm64 hosts
RUN (dpkg --print-architecture | grep -Eq 'aarch64|arm64' || dpkg --add-architecture i386)
RUN (dpkg --print-architecture | grep -Eq 'aarch64|arm64' || (apt-get update && apt-get install $APT_ARGS \
# Install packages for i386 on amd64 hosts, then install common packages
RUN set -ex; \
apt-get update && \
if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
dpkg --add-architecture i386 && \
apt-get update && \
apt-get install $APT_ARGS \
g++-multilib \
wine32) && rm -rf /var/lib/apt/lists/*)
RUN apt-get update && apt-get install $APT_ARGS \
wine32; \
fi; \
apt-get install $APT_ARGS \
autotools-dev \
automake \
autoconf \
@ -23,13 +26,11 @@ RUN apt-get update && apt-get install $APT_ARGS \
bsdmainutils \
curl \
ccache \
clang \
cmake \
g++ \
gettext \
git \
libc++-dev \
libc++abi-dev \
gnupg \
libtool \
libxcb-icccm4 \
libxcb-image0 \
@ -42,11 +43,38 @@ RUN apt-get update && apt-get install $APT_ARGS \
libxcb-xinerama0 \
libxcb-xkb1 \
libxkbcommon-x11-0 \
wget \
lsb-release \
software-properties-common \
unzip \
wget \
m4 \
pkg-config \
zlib1g-dev
zlib1g-dev \
&& rm -rf /var/lib/apt/lists/*
# Install Clang+LLVM and set it as default
# We don't need all packages but the default set doesn't include some
# packages we want so we will need to install some of them manually.
ARG LLVM_VERSION=16
RUN set -ex; \
echo "Installing LLVM and Clang ${LLVM_VERSION}..."; \
curl -sL https://apt.llvm.org/llvm.sh | bash -s "${LLVM_VERSION}"; \
echo "Installing additional packages..."; \
apt-get update && apt-get install $APT_ARGS \
"clang-format-${LLVM_VERSION}" \
"clang-tidy-${LLVM_VERSION}" \
"libc++-${LLVM_VERSION}-dev" \
"libc++abi-${LLVM_VERSION}-dev" \
"libclang-rt-${LLVM_VERSION}-dev"; \
rm -rf /var/lib/apt/lists/*; \
echo "Setting defaults..."; \
lldbUpdAltArgs="update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-${LLVM_VERSION} 100"; \
for binName in clang clang++ clang-format clang-tidy clangd ld.lld lldb lldb-server; do \
lldbUpdAltArgs="${lldbUpdAltArgs} --slave /usr/bin/${binName} ${binName} /usr/bin/${binName}-${LLVM_VERSION}"; \
done; \
sh -c "${lldbUpdAltArgs}";
# LD_LIBRARY_PATH is empty by default, this is the first entry
ENV LD_LIBRARY_PATH="/usr/lib/llvm-${LLVM_VERSION}/lib"
# Python setup
# PYTHON_VERSION should match the value in .python-version
@ -61,10 +89,11 @@ RUN apt-get update && apt-get install $APT_ARGS \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
llvm \
make \
tk-dev \
xz-utils
xz-utils \
&& rm -rf /var/lib/apt/lists/*
ENV PYENV_ROOT="/usr/local/pyenv"
ENV PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${PATH}"
RUN curl https://pyenv.run | bash \
@ -82,19 +111,38 @@ RUN pip3 install \
pyzmq==22.3.0 \
vulture==2.3
# dash_hash
ARG DASH_HASH_VERSION=1.4.0
RUN git clone --depth 1 --no-tags --branch=${DASH_HASH_VERSION} https://github.com/dashpay/dash_hash
RUN cd dash_hash && pip3 install -r requirements.txt .
RUN set -ex; \
cd /tmp; \
git clone --depth 1 --no-tags --branch=${DASH_HASH_VERSION} https://github.com/dashpay/dash_hash; \
cd dash_hash && pip3 install -r requirements.txt .; \
cd .. && rm -rf dash_hash
ARG CPPCHECK_VERSION=2.13.0
RUN set -ex; \
curl -fL "https://github.com/danmar/cppcheck/archive/${CPPCHECK_VERSION}.tar.gz" -o /tmp/cppcheck.tar.gz; \
mkdir -p /opt/cppcheck && tar -xzf /tmp/cppcheck.tar.gz -C /opt/cppcheck --strip-components=1 && rm /tmp/cppcheck.tar.gz; \
cd /opt/cppcheck; \
mkdir build && cd build && cmake .. && cmake --build . -j "$(( $(nproc) - 1 ))"; \
mkdir /usr/local/share/Cppcheck && ln -s /opt/cppcheck/cfg/ /usr/local/share/Cppcheck/cfg; \
rm -rf /tmp/cppcheck.tar.gz
ENV PATH="/opt/cppcheck/build/bin:${PATH}"
ARG SHELLCHECK_VERSION=v0.7.1
RUN set -ex; \
curl -fL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" -o /tmp/shellcheck.tar.xz; \
mkdir -p /opt/shellcheck && tar -xf /tmp/shellcheck.tar.xz -C /opt/shellcheck --strip-components=1 && rm /tmp/shellcheck.tar.xz
ENV PATH="/opt/shellcheck:${PATH}"
# Add user with specified (or default) user/group ids and setup configuration files
ARG USER_ID=1000
ARG GROUP_ID=1000
# add user with specified (or default) user/group ids
ENV USER_ID="${USER_ID}"
ENV GROUP_ID="${GROUP_ID}"
RUN groupadd -g ${GROUP_ID} dash
RUN useradd -u ${USER_ID} -g dash -s /bin/bash -m -d /home/dash dash
RUN set -ex; \
groupadd -g ${GROUP_ID} dash; \
useradd -u ${USER_ID} -g dash -s /bin/bash -m -d /home/dash dash; \
mkdir -p /home/dash/.config/gdb; \
echo "add-auto-load-safe-path /usr/lib/llvm-${LLVM_VERSION}/lib" | tee /home/dash/.config/gdb/gdbinit; \
chown ${USER_ID}:${GROUP_ID} -R /home/dash
# Packages needed for all target builds
RUN apt-get update && apt-get install $APT_ARGS \
@ -111,17 +159,8 @@ RUN apt-get update && apt-get install $APT_ARGS \
valgrind \
wine-stable \
wine64 \
xorriso
ARG CPPCHECK_VERSION=2.13.0
RUN curl -sL "https://github.com/danmar/cppcheck/archive/${CPPCHECK_VERSION}.tar.gz" | tar -xvzf - --directory /tmp/
RUN cd /tmp/cppcheck-${CPPCHECK_VERSION} && mkdir build && cd build && cmake .. && cmake --build . -j 8
ENV PATH="/tmp/cppcheck-${CPPCHECK_VERSION}/build/bin:${PATH}"
RUN mkdir /usr/local/share/Cppcheck && ln -s /tmp/cppcheck-${CPPCHECK_VERSION}/cfg/ /usr/local/share/Cppcheck/cfg
ARG SHELLCHECK_VERSION=v0.7.1
RUN curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | tar --xz -xf - --directory /tmp/
ENV PATH="/tmp/shellcheck-${SHELLCHECK_VERSION}:${PATH}"
xorriso \
&& rm -rf /var/lib/apt/lists/*
# This is a hack. It is needed because gcc-multilib and g++-multilib are conflicting with g++-arm-linux-gnueabihf. This is
# due to gcc-multilib installing the following symbolic link, which is needed for -m32 support. However, this causes
@ -135,20 +174,6 @@ RUN \
update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix; \
exit 0
ARG LLVM_VERSION=16
# Setup Clang+LLVM support
RUN apt-get update && apt-get install $APT_ARGS \
lsb-release \
software-properties-common \
gnupg \
&& rm -rf /var/lib/apt/lists/*
RUN cd /tmp && \
wget https://apt.llvm.org/llvm.sh && \
chmod +x llvm.sh && \
/tmp/llvm.sh ${LLVM_VERSION} && \
rm -rf /tmp/llvm.sh
RUN \
mkdir -p /src/dash && \
mkdir -p /cache/ccache && \

View File

@ -1,17 +1,18 @@
version: "3.9"
services:
container:
entrypoint: /bin/bash
build:
context: '..'
dockerfile: './develop/Dockerfile'
tty: true # Equivalent to -t
stdin_open: true # Equivalent to -i
ports:
- "9998:9998" # Mainnet Ports
- "9999:9999"
- "19998:19998" # Testnet Ports
- "19999:19999"
security_opt:
- seccomp:unconfined
stdin_open: true # Equivalent to -i
tty: true # Equivalent to -t
# A note about volumes:
#

View File

@ -18,7 +18,11 @@ RUN apt-get update && \
sudo \
wget \
xz-utils && \
rm -rf /var/lib/apt/lists/*
rm -rf /var/lib/apt/lists/*; \
targetLocale="en_US.UTF-8"; \
locale-gen ${targetLocale} && \
update-locale LC_ALL=${targetLocale} && \
update-locale LANG=${targetLocale};
ARG guix_download_path=ftp://ftp.gnu.org/gnu/guix
ARG guix_version=1.4.0
@ -30,8 +34,7 @@ ENV PATH="/usr/local/bin:/usr/local/guix/current/bin:$PATH"
# Application Setup
# https://guix.gnu.org/manual/en/html_node/Application-Setup.html
ENV GUIX_LOCPATH="/usr/local/guix/profile" \
LC_ALL="en_US.UTF-8"
ENV GUIX_LOCPATH="/usr/local/guix/profile"
RUN guix_file_name=guix-binary-${guix_version}.$(uname -m)-linux.tar.xz && \
eval "guix_checksum=\${guix_checksum_$(uname -m)}" && \
@ -78,14 +81,15 @@ COPY --from=docker_root ./motd.txt /etc/motd
COPY --from=docker_root ./scripts/entrypoint /usr/local/bin/entrypoint
COPY --from=docker_root ./scripts/guix-check /usr/local/bin/guix-check
COPY --from=docker_root ./scripts/guix-start /usr/local/bin/guix-start
COPY --from=docker_root ./scripts/setup-sdk /usr/local/bin/setup-sdk
# Create directories for mounting to save/restore cache and grant necessary permissions
RUN mkdir -p \
/home/${USERNAME}/.cache \
/src/dash/depends/{built,sources,work} && \
/src/dash/depends/{built,sources,work}; \
chown -R ${USER_ID}:${GROUP_ID} \
/home/${USERNAME}/.cache \
/src
/src;
WORKDIR "/src/dash"

View File

@ -1,4 +1,3 @@
version: "3.9"
services:
guix_ubuntu:
build:

View File

@ -9,19 +9,10 @@ if [[ ! -d "${WORKSPACE_PATH}" || ! "${WORKSPACE_PATH}" = /* || ! -f "${WORKSPAC
exit 1
fi
XCODE_VERSION="15.0"
XCODE_RELEASE="15A240d"
XCODE_ARCHIVE="Xcode-${XCODE_VERSION}-${XCODE_RELEASE}-extracted-SDK-with-libcxx-headers"
XCODE_SOURCE="${XCODE_SOURCE:-https://bitcoincore.org/depends-sources/sdks}"
export SDK_PATH="${SDK_PATH:-${WORKSPACE_PATH}/depends/SDKs}"
export SDK_SRCS="${SDK_PATH:-${WORKSPACE_PATH}/depends/sdk-sources}"
# Check if macOS SDK is present, if not, download it
if [[ ! -d "${SDK_PATH}/${XCODE_ARCHIVE}" ]]; then
echo "Preparing macOS SDK..."
mkdir -p "${SDK_PATH}"
curl -L "${XCODE_SOURCE}/${XCODE_ARCHIVE}.tar.gz" | tar -xz -C "${SDK_PATH}"
fi
./contrib/containers/guix/scripts/setup-sdk
# Add safe.directory option only when WORKSPACE_PATH was specified via cmd-line arguments (happens in CI)
if [[ -n "${1}" ]]; then

View File

@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Copyright (c) 2024 The Dash Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C.UTF-8
set -eo pipefail
SDK_URL="${SDK_URL:-https://bitcoincore.org/depends-sources/sdks}"
SDK_PATH="${SDK_PATH:-depends/SDKs}"
SDK_SRCS="${SDK_SOURCES:-depends/sdk-sources}"
XCODE_VERSION="${XCODE_VERSION:-15.0}"
XCODE_RELEASE="${XCODE_RELEASE:-15A240d}"
XCODE_ARCHIVE="Xcode-${XCODE_VERSION}-${XCODE_RELEASE}-extracted-SDK-with-libcxx-headers"
XCODE_AR_PATH="${SDK_SRCS}/${XCODE_ARCHIVE}.tar.gz"
if [ ! -d "${SDK_PATH}/${XCODE_ARCHIVE}" ]; then
if [ ! -f "${XCODE_AR_PATH}" ]; then
echo "Downloading macOS SDK..."
mkdir -p "${SDK_SRCS}"
curl --location --fail "${SDK_URL}/${XCODE_ARCHIVE}.tar.gz" -o "${XCODE_AR_PATH}"
fi
echo "Extracting macOS SDK..."
mkdir -p "${SDK_PATH}"
tar -C "${SDK_PATH}" -xf "${XCODE_AR_PATH}"
fi