Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nix/ext/tests/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ builtins.listToAttrs (
"index_advisor"
"pg_cron"
"pg_net"
"timescaledb"
"vector"
"wrappers"
]
Expand Down
65 changes: 0 additions & 65 deletions nix/ext/timescaledb-2.9.1.nix

This file was deleted.

166 changes: 124 additions & 42 deletions nix/ext/timescaledb.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,135 @@
postgresql,
openssl,
libkrb5,
buildEnv,
makeWrapper,
switch-ext-version,
}:

stdenv.mkDerivation rec {
pname = "timescaledb-apache";
version = "2.16.1";
let
pname = "timescaledb";
build =
version: hash: _revision:
stdenv.mkDerivation rec {
inherit pname version;

nativeBuildInputs = [ cmake ];
buildInputs = [
postgresql
openssl
libkrb5
];
nativeBuildInputs = [ cmake ];
buildInputs = [
postgresql
openssl
libkrb5
];

src = fetchFromGitHub {
owner = "timescale";
repo = "timescaledb";
rev = version;
hash = "sha256-sLxWdBmih9mgiO51zLLxn9uwJVYc5JVHJjSWoADoJ+w=";
};
src = fetchFromGitHub {
owner = "timescale";
repo = "timescaledb";
rev = version;
inherit hash;
};

cmakeFlags = [
"-DSEND_TELEMETRY_DEFAULT=OFF"
"-DREGRESS_CHECKS=OFF"
"-DTAP_CHECKS=OFF"
"-DAPACHE_ONLY=1"
] ++ lib.optionals stdenv.isDarwin [ "-DLINTER=OFF" ];

# Fix the install phase which tries to install into the pgsql extension dir,
# and cannot be manually overridden. This is rather fragile but works OK.
postPatch = ''
for x in CMakeLists.txt sql/CMakeLists.txt; do
substituteInPlace "$x" \
--replace 'DESTINATION "''${PG_SHAREDIR}/extension"' "DESTINATION \"$out/share/postgresql/extension\""
done

for x in src/CMakeLists.txt src/loader/CMakeLists.txt tsl/src/CMakeLists.txt; do
substituteInPlace "$x" \
--replace 'DESTINATION ''${PG_PKGLIBDIR}' "DESTINATION \"$out/lib\""
done
'';
cmakeFlags = [
"-DSEND_TELEMETRY_DEFAULT=OFF"
"-DREGRESS_CHECKS=OFF"
"-DTAP_CHECKS=OFF"
"-DAPACHE_ONLY=1"
] ++ lib.optionals stdenv.isDarwin [ "-DLINTER=OFF" ];

postPatch = ''
for x in CMakeLists.txt sql/CMakeLists.txt; do
if [ -f "$x" ]; then
substituteInPlace "$x" \
--replace 'DESTINATION "''${PG_SHAREDIR}/extension"' "DESTINATION \"$out/share/postgresql/extension\""
fi
done

for x in src/CMakeLists.txt src/loader/CMakeLists.txt tsl/src/CMakeLists.txt; do
if [ -f "$x" ]; then
substituteInPlace "$x" \
--replace 'DESTINATION ''${PG_PKGLIBDIR}' "DESTINATION \"$out/lib\""
fi
done
'';

installPhase = ''
# Run cmake install first
cmake --install . --prefix=$out

# TimescaleDB has two libraries:
# 1. timescaledb.so (loader)
# 2. timescaledb-VERSION.so (actual extension)
# Both need to be handled for multi-version support

# Rename the loader to be version-specific
if [ -f $out/lib/timescaledb${postgresql.dlSuffix} ]; then
mv $out/lib/timescaledb${postgresql.dlSuffix} $out/lib/timescaledb-loader-${version}${postgresql.dlSuffix}
fi

# The versioned library (timescaledb-VERSION.so) is already correctly named

meta = with lib; {
description = "Scales PostgreSQL for time-series data via automatic partitioning across time and space";
homepage = "https://www.timescale.com/";
changelog = "https://github.com/timescale/timescaledb/blob/${version}/CHANGELOG.md";
platforms = postgresql.meta.platforms;
license = licenses.asl20;
broken = versionOlder postgresql.version "13";
# Create versioned control file with default_version removed and module_pathname pointing to symlink
if [ -f $out/share/postgresql/extension/timescaledb.control ]; then
sed -e "/^default_version =/d" \
-e "s|^module_pathname = .*|module_pathname = '\$libdir/timescaledb'|" \
$out/share/postgresql/extension/timescaledb.control > $out/share/postgresql/extension/timescaledb--${version}.control
rm $out/share/postgresql/extension/timescaledb.control
fi
'';

meta = with lib; {
description = "Scales PostgreSQL for time-series data via automatic partitioning across time and space";
homepage = "https://www.timescale.com/";
changelog = "https://github.com/timescale/timescaledb/blob/${version}/CHANGELOG.md";
license = licenses.asl20;
inherit (postgresql.meta) platforms;
};
};

allVersions = (builtins.fromJSON (builtins.readFile ./versions.json)).timescaledb;
supportedVersions = lib.filterAttrs (
_: value: builtins.elem (lib.versions.major postgresql.version) value.postgresql
) allVersions;
versions = lib.naturalSort (lib.attrNames supportedVersions);
latestVersion = lib.last versions;
numberOfVersions = builtins.length versions;
packages = builtins.attrValues (
lib.mapAttrs (name: value: build name value.hash (value.revision or name)) supportedVersions
);
in
buildEnv {
name = pname;
paths = packages;
nativeBuildInputs = [ makeWrapper ];
postBuild = ''
{
echo "default_version = '${latestVersion}'"
cat $out/share/postgresql/extension/${pname}--${latestVersion}.control
} > $out/share/postgresql/extension/${pname}.control

# Create symlink for the loader
ln -sfn ${pname}-loader-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix}

# The versioned library symlink (timescaledb-VERSION.so files are already in place)

# checks - adjust count since we have both loader and versioned files
(set -x
test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" -gt 0
)
makeWrapper ${lib.getExe switch-ext-version} $out/bin/switch_timescaledb_version \
--prefix EXT_WRAPPER : "$out" --prefix EXT_NAME : "${pname}"

'';
pathsToLink = [
"/lib"
"/share/postgresql/extension"
];
passthru = {
inherit versions numberOfVersions switch-ext-version;
pname = "${pname}-all";
hasBackgroundWorker = true;
defaultSettings = {
shared_preload_libraries = [ "timescaledb" ];
};
version =
"multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions);
};
}
14 changes: 14 additions & 0 deletions nix/ext/versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,20 @@
],
"hash": "sha256-Cpi2iASi1QJoED0Qs1dANqg/BNZTsz5S+pw8iYyW03Y="
}
},
"timescaledb": {
"2.9.1": {
"postgresql": [
"15"
],
"hash": "sha256-fvVSxDiGZAewyuQ2vZDb0I6tmlDXl6trjZp8+qDBtb8="
},
"2.16.1": {
"postgresql": [
"15"
],
"hash": "sha256-sLxWdBmih9mgiO51zLLxn9uwJVYc5JVHJjSWoADoJ+w="
}
},
"vector": {
"0.4.0": {
Expand Down
1 change: 0 additions & 1 deletion nix/packages/postgres.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
ourExtensions = [
../ext/rum.nix
../ext/timescaledb.nix
../ext/timescaledb-2.9.1.nix
../ext/pgroonga.nix
../ext/index_advisor.nix
../ext/wal2json.nix
Expand Down
100 changes: 100 additions & 0 deletions nix/tests/timescaledb.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{ self, pkgs }:
let
inherit (pkgs) lib;
installedExtension =
postgresMajorVersion:
self.packages.${pkgs.system}."psql_${postgresMajorVersion}/exts/timescaledb-all";
versions = (installedExtension "15").versions;
firstVersion = lib.head versions;
postgresqlWithExtension =
postgresql:
let
majorVersion = lib.versions.major postgresql.version;
pkg = pkgs.buildEnv {
name = "postgresql-${majorVersion}-timescaledb";
paths = [
postgresql
postgresql.lib
(installedExtension majorVersion)
];
passthru = {
inherit (postgresql) version psqlSchema;
lib = pkg;
withPackages = _: pkg;
};
nativeBuildInputs = [ pkgs.makeWrapper ];
pathsToLink = [
"/"
"/bin"
"/lib"
];
postBuild = ''
wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib
wrapProgram $out/bin/pg_ctl --set NIX_PGLIBDIR $out/lib
wrapProgram $out/bin/pg_upgrade --set NIX_PGLIBDIR $out/lib
'';
};
in
pkg;
in
self.inputs.nixpkgs.lib.nixos.runTest {
name = "timescaledb";
hostPkgs = pkgs;
nodes.server =
{ ... }:
{
virtualisation = {
forwardPorts = [
{
from = "host";
host.port = 13022;
guest.port = 22;
}
];
};
services.openssh = {
enable = true;
};
users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIArkmq6Th79Z4klW6Urgi4phN8yq769/l/10jlE00tU9"
];

services.postgresql = {
enable = true;
package = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15;
settings = {
shared_preload_libraries = "timescaledb";
};
};

specialisation.postgresql15.configuration = {
services.postgresql = {
package = lib.mkForce (postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15);
};
};
};
testScript =
{ ... }:
''
def run_sql(query):
return server.succeed(f"""sudo -u postgres psql -t -A -F\",\" -c \"{query}\" """).strip()
def check_upgrade_path():
with subtest("Check timescaledb upgrade path"):
server.succeed("sudo -u postgres psql -c 'DROP EXTENSION IF EXISTS timescaledb;'")
run_sql(r"""CREATE EXTENSION timescaledb WITH VERSION \"${firstVersion}\";""")
installed_version = run_sql(r"""SELECT extversion FROM pg_extension WHERE extname = 'timescaledb';""")
assert installed_version == "${firstVersion}", f"Expected timescaledb version ${firstVersion}, but found {installed_version}"
for version in [${lib.concatStringsSep ", " (map (s: ''"${s}"'') versions)}][1:]:
run_sql(f"""ALTER EXTENSION timescaledb UPDATE TO '{version}';""")
installed_version = run_sql(r"""SELECT extversion FROM pg_extension WHERE extname = 'timescaledb';""")
assert installed_version == version, f"Expected timescaledb version {version}, but found {installed_version}"
start_all()
server.wait_for_unit("multi-user.target")
server.wait_for_unit("postgresql.service")
check_upgrade_path()
'';
}
Loading