Skip to content

Commit

Permalink
Deploy 87a9082 to gh-pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Deploy from CI committed Oct 20, 2023
0 parents commit 2a8ffdc
Show file tree
Hide file tree
Showing 82 changed files with 18,749 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build]
# Postgres symbols won't be available until runtime
rustflags = ["-C", "link-args=-Wl,-undefined,dynamic_lookup"]
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.DS_Store
.idea/
target/
*.iml
**/*.rs.bk
*.o
*.so
*.a
cmake*/
.direnv
plrust/postgrestd
.git
Dockerfile.*
5 changes: 5 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# reload when these files change
watch_file flake.nix
watch_file flake.lock
# load the flake devShell
eval "$(nix print-dev-env)"
184 changes: 184 additions & 0 deletions .github/docker/Dockerfile.debian-artifact-build
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# 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 \
llvm-11-dev libclang-11-dev clang-11 \
gcc \
git \
jq \
libssl-dev \
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>&1 > /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 \
.
27 changes: 27 additions & 0 deletions .github/scripts/install_cargo_pgrx.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bash

# Installs/upgrades cargo-pgrx based on version specified in plrust/Cargo.toml
#
# Expects the following environment variables to already exist:
# * None
#
# Expects the following parameters (in-order):
# * None
#
# Example usage:
# . /path/to/plrust/.github/scripts/install_cargo_pgrx.sh
# install_cargo_pgrx

function install_cargo_pgrx() {
set -o pipefail
set -e

if TARGET_VERSION=$(cargo metadata --format-version 1 | jq -r '.packages[]|select(.name=="pgrx")|.version'); then
echo "Installing/upgrading cargo-pgrx to version $TARGET_VERSION"
cargo install cargo-pgrx --force --version "$TARGET_VERSION"
else
echo "Could not determine cargo-pgrx version to install."
exit 1
fi
}

47 changes: 47 additions & 0 deletions .github/scripts/load_cache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash

# Downloads and extracts cache archive from S3.
#
# Expects the following environment variables to already exist:
# * AWS_CACHE_BUCKET: the S3 bucket in which to obtain the archive
# * HOME: executing user's home directory
#
# Expects the following parameters (in-order):
# * $1: the pre-calculated cache key
#
# Example usage:
# . /path/to/plrust/.github/scripts/load_cache.sh
# loadcache "some-cache-key-abc123"
#
# Note: This assumes the host in which this script is running on has the ability
# to read and write from the bucket specified by AWS_CACHE_BUCKET

function loadcache() {
local cache_key="$1"

echo "Checking to see if cache archive exists: $cache_key"

if aws s3api head-object --bucket $AWS_CACHE_BUCKET --key $cache_key &> /dev/null; then
echo "Cache archive exists for $cache_key -- downloading and extracting now."

mkdir -p $HOME/artifacts/
archive_path=$HOME/artifacts/$cache_key

echo "Downloadng archive $cache_key and storing to $archive_path"

aws s3api get-object \
--bucket $AWS_CACHE_BUCKET \
--key $cache_key \
$archive_path

echo "Extracting archive $cache_key"
lz4 -dc --no-sparse $archive_path | tar xvC /

echo "Removing archive $archive_path"
rm $archive_path

echo "Done."
else
echo "Cache archive does not exist for $cache_key -- skipping."
fi
}
50 changes: 50 additions & 0 deletions .github/scripts/save_cache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env bash

# Creates cache archive and uploads to S3.
#
# Expects the following environment variables to already exist:
# * AWS_CACHE_BUCKET: the S3 bucket in which to obtain the archive
# * HOME: executing user's home directory
#
# Expects the following parameters (in-order):
# * $1: the pre-calculated cache key
# * $2: array of full-path directories to be cached
#
# Example usage:
# . /path/to/plrust/.github/scripts/save_cache.sh
# my_paths=(/path/one /path/two /path/three)
# savecache "some-cache-key-abc123" "${my_paths[@]}"
#
# Note: This assumes the host in which this script is running on has the ability
# to read and write from the bucket specified by AWS_CACHE_BUCKET

function savecache() {
local cache_key="$1"
shift
local dirs_to_save=("$@")

echo "Checking to see if cache archive exists: $cache_key"

if aws s3api head-object --bucket $AWS_CACHE_BUCKET --key $cache_key &> /dev/null; then
echo "Cache archive exists for $cache_key -- skipping archive creation."
else
echo "Cache archive does not exist for $cache_key -- creating archive now."

archive_path=$HOME/artifacts/$cache_key

echo "Creating archive at $archive_path"

tar --ignore-failed-read -cvf - "${dirs_to_save[@]}" \
| lz4 - $archive_path

echo "Created archive $archive_path -- uploading now"

aws s3api put-object \
--bucket $AWS_CACHE_BUCKET \
--key $cache_key \
--body $archive_path

echo "Removing $archive_path"
rm $archive_path
fi
}
Loading

0 comments on commit 2a8ffdc

Please sign in to comment.