88, python3Packages
99, writeText
1010, writers
11+ , toxiproxy
1112} :
1213let
1314 withTmpDb =
5455
5556 export PGDATA="$tmpdir/db"
5657 export PGHOST="$tmpdir/socket"
58+ PGPORT=$(${ randomPort } )
59+ export PGPORT
5760 export PGUSER
5861 export PGDATABASE
5962 export PGRST_DB_SCHEMAS
6063 export PGTZ
6164 export PGOPTIONS
6265
6366 HBA_FILE="$tmpdir/pg_hba.conf"
64- echo "local $PGDATABASE some_protected_user password" > "$HBA_FILE"
65- echo "local $PGDATABASE all trust" >> "$HBA_FILE"
66- echo "local replication all trust" >> "$HBA_FILE"
67+ {
68+ echo "local $PGDATABASE some_protected_user password"
69+ echo "local $PGDATABASE all trust"
70+ echo "local replication all trust"
71+ echo "host $PGDATABASE some_protected_user localhost password"
72+ echo "host $PGDATABASE all localhost trust"
73+ } >> "$HBA_FILE"
74+
75+ UNIX_PGHOST="$PGHOST"
76+ export TCP_PGHOST="localhost"
6777
6878 log "Initializing database cluster..."
6979 # We try to make the database cluster as independent as possible from the host
8090 # On MacOS, it's 104 chars
8191 # See: https://serverfault.com/questions/641347/check-if-a-path-exceeds-maximum-for-unix-domain-socket
8292
83- pg_ctl -l "$tmpdir/db.log" -w start -o "-F -c listen_addresses=\"\" -c hba_file=$HBA_FILE -k $PGHOST -c log_statement=\"all\" " \
93+ pg_ctl -l "$tmpdir/db.log" -w start -o "-F -c listen_addresses=\"$TCP_PGHOST \" -c hba_file=$HBA_FILE -k $UNIX_PGHOST -c log_statement=\"all\" " \
8494 >> "$setuplog"
8595
8696 log "Creating a minimally privileged $PGUSER connection role..."
93103 replica_slot="replica_$RANDOM"
94104 replica_dir="$tmpdir/$replica_slot"
95105 replica_host="$tmpdir/socket_$replica_slot"
106+ replica_port=$(${ randomPort } )
96107
97108 mkdir -p "$replica_host"
98109
@@ -105,15 +116,16 @@ let
105116
106117 log "Starting replica on $replica_host"
107118
108- pg_ctl -D "$replica_dir" -l "$replica_dblog" -w start -o "-F -c listen_addresses=\"\" -c hba_file=$HBA_FILE -k $replica_host -c log_statement=\"all\" " \
119+ pg_ctl -D "$replica_dir" -l "$replica_dblog" -w start -o "-F -c listen_addresses=\"$TCP_PGHOST\" -c port=$replica_port -c hba_file=$HBA_FILE -k $replica_host -c log_statement=\"all\" " \
109120 >> "$setuplog"
110121
111122 >&2 echo "${ commandName } : Replica enabled. You can connect to it with: psql 'postgres:///$PGDATABASE?host=$replica_host' -U postgres"
112123 >&2 echo "${ commandName } : You can tail the replica logs with: tail -f $replica_dblog"
113124
114125 export PGREPLICAHOST="$replica_host"
126+ export PGREPLICAPORT="$replica_port"
115127 export PGREPLICASLOT="$replica_slot"
116- export PGRST_DB_URI="postgres:///$PGDATABASE?host=$PGREPLICAHOST,$PGHOST"
128+ export PGRST_DB_URI="postgres:///$PGDATABASE?host=$PGREPLICAHOST,$PGHOST&port=$replica_port,$PGPORT "
117129 fi
118130
119131 # shellcheck disable=SC2329
371383 libraries = [ python3Packages . pandas python3Packages . tabulate python3Packages . psutil ] ;
372384 }
373385 ( builtins . readFile ./monitor_pid.py ) ;
386+
387+ randomPort =
388+ writers . writePython3 "postgrest-random-port"
389+ {
390+ # Quick one-liner: ignore linting errors
391+ flakeIgnore = [ "E702" "W292" "E501" ] ;
392+ }
393+ ''import socket; s = socket.socket(); s.bind(("127.0.0.1", 0)); print(s.getsockname()[1]); s.close()'' ;
394+
395+ withToxiproxyProxy =
396+ checkedShellScript
397+ {
398+ name = "postgrest-with-toxiproxy-proxy" ;
399+ docs = "Run <command> with Toxiproxy proxy created. Proxy name passed as TOXI_PROXY_NAME env variable." ;
400+ args =
401+ [
402+ "ARG_POSITIONAL_SINGLE([command], [Command to run])"
403+ "ARG_LEFTOVERS([command arguments])"
404+ "ARG_OPTIONAL_SINGLE([listen], [l], [Proxy will listen on this address])"
405+ "ARG_OPTIONAL_SINGLE([upstream], [u], [Proxy will forward to this address])"
406+ ] ;
407+ positionalCompletion = "_command" ;
408+ workingDir = "/" ;
409+ withPath = [ toxiproxy ] ;
410+ }
411+ ''
412+ proxyname="tp$RANDOM"
413+ toxiproxy-cli create -l "$_arg_listen" -u "$_arg_upstream" "$proxyname"
414+
415+ # shellcheck disable=SC2317
416+ # shellcheck disable=SC2329
417+ stop () {
418+ toxiproxy-cli delete "$proxyname" || true
419+ }
420+ trap stop EXIT
421+
422+ (TOXI_PROXY_NAME="$proxyname" "$_arg_command" "'' ${_arg_leftovers[@]}")
423+ '' ;
424+
425+ withToxiproxyPgProxy =
426+ checkedShellScript
427+ {
428+ name = "postgrest-with-toxiproxy-pg-proxy" ;
429+ docs = "Run <command> with a Toxiproxy proxy to PosgreSQL." ;
430+ args =
431+ [
432+ "ARG_POSITIONAL_SINGLE([command], [Command to run])"
433+ "ARG_LEFTOVERS([command arguments])"
434+ "ARG_USE_ENV([TCP_PGHOST], [], [PG host name])"
435+ "ARG_USE_ENV([PGPORT], [], [PG port])"
436+ ] ;
437+ positionalCompletion = "_command" ;
438+ workingDir = "/" ;
439+ }
440+ ''
441+ proxy_port='' $(${ randomPort } )
442+
443+ ${ withToxiproxyServer } ${ withToxiproxyProxy } -l "$TCP_PGHOST:$proxy_port" -u "$TCP_PGHOST:$PGPORT" \
444+ env "TOXI_PGPORT=$proxy_port" "$_arg_command" "'' ${_arg_leftovers[@]}"
445+ '' ;
446+
447+ withToxiproxyServer =
448+ checkedShellScript
449+ {
450+ name = "postgrest-with-toxiproxy-server" ;
451+ docs = "Run <command> with toxiproxy-server" ;
452+ args =
453+ [
454+ "ARG_POSITIONAL_SINGLE([command], [Command to run])"
455+ "ARG_LEFTOVERS([command arguments])"
456+ ] ;
457+ positionalCompletion = "_command" ;
458+ workingDir = "/" ;
459+ withPath = [ toxiproxy ] ;
460+ }
461+ ''
462+ if ! test -v TOXI_PROXY; then
463+ export TOXI_PROXY=""
464+ LOG_LEVEL=error toxiproxy-server&
465+ TOXIPROXY_PID=$!
466+ sleep 1 # give the server a moment to start
467+
468+ # shellcheck disable=SC2317
469+ # shellcheck disable=SC2329
470+ stop () {
471+ kill "$TOXIPROXY_PID" || true
472+ wait "$TOXIPROXY_PID" || true
473+ }
474+ trap stop EXIT
475+ fi
476+ ("$_arg_command" "'' ${_arg_leftovers[@]}")
477+ '' ;
478+
374479in
375480buildToolbox
376481{
@@ -385,5 +490,5 @@ buildToolbox
385490 builtins . map ( pg : { inherit ( pg ) name ; value = withTmpDb pg ; } ) postgresqlVersions
386491 ) ;
387492 # make latest withPg available for other nix files
388- extra = { inherit withPg ; } ;
493+ extra = { inherit withPg withToxiproxyPgProxy ; } ;
389494}
0 commit comments