Skip to content

Commit

Permalink
Problem: extensions containing non-unique files
Browse files Browse the repository at this point in the history
Most packaged extensions contain the same files, meaning we can't
install multiple versions of the same extension.

Solution: rename installation artifacts to include versions
  • Loading branch information
yrashk committed Oct 11, 2024
1 parent d7d92a4 commit 8cda466
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lib/pgpm/rpm/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def source_builder(target_directory = nil)
specfile.close
sources = File.join(dir, "sources")
FileUtils.mkdir_p(sources)
@spec.package.sources.map do |src|
@spec.sources.map do |src|
print "Downloading #{src.name}..."
srcfile = File.join(sources, src.name)
File.write(srcfile, src.read)
Expand Down
81 changes: 81 additions & 0 deletions lib/pgpm/rpm/scripts/prepare_artifacts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#! /usr/bin/env bash

set -xe

new_extension_so=

for file in $(find $PGPM_BUILDROOT -name '*.so'); do
filename=$(basename "$file")
if [[ "$filename" == "${PGPM_EXTENSION_NAME}.so" ]]; then
extension_so=$filename
dir=$(dirname "$file")
extension_dirname=${dir#"$PGPM_BUILDROOT"}
new_extension_so=$PGPM_EXTENSION_NAME--$PGPM_EXTENSION_VERSION.so
fi
done

if [[ -n "$new_extension_so" ]]; then

extdir=$PGPM_BUILDROOT$($PG_CONFIG --sharedir)/extension

mv "$PGPM_BUILDROOT$extension_dirname/$extension_so" "$PGPM_BUILDROOT$extension_dirname/$new_extension_so"

# control files
default_control=$extdir/$PGPM_EXTENSION_NAME.control
versioned_control=$extdir/$PGPM_EXTENSION_NAME--$PGPM_EXTENSION_VERSION.control
controls=("$default_control" "$versioned_control")
for control in "${controls[@]}"; do
if [[ -f "$control" ]]; then
# extension.so
sed -i "s|${extension_so}'|${new_extension_so}'|g" "$control"
# extension
sed -i "s|${extension_so%".so"}'|${new_extension_so%".so"}'|g" "$control"
fi
done
if [[ -f "$default_control" ]]; then
if [[ -f "$versioned_control" ]]; then
# We don't need default control if versioned is present
rm -f "$default_control"
else
# Default becomes versioned
mv "$default_control" "$versioned_control"
# Don't need default_version
sed -i '/default_version/d' "$versioned_control"
fi
fi

# sql files
for sql_file in $(find $PGPM_BUILDROOT -name '*.sql' -type f); do
# extension.so
sed -i "s|${extension_so}'|${new_extension_so}'|g" "$sql_file"
# extension
sed -i "s|${extension_so%".so"}'|${new_extension_so}'|g" "$sql_file"
done

# bitcode

pkglibdir=$PGPM_BUILDROOT$($PG_CONFIG --pkglibdir)

bitcode_extension=$pkglibdir/bitcode/${extension_so%".so"}
bitcode_index=$pkglibdir/bitcode/${extension_so%".so"}.index.bc

if [[ -d "${bitcode_extension}" ]]; then
mv "${bitcode_extension}" "$pkglibdir/bitcode/${new_extension_so%".so"}"
fi

if [[ -f "${bitcode_index}" ]]; then
mv "${bitcode_index}" "$pkglibdir/bitcode/${new_extension_so%".so"}.index.bc"
fi

# includes
includedir=$PGPM_BUILDROOT$($PG_CONFIG --includedir-server)

if [[ -d "${includedir}/extension/$PGPM_EXTENSION_NAME" ]]; then
versioned_dir=${includedir}/extension/$PGPM_EXTENSION_NAME--$PGPM_EXTENSION_VERSION
mkdir -p "$versioned_dir"
mv "${includedir}/extension/$PGPM_EXTENSION_NAME" "$versioned_dir"
fi

# TODO: share, docs, etc.

fi
25 changes: 20 additions & 5 deletions lib/pgpm/rpm/spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def versionless
Summary: #{@package.summary}
License: #{@package.license}
BuildRequires: #{@postgres_distribution} #{@postgres_distribution}-devel #{@postgres_distribution}-server
Requires: pgpm-#{@package.name}-#{@postgres_version}_#{@package.version}
BuildArch: noarch
Expand All @@ -32,23 +33,32 @@ def versionless
%build
%clean
rm -rf $RPM_BUILD_ROOT
%install
export PG_CONFIG=$(rpm -ql #{@postgres_distribution} | grep 'pg_config$')
mkdir -p %{buildroot}$($PG_CONFIG --sharedir)/extension
export CONTROL=%{buildroot}$($PG_CONFIG --sharedir)/extension/#{@package.extension_name}.control
echo "default_version = '#{@package.version}'" > $CONTROL
echo ${CONTROL#"%{buildroot}"} > filelist.txt
%files
%files -f filelist.txt
EOF
end

def sources
sources = @package.sources.clone
prepare_artifacts = -> { File.open(File.join(File.dirname(__FILE__), "scripts", "prepare_artifacts.sh")) }
sources.push(Pgpm::OnDemandFile.new("prepare_artifacts.sh", prepare_artifacts))
sources
end

def to_s
setup_opts = ["-q"]
if @package.source_url_directory_name
setup_opts.push("-n", @package.source_url_directory_name)
else
setup_opts.push("-n", "#{@package.name}-#{@package.version}")
end
sources = @package.sources

<<~EOF
Name: pgpm-#{@package.name}-#{@postgres_version}_#{@package.version}
Version: #{@package.version}
Expand Down Expand Up @@ -81,6 +91,11 @@ def to_s
export PGPM_BUILDROOT=%{buildroot}
find %{buildroot} -type f | sort - | sed 's|^%{buildroot}||' > .pgpm_before | sort
#{@package.install_steps.map(&:to_s).join("\n")}
export PGPM_EXTENSION_NAME="#{@package.extension_name}"
export PGPM_EXTENSION_VERSION="#{@package.version}"
cp %{SOURCE#{sources.length - 1}} ./prepare_artifacts.sh
chmod +x ./prepare_artifacts.sh
./prepare_artifacts.sh
find %{buildroot} -type f | sort - | sed 's|^%{buildroot}||' > .pgpm_after | sort
comm -13 .pgpm_before .pgpm_after | sort -u > filelist.txt
Expand Down

0 comments on commit 8cda466

Please sign in to comment.