-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
These changes will allow Github Actions to build Debian packages to be created and attached to releases whenever releases are made.
- Loading branch information
1 parent
f8a9718
commit b821159
Showing
14 changed files
with
648 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,4 @@ cmake*/ | |
.direnv | ||
plrust/postgrestd | ||
.git | ||
Dockerfile.try | ||
Dockerfile.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
# NOTE: This Dockerfile will require a more recent version of Docker that has heredoc support. | ||
# | ||
# Example of how to build this Dockerfile (requires being launched from the root of checkout): | ||
# docker build --build-arg PG_VER=15 --build-arg PLRUST_VER=1.0.2 -f .github/docker/Dockerfile.debian-artifact-build -t plrust-debian . | ||
# | ||
# Example of how to run an image after it has been built (assuming previous step has been done): | ||
# docker run -it --rm plrust-debian /bin/bash | ||
# | ||
# Any artifacts produced will be in the /out directory of the running Docker container. With a container running, an example | ||
# of how to copy out artifacts: | ||
# docker cp container_name:/out . | ||
# which will copy the container's /out directory to the current directory of the host | ||
|
||
FROM debian:bullseye | ||
|
||
# Args to pass in at build-time. Note that these are defaulted. | ||
ARG PG_VER=15 | ||
ARG PLRUST_VER=0.0.0 | ||
|
||
# Change this value if the entire build cache needs to be busted for any reason. | ||
# Any random value can work here. UUIDs seemed to be a good choice. | ||
ARG CACHE_KEY=2d912233-4423-48f9-b7ba-afc6b2ef3a44 | ||
|
||
SHELL ["/bin/bash", "-c"] | ||
|
||
# Install system-level dependencies. Prefer to install Postgres from the official | ||
# Postgres Debian packages | ||
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && \ | ||
apt-get update && \ | ||
apt-get install -y --no-install-recommends \ | ||
ca-certificates \ | ||
gnupg \ | ||
lsb-release \ | ||
wget && \ | ||
sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' && \ | ||
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null && \ | ||
apt-get update -y -qq --fix-missing && \ | ||
apt-get install -y --no-install-recommends \ | ||
build-essential \ | ||
clang \ | ||
clang-11 \ | ||
gcc \ | ||
git \ | ||
jq \ | ||
libssl-dev \ | ||
llvm-11 \ | ||
make \ | ||
postgresql-${PG_VER} \ | ||
postgresql-server-dev-${PG_VER} \ | ||
pkg-config \ | ||
ruby && \ | ||
rm -rf /var/lib/apt/lists/* | ||
|
||
# Install fpm for the creation of the .deb file, | ||
# and install toml so TOML files can be parsed later | ||
RUN gem install --no-document fpm toml | ||
|
||
# Set up permissions so that the postgres user can install the plrust plugin | ||
RUN chmod a+rwx `$(which pg_config) --pkglibdir` `$(which pg_config) --sharedir`/extension | ||
|
||
# Create the directory for the outgoing .deb package | ||
RUN mkdir /out && chmod 777 /out | ||
|
||
# The 'postgres' user is the default user that the official Postgres Debian packages create and set up | ||
USER postgres | ||
ENV USER postgres | ||
|
||
# Copy in plrust source | ||
COPY --chown=${USER} . src/ | ||
WORKDIR /src | ||
|
||
# Obtain the toolchain version from rust-toolchain.toml and store that into a file. | ||
RUN ruby <<EOF | ||
require 'toml' | ||
toml=TOML.load_file('/src/rust-toolchain.toml') | ||
if ver=toml['toolchain']['channel'] | ||
File.open('/tmp/.toolchain-ver', 'w') { |file| file.write(ver) } | ||
else | ||
raise 'Could not determine toolchain channel version. Is rust-toolchain.toml missing or malformed?' | ||
end | ||
EOF | ||
|
||
# Install Rust | ||
RUN TOOLCHAIN_VER=$(</tmp/.toolchain-ver) && wget -qO- https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain=$TOOLCHAIN_VER | ||
ENV PATH="/var/lib/postgresql/.cargo/bin:${PATH}" | ||
|
||
# Install the version of PGRX that is dictated by Cargo.toml for this project | ||
RUN PGRX_VERSION=$(cargo metadata --format-version 1 | jq -r '.packages[]|select(.name=="pgrx")|.version') && \ | ||
cargo install cargo-pgrx --force --version "$PGRX_VERSION" | ||
|
||
# Necessary to build plrustc and company | ||
RUN rustup component add llvm-tools-preview rustc-dev | ||
|
||
# Build and install plrstuc | ||
RUN cd /src/plrustc && ./build.sh && cp ../build/bin/plrustc ~/.cargo/bin | ||
|
||
# Init cargo pgrx | ||
RUN cargo pgrx init --pg${PG_VER} $(which pg_config) | ||
|
||
# Build plrust with postgrestd. Architecture is determined by the host running this Dockerfile | ||
# (i.e. no cross-compiling) | ||
RUN cd /src/plrust && STD_TARGETS="$(uname -m)-postgres-linux-gnu" ./build | ||
|
||
# Use cargo pgrx package to create everything necessary, placed into RELEASE_DIR below | ||
RUN cd /src/plrust && cargo pgrx package --features trusted | ||
|
||
# This is the root of all the files necessary to package up into the .deb file. This specific path is generated by | ||
# 'cargo pgrx package' above | ||
ENV RELEASE_DIR /src/target/release/plrust-pg${PG_VER} | ||
|
||
# Create the plrustc location for our distribution, then copy in the plrustc program into the correct spot | ||
RUN mkdir -p ${RELEASE_DIR}$HOME/.cargo/bin && \ | ||
cp $HOME/.cargo/bin/plrustc ${RELEASE_DIR}$HOME/.cargo/bin | ||
|
||
# The .deb file distribution needs to include the correct postgrestd toolchain files. | ||
RUN cd $HOME/.rustup && \ | ||
export TOOLCHAIN_DIR="$(pwd)/$(find * -type d -name '*postgres*' | head -n 1)" && \ | ||
mkdir -p "${RELEASE_DIR}$TOOLCHAIN_DIR" && \ | ||
cp -r "$TOOLCHAIN_DIR/." "${RELEASE_DIR}$TOOLCHAIN_DIR" | ||
|
||
# Creates a PGRX configuration Toml file, as it is required to build plrust user-defined functions | ||
RUN mkdir -p ${RELEASE_DIR}$HOME/.pgrx && \ | ||
echo '[configs]' >> ${RELEASE_DIR}$HOME/.pgrx/config.toml && \ | ||
echo "pg${PG_VER}='$(command -v pg_config)'" >> ${RELEASE_DIR}$HOME/.pgrx/config.toml | ||
|
||
# Create a Debian preinst script that will run before the installation of the pl/Rust package. | ||
# This will check to be sure the proper Rust toolchain and components are set up beforehand. | ||
RUN TOOLCHAIN_VER=$(</tmp/.toolchain-ver) && cat <<EOF > /tmp/preinst | ||
#!/usr/bin/env bash | ||
|
||
if ! id -u postgres 2&> /dev/null; then | ||
echo "[!] User 'postgres' does not exist. Have the official Postgres packages been installed yet?" | ||
exit 1 | ||
fi | ||
|
||
if ! runuser -l postgres -c 'command -v rustup'; then | ||
echo "[!] The 'postgres' user does not have rustup installed. Please see package installation instructions on how to do this."; | ||
exit 1 | ||
fi | ||
|
||
if ! runuser -l postgres -c 'command -v rustc'; then | ||
echo "[!] The 'postgres' user does not have Rust installed. Please see package installation instructions on how to do this."; | ||
exit 1 | ||
fi | ||
|
||
if ! runuser -l postgres -c 'rustup toolchain list | grep -q "^$TOOLCHAIN_VER-$(uname -m)\b"'; then | ||
echo "[!] The 'postgres' user does not have the Rust toolchain $TOOLCHAIN_VER-$(uname -m) installed. Please see package installation instructions on how to do this."; | ||
exit 1 | ||
fi | ||
|
||
if ! runuser -l postgres -c 'rustup component list | grep -q "^rustc-dev-$(uname -m)\b.*(installed)$"'; then | ||
echo "[!] The 'postgres' user does not have the Rust component 'rustc-dev' installed. Please see package installation instructions on how to do this."; | ||
exit 1 | ||
fi | ||
|
||
if ! runuser -l postgres -c 'rustup toolchain list | grep -q "^$TOOLCHAIN_VER-$(uname -m)\b.*(default)$"'; then | ||
echo "[!] The 'postgres' user does not have the default toolchain set to $TOOLCHAIN_VER. Please see package installation instructions on how to do this."; | ||
exit 1 | ||
fi | ||
|
||
EOF | ||
|
||
# Package everything up based on whatever's in RELEASE_DIR, and send the resulting | ||
# .deb file to the /out directory | ||
RUN TOOLCHAIN_VER=$(</tmp/.toolchain-ver) && \ | ||
DEB_FILENAME="plrust-trusted-${PLRUST_VER}_$TOOLCHAIN_VER-debian-pg${PG_VER}-$(dpkg --print-architecture).deb" && \ | ||
cd ${RELEASE_DIR} && fpm \ | ||
-s dir \ | ||
-t deb \ | ||
-n plrust \ | ||
--deb-pre-depends "postgresql-${PG_VER}" \ | ||
-d "postgresql-${PG_VER}" \ | ||
-d "postgresql-server-dev-${PG_VER}" \ | ||
-m 'Technology Concepts & Design, Inc. <support@tcdi.com>' \ | ||
--description 'PL/Rust is a loadable procedural language that enables writing PostgreSQL functions in the Rust programming language.' \ | ||
-v ${PLRUST_VER} \ | ||
--url 'https://github.com/tcdi/plrust' \ | ||
--license 'The PostgreSQL License' \ | ||
--category 'Databases' \ | ||
--deb-no-default-config-files \ | ||
--before-install /tmp/preinst \ | ||
-p /out/$DEB_FILENAME \ | ||
--deb-user postgres \ | ||
--deb-group postgres \ | ||
-a native \ | ||
. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.