theory / pgenv

PostgreSQL binary manager
MIT License
311 stars 27 forks source link

Configuration not correctly loaded when rebuilding postgres #52

Closed thanodnl closed 2 years ago

thanodnl commented 2 years ago

When rebuilding a specific postgres version it seems that the configuration does not get correctly loaded.

Given the following config/default.conf:

PGENV_CONFIGURE_OPTIONS=(
    --enable-cassert
)

When I run pgenv build 14.2 we get a compiled version of postgres 14.2 with cassert enabled. Simplest way to confirm the build configuration I know is via pg_config

$ pgsql-14.2/bin/pg_config --configure
 '--prefix=/Users/nilsdijk/.pgenv/pgsql-14.2' '--enable-cassert' 'CFLAGS=-I/usr/local/include/ -I/usr/local/opt/readline/include -I/usr/local/opt/openssl@1.1/include/ -I/usr/local/include/ -I/usr/local/opt/readline/include -I/usr/local/opt/openssl@1.1/include/ ' 'LDFLAGS=-L/usr/local/opt/gettext/lib -L/usr/local/opt/zstd/lib -L/usr/local/opt/lz4/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/icu4c/lib -L/usr/local/opt/openssl@1.1/lib' 'CPPFLAGS=-I/usr/local/include -I/usr/local/opt/gettext/include -I/usr/local/opt/zstd/include -I/usr/local/opt/lz4/include -I/usr/local/opt/readline/include -I/usr/local/opt/icu4c/include -I/usr/local/opt/openssl@1.1/include -I/usr/local/include -I/usr/local/opt/gettext/include -I/usr/local/opt/zstd/include -I/usr/local/opt/lz4/include -I/usr/local/opt/readline/include -I/usr/local/opt/icu4c/include -I/usr/local/opt/openssl@1.1/include ' 'PKG_CONFIG_PATH=:/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/readline/lib/pkgconfig:/usr/local/opt/lz4/lib/pkgconfig:/usr/local/opt/zstd/lib/pkgconfig:/usr/local/opt/gettext/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/readline/lib/pkgconfig:/usr/local/opt/lz4/lib/pkgconfig:/usr/local/opt/zstd/lib/pkgconfig:/usr/local/opt/gettext/lib/pkgconfig'

Ignoring the CFLAGS/LDFLAGS/CPPFLAGS that I have in my environment we can clearly see the --enable-cassert as a second configure flag being passed in.

Now we run pgenv rebuild 14.2.

Now the output of pg_config changed as follows:

$ pgsql-14.2/bin/pg_config --configure
 '--prefix=/Users/nilsdijk/.pgenv/pgsql-14.2' 'CFLAGS=-I/usr/local/include/ -I/usr/local/opt/readline/include -I/usr/local/opt/openssl@1.1/include/ -I/usr/local/include/ -I/usr/local/opt/readline/include -I/usr/local/opt/openssl@1.1/include/ ' 'LDFLAGS=-L/usr/local/opt/gettext/lib -L/usr/local/opt/zstd/lib -L/usr/local/opt/lz4/lib -L/usr/local/opt/readline/lib -L/usr/local/opt/icu4c/lib -L/usr/local/opt/openssl@1.1/lib' 'CPPFLAGS=-I/usr/local/include -I/usr/local/opt/gettext/include -I/usr/local/opt/zstd/include -I/usr/local/opt/lz4/include -I/usr/local/opt/readline/include -I/usr/local/opt/icu4c/include -I/usr/local/opt/openssl@1.1/include -I/usr/local/include -I/usr/local/opt/gettext/include -I/usr/local/opt/zstd/include -I/usr/local/opt/lz4/include -I/usr/local/opt/readline/include -I/usr/local/opt/icu4c/include -I/usr/local/opt/openssl@1.1/include ' 'PKG_CONFIG_PATH=:/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/readline/lib/pkgconfig:/usr/local/opt/lz4/lib/pkgconfig:/usr/local/opt/zstd/lib/pkgconfig:/usr/local/opt/gettext/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/readline/lib/pkgconfig:/usr/local/opt/lz4/lib/pkgconfig:/usr/local/opt/zstd/lib/pkgconfig:/usr/local/opt/gettext/lib/pkgconfig'

Again ignore the CFLAGS/LDFLAGS/CPPFLAGS we find that the --enable-cassert flag is missing.

In the mean time we see two new config files created in the conf directory.

config/14.2.conf

...
# Configure flags, including PL languages but without --prefix
declare -a PGENV_CONFIGURE_OPTIONS=()
...

config/14.2.conf.2022-05-04T13-54.backup

...
# Configure flags, including PL languages but without --prefix
declare -a PGENV_CONFIGURE_OPTIONS=([0]="--enable-cassert")
...

The backup seems to be indicating that at some point in time the flag was correctly stored in the version specific configuration, but unused during the rebuild as per output of pg_config --configure. To be completely clear, the only configuration file I have created is config/default.conf, the others are (probably?) created by pgenv during builds.

I ran these experiments on OSX 12.3.1, with zsh as a shell. Both tried bash versions:

Quick experiments and asking around show the same behaviour on Ubuntu (docker ubuntu:22.04).

fluca1978 commented 2 years ago

Seems something wrong with the source of the configuration file, since the file is correctly selected.

thanodnl commented 2 years ago

Having poked around a bit I think the problem is mostly in the declare -a part of the generated config files from pgenv.

When the 14.2.conf file - as generated by pgenv - gets sourced, the variables are correctly set within the pgenv_configuration_load function. However after that function returns control back to the call site the variables have their original value again when the sourced file had delcare -a prepended before the configuration.

contrary to my default.conf file - that doesn't use the declare -a syntax. When this file gets sourced the sourced values retain after pgenv_configuration_load returns.

I am not super fluent in bash, and am not super familiar with declare, however, from its behaviour on my systems I guess it declare's the variable in the scope of the function, instead of populating the global variables with the values from the configuration file.

Anyway, are you able to reproduce the behaviour of rebuilds not retaining the configuration flags configured initially? Or is there something specific to my environments. Guess not, as I can easily reproduce in a vanilla ubuntu environment.

fluca1978 commented 2 years ago

Good guess! Thank you a lot, it was a problem with typeset and declare. Should be working now.