From 4ee4b8bdd9f543dc8b4fe9d04ba154ae5c75c326 Mon Sep 17 00:00:00 2001 From: Eric Ridge Date: Fri, 22 Nov 2024 11:17:25 -0500 Subject: [PATCH] Introduce a blocklist of "yanked" Postgres versions (#1950) Due to the out-of-band release set described here: https://www.postgresql.org/about/news/postgresql-172-166-1510-1415-1318-and-1222-released-2965/, we should refuse to compile on the prior point releases mentioned in this press release. --- .github/workflows/package-test.yaml | 61 +++++++++++++++++++++++++++- .github/workflows/runas.yml | 62 ++++++++++++++++++++++++++++- pgrx-bindgen/src/build.rs | 29 +++++++++++++- pgrx-pg-config/src/lib.rs | 11 ++--- 4 files changed, 154 insertions(+), 9 deletions(-) diff --git a/.github/workflows/package-test.yaml b/.github/workflows/package-test.yaml index 088356911..8468d8080 100644 --- a/.github/workflows/package-test.yaml +++ b/.github/workflows/package-test.yaml @@ -22,14 +22,73 @@ jobs: with: prefix-key: "v1-pgrx--package-test" + - name: Set up prerequisites and environment + run: | + sudo apt-get update -y -qq --fix-missing + + echo "" + echo "----- Install sccache -----" + mkdir -p $HOME/.local/bin + curl -L https://github.com/mozilla/sccache/releases/download/v0.2.15/sccache-v0.2.15-x86_64-unknown-linux-musl.tar.gz | tar xz + mv -f sccache-v0.2.15-x86_64-unknown-linux-musl/sccache $HOME/.local/bin/sccache + chmod +x $HOME/.local/bin/sccache + echo "$HOME/.local/bin" >> $GITHUB_PATH + mkdir -p /home/runner/.cache/sccache + echo "" + + echo "----- Set up dynamic variables -----" + cat $GITHUB_ENV + echo "" + + echo "----- Remove old postgres -----" + sudo apt remove -y '^postgres.*' '^libpq.*' '^clang.*' '^llvm.*' '^libclang.*' '^libllvm.*' '^mono-llvm.*' + echo "" + + echo "----- Install system dependencies -----" + sudo apt-get install -y \ + build-essential \ + llvm-14-dev libclang-14-dev clang-14 \ + gcc \ + libssl-dev \ + libz-dev \ + make \ + pkg-config \ + strace \ + zlib1g-dev + echo "" + + "$TOOL_DIR"/rustup.sh + + echo "----- Set up cross compilation -----" + sudo apt-get install -y --fix-missing crossbuild-essential-arm64 + + echo 'CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc' >> $GITHUB_ENV + # TODO: not all of these should be needed, but for now it's likely fine. + echo 'BINDGEN_EXTRA_CLANG_ARGS_aarch64-unknown-linux-gnu=-target aarch64-unknown-linux-gnu -isystem /usr/aarch64-linux-gnu/include/ -ccc-gcc-name aarch64-linux-gnu-gcc' >> $GITHUB_ENV + + echo "----- Print env -----" + env + echo "" + + - name: Setup release Postgres apt repo + run: | + sudo apt-get install -y wget gnupg + sudo 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 | sudo apt-key add - + - name: Install Postgres deps run: | sudo apt-get update -y -qq --fix-missing - sudo apt-get install -y postgresql-server-dev-$PG_VER + sudo apt-get install -y postgresql-$PG_VER postgresql-server-dev-$PG_VER - name: Rustup run: $TOOL_DIR/rustup.sh nightly + - name: Report version + run: | + cargo --version + pg_config --version + - name: Install cargo pgrx run: cargo +nightly install --path cargo-pgrx --debug diff --git a/.github/workflows/runas.yml b/.github/workflows/runas.yml index f8064be7f..b92710887 100644 --- a/.github/workflows/runas.yml +++ b/.github/workflows/runas.yml @@ -9,6 +9,8 @@ on: env: CARGO_TERM_COLOR: always RUST_BACKTRACE: 1 + TOOL_DIR: ./tools + PG_VER: 14 jobs: ubuntu: @@ -20,13 +22,69 @@ jobs: with: prefix-key: "v1-cargo-pgrx-test--runas" + - name: Set up prerequisites and environment + run: | + sudo apt-get update -y -qq --fix-missing + + echo "" + echo "----- Install sccache -----" + mkdir -p $HOME/.local/bin + curl -L https://github.com/mozilla/sccache/releases/download/v0.2.15/sccache-v0.2.15-x86_64-unknown-linux-musl.tar.gz | tar xz + mv -f sccache-v0.2.15-x86_64-unknown-linux-musl/sccache $HOME/.local/bin/sccache + chmod +x $HOME/.local/bin/sccache + echo "$HOME/.local/bin" >> $GITHUB_PATH + mkdir -p /home/runner/.cache/sccache + echo "" + + echo "----- Set up dynamic variables -----" + cat $GITHUB_ENV + echo "" + + echo "----- Remove old postgres -----" + sudo apt remove -y '^postgres.*' '^libpq.*' '^clang.*' '^llvm.*' '^libclang.*' '^libllvm.*' '^mono-llvm.*' + echo "" + + echo "----- Install system dependencies -----" + sudo apt-get install -y \ + build-essential \ + llvm-14-dev libclang-14-dev clang-14 \ + gcc \ + libssl-dev \ + libz-dev \ + make \ + pkg-config \ + strace \ + zlib1g-dev + echo "" + + "$TOOL_DIR"/rustup.sh + + echo "----- Set up cross compilation -----" + sudo apt-get install -y --fix-missing crossbuild-essential-arm64 + + echo 'CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc' >> $GITHUB_ENV + # TODO: not all of these should be needed, but for now it's likely fine. + echo 'BINDGEN_EXTRA_CLANG_ARGS_aarch64-unknown-linux-gnu=-target aarch64-unknown-linux-gnu -isystem /usr/aarch64-linux-gnu/include/ -ccc-gcc-name aarch64-linux-gnu-gcc' >> $GITHUB_ENV + + echo "----- Print env -----" + env + echo "" + + - name: Setup release Postgres apt repo + run: | + sudo apt-get install -y wget gnupg + sudo 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 | sudo apt-key add - + - name: Install Postgres deps run: | sudo apt-get update -y -qq --fix-missing - sudo apt-get install -y postgresql-server-dev-14 + sudo apt-get install -y postgresql-$PG_VER postgresql-server-dev-$PG_VER - name: Report version - run: cargo --version + run: | + cargo --version + pg_config --version - name: Install cargo pgrx run: cd cargo-pgrx && cargo install --path . --debug diff --git a/pgrx-bindgen/src/build.rs b/pgrx-bindgen/src/build.rs index fed8dcac0..c42bce27f 100644 --- a/pgrx-bindgen/src/build.rs +++ b/pgrx-bindgen/src/build.rs @@ -11,7 +11,8 @@ use bindgen::callbacks::{DeriveTrait, EnumVariantValue, ImplementsTrait, MacroPa use bindgen::NonCopyUnionStyle; use eyre::{eyre, WrapErr}; use pgrx_pg_config::{ - is_supported_major_version, PgConfig, PgConfigSelector, Pgrx, SUPPORTED_VERSIONS, + is_supported_major_version, PgConfig, PgConfigSelector, PgMinorVersion, PgVersion, Pgrx, + SUPPORTED_VERSIONS, }; use quote::{quote, ToTokens}; use std::cell::RefCell; @@ -26,6 +27,20 @@ use syn::{ForeignItem, Item, ItemConst}; const BLOCKLISTED_TYPES: [&str; 3] = ["Datum", "NullableDatum", "Oid"]; +// These postgres versions were effectively "yanked" by the community, even tho they still exist +// in the wild. pgrx will refuse to compile against them +const YANKED_POSTGRES_VERSIONS: &[PgVersion] = &[ + // this set of releases introduced an ABI break in the [`pg_sys::ResultRelInfo`] struct + // and was replaced by the community on 2024-11-21 + // https://www.postgresql.org/about/news/postgresql-172-166-1510-1415-1318-and-1222-released-2965/ + PgVersion::new(17, PgMinorVersion::Release(1), None), + PgVersion::new(16, PgMinorVersion::Release(5), None), + PgVersion::new(15, PgMinorVersion::Release(9), None), + PgVersion::new(14, PgMinorVersion::Release(14), None), + PgVersion::new(13, PgMinorVersion::Release(17), None), + PgVersion::new(12, PgMinorVersion::Release(21), None), +]; + pub(super) mod clang; pub(super) mod sym_blocklist; @@ -209,6 +224,7 @@ pub fn main() -> eyre::Result<()> { )) } }; + let found_major = found_ver.major; if let Ok(pg_config) = PgConfig::from_env() { let major_version = pg_config.major_version()?; @@ -222,6 +238,17 @@ pub fn main() -> eyre::Result<()> { vec![(found_ver.major, specific)] } }; + + // make sure we're not trying to build any of the yanked postgres versions + for (_, pg_config) in &pg_configs { + let version = pg_config.get_version()?; + if YANKED_POSTGRES_VERSIONS.contains(&version) { + panic!("Postgres v{}{} is incompatible with \ + other versions in this major series and is not supported by pgrx. Please upgrade \ + to the latest version in the v{} series.", version.major, version.minor, version.major); + } + } + std::thread::scope(|scope| { // This is pretty much either always 1 (normally) or 5 (for releases), // but in the future if we ever have way more, we should consider diff --git a/pgrx-pg-config/src/lib.rs b/pgrx-pg-config/src/lib.rs index 2a23c91a8..508e8e523 100644 --- a/pgrx-pg-config/src/lib.rs +++ b/pgrx-pg-config/src/lib.rs @@ -86,7 +86,7 @@ impl PgMinorVersion { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct PgVersion { pub major: u16, pub minor: PgMinorVersion, @@ -269,22 +269,23 @@ impl PgConfig { Ok((major, minor)) } - fn get_version(&self) -> eyre::Result<(u16, PgMinorVersion)> { + pub fn get_version(&self) -> eyre::Result { let version_string = self.run("--version")?; - Self::parse_version_str(&version_string) + let (major, minor) = Self::parse_version_str(&version_string)?; + Ok(PgVersion::new(major, minor, None)) } pub fn major_version(&self) -> eyre::Result { match &self.version { Some(version) => Ok(version.major), - None => Ok(self.get_version()?.0), + None => Ok(self.get_version()?.major), } } fn minor_version(&self) -> eyre::Result { match &self.version { Some(version) => Ok(version.minor), - None => Ok(self.get_version()?.1), + None => Ok(self.get_version()?.minor), } }