Source: patroni
Version: 1.6.4-1
Severity: minor
Tags: patch

Within the context of devops it would be important if
`pg_createconfig_patroni` were idempotent. That is, if
it would re-create the same configuration file given
the same input parameters.

Currently it is impossible to achieve idempotence with
`pg_createconfig_patroni` because it will check if a given
port is already used and fail, or if no port is given
assign a new port unconditionally, no matter if the given
cluster is already configured and running or not.

I suggest to:

1. if a port is given and matches an already running cluster, then
   allow the port

2. if no port is given, then determine whether the given cluster is
   already running and reuse the running port

So instead of this:

    if [ -z "$PORT" ]; then
        # try to guess next free port
        PORT=$(($(pg_lsclusters | awk '{print $3}' | grep -v Port | sort -n | 
tail -1) + 1))
        if [ "$PORT" -eq 1 ]; then
            # No cluster exists yet, use default port
            PORT=5432
        fi
    else
        # validate specified port
        pg_lsclusters | awk '{print $3}' | grep -q $PORT && echo "Port $PORT 
already in use" && exit 1
    fi

I suggest to do this:

    # find port of the cluster if it is already running
    EXISTING_PORT=$(pg_lsclusters | tail -n +2 | grep -E 
"^$VERSION[[:space:]]+$CLUSTER[[:space:]]+" | awk '{print $3}' )
    
    if [ -z "$PORT" ]; then
        # no port was specified
    
        if [ -n "$EXISTING_PORT" ]; then
            # if our cluster is already running yet, then reuse the same port
            PORT="$EXISTING_PORT"
    
        else
            # if our cluster isn't running yet, then try to guess next free port
            PORT=$(($(pg_lsclusters | tail -n +2 | awk '{print $3}' | sort -n | 
tail -1) + 1))
            if [ "$PORT" -eq 1 ]; then
                # No cluster exists yet, use default port
                PORT=5432
            fi
        fi
    else
        # validate specified port
    
        if [ "$PORT" = "$EXISTING_PORT" ]; then
            # reuse existing port
            true
        else
            # fail if port already in use
            pg_lsclusters | awk '{print $3}' | grep -q $PORT && echo "Port 
$PORT already in use" && exit 1
        fi
    fi

Thanks,
*t

-- System Information:
Debian Release: 10.3
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.19.0-8-amd64 (SMP w/8 CPU cores)
Locale: LANG=de_CH.utf8, LC_CTYPE=de_CH.utf8 (charmap=UTF-8), LANGUAGE=de_CH:de 
(charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Reply via email to