-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathDockerfile.debian-artifact-build
More file actions
184 lines (153 loc) · 7.76 KB
/
Dockerfile.debian-artifact-build
File metadata and controls
184 lines (153 loc) · 7.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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 --locked --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-bullseye-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 \
.