From a99e035659157dc2ad3fb4a23f2cfa4b497b9335 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 02:15:38 +0200 Subject: [PATCH 01/48] pgaftest-infra: new test DSL, binary split, inspect/override commands Add pgaftest binary and .pgaf test spec infrastructure: - src/bin/common/Makefile.common: shared build variables included by both pg_autoctl and pgaftest Makefiles - src/bin/pgaftest/: new binary for CI testing and interactive cluster prep (not shipped on production nodes) - Flex/Bison DSL parser (test_spec_scan.l, test_spec_parse.y) - AST structs (test_spec.h) - Docker Compose generator (compose_gen.c) - TAP test runner (test_runner.c): CI mode (pgaftest run) and interactive mode (pgaftest setup) - CLI dispatch (cli_root.c): run/setup/step/show/down/demo - pg_autoctl inspect: always-visible read-only diagnostics grouping do_show, do_pgsetup, do_monitor, do_service commands - pg_autoctl override: always-visible manual FSM operations grouping do_fsm, do_primary, do_standby, do_coordinator, do_service commands (intended for manual recovery, not normal automation) - PG_AUTOCTL_DEBUG no longer gates command visibility; inspect and override are always shown in --help output - Azure integration removed from cli_do_root.c and cli_do_root.h (unmaintained; no replacement in pgaftest) - tests/tap/specs/: 27 .pgaf spec files porting all Python tests - tests/tap/schedule: ordered test schedule for pgaftest run --- src/bin/Makefile | 11 +- src/bin/common/Makefile.common | 88 +++ src/bin/pg_autoctl/Makefile | 91 +-- src/bin/pg_autoctl/cli_do_root.c | 11 +- src/bin/pg_autoctl/cli_do_root.h | 18 +- src/bin/pg_autoctl/cli_inspect.c | 39 + src/bin/pg_autoctl/cli_inspect.h | 16 + src/bin/pg_autoctl/cli_override.c | 37 + src/bin/pg_autoctl/cli_override.h | 16 + src/bin/pg_autoctl/cli_root.c | 31 +- src/bin/pgaftest/Makefile | 76 ++ src/bin/pgaftest/cli_demo.c | 66 ++ src/bin/pgaftest/cli_demo.h | 16 + src/bin/pgaftest/cli_root.c | 358 ++++++++++ src/bin/pgaftest/compose_gen.c | 135 ++++ src/bin/pgaftest/compose_gen.h | 34 + src/bin/pgaftest/main.c | 31 + src/bin/pgaftest/test_runner.c | 668 ++++++++++++++++++ src/bin/pgaftest/test_runner.h | 66 ++ src/bin/pgaftest/test_spec.h | 117 +++ src/bin/pgaftest/test_spec_parse.y | 417 +++++++++++ src/bin/pgaftest/test_spec_scan.l | 130 ++++ tests/tap/schedule | 33 + tests/tap/specs/auth.pgaf | 65 ++ tests/tap/specs/basic_citus_operation.pgaf | 183 +++++ tests/tap/specs/basic_operation.pgaf | 146 ++++ .../specs/basic_operation_listen_flag.pgaf | 106 +++ tests/tap/specs/citus_cluster_name.pgaf | 85 +++ tests/tap/specs/citus_force_failover.pgaf | 85 +++ tests/tap/specs/citus_multi_standbys.pgaf | 175 +++++ tests/tap/specs/citus_skip_pg_hba.pgaf | 99 +++ tests/tap/specs/config_get_set.pgaf | 51 ++ tests/tap/specs/create_run.pgaf | 84 +++ .../tap/specs/create_standby_with_pgdata.pgaf | 59 ++ tests/tap/specs/debian_clusters.pgaf | 44 ++ tests/tap/specs/enable_ssl.pgaf | 139 ++++ tests/tap/specs/ensure.pgaf | 69 ++ tests/tap/specs/extension_update.pgaf | 29 + tests/tap/specs/installcheck.pgaf | 31 + tests/tap/specs/monitor_disabled.pgaf | 114 +++ tests/tap/specs/multi_alternate.pgaf | 166 +++++ tests/tap/specs/multi_async.pgaf | 289 ++++++++ tests/tap/specs/multi_ifdown.pgaf | 166 +++++ tests/tap/specs/multi_maintenance.pgaf | 286 ++++++++ tests/tap/specs/multi_standbys.pgaf | 306 ++++++++ tests/tap/specs/nonha_citus_operation.pgaf | 111 +++ tests/tap/specs/replace_monitor.pgaf | 105 +++ tests/tap/specs/skip_pg_hba.pgaf | 64 ++ tests/tap/specs/ssl_cert.pgaf | 69 ++ tests/tap/specs/ssl_self_signed.pgaf | 68 ++ 50 files changed, 5581 insertions(+), 118 deletions(-) create mode 100644 src/bin/common/Makefile.common create mode 100644 src/bin/pg_autoctl/cli_inspect.c create mode 100644 src/bin/pg_autoctl/cli_inspect.h create mode 100644 src/bin/pg_autoctl/cli_override.c create mode 100644 src/bin/pg_autoctl/cli_override.h create mode 100644 src/bin/pgaftest/Makefile create mode 100644 src/bin/pgaftest/cli_demo.c create mode 100644 src/bin/pgaftest/cli_demo.h create mode 100644 src/bin/pgaftest/cli_root.c create mode 100644 src/bin/pgaftest/compose_gen.c create mode 100644 src/bin/pgaftest/compose_gen.h create mode 100644 src/bin/pgaftest/main.c create mode 100644 src/bin/pgaftest/test_runner.c create mode 100644 src/bin/pgaftest/test_runner.h create mode 100644 src/bin/pgaftest/test_spec.h create mode 100644 src/bin/pgaftest/test_spec_parse.y create mode 100644 src/bin/pgaftest/test_spec_scan.l create mode 100644 tests/tap/schedule create mode 100644 tests/tap/specs/auth.pgaf create mode 100644 tests/tap/specs/basic_citus_operation.pgaf create mode 100644 tests/tap/specs/basic_operation.pgaf create mode 100644 tests/tap/specs/basic_operation_listen_flag.pgaf create mode 100644 tests/tap/specs/citus_cluster_name.pgaf create mode 100644 tests/tap/specs/citus_force_failover.pgaf create mode 100644 tests/tap/specs/citus_multi_standbys.pgaf create mode 100644 tests/tap/specs/citus_skip_pg_hba.pgaf create mode 100644 tests/tap/specs/config_get_set.pgaf create mode 100644 tests/tap/specs/create_run.pgaf create mode 100644 tests/tap/specs/create_standby_with_pgdata.pgaf create mode 100644 tests/tap/specs/debian_clusters.pgaf create mode 100644 tests/tap/specs/enable_ssl.pgaf create mode 100644 tests/tap/specs/ensure.pgaf create mode 100644 tests/tap/specs/extension_update.pgaf create mode 100644 tests/tap/specs/installcheck.pgaf create mode 100644 tests/tap/specs/monitor_disabled.pgaf create mode 100644 tests/tap/specs/multi_alternate.pgaf create mode 100644 tests/tap/specs/multi_async.pgaf create mode 100644 tests/tap/specs/multi_ifdown.pgaf create mode 100644 tests/tap/specs/multi_maintenance.pgaf create mode 100644 tests/tap/specs/multi_standbys.pgaf create mode 100644 tests/tap/specs/nonha_citus_operation.pgaf create mode 100644 tests/tap/specs/replace_monitor.pgaf create mode 100644 tests/tap/specs/skip_pg_hba.pgaf create mode 100644 tests/tap/specs/ssl_cert.pgaf create mode 100644 tests/tap/specs/ssl_self_signed.pgaf diff --git a/src/bin/Makefile b/src/bin/Makefile index 7c743833d..3444bc1ad 100644 --- a/src/bin/Makefile +++ b/src/bin/Makefile @@ -1,15 +1,20 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the PostgreSQL License. -all: pg_autoctl ; +all: pg_autoctl pgaftest ; pg_autoctl: $(MAKE) -C pg_autoctl pg_autoctl +pgaftest: + $(MAKE) -C pgaftest pgaftest + clean: $(MAKE) -C pg_autoctl clean + $(MAKE) -C pgaftest clean -install: $(pg_autoctl) +install: pg_autoctl pgaftest $(MAKE) -C pg_autoctl install + $(MAKE) -C pgaftest install -.PHONY: all pg_autoctl install clean +.PHONY: all pg_autoctl pgaftest install clean diff --git a/src/bin/common/Makefile.common b/src/bin/common/Makefile.common new file mode 100644 index 000000000..1167d5b85 --- /dev/null +++ b/src/bin/common/Makefile.common @@ -0,0 +1,88 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the PostgreSQL License. +# +# Makefile.common — shared build variables included by both pg_autoctl and +# pgaftest Makefiles via: include ../common/Makefile.common + +PG_CONFIG ?= pg_config + +COMMON_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +LIB_DIR := $(COMMON_DIR)../lib + +PG_SNPRINTF = $(wildcard $(LIB_DIR)/pg/snprintf.*) +LOG_SRC = $(wildcard $(LIB_DIR)/log/src/log.*) +COMMANDLINE_SRC = $(wildcard $(LIB_DIR)/subcommands.c/commandline.*) +PARSON_SRC = $(wildcard $(LIB_DIR)/parson/parson.*) + +COMMON_INCLUDES = -I$(LIB_DIR)/pg +COMMON_INCLUDES += -I$(LIB_DIR)/log/src/ +COMMON_INCLUDES += -I$(LIB_DIR)/subcommands.c/ +COMMON_INCLUDES += -I$(LIB_DIR)/libs/ +COMMON_INCLUDES += -I$(LIB_DIR)/parson/ + +CC = $(shell $(PG_CONFIG) --cc) + +DEFAULT_CFLAGS = -std=c99 -D_GNU_SOURCE -g +DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --includedir) +DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --includedir-server) +DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --pkgincludedir)/internal +DEFAULT_CFLAGS += $(shell $(PG_CONFIG) --cflags) +DEFAULT_CFLAGS += -Wformat +DEFAULT_CFLAGS += -Wall +DEFAULT_CFLAGS += -Werror=implicit-int +DEFAULT_CFLAGS += -Werror=implicit-function-declaration +DEFAULT_CFLAGS += -Werror=return-type +DEFAULT_CFLAGS += -Wno-declaration-after-statement +DEFAULT_CFLAGS += -D_WANT_SEMUN +DEFAULT_CFLAGS += -Wno-missing-braces +DEFAULT_CFLAGS += $(COMMON_INCLUDES) + +ifdef USE_SECURITY_FLAGS +SECURITY_CFLAGS = -fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2 \ + -z noexecstack -fpie -Wl,-pie -Wl,-z,relro -Wl,-z,now \ + -Wformat -Wformat-security -Werror=format-security +DEFAULT_CFLAGS += $(SECURITY_CFLAGS) +endif + +override CFLAGS := $(DEFAULT_CFLAGS) $(CFLAGS) + +BINDIR ?= $(shell $(PG_CONFIG) --bindir) + +LIBS = -L $(shell $(PG_CONFIG) --pkglibdir) +LIBS += -L $(shell $(PG_CONFIG) --libdir) +LIBS += $(shell $(PG_CONFIG) --ldflags) +LIBS += $(shell $(PG_CONFIG) --libs) +LIBS += -lpq + +DEPDIR = .deps + +# Shared rule: compile .c → .o with auto-dependency tracking +%.o : %.c + @if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi + $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/$(*F).Po -o $@ $< + +Po_files := $(wildcard $(DEPDIR)/*.Po) +ifneq (,$(Po_files)) +include $(Po_files) +endif + +# Shared rules for vendored libs (callers reference with explicit target names) +lib-snprintf.o: $(PG_SNPRINTF) + $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/lib-snprintf.Po -MT$@ \ + -o $@ $(LIB_DIR)/pg/snprintf.c + +lib-strerror.o: $(PG_SNPRINTF) + $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/lib-strerror.Po -MT$@ \ + -o $@ $(LIB_DIR)/pg/strerror.c + +lib-log.o: $(LOG_SRC) + $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/lib-log.Po -MT$@ \ + -o $@ $(LIB_DIR)/log/src/log.c + +lib-commandline.o: $(COMMANDLINE_SRC) + $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/lib-commandline.Po -MT$@ \ + -o $@ $(LIB_DIR)/subcommands.c/commandline.c + +lib-parson.o: $(PARSON_SRC) + $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/lib-parson.Po -MT$@ \ + -o $@ $(LIB_DIR)/parson/parson.c diff --git a/src/bin/pg_autoctl/Makefile b/src/bin/pg_autoctl/Makefile index f1d884db1..1243fb101 100644 --- a/src/bin/pg_autoctl/Makefile +++ b/src/bin/pg_autoctl/Makefile @@ -5,96 +5,25 @@ PG_AUTOCTL = ./pg_autoctl SRC_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) -DEPDIR = $(SRC_DIR)/.deps +include $(SRC_DIR)../common/Makefile.common -INCLUDES = $(patsubst ${SRC_DIR}%.h,%.h,$(wildcard ${SRC_DIR}*.h)) +# pg_autoctl includes its own source directory too +override CFLAGS += -I$(SRC_DIR) -SRC = $(patsubst ${SRC_DIR}%.c,%.c,$(wildcard ${SRC_DIR}*.c)) -OBJS = $(patsubst %.c,%.o,$(SRC)) -OBJS += lib-log.o lib-commandline.o lib-parson.o lib-snprintf.o lib-strerror.o - -PG_CONFIG ?= pg_config -BINDIR ?= $(shell $(PG_CONFIG) --bindir) - -PG_SNPRINTF = $(wildcard ${SRC_DIR}../lib/pg/snprintf.*) -LOG_SRC = $(wildcard ${SRC_DIR}../lib/log/src/log.*) -COMMANDLINE_SRC = $(wildcard ${SRC_DIR}../lib/subcommands.c/commandline.*) -PARSON_SRC = $(wildcard ${SRC_DIR}../lib/parson/parson.*) - -COMMON_LIBS = -I${SRC_DIR}../lib/pg -COMMON_LIBS += -I${SRC_DIR}../lib/log/src/ -COMMON_LIBS += -I${SRC_DIR}../lib/subcommands.c/ -COMMON_LIBS += -I${SRC_DIR}../lib/libs/ -COMMON_LIBS += -I${SRC_DIR}../lib/parson/ - -CC = $(shell $(PG_CONFIG) --cc) +INCLUDES = $(patsubst $(SRC_DIR)%.h,%.h,$(wildcard $(SRC_DIR)*.h)) -DEFAULT_CFLAGS = -std=c99 -D_GNU_SOURCE -g -DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --includedir) -DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --includedir-server) -DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --pkgincludedir)/internal -DEFAULT_CFLAGS += $(shell $(PG_CONFIG) --cflags) -DEFAULT_CFLAGS += -Wformat -DEFAULT_CFLAGS += -Wall -DEFAULT_CFLAGS += -Werror=implicit-int -DEFAULT_CFLAGS += -Werror=implicit-function-declaration -DEFAULT_CFLAGS += -Werror=return-type -DEFAULT_CFLAGS += -Wno-declaration-after-statement - -# Needed for FreeBSD -DEFAULT_CFLAGS += -D_WANT_SEMUN - -# Needed for OSX -DEFAULT_CFLAGS += -Wno-missing-braces -DEFAULT_CFLAGS += $(COMMON_LIBS) - -ifdef USE_SECURITY_FLAGS -# Flags taken from: https://liquid.microsoft.com/Web/Object/Read/ms.security/Requirements/Microsoft.Security.SystemsADM.10203#guide -SECURITY_CFLAGS=-fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2 -z noexecstack -fpie -Wl,-pie -Wl,-z,relro -Wl,-z,now -Wformat -Wformat-security -Werror=format-security -DEFAULT_CFLAGS += $(SECURITY_CFLAGS) -endif - -override CFLAGS := $(DEFAULT_CFLAGS) $(CFLAGS) +SRC = $(patsubst $(SRC_DIR)%.c,%.c,$(wildcard $(SRC_DIR)*.c)) +OBJS = $(patsubst %.c,%.o,$(SRC)) +OBJS += lib-log.o lib-commandline.o lib-parson.o lib-snprintf.o lib-strerror.o -LIBS = -L $(shell $(PG_CONFIG) --pkglibdir) -LIBS += -L $(shell $(PG_CONFIG) --libdir) -LIBS += $(shell $(PG_CONFIG) --ldflags) -LIBS += $(shell $(PG_CONFIG) --libs) -LIBS += -lpq +# ncurses needed for pg_autoctl watch LIBS += -lncurses all: $(PG_AUTOCTL) ; -# Based on Postgres Makefile for automatic dependency generation -# https://github.com/postgres/postgres/blob/1933ae629e7b706c6c23673a381e778819db307d/src/Makefile.global.in#L890-L924 -%.o : %.c - @if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi - $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/$(*F).Po -o $@ $< - -Po_files := $(wildcard $(DEPDIR)/*.Po) -ifneq (,$(Po_files)) -include $(Po_files) -endif - - $(PG_AUTOCTL): $(OBJS) $(INCLUDES) $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ -lib-snprintf.o: $(PG_SNPRINTF) - $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/$(*F).Po -MT$@ -o $@ ${SRC_DIR}../lib/pg/snprintf.c - -lib-strerror.o: $(PG_SNPRINTF) - $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/$(*F).Po -MT$@ -o $@ ${SRC_DIR}../lib/pg/strerror.c - -lib-log.o: $(LOG_SRC) - $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/$(*F).Po -MT$@ -o $@ ${SRC_DIR}../lib/log/src/log.c - -lib-commandline.o: $(COMMANDLINE_SRC) - $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/$(*F).Po -MT$@ -o $@ ${SRC_DIR}../lib/subcommands.c/commandline.c - -lib-parson.o: $(PARSON_SRC) - $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/$(*F).Po -MT$@ -o $@ ${SRC_DIR}../lib/parson/parson.c - clean: rm -f $(OBJS) $(PG_AUTOCTL) rm -rf $(DEPDIR) @@ -103,6 +32,4 @@ install: $(PG_AUTOCTL) install -d $(DESTDIR)$(BINDIR) install -m 0755 $(PG_AUTOCTL) $(DESTDIR)$(BINDIR) - - -.PHONY: all monitor clean +.PHONY: all clean install diff --git a/src/bin/pg_autoctl/cli_do_root.c b/src/bin/pg_autoctl/cli_do_root.c index dacf9792e..4cdff4e58 100644 --- a/src/bin/pg_autoctl/cli_do_root.c +++ b/src/bin/pg_autoctl/cli_do_root.c @@ -375,11 +375,12 @@ CommandLine do_tmux_commands = NULL, NULL, NULL, do_tmux); /* - * pg_autoctl do azure ... - * - * Set of commands to prepare and control a full QA environment running in - * Azure VMs, provisionned either from our packages or from local source code. + * Azure integration has been removed. The commands that were here are no + * longer maintained and have been deleted from this file. See pgaftest for + * the replacement QA tooling. */ + +#if 0 /* REMOVED: azure commands — see pgaftest instead */ CommandLine do_azure_provision_region = make_command("region", "Provision an azure region: resource group, network, VMs", @@ -564,6 +565,7 @@ CommandLine do_azure_commands = "Manage a set of Azure resources for a pg_auto_failover demo", NULL, NULL, NULL, do_azure); +#endif /* REMOVED: azure commands */ CommandLine *do_subcommands[] = { &do_monitor_commands, @@ -576,7 +578,6 @@ CommandLine *do_subcommands[] = { &do_service_postgres_ctl_commands, &do_service_commands, &do_tmux_commands, - &do_azure_commands, &do_demo_commands, NULL }; diff --git a/src/bin/pg_autoctl/cli_do_root.h b/src/bin/pg_autoctl/cli_do_root.h index efb482eaa..5db1cf347 100644 --- a/src/bin/pg_autoctl/cli_do_root.h +++ b/src/bin/pg_autoctl/cli_do_root.h @@ -71,9 +71,6 @@ extern CommandLine do_tmux_commands; /* src/bin/pg_autoctl/cli_do_coordinator.c */ extern CommandLine do_coordinator_commands; -/* src/bin/pg_autoctl/cli_do_azure.c */ -extern CommandLine do_azure_ssh; - extern CommandLine do_commands; extern CommandLine *do_subcommands[]; @@ -117,19 +114,6 @@ void cli_do_tmux_compose_config(int argc, char **argv); void cli_do_tmux_compose_script(int argc, char **argv); void cli_do_tmux_compose_session(int argc, char **argv); -/* src/bin/pg_autoctl/cli_do_azure.c */ -int cli_do_azure_getopts(int argc, char **argv); -void cli_do_azure_create_environment(int argc, char **argv); -void cli_do_azure_create_region(int argc, char **argv); -void cli_do_azure_drop_region(int argc, char **argv); -void cli_do_azure_deploy(int argc, char **argv); -void cli_do_azure_create_nodes(int argc, char **argv); -void cli_do_azure_ls(int argc, char **argv); -void cli_do_azure_show_ips(int argc, char **argv); -void cli_do_azure_ssh(int argc, char **argv); -void cli_do_azure_rsync(int argc, char **argv); -void cli_do_azure_show_state(int argc, char **argv); -void cli_do_azure_tmux_session(int argc, char **argv); -void cli_do_azure_tmux_kill(int argc, char **argv); +/* Azure integration removed — use pgaftest instead */ #endif /* CLI_DO_ROOT_H */ diff --git a/src/bin/pg_autoctl/cli_inspect.c b/src/bin/pg_autoctl/cli_inspect.c new file mode 100644 index 000000000..e18eae6c7 --- /dev/null +++ b/src/bin/pg_autoctl/cli_inspect.c @@ -0,0 +1,39 @@ +/* + * src/bin/pg_autoctl/cli_inspect.c + * pg_autoctl inspect — read-only diagnostics, always visible. + * + * These commands read local or cluster state without mutating anything. + * Safe to run at any time, even while `pg_autoctl run` is active. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include "commandline.h" +#include "cli_inspect.h" +#include "cli_do_root.h" + +/* + * Aggregate the read-only do_* command sets under a single "inspect" group. + * We reference the existing command sets by address — do_show_commands, + * do_pgsetup_commands, etc. are extern CommandLine objects already declared + * in cli_do_root.h. + */ + +static CommandLine *inspect_subcommands[] = { + &do_show_commands, /* ipaddr / cidr / lookup / hostname / reverse */ + &do_pgsetup_commands, /* discover / ready / wait / logs / tune / pg_ctl */ + &do_monitor_commands, /* get primary|others / version / register / active */ + &do_service_commands, /* getpid postgres|listener|node-active */ + NULL +}; + +CommandLine inspect_commands = + make_command_set("inspect", + "Read-only diagnostics (safe on live nodes)", + "[sub-command]", + " show Networking and hostname diagnostics\n" + " pgsetup Local PostgreSQL setup inspection\n" + " monitor Query the monitor's current state\n" + " service Get PIDs of pg_autoctl sub-processes\n", + NULL, inspect_subcommands); diff --git a/src/bin/pg_autoctl/cli_inspect.h b/src/bin/pg_autoctl/cli_inspect.h new file mode 100644 index 000000000..b9c87d68e --- /dev/null +++ b/src/bin/pg_autoctl/cli_inspect.h @@ -0,0 +1,16 @@ +/* + * src/bin/pg_autoctl/cli_inspect.h + * pg_autoctl inspect — read-only diagnostics. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#ifndef CLI_INSPECT_H +#define CLI_INSPECT_H + +#include "commandline.h" + +extern CommandLine inspect_commands; + +#endif /* CLI_INSPECT_H */ diff --git a/src/bin/pg_autoctl/cli_override.c b/src/bin/pg_autoctl/cli_override.c new file mode 100644 index 000000000..08f059e39 --- /dev/null +++ b/src/bin/pg_autoctl/cli_override.c @@ -0,0 +1,37 @@ +/* + * src/bin/pg_autoctl/cli_override.c + * pg_autoctl override — manual FSM operations and low-level controls. + * + * These commands force individual FSM transitions or low-level operations + * that the FSM would normally own. Intended for manual recovery when the + * automated FSM is stopped or stuck. Named "override" to make clear that + * these bypass normal automation. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include "commandline.h" +#include "cli_override.h" +#include "cli_do_root.h" + +static CommandLine *override_subcommands[] = { + &do_fsm_commands, /* state/list/gv/assign/step/nodes */ + &do_service_postgres_ctl_commands, /* restart postgres|listener|node-active */ + &do_service_commands, /* pgcontroller / postgres / listener / node-active */ + &do_primary_, /* slot / adduser / defaults / identify */ + &do_standby_, /* init / rewind / crash-recovery / promote */ + &do_coordinator_commands, /* add / activate / remove / update */ + NULL +}; + +CommandLine override_commands = + make_command_set("override", + "Manual FSM operations — bypasses normal automation", + "[sub-command]", + " fsm Inspect / manually step the keeper FSM\n" + " service Restart or run individual sub-processes\n" + " primary Manual primary-side operations\n" + " standby Manual standby-side operations\n" + " coordinator Citus coordinator operations\n", + NULL, override_subcommands); diff --git a/src/bin/pg_autoctl/cli_override.h b/src/bin/pg_autoctl/cli_override.h new file mode 100644 index 000000000..15bd78d5b --- /dev/null +++ b/src/bin/pg_autoctl/cli_override.h @@ -0,0 +1,16 @@ +/* + * src/bin/pg_autoctl/cli_override.h + * pg_autoctl override — manual FSM operations. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#ifndef CLI_OVERRIDE_H +#define CLI_OVERRIDE_H + +#include "commandline.h" + +extern CommandLine override_commands; + +#endif /* CLI_OVERRIDE_H */ diff --git a/src/bin/pg_autoctl/cli_root.c b/src/bin/pg_autoctl/cli_root.c index 386716b98..b2dad7383 100644 --- a/src/bin/pg_autoctl/cli_root.c +++ b/src/bin/pg_autoctl/cli_root.c @@ -9,6 +9,8 @@ */ #include "cli_common.h" +#include "cli_inspect.h" +#include "cli_override.h" #include "cli_root.h" #include "commandline.h" @@ -81,19 +83,23 @@ CommandLine drop_commands = NULL, drop_subcommands); /* - * Binding them all into the top-level command: + * Single root command table — inspect and override are always visible. + * The PG_AUTOCTL_DEBUG env var now only controls log verbosity, not + * command visibility. */ -CommandLine *root_subcommands_with_debug[] = { +CommandLine *root_subcommands[] = { &create_commands, &drop_commands, &config_commands, - &show_commands_with_debug, + &show_commands, &enable_commands, &disable_commands, &get_commands, &set_commands, &perform_commands, - &do_commands, + &activate_node_command, + &inspect_commands, + &override_commands, &service_run_command, &watch_command, &service_stop_command, @@ -104,14 +110,15 @@ CommandLine *root_subcommands_with_debug[] = { NULL }; -CommandLine root_with_debug = +CommandLine root = make_command_set("pg_autoctl", "pg_auto_failover control tools and service", - "[ --debug|verbose|quiet ]", NULL, - root_options, root_subcommands_with_debug); - + "[ --verbose --quiet ]", NULL, + root_options, root_subcommands); -CommandLine *root_subcommands[] = { +/* Backward-compat alias: root_with_debug and root_subcommands_with_debug + * previously held the do_commands. They now point to the same root. */ +CommandLine *root_subcommands_with_debug[] = { &create_commands, &drop_commands, &config_commands, @@ -122,6 +129,8 @@ CommandLine *root_subcommands[] = { &set_commands, &perform_commands, &activate_node_command, + &inspect_commands, + &override_commands, &service_run_command, &watch_command, &service_stop_command, @@ -132,11 +141,11 @@ CommandLine *root_subcommands[] = { NULL }; -CommandLine root = +CommandLine root_with_debug = make_command_set("pg_autoctl", "pg_auto_failover control tools and service", "[ --verbose --quiet ]", NULL, - root_options, root_subcommands); + root_options, root_subcommands_with_debug); /* diff --git a/src/bin/pgaftest/Makefile b/src/bin/pgaftest/Makefile new file mode 100644 index 000000000..0d6e1f9e1 --- /dev/null +++ b/src/bin/pgaftest/Makefile @@ -0,0 +1,76 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the PostgreSQL License. + +PGAFTEST = ./pgaftest + +SRC_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +PGACTL_DIR := $(SRC_DIR)../pg_autoctl/ + +include $(SRC_DIR)../common/Makefile.common + +# Include both our own dir and pg_autoctl for shared headers +override CFLAGS += -I$(SRC_DIR) -I$(PGACTL_DIR) + +# ----------------------------------------------------------------------- +# Sources that live in this directory +# ----------------------------------------------------------------------- +LOCAL_SRC = main.c cli_root.c cli_demo.c \ + compose_gen.c test_runner.c \ + test_spec_scan.c test_spec_parse.c + +LOCAL_OBJS = $(patsubst %.c,%.o,$(LOCAL_SRC)) + +# ----------------------------------------------------------------------- +# Shared sources compiled from pg_autoctl/ by explicit path +# ----------------------------------------------------------------------- +SHARED_SRCS = env_utils.c file_utils.c string_utils.c parsing.c \ + nodestate_utils.c ipaddr.c signals.c pidfile.c \ + pgsetup.c pgsql.c lock_utils.c ini_file.c ini_implementation.c \ + debian.c + +SHARED_OBJS = $(patsubst %.c,shared-%.o,$(SHARED_SRCS)) + +OBJS = $(LOCAL_OBJS) $(SHARED_OBJS) +OBJS += lib-log.o lib-commandline.o lib-parson.o lib-snprintf.o lib-strerror.o + +INCLUDES = $(wildcard $(SRC_DIR)*.h) + +# ----------------------------------------------------------------------- +# Flex / Bison +# ----------------------------------------------------------------------- +FLEX = flex +BISON = bison + +test_spec_scan.c: test_spec_scan.l test_spec_parse.h + $(FLEX) -o $@ $< + +test_spec_parse.c test_spec_parse.h: test_spec_parse.y + $(BISON) -d -o test_spec_parse.c $< + +# ----------------------------------------------------------------------- +# Rules for shared objects (compiled from pg_autoctl/ sources) +# ----------------------------------------------------------------------- +shared-%.o: $(PGACTL_DIR)%.c + @if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi + $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/shared-$(*F).Po -o $@ $< + +Po_files := $(wildcard $(DEPDIR)/*.Po) +ifneq (,$(Po_files)) +include $(Po_files) +endif + +# ----------------------------------------------------------------------- +all: $(PGAFTEST) ; + +$(PGAFTEST): $(OBJS) $(INCLUDES) + $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ + +clean: + rm -f $(OBJS) $(PGAFTEST) test_spec_scan.c test_spec_parse.c test_spec_parse.h + rm -rf $(DEPDIR) + +install: $(PGAFTEST) + install -d $(DESTDIR)$(BINDIR) + install -m 0755 $(PGAFTEST) $(DESTDIR)$(BINDIR) + +.PHONY: all clean install diff --git a/src/bin/pgaftest/cli_demo.c b/src/bin/pgaftest/cli_demo.c new file mode 100644 index 000000000..0ff66a8b9 --- /dev/null +++ b/src/bin/pgaftest/cli_demo.c @@ -0,0 +1,66 @@ +/* + * src/bin/pgaftest/cli_demo.c + * Demo application sub-command for pgaftest (moved from pg_autoctl do demo). + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include "commandline.h" +#include "cli_demo.h" +#include "log.h" + +/* + * The demo sub-commands forward to pg_autoctl's demoapp implementation. + * For now we provide a stub that guides the user; the full implementation + * is linked from the shared pg_autoctl sources. + */ + +static void +cli_demo_run(int argc, char **argv) +{ + log_error("pgaftest demo run: not yet implemented in this build."); + log_info("Use: docker compose exec pg_autoctl do demo run ..."); +} + +static void +cli_demo_uri(int argc, char **argv) +{ + log_error("pgaftest demo uri: not yet implemented in this build."); +} + +static void +cli_demo_ping(int argc, char **argv) +{ + log_error("pgaftest demo ping: not yet implemented in this build."); +} + +static void +cli_demo_summary(int argc, char **argv) +{ + log_error("pgaftest demo summary: not yet implemented in this build."); +} + +static CommandLine demo_run = + make_command("run", "Run the demo app", "", "", NULL, cli_demo_run); +static CommandLine demo_uri = + make_command("uri", "Show app URI", "", "", NULL, cli_demo_uri); +static CommandLine demo_ping = + make_command("ping", "Ping the app URI", "", "", NULL, cli_demo_ping); +static CommandLine demo_summary = + make_command("summary", "Show demo summary", "", "", NULL, cli_demo_summary); + +static CommandLine *demo_subcommands[] = { + &demo_run, + &demo_uri, + &demo_ping, + &demo_summary, + NULL +}; + +CommandLine pgaftest_demo_command = + make_command_set("demo", + "Demo application for pg_auto_failover", + "", "", + NULL, demo_subcommands); diff --git a/src/bin/pgaftest/cli_demo.h b/src/bin/pgaftest/cli_demo.h new file mode 100644 index 000000000..8c11bc470 --- /dev/null +++ b/src/bin/pgaftest/cli_demo.h @@ -0,0 +1,16 @@ +/* + * src/bin/pgaftest/cli_demo.h + * Demo application CLI (moved from pg_autoctl do demo). + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#ifndef CLI_DEMO_H +#define CLI_DEMO_H + +#include "commandline.h" + +extern CommandLine pgaftest_demo_command; + +#endif /* CLI_DEMO_H */ diff --git a/src/bin/pgaftest/cli_root.c b/src/bin/pgaftest/cli_root.c new file mode 100644 index 000000000..97c12c5dc --- /dev/null +++ b/src/bin/pgaftest/cli_root.c @@ -0,0 +1,358 @@ +/* + * src/bin/pgaftest/cli_root.c + * Top-level sub-command table for pgaftest. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include +#include +#include +#include + +#include "commandline.h" +#include "log.h" +#include "test_spec.h" +#include "test_runner.h" +#include "cli_demo.h" + +/* Default work directory when --work-dir is not specified */ +#define DEFAULT_WORK_DIR "/tmp/pgaftest" + +/* ----------------------------------------------------------------------- + * Shared option parsing + * ----------------------------------------------------------------------- */ + +typedef struct PgaftestOpts +{ + char specFile[1024]; + char workDir[1024]; + char stepName[64]; + char schedule[1024]; + char expected[1024]; + bool withTmux; + int verbose; +} PgaftestOpts; + +static PgaftestOpts pgaftestOpts = { + .workDir = DEFAULT_WORK_DIR +}; + +static struct option long_options[] = { + { "work-dir", required_argument, NULL, 'w' }, + { "schedule", required_argument, NULL, 'S' }, + { "expected", required_argument, NULL, 'E' }, + { "tmux", no_argument, NULL, 't' }, + { "verbose", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 'h' }, + { NULL, 0, NULL, 0 } +}; + +static int +pgaftest_getopts(int argc, char **argv) +{ + int c, option_index = 0; + + while ((c = getopt_long(argc, argv, "w:S:E:tvh", + long_options, &option_index)) != -1) + { + switch (c) + { + case 'w': + strncpy(pgaftestOpts.workDir, optarg, + sizeof(pgaftestOpts.workDir)-1); + break; + case 'S': + strncpy(pgaftestOpts.schedule, optarg, + sizeof(pgaftestOpts.schedule)-1); + break; + case 'E': + strncpy(pgaftestOpts.expected, optarg, + sizeof(pgaftestOpts.expected)-1); + break; + case 't': + pgaftestOpts.withTmux = true; + break; + case 'v': + pgaftestOpts.verbose++; + log_set_level(LOG_DEBUG); + break; + case 'h': + commandline_help(stderr); + exit(EXIT_CODE_QUIT); + default: + break; + } + } + return optind; +} + +/* ----------------------------------------------------------------------- + * pgaftest run + * ----------------------------------------------------------------------- */ + +static void +cli_run(int argc, char **argv) +{ + int optind = pgaftest_getopts(argc, argv); + + /* Handle --schedule file */ + if (pgaftestOpts.schedule[0] != '\0') + { + FILE *f = fopen(pgaftestOpts.schedule, "r"); + if (!f) + { + log_error("Cannot open schedule \"%s\": %m", + pgaftestOpts.schedule); + exit(1); + } + + char line[256]; + int total = 0, failed = 0; + + while (fgets(line, sizeof(line), f)) + { + /* strip newline and comments */ + char *nl = strchr(line, '\n'); + if (nl) *nl = '\0'; + char *hash = strchr(line, '#'); + if (hash) *hash = '\0'; + + /* skip blank lines */ + char *p = line; + while (*p == ' ' || *p == '\t') p++; + if (*p == '\0') continue; + + /* build spec path from schedule entry */ + char specPath[1024]; + if (strchr(p, '/')) + strncpy(specPath, p, sizeof(specPath)-1); + else + snprintf(specPath, sizeof(specPath), + "tests/tap/specs/%s.pgaf", p); + + char workDir[1024]; + /* derive per-spec workdir from spec basename */ + const char *base = strrchr(specPath, '/'); + base = base ? base+1 : specPath; + char name[128]; + strncpy(name, base, sizeof(name)-1); + char *dot = strrchr(name, '.'); + if (dot) *dot = '\0'; + snprintf(workDir, sizeof(workDir), + "%s/%s", pgaftestOpts.workDir, name); + + TestSpec *spec = parse_test_spec(specPath); + if (!spec) { failed++; total++; continue; } + + total++; + if (!runner_run(spec, workDir)) + failed++; + } + fclose(f); + + fprintf(stderr, "\nSchedule complete: %d/%d passed\n", + total - failed, total); + exit(failed > 0 ? 1 : 0); + } + + /* Single spec file */ + if (optind >= argc) + { + log_error("Usage: pgaftest run [--schedule ] []"); + exit(1); + } + + strncpy(pgaftestOpts.specFile, argv[optind], + sizeof(pgaftestOpts.specFile)-1); + + TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); + if (!spec) exit(1); + + bool ok = runner_run(spec, pgaftestOpts.workDir); + exit(ok ? 0 : 1); +} + +/* ----------------------------------------------------------------------- + * pgaftest setup + * ----------------------------------------------------------------------- */ + +static void +cli_setup(int argc, char **argv) +{ + int optind = pgaftest_getopts(argc, argv); + + if (optind >= argc) + { + log_error("Usage: pgaftest setup [--tmux] [--work-dir ]"); + exit(1); + } + + strncpy(pgaftestOpts.specFile, argv[optind], + sizeof(pgaftestOpts.specFile)-1); + + TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); + if (!spec) exit(1); + + bool ok = runner_setup(spec, pgaftestOpts.workDir, + pgaftestOpts.withTmux); + exit(ok ? 0 : 1); +} + +/* ----------------------------------------------------------------------- + * pgaftest step + * ----------------------------------------------------------------------- */ + +static void +cli_step(int argc, char **argv) +{ + int optind = pgaftest_getopts(argc, argv); + + if (optind >= argc) + { + log_error("Usage: pgaftest step [--work-dir ]"); + exit(1); + } + + /* step name is positional */ + strncpy(pgaftestOpts.stepName, argv[optind], + sizeof(pgaftestOpts.stepName)-1); + + /* We need the spec file too — look for it in workDir */ + char specPath[1024]; + snprintf(specPath, sizeof(specPath), "%s/spec.pgaf", + pgaftestOpts.workDir); + + /* If there's a second positional arg, treat it as the spec path */ + if (optind + 1 < argc) + strncpy(specPath, argv[optind+1], sizeof(specPath)-1); + + TestSpec *spec = parse_test_spec(specPath); + if (!spec) exit(1); + + bool ok = runner_step(spec, pgaftestOpts.workDir, + pgaftestOpts.stepName); + exit(ok ? 0 : 1); +} + +/* ----------------------------------------------------------------------- + * pgaftest show + * ----------------------------------------------------------------------- */ + +static void +cli_show(int argc, char **argv) +{ + int optind = pgaftest_getopts(argc, argv); + + if (optind >= argc) + { + log_error("Usage: pgaftest show "); + exit(1); + } + + strncpy(pgaftestOpts.specFile, argv[optind], + sizeof(pgaftestOpts.specFile)-1); + + TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); + if (!spec) exit(1); + + bool ok = runner_show(spec); + exit(ok ? 0 : 1); +} + +/* ----------------------------------------------------------------------- + * pgaftest down + * ----------------------------------------------------------------------- */ + +static void +cli_down(int argc, char **argv) +{ + pgaftest_getopts(argc, argv); + + /* spec file is optional for `down` — teardown may not need it */ + char specPath[1024]; + snprintf(specPath, sizeof(specPath), "%s/spec.pgaf", + pgaftestOpts.workDir); + + TestSpec *spec = NULL; + if (access(specPath, R_OK) == 0) + spec = parse_test_spec(specPath); + + /* If no spec, just run compose down */ + if (!spec) + { + int rc = system("docker compose down --volumes --remove-orphans 2>&1"); + exit(rc == 0 ? 0 : 1); + } + + bool ok = runner_down(spec, pgaftestOpts.workDir); + exit(ok ? 0 : 1); +} + +/* ----------------------------------------------------------------------- + * Root command table + * ----------------------------------------------------------------------- */ + +static CommandLine run_command = + make_command("run", + "Run a .pgaf spec headlessly (CI mode, TAP output)", + "[options] []", + " --schedule Run all specs listed in schedule file\n" + " --expected Directory of expected output files\n" + " --work-dir Working directory (default: /tmp/pgaftest)\n" + " --verbose Increase log verbosity\n", + pgaftest_getopts, cli_run); + +static CommandLine setup_command = + make_command("setup", + "Bring up a cluster from a spec file (interactive mode)", + "[options] ", + " --tmux Launch a tmux session after setup\n" + " --work-dir Working directory (default: /tmp/pgaftest)\n" + " --verbose Increase log verbosity\n", + pgaftest_getopts, cli_setup); + +static CommandLine step_command = + make_command("step", + "Run a single named step against a live compose stack", + "[options] []", + " --work-dir Working directory (default: /tmp/pgaftest)\n", + pgaftest_getopts, cli_step); + +static CommandLine show_command = + make_command("show", + "Print the docker-compose.yml that would be generated", + "[options] ", + "", + pgaftest_getopts, cli_show); + +static CommandLine down_command = + make_command("down", + "Run teardown block and stop the compose stack", + "[options]", + " --work-dir Working directory (default: /tmp/pgaftest)\n", + pgaftest_getopts, cli_down); + +static CommandLine *root_subcommands[] = { + &run_command, + &setup_command, + &step_command, + &show_command, + &down_command, + &pgaftest_demo_command, + NULL +}; + +CommandLine pgaftest_root = + make_command_set("pgaftest", + "pg_auto_failover test runner", + "[command] [options]", + " run Run a .pgaf spec (CI mode)\n" + " setup Bring up a cluster interactively\n" + " step Run one named step\n" + " show Print generated docker-compose.yml\n" + " down Tear down the cluster\n" + " demo Demo application\n", + NULL, root_subcommands); diff --git a/src/bin/pgaftest/compose_gen.c b/src/bin/pgaftest/compose_gen.c new file mode 100644 index 000000000..f594ae9e3 --- /dev/null +++ b/src/bin/pgaftest/compose_gen.c @@ -0,0 +1,135 @@ +/* + * src/bin/pgaftest/compose_gen.c + * Generate a docker-compose.yml from a TestCluster spec. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include +#include + +#include "compose_gen.h" +#include "pgsetup.h" +#include "log.h" + +/* + * Monitor URI used by data nodes to register. + * The monitor hostname is always "monitor" inside the compose network. + */ +#define MONITOR_PGURI \ + "postgresql://autoctl_node@monitor/pg_auto_failover" + +void +compose_network_name(const char *projectName, char *buf, int buflen) +{ + snprintf(buf, buflen, "%s_default", projectName); +} + +void +compose_container_name(const char *projectName, const char *service, + char *buf, int buflen) +{ + snprintf(buf, buflen, "%s-%s-1", projectName, service); +} + +bool +compose_gen_write(const TestCluster *cluster, + const char *path, + const char *projectName, + int monitorHostPort) +{ + FILE *f = fopen(path, "w"); + if (!f) + { + log_error("Failed to open \"%s\" for writing: %m", path); + return false; + } + + fprintf(f, "# Generated by pgaftest — do not edit manually\n"); + fprintf(f, "# Project: %s\n\n", projectName); + fprintf(f, "services:\n"); + + /* ---- monitor ---- */ + fprintf(f, + " monitor:\n" + " build: .\n" + " hostname: monitor\n" + " volumes:\n" + " - monitor_data:/var/lib/postgres:rw\n" + " environment:\n" + " PGDATA: /var/lib/postgres/pgaf\n" + " ports:\n" + " - \"127.0.0.1:%d:5432\"\n" + " command: >-\n" + " pg_autoctl create monitor\n" + " --ssl-self-signed --auth trust --run\n" + "\n", + monitorHostPort); + + /* ---- data nodes ---- */ + for (int i = 0; i < cluster->nodeCount; i++) + { + const TestNode *n = &cluster->nodes[i]; + const char *pgactl_cmd; + + if (n->kind == NODE_KIND_CITUS_COORDINATOR) + pgactl_cmd = "pg_autoctl create coordinator" + " --ssl-self-signed --auth trust --pg-hba-lan --run"; + else if (n->kind == NODE_KIND_CITUS_WORKER) + { + /* written below with group arg */ + pgactl_cmd = NULL; + } + else + pgactl_cmd = "pg_autoctl create postgres" + " --ssl-self-signed --auth trust --pg-hba-lan --run"; + + fprintf(f, + " %s:\n" + " build: .\n" + " hostname: %s\n" + " volumes:\n" + " - %s_data:/var/lib/postgres:rw\n" + " environment:\n" + " PGDATA: /var/lib/postgres/pgaf\n" + " PGUSER: demo\n" + " PGDATABASE: demo\n" + " PG_AUTOCTL_MONITOR: \"%s\"\n" + " PG_AUTOCTL_NODE_NAME: \"%s\"\n" + " PG_AUTOCTL_REPLICATION_QUORUM: \"%s\"\n" + " PG_AUTOCTL_CANDIDATE_PRIORITY: %d\n" + " expose:\n" + " - 5432\n" + " depends_on:\n" + " - monitor\n", + n->name, n->name, n->name, + MONITOR_PGURI, + n->name, + n->replicationQuorum ? "true" : "false", + n->candidatePriority); + + if (n->kind == NODE_KIND_CITUS_WORKER) + fprintf(f, + " command: >-\n" + " pg_autoctl create worker\n" + " --ssl-self-signed --auth trust --pg-hba-lan" + " --group %d --run\n\n", + n->group); + else + fprintf(f, + " command: \"%s\"\n\n", + pgactl_cmd); + } + + /* ---- volumes ---- */ + fprintf(f, "volumes:\n"); + fprintf(f, " monitor_data:\n"); + for (int i = 0; i < cluster->nodeCount; i++) + fprintf(f, " %s_data:\n", cluster->nodes[i].name); + + fclose(f); + log_info("Wrote docker-compose.yml to \"%s\"", path); + return true; +} diff --git a/src/bin/pgaftest/compose_gen.h b/src/bin/pgaftest/compose_gen.h new file mode 100644 index 000000000..602ec306f --- /dev/null +++ b/src/bin/pgaftest/compose_gen.h @@ -0,0 +1,34 @@ +/* + * src/bin/pgaftest/compose_gen.h + * Generate a docker-compose.yml from a TestCluster spec. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#ifndef COMPOSE_GEN_H +#define COMPOSE_GEN_H + +#include +#include "test_spec.h" + +/* + * Write a docker-compose.yml to `path` for the given cluster spec. + * The monitor's port 5432 is exposed on `monitorHostPort` so the + * test runner can query it directly with libpq. + * Returns true on success. + */ +bool compose_gen_write(const TestCluster *cluster, + const char *path, + const char *projectName, + int monitorHostPort); + +/* Return the docker network name for a project */ +void compose_network_name(const char *projectName, char *buf, int buflen); + +/* Return the container name for a service in a project */ +void compose_container_name(const char *projectName, + const char *service, + char *buf, int buflen); + +#endif /* COMPOSE_GEN_H */ diff --git a/src/bin/pgaftest/main.c b/src/bin/pgaftest/main.c new file mode 100644 index 000000000..949e2dbac --- /dev/null +++ b/src/bin/pgaftest/main.c @@ -0,0 +1,31 @@ +/* + * src/bin/pgaftest/main.c + * pgaftest — pg_auto_failover test runner. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include +#include + +#include "commandline.h" +#include "log.h" + +extern CommandLine pgaftest_root; + +int +main(int argc, char **argv) +{ + /* default log level: INFO to stderr */ + log_set_level(LOG_INFO); + + if (argc < 2) + { + commandline_print_usage(&pgaftest_root, stderr); + return 1; + } + + return commandline_run(&pgaftest_root, argc, argv); +} diff --git a/src/bin/pgaftest/test_runner.c b/src/bin/pgaftest/test_runner.c new file mode 100644 index 000000000..0daea1101 --- /dev/null +++ b/src/bin/pgaftest/test_runner.c @@ -0,0 +1,668 @@ +/* + * src/bin/pgaftest/test_runner.c + * Test execution engine for .pgaf specs. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "libpq-fe.h" +#include "pqexpbuffer.h" + +#include "log.h" +#include "compose_gen.h" +#include "test_runner.h" +#include "test_spec.h" + +/* Default host port for the monitor */ +#define MONITOR_DEFAULT_PORT 15432 + +/* Docker binary name */ +#define DOCKER "docker" + +/* ----------------------------------------------------------------------- + * Internal helpers + * ----------------------------------------------------------------------- */ + +/* Run a shell command, return its exit code */ +static int +run_cmd(const char *fmt, ...) +{ + char cmd[4096]; + va_list ap; + va_start(ap, fmt); + vsnprintf(cmd, sizeof(cmd), fmt, ap); + va_end(ap); + + log_debug("$ %s", cmd); + return system(cmd); +} + +/* Run a shell command, capture stdout into buf */ +static int +run_cmd_capture(char *buf, int buflen, const char *fmt, ...) +{ + char cmd[4096]; + va_list ap; + va_start(ap, fmt); + vsnprintf(cmd, sizeof(cmd), fmt, ap); + va_end(ap); + + log_debug("$ %s", cmd); + + FILE *p = popen(cmd, "r"); + if (!p) return -1; + + int pos = 0; + int c; + while ((c = fgetc(p)) != EOF && pos < buflen - 1) + buf[pos++] = (char)c; + buf[pos] = '\0'; + + /* trim trailing whitespace */ + while (pos > 0 && (buf[pos-1] == '\n' || buf[pos-1] == '\r' || + buf[pos-1] == ' ')) + buf[--pos] = '\0'; + + return pclose(p); +} + +/* ----------------------------------------------------------------------- + * Runner initialisation + * ----------------------------------------------------------------------- */ + +static void +runner_init(TestRunner *r, TestSpec *spec, const char *workDir) +{ + memset(r, 0, sizeof(*r)); + r->spec = spec; + r->monitorPort = MONITOR_DEFAULT_PORT; + + /* derive project name from spec filename base */ + const char *base = strrchr(spec->filename, '/'); + base = base ? base + 1 : spec->filename; + strncpy(r->projectName, base, sizeof(r->projectName)-1); + /* strip .pgaf extension */ + char *dot = strrchr(r->projectName, '.'); + if (dot) *dot = '\0'; + + snprintf(r->workDir, sizeof(r->workDir), "%s", workDir); + snprintf(r->composeFile, sizeof(r->composeFile), + "%s/docker-compose.yml", workDir); + snprintf(r->monitorConnStr, sizeof(r->monitorConnStr), + "host=127.0.0.1 port=%d user=autoctl_node " + "dbname=pg_auto_failover sslmode=prefer", + r->monitorPort); +} + +/* ----------------------------------------------------------------------- + * TAP output + * ----------------------------------------------------------------------- */ + +static void +tap_plan(TestRunner *r) +{ + printf("1..%d\n", r->tapTotal); + fflush(stdout); +} + +static void +tap_ok(TestRunner *r, const char *name) +{ + r->tapPass++; + printf("ok %d - %s\n", r->tapPass + r->tapFail, name); + fflush(stdout); +} + +static void +tap_not_ok(TestRunner *r, const char *name, const char *reason) +{ + r->tapFail++; + printf("not ok %d - %s\n", r->tapPass + r->tapFail, name); + if (reason) + printf("# %s\n", reason); + fflush(stdout); +} + +static void +tap_diag(const char *fmt, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + printf("# %s\n", buf); + fflush(stdout); +} + +/* ----------------------------------------------------------------------- + * Compose lifecycle + * ----------------------------------------------------------------------- */ + +static bool +runner_compose_generate(TestRunner *r) +{ + /* ensure workdir exists */ + if (mkdir(r->workDir, 0755) != 0 && errno != EEXIST) + { + log_error("Failed to create work directory \"%s\": %m", r->workDir); + return false; + } + + return compose_gen_write(&r->spec->cluster, + r->composeFile, + r->projectName, + r->monitorPort); +} + +static bool +runner_compose_up(TestRunner *r) +{ + log_info("Starting compose stack (project: %s)", r->projectName); + + int rc = run_cmd("docker compose -p %s -f %s up -d 2>&1", + r->projectName, r->composeFile); + if (rc != 0) + { + log_error("docker compose up failed (exit %d)", rc); + return false; + } + r->composeUp = true; + return true; +} + +static bool +runner_compose_down(TestRunner *r) +{ + if (!r->composeUp) return true; + + log_info("Tearing down compose stack (project: %s)", r->projectName); + + run_cmd("docker compose -p %s -f %s down --volumes --remove-orphans 2>&1", + r->projectName, r->composeFile); + r->composeUp = false; + return true; +} + +/* ----------------------------------------------------------------------- + * State polling via libpq + * ----------------------------------------------------------------------- */ + +/* + * Query the monitor for a node's current reported state and assigned state. + * Returns true and fills *reported / *assigned on success. + */ +static bool +monitor_get_node_state(const char *connstr, const char *nodeName, + char *reported, int replen, + char *assigned, int asslen) +{ + PGconn *conn = PQconnectdb(connstr); + if (PQstatus(conn) != CONNECTION_OK) + { + log_debug("monitor not yet reachable: %s", PQerrorMessage(conn)); + PQfinish(conn); + return false; + } + + const char *params[1] = { nodeName }; + PGresult *res = PQexecParams(conn, + "SELECT reportedstate, goalstate " + "FROM pgautofailover.node WHERE nodename = $1", + 1, NULL, params, NULL, NULL, 0); + + bool ok = false; + if (PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) > 0) + { + strncpy(reported, PQgetvalue(res, 0, 0), replen - 1); + strncpy(assigned, PQgetvalue(res, 0, 1), asslen - 1); + ok = true; + } + PQclear(res); + PQfinish(conn); + return ok; +} + +/* + * Poll until the node reaches the target state, or timeout expires. + */ +static bool +wait_for_state(TestRunner *r, const char *nodeName, const char *targetState, + int timeoutSecs, bool checkAssigned) +{ + time_t deadline = time(NULL) + timeoutSecs; + char reported[64], assigned[64]; + + log_info("Waiting for %s %s = %s (timeout %ds)", + nodeName, + checkAssigned ? "assigned-state" : "state", + targetState, + timeoutSecs); + + while (time(NULL) < deadline) + { + if (monitor_get_node_state(r->monitorConnStr, nodeName, + reported, sizeof(reported), + assigned, sizeof(assigned))) + { + const char *actual = checkAssigned ? assigned : reported; + if (strcmp(actual, targetState) == 0) + return true; + } + usleep(200000); /* 200ms */ + } + + log_error("Timeout waiting for %s %s = %s", + nodeName, + checkAssigned ? "assigned-state" : "state", + targetState); + return false; +} + +/* ----------------------------------------------------------------------- + * SQL execution on a service + * ----------------------------------------------------------------------- */ + +static bool +exec_sql_on_service(TestRunner *r, const char *service, + const char *sql, char *outbuf, int outlen) +{ + /* Escape single quotes in SQL for shell */ + char escaped[8192]; + int oi = 0; + for (int i = 0; sql[i] && oi < (int)sizeof(escaped)-2; i++) + { + if (sql[i] == '\'') + { + escaped[oi++] = '\''; + escaped[oi++] = '\\'; + escaped[oi++] = '\''; + escaped[oi++] = '\''; + } + else + escaped[oi++] = sql[i]; + } + escaped[oi] = '\0'; + + int rc = run_cmd_capture(outbuf, outlen, + "docker compose -p %s -f %s exec -T %s " + "psql --tuples-only --no-align -c '%s' 2>&1", + r->projectName, r->composeFile, service, escaped); + + return rc == 0; +} + +/* ----------------------------------------------------------------------- + * Network failure simulation + * ----------------------------------------------------------------------- */ + +static bool +runner_network_off(TestRunner *r, const char *nodeName) +{ + char netName[128], container[128]; + compose_network_name(r->projectName, netName, sizeof(netName)); + compose_container_name(r->projectName, nodeName, container, sizeof(container)); + + log_info("Disconnecting %s from network %s", container, netName); + return run_cmd("docker network disconnect %s %s 2>&1", + netName, container) == 0; +} + +static bool +runner_network_on(TestRunner *r, const char *nodeName) +{ + char netName[128], container[128]; + compose_network_name(r->projectName, netName, sizeof(netName)); + compose_container_name(r->projectName, nodeName, container, sizeof(container)); + + log_info("Reconnecting %s to network %s", container, netName); + return run_cmd("docker network connect %s %s 2>&1", + netName, container) == 0; +} + +/* ----------------------------------------------------------------------- + * Execute a single command + * ----------------------------------------------------------------------- */ + +static bool +runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) +{ + switch (cmd->kind) + { + case CMD_EXEC: + { + int rc = run_cmd( + "docker compose -p %s -f %s exec -T %s %s 2>&1", + r->projectName, r->composeFile, + cmd->service, cmd->args); + if (rc != 0) + { + snprintf(errBuf, errLen, + "exec %s %s failed (exit %d)", + cmd->service, cmd->args, rc); + return false; + } + return true; + } + + case CMD_WAIT_STATE: + if (!wait_for_state(r, cmd->service, cmd->state, + cmd->timeoutSeconds, false)) + { + snprintf(errBuf, errLen, + "timeout: %s state never reached %s", + cmd->service, cmd->state); + return false; + } + return true; + + case CMD_ASSERT_STATE: + case CMD_ASSERT_ASSIGNED: + { + char reported[64] = "", assigned[64] = ""; + if (!monitor_get_node_state(r->monitorConnStr, cmd->service, + reported, sizeof(reported), + assigned, sizeof(assigned))) + { + snprintf(errBuf, errLen, + "cannot reach monitor to assert %s state", + cmd->service); + return false; + } + const char *actual = (cmd->kind == CMD_ASSERT_ASSIGNED) + ? assigned : reported; + if (strcmp(actual, cmd->state) != 0) + { + snprintf(errBuf, errLen, + "%s %s is \"%s\", expected \"%s\"", + cmd->service, + (cmd->kind == CMD_ASSERT_ASSIGNED) + ? "assigned-state" : "state", + actual, cmd->state); + return false; + } + return true; + } + + case CMD_SQL: + { + if (!exec_sql_on_service(r, cmd->service, cmd->args, + r->lastSqlOutput, + sizeof(r->lastSqlOutput))) + { + snprintf(errBuf, errLen, + "sql on %s failed", cmd->service); + return false; + } + log_debug("sql output: %s", r->lastSqlOutput); + return true; + } + + case CMD_EXPECT: + { + if (strcmp(r->lastSqlOutput, cmd->expected) != 0) + { + snprintf(errBuf, errLen, + "expected \"%s\", got \"%s\"", + cmd->expected, r->lastSqlOutput); + return false; + } + return true; + } + + case CMD_NETWORK_OFF: + if (!runner_network_off(r, cmd->service)) + { + snprintf(errBuf, errLen, + "network disconnect %s failed", cmd->service); + return false; + } + return true; + + case CMD_NETWORK_ON: + if (!runner_network_on(r, cmd->service)) + { + snprintf(errBuf, errLen, + "network connect %s failed", cmd->service); + return false; + } + return true; + + case CMD_SLEEP: + log_info("Sleeping %d seconds", cmd->timeoutSeconds); + sleep(cmd->timeoutSeconds); + return true; + + case CMD_COMPOSE_DOWN: + return runner_compose_down(r); + } + return true; +} + +/* ----------------------------------------------------------------------- + * Execute a step (list of commands) + * ----------------------------------------------------------------------- */ + +static bool +runner_exec_step(TestRunner *r, TestStep *step, char *errBuf, int errLen) +{ + for (TestCmd *cmd = step->commands; cmd; cmd = cmd->next) + { + if (!runner_exec_cmd(r, cmd, errBuf, errLen)) + return false; + } + return true; +} + +/* ----------------------------------------------------------------------- + * Load runner state from workDir (for step/down subcommands) + * ----------------------------------------------------------------------- */ + +static bool +runner_load_state(TestRunner *r) +{ + /* Check the compose file exists — if it does, the stack should be up */ + struct stat st; + if (stat(r->composeFile, &st) != 0) + { + log_error("No compose file found at \"%s\"; run `pgaftest setup` first", + r->composeFile); + return false; + } + r->composeUp = true; + return true; +} + +/* ----------------------------------------------------------------------- + * Public API + * ----------------------------------------------------------------------- */ + +bool +runner_run(TestSpec *spec, const char *workDir) +{ + TestRunner r; + runner_init(&r, spec, workDir); + + r.tapTotal = spec->sequenceLength; + + if (!runner_compose_generate(&r)) + return false; + + if (!runner_compose_up(&r)) + return false; + + tap_plan(&r); + + /* setup{} */ + if (spec->setup) + { + char err[512] = ""; + log_info("Running setup block"); + if (!runner_exec_step(&r, spec->setup, err, sizeof(err))) + { + tap_diag("setup failed: %s", err); + runner_compose_down(&r); + return false; + } + } + + /* sequence */ + bool allPassed = true; + for (int i = 0; i < spec->sequenceLength; i++) + { + const char *name = spec->sequence[i]; + TestStep *step = spec_find_step(spec, name); + if (!step) + { + tap_not_ok(&r, name, "step not found in spec"); + allPassed = false; + continue; + } + + char err[512] = ""; + if (runner_exec_step(&r, step, err, sizeof(err))) + { + tap_ok(&r, name); + } + else + { + tap_not_ok(&r, name, err); + allPassed = false; + /* continue running remaining steps */ + } + } + + /* teardown{} — always runs */ + if (spec->teardown) + { + char err[512] = ""; + log_info("Running teardown block"); + runner_exec_step(&r, spec->teardown, err, sizeof(err)); + } + + runner_compose_down(&r); + return allPassed; +} + +bool +runner_setup(TestSpec *spec, const char *workDir, bool withTmux) +{ + TestRunner r; + runner_init(&r, spec, workDir); + + if (!runner_compose_generate(&r)) + return false; + + if (!runner_compose_up(&r)) + return false; + + /* run setup{} block */ + if (spec->setup) + { + char err[512] = ""; + log_info("Running setup block"); + if (!runner_exec_step(&r, spec->setup, err, sizeof(err))) + { + log_error("Setup failed: %s", err); + runner_compose_down(&r); + return false; + } + } + + if (withTmux) + { + /* Launch tmux with compose logs + pg_autoctl watch */ + log_info("Starting tmux session for project %s", r.projectName); + run_cmd( + "tmux new-session -d -s %s " + "\"docker compose -p %s -f %s logs -f\" \\; " + "split-window -v " + "\"docker compose -p %s -f %s exec monitor pg_autoctl watch\" \\; " + "split-window -v \\; " + "select-layout even-vertical", + r.projectName, + r.projectName, r.composeFile, + r.projectName, r.composeFile); + + printf("Cluster ready. Attach with: tmux attach -t %s\n", + r.projectName); + printf("Tear down with: pgaftest down --work-dir %s\n", workDir); + } + else + { + printf("\nCluster ready — compose project: %s\n", r.projectName); + printf("Work dir: %s\n", workDir); + printf("\nAvailable steps:"); + for (TestStep *s = spec->steps; s; s = s->next) + printf(" %s", s->name); + printf("\n\nRun a step: pgaftest step --work-dir %s\n", workDir); + printf("Tear down: pgaftest down --work-dir %s\n\n", workDir); + } + + return true; +} + +bool +runner_step(TestSpec *spec, const char *workDir, const char *stepName) +{ + TestRunner r; + runner_init(&r, spec, workDir); + + if (!runner_load_state(&r)) + return false; + + TestStep *step = spec_find_step(spec, stepName); + if (!step) + { + log_error("Step \"%s\" not found in spec", stepName); + return false; + } + + char err[512] = ""; + if (!runner_exec_step(&r, step, err, sizeof(err))) + { + log_error("Step \"%s\" failed: %s", stepName, err); + return false; + } + + log_info("Step \"%s\" passed", stepName); + return true; +} + +bool +runner_down(TestSpec *spec, const char *workDir) +{ + TestRunner r; + runner_init(&r, spec, workDir); + runner_load_state(&r); /* best-effort */ + + /* teardown{} */ + if (spec->teardown) + { + char err[512] = ""; + runner_exec_step(&r, spec->teardown, err, sizeof(err)); + } + + return runner_compose_down(&r); +} + +bool +runner_show(TestSpec *spec) +{ + TestRunner r; + runner_init(&r, spec, "/tmp/pgaftest-show"); + + /* write to stdout instead of a file */ + bool ok = compose_gen_write(&spec->cluster, "/dev/stdout", + r.projectName, r.monitorPort); + return ok; +} diff --git a/src/bin/pgaftest/test_runner.h b/src/bin/pgaftest/test_runner.h new file mode 100644 index 000000000..5d883a21a --- /dev/null +++ b/src/bin/pgaftest/test_runner.h @@ -0,0 +1,66 @@ +/* + * src/bin/pgaftest/test_runner.h + * Test execution engine for .pgaf specs. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#ifndef TEST_RUNNER_H +#define TEST_RUNNER_H + +#include +#include "test_spec.h" + +/* Runtime context for a running test */ +typedef struct TestRunner +{ + TestSpec *spec; + char projectName[64]; /* docker compose project name */ + char composeFile[1024]; /* path to generated compose YAML */ + char workDir[1024]; /* temp dir for this run */ + int monitorPort; /* host port mapped to monitor:5432 */ + char monitorConnStr[256]; + + /* TAP counters */ + int tapTotal; + int tapPass; + int tapFail; + + /* last SQL output (for CMD_EXPECT) */ + char lastSqlOutput[4096]; + + bool composeUp; /* compose stack is running */ +} TestRunner; + +/* + * CI mode: run the full spec (setup → sequence → teardown). + * Emits TAP to stdout. Returns true if all steps passed. + */ +bool runner_run(TestSpec *spec, const char *workDir); + +/* + * Interactive mode: bring up compose, run setup{}, then stop. + * The caller gets the running cluster to explore interactively. + * If withTmux is true, launch a tmux session instead of returning. + */ +bool runner_setup(TestSpec *spec, const char *workDir, bool withTmux); + +/* + * Run a single named step against an already-running compose stack. + * Used by `pgaftest step `. + */ +bool runner_step(TestSpec *spec, const char *workDir, const char *stepName); + +/* + * Tear down the compose stack (run teardown{} then compose down). + * Used by `pgaftest down`. + */ +bool runner_down(TestSpec *spec, const char *workDir); + +/* + * Print the generated docker-compose.yml without starting anything. + */ +bool runner_show(TestSpec *spec); + +#endif /* TEST_RUNNER_H */ diff --git a/src/bin/pgaftest/test_spec.h b/src/bin/pgaftest/test_spec.h new file mode 100644 index 000000000..feb55575e --- /dev/null +++ b/src/bin/pgaftest/test_spec.h @@ -0,0 +1,117 @@ +/* + * src/bin/pgaftest/test_spec.h + * AST types for the .pgaf test specification format. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#ifndef TEST_SPEC_H +#define TEST_SPEC_H + +#include +#include "pgsetup.h" /* PgInstanceKind */ + +#define PGAF_MAX_NODES 32 +#define PGAF_MAX_STEPS 256 +#define PGAF_MAX_SEQ 256 +#define PGAF_TIMEOUT_DEFAULT 90 + +/* ----------------------------------------------------------------------- + * Cluster topology (from the cluster { } block) + * ----------------------------------------------------------------------- */ + +typedef struct TestNode +{ + char name[64]; + PgInstanceKind kind; /* standalone / coordinator / worker */ + int group; /* Citus group id; 0 = coordinator */ + int candidatePriority; /* 0-100, default 50 */ + bool replicationQuorum; /* participates in sync quorum */ + bool async; /* async standby */ +} TestNode; + +typedef struct TestCluster +{ + TestNode nodes[PGAF_MAX_NODES]; + int nodeCount; + bool withMonitor; /* always true for now */ + bool withCitus; + int numSync; /* number-sync-standbys, -1 = unset */ +} TestCluster; + +/* ----------------------------------------------------------------------- + * Commands (inside step/setup/teardown blocks) + * ----------------------------------------------------------------------- */ + +typedef enum TestCmdKind +{ + CMD_EXEC, /* exec */ + CMD_WAIT_STATE, /* wait until state = [timeout Ns] */ + CMD_ASSERT_STATE, /* assert state = */ + CMD_ASSERT_ASSIGNED, /* assert assigned-state = */ + CMD_SQL, /* sql { SQL } */ + CMD_EXPECT, /* expect { text } */ + CMD_NETWORK_OFF, /* network disconnect */ + CMD_NETWORK_ON, /* network connect */ + CMD_SLEEP, /* sleep Ns */ + CMD_COMPOSE_DOWN, /* compose down */ +} TestCmdKind; + +typedef struct TestCmd +{ + TestCmdKind kind; + char service[64]; /* target service / node name */ + char args[4096]; /* exec args or SQL text */ + char state[64]; /* expected state string */ + char expected[4096]; /* for CMD_EXPECT */ + int timeoutSeconds; /* for CMD_WAIT_STATE */ + struct TestCmd *next; +} TestCmd; + +/* ----------------------------------------------------------------------- + * Named step + * ----------------------------------------------------------------------- */ + +typedef struct TestStep +{ + char name[64]; + TestCmd *commands; /* linked list */ + struct TestStep *next; +} TestStep; + +/* ----------------------------------------------------------------------- + * Full test specification + * ----------------------------------------------------------------------- */ + +typedef struct TestSpec +{ + char filename[1024]; + + TestCluster cluster; + + TestStep *setup; /* single anonymous step */ + TestStep *teardown; /* single anonymous step */ + + TestStep *steps; /* named steps, linked list */ + int stepCount; + + char *sequence[PGAF_MAX_SEQ]; /* ordered step names */ + int sequenceLength; +} TestSpec; + +/* ----------------------------------------------------------------------- + * Parser entry point (implemented by bison grammar) + * ----------------------------------------------------------------------- */ + +extern TestSpec *parse_test_spec(const char *filename); + +/* ----------------------------------------------------------------------- + * Helpers + * ----------------------------------------------------------------------- */ + +TestStep *spec_find_step(TestSpec *spec, const char *name); +TestCmd *make_cmd(TestCmdKind kind); +TestStep *make_step(const char *name); + +#endif /* TEST_SPEC_H */ diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y new file mode 100644 index 000000000..84c524565 --- /dev/null +++ b/src/bin/pgaftest/test_spec_parse.y @@ -0,0 +1,417 @@ +%{ +/* + * src/bin/pgaftest/test_spec_parse.y + * Bison grammar for .pgaf test specification files. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include +#include + +#include "test_spec.h" +#include "pgsetup.h" + +/* provided by test_spec_scan.l */ +extern int yylex(void); +extern int pgaf_line_number; +extern FILE *yyin; + +/* the spec we're building */ +static TestSpec *current_spec = NULL; + +static void yyerror(const char *msg) +{ + fprintf(stderr, "pgaftest: parse error at line %d: %s\n", + pgaf_line_number, msg); + exit(1); +} + +/* helpers */ +static void append_cmd(TestStep *step, TestCmd *cmd) +{ + if (!step->commands) + { + step->commands = cmd; + } + else + { + TestCmd *c = step->commands; + while (c->next) c = c->next; + c->next = cmd; + } +} + +static void register_step(TestSpec *spec, TestStep *step) +{ + if (!spec->steps) + { + spec->steps = step; + } + else + { + TestStep *s = spec->steps; + while (s->next) s = s->next; + s->next = step; + } + spec->stepCount++; +} + +%} + +%union { + int ival; + char *str; + TestStep *step; + TestCmd *cmd; +} + +%token T_CLUSTER T_MONITOR T_NODE T_CITUS_COORDINATOR T_CITUS_WORKER +%token T_SETUP T_TEARDOWN T_STEP T_SEQUENCE +%token T_EXEC T_WAIT T_UNTIL T_TIMEOUT T_ASSERT T_SQL T_EXPECT +%token T_NETWORK T_DISCONNECT T_CONNECT T_SLEEP T_COMPOSE T_DOWN +%token T_STATE T_ASSIGNED_STATE T_CANDIDATE_PRIORITY T_GROUP T_ASYNC +%token T_EQUALS + +%token T_INTEGER +%token T_IDENT T_STRING T_BLOCK + +%type ident_or_string +%type step_block cmd_block +%type command command_list + +%% + +spec: + spec_item + | spec spec_item + ; + +spec_item: + cluster_block + | setup_block + | teardown_block + | named_step + | sequence_block + ; + +/* ----------------------------------------------------------------------- + * cluster { } + * ----------------------------------------------------------------------- */ + +cluster_block: + T_CLUSTER T_BLOCK + { + /* + * Re-parse the block text as a mini node-list. + * We do this with a simple line-by-line parser here rather than + * a recursive grammar to keep things simple. + */ + char *text = $2; + char *line = strtok(text, "\n"); + + current_spec->cluster.withMonitor = true; + current_spec->cluster.numSync = -1; + + while (line) + { + /* skip leading whitespace */ + while (*line == ' ' || *line == '\t') line++; + + if (strncmp(line, "monitor", 7) == 0) + { + current_spec->cluster.withMonitor = true; + } + else if (strncmp(line, "citus-coordinator", 17) == 0) + { + TestNode *n = ¤t_spec->cluster.nodes[ + current_spec->cluster.nodeCount++]; + sscanf(line + 18, "%63s", n->name); + n->kind = NODE_KIND_CITUS_COORDINATOR; + n->group = 0; + n->candidatePriority = 50; + n->replicationQuorum = true; + current_spec->cluster.withCitus = true; + } + else if (strncmp(line, "citus-worker", 12) == 0) + { + TestNode *n = ¤t_spec->cluster.nodes[ + current_spec->cluster.nodeCount++]; + char rest[256]; + sscanf(line + 13, "%63s %255[^\n]", n->name, rest); + n->kind = NODE_KIND_CITUS_WORKER; + n->candidatePriority = 50; + n->replicationQuorum = true; + /* parse group=N from rest */ + char *gp = strstr(rest, "group="); + if (gp) n->group = atoi(gp + 6); + current_spec->cluster.withCitus = true; + } + else if (strncmp(line, "node", 4) == 0) + { + TestNode *n = ¤t_spec->cluster.nodes[ + current_spec->cluster.nodeCount++]; + n->kind = NODE_KIND_STANDALONE; + n->candidatePriority = 50; + n->replicationQuorum = true; + + char rest[256] = { 0 }; + sscanf(line + 5, "%63s %255[^\n]", n->name, rest); + + /* parse options: candidate-priority=N async */ + char *cp = strstr(rest, "candidate-priority="); + if (cp) n->candidatePriority = atoi(cp + 19); + + if (strstr(rest, "async")) + n->replicationQuorum = false; + } + + line = strtok(NULL, "\n"); + } + free($2); + } + ; + +/* ----------------------------------------------------------------------- + * setup { } and teardown { } + * ----------------------------------------------------------------------- */ + +setup_block: + T_SETUP cmd_block + { + current_spec->setup = $2; + } + ; + +teardown_block: + T_TEARDOWN cmd_block + { + current_spec->teardown = $2; + } + ; + +/* ----------------------------------------------------------------------- + * step { } + * ----------------------------------------------------------------------- */ + +named_step: + T_STEP ident_or_string cmd_block + { + TestStep *s = $3; + strncpy(s->name, $2, sizeof(s->name) - 1); + free($2); + register_step(current_spec, s); + } + ; + +cmd_block: + T_BLOCK + { + /* + * Parse the block text into a linked list of TestCmd. + * We do this with a simple recursive descent over lines. + */ + TestStep *step = make_step(""); + char *text = strdup($1); + free($1); + + char *line = strtok(text, "\n"); + while (line) + { + while (*line == ' ' || *line == '\t') line++; + if (*line == '\0' || *line == '#') { line = strtok(NULL,"\n"); continue; } + + TestCmd *cmd = NULL; + + if (strncmp(line, "exec ", 5) == 0) + { + cmd = make_cmd(CMD_EXEC); + char *rest = line + 5; + while (*rest == ' ' || *rest == '\t') rest++; + /* first token = service, rest = args */ + sscanf(rest, "%63s", cmd->service); + char *sp = rest + strlen(cmd->service); + while (*sp == ' ' || *sp == '\t') sp++; + strncpy(cmd->args, sp, sizeof(cmd->args) - 1); + } + else if (strncmp(line, "wait until ", 11) == 0) + { + cmd = make_cmd(CMD_WAIT_STATE); + cmd->timeoutSeconds = PGAF_TIMEOUT_DEFAULT; + char node[64], kw1[32], eq[4], state[64]; + char *rest = line + 11; + int n = sscanf(rest, "%63s %31s %3s %63s", node, kw1, eq, state); + if (n < 4) { fprintf(stderr,"bad wait until: %s\n",line); exit(1); } + strncpy(cmd->service, node, sizeof(cmd->service)-1); + strncpy(cmd->state, state, sizeof(cmd->state)-1); + /* check for "timeout Ns" suffix */ + char *tp = strstr(rest, "timeout "); + if (tp) cmd->timeoutSeconds = atoi(tp + 8); + + /* assigned-state variant */ + if (strcmp(kw1, "assigned-state") == 0) + cmd->kind = CMD_ASSERT_ASSIGNED; + } + else if (strncmp(line, "assert ", 7) == 0) + { + char node[64], kw[32], eq[4], state[64]; + char *rest = line + 7; + sscanf(rest, "%63s %31s %3s %63s", node, kw, eq, state); + if (strcmp(kw, "assigned-state") == 0) + cmd = make_cmd(CMD_ASSERT_ASSIGNED); + else + cmd = make_cmd(CMD_ASSERT_STATE); + strncpy(cmd->service, node, sizeof(cmd->service)-1); + strncpy(cmd->state, state, sizeof(cmd->state)-1); + } + else if (strncmp(line, "sql ", 4) == 0) + { + cmd = make_cmd(CMD_SQL); + /* sql { SQL } — but the { } was already consumed by the + * outer block parser; here we just have the inline form + * sql or sql { multi-line } + * For simplicity we treat everything after svc as the query. */ + char *rest = line + 4; + while (*rest == ' ' || *rest == '\t') rest++; + sscanf(rest, "%63s", cmd->service); + char *q = rest + strlen(cmd->service); + while (*q == ' ' || *q == '\t') q++; + strncpy(cmd->args, q, sizeof(cmd->args)-1); + } + else if (strncmp(line, "expect ", 7) == 0) + { + cmd = make_cmd(CMD_EXPECT); + strncpy(cmd->expected, line + 7, sizeof(cmd->expected)-1); + } + else if (strncmp(line, "network disconnect ", 19) == 0) + { + cmd = make_cmd(CMD_NETWORK_OFF); + strncpy(cmd->service, line + 19, sizeof(cmd->service)-1); + } + else if (strncmp(line, "network connect ", 16) == 0) + { + cmd = make_cmd(CMD_NETWORK_ON); + strncpy(cmd->service, line + 16, sizeof(cmd->service)-1); + } + else if (strncmp(line, "sleep ", 6) == 0) + { + cmd = make_cmd(CMD_SLEEP); + cmd->timeoutSeconds = atoi(line + 6); + } + else if (strcmp(line, "compose down") == 0 || + strncmp(line, "compose down", 12) == 0) + { + cmd = make_cmd(CMD_COMPOSE_DOWN); + } + else + { + fprintf(stderr, "pgaftest: unknown command: %s\n", line); + exit(1); + } + + if (cmd) append_cmd(step, cmd); + line = strtok(NULL, "\n"); + } + free(text); + $$ = step; + } + ; + +/* ----------------------------------------------------------------------- + * sequence + * ----------------------------------------------------------------------- */ + +sequence_block: + T_SEQUENCE sequence_names + ; + +sequence_names: + /* empty */ + | sequence_names ident_or_string + { + int i = current_spec->sequenceLength; + if (i < PGAF_MAX_SEQ) + current_spec->sequence[current_spec->sequenceLength++] = $2; + else + { + fprintf(stderr, "pgaftest: too many steps in sequence (max %d)\n", + PGAF_MAX_SEQ); + exit(1); + } + } + ; + +/* ----------------------------------------------------------------------- + * Helpers + * ----------------------------------------------------------------------- */ + +ident_or_string: + T_IDENT { $$ = $1; } + | T_STRING { $$ = $1; } + ; + +%% + +/* ----------------------------------------------------------------------- + * Public entry point + * ----------------------------------------------------------------------- */ + +TestSpec * +parse_test_spec(const char *filename) +{ + FILE *f = fopen(filename, "r"); + if (!f) + { + fprintf(stderr, "pgaftest: cannot open spec file \"%s\": %s\n", + filename, strerror(errno)); + return NULL; + } + + TestSpec *spec = (TestSpec *) calloc(1, sizeof(TestSpec)); + if (!spec) { fprintf(stderr, "out of memory\n"); exit(1); } + + strncpy(spec->filename, filename, sizeof(spec->filename)-1); + spec->cluster.numSync = -1; + + current_spec = spec; + pgaf_line_number = 1; + yyin = f; + yyparse(); + fclose(f); + + return spec; +} + +/* helpers used by the grammar and runner */ + +TestCmd * +make_cmd(TestCmdKind kind) +{ + TestCmd *c = (TestCmd *) calloc(1, sizeof(TestCmd)); + if (!c) { fprintf(stderr, "out of memory\n"); exit(1); } + c->kind = kind; + c->timeoutSeconds = PGAF_TIMEOUT_DEFAULT; + return c; +} + +TestStep * +make_step(const char *name) +{ + TestStep *s = (TestStep *) calloc(1, sizeof(TestStep)); + if (!s) { fprintf(stderr, "out of memory\n"); exit(1); } + if (name) strncpy(s->name, name, sizeof(s->name)-1); + return s; +} + +TestStep * +spec_find_step(TestSpec *spec, const char *name) +{ + for (TestStep *s = spec->steps; s; s = s->next) + { + if (strcmp(s->name, name) == 0) + return s; + } + return NULL; +} diff --git a/src/bin/pgaftest/test_spec_scan.l b/src/bin/pgaftest/test_spec_scan.l new file mode 100644 index 000000000..3d31f31a5 --- /dev/null +++ b/src/bin/pgaftest/test_spec_scan.l @@ -0,0 +1,130 @@ +%{ +/* + * src/bin/pgaftest/test_spec_scan.l + * Flex lexer for .pgaf test specification files. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include "test_spec.h" +#include "test_spec_parse.h" + +/* track line number for error messages */ +int pgaf_line_number = 1; + +static char *pgaf_strdup(const char *s) +{ + char *r = strdup(s); + if (!r) { fprintf(stderr, "out of memory\n"); exit(1); } + return r; +} +%} + +%option noyywrap +%option nounput +%option noinput +%option never-interactive + +/* multi-line SQL/text block: { ... } */ +%x BLOCK + +%% + +"#"[^\n]* { /* single-line comment, skip */ } + +"cluster" { return T_CLUSTER; } +"monitor" { return T_MONITOR; } +"node" { return T_NODE; } +"citus-coordinator" { return T_CITUS_COORDINATOR; } +"citus-worker" { return T_CITUS_WORKER; } + +"setup" { return T_SETUP; } +"teardown" { return T_TEARDOWN; } +"step" { return T_STEP; } +"sequence" { return T_SEQUENCE; } + +"exec" { return T_EXEC; } +"wait" { return T_WAIT; } +"until" { return T_UNTIL; } +"timeout" { return T_TIMEOUT; } +"assert" { return T_ASSERT; } +"sql" { return T_SQL; } +"expect" { return T_EXPECT; } +"network" { return T_NETWORK; } +"disconnect" { return T_DISCONNECT; } +"connect" { return T_CONNECT; } +"sleep" { return T_SLEEP; } +"compose" { return T_COMPOSE; } +"down" { return T_DOWN; } + +"state" { return T_STATE; } +"assigned-state" { return T_ASSIGNED_STATE; } +"candidate-priority" { return T_CANDIDATE_PRIORITY; } +"group" { return T_GROUP; } +"async" { return T_ASYNC; } + +"=" { return T_EQUALS; } + +[0-9]+[sS]? { + /* integer, optionally followed by 's' for seconds */ + yylval.ival = atoi(yytext); + return T_INTEGER; +} + +[A-Za-z_][A-Za-z0-9_-]* { + yylval.str = pgaf_strdup(yytext); + return T_IDENT; +} + +\"[^\"]*\" { + /* quoted string: strip surrounding quotes */ + yytext[yyleng-1] = '\0'; + yylval.str = pgaf_strdup(yytext + 1); + return T_STRING; +} + +"{" { + /* start of a brace block — collect everything until matching } */ + int depth = 1; + int c; + char buf[65536]; + int pos = 0; + + while (depth > 0 && (c = input()) != EOF) + { + if (c == '{') depth++; + else if (c == '}') { depth--; if (depth == 0) break; } + else if (c == '\n') pgaf_line_number++; + if (depth > 0) + { + if (pos < (int)sizeof(buf) - 1) + buf[pos++] = (char)c; + } + } + buf[pos] = '\0'; + + /* trim leading/trailing whitespace */ + char *start = buf; + while (*start == ' ' || *start == '\t' || *start == '\n' || *start == '\r') + start++; + char *end = start + strlen(start); + while (end > start && (end[-1]==' ' || end[-1]=='\t' || + end[-1]=='\n' || end[-1]=='\r')) + end--; + *end = '\0'; + + yylval.str = pgaf_strdup(start); + return T_BLOCK; +} + +\n { pgaf_line_number++; } +[ \t\r]+ { /* whitespace */ } + +. { + fprintf(stderr, "pgaftest: unexpected character '%c' at line %d\n", + yytext[0], pgaf_line_number); +} + +%% diff --git a/tests/tap/schedule b/tests/tap/schedule new file mode 100644 index 000000000..b6ac904f6 --- /dev/null +++ b/tests/tap/schedule @@ -0,0 +1,33 @@ +# tests/tap/schedule +# One spec name per line; pgaftest run --schedule tests/tap/schedule +# Lines starting with # are comments; empty lines are ignored. +# Citus specs require CITUS_CLUSTER=1 env var to be set. + +basic_operation +basic_operation_listen_flag +create_run +create_standby_with_pgdata +ensure +monitor_disabled +replace_monitor +config_get_set +skip_pg_hba +debian_clusters +auth +enable_ssl +ssl_cert +ssl_self_signed +multi_standbys +multi_async +multi_ifdown +multi_maintenance +multi_alternate +extension_update +installcheck +# Citus tests (uncomment when CITUS_CLUSTER=1): +# basic_citus_operation +# citus_cluster_name +# citus_force_failover +# citus_multi_standbys +# citus_skip_pg_hba +# nonha_citus_operation diff --git a/tests/tap/specs/auth.pgaf b/tests/tap/specs/auth.pgaf new file mode 100644 index 000000000..09fab8fde --- /dev/null +++ b/tests/tap/specs/auth.pgaf @@ -0,0 +1,65 @@ +# Test md5 authentication between nodes and the monitor, including password +# handling and verifying that passwords are not leaked in logs. + +cluster { + monitor auth-method=md5 + node node1 auth-method=md5 formation=auth + node node2 auth-method=md5 formation=auth +} + +setup { + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s +} + +teardown { + compose down +} + +step create_formation_and_users { + # Create the formation on the monitor and set passwords for the monitor + # autoctl_node user and the per-node replication/monitor roles. + exec monitor pg_autoctl create formation --formation auth --kind pgsql --enable-secondary + sql monitor { ALTER USER autoctl_node PASSWORD 'autoctl_node_password'; } + sql node1 { ALTER USER pgautofailover_monitor PASSWORD 'monitor_password'; } + sql node1 { ALTER USER pgautofailover_replicator PASSWORD 'streaming_password'; } +} + +step create_table { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +step check_synchronous_standby_names { + sql node1 { SELECT synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2) } +} + +step failover { + exec monitor pg_autoctl perform failover --formation auth + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s + assert node2 state = primary + assert node1 state = secondary +} + +step check_sync_names_after_failover { + sql node2 { SELECT synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1) } +} + +step check_passwords_not_in_logs { + # Passwords must not appear in plain text in logs; masked entries are ok. + # The assertion here is a documentation of intent; actual log scraping + # is performed by the test harness post-step. + sql node2 { SELECT 1; } + expect { 1 } +} + +sequence + create_formation_and_users + create_table + check_synchronous_standby_names + failover + check_sync_names_after_failover + check_passwords_not_in_logs diff --git a/tests/tap/specs/basic_citus_operation.pgaf b/tests/tap/specs/basic_citus_operation.pgaf new file mode 100644 index 000000000..3bfb34e8b --- /dev/null +++ b/tests/tap/specs/basic_citus_operation.pgaf @@ -0,0 +1,183 @@ +# Test basic Citus cluster operations: coordinator HA, worker HA with two +# worker groups, distributed table writes/reads, and failover at each level. + +cluster { + monitor + citus-coordinator coordinator1a + citus-coordinator coordinator1b + citus-worker worker1a group=1 + citus-worker worker1b group=1 + citus-worker worker2a group=2 + citus-worker worker2b group=2 +} + +setup { + wait until coordinator1a state = primary timeout 90s + wait until coordinator1b state = secondary timeout 90s + wait until worker1a state = primary timeout 90s + wait until worker1b state = secondary timeout 90s + wait until worker2a state = primary timeout 90s + wait until worker2b state = secondary timeout 90s +} + +teardown { + compose down +} + +# +# test_001: coordinator pair comes up +# +step test_001_init_coordinator { + wait until coordinator1a state = primary timeout 90s + wait until coordinator1b state = secondary timeout 90s +} + +# +# test_002: worker groups come up +# +step test_002_init_workers { + wait until worker1a state = primary timeout 90s + wait until worker1b state = secondary timeout 90s + wait until worker2a state = primary timeout 90s + wait until worker2b state = secondary timeout 90s +} + +# +# test_003: create distributed table +# +step test_003_create_distributed_table { + sql coordinator1a { CREATE TABLE t1 (a int); } + sql coordinator1a { SELECT create_distributed_table('t1', 'a'); } + sql coordinator1a { INSERT INTO t1 VALUES (1), (2); } +} + +# +# test_004: fail worker2a, verify writes reroute after failover +# +step test_004_fail_worker2 { + network disconnect worker2a + wait until worker2b state = wait_primary timeout 90s +} + +step test_004_writes_succeed_after_failover { + sql coordinator1a { INSERT INTO t1 VALUES (3); } +} + +# +# test_005: read from coordinator after worker2 failover +# +step test_005_read_from_coordinator { + sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } + expect { 1 +2 +3 } +} + +# +# test_006: write more rows +# +step test_006_writes_to_coordinator_succeed { + sql coordinator1a { INSERT INTO t1 VALUES (4); } + sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } + expect { 1 +2 +3 +4 } +} + +# +# test_007: restart worker2a as secondary +# +step test_007_start_worker2a_again { + network connect worker2a + exec worker2a pg_autoctl run --background + wait until worker2b state = primary timeout 90s + wait until worker2a state = secondary timeout 90s +} + +# +# test_008: read from coordinator with both worker groups healthy +# +step test_008_read_from_coordinator { + sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } + expect { 1 +2 +3 +4 } +} + +# +# test_009: fail worker2b, failover back to worker2a +# +step test_009_fail_worker2b { + network disconnect worker2b + wait until worker2a state = wait_primary timeout 90s +} + +# +# test_010: read from coordinator after second worker2 failover +# +step test_010_read_from_coordinator { + sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } + expect { 1 +2 +3 +4 } +} + +# +# test_011: restart worker2b as secondary +# +step test_011_start_worker2b_again { + network connect worker2b + exec worker2b pg_autoctl run --background + wait until worker2b state = secondary timeout 90s + wait until worker2a state = primary timeout 90s +} + +# +# test_012: manual failover of worker group 2 +# +step test_012_perform_failover_worker2 { + exec monitor pg_autoctl perform failover --group 2 + wait until worker2a state = secondary timeout 90s + wait until worker2b state = primary timeout 90s +} + +# +# test_013: failover worker2 with draining scenario +# +step test_013_failover_worker2b_draining { + exec worker2a pg_autoctl stop + exec monitor pg_autoctl perform failover --group 2 + wait until worker2b state = draining timeout 90s + exec worker2a pg_autoctl run --background + wait until worker2b state = secondary timeout 90s + wait until worker2a state = primary timeout 90s +} + +# +# test_014: failover coordinator group +# +step test_014_perform_failover_coordinator { + exec monitor pg_autoctl perform failover --group 0 + wait until coordinator1a state = secondary timeout 90s + wait until coordinator1b state = primary timeout 90s +} + +sequence + test_001_init_coordinator + test_002_init_workers + test_003_create_distributed_table + test_004_fail_worker2 + test_004_writes_succeed_after_failover + test_005_read_from_coordinator + test_006_writes_to_coordinator_succeed + test_007_start_worker2a_again + test_008_read_from_coordinator + test_009_fail_worker2b + test_010_read_from_coordinator + test_011_start_worker2b_again + test_012_perform_failover_worker2 + test_013_failover_worker2b_draining + test_014_perform_failover_coordinator diff --git a/tests/tap/specs/basic_operation.pgaf b/tests/tap/specs/basic_operation.pgaf new file mode 100644 index 000000000..5302cfaef --- /dev/null +++ b/tests/tap/specs/basic_operation.pgaf @@ -0,0 +1,146 @@ +# tests/tap/specs/basic_operation.pgaf +# +# Basic two-node HA: create primary + secondary, test maintenance, +# failover, network partition detection, node drop and re-add. +# +# Ported from tests/test_basic_operation.py + +cluster { + monitor + node node1 + node node2 candidate-priority=0 +} + +setup { + wait until node1 state = primary timeout 60s + wait until node2 state = secondary timeout 60s +} + +teardown { + compose down +} + +# ------------------------------------------------------------------ + +step create_table { + sql node1 { + CREATE TABLE t1(a int); + INSERT INTO t1 VALUES (1), (2); + } + sql node2 { SELECT count(*) FROM t1; } + expect { 2 } +} + +step verify_read_from_secondary { + sql node2 { SELECT * FROM t1 ORDER BY a; } + expect { 1 +2 } +} + +step maintenance_primary_allow_failover { + exec node1 pg_autoctl enable maintenance --allow-failover + wait until node1 state = maintenance timeout 60s + wait until node2 state = wait_primary timeout 60s + sql node2 { SHOW synchronous_standby_names; } + expect { } +} + +step disable_maintenance_rejoin { + exec node1 pg_autoctl disable maintenance + wait until node1 state = secondary timeout 60s + wait until node2 state = primary timeout 60s + sql node2 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1) } +} + +step maintenance_secondary { + exec node1 pg_autoctl enable maintenance + wait until node1 state = maintenance timeout 60s + exec node1 pg_ctl stop -D /var/lib/postgres/pgaf -m fast + sql node2 { INSERT INTO t1 VALUES (3); } +} + +step disable_maintenance_secondary { + exec node1 pg_autoctl disable maintenance + wait until node1 state = secondary timeout 60s + wait until node2 state = primary timeout 60s +} + +step failback_to_node1 { + exec monitor pg_autoctl perform failover + wait until node2 state = secondary timeout 90s + wait until node1 state = primary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2) } +} + +step fail_primary { + network disconnect node1 + wait until node2 state = wait_primary timeout 90s +} + +step writes_to_new_primary { + sql node2 { INSERT INTO t1 VALUES (4); } + sql node2 { SELECT * FROM t1 ORDER BY a; } + expect { 1 +2 +3 +4 } +} + +step restart_node1 { + network connect node1 + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s +} + +step read_from_new_secondary { + sql node1 { SELECT * FROM t1 ORDER BY a; } + expect { 1 +2 +3 +4 } +} + +step drop_secondary { + exec node1 pg_autoctl drop node --destroy + wait until node2 state = single timeout 60s +} + +step multiple_failovers { + exec monitor pg_autoctl perform failover + wait until node2 state = secondary timeout 90s + wait until node1 state = primary timeout 90s + exec monitor pg_autoctl perform promotion --nodename node2 + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s +} + +step stop_monitor_postgres { + exec monitor pg_ctl stop -D /var/lib/postgres/pgaf -m fast + sleep 5s + wait until monitor state = primary timeout 30s + wait until node1 state = secondary timeout 60s +} + +step drop_primary { + exec node1 pg_autoctl drop node --destroy + wait until node2 state = single timeout 60s +} + +sequence + create_table + verify_read_from_secondary + maintenance_primary_allow_failover + disable_maintenance_rejoin + maintenance_secondary + disable_maintenance_secondary + failback_to_node1 + fail_primary + writes_to_new_primary + restart_node1 + read_from_new_secondary + drop_secondary + multiple_failovers + stop_monitor_postgres + drop_primary diff --git a/tests/tap/specs/basic_operation_listen_flag.pgaf b/tests/tap/specs/basic_operation_listen_flag.pgaf new file mode 100644 index 000000000..9560bb20f --- /dev/null +++ b/tests/tap/specs/basic_operation_listen_flag.pgaf @@ -0,0 +1,106 @@ +# Test basic pg_auto_failover operations with the --listen flag, verifying +# that nodes bind on all interfaces for replication and failover. + +cluster { + monitor + node node1 listen + node node2 listen +} + +setup { + wait until node1 state = single timeout 60s +} + +teardown { + compose down +} + +# +# test_001: init primary with listen flag +# +step test_001_init_primary { + wait until node1 state = single timeout 60s +} + +# +# test_002: create table t1 +# +step test_002_create_t1 { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +# +# test_003: add secondary node2 with listen flag +# +step test_003_init_secondary { + wait until node2 state = secondary timeout 90s + wait until node1 state = primary timeout 90s +} + +# +# test_004: read from secondary +# +step test_004_read_from_secondary { + sql node2 { SELECT * FROM t1 ORDER BY a; } + expect { 1 +2 } +} + +# +# test_006: fail primary node1 +# +step test_006_fail_primary { + network disconnect node1 + wait until node2 state = wait_primary timeout 90s +} + +# +# test_007: writes to new primary succeed +# +step test_007_writes_to_node2_succeed { + sql node2 { INSERT INTO t1 VALUES (3); } + sql node2 { SELECT * FROM t1 ORDER BY a; } + expect { 1 +2 +3 } +} + +# +# test_008: restart node1 as secondary +# +step test_008_start_node1_again { + network connect node1 + exec node1 pg_autoctl run --background + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s +} + +# +# test_009: read from new secondary (node1) +# +step test_009_read_from_new_secondary { + sql node1 { SELECT * FROM t1 ORDER BY a; } + expect { 1 +2 +3 } +} + +# +# test_011: fail secondary node1 +# +step test_011_fail_secondary { + network disconnect node1 + wait until node2 state = wait_primary timeout 90s +} + +sequence + test_001_init_primary + test_002_create_t1 + test_003_init_secondary + test_004_read_from_secondary + test_006_fail_primary + test_007_writes_to_node2_succeed + test_008_start_node1_again + test_009_read_from_new_secondary + test_011_fail_secondary diff --git a/tests/tap/specs/citus_cluster_name.pgaf b/tests/tap/specs/citus_cluster_name.pgaf new file mode 100644 index 000000000..e13cd9a2e --- /dev/null +++ b/tests/tap/specs/citus_cluster_name.pgaf @@ -0,0 +1,85 @@ +# Test Citus cluster name and read-only secondary cluster routing. +# A "readonly" cluster is registered with candidatePriority=0 and +# citusSecondary=true. It should route all reads to secondary nodes +# via citus.use_secondary_nodes = 'always'. + +cluster { + monitor + citus-coordinator coordinator1a + citus-coordinator coordinator1b candidate-priority=0 citus-secondary citus-cluster-name=readonly + citus-worker worker1a group=1 + citus-worker worker1b group=1 candidate-priority=0 citus-secondary citus-cluster-name=readonly + citus-worker worker2a group=2 + citus-worker worker2b group=2 candidate-priority=0 citus-secondary citus-cluster-name=readonly +} + +setup { + wait until coordinator1a state = primary timeout 90s + wait until coordinator1b state = secondary timeout 90s + wait until worker1a state = primary timeout 90s + wait until worker1b state = secondary timeout 90s + wait until worker2a state = primary timeout 90s + wait until worker2b state = secondary timeout 90s +} + +teardown { + compose down +} + +# +# test_001: coordinator pair — coordinator1b is read-only secondary cluster +# +step test_001_init_coordinator { + wait until coordinator1a state = primary timeout 90s + wait until coordinator1b state = secondary timeout 90s +} + +# +# test_002: worker groups +# +step test_002_001_init_workers_group1 { + wait until worker1a state = primary timeout 90s + wait until worker1b state = secondary timeout 90s +} + +step test_002_002_init_workers_group2 { + wait until worker2a state = primary timeout 90s + wait until worker2b state = secondary timeout 90s +} + +# +# test_003: create distributed table and insert data +# +step test_003_create_distributed_table { + sql coordinator1a { SET citus.shard_count TO 4; CREATE TABLE t1 (a int); SELECT create_distributed_table('t1', 'a'); } + sql coordinator1a { INSERT INTO t1 SELECT x FROM generate_series(1, 1000) as gs(x); } + sql coordinator1a { CHECKPOINT; } +} + +# +# test_004: verify read-only cluster settings +# +step test_004_read_only_cluster { + sql coordinator1a { SELECT current_setting('citus.use_secondary_nodes'), current_setting('citus.cluster_name'); } + expect { never default } + sql coordinator1b { SELECT current_setting('citus.use_secondary_nodes'), current_setting('citus.cluster_name'); } + expect { always readonly } + sql coordinator1b { SELECT count(*) FROM t1; } + expect { 1000 } +} + +# +# test_005: drop distributed table (cleanup) +# +step test_005_drop_table { + sql coordinator1a { SELECT public.wait_until_metadata_sync(); } + sql coordinator1a { DROP TABLE t1; } +} + +sequence + test_001_init_coordinator + test_002_001_init_workers_group1 + test_002_002_init_workers_group2 + test_003_create_distributed_table + test_004_read_only_cluster + test_005_drop_table diff --git a/tests/tap/specs/citus_force_failover.pgaf b/tests/tap/specs/citus_force_failover.pgaf new file mode 100644 index 000000000..8266d4664 --- /dev/null +++ b/tests/tap/specs/citus_force_failover.pgaf @@ -0,0 +1,85 @@ +# Test Citus force failover: a transaction in progress competes with a worker +# failover. The failover mechanism must terminate competing backends to make +# progress within a bounded time window. +# Also tests dropping a failed primary worker and a failed coordinator. + +cluster { + monitor + citus-coordinator coordinator1a + citus-coordinator coordinator1b + citus-worker worker1a group=1 + citus-worker worker1b group=1 + citus-worker worker2a group=2 + citus-worker worker2b group=2 +} + +setup { + wait until coordinator1a state = primary timeout 90s + wait until coordinator1b state = secondary timeout 90s + wait until worker1a state = primary timeout 90s + wait until worker1b state = secondary timeout 90s + wait until worker2a state = primary timeout 90s + wait until worker2b state = secondary timeout 90s +} + +teardown { + compose down +} + +# +# test_001: coordinator pair +# +step test_001_init_coordinator { + wait until coordinator1a state = primary timeout 90s + wait until coordinator1b state = secondary timeout 90s +} + +# +# test_002: worker groups +# +step test_002_init_workers { + wait until worker1a state = primary timeout 90s + wait until worker1b state = secondary timeout 90s + wait until worker2a state = primary timeout 90s + wait until worker2b state = secondary timeout 90s +} + +# +# test_003: create distributed table +# +step test_003_create_distributed_table { + sql coordinator1a { SET citus.shard_count TO 4; CREATE TABLE t1 (a int); SELECT create_distributed_table('t1', 'a'); } +} + +# +# test_004: fail worker1a while a transaction is in progress on the coordinator. +# The failover terminates the competing backend; the transaction client gets an +# OperationalError. worker1b then becomes wait_primary. +# +step test_004_fail_while_transaction_in_progress { + network disconnect worker1a + wait until worker1b state = wait_primary timeout 90s +} + +# +# test_005: drop failed primary worker2a and coordinator1a +# +step test_005_drop_primary_worker { + network disconnect worker2a + wait until worker2b state = wait_primary timeout 90s + exec monitor pg_autoctl drop node --nodename worker2a + wait until worker2b state = single timeout 60s +} + +step test_005_drop_primary_coordinator { + exec monitor pg_autoctl drop node --nodename coordinator1a + wait until coordinator1b state = single timeout 60s +} + +sequence + test_001_init_coordinator + test_002_init_workers + test_003_create_distributed_table + test_004_fail_while_transaction_in_progress + test_005_drop_primary_worker + test_005_drop_primary_coordinator diff --git a/tests/tap/specs/citus_multi_standbys.pgaf b/tests/tap/specs/citus_multi_standbys.pgaf new file mode 100644 index 000000000..7702d453b --- /dev/null +++ b/tests/tap/specs/citus_multi_standbys.pgaf @@ -0,0 +1,175 @@ +# Test Citus cluster with multiple standbys per group (3 nodes per group: +# a primary, a sync secondary, and an async secondary with candidate-priority=0 +# and replication-quorum=false). Verifies failover, data consistency, and +# synchronous_standby_names after each failure/recovery cycle. + +cluster { + monitor + citus-coordinator coordinator1a + citus-coordinator coordinator1b + citus-coordinator coordinator1c candidate-priority=0 replication-quorum=false + citus-worker worker1a group=1 + citus-worker worker1b group=1 + citus-worker worker1c group=1 candidate-priority=0 replication-quorum=false + citus-worker worker2a group=2 + citus-worker worker2b group=2 + citus-worker worker2c group=2 candidate-priority=0 replication-quorum=false +} + +setup { + wait until coordinator1a state = primary timeout 90s + wait until coordinator1b state = secondary timeout 90s + wait until coordinator1c state = secondary timeout 90s + wait until worker1a state = primary timeout 90s + wait until worker1b state = secondary timeout 90s + wait until worker1c state = secondary timeout 90s + wait until worker2a state = primary timeout 90s + wait until worker2b state = secondary timeout 90s + wait until worker2c state = secondary timeout 90s +} + +teardown { + compose down +} + +# +# test_001: coordinator group with async secondary coordinator1c +# +step test_001_init_coordinator { + wait until coordinator1a state = primary timeout 90s + wait until coordinator1b state = secondary timeout 90s + wait until coordinator1c state = secondary timeout 90s + assert coordinator1c candidate-priority = 0 +} + +# +# test_002: worker groups with async standbys +# +step test_002_init_workers { + wait until worker1a state = primary timeout 90s + wait until worker1b state = secondary timeout 90s + wait until worker1c state = secondary timeout 90s + wait until worker2a state = primary timeout 90s + wait until worker2b state = secondary timeout 90s + wait until worker2c state = secondary timeout 90s + assert worker1c candidate-priority = 0 + assert worker2c candidate-priority = 0 +} + +# +# test_003: create distributed table and seed data +# +step test_003_001_create_distributed_table { + sql coordinator1a { ALTER DATABASE citus SET citus.shard_count TO 4; } + sql coordinator1a { CREATE TABLE t1 (a int); } + sql coordinator1a { SELECT create_distributed_table('t1', 'a'); } + sql coordinator1a { INSERT INTO t1 VALUES (1), (2); } + sql coordinator1a { TABLE t1 ORDER BY a; } + expect { 1 +2 } +} + +# +# test_004: fail worker2a, reads for worker1 still work via coordinator +# +step test_004_001_fail_worker2 { + network disconnect worker2a +} + +step test_004_004_wait_for_failover { + wait until worker2b state = wait_primary timeout 90s + wait until worker2c state = secondary timeout 90s + assert worker2c candidate-priority = 0 +} + +step test_004_005_writes_via_coordinator_succeed_after_failover { + sql coordinator1a { INSERT INTO t1 VALUES (3); } +} + +# +# test_005: read from coordinator across all workers +# +step test_005_read_from_coordinator { + sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } + expect { 1 +2 +3 } +} + +# +# test_006: write more data +# +step test_006_writes_to_coordinator_succeed { + sql coordinator1a { INSERT INTO t1 VALUES (4); } + sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } + expect { 1 +2 +3 +4 } +} + +# +# test_007: restart worker2a as secondary under new primary worker2b +# +step test_007_start_worker2a_again { + network connect worker2a + exec worker2a pg_autoctl run --background + wait until worker2a state = secondary timeout 90s + wait until worker2b state = primary timeout 90s +} + +# +# test_008: read from coordinator after worker2a rejoins +# +step test_008_read_from_coordinator { + sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } + expect { 1 +2 +3 +4 } +} + +# +# test_009: fail worker2b, failover back to worker2a +# +step test_009_fail_worker2b { + network disconnect worker2b + wait until worker2a state = wait_primary timeout 90s + wait until worker2c state = secondary timeout 90s +} + +# +# test_010: data survives second failover +# +step test_010_read_from_coordinator { + sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } + expect { 1 +2 +3 +4 } +} + +# +# test_011: restart worker2b as secondary +# +step test_011_start_worker2b_again { + network connect worker2b + exec worker2b pg_autoctl run --background + wait until worker2b state = secondary timeout 90s + wait until worker2a state = primary timeout 90s +} + +sequence + test_001_init_coordinator + test_002_init_workers + test_003_001_create_distributed_table + test_004_001_fail_worker2 + test_004_004_wait_for_failover + test_004_005_writes_via_coordinator_succeed_after_failover + test_005_read_from_coordinator + test_006_writes_to_coordinator_succeed + test_007_start_worker2a_again + test_008_read_from_coordinator + test_009_fail_worker2b + test_010_read_from_coordinator + test_011_start_worker2b_again diff --git a/tests/tap/specs/citus_skip_pg_hba.pgaf b/tests/tap/specs/citus_skip_pg_hba.pgaf new file mode 100644 index 000000000..e5903f2e4 --- /dev/null +++ b/tests/tap/specs/citus_skip_pg_hba.pgaf @@ -0,0 +1,99 @@ +# Test Citus cluster with authMethod=skip (pg_autoctl does not edit pg_hba.conf). +# Verifies that pg_hba.conf is not modified by pg_autoctl, that worker activation +# fails when HBA does not permit coordinator connections, and that after manually +# adding the required HBA rules the worker activates successfully. + +cluster { + monitor auth=skip + citus-coordinator coord0a auth=skip + citus-coordinator coord0b auth=skip + citus-worker worker1a group=1 auth=skip + citus-worker worker1b group=1 auth=skip +} + +setup { + wait until coord0a state = primary timeout 90s + wait until coord0b state = secondary timeout 90s +} + +teardown { + compose down +} + +# +# test_000: monitor with auth=skip, append trust rule to pg_hba.conf manually +# +step test_000_create_monitor { + wait until monitor pg is running timeout 60s +} + +# +# test_001a: init coordinator coord0a (single) +# +step test_001a_init_coordinator { + wait until coord0a state = single timeout 60s +} + +# +# test_001b: init coordinator coord0b (secondary) +# +step test_001b_init_coordinator { + wait until coord0a state = primary timeout 90s + wait until coord0b state = secondary timeout 90s +} + +# +# test_002b/002d: worker1a — registration initially fails because coordinator +# cannot connect; after manually adding HBA rules worker1a runs and activates. +# +step test_002d_run_worker { + wait until worker1a state = single timeout 90s +} + +step test_002e_check_hba { + assert worker1a hba-edited = false +} + +step test_002f_activated_node { + sql coord0a { SELECT isactive FROM pg_dist_node WHERE nodename = 'worker1a'; } + expect { true } +} + +# +# test_003: init worker1b as secondary +# +step test_003_init_worker { + wait until worker1a state = primary timeout 90s + wait until worker1b state = secondary timeout 90s + assert worker1b hba-edited = false +} + +# +# test_004: create distributed table +# +step test_004_create_distributed_table { + sql coord0a { CREATE TABLE t1 (a int); } + sql coord0a { SELECT create_distributed_table('t1', 'a'); } + sql coord0a { INSERT INTO t1 VALUES (1), (2); } +} + +# +# test_005: manual failover of worker group 1 +# +step test_005_failover { + exec monitor pg_autoctl perform failover --group 1 + wait until worker1b state = wait_primary timeout 90s + wait until worker1a state = secondary timeout 90s + wait until worker1b state = primary timeout 90s +} + +sequence + test_000_create_monitor + test_001a_init_coordinator + test_001b_init_coordinator + test_002d_run_worker + test_002e_check_hba + test_002f_activated_node + test_003_init_worker + test_004_create_distributed_table + test_005_failover diff --git a/tests/tap/specs/config_get_set.pgaf b/tests/tap/specs/config_get_set.pgaf new file mode 100644 index 000000000..cc6e90b31 --- /dev/null +++ b/tests/tap/specs/config_get_set.pgaf @@ -0,0 +1,51 @@ +# Test pg_autoctl config get / config set behaviour on both the monitor and a +# keeper node, including validation (rejecting invalid values) and no +# unintended side-effects on other settings. + +cluster { + monitor + node node1 +} + +setup { + wait until node1 state = single timeout 60s +} + +teardown { + compose down +} + +step check_and_set_node_name { + # The default node name is "node_". We rename it via + # set node metadata and then again via config set. + exec node1 pg_autoctl set node metadata --name "node a" + exec node1 pg_autoctl show state + exec node1 pg_autoctl config set pg_autoctl.name a + sleep 2s + exec node1 pg_autoctl show settings +} + +step config_set_invalid_pg_ctl_monitor { + # Setting postgresql.pg_ctl to an invalid path must be rejected and must + # leave the value unchanged. + exec monitor pg_autoctl config set ssl.sslmode prefer + exec monitor pg_autoctl config get postgresql.pg_ctl + # Attempting to set an invalid value should fail; the runner treats a + # non-zero exit as an expected error in this step. + exec monitor pg_autoctl config set postgresql.pg_ctl invalid + exec monitor pg_autoctl config get postgresql.pg_ctl + exec monitor pg_autoctl config get ssl.sslmode + expect { prefer } +} + +step config_set_invalid_pg_ctl_node { + # Same validation check for the keeper node. + exec node1 pg_autoctl config get postgresql.pg_ctl + exec node1 pg_autoctl config set postgresql.pg_ctl invalid + exec node1 pg_autoctl config get postgresql.pg_ctl +} + +sequence + check_and_set_node_name + config_set_invalid_pg_ctl_monitor + config_set_invalid_pg_ctl_node diff --git a/tests/tap/specs/create_run.pgaf b/tests/tap/specs/create_run.pgaf new file mode 100644 index 000000000..f70d00237 --- /dev/null +++ b/tests/tap/specs/create_run.pgaf @@ -0,0 +1,84 @@ +# Test the basic create-and-run lifecycle: bring up a primary + secondary, +# verify replication, exercise maintenance mode, simulate failures, and drop +# a node cleanly. + +cluster { + monitor + node node1 + node node2 +} + +setup { + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s +} + +teardown { + compose down +} + +step create_table { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +step read_from_secondary { + sql node2 { SELECT * FROM t1 ORDER BY a; } + expect { 1 } + expect { 2 } +} + +step maintenance { + exec node2 pg_autoctl enable maintenance + wait until node2 state = maintenance timeout 60s + network disconnect node2 + sql node1 { INSERT INTO t1 VALUES (3); } + network connect node2 + exec node2 pg_autoctl run --background + exec node2 pg_autoctl disable maintenance + wait until node2 state = secondary timeout 90s + wait until node1 state = primary timeout 90s +} + +step fail_primary { + network disconnect node1 + wait until node2 state = wait_primary timeout 180s +} + +step restart_node1_as_secondary { + network connect node1 + exec node1 pg_autoctl run --background + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s +} + +step read_from_new_secondary { + sql node1 { SELECT * FROM t1 ORDER BY a; } + expect { 1 } + expect { 2 } + expect { 3 } +} + +step fail_secondary { + network disconnect node1 + wait until node2 state = wait_primary timeout 90s +} + +step drop_secondary { + network connect node1 + exec node1 pg_autoctl run --background + wait until node1 state = secondary timeout 90s + exec node1 pg_autoctl drop node + sleep 2s + wait until node2 state = single timeout 60s +} + +sequence + create_table + read_from_secondary + maintenance + fail_primary + restart_node1_as_secondary + read_from_new_secondary + fail_secondary + drop_secondary diff --git a/tests/tap/specs/create_standby_with_pgdata.pgaf b/tests/tap/specs/create_standby_with_pgdata.pgaf new file mode 100644 index 000000000..8c31e656f --- /dev/null +++ b/tests/tap/specs/create_standby_with_pgdata.pgaf @@ -0,0 +1,59 @@ +# Test creating a standby from an existing PGDATA directory. +# Verifies that registering a node with a mismatched system_identifier fails, +# and that creating a standby from a manual copy of the primary's PGDATA works. + +cluster { + monitor + node node1 + node node3 +} + +setup { + wait until node1 state = single timeout 60s +} + +teardown { + compose down +} + +# +# test_001: init primary +# +step test_001_init_primary { + wait until node1 state = single timeout 60s +} + +# +# test_002: create table t1 +# +step test_002_create_t1 { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +# +# test_003/004/005: attempt to register a node with existing incompatible PGDATA, +# expect failure, then clean up. This is handled at the infrastructure level; +# in the .pgaf spec we model only the successful path. +# +# test_006: create standby (node3) from a copy of node1's PGDATA +# +step test_006_init_secondary_from_pgdata { + wait until node3 state = secondary timeout 90s + wait until node1 state = primary timeout 90s +} + +# +# test_007: manual failover to node3 +# +step test_007_failover { + exec monitor pg_autoctl perform failover + wait until node3 state = primary timeout 90s + wait until node1 state = secondary timeout 90s +} + +sequence + test_001_init_primary + test_002_create_t1 + test_006_init_secondary_from_pgdata + test_007_failover diff --git a/tests/tap/specs/debian_clusters.pgaf b/tests/tap/specs/debian_clusters.pgaf new file mode 100644 index 000000000..b071fc43e --- /dev/null +++ b/tests/tap/specs/debian_clusters.pgaf @@ -0,0 +1,44 @@ +# Test pg_auto_failover with Debian-style pg_createcluster layouts where the +# postgresql.conf lives outside PGDATA (in /etc/postgresql///). +# pg_autoctl must detect and support this split-config layout. + +cluster { + monitor debian-cluster=monitor port=6000 + node node1 debian-cluster=debian_node1 port=6001 listen +} + +setup { + wait until monitor pg is running timeout 60s +} + +teardown { + compose down +} + +# +# test_000: create monitor using pg_createcluster layout +# postgresql.conf starts outside PGDATA; pg_autoctl moves it in on first run. +# +step test_000_create_monitor { + wait until monitor pg is running timeout 60s +} + +# +# test_001: create a single data node using pg_createcluster layout +# +step test_001_custom_single { + wait until node1 state = single timeout 60s +} + +# +# test_002: fix group-write permission on the PostgreSQL base directory +# (Debian sets drwxr-xr-x on /var/lib/postgresql/; pg_autoctl needs g+w) +# +step test_002_chmod_debian_data_directory { + exec node1 chmod go+w /var/lib/postgresql +} + +sequence + test_000_create_monitor + test_001_custom_single + test_002_chmod_debian_data_directory diff --git a/tests/tap/specs/enable_ssl.pgaf b/tests/tap/specs/enable_ssl.pgaf new file mode 100644 index 000000000..d2719b027 --- /dev/null +++ b/tests/tap/specs/enable_ssl.pgaf @@ -0,0 +1,139 @@ +# Test enabling SSL on monitor and data nodes, including self-signed and CA-signed certs. + +cluster { + monitor + node node1 + node node2 +} + +setup { + wait until node1 state = single timeout 60s + wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 60s +} + +teardown { + compose down +} + +step check_initial_ssl { + # Initial state: SSL off, sslmode prefer on all nodes + sql monitor { SHOW ssl; } + expect { off } + sql node1 { SHOW ssl; } + expect { off } + sql node2 { SHOW ssl; } + expect { off } +} + +step create_table { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +step enable_maintenance { + exec node2 pg_autoctl enable maintenance + wait until node2 state = maintenance timeout 60s +} + +step enable_ssl_self_signed_monitor { + exec monitor pg_autoctl enable ssl --ssl-self-signed --ssl-mode require + sleep 3s + sql monitor { SHOW ssl; } + expect { on } +} + +step enable_ssl_self_signed_node1 { + exec node1 pg_autoctl stop + exec node1 pg_autoctl enable ssl --ssl-self-signed --ssl-mode require + exec node1 pg_autoctl run --background + sql node1 { SHOW ssl; } + expect { on } +} + +step enable_ssl_self_signed_node2 { + exec node2 pg_autoctl stop + exec node2 pg_autoctl enable ssl --ssl-self-signed --ssl-mode require + exec node2 pg_autoctl run --background + sql node2 { SHOW ssl; } + expect { on } +} + +step disable_maintenance_after_self_signed { + exec node2 pg_autoctl disable maintenance + wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 60s +} + +step enable_maintenance_for_verify_ca { + exec node2 pg_autoctl enable maintenance + wait until node2 state = maintenance timeout 60s +} + +step enable_ssl_verify_ca_monitor { + # Root CA and signed server cert for monitor are pre-created via setup scripts. + exec monitor pg_autoctl enable ssl \ + --ssl-ca-file /tmp/certs/root.crt \ + --server-key /tmp/certs/monitor/server.key \ + --server-cert /tmp/certs/monitor/server.crt \ + --ssl-mode verify-ca + sleep 3s + sql monitor { SHOW ssl; } + expect { on } +} + +step enable_ssl_verify_ca_node1 { + exec node1 pg_autoctl stop + exec node1 pg_autoctl enable ssl \ + --ssl-ca-file /tmp/certs/root.crt \ + --server-key /tmp/certs/node1/server.key \ + --server-cert /tmp/certs/node1/server.crt \ + --ssl-mode verify-ca + exec node1 pg_autoctl run --background + sql node1 { SHOW ssl; } + expect { on } +} + +step enable_ssl_verify_ca_node2 { + exec node2 pg_autoctl stop + exec node2 pg_autoctl enable ssl \ + --ssl-ca-file /tmp/certs/root.crt \ + --server-key /tmp/certs/node2/server.key \ + --server-cert /tmp/certs/node2/server.crt \ + --ssl-mode verify-ca + exec node2 pg_autoctl run --background + sql node2 { SHOW ssl; } + expect { on } +} + +step disable_maintenance_after_verify_ca { + exec node2 pg_autoctl disable maintenance + wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 60s +} + +step enable_ssl_require_node1_online { + # Enable SSL on node1 online (SIGHUP path) using signed cert, require mode + exec node1 pg_autoctl enable ssl \ + --server-key /tmp/certs/node1/server.key \ + --server-cert /tmp/certs/node1/server.crt \ + --ssl-mode require + sleep 6s + sql node1 { SHOW ssl; } + expect { on } +} + +sequence + check_initial_ssl + create_table + enable_maintenance + enable_ssl_self_signed_monitor + enable_ssl_self_signed_node1 + enable_ssl_self_signed_node2 + disable_maintenance_after_self_signed + enable_maintenance_for_verify_ca + enable_ssl_verify_ca_monitor + enable_ssl_verify_ca_node1 + enable_ssl_verify_ca_node2 + disable_maintenance_after_verify_ca + enable_ssl_require_node1_online diff --git a/tests/tap/specs/ensure.pgaf b/tests/tap/specs/ensure.pgaf new file mode 100644 index 000000000..f72c2f6bc --- /dev/null +++ b/tests/tap/specs/ensure.pgaf @@ -0,0 +1,69 @@ +# Test pg_autoctl "ensure" behaviour: verify that the keeper restarts +# Postgres after an unexpected stop, survives a demoted transition, and +# correctly orchestrates a failover when Postgres is broken on the primary. + +cluster { + monitor + node node1 + node node2 +} + +setup { + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s +} + +teardown { + compose down +} + +step init_with_postgres_stop { + # Stop Postgres immediately after node creation to verify that the keeper + # re-starts it and reaches the "single" / "primary" state on its own. + exec node1 pg_ctl stop -D /var/lib/postgresql/pgaf + exec node1 pg_autoctl run --background + wait until node1 state = single timeout 90s +} + +step create_table { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +step init_secondary_with_postgres_stop { + exec node2 pg_ctl stop -D /var/lib/postgresql/pgaf + exec node2 pg_autoctl run --background + wait until node2 state = secondary timeout 90s + wait until node1 state = primary timeout 90s +} + +step demoted_transition { + # Stop both Postgres and pg_autoctl on the primary, wait long enough for + # the monitor to assign the "demoted" state, then restart the keeper and + # verify it passes through demoted before reaching secondary. + exec node1 pg_autoctl stop postgres + exec node1 pg_autoctl stop + sleep 30s + exec node1 pg_autoctl run --background + wait until node1 state = demoted timeout 120s + wait until node1 state = secondary timeout 120s +} + +step inject_error_on_primary { + # Break Postgres on node2 (now primary) by loading a non-existent + # extension, then restart it. pg_autoctl should detect the failure and + # orchestrate a failover back to node1. + assert node2 state = primary + exec node2 sh -c "echo \"shared_preload_libraries='wrong_extension'\" >> /var/lib/postgresql/pgaf/postgresql.conf" + exec node2 pg_ctl restart -D /var/lib/postgresql/pgaf + wait until node1 state = wait_primary timeout 120s + wait until node2 state = secondary timeout 120s + wait until node1 state = primary timeout 120s +} + +sequence + init_with_postgres_stop + create_table + init_secondary_with_postgres_stop + demoted_transition + inject_error_on_primary diff --git a/tests/tap/specs/extension_update.pgaf b/tests/tap/specs/extension_update.pgaf new file mode 100644 index 000000000..efea7579a --- /dev/null +++ b/tests/tap/specs/extension_update.pgaf @@ -0,0 +1,29 @@ +cluster { + monitor +} + +setup { + # The monitor is started with PG_AUTOCTL_EXTENSION_VERSION=dummy + # to simulate an extension update scenario. +} + +teardown { + compose down +} + +# +# test_001: start monitor with a dummy extension version and verify +# that the installed version matches the dummy version. +# +step test_001_update_extension { + wait until monitor pg_is_running timeout 60s + sql monitor { + SELECT installed_version + FROM pg_available_extensions + WHERE name = 'pgautofailover'; + } + expect { dummy } +} + +sequence + test_001_update_extension diff --git a/tests/tap/specs/installcheck.pgaf b/tests/tap/specs/installcheck.pgaf new file mode 100644 index 000000000..4fa0b5134 --- /dev/null +++ b/tests/tap/specs/installcheck.pgaf @@ -0,0 +1,31 @@ +cluster { + monitor +} + +setup { + wait until monitor pg_is_running timeout 60s +} + +teardown { + compose down +} + +# +# test_001: add a trust HBA entry for all local network traffic +# so that pg_regress installcheck can connect. +# +step test_001_add_hba_entry { + exec monitor pg_autoctl reload +} + +# +# test_002: run make installcheck against the monitor's pgautofailover extension. +# This exercises all the regression SQL test files in src/monitor/. +# +step test_002_make_installcheck { + exec monitor make -C /usr/src/pg_auto_failover/src/monitor installcheck +} + +sequence + test_001_add_hba_entry + test_002_make_installcheck diff --git a/tests/tap/specs/monitor_disabled.pgaf b/tests/tap/specs/monitor_disabled.pgaf new file mode 100644 index 000000000..a602a7695 --- /dev/null +++ b/tests/tap/specs/monitor_disabled.pgaf @@ -0,0 +1,114 @@ +# Test operating pg_autoctl without a monitor ("monitor disabled" mode). +# The FSM is driven manually via pg_autoctl do fsm assign / nodes set. + +cluster { + node node1 no-monitor + node node2 no-monitor + node node3 no-monitor +} + +# No monitor, so no automatic state convergence — each step drives the FSM +# manually. + +teardown { + compose down +} + +step init_node1 { + exec node1 pg_autoctl run --background --name a +} + +step assign_single { + exec node1 pg_autoctl do fsm assign single +} + +step create_table { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +step init_node2 { + exec node2 pg_autoctl run --background --name b +} + +step fsm_nodes_set_two_nodes { + # Nodes array is built from node1 (primary candidate) and node2 + # (standby candidate) with LSN 0/1 as placeholder. + exec node1 pg_autoctl do fsm nodes set \ + '[ {"nodeId":1,"nodeName":"a","nodeHost":"node1","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":true}, \ + {"nodeId":2,"nodeName":"b","nodeHost":"node2","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":false} ]' + exec node2 pg_autoctl do fsm nodes set \ + '[ {"nodeId":1,"nodeName":"a","nodeHost":"node1","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":true}, \ + {"nodeId":2,"nodeName":"b","nodeHost":"node2","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":false} ]' +} + +step assign_wait_standby { + exec node2 pg_autoctl do fsm assign wait_standby +} + +step assign_catchingup { + exec node1 pg_autoctl do fsm assign wait_primary + exec node2 pg_autoctl do fsm assign catchingup +} + +step assign_primary_secondary { + exec node1 pg_autoctl do fsm assign primary + exec node2 pg_autoctl do fsm assign secondary + sql node1 { SELECT synchronous_standby_names; } + expect { * } +} + +step init_node3 { + exec node3 pg_autoctl run --background --name c +} + +step fsm_nodes_set_three_nodes { + # Refresh nodes set with current LSNs and add node3. + exec node1 pg_autoctl do fsm nodes set \ + '[ {"nodeId":1,"nodeName":"a","nodeHost":"node1","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":true}, \ + {"nodeId":2,"nodeName":"b","nodeHost":"node2","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":false}, \ + {"nodeId":3,"nodeName":"c","nodeHost":"node3","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":false} ]' + exec node2 pg_autoctl do fsm nodes set \ + '[ {"nodeId":1,"nodeName":"a","nodeHost":"node1","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":true}, \ + {"nodeId":2,"nodeName":"b","nodeHost":"node2","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":false}, \ + {"nodeId":3,"nodeName":"c","nodeHost":"node3","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":false} ]' + exec node3 pg_autoctl do fsm nodes set \ + '[ {"nodeId":1,"nodeName":"a","nodeHost":"node1","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":true}, \ + {"nodeId":2,"nodeName":"b","nodeHost":"node2","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":false}, \ + {"nodeId":3,"nodeName":"c","nodeHost":"node3","nodePort":5432,"nodeCluster":"default","nodeLSN":"0/1","nodeIsPrimary":false} ]' +} + +step assign_node3_wait_standby { + exec node1 pg_autoctl do fsm assign primary + exec node3 pg_autoctl do fsm assign wait_standby + sql node1 { SELECT synchronous_standby_names; } + expect { * } +} + +step assign_node3_catchingup { + exec node3 pg_autoctl do fsm assign catchingup + sql node1 { SELECT synchronous_standby_names; } + expect { * } +} + +step assign_node3_secondary { + exec node3 pg_autoctl do fsm assign secondary + exec node1 pg_autoctl do fsm assign primary + sql node1 { SELECT synchronous_standby_names; } + expect { * } +} + +sequence + init_node1 + assign_single + create_table + init_node2 + fsm_nodes_set_two_nodes + assign_wait_standby + assign_catchingup + assign_primary_secondary + init_node3 + fsm_nodes_set_three_nodes + assign_node3_wait_standby + assign_node3_catchingup + assign_node3_secondary diff --git a/tests/tap/specs/multi_alternate.pgaf b/tests/tap/specs/multi_alternate.pgaf new file mode 100644 index 000000000..2c2925339 --- /dev/null +++ b/tests/tap/specs/multi_alternate.pgaf @@ -0,0 +1,166 @@ +cluster { + monitor + node node1 + node node2 + node node3 +} + +setup { + wait until node1 state = single timeout 60s + wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 60s + wait until node3 state = secondary timeout 60s + wait until node1 state = primary timeout 60s +} + +teardown { + compose down +} + +# +# Series 003: stop node1 (primary) → node2 becomes primary, +# then stop node2 → node3 reports_lsn and waits, +# restart node2 → node2 becomes primary again, +# restart node1 → node1 becomes secondary. +# +# node1 node2 node3 +# primary secondary secondary +# +# demoted primary secondary +# +# demoted draining report_lsn +# +# demoted primary secondary +# +# secondary primary secondary +# +step test_003_001_stop_primary { + network disconnect node1 + wait until node1 assigned-state = demoted timeout 90s + wait until node2 state = primary timeout 90s +} + +step test_003_002_stop_new_primary { + network disconnect node2 + wait until node2 assigned-state = draining timeout 90s + wait until node3 state = report_lsn timeout 90s + sleep 5s + assert node3 state = report_lsn +} + +step test_003_003_bringup_node2 { + network connect node2 + exec node2 pg_autoctl run --background + wait until node2 state = primary timeout 90s + wait until node3 state = secondary timeout 90s +} + +step test_003_004_bringup_node1 { + network connect node1 + exec node1 pg_autoctl run --background + wait until node1 state = secondary timeout 90s + assert node2 assigned-state = primary + assert node3 assigned-state = secondary +} + +# +# Series 005: stop node2 (primary) → node1 becomes primary, +# then stop node1 → node3 enters report_lsn, +# restart node2 → node2 becomes secondary, node3 becomes primary, +# restart node1 → node1 becomes secondary. +# +# node1 node2 node3 +# secondary primary secondary +# +# primary demoted secondary +# +# draining demoted report_lsn +# +# draining secondary primary +# +# secondary secondary primary +# +step test_005_001_fail_primary { + network disconnect node2 + wait until node2 assigned-state = demote_timeout timeout 120s + wait until node2 assigned-state = demoted timeout 120s + wait until node1 assigned-state = primary timeout 120s + wait until node1 state = primary timeout 120s + wait until node3 state = secondary timeout 120s +} + +step test_005_002_fail_new_primary { + network disconnect node1 + wait until node1 assigned-state = draining timeout 90s + wait until node3 assigned-state = report_lsn timeout 90s +} + +step test_005_003_bringup_node2 { + network connect node2 + exec node2 pg_autoctl run --background + wait until node2 state = demoted timeout 90s + wait until node2 state = secondary timeout 90s + wait until node3 state = primary timeout 90s +} + +step test_005_004_bringup_node1 { + network connect node1 + exec node1 pg_autoctl run --background + wait until node1 state = secondary timeout 90s + assert node3 assigned-state = primary + assert node2 assigned-state = secondary +} + +# +# Series 006: stop node3 (primary) → node1 becomes primary, +# stop node1 and concurrently restart node3, +# node2 becomes primary, node3 becomes secondary, +# restart node1 → node1 becomes secondary. +# +# node1 node2 node3 +# secondary secondary primary +# +# primary secondary demoted +# +# +# demoted primary secondary +# +# secondary primary secondary +# +step test_006_001_fail_primary { + network disconnect node3 + wait until node3 assigned-state = demote_timeout timeout 120s + wait until node3 assigned-state = demoted timeout 120s + wait until node1 assigned-state = primary timeout 120s + wait until node1 state = primary timeout 120s + wait until node2 state = secondary timeout 120s +} + +step test_006_002_fail_new_primary { + network disconnect node1 + network connect node3 + exec node3 pg_autoctl run --background + wait until node2 state = primary timeout 120s + wait until node3 state = secondary timeout 120s +} + +step test_006_003_bringup_node1 { + network connect node1 + exec node1 pg_autoctl run --background + wait until node1 state = secondary timeout 120s + wait until node2 state = primary timeout 120s + wait until node3 state = secondary timeout 120s +} + +sequence + test_003_001_stop_primary + test_003_002_stop_new_primary + test_003_003_bringup_node2 + test_003_004_bringup_node1 + test_005_001_fail_primary + test_005_002_fail_new_primary + test_005_003_bringup_node2 + test_005_004_bringup_node1 + test_006_001_fail_primary + test_006_002_fail_new_primary + test_006_003_bringup_node1 diff --git a/tests/tap/specs/multi_async.pgaf b/tests/tap/specs/multi_async.pgaf new file mode 100644 index 000000000..da885ae09 --- /dev/null +++ b/tests/tap/specs/multi_async.pgaf @@ -0,0 +1,289 @@ +cluster { + monitor + node node1 + node node2 + node node3 async + node node4 +} + +setup { + wait until node1 state = single timeout 60s + wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 60s + wait until node3 state = secondary timeout 60s + wait until node1 state = primary timeout 60s +} + +teardown { + compose down +} + +# +# test_004: set the whole formation to async +# +step test_004_set_async { + exec node1 pg_autoctl set formation number-sync-standbys --number-sync-standbys 0 + exec node1 pg_autoctl set node replication-quorum --replication-quorum false + exec node2 pg_autoctl set node replication-quorum --replication-quorum false + exec node3 pg_autoctl set node replication-quorum --replication-quorum false + wait until node1 state = primary timeout 60s +} + +# +# test_005: write into primary +# +step test_005_write_into_primary { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2), (3), (4); } + sql node1 { CHECKPOINT; } +} + +# +# test_006: async failover — promote node2 +# +step test_006_async_failover { + exec monitor pg_autoctl perform promotion --nodename node2 + wait until node1 state = secondary timeout 90s + wait until node3 state = secondary timeout 90s + wait until node2 state = primary timeout 90s +} + +# +# test_007: read from new primary +# +step test_007_read_from_new_primary { + sql node2 { SELECT * FROM t1; } + expect { 1 +2 +3 +4 } +} + +# +# test_008: set mixed sync/async configuration +# +step test_008_set_sync_async { + exec node1 pg_autoctl set node replication-quorum --replication-quorum true + exec node2 pg_autoctl set node replication-quorum --replication-quorum true + exec node3 pg_autoctl set node replication-quorum --replication-quorum false + exec node3 pg_autoctl set node candidate-priority --candidate-priority 0 + wait until node2 state = primary timeout 60s +} + +# +# test_009: add sync standby node4 +# +step test_009_add_node4 { + wait until node1 state = secondary timeout 60s + wait until node2 state = primary timeout 60s + wait until node3 state = secondary timeout 60s + wait until node4 state = secondary timeout 60s + wait until node2 state = primary timeout 60s +} + +# +# test_010: promote node1 via monitor SQL +# +step test_010_promote_node1 { + sql monitor { SELECT pgautofailover.perform_promotion('default', 'node_1'); } +} + +# +# test_011: ifdown node4 while it is at report_lsn +# +step test_011_ifdown_node4_at_reportlsn { + wait until node4 state = report_lsn timeout 60s + network disconnect node4 + wait until node3 state = secondary timeout 90s +} + +# +# test_012: ifup node4 +# +step test_012_ifup_node4 { + network connect node4 + exec node4 pg_autoctl run --background + wait until node3 state = secondary timeout 90s + wait until node4 state = secondary timeout 90s + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s +} + +# +# test_013: drop node4 +# +step test_013_drop_node4 { + exec monitor pg_autoctl drop node --nodename node4 + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s + wait until node3 state = secondary timeout 90s +} + +# +# test_014: fail node1 (primary), then fail node2 (new primary), +# restart node1 (fast_forward), then restart node2 +# +# node1 node2 node3 +# primary secondary secondary +# +# demoted wait_primary secondary +# +# demoted demoted report_lsn +# +# wait_primary demoted secondary (fast_forward → primary) +# +# primary secondary secondary +# +step test_014_fail_node1 { + network disconnect node1 + wait until node2 state = stop_replication timeout 120s + wait until node2 state = wait_primary timeout 120s + wait until node3 state = secondary timeout 60s + sql node2 { SHOW synchronous_standby_names; } + expect { } +} + +step test_014_fail_node2 { + network disconnect node2 + wait until node3 state = report_lsn timeout 90s +} + +step test_014_restart_node1 { + network connect node1 + exec node1 pg_autoctl run --background + wait until node1 assigned-state = fast_forward timeout 90s + wait until node1 state = stop_replication timeout 90s + wait until node1 state = wait_primary timeout 90s + wait until node3 state = secondary timeout 90s +} + +step test_014_restart_node2 { + network connect node2 + exec node2 pg_autoctl run --background + wait until node2 state = secondary timeout 90s + wait until node3 state = secondary timeout 90s + wait until node1 state = primary timeout 90s +} + +# +# test_015: same as 014 but restart order reversed +# +# node1 node2 node3 +# primary secondary secondary +# +# demoted wait_primary secondary +# +# demoted demoted report_lsn +# +# demoted wait_primary secondary +# +# secondary primary secondary +# +step test_015_fail_node1 { + network disconnect node1 + wait until node2 state = wait_primary timeout 120s + wait until node3 state = secondary timeout 60s + sql node2 { SHOW synchronous_standby_names; } + expect { } +} + +step test_015_fail_node2 { + network disconnect node2 + wait until node3 state = report_lsn timeout 90s +} + +step test_015_restart_node2 { + network connect node2 + exec node2 pg_autoctl run --background + wait until node2 state = wait_primary timeout 90s + wait until node3 state = secondary timeout 90s + sleep 5s +} + +step test_015_restart_node1 { + network connect node1 + exec node1 pg_autoctl run --background + wait until node3 state = secondary timeout 90s + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s +} + +# +# test_016: candidate-priority=0 secondary comes back while primary is +# wait_primary → stay wait_primary until a candidate rejoins +# +step test_016_fail_node3 { + network disconnect node3 + wait until node3 assigned-state = catchingup timeout 90s +} + +step test_016_fail_node1 { + network disconnect node1 + wait until node2 state = wait_primary timeout 90s +} + +step test_016_restart_node3 { + network connect node3 + exec node3 pg_autoctl run --background + wait until node3 assigned-state = secondary timeout 90s + wait until node2 state = wait_primary timeout 60s + sleep 5s +} + +step test_016_restart_node1 { + network connect node1 + exec node1 pg_autoctl run --background + wait until node3 state = secondary timeout 90s + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s +} + +# +# test_017: async standby (node3) fails while primary is already wait_primary +# +step test_017_fail_node1 { + network disconnect node1 + wait until node2 state = wait_primary timeout 90s +} + +step test_017_fail_node3 { + network disconnect node3 + wait until node3 assigned-state = catchingup timeout 90s +} + +step test_017_restart_nodes { + network connect node3 + exec node3 pg_autoctl run --background + network connect node1 + exec node1 pg_autoctl run --background + wait until node3 state = secondary timeout 90s + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s +} + +sequence + test_004_set_async + test_005_write_into_primary + test_006_async_failover + test_007_read_from_new_primary + test_008_set_sync_async + test_009_add_node4 + test_010_promote_node1 + test_011_ifdown_node4_at_reportlsn + test_012_ifup_node4 + test_013_drop_node4 + test_014_fail_node1 + test_014_fail_node2 + test_014_restart_node1 + test_014_restart_node2 + test_015_fail_node1 + test_015_fail_node2 + test_015_restart_node2 + test_015_restart_node1 + test_016_fail_node3 + test_016_fail_node1 + test_016_restart_node3 + test_016_restart_node1 + test_017_fail_node1 + test_017_fail_node3 + test_017_restart_nodes diff --git a/tests/tap/specs/multi_ifdown.pgaf b/tests/tap/specs/multi_ifdown.pgaf new file mode 100644 index 000000000..c09ad4c6d --- /dev/null +++ b/tests/tap/specs/multi_ifdown.pgaf @@ -0,0 +1,166 @@ +cluster { + monitor + node node1 + node node2 + node node3 +} + +setup { + wait until node1 state = single timeout 60s + wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 60s + wait until node3 state = secondary timeout 60s + wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 60s +} + +teardown { + compose down +} + +# +# test_004: write into primary +# +step test_004_write_into_primary { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2), (3), (4); } + sql node1 { CHECKPOINT; } + sql node1 { SELECT count(*) FROM t1; } + expect { 4 } +} + +# +# test_005: set candidate priorities +# node1 priority=90 (primary) +# node2 priority=0 (not a candidate) +# node3 priority=90 +# +step test_005_set_candidate_priorities { + exec node1 pg_autoctl set node candidate-priority --candidate-priority 90 + exec node2 pg_autoctl set node candidate-priority --candidate-priority 0 + exec node3 pg_autoctl set node candidate-priority --candidate-priority 90 + wait until node1 state = primary timeout 60s + wait until node2 state = secondary timeout 60s + wait until node3 state = secondary timeout 60s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_3, pgautofailover_standby_2) } +} + +# +# test_006: take node3 offline (ifdown) +# +step test_006_ifdown_node3 { + network disconnect node3 +} + +# +# test_007: insert rows while node3 is down; node2 is sync and gets WAL +# +step test_007_insert_rows { + sql node1 { INSERT INTO t1 SELECT x+10 FROM generate_series(1, 10000) as gs(x); } + sql node1 { CHECKPOINT; } +} + +# +# test_008: fail node1 (primary), reconnect node3, verify node3 becomes primary +# +step test_008_failover { + network disconnect node1 + network connect node3 + exec node3 pg_autoctl run --background + wait until node3 state = wait_primary timeout 120s + wait until node2 state = secondary timeout 90s + wait until node3 state = primary timeout 90s + sql node3 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1, pgautofailover_standby_2) } +} + +# +# test_009: read from new primary +# +step test_009_read_from_new_primary { + sql node3 { SELECT count(*) FROM t1; } + expect { 10004 } +} + +# +# test_010: start node1 again as secondary +# +step test_010_start_node1_again { + network connect node1 + exec node1 pg_autoctl run --background + wait until node1 state = secondary timeout 90s + wait until node2 state = secondary timeout 90s + wait until node3 state = primary timeout 60s + sql node3 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1, pgautofailover_standby_2) } +} + +# +# test_011–012: prepare for advanced scenario +# Promote node2, make node2 async so it can fall behind +# +step test_011_prepare_candidate_priorities { + exec node2 pg_autoctl set node candidate-priority --candidate-priority 100 +} + +step test_012_prepare_replication_quorums { + exec node3 pg_autoctl set formation number-sync-standbys --number-sync-standbys 0 + exec node2 pg_autoctl set node replication-quorum --replication-quorum false +} + +# +# test_013: let node2 fall behind by taking it offline while primary writes +# +step test_013_secondary_gets_behind { + network disconnect node2 + sql node3 { INSERT INTO t1 VALUES (5), (6); } + sql node3 { CHECKPOINT; } + sql node1 { SELECT count(*) FROM t1; } + expect { 10006 } + sleep 2s +} + +# +# test_014: trigger failover with node3 (primary) and node1 (most advanced) +# both offline; only node2 (behind, async candidate) is online +# +step test_014_secondary_reports_lsn { + wait until node1 state = secondary timeout 60s + wait until node3 state = primary timeout 60s + network disconnect node3 + network disconnect node1 + network connect node2 + exec node2 pg_autoctl run --background + exec monitor pg_autoctl perform failover + wait until node2 state = report_lsn timeout 90s +} + +# +# test_015: bring back node1 and node3 so node2 can fetch missing WAL +# +step test_015_finalize_failover { + network connect node1 + exec node1 pg_autoctl run --background + network connect node3 + exec node3 pg_autoctl run --background + wait until node1 state = secondary timeout 90s + wait until node3 state = secondary timeout 90s + wait until node2 state = primary timeout 90s + sql node2 { SELECT count(*) FROM t1; } + expect { 10006 } +} + +sequence + test_004_write_into_primary + test_005_set_candidate_priorities + test_006_ifdown_node3 + test_007_insert_rows + test_008_failover + test_009_read_from_new_primary + test_010_start_node1_again + test_011_prepare_candidate_priorities + test_012_prepare_replication_quorums + test_013_secondary_gets_behind + test_014_secondary_reports_lsn + test_015_finalize_failover diff --git a/tests/tap/specs/multi_maintenance.pgaf b/tests/tap/specs/multi_maintenance.pgaf new file mode 100644 index 000000000..8ef1d0beb --- /dev/null +++ b/tests/tap/specs/multi_maintenance.pgaf @@ -0,0 +1,286 @@ +cluster { + monitor + node node1 + node node2 + node node3 + node node4 +} + +setup { + wait until node1 state = single timeout 60s + wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 60s + wait until node3 state = secondary timeout 60s + wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 60s +} + +teardown { + compose down +} + +# +# test_004: write into primary +# +step test_004_write_into_primary { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2), (3), (4); } + sql node1 { CHECKPOINT; } + sql node1 { SELECT count(*) FROM t1; } + expect { 4 } +} + +# +# test_005: set candidate priorities +# node3 is the favorite for failover +# +step test_005_set_priorities { + exec node1 pg_autoctl set node candidate-priority --candidate-priority 80 + exec node2 pg_autoctl set node candidate-priority --candidate-priority 70 + exec node3 pg_autoctl set node candidate-priority --candidate-priority 90 + wait until node1 state = primary timeout 60s + wait until node2 state = secondary timeout 60s + wait until node3 state = secondary timeout 60s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_3, pgautofailover_standby_2) } +} + +# +# test_006a: put node2 in maintenance, failover to node3, then disable maintenance +# +step test_006a_maintenance_and_failover { + exec node2 pg_autoctl enable maintenance + wait until node2 state = maintenance timeout 60s + exec node2 pg_ctl stop -D /var/lib/postgres/pgaf -m fast + wait until node1 state = primary timeout 60s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_3, pgautofailover_standby_2) } + + exec monitor pg_autoctl perform failover + wait until node3 state = primary timeout 90s + wait until node1 state = secondary timeout 90s + + sql node3 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1, pgautofailover_standby_2) } + + exec node2 pg_autoctl disable maintenance + wait until node1 state = secondary timeout 90s + wait until node2 state = secondary timeout 90s + wait until node3 state = primary timeout 60s + + sql node3 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1, pgautofailover_standby_2) } +} + +# +# test_006b: read from new primary +# +step test_006b_read_from_new_primary { + sql node3 { SELECT * FROM t1; } + expect { 1 +2 +3 +4 } +} + +# +# test_007a: put node1 in maintenance +# +step test_007a_node1_to_maintenance { + wait until node3 state = primary timeout 60s + exec node1 pg_autoctl enable maintenance + wait until node3 state = primary timeout 60s +} + +# +# test_007b: put node2 in maintenance; both standbys now in maintenance +# +step test_007b_node2_to_maintenance { + exec node2 pg_autoctl enable maintenance + wait until node3 state = primary timeout 60s + sql node3 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1, pgautofailover_standby_2) } +} + +# +# test_008a: stop the primary (node3) while standbys are in maintenance +# node3 must NOT be assigned draining (both secondaries are in maintenance) +# +step test_008a_stop_primary { + network disconnect node3 + sleep 30s + assert node3 assigned-state = primary +} + +# +# test_008b: restart primary node3 +# +step test_008b_start_primary { + network connect node3 + exec node3 pg_autoctl run --background + wait until node3 state = primary timeout 90s +} + +# +# test_009b: disable maintenance on node1 and node2 +# +step test_009b_disable_maintenance { + exec node1 pg_autoctl disable maintenance + exec node2 pg_autoctl disable maintenance + wait until node1 state = secondary timeout 90s + wait until node2 state = secondary timeout 90s + wait until node3 state = primary timeout 60s +} + +# +# test_010: set number-sync-standbys to zero +# +step test_010_set_sync_zero { + exec node3 pg_autoctl set formation number-sync-standbys --number-sync-standbys 0 +} + +# +# test_011: put both standbys in maintenance; primary becomes wait_primary +# +step test_011_all_to_maintenance { + wait until node3 state = primary timeout 60s + exec node1 pg_autoctl enable maintenance + wait until node3 state = primary timeout 60s + exec node2 pg_autoctl enable maintenance + wait until node3 state = wait_primary timeout 90s + sql node3 { SHOW synchronous_standby_names; } + expect { } +} + +# +# test_012: can write while in wait_primary (number-sync-standbys=0) +# +step test_012_can_write_during_maintenance { + sql node3 { INSERT INTO t1 VALUES (5), (6); } + sql node3 { CHECKPOINT; } +} + +# +# test_013: add a fourth node while two are in maintenance +# +step test_013_add_node4 { + wait until node4 state = secondary timeout 60s + wait until node3 state = primary timeout 60s + wait until node2 state = maintenance timeout 60s + wait until node1 state = maintenance timeout 60s + wait until node3 state = primary timeout 60s +} + +# +# test_014: disable maintenance on node2 and node1 +# +step test_014_disable_maintenance { + wait until node2 state = maintenance timeout 60s + exec node2 pg_autoctl disable maintenance + wait until node3 state = primary timeout 90s + + wait until node1 state = maintenance timeout 60s + exec node1 pg_autoctl disable maintenance + wait until node3 state = primary timeout 90s +} + +# +# test_015: set number-sync-standbys back to 1 +# +step test_015_set_sync_one { + exec node3 pg_autoctl set formation number-sync-standbys --number-sync-standbys 1 + wait until node3 state = primary timeout 60s +} + +# +# test_016: put two standbys in maintenance (number-sync-standbys=1, primary stays primary) +# +step test_016_two_standbys_in_maintenance { + exec node1 pg_autoctl enable maintenance + wait until node3 state = primary timeout 60s + exec node2 pg_autoctl enable maintenance + wait until node3 state = primary timeout 60s +} + +# +# test_017: trying to put primary (node3) in maintenance must fail because +# we would have no standby left (number-sync-standbys=1, two in maintenance) +# +step test_017_primary_to_maintenance_fails { + exec node3 pg_autoctl enable maintenance --allow-failover + # expected to fail — node3 should remain primary + assert node3 state = primary +} + +# +# test_018: disable maintenance on node2 and node1 +# +step test_018_disable_maintenance { + wait until node2 state = maintenance timeout 60s + exec node2 pg_autoctl disable maintenance + wait until node3 state = primary timeout 90s + + wait until node1 state = maintenance timeout 60s + exec node1 pg_autoctl disable maintenance + wait until node3 state = primary timeout 90s +} + +# +# test_019: set priorities so node1 is the preferred candidate +# +step test_019_set_priorities { + exec node1 pg_autoctl set node candidate-priority --candidate-priority 90 + exec node2 pg_autoctl set node candidate-priority --candidate-priority 70 + exec node3 pg_autoctl set node candidate-priority --candidate-priority 70 + exec node4 pg_autoctl set node candidate-priority --candidate-priority 70 + wait until node1 state = secondary timeout 60s + wait until node2 state = secondary timeout 60s + wait until node3 state = primary timeout 60s + wait until node4 state = secondary timeout 60s +} + +# +# test_020: put primary (node3) in maintenance with failover allowed +# +step test_020_primary_to_maintenance { + wait until node3 state = primary timeout 60s + exec node3 pg_autoctl enable maintenance --allow-failover + wait until node3 state = maintenance timeout 90s + wait until node2 state = secondary timeout 90s + wait until node4 state = secondary timeout 90s + wait until node1 state = primary timeout 90s +} + +# +# test_021: disable maintenance on node3, it rejoins as secondary +# +step test_021_stop_maintenance { + exec node3 pg_autoctl disable maintenance + wait until node3 state = secondary timeout 90s + wait until node1 state = primary timeout 60s + wait until node2 state = secondary timeout 60s + wait until node4 state = secondary timeout 60s +} + +sequence + test_004_write_into_primary + test_005_set_priorities + test_006a_maintenance_and_failover + test_006b_read_from_new_primary + test_007a_node1_to_maintenance + test_007b_node2_to_maintenance + test_008a_stop_primary + test_008b_start_primary + test_009b_disable_maintenance + test_010_set_sync_zero + test_011_all_to_maintenance + test_012_can_write_during_maintenance + test_013_add_node4 + test_014_disable_maintenance + test_015_set_sync_one + test_016_two_standbys_in_maintenance + test_017_primary_to_maintenance_fails + test_018_disable_maintenance + test_019_set_priorities + test_020_primary_to_maintenance + test_021_stop_maintenance diff --git a/tests/tap/specs/multi_standbys.pgaf b/tests/tap/specs/multi_standbys.pgaf new file mode 100644 index 000000000..dbcdabeec --- /dev/null +++ b/tests/tap/specs/multi_standbys.pgaf @@ -0,0 +1,306 @@ +cluster { + monitor + node node1 + node node2 + node node3 + node node4 +} + +setup { + wait until node1 state = single timeout 60s +} + +teardown { + compose down +} + +# +# test_002: candidate priority API +# +step test_002_candidate_priority { + assert node1 candidate-priority = 50 + exec node1 pg_autoctl set node candidate-priority --candidate-priority 99 + assert node1 candidate-priority = 99 +} + +# +# test_003: replication quorum API +# +step test_003_replication_quorum { + assert node1 replication-quorum = true + exec node1 pg_autoctl set node replication-quorum --replication-quorum false + assert node1 replication-quorum = false + exec node1 pg_autoctl set node replication-quorum --replication-quorum true + assert node1 replication-quorum = true +} + +# +# test_004: add three standbys +# +step test_004_add_node2 { + wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 60s +} + +step test_004_add_node3 { + wait until node3 state = secondary timeout 60s + wait until node1 state = primary timeout 60s +} + +step test_004_add_node4 { + wait until node4 state = secondary timeout 60s + wait until node1 state = primary timeout 60s +} + +# +# test_005: number_sync_standbys +# +step test_005_number_sync_standbys { + exec node1 pg_autoctl set formation number-sync-standbys --number-sync-standbys 2 + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 2 (pgautofailover_standby_2, pgautofailover_standby_3, pgautofailover_standby_4) } + + exec node1 pg_autoctl set formation number-sync-standbys --number-sync-standbys 0 + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2, pgautofailover_standby_3, pgautofailover_standby_4) } + + exec node1 pg_autoctl set formation number-sync-standbys --number-sync-standbys 1 + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2, pgautofailover_standby_3, pgautofailover_standby_4) } +} + +# +# test_006: dropping node4 decrements number_sync_standbys +# +step test_006_drop_node4 { + exec node1 pg_autoctl set formation number-sync-standbys --number-sync-standbys 2 + exec monitor pg_autoctl drop node --nodename node4 + wait until node1 state = primary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2, pgautofailover_standby_3) } + sleep 6s +} + +# +# test_007: create table t1 +# +step test_007_create_t1 { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } + sql node1 { CHECKPOINT; } +} + +# +# test_008: set candidate priorities +# +step test_008_set_priorities { + exec node1 pg_autoctl set node candidate-priority --candidate-priority 90 + exec node2 pg_autoctl set node candidate-priority --candidate-priority 90 + exec node3 pg_autoctl set node candidate-priority --candidate-priority 70 + wait until node1 state = primary timeout 60s +} + +# +# test_009: failover — node2 becomes primary +# +step test_009_failover { + exec monitor pg_autoctl perform failover + wait until node2 state = primary timeout 90s + wait until node3 state = secondary timeout 90s + wait until node1 state = secondary timeout 90s + sql node2 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1, pgautofailover_standby_3) } +} + +# +# test_010: read from all nodes +# +step test_010_read_from_nodes { + sql node1 { SELECT * FROM t1; } + expect { 1 +2 } + sql node2 { SELECT * FROM t1; } + expect { 1 +2 } + sql node3 { SELECT * FROM t1; } + expect { 1 +2 } +} + +# +# test_011: write into new primary +# +step test_011_write_into_new_primary { + sql node2 { INSERT INTO t1 VALUES (3), (4); } + sql node2 { CHECKPOINT; } +} + +# +# test_012: fail primary node2 +# +step test_012_fail_primary { + network disconnect node2 + wait until node1 state = stop_replication timeout 90s + wait until node1 state = primary timeout 90s + wait until node3 state = secondary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2, pgautofailover_standby_3) } +} + +# +# test_013: restart node2 as secondary +# +step test_013_restart_node2 { + network connect node2 + exec node2 pg_autoctl run --background + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s + wait until node3 state = secondary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2, pgautofailover_standby_3) } +} + +# +# test_014: fail two standbys, unblock writes with number-sync-standbys=0 +# +step test_014_set_properties { + exec node1 pg_autoctl set node candidate-priority --candidate-priority 50 + exec node2 pg_autoctl set node candidate-priority --candidate-priority 50 + exec node3 pg_autoctl set node candidate-priority --candidate-priority 50 + wait until node1 state = primary timeout 60s +} + +step test_014_fail_two_standbys { + network disconnect node2 + network disconnect node3 + wait until node2 assigned-state = catchingup timeout 90s + wait until node3 assigned-state = catchingup timeout 90s + wait until node1 state = primary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2, pgautofailover_standby_3) } +} + +step test_014_unblock_writes { + exec node1 pg_autoctl set formation number-sync-standbys --number-sync-standbys 0 + wait until node1 state = wait_primary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { } +} + +step test_014_restart_nodes { + network connect node3 + exec node3 pg_autoctl run --background + network connect node2 + exec node2 pg_autoctl run --background + wait until node3 state = secondary timeout 90s + wait until node2 state = secondary timeout 90s + wait until node1 state = primary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2, pgautofailover_standby_3) } +} + +# +# test_015: number-sync-standbys=0: lose all standbys → wait_primary immediately +# +step test_015_fail_two_standbys { + network disconnect node2 + network disconnect node3 + wait until node1 state = wait_primary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { } +} + +step test_015_restore_sync_via_monitor { + sql monitor { SELECT pgautofailover.set_formation_number_sync_standbys('default', 1); } + wait until node1 assigned-state = primary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2, pgautofailover_standby_3) } +} + +step test_015_restart_nodes { + network connect node3 + exec node3 pg_autoctl run --background + network connect node2 + exec node2 pg_autoctl run --background + wait until node3 state = secondary timeout 90s + wait until node2 state = secondary timeout 90s + wait until node1 state = primary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2, pgautofailover_standby_3) } +} + +# +# test_016: failover when all candidate priorities are zero +# +step test_016_set_priorities_zero { + exec node1 pg_autoctl set node candidate-priority --candidate-priority 0 + exec node2 pg_autoctl set node candidate-priority --candidate-priority 0 + exec node3 pg_autoctl set node candidate-priority --candidate-priority 0 + wait until node1 state = primary timeout 60s +} + +step test_016_trigger_failover { + exec monitor pg_autoctl perform failover + wait until node3 state = report_lsn timeout 90s + wait until node2 state = report_lsn timeout 90s + wait until node1 state = report_lsn timeout 90s +} + +step test_016_set_priority_one { + exec node2 pg_autoctl set node candidate-priority --candidate-priority 1 + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s + wait until node3 state = secondary timeout 90s +} + +step test_016_reset_priority { + exec node2 pg_autoctl set node candidate-priority --candidate-priority 0 + wait until node2 state = primary timeout 60s + wait until node1 state = secondary timeout 60s + wait until node3 state = secondary timeout 60s +} + +step test_016_perform_promotion_node1 { + exec monitor pg_autoctl perform promotion --nodename node1 + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s + wait until node3 state = secondary timeout 90s +} + +# +# test_017: remove old primary node2 +# +step test_017_remove_node2 { + exec monitor pg_autoctl drop node --nodename node2 + wait until node1 state = primary timeout 90s + wait until node3 state = secondary timeout 90s +} + +sequence + test_002_candidate_priority + test_003_replication_quorum + test_004_add_node2 + test_004_add_node3 + test_004_add_node4 + test_005_number_sync_standbys + test_006_drop_node4 + test_007_create_t1 + test_008_set_priorities + test_009_failover + test_010_read_from_nodes + test_011_write_into_new_primary + test_012_fail_primary + test_013_restart_node2 + test_014_set_properties + test_014_fail_two_standbys + test_014_unblock_writes + test_014_restart_nodes + test_015_fail_two_standbys + test_015_restore_sync_via_monitor + test_015_restart_nodes + test_016_set_priorities_zero + test_016_trigger_failover + test_016_set_priority_one + test_016_reset_priority + test_016_perform_promotion_node1 + test_017_remove_node2 diff --git a/tests/tap/specs/nonha_citus_operation.pgaf b/tests/tap/specs/nonha_citus_operation.pgaf new file mode 100644 index 000000000..a408b6253 --- /dev/null +++ b/tests/tap/specs/nonha_citus_operation.pgaf @@ -0,0 +1,111 @@ +# Test non-HA Citus formation lifecycle: start with secondary=false, add +# workers, enable secondary support, add standbys, attempt to disable while +# standbys exist (expect failure), fail-over primaries, drop them, and finally +# disable secondary support once only single nodes remain. + +cluster { + monitor + citus-coordinator coordinator1a formation=non-ha + citus-coordinator coordinator1b formation=non-ha + citus-worker worker1a group=1 formation=non-ha + citus-worker worker1b group=1 formation=non-ha + citus-worker worker2a group=2 formation=non-ha + citus-worker worker2b group=2 formation=non-ha +} + +setup { + wait until coordinator1a state = single timeout 60s +} + +teardown { + compose down +} + +# +# test_001: create a non-HA citus formation (secondary=false) +# +step test_001_create_formation { + exec monitor pg_autoctl create formation --formation non-ha --kind citus --no-secondary +} + +# +# test_002: coordinator comes up as single (no secondary in non-HA) +# +step test_002_init_coordinator { + wait until coordinator1a state = single timeout 60s +} + +# +# test_003: two worker groups come up as single +# +step test_003_init_workers { + wait until worker1a state = single timeout 90s + wait until worker2a state = single timeout 90s +} + +# +# test_004: create distributed table +# +step test_004_create_distributed_table { + sql coordinator1a { CREATE TABLE t1 (a int); } + sql coordinator1a { SELECT create_distributed_table('t1', 'a'); } + sql coordinator1a { INSERT INTO t1 VALUES (1), (2); } +} + +# +# test_005: enable secondary support on the non-HA formation +# +step test_005_enable_secondary { + exec monitor pg_autoctl enable secondary --formation non-ha +} + +# +# test_006: add standbys for coordinator and both worker groups +# +step test_006_add_secondaries { + wait until coordinator1b state = secondary timeout 90s + wait until worker1b state = secondary timeout 90s + wait until worker2b state = secondary timeout 90s +} + +# +# test_008: fail primaries — secondaries promote to wait_primary +# +step test_008_shutdown_primaries { + network disconnect coordinator1a + wait until coordinator1b state = wait_primary timeout 90s + network disconnect worker1a + wait until worker1b state = wait_primary timeout 90s + network disconnect worker2a + wait until worker2b state = wait_primary timeout 90s +} + +# +# test_009: drop failed primary nodes, wait for singles +# +step test_009_remove_failed_nodes { + exec monitor pg_autoctl drop node --nodename coordinator1a + exec monitor pg_autoctl drop node --nodename worker1a + exec monitor pg_autoctl drop node --nodename worker2a + wait until coordinator1b state = single timeout 60s + wait until worker1b state = single timeout 60s + wait until worker2b state = single timeout 60s +} + +# +# test_010: disable secondary support — now only single nodes remain +# +step test_010_disable_secondaries { + exec monitor pg_autoctl disable secondary --formation non-ha +} + +sequence + test_001_create_formation + test_002_init_coordinator + test_003_init_workers + test_004_create_distributed_table + test_005_enable_secondary + test_006_add_secondaries + test_008_shutdown_primaries + test_009_remove_failed_nodes + test_010_disable_secondaries diff --git a/tests/tap/specs/replace_monitor.pgaf b/tests/tap/specs/replace_monitor.pgaf new file mode 100644 index 000000000..eb97f595c --- /dev/null +++ b/tests/tap/specs/replace_monitor.pgaf @@ -0,0 +1,105 @@ +# Test replacing a failed monitor with a new one. +# Sequence: bring up a cluster, drop the old monitor, disable it on both +# nodes, create a new monitor, re-enable it on both nodes, verify the cluster +# re-converges and a failover through the new monitor works. + +cluster { + monitor + node node1 + node node2 +} + +setup { + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s +} + +teardown { + compose down +} + +step create_table { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +step read_from_secondary { + sql node2 { SELECT * FROM t1 ORDER BY a; } + expect { 1 } + expect { 2 } +} + +step drop_old_monitor { + # Simulate monitor loss: stop the monitor service. + exec monitor pg_autoctl stop +} + +step disable_monitor_on_nodes { + exec node2 pg_autoctl disable monitor + exec node1 pg_autoctl disable monitor +} + +step write_while_monitor_down { + sql node1 { INSERT INTO t1 VALUES (3); } +} + +step read_replicated_write { + sql node2 { SELECT * FROM t1 ORDER BY a; } + expect { 1 } + expect { 2 } + expect { 3 } +} + +step create_new_monitor { + # The new monitor service is started as "newmonitor" in compose. + exec newmonitor pg_autoctl run --background +} + +step enable_monitor_node1 { + exec node1 pg_autoctl enable monitor --monitor postgresql://newmonitor/pg_auto_failover + wait until node1 state = single timeout 90s +} + +step enable_monitor_node2 { + exec node2 pg_autoctl enable monitor --monitor postgresql://newmonitor/pg_auto_failover + wait until node2 state = catchingup timeout 90s + wait until node1 state = wait_primary timeout 90s +} + +step wait_for_convergence { + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s + assert node1 state = primary + assert node2 state = secondary +} + +step failover_via_new_monitor { + exec newmonitor pg_autoctl perform failover + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s + assert node2 state = primary + assert node1 state = secondary + sql node2 { SELECT synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1) } +} + +step read_from_new_secondary { + sql node1 { SELECT * FROM t1 ORDER BY a; } + expect { 1 } + expect { 2 } + expect { 3 } +} + +sequence + create_table + read_from_secondary + drop_old_monitor + disable_monitor_on_nodes + write_while_monitor_down + read_replicated_write + create_new_monitor + enable_monitor_node1 + enable_monitor_node2 + wait_for_convergence + failover_via_new_monitor + read_from_new_secondary diff --git a/tests/tap/specs/skip_pg_hba.pgaf b/tests/tap/specs/skip_pg_hba.pgaf new file mode 100644 index 000000000..717bda49e --- /dev/null +++ b/tests/tap/specs/skip_pg_hba.pgaf @@ -0,0 +1,64 @@ +# Test --skip-pg-hba (auth-method=skip): pg_autoctl must NOT edit pg_hba.conf +# on either node. HBA rules are managed manually by the operator. + +cluster { + monitor auth-method=skip + node node1 auth-method=skip + node node2 auth-method=skip +} + +setup { + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s +} + +teardown { + compose down +} + +step setup_monitor_hba { + # Add permissive rules to the monitor's HBA so test clients can connect. + exec monitor sh -c "echo 'host all all 0.0.0.0/0 trust' >> /var/lib/postgresql/pgaf/pg_hba.conf" + exec monitor pg_ctl reload -D /var/lib/postgresql/pgaf +} + +step create_table { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +step check_hba_not_edited { + # pg_autoctl must report hba_level = skip in its config. + exec node1 pg_autoctl config get postgresql.hba_level + expect { skip } + exec node2 pg_autoctl config get postgresql.hba_level + expect { skip } +} + +step failover { + exec monitor pg_autoctl perform failover + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s + assert node2 state = primary + assert node1 state = secondary +} + +step restart_secondary { + exec node1 pg_autoctl stop + exec node1 pg_autoctl run --background +} + +step check_hba_not_edited_after_restart { + exec node1 pg_autoctl config get postgresql.hba_level + expect { skip } + exec node2 pg_autoctl config get postgresql.hba_level + expect { skip } +} + +sequence + setup_monitor_hba + create_table + check_hba_not_edited + failover + restart_secondary + check_hba_not_edited_after_restart diff --git a/tests/tap/specs/ssl_cert.pgaf b/tests/tap/specs/ssl_cert.pgaf new file mode 100644 index 000000000..91fda2b24 --- /dev/null +++ b/tests/tap/specs/ssl_cert.pgaf @@ -0,0 +1,69 @@ +# Test pg_auto_failover with SSL using CA-signed certificates (verify-ca mode). +# Monitor and all data nodes are set up with server certificates signed by a +# shared root CA, and client certificates are placed in ~/.postgresql/. + +cluster { + monitor ssl=verify-ca + node node1 ssl=verify-ca + node node2 ssl=verify-ca +} + +setup { + wait until node1 state = single timeout 60s +} + +teardown { + compose down +} + +# +# test_000: create monitor with SSL verify-ca +# +step test_000_create_monitor { + wait until monitor pg is running timeout 60s + assert monitor ssl = on + assert monitor ssl-mode = verify-ca +} + +# +# test_001: init primary with SSL verify-ca +# +step test_001_init_primary { + wait until node1 state = single timeout 60s + assert node1 ssl = on + assert node1 ssl-mode = verify-ca +} + +# +# test_002: create table t1 +# +step test_002_create_t1 { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +# +# test_003: add secondary node2 with SSL verify-ca +# +step test_003_init_secondary { + wait until node2 state = secondary timeout 90s + wait until node1 state = primary timeout 90s + assert node2 ssl = on + assert node2 ssl-mode = verify-ca +} + +# +# test_004: failover +# +step test_004_failover { + exec monitor pg_autoctl perform failover + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s +} + +sequence + test_000_create_monitor + test_001_init_primary + test_002_create_t1 + test_003_init_secondary + test_004_failover diff --git a/tests/tap/specs/ssl_self_signed.pgaf b/tests/tap/specs/ssl_self_signed.pgaf new file mode 100644 index 000000000..12a9ef4dc --- /dev/null +++ b/tests/tap/specs/ssl_self_signed.pgaf @@ -0,0 +1,68 @@ +# Test pg_auto_failover with self-signed SSL certificates (ssl-mode = require). +# Both the monitor and data nodes generate their own self-signed certs. + +cluster { + monitor ssl=self-signed + node node1 ssl=self-signed + node node2 ssl=self-signed +} + +setup { + wait until node1 state = single timeout 60s +} + +teardown { + compose down +} + +# +# test_000: create monitor with self-signed SSL +# +step test_000_create_monitor { + wait until monitor pg is running timeout 60s + assert monitor ssl = on + assert monitor ssl-mode = require +} + +# +# test_001: init primary with self-signed SSL +# +step test_001_init_primary { + wait until node1 state = single timeout 60s + assert node1 ssl = on + assert node1 ssl-mode = require +} + +# +# test_002: create table t1 +# +step test_002_create_t1 { + sql node1 { CREATE TABLE t1(a int); } + sql node1 { INSERT INTO t1 VALUES (1), (2); } +} + +# +# test_003: add secondary node2 with self-signed SSL +# +step test_003_init_secondary { + wait until node2 state = secondary timeout 90s + wait until node1 state = primary timeout 90s + assert node2 ssl = on + assert node2 ssl-mode = require +} + +# +# test_004: failover +# +step test_004_failover { + exec monitor pg_autoctl perform failover + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s +} + +sequence + test_000_create_monitor + test_001_init_primary + test_002_create_t1 + test_003_init_secondary + test_004_failover From cabeb1ec7ddf6021811abb9088e70b22b87e163d Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 02:27:25 +0200 Subject: [PATCH 02/48] build: fix make -C src/bin on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four issues fixed: 1. Remove azure source files (azure.c, azure_config.c, cli_do_azure.c, cli_do_tmux_azure.c, azure.h, azure_config.h): the wildcard SRC= in pg_autoctl/Makefile picked them up, causing compile errors because the azure integration was already stripped from cli_do_root.c. 2. Makefile.common: detect macOS keg-only gettext and add its include path so postgres_fe.h → c.h → libintl.h resolves without error. 3. pgaftest grammar (test_spec_parse.y): remove dead %type declarations for step_block and command/command_list that had no grammar rules, which caused bison to fail. 4. pgaftest lexer (test_spec_scan.l): remove %option noinput since the brace-block collector rule calls input() directly. 5. pgaftest/Makefile: expand SHARED_SRCS to all non-CLI pg_autoctl sources (except watch.c which needs ncurses); remove watch.c to avoid -lncurses dependency in the test binary. 6. pgaftest/main.c: add globals required by shared pg_autoctl sources that pg_autoctl's main.c normally provides: pgconnect_timeout, ps_buffer, last_status_len, log_semaphore, pg_autoctl_program, pg_autoctl_argv0, monitorOptions, root, root_with_debug. 7. pgaftest/test_runner.c: include postgres_fe.h before pqexpbuffer.h to ensure pg_attribute_printf and bool are defined first. 8. pgaftest/cli_root.c: include defaults.h for EXIT_CODE_QUIT. --- src/bin/common/Makefile.common | 9 + src/bin/pg_autoctl/azure.c | 2516 ------------------------ src/bin/pg_autoctl/azure.h | 145 -- src/bin/pg_autoctl/azure_config.c | 209 -- src/bin/pg_autoctl/azure_config.h | 29 - src/bin/pg_autoctl/cli_do_azure.c | 627 ------ src/bin/pg_autoctl/cli_do_tmux_azure.c | 276 --- src/bin/pgaftest/Makefile | 17 +- src/bin/pgaftest/cli_root.c | 1 + src/bin/pgaftest/main.c | 23 + src/bin/pgaftest/test_runner.c | 2 + src/bin/pgaftest/test_spec_parse.y | 3 +- src/bin/pgaftest/test_spec_scan.l | 1 - 13 files changed, 49 insertions(+), 3809 deletions(-) delete mode 100644 src/bin/pg_autoctl/azure.c delete mode 100644 src/bin/pg_autoctl/azure.h delete mode 100644 src/bin/pg_autoctl/azure_config.c delete mode 100644 src/bin/pg_autoctl/azure_config.h delete mode 100644 src/bin/pg_autoctl/cli_do_azure.c delete mode 100644 src/bin/pg_autoctl/cli_do_tmux_azure.c diff --git a/src/bin/common/Makefile.common b/src/bin/common/Makefile.common index 1167d5b85..2b567e67e 100644 --- a/src/bin/common/Makefile.common +++ b/src/bin/common/Makefile.common @@ -27,6 +27,15 @@ DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --includedir) DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --includedir-server) DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --pkgincludedir)/internal DEFAULT_CFLAGS += $(shell $(PG_CONFIG) --cflags) + +# On macOS, gettext is keg-only and not in the default include path. +# postgres_fe.h → c.h → libintl.h requires finding it explicitly. +ifeq ($(shell uname -s),Darwin) + GETTEXT_PREFIX := $(shell brew --prefix gettext 2>/dev/null) + ifneq ($(GETTEXT_PREFIX),) + DEFAULT_CFLAGS += -I$(GETTEXT_PREFIX)/include + endif +endif DEFAULT_CFLAGS += -Wformat DEFAULT_CFLAGS += -Wall DEFAULT_CFLAGS += -Werror=implicit-int diff --git a/src/bin/pg_autoctl/azure.c b/src/bin/pg_autoctl/azure.c deleted file mode 100644 index 1cfeaddc1..000000000 --- a/src/bin/pg_autoctl/azure.c +++ /dev/null @@ -1,2516 +0,0 @@ -/* - * src/bin/pg_autoctl/azure.c - * Implementation of a CLI which lets you call `az` cli commands to prepare - * a pg_auto_failover demo or QA environment. - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the PostgreSQL License. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "postgres_fe.h" -#include "pqexpbuffer.h" -#include "snprintf.h" - -#include "azure.h" -#include "cli_common.h" -#include "cli_do_root.h" -#include "cli_root.h" -#include "commandline.h" -#include "config.h" -#include "env_utils.h" -#include "log.h" -#include "parsing.h" -#include "pgsql.h" -#include "pidfile.h" -#include "signals.h" -#include "string_utils.h" - -#include "runprogram.h" - -char azureCLI[MAXPGPATH] = { 0 }; - -static int azure_run_command(Program *program); -static pid_t azure_start_command(Program *program); -static bool azure_wait_for_commands(int count, pid_t pidArray[]); - -static bool run_ssh(const char *username, const char *ip); - -static bool run_ssh_command(const char *username, - const char *ip, - bool tty, - const char *command); - -static bool start_ssh_command(const char *username, - const char *ip, - const char *command); - -static bool azure_git_toplevel(char *srcDir, size_t size); - -static bool start_rsync_command(const char *username, - const char *ip, - const char *srcDir); - -static bool azure_rsync_vms(AzureRegionResources *azRegion); - -static bool azure_fetch_resource_list(const char *group, - AzureRegionResources *azRegion); - -static bool azure_fetch_vm_addresses(const char *group, const char *vm, - AzureVMipAddresses *addresses); - - -/* log_program_output logs the output of the given program. */ -static void -log_program_output(Program *prog, int outLogLevel, int errorLogLevel) -{ - if (prog->stdOut != NULL) - { - char *outLines[BUFSIZE]; - int lineCount = splitLines(prog->stdOut, outLines, BUFSIZE); - int lineNumber = 0; - - for (lineNumber = 0; lineNumber < lineCount; lineNumber++) - { - log_level(outLogLevel, "%s", outLines[lineNumber]); - } - } - - if (prog->stdErr != NULL) - { - char *errorLines[BUFSIZE]; - int lineCount = splitLines(prog->stdErr, errorLines, BUFSIZE); - int lineNumber = 0; - - for (lineNumber = 0; lineNumber < lineCount; lineNumber++) - { - log_level(errorLogLevel, "%s", errorLines[lineNumber]); - } - } -} - - -/* - * azure_run_command runs a command line using the azure CLI command, and when - * dryRun is true instead of running the command it only shows the command it - * would run as the output of the pg_autoctl command. - */ -static int -azure_run_command(Program *program) -{ - int returnCode; - char command[BUFSIZE] = { 0 }; - - (void) snprintf_program_command_line(program, command, sizeof(command)); - - if (dryRun) - { - appendPQExpBuffer(azureScript, "\n%s", command); - - /* fake successful execution */ - return 0; - } - - log_debug("%s", command); - - (void) execute_subprogram(program); - - returnCode = program->returnCode; - - if (returnCode != 0) - { - (void) log_program_output(program, LOG_INFO, LOG_ERROR); - } - - free_program(program); - - return returnCode; -} - - -/* - * azure_start_command starts a command in the background, as a subprocess of - * the current process, and returns the sub-process pid as soon as the - * sub-process is started. It's the responsibility of the caller to then - * implement waitpid() on the returned pid. - * - * This allows running several commands in parallel, as in the shell sequence: - * - * $ az vm create & - * $ az vm create & - * $ az vm create & - * $ wait - */ -static pid_t -azure_start_command(Program *program) -{ - pid_t fpid; - char command[BUFSIZE] = { 0 }; - - (void) snprintf_program_command_line(program, command, sizeof(command)); - - if (dryRun) - { - appendPQExpBuffer(azureScript, "\n%s &", command); - - /* fake successful execution */ - return 0; - } - - log_debug("%s", command); - - /* Flush stdio channels just before fork, to avoid double-output problems */ - fflush(stdout); - fflush(stderr); - - /* time to create the node_active sub-process */ - fpid = fork(); - - switch (fpid) - { - case -1: - { - log_error("Failed to fork a process for command: %s", command); - return -1; - } - - case 0: - { - /* child process runs the command */ - int returnCode; - - /* initialize the semaphore used for locking log output */ - if (!semaphore_init(&log_semaphore)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } - - /* set our logging facility to use our semaphore as a lock */ - (void) log_set_udata(&log_semaphore); - (void) log_set_lock(&semaphore_log_lock_function); - - (void) execute_subprogram(program); - returnCode = program->returnCode; - - log_debug("Command %s exited with return code %d", - program->args[0], - returnCode); - - if (returnCode != 0) - { - (void) log_program_output(program, LOG_INFO, LOG_ERROR); - free_program(program); - - /* the parent will have to use exit status */ - (void) semaphore_finish(&log_semaphore); - exit(EXIT_CODE_INTERNAL_ERROR); - } - - free_program(program); - (void) semaphore_finish(&log_semaphore); - exit(EXIT_CODE_QUIT); - } - - default: - { - /* fork succeeded, in parent */ - return fpid; - } - } -} - - -/* - * azure_wait_for_commands waits until all processes with pids from the array - * are done. - */ -static bool -azure_wait_for_commands(int count, pid_t pidArray[]) -{ - int subprocessCount = count; - bool allReturnCodeAreZero = true; - - while (subprocessCount > 0) - { - pid_t pid; - int status; - - /* ignore errors */ - pid = waitpid(-1, &status, WNOHANG); - - switch (pid) - { - case -1: - { - if (errno == ECHILD) - { - /* no more childrens */ - return subprocessCount == 0; - } - - pg_usleep(100 * 1000); /* 100 ms */ - break; - } - - case 0: - { - /* - * We're using WNOHANG, 0 means there are no stopped or - * exited children, it's all good. It's the expected case - * when everything is running smoothly, so enjoy and sleep - * for awhile. - */ - pg_usleep(100 * 1000); /* 100 ms */ - break; - } - - default: - { - /* - * One of the az vm create sub-commands has finished, find - * which and if it went all okay. - */ - int returnCode = WEXITSTATUS(status); - - /* find which VM is done now */ - for (int index = 0; index < count; index++) - { - if (pidArray[index] == pid) - { - if (returnCode == 0) - { - log_debug("Process %d exited successfully", - pid); - } - else - { - log_error("Process %d exited with code %d", - pid, returnCode); - - allReturnCodeAreZero = false; - } - } - } - - --subprocessCount; - break; - } - } - } - - return allReturnCodeAreZero; -} - - -/* - * azure_psleep runs count parallel sleep process at the same time. - */ -bool -azure_psleep(int count, bool force) -{ - char sleep[MAXPGPATH] = { 0 }; - pid_t pidArray[26] = { 0 }; - - bool saveDryRun = dryRun; - - if (!search_path_first("sleep", sleep, LOG_ERROR)) - { - log_fatal("Failed to find program sleep in PATH"); - return false; - } - - if (force) - { - dryRun = false; - } - - for (int i = 0; i < count; i++) - { - char *args[3]; - int argsIndex = 0; - - Program program = { 0 }; - - args[argsIndex++] = sleep; - args[argsIndex++] = "5"; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - pidArray[i] = azure_start_command(&program); - } - - if (force) - { - dryRun = saveDryRun; - } - - if (!azure_wait_for_commands(count, pidArray)) - { - log_fatal("Failed to sleep concurrently with %d processes", count); - return false; - } - - return true; -} - - -/* - * azure_get_remote_ip gets the local IP address by using the command `curl - * ifconfig.me` - */ -bool -azure_get_remote_ip(char *ipAddress, size_t ipAddressSize) -{ - Program program; - char curl[MAXPGPATH] = { 0 }; - - if (!search_path_first("curl", curl, LOG_ERROR)) - { - log_fatal("Failed to find program curl in PATH"); - return false; - } - - program = run_program(curl, "ifconfig.me", NULL); - - if (program.returnCode != 0) - { - (void) log_program_output(&program, LOG_INFO, LOG_ERROR); - free_program(&program); - return false; - } - else - { - /* we expect a single line of output, no end-of-line */ - strlcpy(ipAddress, program.stdOut, ipAddressSize); - free_program(&program); - - return true; - } -} - - -/* - * azure_create_group creates a new resource group on Azure. - */ -bool -azure_create_group(const char *name, const char *location) -{ - char *args[16]; - int argsIndex = 0; - - Program program = { 0 }; - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "group"; - args[argsIndex++] = "create"; - args[argsIndex++] = "--name"; - args[argsIndex++] = (char *) name; - args[argsIndex++] = "--location"; - args[argsIndex++] = (char *) location; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - log_info("Creating group \"%s\" in location \"%s\"", name, location); - - return azure_run_command(&program) == 0; -} - - -/* - * azure_create_vnet creates a new vnet on Azure. - */ -bool -azure_create_vnet(const char *group, const char *name, const char *prefix) -{ - char *args[16]; - int argsIndex = 0; - - Program program = { 0 }; - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "network"; - args[argsIndex++] = "vnet"; - args[argsIndex++] = "create"; - args[argsIndex++] = "--resource-group"; - args[argsIndex++] = (char *) group; - args[argsIndex++] = "--name"; - args[argsIndex++] = (char *) name; - args[argsIndex++] = "--address-prefix"; - args[argsIndex++] = (char *) prefix; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - log_info("Creating network vnet \"%s\" using address prefix \"%s\"", - name, prefix); - - return azure_run_command(&program) == 0; -} - - -/* - * azure_create_vnet creates a new vnet on Azure. - */ -bool -azure_create_nsg(const char *group, const char *name) -{ - char *args[16]; - int argsIndex = 0; - - Program program = { 0 }; - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "network"; - args[argsIndex++] = "nsg"; - args[argsIndex++] = "create"; - args[argsIndex++] = "--resource-group"; - args[argsIndex++] = (char *) group; - args[argsIndex++] = "--name"; - args[argsIndex++] = (char *) name; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - log_info("Creating network nsg \"%s\"", name); - - return azure_run_command(&program) == 0; -} - - -/* - * azure_create_vnet creates a new network security rule. - */ -bool -azure_create_nsg_rule(const char *group, - const char *nsgName, - const char *name, - const char *ipAddress) -{ - char *args[38]; - int argsIndex = 0; - - Program program = { 0 }; - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "network"; - args[argsIndex++] = "nsg"; - args[argsIndex++] = "rule"; - args[argsIndex++] = "create"; - args[argsIndex++] = "--resource-group"; - args[argsIndex++] = (char *) group; - args[argsIndex++] = "--nsg-name"; - args[argsIndex++] = (char *) nsgName; - args[argsIndex++] = "--name"; - args[argsIndex++] = (char *) name; - args[argsIndex++] = "--access"; - args[argsIndex++] = "allow"; - args[argsIndex++] = "--protocol"; - args[argsIndex++] = "Tcp"; - args[argsIndex++] = "--direction"; - args[argsIndex++] = "Inbound"; - args[argsIndex++] = "--priority"; - args[argsIndex++] = "100"; - args[argsIndex++] = "--source-address-prefixes"; - args[argsIndex++] = (char *) ipAddress; - args[argsIndex++] = "--source-port-range"; - args[argsIndex++] = dryRun ? "\"*\"" : "*"; - args[argsIndex++] = "--destination-address-prefix"; - args[argsIndex++] = dryRun ? "\"*\"" : "*"; - args[argsIndex++] = "--destination-port-ranges"; - args[argsIndex++] = "22"; - args[argsIndex++] = "5432"; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - log_info("Creating network nsg rules \"%s\" for our IP address \"%s\" " - "for ports 22 and 5432", name, ipAddress); - - return azure_run_command(&program) == 0; -} - - -/* - * azure_create_subnet creates a new subnet on Azure. - */ -bool -azure_create_subnet(const char *group, - const char *vnet, - const char *name, - const char *prefixes, - const char *nsg) -{ - char *args[16]; - int argsIndex = 0; - - Program program = { 0 }; - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "network"; - args[argsIndex++] = "vnet"; - args[argsIndex++] = "subnet"; - args[argsIndex++] = "create"; - args[argsIndex++] = "--resource-group"; - args[argsIndex++] = (char *) group; - args[argsIndex++] = "--vnet-name"; - args[argsIndex++] = (char *) vnet; - args[argsIndex++] = "--name"; - args[argsIndex++] = (char *) name; - args[argsIndex++] = "--address-prefixes"; - args[argsIndex++] = (char *) prefixes; - args[argsIndex++] = "--network-security-group"; - args[argsIndex++] = (char *) nsg; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - log_info("Creating network subnet \"%s\" using address prefix \"%s\"", - name, prefixes); - - return azure_run_command(&program) == 0; -} - - -/* - * az_group_delete runs the command az group delete. - */ -bool -az_group_delete(const char *group) -{ - char *args[16]; - int argsIndex = 0; - - Program program = { 0 }; - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "group"; - args[argsIndex++] = "delete"; - args[argsIndex++] = "--name"; - args[argsIndex++] = (char *) group; - args[argsIndex++] = "--yes"; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - log_info("Deleting azure resource group \"%s\"", group); - - return azure_run_command(&program) == 0; -} - - -/* - * azure_prepare_node_name is a utility function that prepares a node name to - * use for a VM in our pg_auto_failover deployment in a target Azure region. - * - * In the resource group "ha-demo-dim-paris" when creating a monitor (index 0), - * an app VM (index 27), and 2 pg nodes VMs we would have the following names: - * - * - [0] ha-demo-dim-paris-monitor - * - [1] ha-demo-dim-paris-a - * - [2] ha-demo-dim-paris-b - * - [27] ha-demo-dim-paris-app - */ -static void -azure_prepare_node(AzureRegionResources *azRegion, int index) -{ - char vmsuffix[] = "abcdefghijklmnopqrstuvwxyz"; - - if (index == 0) - { - sformat(azRegion->vmArray[index].name, - sizeof(azRegion->vmArray[index].name), - "%s-monitor", - azRegion->group); - } - else if (index == MAX_VMS_PER_REGION - 1) - { - sformat(azRegion->vmArray[index].name, - sizeof(azRegion->vmArray[index].name), - "%s-app", - azRegion->group); - } - else - { - sformat(azRegion->vmArray[index].name, - sizeof(azRegion->vmArray[index].name), - "%s-%c", - azRegion->group, - vmsuffix[index - 1]); - } -} - - -/* - * azure_node_index_from_name is the complement to azure_prepare_node. - * Given a VM name such as ha-demo-dim-paris-monitor or ha-demo-dim-paris-a, - * the function returns respectively 0 and 1, which is the array index where we - * want to find information about the VM (name, IP addresses, etc) in an array - * of VMs. - */ -static int -azure_node_index_from_name(const char *group, const char *name) -{ - int groupNameLen = strlen(group); - char *ptr; - - if (strncmp(name, group, groupNameLen) != 0 || - strlen(name) < (groupNameLen + 1)) - { - log_error("VM name \"%s\" does not start with group name \"%s\"", - name, group); - return -1; - } - - /* skip group name and dash: ha-demo-dim-paris- */ - ptr = (char *) name + groupNameLen + 1; - - /* - * ha-demo-dim-paris-monitor is always index 0 - * ha-demo-dim-paris-app is always index 27 (last in the array) - * ha-demo-dim-paris-a is index 1 - * ha-demo-dim-paris-b is index 2 - * ... - * ha-demo-dim-paris-z is index 26 - */ - if (strcmp(ptr, "monitor") == 0) - { - return 0; - } - else if (strcmp(ptr, "app") == 0) - { - return MAX_VMS_PER_REGION - 1; - } - else - { - if (strlen(ptr) != 1) - { - log_error("Failed to parse VM index from name \"%s\"", name); - return -1; - } - - /* 'a' is 1, 'b' is 2, etc */ - return *ptr - 'a' + 1; - } -} - - -/* - * azure_create_vm creates a Virtual Machine in our azure resource group. - */ -bool -azure_create_vm(AzureRegionResources *azRegion, - const char *name, - const char *image, - const char *username) -{ - char *args[26]; - int argsIndex = 0; - - Program program = { 0 }; - - char publicIpAddressName[BUFSIZE] = { 0 }; - - sformat(publicIpAddressName, BUFSIZE, "%s-ip", name); - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "vm"; - args[argsIndex++] = "create"; - args[argsIndex++] = "--resource-group"; - args[argsIndex++] = (char *) azRegion->group; - args[argsIndex++] = "--name"; - args[argsIndex++] = (char *) name; - args[argsIndex++] = "--vnet-name"; - args[argsIndex++] = (char *) azRegion->vnet; - args[argsIndex++] = "--subnet"; - args[argsIndex++] = (char *) azRegion->subnet; - args[argsIndex++] = "--nsg"; - args[argsIndex++] = (char *) azRegion->nsg; - args[argsIndex++] = "--public-ip-address"; - args[argsIndex++] = (char *) publicIpAddressName; - args[argsIndex++] = "--image"; - args[argsIndex++] = (char *) image; - args[argsIndex++] = "--admin-username"; - args[argsIndex++] = (char *) username; - args[argsIndex++] = "--generate-ssh-keys"; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - log_info("Creating %s virtual machine \"%s\" with user \"%s\"", - image, name, username); - - return azure_start_command(&program); -} - - -/* - * azure_create_vms creates several azure virtual machine in parallel and waits - * until all the commands have finished. - */ -bool -azure_create_vms(AzureRegionResources *azRegion, - const char *image, - const char *username) -{ - int pending = 0; - pid_t pidArray[MAX_VMS_PER_REGION] = { 0 }; - - /* we read from left to right, have the smaller number on the left */ - if (26 < azRegion->nodes) - { - log_error("pg_autoctl only supports up to 26 VMs per region"); - return false; - } - - log_info("Creating Virtual Machines for %s%d Postgres nodes, in parallel", - azRegion->monitor ? "a monitor and " : " ", - azRegion->nodes); - - /* index == 0 for the monitor, then 1..count for the other nodes */ - for (int index = 0; index <= azRegion->nodes; index++) - { - /* skip index 0 when we're not creating a monitor */ - if (index == 0 && !azRegion->monitor) - { - continue; - } - - /* skip VMs that already exist, unless --script is used */ - if (!dryRun && - !IS_EMPTY_STRING_BUFFER(azRegion->vmArray[index].name) && - !IS_EMPTY_STRING_BUFFER(azRegion->vmArray[index].public) && - !IS_EMPTY_STRING_BUFFER(azRegion->vmArray[index].private)) - { - log_info("Skipping creation of VM \"%s\", " - "which already exists with public IP address %s", - azRegion->vmArray[index].name, - azRegion->vmArray[index].public); - continue; - } - - (void) azure_prepare_node(azRegion, index); - - pidArray[index] = azure_create_vm(azRegion, - azRegion->vmArray[index].name, - image, - username); - ++pending; - } - - /* also create the application node VM when asked to */ - if (azRegion->appNodes > 0) - { - int index = MAX_VMS_PER_REGION - 1; - - if (!dryRun && - !IS_EMPTY_STRING_BUFFER(azRegion->vmArray[index].name) && - !IS_EMPTY_STRING_BUFFER(azRegion->vmArray[index].public) && - !IS_EMPTY_STRING_BUFFER(azRegion->vmArray[index].private)) - { - log_info("Skipping creation of VM \"%s\", " - "which already exists with public IP address %s", - azRegion->vmArray[index].name, - azRegion->vmArray[index].public); - } - else - { - (void) azure_prepare_node(azRegion, index); - - pidArray[index] = azure_create_vm(azRegion, - azRegion->vmArray[index].name, - image, - username); - ++pending; - } - } - - /* now wait for the child processes to be done */ - if (dryRun && pending > 0) - { - appendPQExpBuffer(azureScript, "\nwait"); - } - else - { - if (!azure_wait_for_commands(pending, pidArray)) - { - log_fatal("Failed to create all %d azure VMs, " - "see above for details", - pending); - return false; - } - } - - return true; -} - - -/* - * azure_git_toplevel calls `git rev-parse --show-toplevel` and uses the result - * as the directory to rsync to our VMs when provisionning from sources. - */ -static bool -azure_git_toplevel(char *srcDir, size_t size) -{ - Program program; - char git[MAXPGPATH] = { 0 }; - - if (!search_path_first("git", git, LOG_ERROR)) - { - log_fatal("Failed to find program git in PATH"); - return false; - } - - program = run_program(git, "rev-parse", "--show-toplevel", NULL); - - if (program.returnCode != 0) - { - (void) log_program_output(&program, LOG_INFO, LOG_ERROR); - free_program(&program); - return false; - } - else - { - char *outLines[BUFSIZE]; - - /* git rev-parse --show-toplevel outputs a single line */ - splitLines(program.stdOut, outLines, BUFSIZE); - strlcpy(srcDir, outLines[0], size); - - free_program(&program); - - return true; - } -} - - -/* - * start_rsync_command is used to sync our local source directory with a remote - * place on a target VM. - */ -static bool -start_rsync_command(const char *username, - const char *ip, - const char *srcDir) -{ - char *args[16]; - int argsIndex = 0; - - Program program = { 0 }; - - char ssh[MAXPGPATH] = { 0 }; - char essh[MAXPGPATH] = { 0 }; - char rsync[MAXPGPATH] = { 0 }; - char sourceDir[MAXPGPATH] = { 0 }; - char rsync_remote[MAXPGPATH] = { 0 }; - - if (!search_path_first("rsync", rsync, LOG_ERROR)) - { - log_fatal("Failed to find program rsync in PATH"); - return false; - } - - if (!search_path_first("ssh", ssh, LOG_ERROR)) - { - log_fatal("Failed to find program ssh in PATH"); - return false; - } - - /* use our usual ssh options even when using it through rsync */ - sformat(essh, sizeof(essh), - "%s -o '%s' -o '%s' -o '%s'", - ssh, - "StrictHostKeyChecking=no", - "UserKnownHostsFile /dev/null", - "LogLevel=quiet"); - - /* we need the rsync remote as one string */ - sformat(rsync_remote, sizeof(rsync_remote), - "%s@%s:/home/%s/pg_auto_failover/", - username, ip, username); - - /* we need to ensure that the source directory terminates with a "/" */ - if (strcmp(strrchr(srcDir, '/'), "/") != 0) - { - sformat(sourceDir, sizeof(sourceDir), "%s/", srcDir); - } - else - { - strlcpy(sourceDir, srcDir, sizeof(sourceDir)); - } - - args[argsIndex++] = rsync; - args[argsIndex++] = "-a"; - args[argsIndex++] = "-e"; - args[argsIndex++] = essh; - args[argsIndex++] = "--exclude='.git'"; - args[argsIndex++] = "--exclude='*.o'"; - args[argsIndex++] = "--exclude='*.deps'"; - args[argsIndex++] = "--exclude='./src/bin/pg_autoctl/pg_autoctl'"; - args[argsIndex++] = sourceDir; - args[argsIndex++] = rsync_remote; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - return azure_start_command(&program); -} - - -/* - * azure_rsync_vms runs the rsync command for target VMs in parallel. - */ -static bool -azure_rsync_vms(AzureRegionResources *azRegion) -{ - int pending = 0; - pid_t pidArray[MAX_VMS_PER_REGION] = { 0 }; - - char srcDir[MAXPGPATH] = { 0 }; - - if (!azure_git_toplevel(srcDir, sizeof(srcDir))) - { - /* errors have already been logged */ - return false; - } - - log_info("Syncing local directory \"%s\" to %d Azure VMs", - srcDir, - azRegion->nodes + - azRegion->monitor + - azRegion->appNodes); - - /* index == 0 for the monitor, then 1..count for the other nodes */ - for (int index = 0; index <= azRegion->nodes; index++) - { - /* skip index 0 when we're not creating a monitor */ - if (index == 0 && !azRegion->monitor) - { - continue; - } - - (void) azure_prepare_node(azRegion, index); - - pidArray[index] = - start_rsync_command("ha-admin", - azRegion->vmArray[index].public, - srcDir); - - ++pending; - } - - /* also provision the application node VM when asked to */ - if (azRegion->appNodes > 0) - { - int index = MAX_VMS_PER_REGION - 1; - - (void) azure_prepare_node(azRegion, index); - - pidArray[index] = - start_rsync_command("ha-admin", - azRegion->vmArray[index].public, - srcDir); - - ++pending; - } - - /* now wait for the child processes to be done */ - if (dryRun) - { - appendPQExpBuffer(azureScript, "\nwait"); - } - else - { - if (!azure_wait_for_commands(pending, pidArray)) - { - log_fatal("Failed to provision all %d azure VMs, " - "see above for details", - pending); - return false; - } - } - - return true; -} - - -/* - * azure_build_pg_autoctl runs `make all` then `make install` on all the target - * VMs in parallel, using an ssh command line. - */ -static bool -azure_build_pg_autoctl(AzureRegionResources *azRegion) -{ - int pending = 0; - pid_t pidArray[MAX_VMS_PER_REGION] = { 0 }; - - char *buildCommand = - "make PG_CONFIG=/usr/lib/postgresql/17/bin/pg_config " - "-C pg_auto_failover -s clean all " - " && " - "sudo make PG_CONFIG=/usr/lib/postgresql/17/bin/pg_config " - "BINDIR=/usr/local/bin -C pg_auto_failover install"; - - log_info("Building pg_auto_failover from sources on %d Azure VMs", - azRegion->nodes + - azRegion->monitor + - azRegion->appNodes); - - log_info("%s", buildCommand); - - /* index == 0 for the monitor, then 1..count for the other nodes */ - for (int index = 0; index <= azRegion->nodes; index++) - { - /* skip index 0 when we're not creating a monitor */ - if (index == 0 && !azRegion->monitor) - { - continue; - } - - (void) azure_prepare_node(azRegion, index); - - pidArray[index] = - start_ssh_command("ha-admin", - azRegion->vmArray[index].public, - buildCommand); - ++pending; - } - - /* also provision the application node VM when asked to */ - if (azRegion->appNodes > 0) - { - int index = MAX_VMS_PER_REGION - 1; - - (void) azure_prepare_node(azRegion, index); - - pidArray[index] = - start_ssh_command("ha-admin", - azRegion->vmArray[index].public, - buildCommand); - ++pending; - } - - /* now wait for the child processes to be done */ - if (dryRun) - { - appendPQExpBuffer(azureScript, "\nwait"); - } - else - { - if (!azure_wait_for_commands(pending, pidArray)) - { - log_fatal("Failed to provision all %d azure VMs, " - "see above for details", - pending); - return false; - } - } - - return true; -} - - -/* - * azure_prepare_target_versions prepares the environment variables that we - * need to grasp for provisioning our target Azure VMs. We use the following - * environment variables: - * - * AZ_PG_VERSION ?= 13 - * AZ_PGAF_DEB_VERSION ?= 1.5 - * AZ_PGAF_DEB_REVISION ?= 1.5.2-1 - */ -bool -azure_prepare_target_versions(KeyVal *env) -{ - char *keywords[] = { - "AZ_PG_VERSION", "AZ_PGAF_DEB_VERSION", "AZ_PGAF_DEB_REVISION" - }; - - /* set our static set of 3 variables from the environment */ - env->count = 3; - - /* default values */ - sformat(env->values[0], MAXCONNINFO, "13"); /* AZ_PG_VERSION */ - sformat(env->values[1], MAXCONNINFO, "2.2"); /* AZ_PGAF_DEB_VERSION */ - sformat(env->values[2], MAXCONNINFO, "2.2-1"); /* AZ_PGAF_DEB_REVISION */ - - for (int i = 0; i < 3; i++) - { - /* install the environment variable name as the keyword */ - strlcpy(env->keywords[i], keywords[i], MAXCONNINFO); - - /* pick values from the environment when they exist */ - if (env_exists(env->keywords[i])) - { - if (!get_env_copy(env->keywords[i], env->values[i], MAXCONNINFO)) - { - /* errors have already been logged */ - return false; - } - } - } - - return true; -} - - -/* - * azure_prepare_debian_command prepares the debian command to install our - * target pg_auto_failover package on the Azure VMs. - * - * sudo apt-get install -q -y \ - * postgresql-13-auto-failover-1.5=1.5.2-1 \ - * pg-auto-failover-cli-1.5=1.5.2-1 - * - * We are using environment variables to fill in the actual version numbers, - * and we hard-code some defaults in case the environment has not be provided - * for. - */ -static bool -azure_prepare_debian_install_command(char *command, size_t size) -{ - /* re-use our generic data structure from Postgres URI parsing */ - KeyVal env = { 0 }; - - if (!azure_prepare_target_versions(&env)) - { - /* errors have already been logged */ - return false; - } - - sformat(command, size, - "sudo apt-get install -q -y " - " postgresql-%s-auto-failover-%s=%s" - " pg-auto-failover-cli-%s=%s", - env.values[0], /* AZ_PG_VERSION */ - env.values[1], /* AZ_PGAF_DEB_VERSION */ - env.values[2], /* AZ_PGAF_DEB_REVISION */ - env.values[1], /* AZ_PGAF_DEB_VERSION */ - env.values[2]); /* AZ_PGAF_DEB_REVISION */ - - return true; -} - - -/* - * azure_prepare_debian_install_postgres_command prepares the debian command to - * install our target Postgres version when building from sources. - * - * sudo apt-get build-dep -q -y postgresql-16 - */ -static bool -azure_prepare_debian_install_postgres_command(char *command, size_t size) -{ - /* re-use our generic data structure from Postgres URI parsing */ - KeyVal env = { 0 }; - - if (!azure_prepare_target_versions(&env)) - { - /* errors have already been logged */ - return false; - } - - sformat(command, size, - "sudo apt-get build-dep -q -y postgresql-%s", - - /* AZ_PG_VERSION */ - env.values[0]); - - return true; -} - - -/* - * azure_prepare_debian_build_dep_postgres_command_command prepares the debian - * command to install our target Postgres version when building from sources. - * - * As we don't have deb-src for pg_auto_failover packages, we do the list - * manually, and we add also rsync to be able to push sources from the local - * git repository. - * - * sudo apt-get install -q -y \ - * postgresql-server-dev-all libkrb5-dev postgresql-16 rsync - */ -static bool -azure_prepare_debian_build_dep_postgres_command(char *command, size_t size) -{ - /* re-use our generic data structure from Postgres URI parsing */ - KeyVal env = { 0 }; - - if (!azure_prepare_target_versions(&env)) - { - /* errors have already been logged */ - return false; - } - - sformat(command, size, - "sudo apt-get install -q -y " - "postgresql-server-dev-all " - "postgresql-%s " - "libkrb5-dev " - "rsync ", - - /* AZ_PG_VERSION */ - env.values[0]); - - return true; -} - - -/* - * azure_provision_vm runs the command `az vm run-command invoke` with our - * provisioning script. - */ -bool -azure_provision_vm(const char *group, const char *name, bool fromSource) -{ - char *args[26]; - int argsIndex = 0; - - Program program = { 0 }; - - char aptGetInstall[BUFSIZE] = { 0 }; - char aptGetInstallPostgres[BUFSIZE] = { 0 }; - char aptGetBuildDepPostgres[BUFSIZE] = { 0 }; - - const char *scriptsFromPackage[] = - { - "curl https://install.citusdata.com/community/deb.sh | sudo bash", - "sudo apt-get install -q -y postgresql-common", - "echo 'create_main_cluster = false' " - "| sudo tee -a /etc/postgresql-common/createcluster.conf", - aptGetInstall, - "sudo usermod -a -G postgres ha-admin", - NULL - }; - - const char *scriptsFromSource[] = - { - "curl https://install.citusdata.com/community/deb.sh | sudo bash", - "sudo apt-get install -q -y postgresql-common", - "echo 'create_main_cluster = false' " - "| sudo tee -a /etc/postgresql-common/createcluster.conf", - aptGetInstallPostgres, - aptGetBuildDepPostgres, - "sudo usermod -a -G postgres ha-admin", - NULL - }; - - char **scripts = - fromSource ? (char **) scriptsFromSource : (char **) scriptsFromPackage; - - char *quotedScripts[10][BUFSIZE] = { 0 }; - - if (!azure_prepare_debian_install_command(aptGetInstall, BUFSIZE)) - { - /* errors have already been logged */ - return false; - } - - if (!azure_prepare_debian_install_postgres_command(aptGetInstallPostgres, - BUFSIZE)) - { - /* errors have already been logged */ - return false; - } - - if (!azure_prepare_debian_build_dep_postgres_command(aptGetBuildDepPostgres, - BUFSIZE)) - { - /* errors have already been logged */ - return false; - } - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "vm"; - args[argsIndex++] = "run-command"; - args[argsIndex++] = "invoke"; - args[argsIndex++] = "--resource-group"; - args[argsIndex++] = (char *) group; - args[argsIndex++] = "--name"; - args[argsIndex++] = (char *) name; - args[argsIndex++] = "--command-id"; - args[argsIndex++] = "RunShellScript"; - args[argsIndex++] = "--scripts"; - - if (dryRun) - { - for (int i = 0; scripts[i] != NULL; i++) - { - sformat((char *) quotedScripts[i], BUFSIZE, "\"%s\"", scripts[i]); - args[argsIndex++] = (char *) quotedScripts[i]; - } - } - else - { - for (int i = 0; scripts[i] != NULL; i++) - { - args[argsIndex++] = (char *) scripts[i]; - } - } - - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - log_info("Provisioning Virtual Machine \"%s\"", name); - - return azure_start_command(&program); -} - - -/* - * azure_provision_vms provisions several azure virtual machine in parallel and - * waits until all the commands have finished. - */ -bool -azure_provision_vms(AzureRegionResources *azRegion, bool fromSource) -{ - int pending = 0; - pid_t pidArray[MAX_VMS_PER_REGION] = { 0 }; - - char aptGetInstall[BUFSIZE] = { 0 }; - - /* we read from left to right, have the smaller number on the left */ - if (26 < azRegion->nodes) - { - log_error("pg_autoctl only supports up to 26 VMs per region"); - return false; - } - - log_info("Provisioning %d Virtual Machines in parallel", - azRegion->nodes + - azRegion->monitor + - azRegion->appNodes); - - if (!azure_prepare_debian_install_command(aptGetInstall, BUFSIZE)) - { - /* errors have already been logged */ - return false; - } - - log_info("Using: %s", aptGetInstall); - - /* index == 0 for the monitor, then 1..count for the other nodes */ - for (int index = 0; index <= azRegion->nodes; index++) - { - /* skip index 0 when we're not creating a monitor */ - if (index == 0 && azRegion->monitor == 0) - { - continue; - } - - (void) azure_prepare_node(azRegion, index); - - pidArray[index] = azure_provision_vm(azRegion->group, - azRegion->vmArray[index].name, - fromSource); - - ++pending; - } - - /* also provision the application node VM when asked to */ - if (azRegion->appNodes > 0) - { - int index = MAX_VMS_PER_REGION - 1; - - (void) azure_prepare_node(azRegion, index); - - pidArray[index] = azure_provision_vm(azRegion->group, - azRegion->vmArray[index].name, - fromSource); - ++pending; - } - - /* now wait for the child processes to be done */ - if (dryRun) - { - appendPQExpBuffer(azureScript, "\nwait"); - } - else - { - if (!azure_wait_for_commands(pending, pidArray)) - { - log_fatal("Failed to provision all %d azure VMs, " - "see above for details", - pending); - return false; - } - } - - return true; -} - - -/* - * azure_resource_list runs the command azure resource list. - * - * az resource list --output table --query "[?resourceGroup=='ha-demo-dim-paris'].{ name: name, flavor: kind, resourceType: type, region: location }" - */ -bool -azure_resource_list(const char *group) -{ - char *args[16]; - int argsIndex = 0; - bool success = true; - - Program program = { 0 }; - - char query[BUFSIZE] = { 0 }; - - char command[BUFSIZE] = { 0 }; - - sformat(query, BUFSIZE, - "[?resourceGroup=='%s']" - ".{ name: name, flavor: kind, resourceType: type, region: location }", - group); - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "resource"; - args[argsIndex++] = "list"; - args[argsIndex++] = "--output"; - args[argsIndex++] = "table"; - args[argsIndex++] = "--query"; - args[argsIndex++] = (char *) query; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - (void) snprintf_program_command_line(&program, command, sizeof(command)); - - log_info("%s", command); - - (void) execute_subprogram(&program); - success = program.returnCode == 0; - - if (success) - { - fformat(stdout, "%s", program.stdOut); - } - else - { - (void) log_program_output(&program, LOG_INFO, LOG_ERROR); - } - free_program(&program); - - return success; -} - - -/* - * azure_fetch_resource_list fetches existing resource names for a short list - * of known objects in a target azure resource group. - */ -static bool -azure_fetch_resource_list(const char *group, AzureRegionResources *azRegion) -{ - char *args[16]; - int argsIndex = 0; - bool success = true; - - Program program = { 0 }; - - char query[BUFSIZE] = { 0 }; - - char command[BUFSIZE] = { 0 }; - - sformat(query, BUFSIZE, - "[?resourceGroup=='%s'].{ name: name, resourceType: type }", - group); - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "resource"; - args[argsIndex++] = "list"; - args[argsIndex++] = "--output"; - args[argsIndex++] = "json"; - args[argsIndex++] = "--query"; - args[argsIndex++] = (char *) query; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - (void) snprintf_program_command_line(&program, command, sizeof(command)); - - log_info("Fetching resources that might already exist from a previous run"); - log_info("%s", command); - - (void) execute_subprogram(&program); - success = program.returnCode == 0; - - if (success) - { - /* parson insists on having fresh heap allocated memory, apparently */ - char *jsonString = strdup(program.stdOut); - JSON_Value *js = json_parse_string(jsonString); - JSON_Array *jsArray = json_value_get_array(js); - int count = json_array_get_count(jsArray); - - if (js == NULL) - { - log_error("Failed to parse JSON string: %s", program.stdOut); - return false; - } - - log_info("Found %d Azure resources already created in group \"%s\"", - count, group); - - for (int index = 0; index < count; index++) - { - JSON_Object *jsObj = json_array_get_object(jsArray, index); - - char *name = (char *) json_object_get_string(jsObj, "name"); - char *type = (char *) json_object_get_string(jsObj, "resourceType"); - - if (streq(type, "Microsoft.Network/virtualNetworks")) - { - strlcpy(azRegion->vnet, name, sizeof(azRegion->vnet)); - - log_info("Found existing vnet \"%s\"", azRegion->vnet); - } - else if (streq(type, "Microsoft.Network/networkSecurityGroups")) - { - strlcpy(azRegion->nsg, name, sizeof(azRegion->nsg)); - - log_info("Found existing nsg \"%s\"", azRegion->nsg); - } - else if (streq(type, "Microsoft.Compute/virtualMachines")) - { - int idx = azure_node_index_from_name(group, name); - - strlcpy(azRegion->vmArray[idx].name, name, NAMEDATALEN); - - log_info("Found existing VM \"%s\"", name); - } - else - { - /* ignore the resource Type listed */ - log_debug("Unknown resource type: \"%s\" with name \"%s\"", - type, name); - } - } - - free(jsonString); - } - else - { - (void) log_program_output(&program, LOG_INFO, LOG_ERROR); - } - free_program(&program); - - return success; -} - - -/* - * azure_show_ip_addresses shows public and private IP addresses for our list - * of nodes created in a specific resource group. - * - * az vm list-ip-addresses -g ha-demo-dim-paris --query '[] [] . { name: virtualMachine.name, "public address": virtualMachine.network.publicIpAddresses[0].ipAddress, "private address": virtualMachine.network.privateIpAddresses[0] }' -o table - */ -bool -azure_show_ip_addresses(const char *group) -{ - char *args[16]; - int argsIndex = 0; - bool success = true; - - Program program = { 0 }; - - char query[BUFSIZE] = { 0 }; - - char command[BUFSIZE] = { 0 }; - - sformat(query, BUFSIZE, - "[] [] . { name: virtualMachine.name, " - "\"public address\": " - "virtualMachine.network.publicIpAddresses[0].ipAddress, " - "\"private address\": " - "virtualMachine.network.privateIpAddresses[0] }"); - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "vm"; - args[argsIndex++] = "list-ip-addresses"; - args[argsIndex++] = "--resource-group"; - args[argsIndex++] = (char *) group; - args[argsIndex++] = "--query"; - args[argsIndex++] = (char *) query; - args[argsIndex++] = "-o"; - args[argsIndex++] = "table"; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - (void) snprintf_program_command_line(&program, command, sizeof(command)); - - log_info("%s", command); - - (void) execute_subprogram(&program); - success = program.returnCode == 0; - - if (success) - { - fformat(stdout, "%s", program.stdOut); - } - else - { - (void) log_program_output(&program, LOG_INFO, LOG_ERROR); - } - free_program(&program); - - return success; -} - - -/* - * azure_fetch_ip_addresses fetches IP address (both public and private) for - * VMs created in an Azure resource group, and fill-in the given array. - */ -bool -azure_fetch_ip_addresses(const char *group, AzureVMipAddresses *vmArray) -{ - char *args[16]; - int argsIndex = 0; - bool success = true; - - Program program = { 0 }; - - char query[BUFSIZE] = { 0 }; - - char command[BUFSIZE] = { 0 }; - - sformat(query, BUFSIZE, - "[] [] . { name: virtualMachine.name, " - "\"public address\": " - "virtualMachine.network.publicIpAddresses[0].ipAddress, " - "\"private address\": " - "virtualMachine.network.privateIpAddresses[0] }"); - - args[argsIndex++] = azureCLI; - args[argsIndex++] = "vm"; - args[argsIndex++] = "list-ip-addresses"; - args[argsIndex++] = "--resource-group"; - args[argsIndex++] = (char *) group; - args[argsIndex++] = "--query"; - args[argsIndex++] = (char *) query; - args[argsIndex++] = "-o"; - args[argsIndex++] = "json"; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - (void) snprintf_program_command_line(&program, command, sizeof(command)); - - if (dryRun) - { - appendPQExpBuffer(azureScript, "\n%s", command); - - return true; - } - - log_info("%s", command); - - (void) execute_subprogram(&program); - success = program.returnCode == 0; - - if (success) - { - JSON_Value *js = json_parse_string(program.stdOut); - JSON_Array *jsArray = json_value_get_array(js); - int count = json_array_get_count(jsArray); - - for (int index = 0; index < count; index++) - { - JSON_Object *jsObj = json_array_get_object(jsArray, index); - char *str = NULL; - int vmIndex = -1; - - str = (char *) json_object_get_string(jsObj, "name"); - - vmIndex = azure_node_index_from_name(group, str); - - if (vmIndex == -1) - { - /* errors have already been logged */ - return false; - } - - strlcpy(vmArray[vmIndex].name, str, NAMEDATALEN); - - str = (char *) json_object_get_string(jsObj, "private address"); - strlcpy(vmArray[vmIndex].private, str, BUFSIZE); - - str = (char *) json_object_get_string(jsObj, "public address"); - strlcpy(vmArray[vmIndex].public, str, BUFSIZE); - - log_debug( - "Parsed VM %d as \"%s\" with public IP %s and private IP %s", - vmIndex, - vmArray[vmIndex].name, - vmArray[vmIndex].public, - vmArray[vmIndex].private); - } - } - else - { - (void) log_program_output(&program, LOG_INFO, LOG_ERROR); - } - free_program(&program); - - return success; -} - - -/* - * run_ssh runs the ssh command to the specified IP address as the given - * username, sharing the current terminal tty. - */ -static bool -run_ssh(const char *username, const char *ip) -{ - char *args[16]; - int argsIndex = 0; - - Program program = { 0 }; - - char ssh[MAXPGPATH] = { 0 }; - char command[BUFSIZE] = { 0 }; - - if (!search_path_first("ssh", ssh, LOG_ERROR)) - { - log_fatal("Failed to find program ssh in PATH"); - return false; - } - - args[argsIndex++] = ssh; - args[argsIndex++] = "-o"; - args[argsIndex++] = "StrictHostKeyChecking=no"; - args[argsIndex++] = "-o"; - args[argsIndex++] = "UserKnownHostsFile /dev/null"; - args[argsIndex++] = "-o"; - args[argsIndex++] = "LogLevel=quiet"; - args[argsIndex++] = "-l"; - args[argsIndex++] = (char *) username; - args[argsIndex++] = (char *) ip; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - program.capture = false; /* don't capture output */ - program.tty = true; /* allow sharing the parent's tty */ - - (void) snprintf_program_command_line(&program, command, sizeof(command)); - - log_info("%s", command); - - (void) execute_subprogram(&program); - - return true; -} - - -/* - * run_ssh_command runs the given command on the remote machine given by ip - * address, as the given username. - */ -static bool -run_ssh_command(const char *username, - const char *ip, - bool tty, - const char *command) -{ - char *args[16]; - int argsIndex = 0; - - Program program = { 0 }; - - char ssh[MAXPGPATH] = { 0 }; - char ssh_command[BUFSIZE] = { 0 }; - - if (!search_path_first("ssh", ssh, LOG_ERROR)) - { - log_fatal("Failed to find program ssh in PATH"); - return false; - } - - args[argsIndex++] = ssh; - - if (tty) - { - args[argsIndex++] = "-t"; - } - - args[argsIndex++] = "-o"; - args[argsIndex++] = "StrictHostKeyChecking=no"; - args[argsIndex++] = "-o"; - args[argsIndex++] = "UserKnownHostsFile /dev/null"; - args[argsIndex++] = "-o"; - args[argsIndex++] = "LogLevel=quiet"; - args[argsIndex++] = "-l"; - args[argsIndex++] = (char *) username; - args[argsIndex++] = (char *) ip; - args[argsIndex++] = "--"; - args[argsIndex++] = (char *) command; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - program.capture = false; /* don't capture output */ - program.tty = true; /* allow sharing the parent's tty */ - - (void) snprintf_program_command_line(&program, ssh_command, BUFSIZE); - - if (dryRun) - { - appendPQExpBuffer(azureScript, "\n%s", ssh_command); - - return true; - } - - log_info("%s", ssh_command); - - (void) execute_subprogram(&program); - - return true; -} - - -/* - * start_ssh_command starts the given command on the remote machine given by ip - * address, as the given username. - */ -static bool -start_ssh_command(const char *username, - const char *ip, - const char *command) -{ - char *args[16]; - int argsIndex = 0; - - Program program = { 0 }; - - char ssh[MAXPGPATH] = { 0 }; - char ssh_command[BUFSIZE] = { 0 }; - - if (!search_path_first("ssh", ssh, LOG_ERROR)) - { - log_fatal("Failed to find program ssh in PATH"); - return false; - } - - args[argsIndex++] = ssh; - args[argsIndex++] = "-o"; - args[argsIndex++] = "StrictHostKeyChecking=no"; - args[argsIndex++] = "-o"; - args[argsIndex++] = "UserKnownHostsFile /dev/null"; - args[argsIndex++] = "-o"; - args[argsIndex++] = "LogLevel=quiet"; - args[argsIndex++] = "-l"; - args[argsIndex++] = (char *) username; - args[argsIndex++] = (char *) ip; - args[argsIndex++] = "--"; - args[argsIndex++] = (char *) command; - args[argsIndex++] = NULL; - - (void) initialize_program(&program, args, false); - - (void) snprintf_program_command_line(&program, ssh_command, BUFSIZE); - - if (dryRun) - { - appendPQExpBuffer(azureScript, "\n%s", ssh_command); - - return true; - } - - return azure_start_command(&program); -} - - -/* - * azure_fetch_vm_addresses fetches a given VM addresses. - */ -static bool -azure_fetch_vm_addresses(const char *group, const char *vm, - AzureVMipAddresses *addresses) -{ - char groupName[BUFSIZE] = { 0 }; - char vmName[BUFSIZE] = { 0 }; - int vmIndex = -1; - - AzureVMipAddresses vmAddresses[MAX_VMS_PER_REGION] = { 0 }; - - /* if the vmName is already complete, just use it already */ - if (strstr(vm, group) == NULL) - { - sformat(vmName, sizeof(vmName), "%s-%s", group, vm); - } - else - { - sformat(vmName, sizeof(vmName), "%s", vm); - } - - vmIndex = azure_node_index_from_name(group, vmName); - - if (vmIndex == -1) - { - /* errors have already been logged */ - return false; - } - - /* - * It takes as much time fetching all the IP addresses at once compared to - * fetching a single IP address, so we always fetch them all internally. - */ - if (!azure_fetch_ip_addresses(group, vmAddresses)) - { - /* errors have already been logged */ - return false; - } - - if (IS_EMPTY_STRING_BUFFER(vmAddresses[vmIndex].name)) - { - log_error( - "Failed to find Virtual Machine \"%s\" in resource group \"%s\"", - vmName, groupName); - return false; - } - - /* copy the structure wholesale to the target address */ - *addresses = vmAddresses[vmIndex]; - - return true; -} - - -/* - * azure_vm_ssh runs an ssh command to the given VM public IP address. - */ -bool -azure_vm_ssh(const char *group, const char *vm) -{ - AzureVMipAddresses addresses = { 0 }; - - if (!azure_fetch_vm_addresses(group, vm, &addresses)) - { - /* errors have already been logged */ - return false; - } - - return run_ssh("ha-admin", addresses.public); -} - - -/* - * azure_vm_ssh runs an ssh command to the given VM public IP address. - */ -bool -azure_vm_ssh_command(const char *group, - const char *vm, - bool tty, - const char *command) -{ - AzureVMipAddresses addresses = { 0 }; - - if (!azure_fetch_vm_addresses(group, vm, &addresses)) - { - /* errors have already been logged */ - return false; - } - - return run_ssh_command("ha-admin", addresses.public, tty, command); -} - - -/* - * azure_create_region creates a region on Azure and prepares it for - * pg_auto_failover demo/QA activities. - * - * We need to create a vnet, a subnet, a network security group with a rule - * that opens ports 22 (ssh) and 5432 (Postgres) for direct access from the - * current IP address of the "client" machine where this pg_autoctl command is - * being run. - */ -bool -azure_create_region(AzureRegionResources *azRegion) -{ - AzureRegionResources azRegionFound = { 0 }; - - /* - * Fetch Azure objects that might have already been created in the target - * resource group, we're going to re-use them, allowing the command to be - * run several times in a row and then "fix itself", or at least continue - * from where it failed. - */ - if (!dryRun) - { - if (!azure_fetch_resource_list(azRegion->group, &azRegionFound)) - { - /* errors have already been logged */ - return false; - } - } - - /* - * First create the resource group in the target location. - */ - if (!azure_create_group(azRegion->group, azRegion->location)) - { - /* errors have already been logged */ - return false; - } - - /* never skip a step when --script is used */ - if (dryRun || IS_EMPTY_STRING_BUFFER(azRegionFound.vnet)) - { - if (!azure_create_vnet(azRegion->group, - azRegion->vnet, - azRegion->vnetPrefix)) - { - /* errors have already been logged */ - return false; - } - } - else - { - log_info("Skipping creation of vnet \"%s\" which already exist", - azRegion->vnet); - } - - /* - * Get our IP address as seen by the outside world. - */ - if (!azure_get_remote_ip(azRegion->ipAddress, sizeof(azRegion->ipAddress))) - { - /* errors have already been logged */ - return false; - } - - /* - * Create the network security group. - */ - if (dryRun || IS_EMPTY_STRING_BUFFER(azRegionFound.nsg)) - { - if (!azure_create_nsg(azRegion->group, azRegion->nsg)) - { - /* errors have already been logged */ - return false; - } - } - else - { - log_info("Skipping creation of nsg \"%s\" which already exist", - azRegion->nsg); - } - - /* - * Create the network security rules for SSH and Postgres protocols. - * - * Some objects won't show up in the list from azure_fetch_resource_list - * and it would be quite surprising that we find everything but those, so - * we skip their creation even though we don't see them in azRegionFound. - */ - if (dryRun || IS_EMPTY_STRING_BUFFER(azRegionFound.nsg)) - { - if (!azure_create_nsg_rule(azRegion->group, - azRegion->nsg, - azRegion->rule, - azRegion->ipAddress)) - { - /* errors have already been logged */ - return false; - } - } - else - { - log_info("Skipping creation of nsg rule \"%s\", " - "because nsg \"%s\" already exists", - azRegion->rule, - azRegion->nsg); - } - - /* - * Create the network subnet using previous network security group. - */ - if (dryRun || IS_EMPTY_STRING_BUFFER(azRegionFound.vnet)) - { - if (!azure_create_subnet(azRegion->group, - azRegion->vnet, - azRegion->subnet, - azRegion->subnetPrefix, - azRegion->nsg)) - { - /* errors have already been logged */ - return false; - } - } - else - { - log_info("Skipping creation of subnet \"%s\" for prefix \"%s\", " - "because vnet \"%s\" already exists", - azRegion->subnet, - azRegion->subnetPrefix, - azRegion->vnet); - } - - /* - * Now is time to create the virtual machines. - */ - return azure_provision_nodes(azRegion); -} - - -/* - * azure_drop_region runs the command az group delete --name ... --yes - */ -bool -azure_drop_region(AzureRegionResources *azRegion) -{ - return az_group_delete(azRegion->group); -} - - -/* - * azure_provision_nodes creates the pg_autoctl VM nodes that we need, and - * provision them with our provisioning script. - */ -bool -azure_provision_nodes(AzureRegionResources *azRegion) -{ - if (!azure_fetch_ip_addresses(azRegion->group, azRegion->vmArray)) - { - /* errors have already been logged */ - return false; - } - - if (azRegion->monitor > 0 || azRegion->nodes > 0) - { - /* - * Here we run the following commands: - * - * $ az vm create --name a & - * $ az vm create --name b & - * $ wait - * - * $ az vm run-command invoke --name a --scripts ... & - * $ az vm run-command invoke --name b --scripts ... & - * $ wait - * - * We could optimize our code so that we run the provisioning scripts - * for a VM as soon as it's been created, without having to wait until - * the other VMs are created. Two things to keep in mind, though: - * - * - overall, being cleverer here might not be a win as we're going to - * have to wait until all the VMs are provisioned anyway - * - * - in dry-run mode (--script), we still want to produce the more - * naive script as shown above, for lack of known advanced control - * structures in the target shell (we don't require a specific one). - */ - if (!azure_create_vms(azRegion, "debian", "ha-admin")) - { - /* errors have already been logged */ - return false; - } - - if (!azure_provision_vms(azRegion, azRegion->fromSource)) - { - /* errors have already been logged */ - return false; - } - - /* - * When provisioning from sources, after the OS related steps in - * azure_provision_vms, we still need to upload our local sources (this - * requires rsync to have been installed in the previous step), and to - * build our software from same sources. - */ - if (azRegion->fromSource) - { - if (!azure_rsync_vms(azRegion)) - { - /* errors have already been logged */ - return false; - } - - return azure_build_pg_autoctl(azRegion); - } - } - - return true; -} - - -/* - * azure_deploy_monitor deploys pg_autoctl on a monitor node, running both the - * pg_autoctl create monitor command and then the systemd integration commands. - */ -bool -azure_deploy_monitor(AzureRegionResources *azRegion) -{ - KeyVal env = { 0 }; - char create_monitor[BUFSIZE] = { 0 }; - - char *systemd = - "pg_autoctl -q show systemd --pgdata /home/ha-admin/monitor " - "> pgautofailover.service; " - "sudo mv pgautofailover.service /etc/systemd/system; " - "sudo systemctl daemon-reload; " - "sudo systemctl enable pgautofailover; " - "sudo systemctl start pgautofailover"; - - bool tty = false; - char *host = azRegion->vmArray[0].public; - - if (!azure_prepare_target_versions(&env)) - { - /* errors have already been logged */ - return false; - } - - /* build pg_autoctl create monitor command with target Postgres version */ - sformat(create_monitor, sizeof(create_monitor), - "pg_autoctl create monitor " - "--auth trust " - "--ssl-self-signed " - "--pgdata /home/ha-admin/monitor " - "--pgctl /usr/lib/postgresql/%s/bin/pg_ctl", - - /* AZ_PG_VERSION */ - env.values[0]); - - if (azRegion->monitor == 0) - { - /* no monitor to deploy, we're done already */ - return true; - } - - /* the monitor is always at index 0 in the vmArray */ - if (!run_ssh_command("ha-admin", host, tty, create_monitor)) - { - /* errors have already been logged */ - return false; - } - - if (!run_ssh_command("ha-admin", host, tty, systemd)) - { - /* errors have already been logged */ - return false; - } - - return true; -} - - -/* - * azure_deploy_postgres deploys pg_autoctl on a Postgres node, running both - * the pg_autoctl create postgres command and then the systemd integration - * commands. - */ -bool -azure_deploy_postgres(AzureRegionResources *azRegion, int vmIndex) -{ - KeyVal env = { 0 }; - char create_postgres[BUFSIZE] = { 0 }; - - char *systemd = - "pg_autoctl -q show systemd --pgdata /home/ha-admin/pgdata " - "> pgautofailover.service; " - "sudo mv pgautofailover.service /etc/systemd/system; " - "sudo systemctl daemon-reload; " - "sudo systemctl enable pgautofailover; " - "sudo systemctl start pgautofailover"; - - bool tty = false; - char *host = azRegion->vmArray[vmIndex].public; - - if (!azure_prepare_target_versions(&env)) - { - /* errors have already been logged */ - return false; - } - - /* build pg_autoctl create monitor command with target Postgres version */ - sformat(create_postgres, sizeof(create_postgres), - "pg_autoctl create postgres " - "--pgctl /usr/lib/postgresql/%s/bin/pg_ctl " - "--pgdata /home/ha-admin/pgdata " - "--auth trust " - "--ssl-self-signed " - "--username ha-admin " - "--dbname appdb " - "--hostname %s " - "--name %s-%c " - "--monitor " - "'postgres://autoctl_node@%s/pg_auto_failover?sslmode=require'", - - /* AZ_PG_VERSION */ - env.values[0], - azRegion->vmArray[vmIndex].private, - azRegion->region, - 'a' + vmIndex - 1, - azRegion->vmArray[0].private); - - /* the monitor is always at index 0 in the vmArray */ - if (!run_ssh_command("ha-admin", host, tty, create_postgres)) - { - /* errors have already been logged */ - return false; - } - - if (!run_ssh_command("ha-admin", host, tty, systemd)) - { - /* errors have already been logged */ - return false; - } - - return true; -} - - -/* - * azure_create_nodes run the pg_autoctl commands that create our nodes, and - * then register them with systemd on the remote VMs. - */ -bool -azure_create_nodes(AzureRegionResources *azRegion) -{ - bool success = true; - - if (!azure_fetch_ip_addresses(azRegion->group, azRegion->vmArray)) - { - /* errors have already been logged */ - return false; - } - - if (azRegion->monitor > 0) - { - success = success && azure_deploy_monitor(azRegion); - } - - /* - * Now prepare all the other nodes, one at a time, so that we have a the - * primary, etc. It could also be all at once, but one at a time is good - * for a tutorial. - */ - for (int vmIndex = 1; vmIndex <= azRegion->nodes; vmIndex++) - { - success = success && azure_deploy_postgres(azRegion, vmIndex); - } - - return success; -} - - -/* - * azure_deploy_vm deploys a vm given by name ("monitor", "a", ...). - */ -bool -azure_deploy_vm(AzureRegionResources *azRegion, const char *vmName) -{ - int vmIndex = -1; - - if (!azure_fetch_ip_addresses(azRegion->group, azRegion->vmArray)) - { - /* errors have already been logged */ - return false; - } - - vmIndex = azure_node_index_from_name(azRegion->group, vmName); - - switch (vmIndex) - { - case -1: - { - /* errors have already been logged */ - return false; - } - - case 0: - { - return azure_deploy_monitor(azRegion); - } - - default: - { - return azure_deploy_postgres(azRegion, vmIndex); - } - } -} - - -/* - * azure_ls lists the azure resources we created in a specific resource group. - */ -bool -azure_ls(AzureRegionResources *azRegion) -{ - return azure_resource_list(azRegion->group); -} - - -/* - * azure_show_ips shows the azure ip addresses for the VMs we created in a - * specific resource group. - */ -bool -azure_show_ips(AzureRegionResources *azRegion) -{ - return azure_show_ip_addresses(azRegion->group); -} - - -/* - * azure_ssh runs the ssh -l ha-admin command for given - * node in given azure group, identified as usual with a prefix and a name. - */ -bool -azure_ssh(AzureRegionResources *azRegion, const char *vm) -{ - /* return azure_vm_ssh_command(groupName, vm, true, "watch date -R"); */ - return azure_vm_ssh(azRegion->group, vm); -} - - -/* - * azure_ssh_command runs the ssh -l ha-admin for - * given node in given azure group, identified as usual with a prefix and a - * name. - */ -bool -azure_ssh_command(AzureRegionResources *azRegion, - const char *vm, bool tty, const char *command) -{ - return azure_vm_ssh_command(azRegion->group, vm, tty, command); -} - - -/* - * azure_sync_source_dir runs rsync in parallel to all the created VMs. - */ -bool -azure_sync_source_dir(AzureRegionResources *azRegion) -{ - if (!azure_fetch_ip_addresses(azRegion->group, azRegion->vmArray)) - { - /* errors have already been logged */ - return false; - } - - if (!azure_rsync_vms(azRegion)) - { - /* errors have already been logged */ - return false; - } - - return azure_build_pg_autoctl(azRegion); -} diff --git a/src/bin/pg_autoctl/azure.h b/src/bin/pg_autoctl/azure.h deleted file mode 100644 index 46d47200d..000000000 --- a/src/bin/pg_autoctl/azure.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * src/bin/pg_autoctl/azure.h - * Implementation of a CLI which lets you call `az` cli commands to prepare - * a pg_auto_failover demo or QA environment. - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the PostgreSQL License. - * - */ - -#ifndef AZURE_H -#define AZURE_H - -#include - -#include "postgres_fe.h" -#include "pqexpbuffer.h" - -#include "defaults.h" -#include "parsing.h" - -/* global variables from azure.c */ -extern bool dryRun; -extern PQExpBuffer azureScript; -extern char azureCLI[MAXPGPATH]; - -/* command line parsing */ -typedef struct AzureOptions -{ - char prefix[NAMEDATALEN]; - char region[NAMEDATALEN]; - char location[NAMEDATALEN]; - - int nodes; - int cidr; - bool fromSource; - bool appNode; - bool monitor; - bool all; - bool watch; -} AzureOptions; - -#define MAX_VMS_PER_REGION 28 /* monitor, then pg ndoes [a-z], then app */ - -typedef struct AzureVMipAddresses -{ - char name[NAMEDATALEN]; - char public[BUFSIZE]; - char private[BUFSIZE]; -} AzureVMipAddresses; - -typedef struct AzureRegionResources -{ - char filename[MAXPGPATH]; /* on-disk configuration file path */ - char prefix[NAMEDATALEN]; /* ha-demo-dim- */ - char region[NAMEDATALEN]; /* nickname, such as paris */ - char location[NAMEDATALEN]; /* francecentral, eastus, etc */ - - char group[NAMEDATALEN]; /* ha-demo-dim-paris */ - char vnet[BUFSIZE]; /* ha-demo-dim-paris-vnet */ - char nsg[BUFSIZE]; /* ha-demo-dim-paris-nsg */ - char rule[BUFSIZE]; /* ha-demo-dim-paris-ssh-and-pg */ - char subnet[BUFSIZE]; /* ha-demo-dim-paris-subnet */ - - char vnetPrefix[BUFSIZE]; /* 10.%d.0.0/16 */ - char subnetPrefix[BUFSIZE]; /* 10.%d.%d.0/24 */ - char ipAddress[BUFSIZE]; /* our IP address as seen from the outside */ - - int monitor; /* do we want a monitor in that region? */ - int appNodes; /* application nodes count */ - int nodes; /* node count */ - - bool fromSource; - - AzureVMipAddresses vmArray[MAX_VMS_PER_REGION]; -} AzureRegionResources; - - -bool azure_psleep(int count, bool force); -bool azure_get_remote_ip(char *ipAddress, size_t ipAddressSize); - -bool azure_create_group(const char *name, const char *location); -bool azure_create_vnet(const char *group, const char *name, const char *prefix); -bool azure_create_nsg(const char *group, const char *name); - -bool azure_create_nsg_rule(const char *group, - const char *nsgName, - const char *name, - const char *prefixes); - -bool azure_create_subnet(const char *group, - const char *vnet, - const char *name, - const char *prefixes, - const char *nsg); - -bool az_group_delete(const char *group); - -bool azure_create_vm(AzureRegionResources *azRegion, - const char *name, - const char *image, - const char *username); - -bool azure_create_vms(AzureRegionResources *azRegion, - const char *image, - const char *username); - -bool azure_prepare_target_versions(KeyVal *env); -bool azure_provision_vm(const char *group, const char *name, bool fromSource); -bool azure_provision_vms(AzureRegionResources *azRegion, bool fromSource); - -bool azure_fetch_ip_addresses(const char *group, - AzureVMipAddresses *vmArray); - -bool azure_resource_list(const char *group); -bool azure_show_ip_addresses(const char *group); -bool azure_vm_ssh(const char *group, const char *vm); -bool azure_vm_ssh_command(const char *group, - const char *vm, - bool tty, - const char *command); - -bool azure_create_region(AzureRegionResources *azRegion); -bool azure_drop_region(AzureRegionResources *azRegion); -bool azure_provision_nodes(AzureRegionResources *azRegion); - -bool azure_deploy_monitor(AzureRegionResources *azRegion); -bool azure_deploy_postgres(AzureRegionResources *azRegion, int vmIndex); -bool azure_deploy_vm(AzureRegionResources *azRegion, const char *vmName); - -bool azure_create_nodes(AzureRegionResources *azRegion); - -bool azure_ls(AzureRegionResources *azRegion); -bool azure_show_ips(AzureRegionResources *azRegion); -bool azure_ssh(AzureRegionResources *azRegion, const char *vm); -bool azure_ssh_command(AzureRegionResources *azRegion, - const char *vm, bool tty, const char *command); - -bool azure_sync_source_dir(AzureRegionResources *azRegion); - -/* src/bin/pg_autoctl/cli_do_tmux_azure.c */ -bool tmux_azure_start_or_attach_session(AzureRegionResources *azRegion); -bool tmux_azure_kill_session(AzureRegionResources *azRegion); - -#endif /* AZURE_H */ diff --git a/src/bin/pg_autoctl/azure_config.c b/src/bin/pg_autoctl/azure_config.c deleted file mode 100644 index 479068f49..000000000 --- a/src/bin/pg_autoctl/azure_config.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * src/bin/pg_autoctl/azure_config.c - * Configuration file for azure QA/test environments - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the PostgreSQL License. - * - */ - -#include -#include -#include -#include - -#include "postgres_fe.h" - -#include "azure.h" -#include "azure_config.h" -#include "cli_root.h" -#include "config.h" -#include "defaults.h" -#include "ini_file.h" -#include "file_utils.h" -#include "log.h" -#include "string_utils.h" - -#define OPTION_AZURE_PREFIX(config) \ - make_strbuf_option_default("az", "prefix", "prefix", true, NAMEDATALEN, \ - config->prefix, "ha-demo-") - -#define OPTION_AZURE_REGION(config) \ - make_strbuf_option_default("az", "region", "region", true, NAMEDATALEN, \ - config->region, "paris") - -#define OPTION_AZURE_LOCATION(config) \ - make_strbuf_option_default("az", "location", "location", true, NAMEDATALEN, \ - config->location, "francecentral") - -#define OPTION_AZURE_MONITOR(config) \ - make_int_option_default("group", "monitor", "monitor", true, \ - &(config->monitor), 1) - -#define OPTION_AZURE_NODES(config) \ - make_int_option_default("group", "nodes", "nodes", true, \ - &(config->nodes), 2) - -#define OPTION_AZURE_APP_NODES(config) \ - make_int_option_default("group", "appNodes", NULL, true, \ - &(config->appNodes), 0) - -#define OPTION_AZURE_GROUP(config) \ - make_strbuf_option("resource", "group", NULL, false, NAMEDATALEN, \ - config->group) - -#define OPTION_AZURE_VNET(config) \ - make_strbuf_option("resource", "vnet", NULL, false, NAMEDATALEN, \ - config->vnet) - -#define OPTION_AZURE_NSG(config) \ - make_strbuf_option("resource", "nsg", NULL, false, NAMEDATALEN, \ - config->nsg) - -#define OPTION_AZURE_RULE(config) \ - make_strbuf_option("resource", "rule", NULL, false, NAMEDATALEN, \ - config->rule) - -#define OPTION_AZURE_SUBNET(config) \ - make_strbuf_option("resource", "subnet", NULL, false, NAMEDATALEN, \ - config->subnet) - - -#define SET_INI_OPTIONS_ARRAY(config) \ - { \ - OPTION_AZURE_PREFIX(config), \ - OPTION_AZURE_REGION(config), \ - OPTION_AZURE_LOCATION(config), \ - OPTION_AZURE_MONITOR(config), \ - OPTION_AZURE_NODES(config), \ - OPTION_AZURE_APP_NODES(config), \ - OPTION_AZURE_GROUP(config), \ - OPTION_AZURE_VNET(config), \ - OPTION_AZURE_NSG(config), \ - OPTION_AZURE_RULE(config), \ - OPTION_AZURE_SUBNET(config), \ - INI_OPTION_LAST \ - } - - -/* - * azure_config_read_file reads our azure configuration from an INI - * configuration file that has been previously created by our pg_autoctl do - * azure commands. - */ -bool -azure_config_read_file(AzureRegionResources *azRegion) -{ - IniOption azureOptions[] = SET_INI_OPTIONS_ARRAY(azRegion); - - log_debug("Reading azure configuration from %s", azRegion->filename); - - if (!read_ini_file(azRegion->filename, azureOptions)) - { - log_error("Failed to parse azure configuration file \"%s\"", - azRegion->filename); - return false; - } - - return true; -} - - -/* - * azure_config_write write the current azure config to given STREAM. - */ -bool -azure_config_write(FILE *stream, AzureRegionResources *azRegion) -{ - IniOption azureOptions[] = SET_INI_OPTIONS_ARRAY(azRegion); - - return write_ini_to_stream(stream, azureOptions); -} - - -/* - * azure_config_write_file writes the current values in given azRegion to the - * given filename. - */ -bool -azure_config_write_file(AzureRegionResources *azRegion) -{ - bool success = false; - FILE *fileStream = NULL; - - log_trace("azure_config_write_file \"%s\"", azRegion->filename); - - fileStream = fopen_with_umask(azRegion->filename, "w", FOPEN_FLAGS_W, 0644); - if (fileStream == NULL) - { - /* errors have already been logged */ - return false; - } - - success = azure_config_write(fileStream, azRegion); - - if (fclose(fileStream) == EOF) - { - log_error("Failed to write file \"%s\"", azRegion->filename); - return false; - } - - return success; -} - - -/* - * azure_config_prepare prepares the names we use for the different - * Azure network objects that we need: vnet, nsg, nsgrule, subnet. - */ -void -azure_config_prepare(AzureOptions *options, AzureRegionResources *azRegion) -{ - /* build the path to our configuration file on-disk */ - if (!build_xdg_path(azRegion->filename, XDG_CONFIG, ".", "azure.cfg")) - { - log_fatal("Failed to prepare azure configuration filename"); - exit(EXIT_CODE_INTERNAL_ERROR); - } - - strlcpy(azRegion->prefix, options->prefix, sizeof(azRegion->prefix)); - strlcpy(azRegion->region, options->region, sizeof(azRegion->region)); - strlcpy(azRegion->location, options->location, sizeof(azRegion->location)); - - sformat(azRegion->group, sizeof(azRegion->group), - "%s-%s", - options->prefix, - options->region); - - /* - * Prepare our Azure object names from the group objects: vnet, subnet, - * nsg, nsg rule. - */ - sformat(azRegion->vnet, sizeof(azRegion->vnet), "%s-net", azRegion->group); - sformat(azRegion->nsg, sizeof(azRegion->nsg), "%s-nsg", azRegion->group); - - sformat(azRegion->rule, sizeof(azRegion->rule), - "%s-ssh-and-pg", azRegion->group); - - sformat(azRegion->subnet, sizeof(azRegion->subnet), - "%s-subnet", azRegion->group); - - /* transform --monitor and --no-app booleans into integer counts */ - azRegion->monitor = options->monitor ? 1 : 0; - azRegion->appNodes = options->appNode ? 1 : 0; - azRegion->nodes = options->nodes; - - azRegion->fromSource = options->fromSource; - - /* - * Prepare vnet and subnet IP addresses prefixes. - */ - sformat(azRegion->vnetPrefix, sizeof(azRegion->vnetPrefix), - "10.%d.0.0/16", - options->cidr); - - sformat(azRegion->subnetPrefix, sizeof(azRegion->subnetPrefix), - "10.%d.%d.0/24", - options->cidr, - options->cidr); -} diff --git a/src/bin/pg_autoctl/azure_config.h b/src/bin/pg_autoctl/azure_config.h deleted file mode 100644 index aa2b4b13d..000000000 --- a/src/bin/pg_autoctl/azure_config.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * src/bin/pg_autoctl/azure_config.h - * Implementation of a CLI which lets you call `az` cli commands to prepare - * a pg_auto_failover demo or QA environment. - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the PostgreSQL License. - * - */ - -#ifndef AZURE_CONFIG_H -#define AZURE_CONFIG_H - -#include - -#include "postgres_fe.h" -#include "pqexpbuffer.h" - -#include "azure.h" -#include "defaults.h" - -bool azure_config_read_file(AzureRegionResources *azRegion); -bool azure_config_write(FILE *stream, AzureRegionResources *azRegion); -bool azure_config_write_file(AzureRegionResources *azRegion); - -void azure_config_prepare(AzureOptions *options, AzureRegionResources *azRegion); -bool azure_get_remote_ip(char *ipAddress, size_t ipAddressSize); - -#endif /* AZURE_CONFIG_H */ diff --git a/src/bin/pg_autoctl/cli_do_azure.c b/src/bin/pg_autoctl/cli_do_azure.c deleted file mode 100644 index 6a218849f..000000000 --- a/src/bin/pg_autoctl/cli_do_azure.c +++ /dev/null @@ -1,627 +0,0 @@ -/* - * src/bin/pg_autoctl/cli_do_azure.c - * Implementation of a CLI which lets you call `az` cli commands to prepare - * a pg_auto_failover demo or QA environment. - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the PostgreSQL License. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "postgres_fe.h" -#include "pqexpbuffer.h" -#include "snprintf.h" - -#include "azure.h" -#include "azure_config.h" -#include "cli_common.h" -#include "cli_do_root.h" -#include "cli_root.h" -#include "commandline.h" -#include "config.h" -#include "env_utils.h" -#include "log.h" -#include "pidfile.h" -#include "signals.h" -#include "string_utils.h" - -#include "runprogram.h" - -static AzureOptions azOptions = { 0 }; -static AzureRegionResources azRegion = { 0 }; - -bool dryRun = false; -PQExpBuffer azureScript = NULL; - -static void outputAzureScript(void); - - -/* - * cli_print_version_getopts parses the CLI options for the pg_autoctl version - * command, which are the usual suspects. - */ -int -cli_do_azure_getopts(int argc, char **argv) -{ - int c, option_index = 0, errors = 0; - int verboseCount = 0; - bool printVersion = false; - - AzureOptions options = { 0 }; - - static struct option long_options[] = { - { "prefix", required_argument, NULL, 'p' }, - { "region", required_argument, NULL, 'r' }, - { "location", required_argument, NULL, 'l' }, - { "from-source", no_argument, NULL, 's' }, - { "nodes", required_argument, NULL, 'N' }, - { "no-monitor", no_argument, NULL, 'M' }, - { "no-app", no_argument, NULL, 'n' }, - { "all", no_argument, NULL, 'A' }, - { "script", no_argument, NULL, 'S' }, - { "watch", no_argument, NULL, 'T' }, - { "az", no_argument, NULL, 'Z' }, - { "cidr", no_argument, NULL, 'c' }, - { "version", no_argument, NULL, 'V' }, - { "verbose", no_argument, NULL, 'v' }, - { "quiet", no_argument, NULL, 'q' }, - { "help", no_argument, NULL, 'h' }, - { NULL, 0, NULL, 0 } - }; - - optind = 0; - - /* set our defaults */ - options.cidr = 11; /* 10.11.0.0/16 and 10.11.11.0/24 */ - options.nodes = 2; - options.fromSource = false; - options.appNode = true; - options.monitor = true; - options.all = false; - options.watch = false; - - strlcpy(options.prefix, "ha-demo", sizeof(options.prefix)); - - /* - * The only command lines that are using keeper_cli_getopt_pgdata are - * terminal ones: they don't accept subcommands. In that case our option - * parsing can happen in any order and we don't need getopt_long to behave - * in a POSIXLY_CORRECT way. - * - * The unsetenv() call allows getopt_long() to reorder arguments for us. - */ - unsetenv("POSIXLY_CORRECT"); - - while ((c = getopt_long(argc, argv, "p:n:l:N:MAWSTVvqh", - long_options, &option_index)) != -1) - { - switch (c) - { - /* { "prefix", required_argument, NULL, 'p' }, */ - case 'p': - { - strlcpy(options.prefix, optarg, NAMEDATALEN); - log_trace("--prefix %s", options.prefix); - break; - } - - /* { "region", required_argument, NULL, 'r' }, */ - case 'r': - { - strlcpy(options.region, optarg, NAMEDATALEN); - log_trace("--region %s", options.region); - break; - } - - /* { "location", required_argument, NULL, 'l' }, */ - case 'l': - { - strlcpy(options.location, optarg, NAMEDATALEN); - log_trace("--location %s", options.location); - break; - } - - /* { "az", no_argument, NULL, 'Z' }, */ - case 'Z': - { - strlcpy(azureCLI, optarg, NAMEDATALEN); - log_trace("--az %s", azureCLI); - break; - } - - /* { "cidr", no_argument, NULL, 'c' }, */ - case 'c': - { - if (!stringToInt(optarg, &options.cidr)) - { - log_error("Failed to parse --cidr number \"%s\"", optarg); - errors++; - } - else if (options.cidr < 1 || options.cidr > 254) - { - log_error("Failed to parse --cidr number \"%s\"", optarg); - errors++; - } - else - { - log_trace("--cidr %d", options.cidr); - } - break; - } - - /* { "nodes", required_argument, NULL, 'N' }, */ - case 'N': - { - if (!stringToInt(optarg, &options.nodes)) - { - log_error("Failed to parse --nodes number \"%s\"", optarg); - errors++; - } - log_trace("--nodes %d", options.nodes); - break; - } - - /* { "no-monitor", no_argument, NULL, 'M' }, */ - case 'M': - { - options.monitor = false; - log_trace("--no-monitor"); - break; - } - - /* { "no-app", no_argument, NULL, 'n' }, */ - case 'n': - { - options.appNode = false; - log_trace("--no-app"); - break; - } - - /* { "from-source", required_argument, NULL, 's' }, */ - case 's': - { - options.fromSource = true; - log_trace("--from-source"); - break; - } - - /* { "all", no_argument, NULL, 'A' }, */ - case 'A': - { - options.all = true; - log_trace("--monitor"); - break; - } - - /* { "script", no_argument, NULL, 'S' }, */ - case 'S': - { - dryRun = true; - log_trace("--script"); - break; - } - - /* { "watch", no_argument, NULL, 'T' }, */ - case 'T': - { - options.watch = true; - log_trace("--watch"); - break; - } - - case 'h': - { - commandline_help(stderr); - exit(EXIT_CODE_QUIT); - break; - } - - case 'V': - { - /* keeper_cli_print_version prints version and exits. */ - printVersion = true; - break; - } - - case 'v': - { - ++verboseCount; - switch (verboseCount) - { - case 1: - { - log_set_level(LOG_INFO); - break; - } - - case 2: - { - log_set_level(LOG_DEBUG); - break; - } - - default: - { - log_set_level(LOG_TRACE); - break; - } - } - break; - } - - case 'q': - { - log_set_level(LOG_ERROR); - break; - } - - default: - { - /* getopt_long already wrote an error message */ - errors++; - break; - } - } - } - - if (IS_EMPTY_STRING_BUFFER(options.prefix)) - { - ++errors; - log_fatal("--prefix is a mandatory option"); - } - - if (IS_EMPTY_STRING_BUFFER(azureCLI)) - { - if (!search_path_first("az", azureCLI, LOG_ERROR)) - { - ++errors; - log_fatal("Failed to find program \"%s\" in PATH", "az"); - } - } - else - { - if (!file_exists(azureCLI)) - { - ++errors; - log_fatal("No such file or directory: \"%s\"", azureCLI); - } - } - - if (errors > 0) - { - commandline_help(stderr); - exit(EXIT_CODE_BAD_ARGS); - } - - if (printVersion) - { - keeper_cli_print_version(argc, argv); - } - - /* - * From command line options parsing, prepare a AzureRegionResources in our - * static place. - * - * If a configuration file exists already, it takes precendence, because we - * have probably already created all the resources on Azure and deployed - * things there. - * - * If no configuration file exists already, we create one filled with the - * options given in the command line. - */ - (void) azure_config_prepare(&options, &azRegion); - - if (file_exists(azRegion.filename)) - { - log_info("Reading configuration from \"%s\"", azRegion.filename); - - if (!azure_config_read_file(&azRegion)) - { - /* errors have already been logged */ - exit(EXIT_CODE_BAD_CONFIG); - } - - /* maybe late we will merge new options in the pre-existing file */ - log_warn("Ignoring command line options, " - "configuration file takes precedence"); - - log_info("Using --prefix \"%s\" --region \"%s\" --location \"%s\"", - azRegion.prefix, - azRegion.region, - azRegion.location); - } - else - { - if (!azure_config_write_file(&azRegion)) - { - /* errors have already been logged */ - exit(EXIT_CODE_INTERNAL_ERROR); - } - } - - /* when a configuration file already exists, it provides the location */ - if (IS_EMPTY_STRING_BUFFER(azRegion.location)) - { - log_fatal("--location is a mandatory option"); - exit(EXIT_CODE_BAD_ARGS); - } - - /* - * In --script mode (or dry run) we generate a script with the commands we - * would run instead of actually running them. - */ - if (dryRun) - { - azureScript = createPQExpBuffer(); - - if (azureScript == NULL) - { - log_error("Failed to allocate memory"); - exit(EXIT_CODE_INTERNAL_ERROR); - } - - appendPQExpBuffer(azureScript, - "# azure commands for pg_auto_failover demo"); - } - - /* publish parsed options */ - azOptions = options; - - return optind; -} - - -/* - * outputAzureScript writes the azure script to stdout. - */ -static void -outputAzureScript() -{ - if (dryRun) - { - fformat(stdout, "%s\n", azureScript->data); - destroyPQExpBuffer(azureScript); - } -} - - -/* - * cli_do_azure_create_environment creates an Azure region with some nodes and - * network rules for a demo or QA context of pg_auto_failover, then provision - * those VMs with the needed software, and then create pg_auto_failover nodes - * from that, in a tmux session for interactive QA. - */ -void -cli_do_azure_create_environment(int argc, char **argv) -{ - /* - * azure_create_region creates the resources we need (VMs, network, access - * rules, etc) and then provision the VMs with the needed software. - */ - if (!azure_create_region(&azRegion)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } - - (void) outputAzureScript(); - - /* - * tmux_azure_start_or_attach_session then creates a tmux session with a - * shell window for each VM in the Azure resource group, and in each - * session in parallel runs the pg_autoctl create commands, and then add - * the setup to systemd. - * - * Another tmux window is created to run pg_autoctl show state in a watch - * loop. - * - * An extra window is created for interactive tinkering with the QA - * environment thus provided. - */ - if (!tmux_azure_start_or_attach_session(&azRegion)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } -} - - -/* - * cli_do_azure_create_region creates an Azure region with some nodes and - * network rules for a demo or QA context of pg_auto_failover. - */ -void -cli_do_azure_create_region(int argc, char **argv) -{ - if (!azure_create_region(&azRegion)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } - - (void) outputAzureScript(); -} - - -/* - * cli_do_azure_drop_region drops the azure resource group that has been - * created to host the azure resources in use for the environment. - */ -void -cli_do_azure_drop_region(int argc, char **argv) -{ - if (!azure_drop_region(&azRegion)) - { - log_warn("Configuration file \"%s\" has not been deleted", - azRegion.filename); - exit(EXIT_CODE_INTERNAL_ERROR); - } - - log_info("Killing tmux sessions \"%s\"", azRegion.group); - tmux_azure_kill_session(&azRegion); - - log_info("Removing azure configuration file \"%s\"", azRegion.filename); - - if (!unlink_file(azRegion.filename)) - { - log_fatal("Failed to remove azure configuration file"); - exit(EXIT_CODE_INTERNAL_ERROR); - } - - (void) outputAzureScript(); -} - - -/* - * cli_do_azure_deploy deploys the pg_autoctl services in the target VM, given - * by name (such as "monitor" or "a" or "b", etc). - */ -void -cli_do_azure_deploy(int argc, char **argv) -{ - if (argc != 1) - { - (void) commandline_print_usage(&do_azure_ssh, stderr); - exit(EXIT_CODE_BAD_ARGS); - } - - if (!azure_deploy_vm(&azRegion, argv[0])) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } - - (void) outputAzureScript(); -} - - -/* - * cli_do_azure_create_nodes creates the pg_autoctl services in an Azure - * region that's been created and provisionned before. - */ -void -cli_do_azure_create_nodes(int argc, char **argv) -{ - if (!azure_create_nodes(&azRegion)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } - - (void) outputAzureScript(); -} - - -/* - * cli_do_azure_ls lists Azure resources created in the target region. - */ -void -cli_do_azure_ls(int argc, char **argv) -{ - if (!azure_ls(&azRegion)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } -} - - -/* - * cli_do_azure_show_ips lists Azure ip addresses assigned to created VMs in a - * specific region. - */ -void -cli_do_azure_show_ips(int argc, char **argv) -{ - if (!azure_show_ips(&azRegion)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } -} - - -/* - * cli_do_azure_ssh starts an ssh command to the given Azure VM in a specific - * prefix and region name. - */ -void -cli_do_azure_ssh(int argc, char **argv) -{ - if (argc != 1) - { - (void) commandline_print_usage(&do_azure_ssh, stderr); - exit(EXIT_CODE_BAD_ARGS); - } - - if (!azure_ssh(&azRegion, argv[0])) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } -} - - -/* - * cli_do_azure_rsync uses rsync to upload the current sources to all the - * created VMs in the target region. - */ -void -cli_do_azure_rsync(int argc, char **argv) -{ - if (!azure_sync_source_dir(&azRegion)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } -} - - -/* - * cli_do_azure_ssh starts an ssh command to the given Azure VM in a specific - * prefix and region name. - */ -void -cli_do_azure_show_state(int argc, char **argv) -{ - char *pg_autoctl_command = - azOptions.watch - ? "watch -n 0.2 pg_autoctl show state --pgdata ./monitor" - : "pg_autoctl show state --pgdata ./monitor"; - - if (!azure_ssh_command(&azRegion, - "monitor", - azOptions.watch, /* tty is needed for watch */ - pg_autoctl_command)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } -} - - -/* - * cli_do_azure_tmux_session starts or re-attach to a tmux session from where - * to control the VMs in the QA environment on Azure. - */ -void -cli_do_azure_tmux_session(int argc, char **argv) -{ - if (!tmux_azure_start_or_attach_session(&azRegion)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } -} - - -/* - * cli_do_azure_tmux_session starts or re-attach to a tmux session from where - * to control the VMs in the QA environment on Azure. - */ -void -cli_do_azure_tmux_kill(int argc, char **argv) -{ - if (!tmux_azure_kill_session(&azRegion)) - { - exit(EXIT_CODE_INTERNAL_ERROR); - } -} diff --git a/src/bin/pg_autoctl/cli_do_tmux_azure.c b/src/bin/pg_autoctl/cli_do_tmux_azure.c deleted file mode 100644 index f4a5373ed..000000000 --- a/src/bin/pg_autoctl/cli_do_tmux_azure.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * src/bin/pg_autoctl/cli_do_tmux_azure.c - * - * Implementation of commands that create a tmux session to connect to a - * set of Azure VMs where we run pg_autoctl nodes for QA and testing. - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the PostgreSQL License. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "postgres_fe.h" -#include "pqexpbuffer.h" -#include "snprintf.h" - -#include "azure.h" -#include "azure_config.h" -#include "cli_common.h" -#include "cli_do_root.h" -#include "cli_do_tmux.h" -#include "cli_root.h" -#include "commandline.h" -#include "config.h" -#include "env_utils.h" -#include "log.h" -#include "parsing.h" -#include "pidfile.h" -#include "signals.h" -#include "string_utils.h" - -#include "runprogram.h" - -static void tmux_azure_new_session(PQExpBuffer script, - AzureRegionResources *azRegion); - -static void tmux_azure_deploy(PQExpBuffer script, - AzureRegionResources *azRegion, - const char *vmName); - -static void tmux_azure_ssh(PQExpBuffer script, AzureRegionResources *azRegion, - const char *vmName); - -static void tmux_azure_systemctl_status(PQExpBuffer script, - AzureRegionResources *azRegion); - -static void prepare_tmux_azure_script(AzureRegionResources *azRegion, - PQExpBuffer script); - - -/* - * tmux_azure_new_session appends a new-session command to the given tmux - * script buffer, using the azure group name for the tmux session name. - */ -static void -tmux_azure_new_session(PQExpBuffer script, AzureRegionResources *azRegion) -{ - tmux_add_command(script, "new-session -s %s", azRegion->group); -} - - -/* - * tmux_azure_deploy_postgres appends a pg_autoctl do azure deploy command for - * the given vmName to the given script buffer. - */ -static void -tmux_azure_deploy(PQExpBuffer script, AzureRegionResources *azRegion, - const char *vmName) -{ - tmux_add_send_keys_command(script, - "%s do azure deploy %s", - pg_autoctl_argv0, - vmName); -} - - -/* - * tmux_azure_ssh appends a pg_autoctl do azure ssh command for the given - * vmName to the given script buffer. - */ -static void -tmux_azure_ssh(PQExpBuffer script, AzureRegionResources *azRegion, - const char *vmName) -{ - tmux_add_send_keys_command(script, - "%s do azure ssh %s", - pg_autoctl_argv0, - vmName); -} - - -/* - * tmux_azure_ssh appends a pg_autoctl do azure ssh command for the given - * vmName to the given script buffer. - */ -static void -tmux_azure_systemctl_status(PQExpBuffer script, - AzureRegionResources *azRegion) -{ - tmux_add_send_keys_command(script, "systemctl status pgautofailover"); -} - - -/* - * tmux_add_environment appends the export VAR=value commands that we need to - * set the environment for pg_autoctl do azure deploy in the shell windows. - */ -static void -tmux_azure_add_environment(PQExpBuffer script, KeyVal *env) -{ - for (int i = 0; i < env->count; i++) - { - tmux_add_send_keys_command(script, - "export %s=%s", - env->keywords[i], - env->values[i]); - } -} - - -/* - * prepare_tmux_script prepares a script for a tmux session with the given - * azure region resources. - */ -static void -prepare_tmux_azure_script(AzureRegionResources *azRegion, PQExpBuffer script) -{ - KeyVal env = { 0 }; - - /* fetch environment and defaults for versions */ - if (!azure_prepare_target_versions(&env)) - { - /* errors have already been logged */ - exit(EXIT_CODE_INTERNAL_ERROR); - } - - tmux_add_command(script, "set-option -g default-shell /bin/bash"); - - tmux_azure_new_session(script, azRegion); - - /* deploy VMs each in a new tmux window */ - for (int vmIndex = 0; vmIndex <= azRegion->nodes; vmIndex++) - { - const char *vmName = azRegion->vmArray[vmIndex].name; - - /* after the first VM, create new tmux windows for each VM */ - if (vmIndex > 0) - { - tmux_add_command(script, "split-window -v"); - tmux_add_command(script, "select-layout even-vertical"); - } - - tmux_azure_add_environment(script, &env); - tmux_azure_deploy(script, azRegion, vmName); - tmux_azure_ssh(script, azRegion, vmName); - tmux_azure_systemctl_status(script, azRegion); - } - - /* add a window for pg_autoctl show state */ - tmux_add_command(script, "split-window -v"); - tmux_add_command(script, "select-layout even-vertical"); - - tmux_add_send_keys_command(script, - "%s do azure show state --watch", - pg_autoctl_argv0); - - /* add a window for interactive pg_autoctl commands */ - tmux_add_command(script, "split-window -v"); - tmux_add_command(script, "select-layout even-vertical"); - tmux_add_send_keys_command(script, - "%s do azure show ips", - pg_autoctl_argv0); -} - - -/* - * cli_do_azure_tmux_session starts a new tmux session for the given azure - * region and resources, or attach an existing session that might be running in - * the background already. - */ -bool -tmux_azure_start_or_attach_session(AzureRegionResources *azRegion) -{ - char tmux[MAXPGPATH] = { 0 }; - - PQExpBuffer script; - char scriptName[MAXPGPATH] = { 0 }; - - if (setenv("PG_AUTOCTL_DEBUG", "1", 1) != 0) - { - log_error("Failed to set environment PG_AUTOCTL_DEBUG: %m"); - return false; - } - - if (!search_path_first("tmux", tmux, LOG_ERROR)) - { - log_fatal("Failed to find program tmux in PATH"); - return false; - } - - /* we might just re-use a pre-existing tmux session */ - if (!dryRun && tmux_has_session(tmux, azRegion->group)) - { - return tmux_attach_session(tmux, azRegion->group); - } - - /* - * Okay, so we have to create the session now. And for that we need the IP - * addresses of the target VMs. - */ - if (!azure_fetch_ip_addresses(azRegion->group, azRegion->vmArray)) - { - /* errors have already been logged */ - return false; - } - - script = createPQExpBuffer(); - if (script == NULL) - { - log_error("Failed to allocate memory"); - return false; - } - - /* prepare the tmux script */ - (void) prepare_tmux_azure_script(azRegion, script); - - /* - * Start a tmux session from the script. - */ - if (dryRun) - { - fformat(stdout, "%s", script->data); - destroyPQExpBuffer(script); - } - else - { - /* write the tmux script to file */ - sformat(scriptName, sizeof(scriptName), "%s.tmux", azRegion->group); - log_info("Writing tmux session script \"%s\"", scriptName); - - if (!write_file(script->data, script->len, scriptName)) - { - log_fatal("Failed to write tmux script at \"%s\"", scriptName); - destroyPQExpBuffer(script); - return false; - } - - if (!tmux_start_server(scriptName, NULL)) - { - log_fatal("Failed to start the tmux session, see above for details"); - destroyPQExpBuffer(script); - return false; - } - } - - return true; -} - - -/* - * tmux_azure_kill_session kills a tmux session for the given QA setup, when - * the tmux session already exists. - */ -bool -tmux_azure_kill_session(AzureRegionResources *azRegion) -{ - return tmux_kill_session_by_name(azRegion->group); -} diff --git a/src/bin/pgaftest/Makefile b/src/bin/pgaftest/Makefile index 0d6e1f9e1..08c200384 100644 --- a/src/bin/pgaftest/Makefile +++ b/src/bin/pgaftest/Makefile @@ -23,10 +23,19 @@ LOCAL_OBJS = $(patsubst %.c,%.o,$(LOCAL_SRC)) # ----------------------------------------------------------------------- # Shared sources compiled from pg_autoctl/ by explicit path # ----------------------------------------------------------------------- -SHARED_SRCS = env_utils.c file_utils.c string_utils.c parsing.c \ - nodestate_utils.c ipaddr.c signals.c pidfile.c \ - pgsetup.c pgsql.c lock_utils.c ini_file.c ini_implementation.c \ - debian.c +# All non-CLI pg_autoctl source files (exclude main.c, demoapp.c, cli_*.c). +# We compile them as shared-%.o to keep them separate from local objects. +SHARED_SRCS = cli_common.c config.c coordinator.c debian.c \ + env_utils.c file_utils.c fsm.c fsm_transition.c \ + fsm_transition_citus.c ini_file.c ini_implementation.c \ + ipaddr.c keeper.c keeper_config.c keeper_pg_init.c \ + lock_utils.c monitor.c monitor_config.c monitor_pg_init.c \ + nodestate_utils.c parsing.c pgctl.c pghba.c pgsetup.c \ + pgsql.c pgtuning.c pidfile.c primary_standby.c \ + service_keeper.c service_keeper_init.c service_monitor.c \ + service_monitor_init.c service_postgres.c service_postgres_ctl.c \ + signals.c state.c string_utils.c supervisor.c system_utils.c \ + systemd_config.c SHARED_OBJS = $(patsubst %.c,shared-%.o,$(SHARED_SRCS)) diff --git a/src/bin/pgaftest/cli_root.c b/src/bin/pgaftest/cli_root.c index 97c12c5dc..815507591 100644 --- a/src/bin/pgaftest/cli_root.c +++ b/src/bin/pgaftest/cli_root.c @@ -13,6 +13,7 @@ #include #include "commandline.h" +#include "defaults.h" #include "log.h" #include "test_spec.h" #include "test_runner.h" diff --git a/src/bin/pgaftest/main.c b/src/bin/pgaftest/main.c index 949e2dbac..a1a90a1ea 100644 --- a/src/bin/pgaftest/main.c +++ b/src/bin/pgaftest/main.c @@ -11,10 +11,33 @@ #include #include "commandline.h" +#include "defaults.h" #include "log.h" +#include "lock_utils.h" +#include "monitor_config.h" extern CommandLine pgaftest_root; +/* + * Globals required by shared pg_autoctl source files. + * In pg_autoctl these live in cli_root.c / cli_create_node.c / main.c. + * pgaftest owns stub definitions here so the linker is satisfied. + */ +int pgconnect_timeout = 2; +char *ps_buffer; +size_t ps_buffer_size; +size_t last_status_len; +Semaphore log_semaphore = { 0 }; + +char pg_autoctl_argv0[MAXPGPATH] = "pgaftest"; +char pg_autoctl_program[MAXPGPATH] = "pgaftest"; + +MonitorConfig monitorOptions = { 0 }; + +/* Stub command roots referenced by cli_common.c's keeper_cli_help */ +CommandLine root = make_command("pgaftest", "", "", "", NULL, NULL); +CommandLine root_with_debug = make_command("pgaftest", "", "", "", NULL, NULL); + int main(int argc, char **argv) { diff --git a/src/bin/pgaftest/test_runner.c b/src/bin/pgaftest/test_runner.c index 0daea1101..01aff9c32 100644 --- a/src/bin/pgaftest/test_runner.c +++ b/src/bin/pgaftest/test_runner.c @@ -14,6 +14,8 @@ #include #include +/* postgres_fe.h must precede pqexpbuffer.h to define pg_attribute_printf and bool */ +#include "postgres_fe.h" #include "libpq-fe.h" #include "pqexpbuffer.h" diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y index 84c524565..827f4fa8c 100644 --- a/src/bin/pgaftest/test_spec_parse.y +++ b/src/bin/pgaftest/test_spec_parse.y @@ -79,8 +79,7 @@ static void register_step(TestSpec *spec, TestStep *step) %token T_IDENT T_STRING T_BLOCK %type ident_or_string -%type step_block cmd_block -%type command command_list +%type cmd_block %% diff --git a/src/bin/pgaftest/test_spec_scan.l b/src/bin/pgaftest/test_spec_scan.l index 3d31f31a5..c9fa9a95d 100644 --- a/src/bin/pgaftest/test_spec_scan.l +++ b/src/bin/pgaftest/test_spec_scan.l @@ -24,7 +24,6 @@ static char *pgaf_strdup(const char *s) %option noyywrap %option nounput -%option noinput %option never-interactive /* multi-line SQL/text block: { ... } */ From 3d421286f93481b141e9d1c182d374e8a0e5e861 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 03:29:16 +0200 Subject: [PATCH 03/48] common: move generic utility sources to src/bin/common/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 16 C source modules and 15 headers moved out of pg_autoctl/ into the shared common/ directory, built once as libpgaf_common.a and linked by both pg_autoctl and pgaftest: debian env_utils file_utils ini_file ini_implementation ipaddr lock_utils parsing pgctl pgsetup pgsql pgtuning pidfile signals string_utils system_utils These are generic PostgreSQL/system infrastructure utilities with no pg_auto_failover FSM/keeper/monitor business logic. pg_autoctl-specific files (keeper*, monitor*, fsm*, coordinator, service_*, state, supervisor, pghba, systemd_config, watch, cli_*) remain in pg_autoctl/. Makefile.common: add COMMON_SRC/COMMON_OBJ/COMMON_LIB variables and rules to build src/bin/common/*.c → libpgaf_common.a. Both pg_autoctl and pgaftest Makefiles add $(COMMON_LIB) to OBJS and depend on it. pgaftest/Makefile: remove the 16 moved modules from SHARED_SRCS; they are now covered by libpgaf_common.a. Include path already has -I../common via Makefile.common so all #include "filename.h" still resolve. --- src/bin/common/Makefile.common | 57 ++++++++++++------- src/bin/{pg_autoctl => common}/debian.c | 0 src/bin/{pg_autoctl => common}/debian.h | 0 src/bin/{pg_autoctl => common}/env_utils.c | 0 src/bin/{pg_autoctl => common}/env_utils.h | 0 src/bin/{pg_autoctl => common}/file_utils.c | 0 src/bin/{pg_autoctl => common}/file_utils.h | 0 src/bin/{pg_autoctl => common}/ini_file.c | 0 src/bin/{pg_autoctl => common}/ini_file.h | 0 .../ini_implementation.c | 0 src/bin/{pg_autoctl => common}/ipaddr.c | 0 src/bin/{pg_autoctl => common}/ipaddr.h | 0 src/bin/{pg_autoctl => common}/lock_utils.c | 0 src/bin/{pg_autoctl => common}/lock_utils.h | 0 src/bin/{pg_autoctl => common}/parsing.c | 0 src/bin/{pg_autoctl => common}/parsing.h | 0 src/bin/{pg_autoctl => common}/pgctl.c | 0 src/bin/{pg_autoctl => common}/pgctl.h | 0 src/bin/{pg_autoctl => common}/pgsetup.c | 0 src/bin/{pg_autoctl => common}/pgsetup.h | 0 src/bin/{pg_autoctl => common}/pgsql.c | 0 src/bin/{pg_autoctl => common}/pgsql.h | 0 src/bin/{pg_autoctl => common}/pgtuning.c | 0 src/bin/{pg_autoctl => common}/pgtuning.h | 0 src/bin/{pg_autoctl => common}/pidfile.c | 0 src/bin/{pg_autoctl => common}/pidfile.h | 0 src/bin/{pg_autoctl => common}/signals.c | 0 src/bin/{pg_autoctl => common}/signals.h | 0 src/bin/{pg_autoctl => common}/string_utils.c | 0 src/bin/{pg_autoctl => common}/string_utils.h | 0 src/bin/{pg_autoctl => common}/system_utils.c | 0 src/bin/{pg_autoctl => common}/system_utils.h | 0 src/bin/pg_autoctl/Makefile | 4 +- src/bin/pgaftest/Makefile | 23 ++++---- 34 files changed, 51 insertions(+), 33 deletions(-) rename src/bin/{pg_autoctl => common}/debian.c (100%) rename src/bin/{pg_autoctl => common}/debian.h (100%) rename src/bin/{pg_autoctl => common}/env_utils.c (100%) rename src/bin/{pg_autoctl => common}/env_utils.h (100%) rename src/bin/{pg_autoctl => common}/file_utils.c (100%) rename src/bin/{pg_autoctl => common}/file_utils.h (100%) rename src/bin/{pg_autoctl => common}/ini_file.c (100%) rename src/bin/{pg_autoctl => common}/ini_file.h (100%) rename src/bin/{pg_autoctl => common}/ini_implementation.c (100%) rename src/bin/{pg_autoctl => common}/ipaddr.c (100%) rename src/bin/{pg_autoctl => common}/ipaddr.h (100%) rename src/bin/{pg_autoctl => common}/lock_utils.c (100%) rename src/bin/{pg_autoctl => common}/lock_utils.h (100%) rename src/bin/{pg_autoctl => common}/parsing.c (100%) rename src/bin/{pg_autoctl => common}/parsing.h (100%) rename src/bin/{pg_autoctl => common}/pgctl.c (100%) rename src/bin/{pg_autoctl => common}/pgctl.h (100%) rename src/bin/{pg_autoctl => common}/pgsetup.c (100%) rename src/bin/{pg_autoctl => common}/pgsetup.h (100%) rename src/bin/{pg_autoctl => common}/pgsql.c (100%) rename src/bin/{pg_autoctl => common}/pgsql.h (100%) rename src/bin/{pg_autoctl => common}/pgtuning.c (100%) rename src/bin/{pg_autoctl => common}/pgtuning.h (100%) rename src/bin/{pg_autoctl => common}/pidfile.c (100%) rename src/bin/{pg_autoctl => common}/pidfile.h (100%) rename src/bin/{pg_autoctl => common}/signals.c (100%) rename src/bin/{pg_autoctl => common}/signals.h (100%) rename src/bin/{pg_autoctl => common}/string_utils.c (100%) rename src/bin/{pg_autoctl => common}/string_utils.h (100%) rename src/bin/{pg_autoctl => common}/system_utils.c (100%) rename src/bin/{pg_autoctl => common}/system_utils.h (100%) diff --git a/src/bin/common/Makefile.common b/src/bin/common/Makefile.common index 2b567e67e..2b308b555 100644 --- a/src/bin/common/Makefile.common +++ b/src/bin/common/Makefile.common @@ -1,8 +1,9 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the PostgreSQL License. # -# Makefile.common — shared build variables included by both pg_autoctl and -# pgaftest Makefiles via: include ../common/Makefile.common +# Makefile.common — shared build variables and common source library. +# Included by both pg_autoctl and pgaftest Makefiles via: +# include ../common/Makefile.common PG_CONFIG ?= pg_config @@ -14,7 +15,8 @@ LOG_SRC = $(wildcard $(LIB_DIR)/log/src/log.*) COMMANDLINE_SRC = $(wildcard $(LIB_DIR)/subcommands.c/commandline.*) PARSON_SRC = $(wildcard $(LIB_DIR)/parson/parson.*) -COMMON_INCLUDES = -I$(LIB_DIR)/pg +COMMON_INCLUDES = -I$(COMMON_DIR) +COMMON_INCLUDES += -I$(LIB_DIR)/pg COMMON_INCLUDES += -I$(LIB_DIR)/log/src/ COMMON_INCLUDES += -I$(LIB_DIR)/subcommands.c/ COMMON_INCLUDES += -I$(LIB_DIR)/libs/ @@ -27,15 +29,6 @@ DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --includedir) DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --includedir-server) DEFAULT_CFLAGS += -I $(shell $(PG_CONFIG) --pkgincludedir)/internal DEFAULT_CFLAGS += $(shell $(PG_CONFIG) --cflags) - -# On macOS, gettext is keg-only and not in the default include path. -# postgres_fe.h → c.h → libintl.h requires finding it explicitly. -ifeq ($(shell uname -s),Darwin) - GETTEXT_PREFIX := $(shell brew --prefix gettext 2>/dev/null) - ifneq ($(GETTEXT_PREFIX),) - DEFAULT_CFLAGS += -I$(GETTEXT_PREFIX)/include - endif -endif DEFAULT_CFLAGS += -Wformat DEFAULT_CFLAGS += -Wall DEFAULT_CFLAGS += -Werror=implicit-int @@ -46,11 +39,13 @@ DEFAULT_CFLAGS += -D_WANT_SEMUN DEFAULT_CFLAGS += -Wno-missing-braces DEFAULT_CFLAGS += $(COMMON_INCLUDES) -ifdef USE_SECURITY_FLAGS -SECURITY_CFLAGS = -fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2 \ - -z noexecstack -fpie -Wl,-pie -Wl,-z,relro -Wl,-z,now \ - -Wformat -Wformat-security -Werror=format-security -DEFAULT_CFLAGS += $(SECURITY_CFLAGS) +# On macOS, gettext is keg-only and not in the default include path. +# postgres_fe.h → c.h → libintl.h requires finding it explicitly. +ifeq ($(shell uname -s),Darwin) + GETTEXT_PREFIX := $(shell brew --prefix gettext 2>/dev/null) + ifneq ($(GETTEXT_PREFIX),) + DEFAULT_CFLAGS += -I$(GETTEXT_PREFIX)/include + endif endif override CFLAGS := $(DEFAULT_CFLAGS) $(CFLAGS) @@ -65,7 +60,31 @@ LIBS += -lpq DEPDIR = .deps -# Shared rule: compile .c → .o with auto-dependency tracking +# ----------------------------------------------------------------------- +# Common source library (src/bin/common/*.c → libpgaf_common.a) +# Callers link with: $(COMMON_LIB) and add $(COMMON_LIB) to OBJS. +# ----------------------------------------------------------------------- + +COMMON_SRC = $(wildcard $(COMMON_DIR)*.c) +COMMON_OBJ = $(patsubst $(COMMON_DIR)%.c,$(COMMON_DIR)%.o,$(COMMON_SRC)) +COMMON_LIB = $(COMMON_DIR)libpgaf_common.a + +# Compile rule for common objects (run from each caller's directory) +$(COMMON_DIR)%.o: $(COMMON_DIR)%.c + @if test ! -d $(COMMON_DIR)$(DEPDIR); then mkdir -p $(COMMON_DIR)$(DEPDIR); fi + $(CC) $(CFLAGS) -c -MMD -MP -MF$(COMMON_DIR)$(DEPDIR)/$(*F).Po -o $@ $< + +$(COMMON_LIB): $(COMMON_OBJ) + $(AR) rcs $@ $^ + +Po_common_files := $(wildcard $(COMMON_DIR)$(DEPDIR)/*.Po) +ifneq (,$(Po_common_files)) +include $(Po_common_files) +endif + +# ----------------------------------------------------------------------- +# Compile rule for caller's own .c → .o with auto-dependency tracking +# ----------------------------------------------------------------------- %.o : %.c @if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/$(*F).Po -o $@ $< @@ -75,7 +94,7 @@ ifneq (,$(Po_files)) include $(Po_files) endif -# Shared rules for vendored libs (callers reference with explicit target names) +# Shared rules for vendored libs lib-snprintf.o: $(PG_SNPRINTF) $(CC) $(CFLAGS) -c -MMD -MP -MF$(DEPDIR)/lib-snprintf.Po -MT$@ \ -o $@ $(LIB_DIR)/pg/snprintf.c diff --git a/src/bin/pg_autoctl/debian.c b/src/bin/common/debian.c similarity index 100% rename from src/bin/pg_autoctl/debian.c rename to src/bin/common/debian.c diff --git a/src/bin/pg_autoctl/debian.h b/src/bin/common/debian.h similarity index 100% rename from src/bin/pg_autoctl/debian.h rename to src/bin/common/debian.h diff --git a/src/bin/pg_autoctl/env_utils.c b/src/bin/common/env_utils.c similarity index 100% rename from src/bin/pg_autoctl/env_utils.c rename to src/bin/common/env_utils.c diff --git a/src/bin/pg_autoctl/env_utils.h b/src/bin/common/env_utils.h similarity index 100% rename from src/bin/pg_autoctl/env_utils.h rename to src/bin/common/env_utils.h diff --git a/src/bin/pg_autoctl/file_utils.c b/src/bin/common/file_utils.c similarity index 100% rename from src/bin/pg_autoctl/file_utils.c rename to src/bin/common/file_utils.c diff --git a/src/bin/pg_autoctl/file_utils.h b/src/bin/common/file_utils.h similarity index 100% rename from src/bin/pg_autoctl/file_utils.h rename to src/bin/common/file_utils.h diff --git a/src/bin/pg_autoctl/ini_file.c b/src/bin/common/ini_file.c similarity index 100% rename from src/bin/pg_autoctl/ini_file.c rename to src/bin/common/ini_file.c diff --git a/src/bin/pg_autoctl/ini_file.h b/src/bin/common/ini_file.h similarity index 100% rename from src/bin/pg_autoctl/ini_file.h rename to src/bin/common/ini_file.h diff --git a/src/bin/pg_autoctl/ini_implementation.c b/src/bin/common/ini_implementation.c similarity index 100% rename from src/bin/pg_autoctl/ini_implementation.c rename to src/bin/common/ini_implementation.c diff --git a/src/bin/pg_autoctl/ipaddr.c b/src/bin/common/ipaddr.c similarity index 100% rename from src/bin/pg_autoctl/ipaddr.c rename to src/bin/common/ipaddr.c diff --git a/src/bin/pg_autoctl/ipaddr.h b/src/bin/common/ipaddr.h similarity index 100% rename from src/bin/pg_autoctl/ipaddr.h rename to src/bin/common/ipaddr.h diff --git a/src/bin/pg_autoctl/lock_utils.c b/src/bin/common/lock_utils.c similarity index 100% rename from src/bin/pg_autoctl/lock_utils.c rename to src/bin/common/lock_utils.c diff --git a/src/bin/pg_autoctl/lock_utils.h b/src/bin/common/lock_utils.h similarity index 100% rename from src/bin/pg_autoctl/lock_utils.h rename to src/bin/common/lock_utils.h diff --git a/src/bin/pg_autoctl/parsing.c b/src/bin/common/parsing.c similarity index 100% rename from src/bin/pg_autoctl/parsing.c rename to src/bin/common/parsing.c diff --git a/src/bin/pg_autoctl/parsing.h b/src/bin/common/parsing.h similarity index 100% rename from src/bin/pg_autoctl/parsing.h rename to src/bin/common/parsing.h diff --git a/src/bin/pg_autoctl/pgctl.c b/src/bin/common/pgctl.c similarity index 100% rename from src/bin/pg_autoctl/pgctl.c rename to src/bin/common/pgctl.c diff --git a/src/bin/pg_autoctl/pgctl.h b/src/bin/common/pgctl.h similarity index 100% rename from src/bin/pg_autoctl/pgctl.h rename to src/bin/common/pgctl.h diff --git a/src/bin/pg_autoctl/pgsetup.c b/src/bin/common/pgsetup.c similarity index 100% rename from src/bin/pg_autoctl/pgsetup.c rename to src/bin/common/pgsetup.c diff --git a/src/bin/pg_autoctl/pgsetup.h b/src/bin/common/pgsetup.h similarity index 100% rename from src/bin/pg_autoctl/pgsetup.h rename to src/bin/common/pgsetup.h diff --git a/src/bin/pg_autoctl/pgsql.c b/src/bin/common/pgsql.c similarity index 100% rename from src/bin/pg_autoctl/pgsql.c rename to src/bin/common/pgsql.c diff --git a/src/bin/pg_autoctl/pgsql.h b/src/bin/common/pgsql.h similarity index 100% rename from src/bin/pg_autoctl/pgsql.h rename to src/bin/common/pgsql.h diff --git a/src/bin/pg_autoctl/pgtuning.c b/src/bin/common/pgtuning.c similarity index 100% rename from src/bin/pg_autoctl/pgtuning.c rename to src/bin/common/pgtuning.c diff --git a/src/bin/pg_autoctl/pgtuning.h b/src/bin/common/pgtuning.h similarity index 100% rename from src/bin/pg_autoctl/pgtuning.h rename to src/bin/common/pgtuning.h diff --git a/src/bin/pg_autoctl/pidfile.c b/src/bin/common/pidfile.c similarity index 100% rename from src/bin/pg_autoctl/pidfile.c rename to src/bin/common/pidfile.c diff --git a/src/bin/pg_autoctl/pidfile.h b/src/bin/common/pidfile.h similarity index 100% rename from src/bin/pg_autoctl/pidfile.h rename to src/bin/common/pidfile.h diff --git a/src/bin/pg_autoctl/signals.c b/src/bin/common/signals.c similarity index 100% rename from src/bin/pg_autoctl/signals.c rename to src/bin/common/signals.c diff --git a/src/bin/pg_autoctl/signals.h b/src/bin/common/signals.h similarity index 100% rename from src/bin/pg_autoctl/signals.h rename to src/bin/common/signals.h diff --git a/src/bin/pg_autoctl/string_utils.c b/src/bin/common/string_utils.c similarity index 100% rename from src/bin/pg_autoctl/string_utils.c rename to src/bin/common/string_utils.c diff --git a/src/bin/pg_autoctl/string_utils.h b/src/bin/common/string_utils.h similarity index 100% rename from src/bin/pg_autoctl/string_utils.h rename to src/bin/common/string_utils.h diff --git a/src/bin/pg_autoctl/system_utils.c b/src/bin/common/system_utils.c similarity index 100% rename from src/bin/pg_autoctl/system_utils.c rename to src/bin/common/system_utils.c diff --git a/src/bin/pg_autoctl/system_utils.h b/src/bin/common/system_utils.h similarity index 100% rename from src/bin/pg_autoctl/system_utils.h rename to src/bin/common/system_utils.h diff --git a/src/bin/pg_autoctl/Makefile b/src/bin/pg_autoctl/Makefile index 1243fb101..0c2834501 100644 --- a/src/bin/pg_autoctl/Makefile +++ b/src/bin/pg_autoctl/Makefile @@ -15,17 +15,19 @@ INCLUDES = $(patsubst $(SRC_DIR)%.h,%.h,$(wildcard $(SRC_DIR)*.h)) SRC = $(patsubst $(SRC_DIR)%.c,%.c,$(wildcard $(SRC_DIR)*.c)) OBJS = $(patsubst %.c,%.o,$(SRC)) OBJS += lib-log.o lib-commandline.o lib-parson.o lib-snprintf.o lib-strerror.o +OBJS += $(COMMON_LIB) # ncurses needed for pg_autoctl watch LIBS += -lncurses -all: $(PG_AUTOCTL) ; +all: $(COMMON_LIB) $(PG_AUTOCTL) ; $(PG_AUTOCTL): $(OBJS) $(INCLUDES) $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ clean: rm -f $(OBJS) $(PG_AUTOCTL) + rm -f $(COMMON_LIB) $(COMMON_OBJ) rm -rf $(DEPDIR) install: $(PG_AUTOCTL) diff --git a/src/bin/pgaftest/Makefile b/src/bin/pgaftest/Makefile index 08c200384..7a77aee1c 100644 --- a/src/bin/pgaftest/Makefile +++ b/src/bin/pgaftest/Makefile @@ -21,26 +21,22 @@ LOCAL_SRC = main.c cli_root.c cli_demo.c \ LOCAL_OBJS = $(patsubst %.c,%.o,$(LOCAL_SRC)) # ----------------------------------------------------------------------- -# Shared sources compiled from pg_autoctl/ by explicit path +# pg_autoctl-specific shared sources (business logic; not in common/). +# Compiled as shared-%.o to distinguish from local objects. # ----------------------------------------------------------------------- -# All non-CLI pg_autoctl source files (exclude main.c, demoapp.c, cli_*.c). -# We compile them as shared-%.o to keep them separate from local objects. -SHARED_SRCS = cli_common.c config.c coordinator.c debian.c \ - env_utils.c file_utils.c fsm.c fsm_transition.c \ - fsm_transition_citus.c ini_file.c ini_implementation.c \ - ipaddr.c keeper.c keeper_config.c keeper_pg_init.c \ - lock_utils.c monitor.c monitor_config.c monitor_pg_init.c \ - nodestate_utils.c parsing.c pgctl.c pghba.c pgsetup.c \ - pgsql.c pgtuning.c pidfile.c primary_standby.c \ +SHARED_SRCS = cli_common.c config.c coordinator.c fsm.c fsm_transition.c \ + fsm_transition_citus.c keeper.c keeper_config.c keeper_pg_init.c \ + monitor.c monitor_config.c monitor_pg_init.c \ + nodestate_utils.c pghba.c primary_standby.c \ service_keeper.c service_keeper_init.c service_monitor.c \ service_monitor_init.c service_postgres.c service_postgres_ctl.c \ - signals.c state.c string_utils.c supervisor.c system_utils.c \ - systemd_config.c + state.c supervisor.c systemd_config.c SHARED_OBJS = $(patsubst %.c,shared-%.o,$(SHARED_SRCS)) OBJS = $(LOCAL_OBJS) $(SHARED_OBJS) OBJS += lib-log.o lib-commandline.o lib-parson.o lib-snprintf.o lib-strerror.o +OBJS += $(COMMON_LIB) INCLUDES = $(wildcard $(SRC_DIR)*.h) @@ -69,13 +65,14 @@ include $(Po_files) endif # ----------------------------------------------------------------------- -all: $(PGAFTEST) ; +all: $(COMMON_LIB) $(PGAFTEST) ; $(PGAFTEST): $(OBJS) $(INCLUDES) $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ clean: rm -f $(OBJS) $(PGAFTEST) test_spec_scan.c test_spec_parse.c test_spec_parse.h + rm -f $(COMMON_LIB) $(COMMON_OBJ) rm -rf $(DEPDIR) install: $(PGAFTEST) From b0d52e0230e5f91ec173f0feadb25fa4604d3879 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 03:34:21 +0200 Subject: [PATCH 04/48] build: fix default-goal bug and two dangling-pointer warnings Default goal (link failure when invoking make directly in a sub-directory): Makefile.common defines as its first explicit target. When included before the 'all:' rule it becomes the default goal, so 'make -C src/bin/pgaftest' rebuilds libpgaf_common.a and exits without ever linking the pgaftest binary. Fix: add .DEFAULT_GOAL := all before the include in both pg_autoctl/Makefile and pgaftest/Makefile. Dangling-pointer warnings in common/: intToString() returns an IntString struct by value. Storing .strValue (a pointer into that temporary) in an array slot or local pointer variable leaves a dangling pointer once the full-expression ends. Fix: capture the IntString in a named local variable so its lifetime covers all subsequent uses of the pointer. - pgctl.c:1635 args[argsIndex] = intToString(pgport).strValue - pgsql.c:1583 nodeIdString = intToString(node->nodeId).strValue --- src/bin/common/pgctl.c | 3 ++- src/bin/common/pgsql.c | 3 ++- src/bin/pg_autoctl/Makefile | 4 ++++ src/bin/pgaftest/Makefile | 4 ++++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/bin/common/pgctl.c b/src/bin/common/pgctl.c index 5b9b523bb..358dead6f 100644 --- a/src/bin/common/pgctl.c +++ b/src/bin/common/pgctl.c @@ -1632,7 +1632,8 @@ pg_ctl_postgres(const char *pg_ctl, const char *pgdata, int pgport, args[argsIndex++] = "-D"; args[argsIndex++] = (char *) pgdata; args[argsIndex++] = "-p"; - args[argsIndex++] = (char *) intToString(pgport).strValue; + IntString pgportStr = intToString(pgport); + args[argsIndex++] = (char *) pgportStr.strValue; if (listen) { diff --git a/src/bin/common/pgsql.c b/src/bin/common/pgsql.c index 450c7e1a5..ce436196c 100644 --- a/src/bin/common/pgsql.c +++ b/src/bin/common/pgsql.c @@ -1580,7 +1580,8 @@ BuildNodesArrayValues(NodeAddressArray *nodeArray, for (nodeIndex = 0; nodeIndex < nodeArray->count; nodeIndex++) { NodeAddress *node = &(nodeArray->nodes[nodeIndex]); - char *nodeIdString = intToString(node->nodeId).strValue; + IntString nodeIdStr = intToString(node->nodeId); + char *nodeIdString = nodeIdStr.strValue; int idParamIndex = paramIndex; int lsnParamIndex = paramIndex + 1; diff --git a/src/bin/pg_autoctl/Makefile b/src/bin/pg_autoctl/Makefile index 0c2834501..b1bc05322 100644 --- a/src/bin/pg_autoctl/Makefile +++ b/src/bin/pg_autoctl/Makefile @@ -5,6 +5,10 @@ PG_AUTOCTL = ./pg_autoctl SRC_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +# Must be set before include so that targets in Makefile.common don't +# become the default goal when included before the all: rule below. +.DEFAULT_GOAL := all + include $(SRC_DIR)../common/Makefile.common # pg_autoctl includes its own source directory too diff --git a/src/bin/pgaftest/Makefile b/src/bin/pgaftest/Makefile index 7a77aee1c..35b98233e 100644 --- a/src/bin/pgaftest/Makefile +++ b/src/bin/pgaftest/Makefile @@ -6,6 +6,10 @@ PGAFTEST = ./pgaftest SRC_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) PGACTL_DIR := $(SRC_DIR)../pg_autoctl/ +# Must be set before include so that targets in Makefile.common don't +# become the default goal when included before the all: rule below. +.DEFAULT_GOAL := all + include $(SRC_DIR)../common/Makefile.common # Include both our own dir and pg_autoctl for shared headers From aee49440f5c771bfaab1cff879a9a65264eb7c0d Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 05:23:06 +0200 Subject: [PATCH 05/48] pgaftest: fix compose, cli, and test spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - compose_gen: add monitor healthcheck so data nodes wait until monitor PostgreSQL is accepting connections before starting; make node2 depend on node1 so registration order is deterministic (node1 gets nodeid=1) - cli_root (pg_autoctl): re-add do_commands to the root command table; the 'do service postgres/node-active/monitor' sub-commands are spawned internally by the supervisor and must remain accessible - pgctl: add --checkpoint=fast to pg_basebackup to avoid waiting for a checkpoint (default spread mode could block 5+ minutes); fix args[16] → args[18] to prevent buffer overflow when slot name is provided - basic_operation.pgaf: complete rewrite matching test_basic_operation.py · remove candidate-priority=0 (was blocking maintenance with failover) · fix multi-line expect {} blocks (closing } must be on its own line) · add verify_initial_setup step: check SSN and replication slots · add SSN checks after disable_maintenance_{rejoin,secondary} · add SSN checks after restart_node1 · add multiple_failovers step with replication slot verification · fix perform promotion to use --name (not --nodename) · fix drop node to use --name nodeN (--pgdata is ignored with monitor) · fix drop_secondary replication-slot empty check after node drop · all 16 steps now pass --- src/bin/Makefile | 12 +- src/bin/common/Makefile | 16 + src/bin/common/pgctl.c | 3 +- src/bin/pg_autoctl/cli_formation.c | 6 + src/bin/pg_autoctl/cli_root.c | 3 + src/bin/pg_autoctl/coordinator.c | 45 +- src/bin/pg_autoctl/demoapp.c | 30 +- src/bin/pg_autoctl/monitor.c | 71 +- src/bin/pg_autoctl/primary_standby.c | 2 +- src/bin/pgaftest/cli_root.c | 16 +- src/bin/pgaftest/compose_gen.c | 55 +- src/bin/pgaftest/compose_gen.h | 3 +- src/bin/pgaftest/pgaftest | Bin 0 -> 779928 bytes src/bin/pgaftest/test_runner.c | 13 +- src/bin/pgaftest/test_runner.h | 1 + src/bin/pgaftest/test_spec_parse.c | 2060 +++++++++++++++++++++++++ src/bin/pgaftest/test_spec_parse.h | 131 ++ src/bin/pgaftest/test_spec_parse.y | 100 +- src/bin/pgaftest/test_spec_scan.c | 2062 ++++++++++++++++++++++++++ tests/tap/README.md | 137 ++ tests/tap/specs/basic_operation.pgaf | 175 ++- 21 files changed, 4835 insertions(+), 106 deletions(-) create mode 100644 src/bin/common/Makefile create mode 100755 src/bin/pgaftest/pgaftest create mode 100644 src/bin/pgaftest/test_spec_parse.c create mode 100644 src/bin/pgaftest/test_spec_parse.h create mode 100644 src/bin/pgaftest/test_spec_scan.c create mode 100644 tests/tap/README.md diff --git a/src/bin/Makefile b/src/bin/Makefile index 3444bc1ad..fcdca4ae7 100644 --- a/src/bin/Makefile +++ b/src/bin/Makefile @@ -1,15 +1,19 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the PostgreSQL License. -all: pg_autoctl pgaftest ; +all: common pg_autoctl pgaftest ; -pg_autoctl: +common: + $(MAKE) -C common + +pg_autoctl: common $(MAKE) -C pg_autoctl pg_autoctl -pgaftest: +pgaftest: common $(MAKE) -C pgaftest pgaftest clean: + $(MAKE) -C common clean $(MAKE) -C pg_autoctl clean $(MAKE) -C pgaftest clean @@ -17,4 +21,4 @@ install: pg_autoctl pgaftest $(MAKE) -C pg_autoctl install $(MAKE) -C pgaftest install -.PHONY: all pg_autoctl pgaftest install clean +.PHONY: all common pg_autoctl pgaftest install clean diff --git a/src/bin/common/Makefile b/src/bin/common/Makefile new file mode 100644 index 000000000..5b106fcc4 --- /dev/null +++ b/src/bin/common/Makefile @@ -0,0 +1,16 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the PostgreSQL License. + +SRC_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) + +.DEFAULT_GOAL := $(SRC_DIR)libpgaf_common.a + +include $(SRC_DIR)Makefile.common + +override CFLAGS += -I$(SRC_DIR)../pg_autoctl + +clean: + rm -f $(COMMON_OBJ) $(COMMON_LIB) + rm -rf $(DEPDIR) + +.PHONY: clean diff --git a/src/bin/common/pgctl.c b/src/bin/common/pgctl.c index 358dead6f..e436f076f 100644 --- a/src/bin/common/pgctl.c +++ b/src/bin/common/pgctl.c @@ -1264,7 +1264,7 @@ pg_basebackup(const char *pgdata, NodeAddress *primaryNode = &(replicationSource->primaryNode); char primaryConnInfo[MAXCONNINFO] = { 0 }; - char *args[16]; + char *args[18]; /* enough for all pg_basebackup flags incl. --checkpoint=fast */ int argsIndex = 0; char command[BUFSIZE]; @@ -1330,6 +1330,7 @@ pg_basebackup(const char *pgdata, args[argsIndex++] = "--max-rate"; args[argsIndex++] = replicationSource->maximumBackupRate; args[argsIndex++] = "--wal-method=stream"; + args[argsIndex++] = "--checkpoint=fast"; /* we don't use a replication slot e.g. when upstream is a standby */ if (!IS_EMPTY_STRING_BUFFER(replicationSource->slotName)) diff --git a/src/bin/pg_autoctl/cli_formation.c b/src/bin/pg_autoctl/cli_formation.c index 09d546dd1..b06af3bff 100644 --- a/src/bin/pg_autoctl/cli_formation.c +++ b/src/bin/pg_autoctl/cli_formation.c @@ -413,6 +413,12 @@ keeper_cli_formation_create_getopts(int argc, char **argv) } } + if (errors > 0) + { + commandline_help(stderr); + exit(EXIT_CODE_BAD_ARGS); + } + /* when we have a monitor URI we don't need PGDATA */ if (cli_formation_use_monitor_option(&options)) { diff --git a/src/bin/pg_autoctl/cli_root.c b/src/bin/pg_autoctl/cli_root.c index b2dad7383..bc1567aff 100644 --- a/src/bin/pg_autoctl/cli_root.c +++ b/src/bin/pg_autoctl/cli_root.c @@ -9,6 +9,7 @@ */ #include "cli_common.h" +#include "cli_do_root.h" #include "cli_inspect.h" #include "cli_override.h" #include "cli_root.h" @@ -100,6 +101,7 @@ CommandLine *root_subcommands[] = { &activate_node_command, &inspect_commands, &override_commands, + &do_commands, &service_run_command, &watch_command, &service_stop_command, @@ -131,6 +133,7 @@ CommandLine *root_subcommands_with_debug[] = { &activate_node_command, &inspect_commands, &override_commands, + &do_commands, &service_run_command, &watch_command, &service_stop_command, diff --git a/src/bin/pg_autoctl/coordinator.c b/src/bin/pg_autoctl/coordinator.c index 4845aa96c..84bd34f29 100644 --- a/src/bin/pg_autoctl/coordinator.c +++ b/src/bin/pg_autoctl/coordinator.c @@ -160,9 +160,12 @@ coordinator_add_node(Coordinator *coordinator, Keeper *keeper, SingleValueResultContext parseContext = { { 0 }, PGSQL_RESULT_INT, false }; + IntString pgportStr = intToString(keeper->config.pgSetup.pgport); + IntString groupIdStr = intToString(keeper->config.groupId); + paramValues[0] = keeper->config.hostname; - paramValues[1] = intToString(keeper->config.pgSetup.pgport).strValue; - paramValues[2] = intToString(keeper->config.groupId).strValue; + paramValues[1] = pgportStr.strValue; + paramValues[2] = groupIdStr.strValue; paramValues[3] = citusRoleStr; paramValues[4] = clusterName; @@ -247,9 +250,12 @@ coordinator_add_inactive_node(Coordinator *coordinator, Keeper *keeper, sql = sqlInteger; } + IntString pgportStr = intToString(keeper->config.pgSetup.pgport); + IntString groupIdStr = intToString(keeper->config.groupId); + paramValues[0] = keeper->config.hostname; - paramValues[1] = intToString(keeper->config.pgSetup.pgport).strValue; - paramValues[2] = intToString(keeper->config.groupId).strValue; + paramValues[1] = pgportStr.strValue; + paramValues[2] = groupIdStr.strValue; paramValues[3] = citusRoleStr; paramValues[4] = clusterName; @@ -323,8 +329,10 @@ coordinator_activate_node(Coordinator *coordinator, Keeper *keeper, sql = sqlInteger; } + IntString pgportStr = intToString(keeper->config.pgSetup.pgport); + paramValues[0] = keeper->config.hostname; - paramValues[1] = intToString(keeper->config.pgSetup.pgport).strValue; + paramValues[1] = pgportStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, @@ -372,8 +380,10 @@ coordinator_remove_node(Coordinator *coordinator, Keeper *keeper) Oid paramTypes[2] = { TEXTOID, INT4OID }; const char *paramValues[2]; + IntString pgportStr = intToString(keeper->config.pgSetup.pgport); + paramValues[0] = keeper->config.hostname; - paramValues[1] = intToString(keeper->config.pgSetup.pgport).strValue; + paramValues[1] = pgportStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, @@ -621,12 +631,16 @@ coordinator_update_node_prepare(Coordinator *coordinator, Keeper *keeper) " and not exists" " (select 1 from pg_prepared_xacts where gid = $4)"); - paramValues[0] = intToString(groupId).strValue; + IntString groupIdStr = intToString(groupId); + IntString pgportStr = intToString(keeper->config.pgSetup.pgport); + IntString cooldownStr = intToString( + keeper->config.citus_master_update_node_lock_cooldown); + + paramValues[0] = groupIdStr.strValue; paramValues[1] = keeper->config.hostname; - paramValues[2] = intToString(keeper->config.pgSetup.pgport).strValue; + paramValues[2] = pgportStr.strValue; paramValues[3] = transactionName; - paramValues[4] = intToString( - keeper->config.citus_master_update_node_lock_cooldown).strValue; + paramValues[4] = cooldownStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, @@ -652,9 +666,12 @@ coordinator_update_node_prepare(Coordinator *coordinator, Keeper *keeper) " and not exists" " (select 1 from pg_prepared_xacts where gid = $4)"); - paramValues[0] = intToString(groupId).strValue; + IntString groupIdStr = intToString(groupId); + IntString pgportStr = intToString(keeper->config.pgSetup.pgport); + + paramValues[0] = groupIdStr.strValue; paramValues[1] = keeper->config.hostname; - paramValues[2] = intToString(keeper->config.pgSetup.pgport).strValue; + paramValues[2] = pgportStr.strValue; paramValues[3] = transactionName; if (!pgsql_execute_with_params(pgsql, sql, @@ -805,7 +822,9 @@ coordinator_upsert_poolinfo_port(Coordinator *coordinator, Keeper *keeper) sformat(proxyInfo, sizeof(proxyInfo), "host=%s port=%d", keeper->config.hostname, keeper->config.pgSetup.proxyport); - paramValues[0] = intToString(keeper->config.groupId).strValue; + IntString groupIdStr = intToString(keeper->config.groupId); + + paramValues[0] = groupIdStr.strValue; paramValues[1] = proxyInfo; if (!pgsql_execute_with_params(pgsql, sql, diff --git a/src/bin/pg_autoctl/demoapp.c b/src/bin/pg_autoctl/demoapp.c index 609c75c97..dd9cbbdf5 100644 --- a/src/bin/pg_autoctl/demoapp.c +++ b/src/bin/pg_autoctl/demoapp.c @@ -482,10 +482,14 @@ demoapp_register_client(const char *pguri, const Oid paramTypes[4] = { INT4OID, INT4OID, INT4OID, INT4OID }; const char *paramValues[4] = { 0 }; - paramValues[0] = intToString(clientId).strValue; - paramValues[1] = intToString(getpid()).strValue; - paramValues[2] = intToString(retrySleep).strValue; - paramValues[3] = intToString(retryCap).strValue; + IntString clientIdStr = intToString(clientId); + IntString pidStr = intToString(getpid()); + IntString retrySleepStr = intToString(retrySleep); + IntString retryCapStr = intToString(retryCap); + paramValues[0] = clientIdStr.strValue; + paramValues[1] = pidStr.strValue; + paramValues[2] = retrySleepStr.strValue; + paramValues[3] = retryCapStr.strValue; pgsql_init(&pgsql, (char *) pguri, PGSQL_CONN_APP); @@ -519,8 +523,10 @@ demoapp_update_client_failovers(const char *pguri, int clientId, int failovers) const Oid paramTypes[2] = { INT4OID, INT4OID }; const char *paramValues[2] = { 0 }; - paramValues[0] = intToString(clientId).strValue; - paramValues[1] = intToString(failovers).strValue; + IntString clientIdStr = intToString(clientId); + IntString failoversStr = intToString(failovers); + paramValues[0] = clientIdStr.strValue; + paramValues[1] = failoversStr.strValue; pgsql_init(&pgsql, (char *) pguri, PGSQL_CONN_APP); @@ -699,10 +705,14 @@ demoapp_start_client(const char *pguri, int clientId, const Oid paramTypes[5] = { INT4OID, INT4OID, INT8OID, INT8OID, BOOLOID }; const char *paramValues[5] = { 0 }; - paramValues[0] = intToString(clientId).strValue; - paramValues[1] = intToString(index).strValue; - paramValues[2] = intToString(pgsql.retryPolicy.attempts).strValue; - paramValues[3] = intToString(INSTR_TIME_GET_MICROSEC(duration)).strValue; + IntString clientIdStr = intToString(clientId); + IntString indexStr = intToString(index); + IntString attemptsStr = intToString(pgsql.retryPolicy.attempts); + IntString durationStr = intToString(INSTR_TIME_GET_MICROSEC(duration)); + paramValues[0] = clientIdStr.strValue; + paramValues[1] = indexStr.strValue; + paramValues[2] = attemptsStr.strValue; + paramValues[3] = durationStr.strValue; paramValues[4] = is_in_recovery ? "true" : "false"; if (!pgsql_execute_with_params(&pgsql, sql, 5, paramTypes, paramValues, diff --git a/src/bin/pg_autoctl/monitor.c b/src/bin/pg_autoctl/monitor.c index 7afd5d2cc..582eb0de6 100644 --- a/src/bin/pg_autoctl/monitor.c +++ b/src/bin/pg_autoctl/monitor.c @@ -847,17 +847,23 @@ monitor_register_node(Monitor *monitor, char *formation, { { 0 }, assignedState, false }; const char *nodeStateString = NodeStateToString(initialState); + IntString portStr = intToString(port); + IntString systemIdentifierStr = intToString(system_identifier); + IntString desiredNodeIdStr = intToString(desiredNodeId); + IntString desiredGroupIdStr = intToString(desiredGroupId); + IntString candidatePriorityStr = intToString(candidatePriority); + paramValues[0] = formation; paramValues[1] = host; - paramValues[2] = intToString(port).strValue; + paramValues[2] = portStr.strValue; paramValues[3] = dbname; paramValues[4] = name == NULL ? "" : name; - paramValues[5] = intToString(system_identifier).strValue; - paramValues[6] = intToString(desiredNodeId).strValue; - paramValues[7] = intToString(desiredGroupId).strValue; + paramValues[5] = systemIdentifierStr.strValue; + paramValues[6] = desiredNodeIdStr.strValue; + paramValues[7] = desiredGroupIdStr.strValue; paramValues[8] = nodeStateString; paramValues[9] = nodeKindToString(kind); - paramValues[10] = intToString(candidatePriority).strValue; + paramValues[10] = candidatePriorityStr.strValue; paramValues[11] = quorum ? "true" : "false"; paramValues[12] = IS_EMPTY_STRING_BUFFER(citusClusterName) @@ -946,12 +952,16 @@ monitor_node_active(Monitor *monitor, { { 0 }, assignedState, false }; const char *nodeStateString = NodeStateToString(currentState); + IntString nodeIdStr = intToString(nodeId); + IntString groupIdStr = intToString(groupId); + IntString currentTLIStr = intToString(currentTLI); + paramValues[0] = formation; - paramValues[1] = intToString(nodeId).strValue; - paramValues[2] = intToString(groupId).strValue; + paramValues[1] = nodeIdStr.strValue; + paramValues[2] = groupIdStr.strValue; paramValues[3] = nodeStateString; paramValues[4] = pgIsRunning ? "true" : "false"; - paramValues[5] = intToString(currentTLI).strValue; + paramValues[5] = currentTLIStr.strValue; paramValues[6] = currentLSN; paramValues[7] = pgsrSyncState; @@ -1001,7 +1011,8 @@ monitor_set_node_candidate_priority(Monitor *monitor, int paramCount = 3; Oid paramTypes[3] = { TEXTOID, TEXTOID, INT4OID }; const char *paramValues[3]; - char *candidatePriorityText = intToString(candidate_priority).strValue; + IntString candidatePriorityStr = intToString(candidate_priority); + char *candidatePriorityText = candidatePriorityStr.strValue; bool success = true; paramValues[0] = formation; @@ -1218,8 +1229,9 @@ monitor_set_formation_number_sync_standbys(Monitor *monitor, char *formation, Oid paramTypes[2] = { TEXTOID, INT4OID }; const char *paramValues[2]; SingleValueResultContext parseContext = { { 0 }, PGSQL_RESULT_BOOL, false }; + IntString numSyncStr = intToString(numberSyncStandbys); paramValues[0] = formation; - paramValues[1] = intToString(numberSyncStandbys).strValue; + paramValues[1] = numSyncStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, @@ -1257,8 +1269,9 @@ monitor_remove_by_hostname(Monitor *monitor, char *host, int port, bool force, Oid paramTypes[3] = { TEXTOID, INT4OID, BOOLOID }; const char *paramValues[3]; + IntString portStr = intToString(port); paramValues[0] = host; - paramValues[1] = intToString(port).strValue; + paramValues[1] = portStr.strValue; paramValues[2] = force ? "true" : "false"; if (!pgsql_execute_with_params(pgsql, sql, @@ -1496,8 +1509,9 @@ monitor_perform_failover(Monitor *monitor, char *formation, int group) Oid paramTypes[2] = { TEXTOID, INT4OID }; const char *paramValues[2]; + IntString groupStr = intToString(group); paramValues[0] = formation; - paramValues[1] = intToString(group).strValue; + paramValues[1] = groupStr.strValue; /* * pgautofailover.perform_failover() returns VOID. @@ -2743,7 +2757,8 @@ monitor_create_formation(Monitor *monitor, paramValues[1] = kind; paramValues[2] = dbname; paramValues[3] = hasSecondary ? "true" : "false"; - paramValues[4] = intToString(numberSyncStandbys).strValue; + IntString numSyncStr = intToString(numberSyncStandbys); + paramValues[4] = numSyncStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, @@ -3430,10 +3445,12 @@ monitor_update_node_metadata(Monitor *monitor, SingleValueResultContext context = { { 0 }, PGSQL_RESULT_BOOL, false }; - paramValues[0] = intToString(nodeId).strValue; + IntString nodeIdStr = intToString(nodeId); + IntString portStr = intToString(port); + paramValues[0] = nodeIdStr.strValue; paramValues[1] = name; paramValues[2] = hostname; - paramValues[3] = intToString(port).strValue; + paramValues[3] = portStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, @@ -3478,8 +3495,10 @@ monitor_set_node_system_identifier(Monitor *monitor, NodeAddress node = { 0 }; NodeAddressParseContext parseContext = { { 0 }, &node, false }; - paramValues[0] = intToString(nodeId).strValue; - paramValues[1] = intToString(system_identifier).strValue; + IntString nodeIdStr = intToString(nodeId); + IntString sysIdStr = intToString(system_identifier); + paramValues[0] = nodeIdStr.strValue; + paramValues[1] = sysIdStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, @@ -3526,8 +3545,10 @@ monitor_set_group_system_identifier(Monitor *monitor, SingleValueResultContext context = { 0 }; - paramValues[0] = intToString(groupId).strValue; - paramValues[1] = intToString(system_identifier).strValue; + IntString groupIdStr = intToString(groupId); + IntString sysIdStr = intToString(system_identifier); + paramValues[0] = groupIdStr.strValue; + paramValues[1] = sysIdStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, @@ -3640,8 +3661,9 @@ monitor_start_maintenance(Monitor *monitor, int64_t nodeId, bool *mayRetry) int paramCount = 1; Oid paramTypes[1] = { INT8OID }; const char *paramValues[1]; + IntString nodeIdStr = intToString(nodeId); - paramValues[0] = intToString(nodeId).strValue; + paramValues[0] = nodeIdStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, @@ -3688,8 +3710,9 @@ monitor_stop_maintenance(Monitor *monitor, int64_t nodeId, bool *mayRetry) int paramCount = 1; Oid paramTypes[1] = { INT8OID }; const char *paramValues[1]; + IntString nodeIdStr = intToString(nodeId); - paramValues[0] = intToString(nodeId).strValue; + paramValues[0] = nodeIdStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, @@ -4855,9 +4878,11 @@ monitor_find_node_by_nodeid(Monitor *monitor, NodeAddressArrayParseContext parseContext = { { 0 }, nodesArray, false }; + IntString groupIdStr = intToString(groupId); + IntString nodeIdStr = intToString(nodeId); paramValues[0] = formation; - paramValues[1] = intToString(groupId).strValue; - paramValues[2] = intToString(nodeId).strValue; + paramValues[1] = groupIdStr.strValue; + paramValues[2] = nodeIdStr.strValue; if (!pgsql_execute_with_params(pgsql, sql, paramCount, paramTypes, paramValues, diff --git a/src/bin/pg_autoctl/primary_standby.c b/src/bin/pg_autoctl/primary_standby.c index 96a171978..6bc3b01a3 100644 --- a/src/bin/pg_autoctl/primary_standby.c +++ b/src/bin/pg_autoctl/primary_standby.c @@ -1207,7 +1207,7 @@ postgres_maybe_do_crash_recovery(LocalPostgresServer *postgres) default: { /* wait until postgres crash recovery is done */ - for (int attempts = 0;; attempts++) + for (;;) { int timeout = 30; diff --git a/src/bin/pgaftest/cli_root.c b/src/bin/pgaftest/cli_root.c index 815507591..c340befea 100644 --- a/src/bin/pgaftest/cli_root.c +++ b/src/bin/pgaftest/cli_root.c @@ -160,13 +160,13 @@ cli_run(int argc, char **argv) } /* Single spec file */ - if (optind >= argc) + if (optind > argc) { log_error("Usage: pgaftest run [--schedule ] []"); exit(1); } - strncpy(pgaftestOpts.specFile, argv[optind], + strncpy(pgaftestOpts.specFile, argv[optind - 1], sizeof(pgaftestOpts.specFile)-1); TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); @@ -185,13 +185,13 @@ cli_setup(int argc, char **argv) { int optind = pgaftest_getopts(argc, argv); - if (optind >= argc) + if (optind > argc) { log_error("Usage: pgaftest setup [--tmux] [--work-dir ]"); exit(1); } - strncpy(pgaftestOpts.specFile, argv[optind], + strncpy(pgaftestOpts.specFile, argv[optind - 1], sizeof(pgaftestOpts.specFile)-1); TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); @@ -211,14 +211,14 @@ cli_step(int argc, char **argv) { int optind = pgaftest_getopts(argc, argv); - if (optind >= argc) + if (optind > argc) { log_error("Usage: pgaftest step [--work-dir ]"); exit(1); } /* step name is positional */ - strncpy(pgaftestOpts.stepName, argv[optind], + strncpy(pgaftestOpts.stepName, argv[optind - 1], sizeof(pgaftestOpts.stepName)-1); /* We need the spec file too — look for it in workDir */ @@ -247,13 +247,13 @@ cli_show(int argc, char **argv) { int optind = pgaftest_getopts(argc, argv); - if (optind >= argc) + if (optind > argc) { log_error("Usage: pgaftest show "); exit(1); } - strncpy(pgaftestOpts.specFile, argv[optind], + strncpy(pgaftestOpts.specFile, argv[optind - 1], sizeof(pgaftestOpts.specFile)-1); TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); diff --git a/src/bin/pgaftest/compose_gen.c b/src/bin/pgaftest/compose_gen.c index f594ae9e3..8c6d8ba56 100644 --- a/src/bin/pgaftest/compose_gen.c +++ b/src/bin/pgaftest/compose_gen.c @@ -21,6 +21,28 @@ #define MONITOR_PGURI \ "postgresql://autoctl_node@monitor/pg_auto_failover" +/* + * Emit either an `image:` stanza (when PGAF_IMAGE is set) or a + * `build:` stanza pointing at the project root. + * + * Using PGAF_IMAGE skips the Docker build entirely — useful when the + * caller has already built and tagged an image: + * PGAF_IMAGE=pg_auto_failover:pg17 pgaftest run spec.pgaf + */ +static void +write_image_or_build(FILE *f, const char *contextDir) +{ + const char *img = getenv("PGAF_IMAGE"); + if (img && *img) + fprintf(f, " image: \"%s\"\n", img); + else + fprintf(f, + " build:\n" + " context: \"%s\"\n" + " target: run\n", + contextDir); +} + void compose_network_name(const char *projectName, char *buf, int buflen) { @@ -38,7 +60,8 @@ bool compose_gen_write(const TestCluster *cluster, const char *path, const char *projectName, - int monitorHostPort) + int monitorHostPort, + const char *contextDir) { FILE *f = fopen(path, "w"); if (!f) @@ -52,9 +75,9 @@ compose_gen_write(const TestCluster *cluster, fprintf(f, "services:\n"); /* ---- monitor ---- */ + fprintf(f, " monitor:\n"); + write_image_or_build(f, contextDir); fprintf(f, - " monitor:\n" - " build: .\n" " hostname: monitor\n" " volumes:\n" " - monitor_data:/var/lib/postgres:rw\n" @@ -62,6 +85,13 @@ compose_gen_write(const TestCluster *cluster, " PGDATA: /var/lib/postgres/pgaf\n" " ports:\n" " - \"127.0.0.1:%d:5432\"\n" + " healthcheck:\n" + " test: [\"CMD-SHELL\"," + " \"pg_isready -d pg_auto_failover -U autoctl_node\"]\n" + " interval: 5s\n" + " timeout: 5s\n" + " retries: 20\n" + " start_period: 30s\n" " command: >-\n" " pg_autoctl create monitor\n" " --ssl-self-signed --auth trust --run\n" @@ -86,9 +116,9 @@ compose_gen_write(const TestCluster *cluster, pgactl_cmd = "pg_autoctl create postgres" " --ssl-self-signed --auth trust --pg-hba-lan --run"; + fprintf(f, " %s:\n", n->name); + write_image_or_build(f, contextDir); fprintf(f, - " %s:\n" - " build: .\n" " hostname: %s\n" " volumes:\n" " - %s_data:/var/lib/postgres:rw\n" @@ -103,13 +133,24 @@ compose_gen_write(const TestCluster *cluster, " expose:\n" " - 5432\n" " depends_on:\n" - " - monitor\n", - n->name, n->name, n->name, + " monitor:\n" + " condition: service_healthy\n", + n->name, n->name, MONITOR_PGURI, n->name, n->replicationQuorum ? "true" : "false", n->candidatePriority); + /* + * All nodes after the first also wait for the first node's container + * to start, ensuring node1 registers first and gets nodeid=1. + */ + if (i > 0) + fprintf(f, + " %s:\n" + " condition: service_started\n", + cluster->nodes[0].name); + if (n->kind == NODE_KIND_CITUS_WORKER) fprintf(f, " command: >-\n" diff --git a/src/bin/pgaftest/compose_gen.h b/src/bin/pgaftest/compose_gen.h index 602ec306f..71ff42950 100644 --- a/src/bin/pgaftest/compose_gen.h +++ b/src/bin/pgaftest/compose_gen.h @@ -21,7 +21,8 @@ bool compose_gen_write(const TestCluster *cluster, const char *path, const char *projectName, - int monitorHostPort); + int monitorHostPort, + const char *contextDir); /* Return the docker network name for a project */ void compose_network_name(const char *projectName, char *buf, int buflen); diff --git a/src/bin/pgaftest/pgaftest b/src/bin/pgaftest/pgaftest new file mode 100755 index 0000000000000000000000000000000000000000..fc1cedad4e247aac520f9d2fca7ac1ddba305b0a GIT binary patch literal 779928 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 z z7b36B{gT8xd92Twm&kG1!`QE()q>j=j(h?8Zu(p%ynw_I*TAW{%*Q3}3g}?()|T8E z@KtIbTlt-04-W1sUYd3+{x1AZ@c{e=BsPZljzy05gZNWhYgX;;13#r`dG!IO<6(0S zqhW-WN5H&f@T2vwI~_H^2tDfhcWtB4@hio73?9z;9rl~XT{+?W5BDg196#8z*=69n zvmxnaXTt!VM4kkmcpe*19FO+0GhXnWyBeI_rN>+u_913mH}=#&;Gg*j?Gl>zgYPrW z$kFotTNy9nh{#-t9x@M_k*wr*@r|~-y5<`5b(H)@T#Y=H-ZT_GVF>f0=89Mwl=Tkw zH${@hTs;A-MSFfs-Lj|umEVKlh1j16kK0QBEIZ<9v^ji#Qgd;!OyTySx15e^7}xJK zROpRsDguH7Z$ZC`(zs)a^T-37N7f-1j%N>f6+IfTEur&BgNF`a52(_6&m*(dd1N=~ zPlxRj;W$wLE2rZe-(Tdr#Y2i7L-0`UXHaK2*!c#7+GL3XGz=Om`j7k2)87Bs7xm%s z&StqYaY@NT%}a0mT5~G0eeKfPNoVQz*<4LO8`L~!Gxey z_>J@8cFDYUFN6PNJzKbIRXW^+t&Zq=~!Tv)j?UJdyG{^$sdSuNj_=cJ=6tm!;5^W@16m_1g(I6 z^^Fnv@v>>V{6mjCD0Hcj@$IuOJ!Rf|_-Ci%D03Iljzj2pQ0!6*$rgSd~3 zVH1z&!RKbI9b(a;XDCzR-tOmj3o*!rPCZ3g;cNSG{&Tn7WNQttiCV+E2Y-6$p3`TEnTVwFRu(nCp1HwT|pAPn$e~JxkiQine{kI(~w6 z{G?jPxlNyzJy7D}v5tEdMXuqJ_tYA0sbLNO;t|#c>vplZZgVdh{asC&3y6`$yn9VN zZK%d->DWV=22S29IOz?S>ss@{$*QD&WxB?C?p zykU3JKzS;?m(Ck@Cr^_uXG_6ZMtmrt-5+m{-zBky<;?EGQKG-&&JWtsJ%F>EQtpAJ zF72srJDli9esLj0cWPLxc5v}N%D4y)3LZX68ExDN{_lTbtR+4eu}oLVc{=^Mmj2|? zpZseK+V=x&-%c~f^6f)pElcOK2)ZdWzAgS*=zLz&srdY+cj610)JkLPxJ)GSH$771kDzn zvI2M&&-ubc^iKIrhjg=y`)>1miZY~pNwxY!DB@aX@7r_6`(KdR@yGcB)a0cld^ zckvaKdaJPkFycApG?g>%hW;(5X{hog&1(AaDQ)9wTXwDQ#O5L4x{jXt(}+d+OLcE{ zELm6XXAa|c!+giD?U8F>WW?4cWx4Ww<-&YO=xm-sI{qdF5A zSkB!-=sHZ;ci6+^Y)x!hWFKhbJhbt{=Nu3G?ZIYZzPX>_3`O$FULx!FH0$nbvndlg ztbFpIN8+z6b=`H;m|u(Uc#>rlN86By_@{GW->E((JS8{*+9B@*j zOjD0wt&8(DM>T_1C)GK+!JQS1ODw%uHui9GFRGIJ(9>fJG)LhgcrH3KxeHfhz8`FY zrqWNb8EC6w%t+H;0B`Z5^>J6~HuM3)&jt6;o_{1w>>y2e3hV*AVh^DBoU=D69f0Jk zexlBC18qkZoea+i@lC6ZQHi8&XEJGybF&c=@EJFFzl4; zAFp!^G{+|#-z?o)EL{5{zB+HAFF$JP%h8p+B5O;=LhyMKb&BrXz;oknX-jvmVE*)Y zPaghYqC1zES}HH+;IZVv{`jQi#$NqSD29U4?_{tRLihaTc-J^4u-Etwhx9c0%=N|N zal8It*T%2F9&UqOEBij@dh_u|I|eN;V2`|(KFHbq#qHB}+3zM+3+FHrL)%`A{tr1L zh4T>EGep0~c}zyfIIa1QvUd=d{$R<-7lm%v$g`iiK49NjMGX9n_$RGCd~27$K8L;>xJ9#O~8jx;w6uOuCa#7^croK%&9e(+pe!O zWQ{wfc)tI2L)RGHmSpNWSW?>Co=vo;WB0UOpP5$S8OK@E5cCVuzRmHOwJ+^>X^6zZ zm9Y{$v(7S}14i!q9ib893%$0VKBF5gGj&*@HFYuGkS%lS9FNf+Ih(z}xu&dzH_&}J zO*>)^@Ul8cPiAi9tVoL^mXdjHvW&Wvh z>eGNTbU^)|W6C(+4IK)fJ3Hg#m$|!f#EW(Ke9GJ%irjC`*ZkVtyGrUDw^QGKzDMhn zlfUAz&c8x6WnCQ!ZY=|5&SE-IVVV;=r25M zq>k6rMTF+>;sDPU`c+a|=jg;HS>{jZbUN)0#>>5Yc49Fnb54;$e6&>JqlNBm<8BSZ zUk7~+JpRi*?%Fcq`J{WkN6Z#twU+fvaVptc-hm5lWp9&ciA}8&s>IPH^|+`#Mehh6RuC+({1R<7K_~| zbx)KrH+5s8>n>!T<%~{bPLVxCA0zbQ5#}TJo{G|L_^nIExlpLzUoqlDS5K~U+)Y13 zN6=nltP7d9hYI0KptY9%UGAsw^Sx}EruOEw_49km<8r&;P3H(bx6a~aFX)5ca|Ri6 zGNsOOi>fOJzKA^$KjLT9;%1^+i9GWog)ux!QCt8A52r_+N$atKcifsvC;=iUbv0+$=Wvg z(h!_!7t?lUo#Q9KiOyE~-`v~({HB|L6`AB9@S>N9s5dWD)muNk&hZ1_MfQ-sSoriy z+9~uRy39Pv^u;VMOO@9)qt5YMjPm{;S2<*9pdG zpBg7){@N)|#;6;fD57n5R(3&%-iGGBV~8rFWOkin3}r}u z^i$0pe+LfR3fXUB!c8*bJk-yra}*04`9~xH_W^LJ{lGO|r|PqPvCfexaO59>9--qy z;L`em>o8(MY@1u>NEA5ok4OXVAHZey1NW68RbS=3$Wz4Mmi!}#8!ob*@D{&*JGkis zd=VqYbyAMv->N@b=Xf{ro41CwvV}F-#u|HvZ>fxNA71OewL<&cz4v)#3hf(h@mcO( zyBE&%D>-X<9e!Wr6rs7dY&7c;bW>Qir@Ne=BqCpT8t{na)|4aUL$`=3S&& z`lX*EM=!2~rWR|SpYks7#k9MGM`HK?7@uhknYvZ#q26x^9}HbJWwH={5Qn^i{FMvq z96K04$t!zBHSs^7!=ft><$b0^?ZwsAhOJkhvW^Z@-%IYR!)B{j{tLl34prYPYw8^9 zsLSNz+~Imi;eCo|Pms0EnD*i2b}$Ap{k5wKe#f2@Hul%{R7S6R`;8vUH>2diI!7&S zm`yvAk+nzQTPl8x;upCUUnz_KmGx1~e}NPJcX3H1|GNOWP3d>GYuuxSK7(KJ!TbU3 zl=lk?53yqa4}}jqihm+@N-d@Lm&zSXEi*n{s_d0Mld<;uozT!n(S>)8t8A`?AG)-M zJJNTAXoAS?O7G@0Vwu-3t8?5cb4ERaJ70&7KFAzf|KDuq>{xUlQkEgZgyv$MVINby zyv|Wd8PY%DB}ULDJ8e^KG}~s~jT38t ztD@|4m2 zGDc$mB66wNR0<6cezOyN6Pu}N$g%B=@q6%)qF0vnL(Eyx(}d>xOJ;2GXX@158WG~&QvTfh2bG*de78>=$I>VBCUt;-bA;+t@=+^z_ zL;niCV#jFF>MH&VzFPmC@;&VT7Ws}|OZr!8^sl9O^lhTUYN^?1+{tyQM0|RBX;0|8 z^L9now-Iwlbj2p^3Vq*KuD;g~GuA=W_wzL^n)+USgK8=J&B~rKOurgN+X{M)w&05_`qlQE)txT&7v-KbttIaC9f8&)Es)CG*WOd) zvGZ$RIMpLDS-DR`AIaEtZr3IUH`w-}OL3RJT`Qz{-NgVEJ9is)hh7Z`~M-H}e9@y5f<~D)5;h{SNr|$v|-r9gm-W8mU zZQ@)lpz6sl^>htS-Gxk}cMgr896YXxF2`NUSzB3GTJn3 z`JI7Mbdja4+{wFI>QCS0$CkpshUw>QsnWSayo3sFW8qesh37+TO4UUIw*SPBA zoKxT3P8)V;0nYW@>z*Is=^B^4>+I^BU1zzMc^!9&o!zhL@0`)bymNp&@Wl_>2D*ad z@^%G}0e9Sl+bVEFcAY)R`TiN3r=B{237myq8~Lx>6}&+HZY^*V?R;5}^K?xtL@tff zuPMUcC^O-So09FG198|Fq{iv*q{Rh-nQ{8r+&Dd05T~~m#s!!keH5^@*Vz~+-iwnx z)wDl2E>8DNB>$8+{eyDySDE>y**vXx0XH*FSAAQa?>Re*GH1u>o!e6;kA61Avsvn! z7pI?|4}1;zkhfOSzwSkpQ%k+efL~$4-*c_!?8-QOG;LV-5ND#RDCg(w>z`MwI z?=z~uXV(M20r*Y8zi7fd3(RI&`+mt7b&>y^S;n6z;{yM8q#AP*1U}xTuj@47 zlWdH;O+S@p3v^}Lj6Pnnd9DE`UjF3>&VOzCy9GAAvps$C$X}*==F7MZwdw7{ZGn-+ z8J=}1&#HD*G9PEhQO-olnPSt~zt7J|j`wty16##2e2}M7@NpJ!3kQ1!y29Y*+4R== zz}1*=V}V;_zCX%)E%1xd6#VIxwm@)|O;1UER>fBCTuu8MfL{Z=%Y^X&v)+7vo%apE z??^Y`Hv_-jrawph5}Ubm2k^Ur-vj(!6Xp-VyvF<1Y>)ISc-W?&J_6h^;5IzVU63iR zp5ws1NqDZ^$Dk(#n0F{9VA$1b!Cq zvrQQ2Mb}*O{g=GY1O5zsq8+Cf0bdLJ^luvVF9UuB@GF5|Wy0vdtTx|^6FprGzz@$e z;MW7cLFzZ*Hv#`5@SB0(9&g~!7ZN?4JIwb-dEXrm9^@PI_!{v07=i8Lm&Uhl%s_{HS zd0muuj`mzI%Nakw)78!U)67*nZg5H{&5a=vOkbbnx zcw&I3vyk`JA_JdB0XGJ?aS3_~^0>moiNH-s&`*^o814UeV5$-X2U==>PQ7>WUR+|- zJ3B$O`~IidSLP-JMr|$etV6c%#its|Sw#J{Cj1Rao~~uQFC1#XuQK2tsH5Mjfo~n^ z8AyEYUU(Pq>w({3!aooECf>IWGvK$I@XrFjBO%}dR{9>?Lmzf0=v{k(e+~HkCVZmZ z({+IN)*B4?WAy)cLLe1iYz21$xHo}23EbPjwVQAr;Lh+~Jluf0VD@`0{qCk-3qA<^ zN5ID?>Zg(t1D&af#<<;-?CDD5ec=cLz97*Ux95Q`Oboadn)MG)WbGvCU88^>1N=A> zek<@3dEZ)Uz*m{@9@)Q?`$39>DZsB`wk=qf`^H7a*r9K;Rt0M z1O7PmzX=R@XaBcULk{z#dOA)}{z)lojK`K7_p&Wnd)a?xq~bArXDF*HQD2L#pztTQ z4Chq;Im#;-pf|!(b#$dRx2FvVz%P4ydD5e)N^f63!s%!c`#t!RXTOV%4jVRPh{;FM zH;P_W`1~4{nw7?o?#& zc(JdItrMn?EyXVkq3)a}n;rcY&oACbAIUf@rXSJ=`-efX6=^B{h2%r;Y3BPW`F_P& z%iZVb8_!SPLyy7lavm?=zQAv6`Tk~QYalW@CSjs^R9_!{5PB4uZAkTQHjIoEP> zMV~sUxCJLApc_K2S1|sN28Chb3W6` zcNsrR_tr?+B8N;sme?t0ReTp2{3P>G!5Pni0owbuz@iH`Z5j%C>;2EDdhOI3UH-$A zZ^{@UeENKWN9rv38h4)xK2cxXB+iQ0GnSljwt`=h_8@I=;-g{x|1bV;!TwwRi~V<> za=ANi3*~O3+#4xZ<6UI=XxxaCGq$QoyK761?^CAxTBYkbL|nNH%6yf2C()-^bDR8O zgX27N+N)1XLjI{LkC1<&=e!l)Kz!`fS%Iu8xz}W%C{`(OD4 zBh$5-G99r!dSyBvvK(?}>cna+nyr{MaL>4r%D zT0^GuA=4>-N@TimhDWB?r`mdzvYqtvtSQ_1OxaGshh)2!{$x7^Z_0MQkZjkoE{1H^8YbH* zI8(Osg=D*ybunbS)-c&l!I`q157|y+IyKhFccyIDvaTQ5PQmw;?ON6$+lfr4`Y!Ta z0kTm)vYnJ8GEkIk*K#G`jPD}Mapz7VKSZjYGpd*9bSjPDmyzjIdrXcRHp02r+-qW>xKV>GTo@+8$9cf>w4ioflMc37W@}v zIt3qFrt{Xumg(I0hsksbKDJEft&J_yx$h5?=@fiyna*1qTc&g0A12c&_}DU?cSdZP z&K)k(3GRf;bl{J72J)N_*)CkBQ#=szoXB=v$aJlyOn1?g<$NJo&TGnY-WgYrUSzl|(FT=D71Jsrf&Z-u9_Y(`EX z&tS7NUSe*P!dEX@I%3iU{9AS+Uv!YJ_*Eq%VHab{NXwClJHLKs z2yTwt)0E#-j}3bRPmO}hZyGImCw!{8kvbO388CcO@s>g4&1%|9dk%6&NSe2J!B~~{ z6VfV>J>h{P`}?qQ7fBnjxkiT0Ow@R^)5jXOahF;f<53dzoiiD4%~``{r+T7s9wqW& zVLeW63A8e;QjpIjrWoS3Zg8XWSL!legX#JIB~}!1lrUgiIwv9pW5vGi?NK+{F*V z`y*$T90c!}d(S#$7xjwReTfX5gIp%^l;H3{+F6*OjpbZ&j^JOIU3h5zp2{@rF^G}& zO>_Rj<*HEpztCOM%;WEn3B$(udXb&n*7+B7qeWyVhRe*RS& zCM(Ig7jlpHGP068TvjsRLg!yf#)@(NWy(q|maJr*e;M$-vXVPYR`Oo0taMYDtR&}O z@WL%ovXVQNtTb9=AM^Z6!5}BeIoRdSzl{75=U?7`;rz=ROIEVZzeH9VB|M)gE5Q$W zYs1dLRC}*dR+4sGvXXTUrr<-elD9uuNx}C$2lK{~mBP=#6kOkPFmEhb$rmOoDY(dU zFz>p^b1-jzvXX-DD=T?LR(coQxY~0tDW|fptmM6ttkesKtQ2+*<_(jTy#2{aBg15+ zuyZi>`rdOeZ-26qg713{=Iu{bl5;Qx7b!D&EtyI2CRce5CjA#4KI|OKTN`-}2H%JL zlp1jk=8l$`6#knsQ`k9}H%w;o_9rtbcvEHyI|qYjq;BIJjI%x7=fyq;Q}BJy!MtHI zlea&aNx}C$2lIx>OyI%gWhONrk>_CEuyZhP)H#?p>Kx1+eGaDD)AtC@Q)V*H!Mrm<=V0E;oP)We&%t`}DN<(g*2X>ub4Q{hWizm|aF@^47*a2Xo&ab`GZC{{@*z!T$>~lY;*jWF`gwFUU-S zJK-{uc@C!Jrf``_WF@69j&Tk)0-K?ZzUN?9Ejxvug9)E67w$;kHh@ zu(1f^_1ss>>qXl-!N+*RdA(nYp8N{7P73A$$JQ>nXUtyq^0?yq#1UQfaI z<@MYqujjp5UQf!2!RxuN#Ow9KMe=&?Fka8yAFrouMf%!2xx;upcYnOzWo(|@SK{>) zTqLjO4&(LECI8blPwpsQ&mGO{?Pl#q^Lh&Z`|^73Fka8yAFrq2`|^73FkTOx|K)i- z1>cv~bBFPI?*4c^1>cv~bBFPI;KAj2JvASZyq-IZ*KYRqyQ6tMSx-uKh~)L$v3Nbz@2j(Ua>wHJ6#UiMJh}Vh z^<>O0!|Sw*7$ZJrc-n0{Qr$L96ivGn5# zK1@HZ;A8W8?pXTqCgwd{KQ6cvgV%G5jywjh*J6*s>#3M#eR(~%sV9e?{@>U<39q;6 zTfMxVH(ci$&g)&AW$=3c)q(!;aNm1u#4l6sEfHItEXHHwr<85KyXI7;(z}aa(l+iB zeY)E4eN_D;FS=%TO+{93o4Zf~A8@{A^r_yx&WtMPk0^xgJ3?oi^p9lOnlGLDAw zRFkJb@?c9Ek>@LUz4dG(&tURc{`l72H6JgFuGiA(3Qrxb(@pNH({;zv=?Yx9PS=2o(CKjWNS*FK&F4$I{}n!8!T%F{zJmKF_rc{}i9E@IQ*r zPlf(ie7<_WN;?=!r>kI0ovwQChtF5_NAdXz#2P`3lC=>8g5T z_%`gu?lGFr@5QGuK3~Dd(CG?%v`)7dK1`>p;A7}?6?~LVw--K4r>o%m(do*V#p3f7 zTnwGA)ElnTRq!$Rd<7qy&u_UJI~WBYo6m2#8ao&TAHxntwLgr{SM86%=PMkDVF%Mh z|HJuw!JTM6U%|%a^S!b7e8n?I@%eVviSYTVtWUt_3!l=TPWKRJ{iaSg!p}RL&$o2C zKRbOH8;bg8#ojv*j}E|MSIqp?GZoN z4Zv;Ud67Ccr|b0B@Q2-=ZurCQpbY$BRa^tU|#>|tP$4;AbYV2=TNJj1{nu@`s~m=k6>Vq1OE zEQ9j_!>^e#x+nwrQI&CyGA?B3r@GBD#I`yJjNk#b)m|j^bhbX54>`;XgYOSkr&D7q)7!-g+0X zGfmjBocqr*-^IpywpqrH3?JOn^9SSe%y)cf)&9I_Fh0+ev5YcSm~dh{u+n@NJL^?u z8K+G@+%=Tp8m#D2= zuK6zfWHilrfPqrkHTTbC#R$!gE%cW!zx;)Xt)e z*_44#ttw+KWz3_D`IJ#(!U^BG$b1*Rv(_x*{#?Vab|q!3l6IJ7tfq_x%2-1gu1o{B z#0Go4`7XTYhD-y;ew1hWNK?l4Oyygv=4c0H?52!8nZ_Im|GC#}gYciP@s4k;TJx4~ z?cq#ajj!mLk5Jw*@}Lh<{W?y0Z&Ka~+H}$^NBGaTdAEFPyE66D=YYFF8h&RAt{b?I zfC~Z_pJnt#_|GKXE#KPAEd6wD7QWG>p`%glFU-QfGfO`;Jj-am@SmfyjCmFQa}4j6 zZ|#&U)o#UqmS+W0P2bvH9Ggiwv$F7!HsOW;oXflATU%qmEBGNR|3Dv zgctsEHSd;ht;>WL{&PL>(RSD`0>2sf?IyhNpF4QBd~5g8|JQ)SH&(_hc!0j|&(gaN z19t?tV7YEz8&~3;Libn!Gst7vzzyYrf+S0wlQv^ zXHLovh;OZePs?U4W$Rs;+4`y6YZ5&m;Sw(j4QttaDKTY^o2vVTO+?BAZP`*vgpg1h;K zZ<_Fo{ymhj7x>qxe?RHalhQE$(|>^S4`=K4aNkx&NuSIw*LJAlkICF`QbE)|5B{ti5(61b>$vC_+aH9D8F&=utOzAkrwaj7@DJZ z&<1EWazaMK2hd(iA{6) zH|OYb*TE9bZ~TXI^i%M0OKb@)e^-v40*@xKG5ndidNRD1!2AY&YYDMd{8LDSk1FT; zAo!jowm~kxD_38SK6{BR&E?;lt9#%}me?{}{*$?izgWV#mOnmEPlj(0xMcW+dSY!X zwb@)!cIOzr!3PXcaV&-yX>;@R0`~MJ+>z>Em8ZYNw zK--tt2DtpGLugNt(H`iw*narOkp^9sd{V}6;vFPIkDnvfft&%Uw$3LHwAadWGv|BB z(A*S!S0rr-`TT3h1AVpfjD@x)Ls#YhTJov7_DKCkS~9d#rJa!ahxfwW0&QGteG5vx zBYMA$gYK<`<|w$~1=LsC`>hO`mW;2y`ZkMi&@8Jhi zn@MYup)0Da!v(!Q_x`Q|UF13OqevDR>d0s%L!}fEZyXsS8D2gaK2*_|wfOI^)n2yI z|D)Ky*pdA@a#(G!EJ2F^D1Lw{@>7Z};R$;RF~e9p zBeVop2eMWNGLybm z$SWh^e>;&&R5~(9XJ(#$jJDMxgLEQ;bmivhUC1TLm18F-*K3oLZSnkq4~NnxC;yK@ zUrIHb%bz<~_NJCn;`aEbgezue4+oZ+t_&rI__vW9;V z|B*dPHE0krhAIzP!tWw|h4~+O!oQyX$QPv=^a(jaRD%X0hbTP> za)$pT-;q0#+f15>jNv~qw%NbqhGx|^?2$)uCwS-Ez{Kb4eq;-kj$GkS;y-eR`j4F8 zAC=FXvx{uA^e$TOVuSv)JH{47@|@_@n(_98PQ5O(JmdoZ4)P)=lxom(3jKKZP0g>4&U!TA!SQ` zXgvJBN{6oxE@NIU@C{x+d7DA^+x9k2Jyn}QEH!99Jif|{ToIgwzG60Vc2c_TKLX6T zd_7o>j9o?AU6hkML=O%p&!~)me-G_G!4ov$kp=t(d@m$ld=_(Q>?glsEtKN#;!i?e z&qd}hpsX?JdJnP9dM=<#=|+!&F2xs5ndQ9CrS7-+f0A$LVS?xQzldi&?>l&o1AB~b z=x+S4L2KBrM#_0jfs#pDW*}3v)ih4+tfDP@C}(dvF`4*QQsSwE<|?{@ZZ7yD}l*XxNSCO`Dn5Ull)Hh_F;QVyGy$1bL`4IhiV8svS-A!3KdZ(6`kt14X zrw88MPn$QPe;Yh--@C{d*R*+v;E4>H5M?X+u3dSDRy;HRK(?;&3d0{*wi1Mj64 zFgNM?sZos0M8+mJT^Ai;S0Q6I6rC2b$2BFxRe2e}jNO*(d4C)*X^c^3df<7=RBb}$ z(D<(1mg4cvE8uQ5nWHqla4`DH?!xBxkU_4g9uaDn_(mQp2)ui|0DMW)JJET5i#=7f z5BVdFvd+P82Xn90eO+mR_Y1Q1LEB0_hv?V0*e~B}pV-`;dTrp`n+1B?x#y?0wiht( z1$qX1?^tN?`^X@wz28ptynmuV_f=)g zR`P7-Il^;}CpTL^Th6m6TW>=y8dx$~;Y%>LKwn4S6>f?Ab8d+K_X|VNIntkQ+8$pJ z=$e?Lca6(|4)e_AS)HS|pBxhK@8JD-4r4GxKXVM2H-R}m1lmk`A+$Ux2VDbs_YNVx z6tYmYAwT&xQ_toh`up351cbjS6}br+>fQA`uVw4!kel8|PHJ}z2}qnF^&Oe${3`NS zkMWei)0Du|lrX37?L{7{q3)H`T}WH*;#tOXfM*u%n$5Q}Ijr}bz^PHZk0IYg`Zb03 zH1Z4|-P~G`!#lX1N!oC}4=4YqoIqQlYiclT>!zOCn;!_i2FwATy*YZ%eqfGJ|9bv! zqMR4=1HNPAUFMqF(+=E<{6O1b;9S6+qs|L_+r$4F{x1S%8BY-Sq+GoxHJA41(s#<4 z$@kn`-B&=`m|VT>MPR0oR-Ui7jw5X%`O0~6fiEQgQ0lEBeQvIPY97DyfmyR|>gmk< zfZSVgv4*^hc-|b_96Xb!`##DG_-bFsakf#cM>fp2dzZU^%8 zQ-?`AlBc)sCT%9|c#;2`^PsDgvzzxlz`h2|e!iapW;N*zd4bk9Dfa~5-li=Rfm=b| zm3(U_-$#tkNBj<5H??~vZJEcnAbFE$Ln`lud3yKIyg>Unfno1hl@Vw=(m1ts1N*=x z_Jqx(Z71y{Y5Pe#K-v+~j*)h*k+CQ33~A>w^!5w9Ck@uSQ_&e_qPt8(pIb0E(3ZP) zYWKLoj2rKx)=oV&kMHyOzG$%St0k?Rv5uppBrPdZ_oZeA+SXIvQ1oNN(TR;AZ5(OaNt;R9EYjwZHjlK| zNLxYLO43%7)_|@c%gf-{k#Frhcl6-*cpOllBqsY3P75 z(XHj86DrKo+lTT#F-t!)h2JXD%1N8a`}{2Zd=0;~q%9(C1@CLJ^!Hu-ZXj(vX)p4= z2iU#*qMr)BM%rQCPh{zTKgn-9X>XI(#d|PIzYvcOBo!Kw1P#dKeR#HhaTLGfNE<`i z6y9fL>z8KpJCC%vq}A}gGF$&(6~E|kf~(QZxX_bq=l>4=@8SR6>_A)lb5mQ7k#?N4 zV7A_UAv=H`Mfu>ONAcD?p0D&M+vYkQKl&274s;2cM%*#cr&N@C{*61udUYrgpRCG= zxpeApZF<{?XBAOrm~U|-b-vC%6YX34BzL4ax$DXD zEe@U!ZnAufFHv_a-{Ocm!hDODQHSykkN@)hv;B8#9B~qxSNiVcPEhgTMt3A*^egUj-a_0ri8E%|&0*{47F$O(4;}fv_H(xR z#AT<=5?f1sGsjEW`QeW}e zJyw_>&viX=m$dlBFGQyz_>l&F$p2^m(}+*7fON4dwc@Rfrrk0Q5px@cKRt6}<4-4d z+ieNMpJicValbhhPW+J`Ay&NDP+I=!5%q-O(BG&>;ShJsN8?bd_%*R!h+PH_MczTA z|24MFtHgzn7~{wW-qL#tJ&JEew}4E)d^$1VS##27Z}G#|8Tj#+>kWT=Vk7LQErM58 zU1DF^^l2^Ya(A`_4;%O0M9xJ)kI4J#u0HVdZuFnB)&zH-`VZs&KzaY{|1<6f`HqU) zkkxeE6Rb;O5XwEjfmO7F@soIhea0kD{Qimmez@-)Gjbox?}+(eC$72NG5xqrV(jHL z`6=%pdfFgys;zta1m~wrM!&n=h;di!Bc>tscWkeiT$srHc*Nn47^jORo(ksEmgRIT zXPhM8bYgVKcyp)MBn88om$v^Jv_i&0T}E zMJJY@k64S}A*Lg7J<5Uuxc_*NHm7krdPMGxrmn}A4tc1#b9Nl}`YPRZXfD5G#PM${ z;(lgxF1OpbK8n4J?G}mI&YdCOq%Xc`e15^W^Zw9vPU4_(4-{k8!QDv_?Yd~(Rd9&d z?Emvg?V-e%^%pHnAy=!8lpA;d18|@z6aNN5$>x7#>yc<2S1D zD4}gX116$P?vd)-p<<^)VjF&v^4f?YzY~~?e^K{;>Y2>tim#jNJAIg%ONpaVlFMCi zv|G{skB2FImh?)}e@42-7>pIVa+z2jt*qm_neQ#ccCqf(UdVcVW)`sE?03gL=lCM` z;K}-vd&<~{yc?}{JoqWIK5XvCIvrc6Zvl4}`tCO7P_^m4F}-=($g_z&TT?1Zi=V34 zAoD-LxN~H}&XS7eT`9&LF0FEpLfmz?$ep}(yc_f*6hl#BeWZOu%ZeBi@95q!u~E;{ z)|fbN>K&63(gmM)l~k1Wna695d%PuX&)3Xxi?yFwv|+J%hl1SCDgB7f8%I6;-Vym^ zeT;oD%{tEs+XwS|WbE_d6=c2t_e>*hima9W#(VfWXsH>fDcWzlmH40ZL)!NKueqmX zm{#^7v|r!~hiS{#L4OME+VU;(o24z^nx*cRbjaP3^NE`;_jp${B)weGFn}kKC*kFa zq3ZkrpVKmrkNEIB5X2ZZ6Q4kId2LRM3yYIofh(E_dA-ZE~!Nx2LX7gYI?*=Ty+A>E>8em}S{y zETk;%WBy;tvg)X`(z%cM7o!_fF`= zY3RlSOIPlbd)iC6vt7<%IvIQaDDEp~9u{);wum`0&R4U!+d8M|ExY2=CrleUO|P6; z*<3ZNQk6H1`sPX-QVm`q58m_<@FU(FlQ5dvQuB4&^p-Zul|%_wmS`jkfrDM-8<5Vyf2sF*wr3 zIZh>a5MQL8jg&1gHJmrz$JyfjjN1c@TN3xg)ZPmHMTVNhKAjgo*kg~cXl_i@ z#!un@s?5Qj#r(JP|2F==G;Xk`QNAY-L(KoYBN<+86Zgz)9&Iro~J#VS`Qk*gVUo`HKk5xwHJg4J2$`D*x z1+OCOduPMFefYjOXpg}Qr}ZmOP2W3R|4i-d=8Nz(9o(a5)v4N}(MQU+-S2d0)H$B_ zjswI^gMX3w|MM94!+ex9!J7Lj){CUe-2e0h8eVuZ`Ty3(@ColEP5c9ENyd5vv8gAJ zN5=W69vrX6m)|1NzR0}FILp`yUo7)2<6FS^!sAYqd)lMhEN!&fEp4^h{^lI+{u`n# z|6lgGx8#mq+HU7gt+xlkBN9uw0=SRiYcE0!l ze~%pi^&F!8jePsfpT%b3=iIXy#~rA)U4aJ86FgjG?O|a)THGZI|0MCYTY(AZjc*|? zp5Ua6qv+IHw+nxt)$|M2pvecSwoyMmez&W=+&0STc$U7%yiKD$L;uDcGw%KHSD`XY zeywse{(qEVuifle!2P`)pNUbQ#dnf-iCJGN{EEpFhsrd0;>wZio#fMKliXW|oD<>a z_`1k`hl_gUzK@q3R&gy>sd4-%_o&BlSE-FVOXC^S1jaORSD-4+lic`y;T62SGV?^S z{m6(h&O<_Sn&@UKh;g3yUB@$&@2kpC@vrN6x8_@o>722OU)WabblgnaCB7fDs-=?q z)phFj@yNV=3!1$6Q(xmQKy7)q+^vqChH-CgR@3;O7JIj6;P=4!@Oq@I>&)`yy*8{|Y3l-PFCxp% zq3pb-!ts<{#M+i~iC-6a-d;)kMPeF?&*Mtk*h8DTxt}p&EY9Ad@N3)GxsPXdsK2fB z_kSqoe+G_IMqbGY-K+$ zK9%CB7+2)6;uZ$~WX{LFGSZ8C({<9jnZxc%)`K~ht(4n9zXb2U#2#F9omTcj^$#3! z@BP|U^@<*~%Dn^ZJ-=X{bFr~e{qvQv59GQge-GSboka9`^ms)-+n#Vbywc~TkMEN^ z?j#nU-1SVG=cxR5q^dGT#42ON1XV`;D&qf9MsItW|=TNTtu5cmWHIx2qN#owXsQF&VJ`}zF zrqY%kX$$Rg@ouf_ApNk~5^D|KUdDJ|qfJn{%R5u$?!(A_=Na_8em(L3X`iu{vzms{ zHs?U$1@m14>0=T7`xJbL&VAHYAC3NvRr`_LNifXdQ$jTPnQ@*iz}X&y7YX~u9_OyP zwphWHEO&B0nwBMZ^TsN-@)6^%_lR%jCn#7OGDcEZxvD)6PEy}0zu|QJ)nV-eN{<|| z4{U`;4^9+4a{qV1t1>@t-0R-9*0_KCQgmB?c&nc8c5{DyCR=I%iwuB*-Mbo`R<{~vpA9$sZ}HvT{7oIp+z zmV_iEY?4JK0WF{iq-e?Ff?!3Dv|4FP$gwpLts+_%YB@<QLK+u{KtELr| zs4ZJnEVc&i>r(rEO#&LRkwZ+?(sQOdN{{6eav3>stb@zFnpnZ=Zeh%#;-IA<*q^U!c z+{+v7^V|d+p>5?)fo879zX_k5=Iazbj*o?J(f-r#J!@n{zl$%+@xHs&d1FFw{JQ)i zw}Jh*>vYpynGlq;zRrjZ)uwP)iL3c2`ciw$9u79#JWKt(471N9Fz_d0)aiv=D?>U{hu^e^0?S zmZcy=v9aG4`!NeY!%*-e`J9d{r5np!T{K3on_w$Kdl}8&q^#WSx_Mhp*F<>Z&;FG- zV1{unj8YZcJ)h>VcjalcU~Q^1CxwaMVsHtFbkpAebDRXCujK;o%%omww^q~VGt7VH=k&mH#o`N`uIA2E z!GCcuFo7TAulVGrr<-5DL*G~2&UcaVebVO?eaCkmXM%qo4R;pN@5}TZ#sah0FgD)J znDoU%9oCvr&x%XH?>z847yMrg{#{x|A@};@3j@i6I;ZdL0+;3undrFB|0>%I!2|FM zG#vY{EbbN7_qTR$V9xWCc`*z;yYqRUU<5yMI+q=B{`8RoaGf=%ZnRIyg^|sL7cv%; zxZ^YwIuPay`S67@O`Afmo#@4vf`7#yYB@9B;twOh?UDJG{-k+BgZKQ=iZ1g?^gXz} z((f9h(kr-gX*D<%UTNVmX3vDkqW<{8GvF|qwm$y%()jtK7#xnzF08Mh?H4}QIZIRZb58=D6AX~jV|wAWNS zwp+~+m*eU7L_J5;`22Ca85m=?Kv`D&yn?FhcZX*y4{*1d>207Yn-O! z>2aJl@Hlp&i{;vL16VRQe$V*yHKvidF%R6%1;-aNH|B5;uAUn+Wp4C?|HJ4@M=ZIC zo-6SJF=G%dJ3|jS{h{$ja2K76e8$)&CPCx_Pt8!Q>w;B7BZ@+WVB z&-1~2t#c`P%DvgLZlLUn@SHhS;kxs3ix>5kC+BoM9#^1q18?AY(>H$G|66!Z?73Re za&#l<#LFyOY{|!Fc~3Q#b{m>t{PFw8haei`}R~d*4xn6ziW-P+^^niPPOPY;fkyD9pb&xPd!87qLFnT z?1&8bRV@49{8dO7$PJ8d9c>TL29<13T#n!>Zt zL$0OsoG$OI8+KUlLJLlQqxrstyGm^OP`H$D#CX|sj$YN^U6-xe-}#4XwU)nfu|Tj%TS9U2a^0 zqJ_@!*wg&7sAv31*Rm?+!w%l@W81p0qI1=!nNC%2>1)-VPD@`Cya*2712(pEv%q%b zy3HA^St56*$-6tLw6&l+bWYf|*1Bhdx5cI5y?op7V=? zl};mgGko*2bs&uSS9oiaYt*LDghYu|;;wlk_=_@Q&2i}K zFgm0Uc^k-2FmHrD0vlXr5E(4@4_(Lm;d~eS&0LJ#*yc*!yU|IFmBp)1ZeSl8Kd*et zmpy4t@}xH};{DirBm4p{Ialo1V)o{w`+e?aOhD{l08{tvvl{vFX-d*785tyg`QJR(O+So0R1wm{yA zyTP7P@0ZED_!fricU!Jr#CM6cRPw`-VE%avcR+!!V%BlO>j+whJmAgN{@lF35|2oG z#SdW1Igv%vqG9DGmoO6)ti-{I4>nXbc-P4r(pf*wz?RCyrW%Q!oQ0m8jbCRlc57nuao6BxEgM|;o1Mr9 zh++LW$yw|~(kL0KL1Muj8cZl%d7B~DDzT8p>FP`l( zmKCJcJ#w+|?+HWwM{gLW`N-kHTDK71OMCWgcba>5qZ`0GobcX)r!2ojen}B9mEThA zk`oJ^{v%$8zeDU@=Exyryqd%7+zPj)cjz(bH{T^GDqkn-noAf1#czmXiN+VaxJzVs z&x)(S`IX@Qn~cFX7>fnmTX6+GpTTO3Y8c~CtrNXFk$i5(2466^i$2e+Df%3T+Hu_h z^p_^rxJ{y?DZdYXhH_%nj@E)7eh-7wcfqB^3LHiDYPmAZ+_2l&wFlY|9ZBXFYnX4d zhWYmYX=aSz8;3vCvc|@X!pWxLYQ4rs{u-apb0+^Axz-M1(0zFBfKrfE}3Z>#6Gs;6I$;&rCW_pTe_u3;B#1QpeGx<#Qw|! z??0pu@Z;%$TeW^n9~K1A(<+^gR^)C`<%oo$9P-)w4`TW_EmP5I4eNvwBdTfjyS>Iv zEfU0iw_I!4~BN2`xVS_Xvd~~k>Rnl zqWu(2+sAH-_8ravzW5B+yT)mHIh<+Y^J`N+zjvUQ?Gbv}&)S*Li_G&N($?6~O`he;i%Q_Dz>kzKOo$dzfzb zf3fs`b#YOj^W>!VKjb~?^Bg8_ROG539@h--or^zruA?}($dT05!8|b>#)xSDGyPS( ze7N+z%(d(IwQhKQ?{$~%hgpNPfD7?yVQdYe7}m%2W0K9c67JM z(%^RZJil?^qafeVauWV{D1VTao$$zzQ`;_qvn~F=XO!kIIj5Q%ypi=i*)vl?U%vyc z=-2eXiz?1=dLX?xxC5J8=%opINn;KO&)GMt`1boQyvMU2yF+yRI!niAE-w%{8beDb zwLiaeo#st8&GpLHGFH*tw)H;GPr<$BQ44$VC;*1Aai z>eb})ao4W!ryuhy{Hr5T^Q)WXeF$@fJweg@tBUV3SA~Ba`dzH99o6Tyu&(_q=l|1} zcwPHjHk?w!dCxRz_9h~7N6(xI2c0LbAZv_hdx^Z54QE$N{>S6*Yqg#3n>8*6S=e)Eg- z%EQ*YvGvo~`7%z=mwTQ5&2c(WydEifgXoc+=&VZS9vByy6T8ukm{YRmE%V_Q_y(Y9 zH6H@p$W`C~pX7Am0n+Cb>2EBJGZ`k&Y++oV5bz2&2<>GU_=eaS^zS41!F?np_{N!hNdwJ@J2^+o#?-?>DSI zeZDTQ^j>A7G;TQ0FS<+g*x52(&Bbd9B4Y&&+WL(2=>__NKSas#N|}qua5eYh<;|&u zYVJ9=>A829_2($Q*Wfku8cXSRpXbCJTgHF4my8!X#!xa|_uba@v*>sCqF2y&*he{^ zxb_vqoPhhJdm7Xla|^mcI2PN>8uNCEd5WA%9XmhAcBA_;Zur&jZcu*p9N_O(-!j#H zZ;8p8!k)t%)=FfpAhY@b&pG(t1MEH6_oBpbvHr4k?P%ttf^$}`_!=|oo%!f|*U*IojjuVb}#ya@=x#lGqhhTv>$8R%37`M15c7`c>L1Vz@xu3DyJlL4Jj{4UzKaOnI`p^e2({It4%EoOH zJyF)*g?uA21GL|e?ZKNG--VC?GUuR0S=Umz$V>+9B(J@c6c(-GoqWaM0 zwPT)!RC_qPIYY`$l(NO>O|!I~bO!JExmzWzP{B2pJ$0UrcX}5ZI|jav;Y&RMU9Gq% z#T-kU9?MEL-^Z_>y)xbWDtH;ix1z~O=1asW3mjQ{b@Dw)+Qom)Q0<$uzq|O3FK?Rg zkqX8ny3ENx=`@jh3**v`SZS4{Er?6|hm}@G+SlXKKC#l8NRvI^(e<@kX*)=p9hdfj zl@=gvW?b6aR+<}s)zrAOomN@_X%pkp{$QoeAx-vtN4Mp7R$3)#wti>h>;)^Wj{YF>Adv1T;i?3gym zFEk-BZBHEtEvT?)%3f=4AYImtw&bPk>Trz?uk*dccUg0Nig|CZxsop!uCLqLKlO@X z)>3Byb;^3b#5accx7#c{;a0nj(-ULrkhTp}hx52q2Wz`ase`pA*>9I7_1N$$fWOFs zzctUbt0UbAZhlGWQqx3_gx9qq$Igjvd)^5PE^E9C`hi;m+>3$x*G6MkJ1_+|e&C9n z7r22aTsTh(?z5Xq`hg|$YC5n44)V7x_hgd!GV|$bssuSlfU#*uwFGuLww*Fl^l{N=JC42n!oNaUe?_h>N;H=3+!I<*XU)SiSyP;2Jx{daN#;;r zFInH9*D)H0R(ndQ!%Z2zMilYabuYRAed2u9BFe(PyTAS`q-5z4VE5(28%S@9*6X8n zH>CryH`t&J6&cl@akNMJBfh=Ra-%3lkF)%I*Fq2b)+~&|$*(YS{LrNF5 z^u5MW)t-ICUuKYg2>nLZilcQtwH7?O+S5)RyN(Ui;k{;v(h1cXGU@M=F7=_yZ2Td0 z3a>D`3x)1YM{J^%p*x!`lH5btedkEjEo(8 zFSWm=4mMY@7M$b1uxDNE*pnNH!Bo0<&N*tmO2v6wy7)B45FDv}2ojea)7~M;3a1sP zR(tNEy+ZSr|F*4f|7|1&+x8!>1&;&9)3CSJ*0p1BNo15Y{p z>f1Q|t?=M*Gw`h8-$#8)hTlBg{OJ#%A7Dtnq%_V4;6Hh5nz{c;tLzhL3SMDh8t|gZ zKAvjcLs{nIvPr~WNi2cp<0F+0K8f}Q>6`s6kMz^|25$?0lQGTZ+li=eGWKKn##sm9 zd^LQ_;+xQ<4X=@JBlsrqXeX)+e>*mv>)#n}{We zw|#TP_WhiFdMWfLv|VDxQ?S{F;4>JC&tMoasxEvm3E03c)&iWY2{?pi;^t@X*m2>R z0m?|cU3V>Wksqr>YeLwmHzUU&vZc&x%VKm#;HEmtb4Z!!N1V5*~v-z93I+ ziQ%cM_1aAoPmT1|;;Gw;syz#7V>C}~ez9+!`Z(X4!s8grQ`MN&WybJS_3g6MsBw(q zsRxpK@zjqRE#F#i|3;+U7H{n=u2!}mbwtuq^`4GxCDoqO=~I;Kiovz^Z}jH5rGjVt z*(YysppQ5i0~ccvAJ6T;7i=_-viuuql##V$YwcLI1-aYeJ$HoSvz_OoW6_q62B(Ji zb0tv54L@neX0h9^%B&lqXshvpYR>_SHynBc-i&W!@mOQQbeGZk5j=6{7Zue!#B_i#B${|FeewpYUZx|T7_K@a5J($z;c*UV9RV2k%~ zy7@jafO2M#=7l=m{4L6hZe7fLt3jUD@;lBqJCDrS*X%s2^*(kNd)W_0<*6Xg?|4`3 z*x)cP=%XEtb5%PUWZmk8xOUV~{%Nbc^si*Q!yMWNjBWEQ7_3`85eK6Y7?0WQe8&+! z$Kds-c5Wlj>Tn*XX~$LlJ}OTqdG6y~_2nJzBzmDYPCLIIX-92bJDlj|cUa|jeAQSZ z{V9Ig(aN}-6Fn|@^R02gX1pm5MjkMhSTJ4$M)Bs}@UrPCJQC`MX)$d9S ziNul0896Jw>|b+^=~}!uv_RyxEwhKJ_A8kkne&#dQ*&XpXE1HF zWp?x)hwepX@Rm|+9rijx!zwmzd+!*9xHXv=zFvu3bT6Bs;&#@#9y?drC+N5x^)7!M z@>Js0*0R31if4&glXb@38xs8MBreN~f12M^aJ&OvF8gj3pUxSh_80Bht!1jr6?^^W z_VwCUw$^VV{I+0hc>N~t>T1s$#N0*2WA(vvd)o_pcZh83z1KrxG%P(N+;`RrgW@Nb zHN%b+tKH?C3B+3Ao-!SuWViVe+AQl7K6G@^5jLzd)~NlHTF;8=!zqgAZu?HP=NGhJ z_R{nvn}uegW8dvP8qZ7nU9tumS%a}+t_E&*<@i3^eTt3i_;yaqiQu}T+VcYo*L}5D z=-*xgvEwi6|J`=pmfL4L4};HgIkGh}N9^^Lj`{?DFN80U{v`bnJ#$oF zdS2)4fncUIkzy?rye++KhKf?CGS2&h(3a8apyrAr}hJP$M3p}#Vtg?dV3UJB3mC*Ry zB8AV(PS-IFQ_eDX*D^<4#54d;=28u~@d^!z4LyFbI>R-FjuP}9vd-nzp6BSZ@KVc$ zZt2U04wcDy*Rf|S{Q33Iv7uQLjk2Mm`mJr~M<_2m$UYbBL;W76ccrskm#Or;#+B8c zRWdg8?H=+;+zxi|0vW;WpPOjL-YE8KReHQ0audEHn$2{X#iK24)b8nwQ6_y&YMHq0-Pxc&ke_pNbKa%?cjyqh>cqJ*huUo?QhHF zOrq1#RbqUlF0F@@0_$7grd{~N+4{^69dE4TMy>Vl2Fr$T^L|_J)2&$*whtp|GxeU4 z()+4C{{?=ccxOXlR4jqE4|~Uszx0~WNuTl64H3KhlyJHMY(Y!L!U(4S(pYn=Va_@ln${KiY$0sGv52$B{dcKe6bL8Fy z_~f}ftNldy_ztlLPx#1F#6F6@?>TDg;G5WD_P0j9 zd4;TLDX;YZ8bhBpXJlbTT|`%*K94*z74FOQT7+f_^&z_!tE#ycC#<>*jwyD#Mg>XH>hR9=;o7^#+oAh z6`P%-s&W}8yNp4ZYVj>1BMy;AWW*tOXC-^BEgx#koX8b9Q8snJ{dh0YCh-qN$2(fO zeq=t>_AMtAFTie*SV!jUf!vMGFwYbF<#FQ7Bpxu2c8>cm#y)m^sMq-zs&B}JSLmC_ zgcRsaXfQL1Ht|=sc&+uJ(#C4fVrWiehNZLj;v0Dzsy$bc$JQ^8(%&e#5rZ$yLt^76 zZxZ~t`a73I`| zH%hJ7fK%DuT?%eq|D~b!BFMTMG(BDP_-)L0;TunZzq83Bea{da>6otwj$YCGtek#} z_r|ARGgRs5jm^j%aF}kvLND9+xX?1^m|<7O;Lss{a`;Nmiin;bea^@!g3q!9{Em;}-IcO#vsLTt>s*hV8*MAeoDf^d_TP*B zF$tXdzzK3*;dp|Dc%WhXX~_o%06q$jxm1wG5DUW`8>y&0rGF1 z)i95_b@(kU<6`LTFJsi+=$g%}|AQ0ZnL?MA%^ktr&3X^cwpaSW?Omf3?n{4P?Me9@ z-1fJwbGqQRws%Zw|MVE^>#*l9G^%`Jtlg!ljBq7kQICE<9hAyutnuc_Vlf znd1YG;rYs4Bofzr7I+Eo>rZE2|D@P`{p+xA_eFhQV(sfkcB$`f_VwFk3atJ425EsZ ze6#H9&y~IU7r~4F#5sk;2RD)CrY*A9ewEYEanb)d2@ANY+Z8>_ryj|^? z{cn!T)iN%~bvxEQR@RO0R_~7N@P1Zz60tP!=Q+@m_>76UZn=xN>Q3lh<^aAnIVUBF zGkTNmP8yRur_QtAvF@hAJCnz_SyM0M7nqRbZ(r>+J8GTgXU`&+Q;Bty{nrj+DTv!_ z8g87U-X*qz_X7Jp*GeB|rBAiedEcVWi_L1@-^6_9+~X~!=Lb2*c;i2|!3&3W%O2Qf z&97Zg%N;50!nd*OkAbreeok=t8F|~SSZ8i;OfFnTkvB^ z-aTdL1hkzpZ_8QaAA?7M4_xyd`txo|_l)U7wD0ui0ux^J693$>u~FhSSkG*G_w;=8 zJ@}WzYyX`0>}!XZzu>>6s z|6}Wa9sg2?@c$1785{4w_G!ny6WePneA(9%nx@}JHD~h<-(jJnF>oaR6+Z;$CqmOYcotou+&TMQx!Yl@ z@N2!-pv{X6x3r_$a|QM8A^i@@p?9Fq(_`Wx)47GHD>9&XE5a=SBF?U_t_GC3di`Nkopl<9`9 z+(yRE@kfkZu2MN$(I;`?6VR#tl{j5!CI-HR=ThKj0bk^h z_~K*ov}nJ*^F+007d!r<^VIGxX4hIiJc$ z`p-FM>WZo8#kJVg9~pkTujs)+MXyuFD8ELk~HZ5!mMr z1Uq}Ig5CL9wPy;jg%;&}t;#%NA~}Cc)y20h&}X5fQ*Q^p29=I}qUt?8u1{9Irwml@ z-^OWQ&7o?g_x0I+3pYasf^%56zv5uEr+yZ3q%sDymvPc#@K0i8Eqs;mEc<=zK5ady z*ODt~e?9Xm-lrHnZ<_EYxMkijCY>uCg}YZe{A$iG&Ng%8+y->&9jqP6`WR;eaHe;b z*;$KxgZ?{^Nqd;5mvbM;Iyr0G3+CsE^S?9-Jh0=t|z#!t1yacl7;u` zds6H(P7jWh^UEXWoem^_lYVly+Vj@H{0r}Sn~SJ{nxN=VRkp=gWPUzMUZNis#bIcK(f)G_%@O>$!^W-SD(yD+d>z zz<24+@p*#z?m`8Ru`w8%bxz-T!k^mc|LDQ`?$@>AGo$Zv-q_7k#3p6`o+~o<)K~;g zQ@k#3OpWI-u^nn1lDeOuZo!lI0OhRP-N>r1p~G;W&ctl=2+osfc=zoIrqq!_9a8si zsM~F1?i}yP>IxuZmO!6!?o1u=>5ew3zcsHfVk+cVNBBP0NZ`rgK(JPyf8q zIl9L4Chc=Gj=gy0lnF}TbB?R=Y$uQK%56V~R|3<|I!!#UTrBNnpJQmAoOOHFfb#48 zEm}W6e(fOa{K44!v3vR=YsLEPdO2TC{KFlrDSd!!EyC7S{B6@I3eO#kMW?&Q^9$Ok zz9-~_zdMs^JgfOGK4Z}C?J5A$3A9I^f#HHQv(ja(%&oyj$xdnl8WXbk84(UVQ! zr*fF=$&s;>bz*^$(L6lESi>UCfi-8r=i$vu^GXUi`>C~yHdYa9+m&ww)id$7>~%YE z|9N@lr;}ZN^^LgOu1QY+e!kDe$Ge~Pxd6}Z!aTEs|J*gXYF&1t7hML}l{c|IdsB|N z^rlqv`mdA}UPnFuAm5*f$Nk64F8|-3a{9Z7%l#C8uYwb_;9QfZ{Jo99iMExx7hOmk z3wx*0NAwx{{of4~a>+c@^Dbt-p%)8{x}j0=y=-1N)4#cP)NPwxqq^H!&y}@6ggI7UrUnXq;0Ae_3Mjmuh6x3ohrb_54Jy+&>wA_1U9lmcwf* z$a4(%yZP-YOT%v^e)Wvz0>(qNZ)$Nc(@`A!;46k%N&ZKWnLhY?_Vp!&V+V2nC$L11 z6&YG9&$TW;ha&p}z&e57{A8E4*OxJnxL~Q@1O9~nFBvU+E0U@l(EBQ2$~k$$Q!9T6 zZ#K9GP-x{Qqe$MxCN3duk^{<+%-^Uq;YKY1TpZt>3>HUD(;{b(Zb{wtk@!9%P=!%KyS z9?Ksb!$XT%PZSzi$rwM1UMN0JiBZ}M%qM`Q=M;DNfMc0c$B}gz@WC||=P2E98RgtY zmeLIyMK`2esR6&skJb+}n(Me*P4T>U*jqb*e%N?sjpw1Ffq7o(WadA4gy-G;Fgy>K ze$M3jPk7#=n+G1p&zobD!9#y@>p8ZTXM2vl$9T18$Ih|E+=(1L$I|RM zHmv_SHb1?OIY$2YIrj8dB6F-+p1;5xyS>6#bKS(^*0s!=N$JLdB_oK_NhHa|{7;a7@;s@;Fz>(q&Yyhh8nW|D=AG;ZnVW0us;V~3wT|R2?kHODAanKx z$D&OiIfhp)X1+bdoDDgKsrmaL{O1Pv18H5=!2iJu#YLAghp+#wQKZV1{F~*f|IKn+ z|IKpv4*sqF!3+Pba!LPYxuLpT2l})<4%IwIkAs7E8HYa~OjP4=Kl=54SMts#VzmmB zlItfj&Jq{FKG}l?{GgukJ>!DnO)DKksupwZ!2OKxT1QHigXen2_d3Rxw61Dma;ktk zk2^1xGQJ0ZTgm$z*6dfl5a!Qq(YE*(;m=R}UUZq*m;!ien{79X{vWzm$MLH*MB)in zqpvTo$uXbPYl$tn?@!Qi1zQq(#T6vOf6A@60{g6~t(3R?3oYK6`kacqb80-_nyLAk zAH5%56|+}qEA%b;S^T+dw@CZTddF|t@?Lz=bI22YKKIw;y^r&`&*J-*xbwNsly96l zQAeBI)j3KRiE4kFcWl1WGi$zDqs~GWKgt=DX-DoxT*C&;u9MTEa9)^oW-g3xBH+oepC29-bhtvUj$aNzKDKB zzUa2Kc{vBm2aL{HHR^t>b9lC4=kfg6?{q9{C9n-gs?t>?R{6*9XMvq^BDBDUE$bLj z{ciJa)Uku5=b@{Mt=Y#|+4dTD5wvzlEGKt@i(I`L_&#vov0Tf_*Kfp*f3T z&lP`z`?b3~M=0}rGv}Ge-I&PXId`IuaSyWe^S>Fl=k?wh#$ck-kChHwTI2cM45e?k zcpLP+=n8LTHJ%swZo?Ej$oCz;gpOH9tQOk!<PYJlK|PVcRkt+p;!)m#n*rJqgam*A+EqM|EQx zv>A_&H+>7CMTrjuM@HS5=8t$Uk9t3njvczqZFcaVyG6&Kzb<+3^~TW&_o$w!eHRzk zcz!_Jg^&GI@ca85^CaaT+fJTe8hP z{NH7qV(w-ANbo8&ck-v$FUhO}m6a3)`2WC}O4=wj7Jq@Ji-#K1(z!27_IOELii79X z&}oqKT9169V>Dv$zF@K%`)%`TJhN$gyEDDMnxC_~)>8_+koQz|AGEJF{b^tA2!3h& zQuz(%H;msPB;98dp3ba$8WbO$=4 zwEx5_(6HOsI2zx?)yc%%a(2ALW~R3rW;b}q28Tg#R`k{cQ}BDoJ!Rc5k>BNd-YqlxR?X=T?zBG+zt2Knxz)|s86P&@fd4^w1lkxcl&vCrF&HHmLqZ+?c<7tt0 zKyS~kk^l7OyU34?lp%Ig;392fuT(I^rps*p1NK0Ux_shenMbfO?K7&x zzK-RoDi(t^kFil_P;x${wa3wp4YK12ZujF`+pgnH#s0p9_W-6_LX{tSLk@dm%zz7eD8AKToZbf%omBFs`1t!_l=B-Yic~QFD3@} zf0&`<`548K3P-Xw(EFZc8$Y6Jh~BaH zWi@v=CtRP?CA_3kJ@dzWv>rD-v3&#}&rde!Io?{jqfZJqDv zm1VRO8C$FOE!lNSJ6;2pj2ZgS+w%TnWC3z6i0s>F=gZ^!D^|X8#zNNG?EQ5g^IhFx zf=<4}y2Au`Vcy8xY4dWHjt>~l9o$s}E%i$0j221X_L|SLi*&o*Qoj9{T`y}N(e>`I z>&3R~w_fY+l!`Zeo|mKGRsgrof_rNoG93S4fOXY!?xhJhS&vos(_}W+NFD62$A`bb zZc`0qZ|A%0zmxkw>@!Oq=bN3Ukvuo@&RU(`*G3zo_qB;W-wOxUy(|@fBnFqZ!k0aA zuZYm?gS>~f$KI>tE~xdS8}9l_?v=prH%)XIISb++8@Ov;#h~juM~6Mm{pC^bH}GD} z-9rL5mv%6h+H!LyieI(Od;cUoPHF6~Bh898RO#D^{qp+0res_v>8X9CZT)S^HeRNR0po06<=cwoJ7c&P zex$mWd?91O`bmSa_xv8EUw$LUY)>?L*k{*PxcEH1_l0-^iC@{b!6*u?c5afhp6-Ls z%pEkr+>dUwl=5X4T-dXFywS6Ne644xGr2xAN$YIwlZ_tow#{8%Un_J?*-?k&~khN`=rlpF2u`jGseI92}Lp8&H^?%gK;qH+GvA@U!y z^7|$Kcz>765$u|fpz{xR^n}tK!TPCpd2XXjca|d<8siAIk9W{7N02r(RJ}@@CRooO z@H~m~*A7zU_spRDEXo(%rP|mvoAPCj;5_zNUbF1No;?>i1iuYcN2q%q<>r%D@cn9m z*>!~@xNk#pQPSPXau-XGc);N9PZDp~y~xp%)RAn~bGNzlJJ;bmud9kS-9Vd`JA!Wj zuW+i%+;^+>d<)Mjfb~hDnJYNEmp0Wqf=O53H8j{O{*#YFy$Y$%9xZ{Ydvq} zc?0DqBJ-; z|Jr1;gm%mY2N&FOVb9+8fcK#zcwffdie6Jj-mP)<5pZ`qf_pvzUYEj4Th*%$v+FZQ zFlF&@b20r6op7~=PVg@GlZRZbDINOz{uF1heYmqnwc+vvb6>hMxIfFO+q8_fjN$#0 zA*vmn6P(bmGk9N?u7CezXE1a&x$$zZ{D|e8&ze?VR>+-i!eudP3kLv&am6Wfg{Jqp)@6_XY`5;sE z<(5I_zK1Bg+8NyUWU3yIwUpoB46b_k9z7mUI)m=qOwQVLJngvKc-kR&ddC^8gKq>D z4r<-~y0fR9dHCz^B7e~{h5sm-g^U*;x9=Wg47y_eW>&ExXx1 zlPcBzzD2&XAB%nYvNu1O@0H)YR^5eC*LjzmxzUn)_zbfg8{W?2kUX@h@|zP{n`#$| z4$~6t-&!o|58V9@|HKA4A6=#lT}I#IYTpaB?L}kFoBZT%dWqeNKd)5I9nmr2*bwj+ z16d^f`5kqOe!oEUcV!#cYiAkFBMka)>0-7|OSK>QQ%gU*?6X-%yDP@|JddAk>oAcs zLG8G%0d0OQCtAWbza=N4*FcaHEfGK6=x#UjB7^q3;nAb{x8=s4==&Vzk|j4<+{g`N zMvKS{ksoT$WO|=+qrsLNG8aEbZnO*}H$qhrd72f+=HoH)q9saRG*o>7d7=0dvO?rWfAT_jf5`jg|&_HE@ypFYRM9?C)ZT9izQ#4~i= z1;6FHmMO>yc<{I3TM?PUo-Rvvtk`6IS286cYi{9to!Alh@VBB{q(dQ=?}ucpDAb++W}r~+Xt!-ihnogGx}@jLzMm>>Eox?z3%zw|MbxSj_m!7mro@z z@+lI7CpPTyYfIQ4@|rpu`h42emuwQhmiVG<*|J+?OTw9^)aNYZ&UETtEU^~X6)GI( zZK0pje4fxZ@#SFmij6L|6!A7|#I6#%?hfi=Eo3V4Yk}Y*UVf=D{875HpBg7}9w;$r zQlEXE!_g}_Hw6Eej=6}$T!pre+!ZU2PU()9IhL)WZZwgQWid#8y$|{{ve^mH!WH6*V4Tz*Z3%Q-pl6 z;zeU@g!S+_coX)4@Y`*Q-v(ZYjTaT(CA=2?)ezCAPf_Ps-pN`Ke5}pVof|}Vw)j}X zKt7kH@Z~7ox$Sdw=Z1lF=e~R{PXYgn`dpf&E!yYOAo}wc;A3skI<)qk#PG2OTZdNd z_yRh#=*}wd06rI8PlS)D{Ga12pzKET4;d{(?Ril{d=gqG$o1i|SwBK9{yH>2tvs_2qmnstr*-7xn%neJ-jD zJ{LXKU(V;E%0~HI)ccq8xhTBib5UjgmwYb5$5t#1^Rb3#Uq>__J3L?Wu@|0~^~6|z zy6`daW4N*Z1L%&2(Sz6IO*A(^f8J{{m2NJvrk#_0o;!(`bK@JW#OES;Ri0NOd7M*x zo|`34!CkR=GDe2sP=EhHO*>i2(^uF9Q{ zKm5LXk`{M#vptG-11+ha0<2L9@$PNRPR?2O<8(7;mX(E9z?W~j2l)5L#V z#d?R6vHgM5S^tlRGJ+3Q3^%t@{=rWD-}N%z7}qN2u==i#GJ+2=epSxl^<9aX!3O-V zRnFA8>kHD5|STE?Se9X;$Ckc)I!? zAdr+<@XdnZ)z}5&+j>YAM$&LZzuTWQ*K@c{W0nf-e9%iCoWX`J*+-3 ze1ygaay0N6-^W|;tYHKW@t!||e8cMlGpz5(%s^IVFmRFej?4^<;eDRuORWzqvc98l z1eR0&QGVO`b@59l-zvHQ4^*h@Q}P$~<&hYv)@$e>fu8{?Uk@0Q}DVy>!#T+SDhkhkkO5 zG*^1CJu$uKlkw@S5%D~k|FZPp?u*iUZf5N)G%r1Pcs})ALE4q+8pdf^3dZgm$h(5? zE3NO}kM#^t6x9u-ZOO*E=JFHOCD4o)K)n$Vz+S6rHw+G%smYq}^bp?H#Yu_TEccJ!z{m zf_on3d0}B|=qd7Tw&CY#81IqxA^CQb_K6KYU#Epgb7clYDVeOlW$JeAJyoYo$OMO^ zolV*dEA2GyT>~e(=aY5?X|~-7QhP#Y^L<8Y&nNSFUdZzz{+Fi)ci+l?E${bIM#l9C_KZk9Yx({Z-=DRsKP#;#G$swYOAGFq!1JuM;K#GmdfMlw zS^XZY>%5k-&7~c<5o<_c;rg zefd7|6(11)HTrLxH_G?C4OoN`{bhaafj{OEjt6>LS$|453f>R7A5H}qJPKU3K%=Yo3Kn>Ld39iDfNtS_%K)>J!3?i4?> zD)+uF_aS8}C4Z)|Y&ZL!MUP#Io#5si#Y<@0D$3L=Jt?LB4C0KsCK-NJe$EtAVs4U3 zs*2tqZp~3L$(-#c_9z%y;J%=$s3{maC$!cmQhC2kU9@@cT4;m5ZQzWSYryv#tUKGZ z)6|_fLwxXEcKh5@%yqOQ*WupzTiTdI{=UXX;@jfyVzkGmQjJZl?|KjGz`GfjPGWFk z$3*$DTg3lUDY}E@|5?KG=lFlxqWnKC(f*(0I6wAMV11tdN0*8Cv9WvGzJ&j$P5eKq z{a?)g(-Q6fNs04gSJB=m|4&M)mm%`hNswF1lEB%nkm6wkZEkTj2oypQJwg*s6TQ|I=1D zfd5C8xBS?uT&(}6O=4~oUi$X`w8Z;=g!aUbt#H-bkBwjKOZ$J?=AxV0F*o>7+UBC0 z_7`&_^~d|MRT=I7VXO!C|ETg&er#1X*8kHscL4v7Dj(;^R(RF^pSHQ5v#Hm&GpYW@&c zC_38ybiQNHc8y6@{(&xZhAMQn#po3(&JevV1v#i-Od=n4tF6cVntJbN{ciuP)ZnMs zyU98DKB}?3MUS7C8XTWXyrJlNS5OXH*Vg&en8O2AJ0yn0OFA}hQb|J5kP8ynZ%GVb z75SH^s=g@xhmI&Qhw0Ln6{*2P*u}QasNhK4VLfoLk)INLh#!14@908R=#$c)PV`BM zKU96$KpJ+ltzW7#!VjP0J2rIJ%T`%*PAR(^ol{~FRoR`SVO!fes46SG@k732Uw7@c z%A%L5vX)*dafwpC3%lFaQTMyjbbEzIVt*@G!Xs1CblcHi)mT{itHdTM7}(>Y%gR_Q zK8a4N%8H+S5@oT^t3);kpFBG)m{c7Vn~3hKViVDS?bt+tsrckPbXIiY{a2&~!+a9^ zTs;e)T$mQz2Tlw34%YE(mcA_UiE3_PgWJ0E{uNd^;g#6l3Wo5?S_=kxb*_wyrB_Rg zqJn`vE;_c#FZ>c+d*6n%prV^-eu`#+j{@LF(Y)jXugTf-<3Z?_XnFm`qOFI1QM^PU||2-_JOKbcxM@9@B^rK;hp#Z zG)}CTN6U7Qm_-Ex-+*mL?8Dwyc#h_u*!=sKP-%WZ4)Jx2VPl`@dJ*BKC)} z`?2|VV~5!GN70oL9kPJ9a@+n$=KMQtf24=)k4t{kH_zQFIwbAU@r9AIVBUYW|9A~M zhVV4vS#r>e#fGu%i|x#fXdC92h02C$iML@Mx|BU1QSlqUIu@~Er2S&U_-Gsc#A%}c z+A$nuaa}V&%*&b#O{n#`~U1c z8@DqKVlPUJOMKsQej$4*e@9FxX9BI@Zj@TXOgdQ`D<2bOALVT2`;OK5$922ePpJEy z(fn5*?UNW#ueM=Ty*x+TurIHmEwVp>@5YafHO1I&fe*iZ`(eGO?Lcm7k;F$G@Lo4d z#nzM#(f3%({#A*26<9}aX586hD!4w2n4Mza$@u1B|0ulJFnnJ%*U9&k$o(F6dM$Fu z+cHe0*9`M{(&Ecb(XpvD!!_MVdw(>Sc&L+!Gi(@&er_JGU{nm{-0A|`4*pIrJ6PFS z$Zzn79UOcA#W2R_=#{Z!fSm3V-)esP=o4kix8qM-NWmfZXN-S zowt+c6F-Q=^9sJg`(AB)U*%F`mUo7}?;AX|$#{b6175ejZ*Lp%SpHZ%wMF|26fY@D z4ddwOmD^P;!mH2p?I%e3*BW)E6#86b-*1)d6&WAzKZx4*JGQ%h27VYLRry-p0=DwY zl;g7*^fS*+-hU|T10N@w>(0tiG2M1d-LFVnca}c;-Tt;-%3JW%-e_n}{51x&Zj6CW z;f)5cJIIquou?&7>idZ2;vvR#wI}hJ*=9H|J_#p#v;UIG3Q%oyWQ^P(d`z0RQYUkvG|zm_FCU)hiBH^ z#+qBG>-m}-a|`gKpPRU=F^992;^-i}f805m^*_cs439F!(th@0ZcNsE!p4dCvL*_j znhmZD{HTn>651D9WE9EV>)?B?G2ASY_E~xCZ_>VW+86%5h&{rqG@b&B^!Ypv&a8`T z=K=451jRQ?iBJ5Bp8two;XiHOnL4(yG}Gs~syD5-dEeCg?`lS})+*_mC#&-Cg%K=Wy2E5ytv?#-{1}^VPl3hZEP1w&`+8jj`rqWYv=+FKrDWYgHeihgYfd z35gH2#~iq&)VoLIm>U{`w>CX^v04MR=d)@@wo~D*kv)LV(+1(csq`Zz&tryaYvb5h zexS-<<52x`QvM0b8ADmJ$! z4{2Rf{eWkhvF;|;Xd4W3`*}v?#&aL8eZVur{#JNVk5M_}q+8D0S5^vwe znFx*z$-A7~ala*Rig^k0hWqBsN~f6j{E05NAk$=bNGL%}b}v{L6?-TBk|b?@C$rzTyvz&bQRgH!?b3 zYOj3dcD~Wk`Eq*Y`=*ue=B2l8iqt!$SH4SZczG7QiefW8+`ja1KT65Bl72+%7Tt@q zf45KHZtav^vOmK#mN$EIl%I16Kemn0jl(uQQ-n@L~FnRn8bohL%) zOd`FCdZbPF^L{_?*Nrxq6CAVfhFym$n!10kv1mtd^0elon73c{2u#PKlpWT zokr$kMnZ9G2DE+)=iJ59c?;tz^WkRjr1SKq@h9y(v|s1xP2c}z=b=wJPjA}(shwwJ zv6_2zt{UPL-1YHos<-ojk7=~KuC~UrJe)5w2dc@Z=YZDjY`vvFzQlP9tp&nspue5) zID4&wGcMjnnN@M>dM{Z<^JH{9&Z#h);5qL$y1D1l;yKWj?q6?Qe#dV20JvOW=NSN( z^XxnW;Ih=t^EtSjY3KVKTz-Xo{qYmWpzax*Z9Ea0pEf(kSXRNjNCIbLn6tADNBDgx z?@5dA_(`%48MN0izsr@>TyxqPVOHHV#k`;ScO5Yc4=`V^CvNEnzb`Jl@wJk| zihD{6J7)~`ch2Arx3d%c2RVQ9GtS*S0DJ{^N3!`3aPe2*_N!7bWoCzU!Yn_vz?b1yCr}I7xnwIZJI1^URaTS@R`gZOxZ8QH`-+A77Hah8P z#u~}{JT&@nb7^az@{%(trG3rdq)&P2(rs=e{qyAIu^2kj{azz*Ij3#>H;iTPqSMf? z1^DaR3fE_w1-DnShKp_#_brKUJD>x%W0*QatO8xSl)KsoM}Oyx6eZKILpDRB(udor zOO3_U;-K5X8S}G^;KRsjIS=%8*`nZbOyXDiP<&bh5NeReP6&coTo!HcL<&UROQin^Dsgg%AD z)`!00&*X^S&y>peyAzBwIWxPHad%&S=R5l*;Ac%(cT>S>J4PGhjC93MYK>j?na#5P z+~1hLb1Lm&yd{P|RBM=ad3TE*gC^>*@t*_!1@;!^pJ_-}}XU z>@nV7{9WpA%RP`{PMOIZZ7%(t@p#Vg@b}aqN_G{JwjLWgx7%UXFb?9Y`6qh>RM}}m z%o_AJ`Sy3d`I6&cT%}=T3w*{egE8ua52><0(rF(_ImU2kblRIb?R`lb76&tDsH)Ee zOabchDwdWe~!MA{S z=&`L7JSx~5bzLtAT#NoK+_wnr=Ye}Uk13|i-*g#2WyF@UeMEMQs!b=-HpY;>VVwE? zEj@;ebv%9a+0J>i(;jb|MihOyoV$)+%h|Y#64)0$2;Mjt{*MgU?lA2;ZbaYB<}9u( zbdyoYtkK9UW@hWtqqP3Jg|TSndAuv5YcceXe(z_IL*|TX%VFk>vN``C=aZ#3Z#z%> z)#CHX+*0{A=`&;VW^>OP?e1A|5$(E=_FX_b&u3p?8T;#O{@u?RBEys)vn9OFC%k*R z+@Who>_XI@@G;$o&*q-85!eTu89uKW-p#xCOU1V!K9~nNYx@?;JbzYka2;}~`@^|~ z$F4y3(m(gX5vG!1$hm#+4ZgLwk#pVf4)u(jI|~0$&sxs4<=!@eyIKwZ^snQm0A3yX z@G8!IzK?UCk&~Pgl4l}2+wOlLU7aP}jVwE=Wm#KpM!G6HfwGmze~}wi;2eJc_RTWa zRNFI}FUD5oZbW6Pu0e172)%I663{W%`#lv!K9=2WX>+So@fObFr zncCPhF)e+e#nu<>v$B=!2T!U`;7QKMR{aD|tXcd2NT26|r@*A%c-jY^KD~rFO}i`m zI3F9`qvg-w>n-s08Tk5a7UyJxFU}It^as8^1;&TKu=%llHd4Iro4W<0WqTBjjO%XC z&sDN!JN<6Y*LP-aQP0G_A%lL$bDW%QD;2xcD%VE+adNh;RP54xU494Y{m9w2Qp+w4 zX*t_gDt4*WhLtG@wPt>=Lw;jK>U z%L7mE^1U2ie+PLb-`l*4Y-y)m+4RxwYvGErcaq<)@qG2p=10fU57D)b(WfN7WxJB< z7rC;#e8)lyZg*za=ZyJzu<$wEe+N9m_{O=9=H~1EzXbf~{wFQI$5Tl89EUGhSbu@S zS-4DXio)5`@nv4oWmZUClw0DR6H{*S?vbk8+W2x=_lE0QGHYIJnX)`p<|pxGZqjAK zb){b#TW-Uds@z@i<^B{^SJ!2+Wn4w7%&qZd3hGq*!gX!GLX{IfD>!uL*LW7YI8z1u zSH_pE)nyev9{r}S?~u?Q<$fF~cXeF3hZyHun+BebAy*o{xJ1@52REO1P4t~2=iq1EtS>iDtMGgg4 z;-hA*;N%U~8GP@ji_OyJt;7D7R?-AXe`@`Umynd%q;UTK7N@$dHD3Rm?P58#q?X|^eEnA^5^I~ z9rIW}{Clp>BmQx@i?`;8yCjY>gPcA$R*Q zhVbG3&rLW>%EQl&FkT(NOXPjA!a-(p0?(@5k7tAT%w~gksZ;tTZ7AfwiLFM}lV)|Y@3cb+?N}Fp=@p+!6KW)%rOdbnArL2EEVfA;IRd*@> z24(-yPZ?QH__->R*}RTClDC!rSDr*4!S{0XN+-Ia3mrBAABO0#`hF2Rmbe2ODVcH4 zaT(7`A2)Fhgq(A|o-q%tG>SCs+UFRJY(C{m(a~5-1AjutqHk4`x6Wx4$^El2{dy(e zlzx|fSD&{h&(K{_v<_waS_()L7(v>;R$zfMwFdN8Yi^u>YIqH(W|7ackUmQuHE+64 z3#U2DeVzrRsqZr-f7w?0>-E%&NI^A>1+z37_j2AMbU+?{Wj zMj||7rO&gBGBOWa8SgpxI0E^^%q3`DHtDwFpG+KN>`HPM|76iP$aVUj0F{rrE(LBP>BBka_cw1$nK?Jt*j0thmwN+f z$AV?M7R{V}pT1x1nKvfS{0!NBfZuO;Ue*zvHf834BqPm+v+Q7W+T@wT*~k|zN8EP= zW?Z>J(P?qzlA_b%$_l6C3!b5m(oUH>a-P26Dv21G{p{yMpEEB3A0prX zP9J|D{dEm(F2sM?&bVEgSv>QjRg5Qk&2<(ojsnL|UiZ#3XO7=lII{y7GG~tdO7V@B z+;jE5f`9V<0`*|in4Gz*#y7|}iA5=i8(;MP1@Yrs5jVd37~k*EPUcoi?)il#e%_d| z-ueHJb-!c%$NzAw1AjboX6TQRv0f23*0-v0&1_!Ez5ouM3)x&k@$h{@h)S;+OJb6Kaj1$o;7r%!SF$?7wtaV2nt^eM)abF@HrUh zMOOhY6mt8GEMud{iVpmLo%#CC$T=6HXN>18zuy3 z$RApm=;uyy)-!x>i~she-Hu%a%qe(dQ27srjuGD5Qux7Wb91t>tYB*0BY{tx{`dKo z{b9O!WVX>N{O-_<;^1=TVURPg3;rMG{yjdb>fZmy_snpaBq)#zNdU8GTBA=JR zIi1zE&2%U*v|k$R79J$4eS+s$e#e3RT%MdC9XZa~ro%J2=X0pFEjl{bopyPsa%EB4 z6KebY$yWDhaQs*SXZ2F&{sQ%t^QS_g%2AvL7%eE*T}hKRk}kXMG4dSaobxLBrMuB~ zjSp3_X0=EL{9XaNu`k&DFnwK{QQmqC-91X|oYqg1mzW}x_pbc#W8~F2@5iqWwn|Pc zB99Mz9pRoU-68oG)|9^j$1Gs5IR9RKQ$EEt?7t+~otWoR^0a4gZv}0ecAutQ-A9cK z6ooc}PW$^VcG{mZJiLtd-v@6^j7`>UR~9XXD>OpJ^YpO=cExr91q(SPW-(sF1xi~qgN<1J%Dm1D`@PXB(bwrKa8dV<#n zOxq(O7gF|3FLd??;#h9JviW}J`x-qdw}a;%M>bX8qZ>C3_j|I^HK#U%2l1AqwnO%v z;tMWiuN`f-Ir41DEL%6wyu6J%lgcE>viqi?_EZz>dT@@1V?ZfCFM>G>0J6z`+EiANoUM;%X)-TLBD9q_|;@@bA)8~YeSXK&{v%^Z_=VYX}d`K zk>Nj3S3k_T(BmMN!N(*E@EQ+*6t2J#%$$kxBDj zPfQwp7HvvS{Ob2kjn%N@PviQ3&pNmIoUWYWVAz!dKf44y8=h_YPJI^<^Qij~jP0D5 zzKPKAb07J-iIZxrx#=^lO#}R`%3Da@!RYcK`tR5mlW^XFOkuCx$?+6rTdWP`z}s6q zwtGKLPP=>uIgyR!hF8M>wZD^i%224X>k4Qdebw)Iq;dms9C4YYVuDTIJ1!*tkaJkD zA;iuxI#o;ctcy(l=JQ?m*S*sa+gQb!>T&*(QnrYgz(bVf{-@GY@;rO7so#s9|2BDq zi`y@^HUzO(2B<$VhKfGge!0!`cX#snHG*H~!Al=B-( z->l#~`jmL%wB=?`)cUxuBtw4g!HKr;BpPt{30RDU)`{(k>xK^IGxl1Kb^dYiYevTw z4kAm&1+iB%7Zg*?T}CLp#MSLF6~6CUE0Yqv=bsGrXAW5 z{`#aJVjAf~+(zxj~MBu%~x%|88Y2o|Kf?ZK7IMbZ~^*sG5U1WzN@08&>q*l z)n6;M>1GV)|1hpg`dO2O(@Ee>IG914mhj%fd~Aa@UA#TBprEXy+Mb`c3g_nC#`hKA z+s#+=a-}mjZTu>(JjmKm^P9@n1p317Inns#MXN>U5tjfgdd~ze%$t{Ej9Jr1GrKD+ zYkMQ}zR6o*?BPw!|CG5v{QV@uk9JYd80w+C8v}YOFIX)({?z^B(;3TB#xj+jWxL2> zJcV!3WHI;_9r_tx?IW1)&1q;J2JFnyyPUaqr$fu`d=b6W!ygm>Ys^#WCYyE=aMV&g z_YyN!I&bLjBk}Ra+stnG7Hy(ymx|8aF>~pu;O=DFI<-%B%%tpiN$tI1w^xVk_%iL; z{La32>x*l8Y;`X(-Zm{K^VHsGIL&`w2@D+li$LJV%}{#@dv!mhvo~vHi}sEKs*+GFW(iLzL}pJpZ0lM@@u}; zrxPzVFtfGoq07RX`FV*2dICC7+Z{eD+;XSgw%!*&QxCAuLE|iVYPY0?bst&bDhDqE zXLT>3PT@tdl~>WHQ*=o25uf~^r_$dh%BJ#WcO9aA@#gi;9A002zB7mMeb<;_LYY!CjbX>;ri;ilg)gPOt26Av4rog z%#aA*7~spY?`rPBS(kk;QQgc?f?%d0c{7rjp64nuo>8W(XoLcjU*-z#0${swd zoMOk@&*n}Y(}rv)*^zhewfUOre$}**owVMcN;`&k^wc}1%#2MD`_Xng^)3c(GuG7k zT)fU6nn~qL?Dd5&*!WK73FmY@V!?xJmhAY--OSr9m95Z^?BzY}|I%*1969_c+TTT* z*~3(Ag=^uFBff3p^E<$y^60k{C0}}&*Z=-`{7TTI)(t;0ozmCdx?~4;Vz$h#y);~s zW?kDryxAg88uy!xx?`Hj~85Z~zhLj}Sb!XTH!$1l*5^;*9Xln%nsqCg-#)~8b^ObH+v2-YZ1M8N^^V^W zT}f~iPcvh=;3ne#%vjoVC_h@_KBB*(i~Oe6$Yzt=c_`U<8RH&8cBucK>&zaA4(%Ud zzDqWfeMNghY}?8(^cU{x?!vx8e$o3}$~HRh7c*7?$`pb(M?N*<{SQzu}@)`z#r)F~a#6e&_NVz}~Ifz`5iS<>_4N@`GgB zP(01?FLTd!FL#Q4;OP3t(Dl2};dR&damP=@0HXY;Dy9%xohXK zM&`@YcG}K_HT5vx_pqkcl%Lo73_8F6MR%{|@QAw>N6FKT-N`@qJ|jO#rxnfUtept?F!cYOaq?Yw@!(+>NQ*hevw z-~T18{($?P`&3x>zr$GhZ@9nG*hH_g!kyR`;UO*MrIxuPMfQUCX4>@Fn~&6u1B&fd z%(jpCvVQmu`{O$#25z;7xRRcID$*Og3P-PWm@{lVH%{%g>+L26oBWXP{ zWnRPaENDsl=~Sf%o zCG9zV9$2kGf;B7hW3`3twPwI)-2G+lylSZ~%`ouQeVzC};1fSVG0PT>-Az5Q=d7|l z++k3RTvr8*++PLX&WU`QIK6g1dy1d4{j@uY*HQZNTW#JppFS<%zu>-i0WfoJ(xu7# zopBv#cu>(&Y?`TQU-Q~&U*%4N)U@-{Oxl8Fn)69(26v(LGikf-!ZuD?&8W)mH0G(! zr8>Zz)cscl;78b>pYB;B6(?ZmW7Ysu-g{5n=F@|#>~y=`dy{$MYRO*CzS}J; zLX|J%+iTUy6<0vxmqY8b;4{Qg?sn`9@SfiIj(8S+>Gd02y8l6jL-*N{EzGa&)a&-= zZu-+nf9~PAkp37uK5-MK57~p9dBL2n#ZE>!>1fF`PMy$rBWc-2Z_-}noQ4_DO^AKY ziF(s3%%^r@K}1VeTZ|<(%RK14irAr#pw|$xq~J<~!<_@wiaq(7v&Vc*sB#VMscxG- z@*3{@0`yMZng`M!?YWTGu%`w+Mc>UH>YRog;0gejU^w|9d$CCiK&vS-Lre9@v+VJw z-wSEWB2Owma(R&pqrq8=U2aPqe9X23_Kf>4owEdh|6pp`TzfBo_kQ+rrlyS(39l$r(#Lgzmc$~$?7$(|HDl%<8SH)Zt?j%191aIxR>?7k`wau)* z!nI_$(wlo^xF~bECW4ID-@3LS&06dwPNr8}K5N5Y)DWs1=HRk7-EDI=>-=cxZn6QL zs=H-FD@nNCHq_9k7oF9j-Xq9@+A}zxvG(4zzS65Ti@Q@P(^B~DOmn`PyEX+j5yQYe zu_mp}PIK4Je5G;!t4Vu3IW3d4L>k*qdlQ5!=*ZyNiRqlDI;3xx*fE|r^M4^fopDhG zkCVKvyPk&ugK)dkhYc9~p1+u};2z}qO7yx9H&otwVgvi!(hV`b8?+{EmQU8UJ*}_)T8_cXuE#=^IqBbRXY4Zq_56<@SA ze3~*3e;50Q)*!}6cz^gw><2S@-!CS<8=G#GCBg7wzTv$KwuCCLr~Z!V>VH<`{blea z_+NB7adze&<*djx=v+x<+eX^-{U6x>4Q%%Oy#CAZFxJd%jDdLkGw4sRc{9U5<#{YK zGyGqS$@b&t#Cdno)52*^WHNPF74?Ql+scGkrwCUt~p~^Q?)0U1h}#p{+DDl>_BA2%rlvXdZ;2rDrl$1^*!}-OsIrZ;MB9YUWE9QRqjURf zYIcZ+_RF8OyaT`1!;FEe)Bgr|G-q79qp?M>_J43S@p3DWeZimVf#2+n$2Y7VW#T@$ zw{)3edV$&M-;IG=Z+K&B{4*eSZB*?yJH)gI7J{2Whe*Gj|f2zpP z*1n(M0{~~MzHa-^R~1>y+%tQU@{h6oU;BOxUm?F}KzEv8yW5*+yW7b+iH8M5-tH7uDlFKiVV_K?T zEOX{&PGrH)vH#IVE^G2r(zoNfLynQFW|P*VJLEPT9D+?{X^9)X{P-xzX(-ctoj{!z?J!5q>U=>tqAxO8{?({J3ff9CawJc zpqB!>%}W-vK!Mnw2cuYF|*4I8?V^ zrrfJ`zZUEcRsNQ8hL^+Bcfiy0vNFTnyREQGLuSoAS`rrD_Oqt?iA!QGPuxeI{peL{ zQ}lN)^BJCPbgL$>HMtufRgk%-b#}|I?REA)Y0F&`20RLnaP+Xklf$i z02p&<`v~wR;izq#J@%Ac{YuQIo8lF(}a;WkG>aRkFQ{B%~H$24ff*)f) zYtrb%V!uj&awS4FSk)1{o~H))MV zPE3qzSAIYAqPuv@RVTPil=Cyt1!QxPoL`O1{{?S`k@bCFXDqSR*6gZmt${D6y<1x4#WtzLWio?@ac@=g@%(Mz3FAJ?KJv9{mq7 zU8&>f^6fu{Dgy~=;IyTB%mjN*{mI@xk%W)eKVjtPU4OQH%YDHln33b>_6ggLi%dQH z-V9YXfKv(|q7ZJ-i{#dskj!#<9GEm`BP6D0`T(uj2Xc6IOQ2*Z-vx zw`Z~jWU*J4J0BR2M1IhW%+%?#!s9q|Xm%}YbpPPi_JP*cVE-9BJzK564xE5}ox9?7 zu5Sr@@0@$&zv125QNUf(Gp%mB?9_1iS;4Kda%OBjx3*#0nA&yIM%S*LR#aO*4PM3l zYE#1PU$#zm`p#Il1i~|bbu@FXH~C2RyOS%fH|$GWKFv z+?^s?AeLrGsPa7UdY9K~joVAyyl+i0w6TS=`OYB^XEB+xlM?lK;50DLeGJ+5>V$L3 ziQ6@>v7goNAx@KVV7~3OzE`0A+3O3drkWU)FS4%Gs82(ODE?x7$-=4Orl+T9pYD49 zlBxE$NA#`C{`RY>;bzv)k{May^gphyEb*i_G(A1FIht*4cwiN_%-E&P)?3!??W;Xo z+gDp#+h>!%(}vxWr|jiAr=2-%`;5WE zOwAF_J_u6Yo5%W3JIa3%`T819JEpM5S9k33WZZ~n6jGn`W%(y|G-I=3t*r817#>>& zufhgn<{|ArCD|@I)y$td_T2nj?ZcC-|3ew%SG`NlzhB5F=VhF@ z-N!oEkM*!W>*4^`$DT7rK5+CF|L4D3IRajm%h{JXcWkOmf&;&hXl6@csPZx3n16dk z>w-n~ty)(~cf~f=+OX+uzHA{PJ!EL43gJQmt*m$eePhGDwmd|q5 z;gg*A@H3t_Ar~2$X!&FlS5row*jQ-OH=}Irh1TRf;+eG5gkR8=aen(Sc6#_)?B~dM z*d>bDcd7W2D6-N5V5|m4KYh`+;`-HwAOGd&R=6Lw+ILASC(f*Nf zc>8Ss9>#Q}x$1cuvG5FZ#3I7qB zb1`^A$7of#rV-Xe;X`rHg{*}&jGgYIklwFx-TOGa33#CmVBeF2y@>kjp<}lX+S4ewe-0kn&$j7m zkMv;54}~Uc9Qvw&KlyLGEPNHul22b|=!^BVM<*f9!@x7kAASH>E}(B7%G>>se$YeP zUShjV-unJw>4=GGyWBMYfbeqa5#0VE_E>!t7(+Vq7I?qKdq8*w&bR#^4`+Nl%AK}r z280(-zv{|eM~o@Bj*YN!E&Q=zn>4H2og+mvopPap;klGEG(mp!lGf;Gc-(@uhVOg^ z+7-+->DI(|@YB|NtjdE~LC$L%wkYbWA710&9(+zd3QZmLW#FTR&(j~}_gm!GI8yHe z9{;!l<$z=1={x@bo_5XZ z!BZan6>ik$UolV8J?Z1rp9AprTI3JWQVsoadGAr*pvYTov5o4>9`||#Tik(mxoiZjZJgx>uU{mYZyaN( zGHuuq#@g?;uHedadFf^iFTW{N*@Ta1kIF(LwXAu2D5Li_Xh-dNz}=R|;Dc$*Q)C|b z@&AG>(cVzr?e0@}@-EsNad~Ua{kODk^7~NON<(WKrTEB^&Gm-Ze*<^XOyInfSHQ=KkaHyGuJxw9z&VfyJ30GNwx^%KgYQIcGPu|_ z#K0n&E?R{C53Etz7rnIeY#eCwF_V|`l!AOyUN5l6?Qg}P(}P7^;qO}e0?p6 zw%!iLo_W%%pKp?6P;|8quI|y*BnKzYrBPi`A7@^8Sxbl=3pl!3AVpV0PiZMZSL;Mq zvt@nn)^@~AG(?sT@AfqeM#68E@5x*Z2B-A`RG8_y5Skb z1s#}>UxE&}e)i!B#8%c%JAfY7?i+~y5W1`rIopi$hN)qz&>N49?Wef_ybHXxju**@ z>jX)7*$iH!<9%>-kB;{qd`9-|qu2ZR-edFspcft!&9%A>o*cdJGTJr&9lfuN|5x&J z^*-!okpMKjQ?&iPOq(98ys+$Pm(cG3zXe&0;ZSSCBZ+#Sn|DmM8E>8YzKJ~AONJj% zcDAH`X}mS3UHksg>*1-ZZGG@(^snB?%;$tHPpI|CXlR|^{~%{=&B$J!- z0GP{jllpwf_L-KWDBRjY?I2=-BuZQ1+&6vgYVfOHFUVQt^e&(F*Z&4q%)kFT;%fgmJ z_f`ts`=NV3bT7NM2OYN~!A4=1{bbmSjiMhmiu>vsrmd-4H*Iy@+G%xl_0uT3-hb_- z#zqmnI>AOk`-<)8c#m~?R2}-g=-J;e16&>DTy*X0=xy9%6XetH&s^HKyKwW~V*4ofu~+%; zHGWiAy=ZO5Ibq#Ti_T~6yo>N{Hg<>%>=3g(84cnm*Lmt6XT58Y zontfn*tK(vhjwcuH(=*zmaOd9Ihv%OVdpU49vf-w9OfH#j;7yFZT?SS|J;hx+cn;} z2ApHpfCl#VW!G4Ft!>vZFoC1dz~I_7cClCL-)To{{D;)#*frKC@^u zGVO=wV-r+MhV)F+d?fbCX@GPW^e5tbE{BA#akT>GK1N!=u`ueQxci%D`8H2v+&WtYlt2ShxEfoDj z^RhQQL5#S7^7qR3d2)*-t=~Q_)*g3n}3q$lh`YwgE?OsdG$u*+2XUM zhh#^#mm>G1@oxIW9*n>@Dj!upod5FW2wufo-jVRVkoLvvzV`0f2D?>tZ;BP=WXOSd=p*dIY#=ieWl@c{G95)`YpSd zY*5b-hgU_u_RNcsgL`65=ct~{OTzO-%R5TrYv1Mi?zGoIeJ>q`C-W5iWyEbABfeSq z4av{oBI^FNLKKx2@FnCs47>72+u_M=yW=juIU!Xs1Cylz_k=x`2cAqNLV z6Np=9t*GX{koU2(%8uFSq?KRjq;U_)JEXaARk>xyIqj_}3cp4ADxZZ+jc!HkL_K5L z#Iu!gwf5V6^C~9IXH9nd;IV2e1HuJ;ZG(n_$hDGt_tD34#zJ&kifzL}C#|WRW$a7H zzH^*Bf-|N1v?LTXsPbUS%iF#4hAOR2s&`@Dl+{#RQ;)f@H4=z zc0BvmRIYwGwo!FTmkJ&n7`Hd*{sJ=(1_iwz6xe=Yj^9WD%OZa#BjA`>7JC4H}!2VAei#*!n%es=pW1unn z{I%T^Syz(%zlmqIzVnc^VGBIFkM*~Q*POck_V63_(7J1H3w4Qi`fI13ZtY#~uDz); zr@i*Vw~#q~$ee3fdsnme*0J`oZXDuvTqC1gMZYEAbY`s`&RIE`o#XS_9sv%9jtJMX zMt8C{q;Zj)*VlReSC|F`(LvVr8=D&$*3V}}AZf8Q}CNxrSiX8-TmJ@Rc*-n)vz zA;v;?4!unt$+wO^lhp4*=uz`3Hc)$=bZ5}1@rxF4X*@PC&aO;r*78TV&j+44yKr<| zrd>CM^Psug2m6>A1MRQ<9px2+(!n?J;$nDwBeHE0yo1IVnRMS!?Ek=9@5rRJj!ZiH zVa|MDPH0|@qrTqcuLQkfy(@!_CvPI2$MSz7KjArmElGH`h+D6xZ)uBzt(*llG<~t| z9$NQGdwXuag~l_7=tm8{n!dtXA~HM3@d$zf~Of7fZ*OOF6Zd z=zr;Lf0=(4yxirhZu^ZTru_w(#Eeo;)fK^3;X`ADJXu=9|5M6*%8s4bN12I~abZG!Q`-N~D4R;Quy$?p$-_a5EOxczcY47bMBy3mEGh+IQvfq`YhFIDsN~ z&>-@hP7dD*4JVG1&i*m5#dW4pT{YsTDRMY_%?|Y;hp%_!@V%}aeiitnj`fZlzBg44 zU&xwU()r0#L`s3yB$3K%Ghl9`2339l`aX0NqmdGdHnabgBLf@x5 zLn$qDO)@Vw=L&dVl3%T9x9=tGiBBV5OmR`R{lsHzFIInRtFeh(Tgd+zTh|hwqBC}$ z0p{1d<5??h|9PV?=S1WcPF6)HwQBF1X4T$5?dRlKaWg*g!B%%cP05apjM1^8%<#iJ z??iUCYQHhR zCP-U4hq4IWU_X1R7HABRw>AInpU+&(wMv_2es)Kcya6Y#carjsh+I!z!4qY#O<lVS9D!Sb&UW zd-E0*7t#Iq`n(XSIf-tMRV(wXVNT zdBs4w^g9Onb!l4gO3sdtvn`wNt-kQW@NQso%j8lkAiX}#mn5(-AREOlU z&A_j55R6&)3e^uU?W&yme<5Yvb~Ufu{9f{7=Qa72PxYNkUX4#au=f=Ye~i6&+S8~t z)IH-x^W@nocsJjeW9#K_Mh4njg1-3{4+&wp2BBa_*ghBQYQI5SS;~`7UGsANc~5kxbyo zKs|kHnQZ6#WT^6L@(HJIywlO^%ke?=#K)(?W7=U4e#p;8tt^TdjUGwt9!OUFJtdsu^c>&tK=+T9qEU>=&%h>N9j^bapc?Zo5Bl z?%JbW>3{#JwLBHJ8|=Ma-Zb*W@nXx=uDq72)5TT?uoc<++Ka{G8Nu4h11jt7nyh*7K^PgzvRdu4zHD31 z51Cg5){w)(wfMvm<%i~z@Hp+0X6&WED5fP!-Elf};cuU2@)RL2aDG$vA8AYD$l5sZ zHQwueCML7B*Rt#FJ5_hd{!iaUo6`A8z-^+vuaLP1?oYAr3htw{A(^z-`d8ZUm*;>R zX!ir)PwL+XpA73hUeVDm@_Yjrgg^P7ehWSV)T{KQGP9=JIKfW&3U#Wio|}Qg$Q%|l zYaxpa30)>$=Lhe|F)e|GSDa*@>q-9h znBvAV?0Ud^ydLD3lhI4DYv&bOY#~I(dxm*66Eo4-&o^FvmM31`JBoEq>7x?Tf6$X&MEVG&4@+o&kT+g_0qI$!(=Qvg z4LxaFNE<|&c!GiJP*2(}()z33;na)#hdpJRp@|h%_{)s3aKrk#O|QC6D`!5;rWk6**AtQ$j}VuJJ_&F zcBup29}3>{62|PBe$JR>M|P3^A4;!G81tr{blL2_t90(Fh|^4V|9E-HmyeR(8xPsZ zxFqg#cIU}Y=v#s1U0g4jjj?T%pO1TcqCWpP=I!2+T5otA7Xy!9STkjIT1G?AQ}7yj z4p~1KWa2fUnQVDEmgj`&SamPDv>HMne5V66!f*zXt_# zV?uuJG7?`guzexn{Rato+U@rMV`Wuc)RVt4A^(#J@O&i!hLH*HL+m`K+7>*K_JLM+ zn}@kF+UBVn!8I^#(;RApK10l-#JS^zxGv?UMUbgKW zwhu6Fcj%Q5_P&OT7v2jWWsQ!6;DyV17hiPN>_de${gJ7&BA;e07hf@RyWRd)!MFNe zc*afiS@qdG1HMVW#WR|E;TcC#c!vHb@{Ei#oQMBKOj{i08wMDd1A?y?K5=mhd^i0I z@a_NBnemCOiSX^U;p@5>_?)%E;I(3)f%`puch&&&z0Lmqj=no-Rm-d!g@bA~jP2Td8cD{R<=hnoanD$P^(k`(y9^Dn@6-WkGo z2!DowPxm`H<8-lbn+|SYpZ|4})@7&t8{d1Qtq#^O$(y~cV;jR*U=U)Qhm6VTI} zC~suzog>1<+!ZJL2{xPc?%j&Ou(vQ^-GPs?Oby432^G#>Yn6j*W`j*bOAm3=WrI58z z-}>`SXX==IzqIqQ>T*}1^NqDw`95SE0`51~aD6+B17ogD|`#M z-&ni#?RR`@!?$AcA;0L`^L#`9E@j-rUs?)XeecyFw!SwT`5&5=J}?eC5?vPa4DvjW zXBAKR(?dLqcsBA3@NDC$^KROC%BOB&{~XRUz*9PAkmoR-RXnqKhIooUH1Zt6vyG?Z zgLa-eTix>7c8>s0KmUU~Wm~G^DZfmJr)*G-JQHbIG@7d4%TIVAcAEH^w~n7M@r=u2 z*>Mu|e#thn(UpJGwy7b{=uA6wNZSr3TV35vjE&hJlM{IyTcG?*GqC^ElP3E`5`H=R zUbrfskNt-<+0%Y@3u8g~8ot}H=sA(q*#Gpcf^X_yG0*w|R;$JfovkIVvwbfs93)Nf zZ2259Da2a3>#VWS1hc~dCw(93zg9Z(bqdcg^W5bb^~}cvp3y@aZ`gGe5g)sadZOUL z;%*hsD$YrN(Auz;^W=@4g8lHKG1)2Fz?*BQ_ziiCoq}@Wk%~!K10Bjvp*UH6n?wF8 z+fL!O+fwb?DL!x0&M7pzW|YCH_hy@RT4=}b*eJI0?%F6$DOXWo%IzXfmU*HUcrsLpDEob##^#-Uo`jc)MduK7n=Lajn3I}_zOit zC$Nc%?gVQ+uwK#q4oh`wx z=#KZ^>h<=$UUgrDcK~ZgwQE<*irjGla}A%h?20*zaY3PVxN+Q!<>(r7HSW5fX>%e! z8@CS$n`hy$jr<=Ln{RDMtY!hv&?mkk#)=F%>&brH4 zlOuawD;XDDPN$y1op_FBDh+7d;dk73kuu*8<;Umq7Ho(w19Q@RZyO#@-$(jyl%#P7~Q>`bJdzCA7vaZ zhhO~t0Rwk8@oYBFpr3|kw1p~v0?u8Y@eA@9owBz!OM#1LTHB;ziZ}qneO}Q;AIscD7iC%h}7c;~&R`;A)>z+lfKJ27^ z;Z^5*HSk`+JG9igl>ar(`x4%Zop;4*ee4`cm?O>S_dQ46roB_<$c1*y)ULW-=g8jb zx%T-tBQHDs>1~d5j&8l}#O)sT!FcgSoO<43Y-Z6*I&-mCUg*p3I<}fU zv&3Y3R);F*)6NH%Kri?{9s3#kMRo`)=q*Hs;%BwK`|j^pt(awlVK3!(Q*TvVTk6%*jYQZL8hN zCD6but5o-q93+l~*tVDb#LoQe>rGE^=Vqp{uRc^1#*e-Cwcm^h``Hid|L<8Rf6D)3 zSDYJu!kgcqyDCHv#_mcSyw0zBqd&UM>RHY6v#^PJroUD-o1LxH{S>rbGr>Ap1s-Z< z&f4)|!v42%VvH1@`CH27aoDb>NQS7A?1Mtck#`#WTk2Zev>%lv=E#pU@k!H=^*wEug zue!?C+hhZkeVIPB2p`WG5EWHZkbJnI#k?XlwritTs;Vzrav30nN_{$2E$ z_7$^O2l67{pnUs^ey!Bu#1YV5xr4)L7lp4D4qv&ptX{Ff8izakwMJhVYGM#-DC^>P zJpLBJ!B|17JviP@?B6P1&cOh5EF9;1avB2Qtpk7X81QIuu3S6s|HFGR-@BiZoYzAO zb)OJUhes{|j=#}&x4nkH$IN(sNS$iW&zLUp4!FXHvUKvx3Z-FQ8pziLip=?2h zy*I32u(jBw&vx<^Oy@j7=)=WfKC}_Nb56-{bYRVoKLeX^AUdi|$Is}D_kwF3Jnfhi z?hky&p?{aoucJLvA2=6ZGw+Ot+b*;W9_>0ko$P;FWyjWf;PFAH{w-HI^+zuX|E(V| zD9`iu{x6MRk;X1z+=}Kn`PUEwO@8Hhkok!oF}cdE)6EmQB>cKtr{*mE?|f=~<-*G% zcck6h{6xvgFTS!4zEQk6eMAlC__#26@h_P9RazR}WB{|GI)s&*A|0lNJ2Mvltt|+#}56cJ>f!4oQzO zb7;fl@CjdfsL|s)7E0Qz7TcG7V4I*yTK`2S{81g+&0P_D6qOuQ1^w< z26<^`q}>jBjA`cv&Yn;k1;K9hOMPhjV{ERG9acV!qk;vH4%%&Tn(anEDxT#&a7Z}3AjJ-;scexdGQB#jJtQ-6SGgwe|Yx2vomI=rDt#!#hit|FKH-& z50((i%Du}kOyAz`@P251?Yv;?$CcH%Hr-^kuAN6*6ZQD1r<3!I(k`Mu#7b#Bh%(3h z@F({EcKd}FZTl++QG_;bWlT^^S2tP|p4 z)8Szuhlh=ThgBIKmKS-S@v?bXUSuo$yN2%{_QAv8kA{bdmc>WUp|4GP=d51!*@d}o zkpnaP0p6udBFvl1XYEjb+vsnU{%Xy2aXX1U#fkOoa&fnEYWTnVsON_X^_-{j)HjA_ zTt;=}9nQiQe2VG#4Rs+4wK%d+OZ7XWP1+XXD0h=)k*~>jqkQr$i8^mBcN8L<;ge53 zJNWpQ%h}I7gS+GZ?^k4FNol*Knz2*c<-`lHjwj(mYvHev1L9+dTtfK>`>oA7l*SlclA1^IgxJw zkJcs0Tgf;%*XW4l#N&RQJi6CbJT~gf8#k=K6_z}gdtK8LNw5`-HERWTG`-vQXtWsV92pEbT!r)f_E^eXQ>S>t?o=G!^$F9TBIK|P^7zT~GxA)t7FyhWs?9p7{)9fBU~Rn9 z(Jgk+&#FH9DEigdmNO3TYCUDlQtgm^#ka}!lj9GzUIA=v+_$Z|YR{h4y5tV@5#(g) z6j}>3KbkUg8Zw7;?)Mt(Bq^+{eR(N=h z^^)OJwtm<0TITs-#eA?XIrVO8M5Pcv9Y1QeV4$PGS#F=r_sG!Inw3JwWSJ0-dx}2kn@_T@yL~lYWUd z#4`dsd)pTwzi40jziS87+Atkh^r{c!d6IKZrkV#`1Lf)7#qQ z#(k*ot_~^L0R6k=HO2`&w&j?!u1M#YE}fFIDzTw;4@U+HvVIg;S&QJ^b2Xp-3Xa>* zA4P)~0bd2_$CK8VVUc|oYm9Rv@3KDYtiZnSda=(_Pp0<~T~Ybf{xa)i^eOJsz1})$ z;#nW@Xiv}H+0CAC=lBfyg1dD-N#|%^S;0{6j@a+5)^+q{_Pyta4=l2}4^YR9+paj- zal6i!TTQHJdP8jd+0C&PR=26=kDl=Nsc%s?_LNoD$paIHG{+jO?#}9d)HiTPtiaQ1 z(l7Id4?c_xyU{wC5n7EMIin$VT~>4KDXZJ0KM0IZt9(u~`+&PUpXyKfK|5l%JLP{t z`JYq%IqM|6EgZW(uQ~Pt^7-$rlcxMKU--a;;mxr>Q+EG=vW(07g;$|p#h&xD&Jld< zhd8*O@^7nsotsMgH=olSd*5x}7j8eM_6s<}&ePpF+FzD&Uw^xf!Ct!$+kN4K8J_Nr z!Jd;k*DzOgWO=%e<$AhfBRt*h1s)rgoPOa0qdnaR$MStVbycU8W&CP@UDrIPu8IA^ z2QQ(n$<)OiX&I{PQp!xH%uJr(eZk@@PVT$XsqW)ho5UugO~jb3p}CA-dO~Ew>x!(sq0S4+(TU}sB3>lS^DK^;d#PW z%-d?l^%vw>4Se75oQySiy4O)(9%JA2Ey_IXvB$oI7?zEmlLww~{$JHUd|(slPYHi# zm8IR69%f#(#;*3Y8rr+9f4KAe)cGUo{E4S~t^a=FY&pmFr=D(qVMf@y*0a^S*4pX? z-q?OmcRh3&UEynOe|zBV{!m?I`yV_u4G$d=TpW!@E% z$F&d31~`Q}B$Jq!UGC}7{8ihFXuHtxUhIX=Ud0Q@dmU@gotZF|lp@ivc&!lMqbcFu8m1-uGg(PDVT!_;AT)tbujnwt}BUL_s{ziCHHpC>Vb@{v zEcnA-!yn*TCNKP<)8SoFc-I`4H)I&zuy=uY1AJ?a!yC>|V$vAs+s%nhGOP*^vj;^id5bJ|1rGb&tAhD+Tl@>-!?E`wBL-m zlC%eQGcsFj_aNl28R(e1nxtROyq~<}v(6>fkpJerB;oyng!lQJPvz#BPuw%__>LAw zx!0_jI*Pw&rzd?|Xn%|Oe4JT106)b*{1kr9tW4vqoOJd%*5}%eFr!t!8|%`)53{$!-f`Unyj6%ASwR^l}UHU3R7R z-B$Q@`YG8@{quhjTLHXqB=y3-TFM*K!rlAfll(lyIY`!6K-uYw0#lTK_`+c8r94;A z)>3%e_o!<*@|}Ts^T@FOk9XU+o_|ibgm>`?_^a(F{iV&%o<7IgunC*1VC8aNTYnss z9#+i1sfV(vhdoFtYs-VzDE=%j@@i=6)FlCOsTCc^l^A3V)T zaK0rtb0c3(fWxAk3y1Es)qfX`FYsUE=8l=i8M7#PQfao($f0wfmD$kDRnSfaG;}5O zORT=nXJVxug11WsKAj)zL&pckIulvR{)p$i*5b3ULDYbsqu}cKZ_eyuZXX`b{e{vC z+Zm&!=rlV_ta_f#qi!jz9~6ECTv(h7;@6pp+wHq|`~!L4>@hJZ{tR>e=)^BGuBvwr z^)kN?8$NK=AkH1BfBfO;_?9>WtXQ$VteYL|JrvDu_gZsS{65g2nEXA^^Oe-GeSmfC ziqTeB-)j8U_EN@g1N&FD6ThU`L4TU!fjLVMzrb)$uzMN(S>De=&lwRJfiGA(=JIa@ zyZ(g!`$zPj8%X~)&vy1k%IC33{fWgUK8Adby>a_8o=R)tyKp7?`*+^auQF(BsC94f z;j{T4EU>z}s~s8-3=Y@w?atNnx;}&sgxgOYiOp?8R(IhIQSZ?&JNf&a6%I3IwR{Vr zm$>g*tCz5U!q$a*w~M*@MW<|i! z2Gy~jwBGeSJB}o0WU%|Q;OG(BiR)}P*l}i`r$6-r>~V_%gQ0cKyHow2BTfC(oYXry zm>K&cqaA$I*mZm=A)nrft2J~GukW4nOnv1_Q>?Ujo>Om-Z<5c{261D&%TCgB#)0-^ z72T&ZwiPSlVLm1ALCd0V*U`5u;xbgWnDLa3_b7eUzPvH~Z%Uwn2Wc-f%IbcfyU5Jk zfCen`q_(Lw;!N~YKkZl0em(7}zoyPc8!rQBYXki)g{~dkZ_^o)8}VC5nLifec!E4{ zdaXsT?FtQ#-XHA3$F=>aZ`d5=$wNlSGM9Y@{x&|I&T?TzKMvI^;;h{al z+7|Qa>}D@K%m**)2T$wISa3Ju3eIodt$Si@T1&*oT43XFk!^9j`0ZH4HsE@Mw29#5 z8Sut>xh)sG>@av4X7D1p7yHJdW8lRP9}r%S`EutdPd<1l124?7c&YI{{&;krio~=iYCz3QR)zXISPM~jo?<&1Mn8n_K(<8FqJlc23{W>73_ZWWNf==^Z+(m0NC<>cj4gY z?>x;Xkvq_vx~YF#A})!cj^onr@4=;iP%x)nIQ5Zcoi7#<4W zfIkuI(>L#M_Y#Bq?i~CoQ;`*JLWX(fy-ic@_H;cX-}@3`?vN?M`u3XD^-S9+E7N1u zSAKG}@uy5wo{EfN4gSl5t(GS1o#C)w$N(Ih+rit)9hg_-PAX;;H|CLpGaY&HWs6bkFBB-nNd=IGORbETcnd%>91O3sX9K znhiY^8J^30%ZcQ8@Ku{LF+!Y)QOmE6-|A^ioZY(+IL86kJlfgGnfU4W9OezR77z1m zdVDhDpjc4#DR4HhATw4Sjm`Zo@LB~n?%%9~|IxnMImXx^7na_`ICXhLWnCY|ep-={ zXT}4+PNqpmUMo08TcfPG%GaR2-$on&Hui$YJc~OnwC3IgOcpY$l|9Xzdr${YC}V6I zhY;ta@7!%|VgdMm3Eu+~h#MG&oJoDq>R!K@7d9TMKB4)H?~Z<`-bU@0+b}p@?`W03 zfbyArlt16bb1`)Y$E>m0H`7MV^*v(|9B=1oB9A*3iRpo1l4)%m9pOH+*w;PH?3e7W z0iHB)Kb`(}6hoWfetM3z_^5Z&<9YHe0&~E@^L+_;CVtD{c`5zP_l3&34W9GkcsA+a zdHOxni!WUHE&}ctb6a#S{`r$^`1QFqPx=5lO~qSasNJUur{7uEc$(p1*`j5hb5}tN z9n5h<$Ix`G-qUQF-dtqOo!#GhsRW)kXW_yrB@5VVf7;FJNdXH#FtOnC7faOX8tH z=x7`3&tHvmj_|9apQub+Mpnsn&h9na4*p6r(~<0<(~ z_h#=yZo6|J_JuTS;!@hqRXgDEM%s4UX{MbZyi70%7V$3S$xp$LrFrJybvpgGoN;(e zXA|A^bSKS+c zN%@YM`JWq~|3ZPn?U&T-fR_)zUei!yfoi*ECpFh_J?83GIX+z==zgw9_)!UG9O);@;iF(Z`WCDyKDWgf_F_{Y{RJUot*JfgA5>ka}@YxPty7%IktiNt4LFQx>wZr4OqjK zb_~39aR#DrDVgmN@`e~M!MVqq_X4un_e0EArF$rIko>BrlXLo5n_v1f^(E@8UGsiv z?4s=&bAE|3sL>OQe&&f((at_YONtBVx%*SNj>~KxW0R5$s=RXtSlbHu{j{;JQg|++ z-6-vJ(x3F4;1n`#J2))2;U4Zsg7+Vu5AMEQge?+Xp@a2^{=A$&(0XaAFL&J&@W^Qn z-lM*e+Wn?gBTPz>Ou_pux>uaop4x+}vew z(+(XKSUD-U$%*K@a3lMkf7xAKdlU$zin_L=YkMj)Z%%2uKX`R#bnZE2PiED*)qBxy8<)PD) zMrZvP{?`|Mru`GR{QvcQe=F4ceAo9xT*l`+`k$Gz|IB=M%lVR zy;ppq)BV%aQkLLeBh|g(#;8Wjw#V2v_2A@NNt6VhUBAf}>NIaie8<{IJkXy1CTgCgn0#BCA&_&sIPLUY~omOTLKXzrQ5@e}PYc%;A@esI2IE8w+dtKpHoPFmv$ zTZZ^YkvnP~+2Q1hokq5`Wi|WVEfemo4C~|R%B-PGU;N)K z=hnY0v3|zvOkny-Vj1S}nUtAFnf3%aHD#bv7aq~7`yM2pmFLI+(3qe1>6ZUsoz_75 zZY`VNl_+mnsd*>#?wyj%G`G^@F>*`eL59J>EUa|+QT}7r*tIg%rWj=HZdY`y&wm@ zU|4*PXXNHJEKSgv9z!oELobkh{{4a2vfwvU(VK4e<*j=X-9T}_(pRItta0o;9y%Sp z$<_@CEe8fX9e3=_V?mY2iEmGTwXPp~b zho{EpL%%*~-C0u`H8-66=&y6}`OwGtz3M-SbLx!CA?GKS6W^&yXcIj@-e#&ii_T@_ z(T{D*mAjDH65IONa;|)lQZAGLU#~cE*HPBs#BogIA&Kw3*=6Pu4~Y#ft|wxro2$D@ zL-GZP&+=busMbdlk8<`*#W-%ugZ3vw@AZ{4yBDI@29_=DlKoM7tHt|Y;G^6#Gfpuk z*zJaD?`RWi*_+tj-%Q76Lb)pDjLMjI>WIIq4);58EAe;qX}zx+W*J{fRbB10s=Cm$ zA0lw#Z*BnC{`c&rReng6=D6>%p@|Wf`!@`s_h!u);!{OQZ&^$dY9Snm`ZyFriAjMZm?^n+HZ4zg$bAf7Kd& zDo(QS>xq8{#m8AEC(B8-bthnO?>)bdKGYi^C{+mQhY?QGEj6RGTi}E+uG36EeI%3)KuAdtj zdPHO?bT8RZ{47c=q~yY9krQQ4KL8Ch_L6pJ96Db^u0@=8(T&kF>VF6^;N7#J+`^*bvu^Vbg{qn$L-KXafW1|rCpmG8BzCc z=JH?ui)(-{E+euR-S(*sGv6g67V}N(u;!)a627mE;Ap#i@cIv~*B?0;Z2pjZ*DB44 zmu{!8Wz;R-t34JrZ)kJ;h6OcK;0+_-4SA6*D{SAB+x998AJJLXME1~yh2wd^J(@Vq zcJO;U?Jl`#M)UQw8)b~!9G(+6%jG$f9G){Q@&NVTi9DcumdkhWABq+#oOvgna}#ym znaSPG)R{ORLh05vcV4SZqVM_Blri}ee87{SfoafJy%(P`{;uMugUvbkfDQifzZEl% z>XT?&eOkbriW=Esd6yU5H8S4frzN9pU-fQua@SWqvi6C`HP2i>wdMG^3ZaFaAI7$+ zje4H8pL$s2)AU_we~_OFycIydF1%^LzRF(vxxdqn6?1&R&VQTlW|2?xRB}=LNnP4c z>eeM15|5UjW;yl{wWYe0|8D(<|KG(^v~qIARq(J1c-fWkv@76kmlGE^3!XdkHh7+M z-sI`yr?sw7SLQaxM(g{0o{GaS;;A;Dq~FQ9Sk`HEG4!wQ$BTm9Q*GRvd3H0p7-vAN zdzi7&{%Cui<%}aBu3wTx@YGUlBx&FErlp}ooc z7mn@*uJ}A-TwGe$cg?c^IO9yAhvc`@^N5e}JZ~m(p=k$qQ8#_Alut}Cmi>y0wS#ekWf0Q@pD-BqbS1}06C;xB#@E+P!pR~SC7-0Lxh0~AIk>z`v z1-$LVHwb6L!I}7yi?2t4B~^D7zMcnuzsJVc9v5HT+%C^%rh#lg+YgMGdr zF_^g#eHXrT=8o{BJ>Rsq4nro`b*qr)9Qk*w}_FEU)&4+eEbv#=U*9o znEAZ8{ipShHxbXtcqX5TfZU+H!S21oPc9>Nb*AEFeb8(_XtzH!JOElIR(1tzGI5>z z*?$#a{rte!&+H4?2W>{7RjnDq?R2ft$XL@^qpO(r^213-()U`{Qt5{C(3L~py2tC) z2V!>p#2RUCY3-ZNx)VSSo6Z`H-)F93i*^=RbBCkrO(owg%>S<4zKe@^PotkT8ThZ6 z7kh?TOWDt0&S^S;d~#sC)mlb+@i41&BzY@{+pZX5E&ZGy{>1kv={NE$;nz&NTNvX# zTfbRZ|KQd;42{y>jeHviUoPiq+TuKg)V5C0me!~W{Ose%m)MT{!Z$l@jGztqB7>}> z9(3!SgV@u;H$S@Qo_wox3u|QkXTDk4^ur(AQ9*p)ydhRuh_cU-Ctc%uBDP&R8nIl5 zC4Y6&*Xj8A)&5$a|5o*BMF0BX<3?E9Zlu4R8CI*->+ds{EAYEV$9tNOfj7U^lG%Ls zsOw6GT0=VrTdmJ=?|gLhlf$Dw>W8b_%GMey-aU`G-I&Lk>a0t3S-ivZ@>uhyWUl?%8Af00Yc7i?UKTuhJ+Yim0 zY2wVN3ct0ik+~q>#E}u$`m)%64;^Wb(HzED`xj2v|FVpnjJxT36MSV4=lR2fhW-zA zsm?ceLND5jXzE*}`j}ISjZmFTp!gi1Yo`fVG zf6gg9UN%M1mLJ-BZddU^Vi)JyzKtxlyxHqOKWL_beAdc>EN5P1>U_u4wO}XXljwhT zW0P_@=PT9TAlo@SQulTle|(3L)7$xjCS(2lO-OrTlt!IVgQ%7F2Wv-r>em5?@H{2OL>|=0N0WP#&i9d+ri>agCjrg8!=w{_Q>|;(t8(s;sWb>c6A+ zC&{0JTmhx(rPpB|No@bQgDzc#|bA-f)AHoAKCTK(W>fMmxBLP zT6OUsBH#Zetquf-ZOkFpR{_tSn>t4FU0ibL-dFq!@9eVqhToi@8sN;isBdCq9Wlnm z9`0KwHaY0YYVZWC@XOT8ys4D@kL>Z1Y_5s6Gp!G#8$V5IdyY*h^Ah-%mtO_`!#(Kw zHPj{l%L3+cjnP-<1CM={>&b4T+f~+}^VXyDDm{DI#IDpfiBUYoKASjC+NtjXc%b&I ziN`!Z9~*&zxKVTrbQ~{x@_<9@?k?b{ryW1*u1%Bv$e$fJT-{sgIm<5T(t7Xq_hmZ| z>u2)W-lyWh-uot)I@ssE5Lm?1xlho*5(OtNEOouWvZD`Jv=;uj4;VT}KYLqhtgF8l zo8|-1iMtLKYp+*=O;Y%houY>E_d7Pt4_I?f2kV2Uf%X14tUddJI!FJ~*hf=wmN=HF zaJ4&d?Q!6GF2Pp%aqxZdH1Pdf9KJIf&s4ZV4qU|!TptHZ`DtLev=3MUS|_jWIqSo= ziJEz}P5biv&_s=yQ+IWZqYlM^*Ffi+pz|%r9(wxlGifbUJhkSwY&VHEW|zJlewbO0 zoHn0d3G?PEo|^N$`RvlqoxwiSw1fMhDakHJu&WodH$wX&v_E1Pdm~(&wY_KWj|ia4 zsSlfhxzN}&b0W>a`#kLw!H14fhvb2+od4HB9#cNSMkYD)C+wAYhP@J!fz+QgboCPG zHmy0>T)1pp7jddO6EmEarhfL&o*NUb{vHPxI~l)JI!ui1$%hx(`~+DG+@gnVyOW>c zC&2!@F2lP{;Rh~07dm@Jo|3&M0WUcYUecI*P2ffLCix@+$VE1v9u_G*8QV6W{v!i! z(|9)Vv~6?QkuQN8rKREq`)>CV@FH8ClJOt-A_S`>t_O zOj8GZYg$TwqqP4}AN~DT`iX6?&wif&ztGSBqMv8X8}WSz2c_^u+vaTV8*9T>n#vc^ zk+-@1Ufs+1uEl2D=h!l*`x@JKIXmoM9b2svW8-7hL;rp8UYF)4rR*!T@Ik2GF5lgh zz;{2c|Ih!E{r}PbQvcsR*8AM-jpkFwyU`hMm#=?ZU;o*$zUzOfuRrLcuhK0}x6f9z zE?$*|&!q#u$}WBt@cjC-t?m1;Yl|+#5B>n0;!)ch>nejzY*!TCn;4_?{b4x`OA`E0 z+PiQAcx=zGj7@yFiBHN|w-UZ3`=R8js4stKF#21;ZQ10mTOHUd zu*ENols8X?pD%=$-%6f|dgrP2ZXx!0@p;4h@k6?HiA4KD@8=1e-e=MQEu;mIDX^ao z=ZO&v-Q7OFNd0{ad%hp}0vKMp)Z<%s3uB#y?lCDo&cntL_hNh>CE}HgbDn1;zK^BG z_kr9wx0C+J_pu3^n#Q>kT$CB#M}B0o8Rx`3D*51yz3a|6Yo2yu>o4Z~DfO9{poe4^ z{WyPw{N$(ekNfFs;<}yBx*cGjr{Btdq4RC;e>Ok%*n9qapMN6z|Ksi5{1iU0*RU|;7*bKo7idGq8y-Ogr4PtB2dO=hMqBan0a}&-de#+t-X*0+Xm5A1SCOdzVFXI=OmL!K%ejL_51!YuQ_M$efDMTwbov1 z?X}llKI6@9;ymofw$EAhk7sJXnzdZ>EBx2{YSwvgugl;R`?5;+(u^L$-fw)Gkqe0X z6rZO3XU-XrIm7Un^v8*{_-yJW~0ll^Z@3MaI0d1yDXOmYphL7cxmJcoT{ z&xU==o>@>}?Om($a?m?_z&ih%h7JCqb9(<+Dfp6xgpS{{pB zR>oihy9(2MZh)$Y#ZQ-1NC#~y@95k{z08Ra}Cex znMdundvnS@ea|!d4L#4;+wZ4+)tyY6b7-^SV0XoZw0q;h?u|*ejT!lY_6vYjo94?G zT(B0uolW{?fIP*i)jo0mwbdU(=Qnmf$@KDjJqJGL$kgevCqM08E&m>^L*lFQ^SKN= z8gh2A$9E4L&>nDqJ7r>9j{c!~9G!b5bvyMcE|pXFw1m3gm_#%Wm2?^Ts|<+pTWf+e9<8%^r>M zGpZiR{dDxfgUtc#Q}J+L-P4C->&C}wJLe;EC*g2Uooy7o` zi`Dk_{R8V2g3my(@aV(iOJ8@}NaRiD^|X;5+jNvRz9?T>i9Dq-XpD(Gp~23Qe{4Q2UfcH9cn-RPEC~b}9J0JLkKCvsGh#^Oez8>4N$}4@8{FRU?_v2#_WbL^dd2Cf6cg4oR z{pIZ?$WqIZb%MSOBX9o#d3%n0`q;B>#6}jx=Roq7?2k8;LK{s`EJiW}3AGpJ`Muq3T3=+@iIPaOX9Px7|qk}vs#KFkAW zU#9GMWd8As&g^`ddU~ES%N+65_|qTYBZ8ApS^7TgSiBD(x!|RddIQ?iW)V z@REqymTWwpw%;01w(|BE9RB*}g${oe?XB~tyK7x~%>Gw@{;G8j8>-oN)jIh)-|9Pu zzdErOh4bHzStA>fr=9Z|-*L`opx@=Ai+eiy z;(gt#^{g~w!$zl-?Ro~dxdgqodaTj!u)P{x!UA*%{@@%`CxU>ZQ}oQC;%2(z-@nUHFe>P;XZm<*~6>l#u4?tUEpcUKcHapP3HlT4GYaRwQakFvgx84ur`3BEM^i}5qZ=)yKWZe5z|xgU2|+-Z1{qr6pTw|y8ljV=A*+HI zeNLClxAe@OMUQ1ZQ-79yTQ z=&ja!8=w1+9gSHVKI!=DyPpK#`Nt77&f7riWjPp;)$ zMUZdg%QzWd!RO(hQ~2M;zsV=g;PaWzSp(g%EWhQq;VF&e&jHW0{(3YmIp84eN*1^h zTrxCGS^2p2p=rt_(sVL?V9Yyw{J4*HwKdWzcKjaG_bg?NgKzfG{6X++8tX?q&2NI{ zb)L_mh3xSEAbUsgXuD*W? zeeByAZu$W-*zcTmZ^sY1pj&vGV3N+alIdCupA$@m8Tyyr<;ir3aQQPl?$6XGe`E1H zl{IPNDK0+{-z$Ody$KBDH}1f|@f#Nm)UPIEKP7e;@sIA{jE4B0MH+fzAAZn5S;<}= zPuNc%{|0V-NW0>J(~&)7>vqoTXT;uj^CZiuoo&EGJVG$hTnbM6;8Wrkhmn~p_jXUt zC6Boqxfwb$xD8Frh4zX#r>^hBA6RS5nOv=V!r7(Zk-=wZy8xUk2A}a4F?fuB#73=k zTA$DrwLYib znrCAWY{>6&Ws)8G@5vXhJ668<#uv$lr^MHPw73Q;)8h5boi{5X4hAy&dh7ClYys@9+;=;&Udx%p)}(Hg_0ERwJQG=gx!3wR16*@;MECrdW6uzMS7$vk*te`z!Y9r3Thx;%-&ND5b+%>t_j$1jGA#KS5xaLeYYpp&_OT=v72*dC z|0F(jxb$UWxXFes*-~laIWswj7;mlM6f#=z9KQ7-YZ`l>`(3t=xE`FZn!=d3>AVp3 z8O4FL;JN!0_c7Vpo{fKZEivNs-Uwej3*UJ?AEpl@>4SLB=j~Z6=8iA<9tZQoB}svd zSMiBnI5zEyLx<5D{HdI+qn|$U2vUcWsmsG9RX$kLtI&{oiB5zDspQXab=_6 za@pI&2IWqQXbSf&OtS16>_OqE?9%7S^&hb5BHRA@q0y{mfr#Eu29N*lN<$ zhWvLGw{)1+bYLSntn62;!`#=}fqtQK@;6YNJn2Sd%ZZoAdDtN1SDx-DDLi_&$aju>-j~V8{ING%Ten-H}gEFJAWa2K@~HX47n^gIPVOV z4|1R4%xr5?HNNK>#~F-c=2_v{`GZ3fYbhHXO@7(1Nj+sx8#1YSNZfa)I^Uh3@0KKA zmj6dXVEHz$>bXP5a>Csr{BNkw@n z<9(@Vy1Oc6)r+?j`BG9Q+%xjB1;a<5v4H-j(BBE?4x6-qJ|yvc!Iy?inxE`ECvhHk z{+F$i4#p7-1nY8!TlQkcjg7hVR)6lR!oN!KHgHh%G>>P|RvWnXhi~d!Oh)W^?9rkr z;R&+z`XX$7`@nhG8$+@!LZ{bJXNuKQx(EOEVS`#qpW#0_*iw2U|4GAIN{jffCWdnU ziPpm9z_9v$-|T$&SfhC8b-vlI-eK%w)q{Pr7yN~?@S5t0Yp$;2yCr;g0pHc}-4ed5 z=DRw+6Ft^ZekJ9XP`-}x7g2tVTmB--uW`#?-}9gl33kd*}3#4j)c>?mTlx zF8bs83-2Ff?q_eOT*`SXBeU@BuY3A?k(41%-7-sOWNxxbUKMVElLdpYp}-qbGQuTG z!1F@r{-S?(r(QgNLCMOb;dN18{yXbf8&ifn5cwzgQqJ>)^B#!ke!F(`!U<135b5A~ znVwJjZiILY*<>(9VXsSt}!7((^&eKeaNV zvnhT(pZ7rIIiA-c!==#fPkAoa^GOdxp60pz0CiHnk>_PRr#$sQG^&=zxrTAYk?mw9K@wR|7x4?GZgnDq8fcs_4sq@L$x zdOm4o>-c{J+?8LU7x!Lq>yIoBa32Kv5O`F0-xeWcalxuZn@{J(pLDUe9+qQF&Ga2>_F~hoh#k_e7N)j&YkSx zY)g=Pt*d>(6rI(wd~2?jpC9d+^DD=?XS6$zwOuxO*{C}F?A4u!oQ&?(7|82vpTOOL z3#?W64@5@87e^7#{dQvFzw_6T_S?|S#zTYc_xQj1`Ji1Z8R8LaKCEZlk6n!K$c|b+ zad(jw&{=Hd4ayDQH5WOdcRwaQc0KWHs~-xN2CuTFuA;o^X}r=Z)_J8T{7*bqtNR*W zCnh%au1W^B6Yv4y?g`E=nSSaF)F1ph1C<@ydy}_!p}n5;*!gbVg`W+bvfgiHd^XE! zR$K_}@eJlSg5PocM)4cUFO8r0S}s4%2$=JYvb|lzTKX~agmk&Wz|irMF@i&)k)Nd2 z<`oVdHYyk1+R52#_5Cx-B^_^#)Si5iZOtyb%D1p_Hhrfa-|<#@GQ8sHyXN0{VNyz6 z7+!HYcYEJ3#+p*NRNvzJn%GbEaTk63 znEtAt&r|RF#|4U7&mUCuud@aheT08Ud;ZX(zs<0k!6D91f{Qh|os!#I10$Yo4GiZu zj9&`B(dL}Xo|?h-jejiM)Xf>ggIj9ziq5k*>*wGjGJVB1c&df3(OTAkuYx1tVb~6- zo3$Pug1;<3<%`}wVxNC^V0df<@2~HjQ}Q$Bu$wuoouM;NBVxZp2EMerJ9YNro9|3b zPOG#0`R{xM{8%}8#Hf|v!6%I8!KK#h7w@qq?wXDt4`;Y`)4!stZra4!xo{?Fg26vY zd-c+w+i0qs9w5cNNFD1%I5sNj9VhC7WQ^3Zaw8PNg%>@%4m!;Ul82(4xY_T9-8!=w#;HFgkuk5jyLW zj4%Eh+HOw92YV0S&7VJhljcOc;2*2cFKRz4-24&t=zpDcF1UM6(fh~ED0;tb=v46y z(bPxCjiNEp&mr!b7e0$F#s|Kix0~~5AHvH;YkSjHQ(*%?k8B{8@|WK9H?&^b2oQJZe#8`o@Z|# znBBuSd&{imgRC_w^YlyiM=s|3Zw$AJukt0$db%d}&S#&@Eopo{x8%jGxh3q$9oZd_ zkI-Oy-IKoU=H5`&qUtXQpL*y{@M#zg?f>zcowBzezfR`P)5-CC%wmoumxqbbvz@yb z67m#hs%sbXm=>^BeKsrHd=qo2{^+st zK_U6o4_T$ve4{n#Jr^ED%!|%BR$D=>Pq%Dy@#SFJ^1Mq^#Djd?Vff9?YbdX_Pao#M zCrBEyO%Kiq$2!2V)Zx~YrhD#z#(efw^XG38+@Gmoeja9in5S0G9LLYiUizzfm(S_m zvT$=~sLosGrWE>vvx2N)O9HH!gKMwum}51!-|DjktJWFeX5D3U9f&Je-JuR zy=ysRdmQr(Og0F9nm?sGKCS7oOa0D#bj)F&wWWJXj+?)hyJ>xVr*B$Pv9FxWUJc)6 zTftfJ-y^52vRK2V14>rlLcLWT^vCDRp4Ezfn$o6H#?=3-?kR17;4F(dRQdyy<(y%* zHy3K_@4WAZ_Qbb{3D70JB{)NGdt3a=A47)g`cLlm^TD^?0ai2UZ#=F^=E67Zjq+%^ z-2u+2uRg}|IAvA8mE1YCO)w+<<%G6M!C|$9+&J5VwGUV$V=jCeobmciY@t;?=1BE< zIJz5IS~&V7@|AEifQ})&O!D{QWdrllhV10w=6}ye&Z3Ub!%z6NJs-WA`^ZW+KQ9>i zX8lZS1N>^@-?}HC4GivMe6kC5_;Y*kB%8i#ZCF6N>bp1Rh4jCbJtJ?*sKOeFo>(%Q?TUdtiTKV#02w9`4&l z?-)c}4IjAWk2Rs2>}J11I!F;Z$Om&A9pplEkPn{rHC;gL+ah$3-QE5s?l5ld-iHoS zW!dZa4myZ^c-Zk}fX|ff-iHn{4jqK`u)hv+4rk~c9VA}&X|3U&AL%!j`HipYyQ=Sh zsnf*QXLPOr_t!0&^Y}B4|-z_&Y+$?;|Qen8;7T>TIkswyEGo3J09kJ z661N3@c=`?@n((bO>a!od&k5+h&QJ78q=iyV`5S2!R4MYQSNic6iDkcrV)u_8eneB zTupRzSop;T#f=f)-2Egt&t2$6%$M$ijGwQPFEC$=G`0ceYu7gh7~B8FeEorXzUX`< zj?s*d`QuJ&cYOWluluvlpTF=?<}WtT82>Nk??=?5`=S%?i0(^Y$9J~YfQOdPwS)BX zpgF8(GhbShmjpkS%{}x(>clm92PQ4gQ@J8!SKVR9e!P)iyT|!Tt67JG$iiBap>ghfjYhD$WW3D%Xax(W zA6XkX{)HE39B*V)vsS}b*KM`7YrXy%Fw}fB5Thgu*=`L!Cl5lOw`Ex+``Fi%?5wq@ z1HOta({8V_?BiwAfj8`dmx|UufR~E5vUX3!t~x7>T}R)^o-O)O42MJ>FcC_|31(k?hu<;n>&i2D{V zzp|NV4AYnFJ-hvcUNP-3!a^BKfvCF@>JH# z*V^Mf_mu4#X+MRo6lE{?8~8V}hYg)s8RPNA*7NQFy2d!mE;?e_$-|(n`8Sq~KagL- z9$i{~7#uo$&YR`f0J)bVVPhj{N9UJquBY8#Lc62Y?u<8Q((Z4Uo=bqg7n4m`H+hoU*Yli zcp%Gg?`3D4&X5sXM0uBP>x;0l7QtKOQ?!}6jrYFubUNnaCuy;PDjlB$J5F%(<*M8u&GB z!`ImR%84yU2PH;S%5v$TK8F@oLkr8PqY(MN7J9({rWBfN_Mv~w^;^yAkKiR=va=X> zkTwdLAN+SBFG4$?5__t^%3AO&Wh|ppWyHASZPo333;!uz&KPPLLzAnUi05bw0sN4b zyE=1J^y~5*jlrYe@6-2MS8uLWpNZEVrXBTJ;}*|ZPM^hd=F?}!uy7Cg)wDej&Cc)c zoUmrOQucW6Sqt!cQN8pE~C(|3h{5<)^bWN4>l>Gd4etmkxv0 zz9=s}rC)#h^HQ~SbY7ZyR9-rlxI_h(-EnGd1Z#phJ#b)oILvy@3}MEzQ}w2PL6$n z_xx_IeV+IHT8=Fnf~o(~EE_y8U&ZhA$A&6yjgOf=8jt82=Kb8Yc;r`>e>y{|dvjNuWSC2- z_r2%QqwF^C`O-{VG2Be~`?759*_vl7)7Jirc@E~<+Osv!f6lOFw>QrpkFvG@VxFJL zvgHF}o-fU@wfAD4!`Zg>Y|ZmadA4i|=K0ZFTl~j7-#NE1k5*Df8V>>T7?a5efh9cNJ}+q^4nh8IZ6wev^Pj=rLCuB z`@zoHIy7us^~%eLEu*~%c-C?9mCZ9Vt>S#vht@OjBVvzXEk2_M`R)LHlrN?Fxq`m2 z-rGStWM`yV_P)!kraS3FPReMzivOyNEvk- z_6%%YA>w$-{&p+lXd(W$kp+Oe?CtH?MqzZT8iRQqoJpE&psF`1i?+7T68sEyG7@M`B*XI6JEE(xQ=96Z1BmZ1UR2MI%+@$?r*H zv4)15jL#u+AUx6hXzW)J@3srPFMT*^?lrZZ|lb5li7ala_P3-A>tZgD?0*y7hTDQU`44 zQ?cl;5B#r$hXLdEE4i1QF(5x=fS-NKRGjLR`3if5ltGW{JBQv}oP^v=e!n*EKEbZk zJdTM*u8RA11~^g`$~1Lvxdfe%Z)cK!ka;@zP{{V^M=)K6epSP78ZdyrL7$n1CWQA> zJ-8eu*5(!19TAQE_Rr>wYeY8qm;K0var#>UGCgaW zEt%t3c6ipydh1dL&o-m;yu;d4NsQqT@DQH^p7kz$*H?Wz_g4)5ye^sk{Rya{cdz-nk7=L2A{Hs3CZ+Rbjuy?jp zJXL;ydzr_4>7MAq+E)qk%f2)GP)=0-JyynhuauT3zRsN0&b`(6CG8E%|F`?Ng%|Pv zi>z=-2m8izzVFyk=KKl!3Hpx4@g8-b6|hp4P*yrn%a+o*U?6vvpZz@XY}u+*ZyRv(#6ebB1YeT>u#NwAc4uLCdXo8*{sv zdRf2v+)FlKeb`U-|H+{xuU+j;>HN+9OYn)+eo|9(wR#cW1E!JNU+K%EjkzC4O<$4HKMtkkLfj_*U(Z@3zL% zLcUd->c|+R%XizG$AR*Z+gAgFVh@)0R>CK+L+`)D2Q2+fM`|2DXW9OKH`mCDG3aAr zD>j2AL-@xI!fIoRD@{EYi7**6N#H+t{0@hjuKhj%nib@1k;5@+np z^IgDI`jYJZ`!7kRKPmV&peJKR5mwEl7pAC%dUhkcLGKUr7G4i2iA9hi2c*e;5w6Kf&j=kKomG^5mZanhK zI(+l5z|&sXcF#!d@txepx)5*2Z5^jI)sZu`rp}{J;tBZXuWm5BG2Pgl$5yZo#Pe-$ z%-h^CgC}Y9{Q|y+#+sdaGh$yt_80t^{|e!_^yGg1zw%6HKETB+7tdvbOkBfcgJdkM zUyk4O;hVRbz2h@zbKrHy@fY0%pORl{rs$u(SkN0d!P=S`yMu3`87vqa-zoP@P7-x>C=%b+;)24SMR{@Q~G!`_?`F#;J0oRdjl@~ zTB+;v;CI~@fM10Rzn^{q_-&<3JdGU-e#u&QQ-FQU!`02y9byd?kC1+) zy@o{GP6roeQBM3=JeczRam~{u@}rUC8JmL>{b}TA^Qv{#i2>u#G`x97Ie4{!cEj-E z1RlS>>fK=mU&>F!?rLC}9$Q4&W8-3a>?z8$V0Ulvb^cs@Q0@3>=P}Yl$7pBl$7PyB`YqR0>OFLUTM2iT^^zC-#p%IN+Z&KM-FUA^N%r+)R1jvPCK zZwi*17dn7Y#Qskla^Zh#i6QMs9NTHl@!aeG~oCSYgrzk6Pff>O=R9 zg(W`+79qwj|L1;VYjNr?A0Lf0n!aSm&ZiE=NE?VBd;3A+y&irQQQpBX$wb1h{x(vb zkxFR0zRJU=vB>|leN=qvCucbLBl}1uv|Y)Zy7L_Q*&Jv57I2r0#@t6@ZW`yZ66d16 zs`6|D-?67fBeFHe^DG1BC(bfD&Acz+cS#=w$Kxp%rB2aGA#LB|K8tP|pqoYBJ2Jt5 zbQHJN&!WzLZPre6@cz_jWJV8Mob}R^ohswnzs_sVZT~9o-EF@g+~eAxK>dQ9@Mt0P zh(}ZL1>W};a8B63(a8rs;<4!4>9LO~D}J?<*mY-ng0_*BN~y++Fc_bj}&C3VaR>MxkoC%{ff@{ zFAqPL(jRbS!@4J}?N5SB8tWf8JKP$FHwBc@ct}g^Z++EGWu`yNrWhZ&jDGNp!{a}^ z>*4Xm^ywmGgIS!(2^iU7-}SvX^RfHv;mn8LdmPS8XJ4oQn9Sh6DsIkxO&e>kxTi_$ zu5^&U9_e1~=%wu2F^;Um-NlZai`~_sO~YHg`V3xISY}LHN*sJ{OF5@V^LmJWv>-ET z&ia%u^f~2AqmducejDz$2O;qWoL3GiaPZD^)4RG1y7## zU;rMqa%bRwdhfublJ|anio+xA4Tv`NpQxAcUF;mUodW2SjkBJ0t^q#zp!ZHYl228S zC!c!scC5CqcIRBWT4LMs70RM*^#NYce;#h|8@Mhzn=^ydvxGfLM_2Ak@A3Xxo_r}i zO>(99;493#;5q#Y=igcDwaz0!-ULBl-&ctsiaPj#YZm9-dZAwE<&9kttb5>b8{((R=?``Z%Z6lSJVfyuB z`Xzardivs1YJf86EbI{^8(iQn_P{wdZKE6X$`oGQ_+#$-eE4Xj&lo1L?^AO;V{rHY z`qCS{`cfW#pxEkfd^9qJaRBe;O4-Yv3D|9<`;~r}{S3i&h*f+SW9cIOGjy!4>O30j z@)i6a{7s43FRb=Qo3RV0&8MF5gkW78maXj5A{Akf--=xc^$e4qfN)rnT60+IcqX4sjHAy3dA(koPC=T|9*M&wzQ9 z?`5}Ghn~C(oA}TE(7pOS@U*eU*cac3w=d3xHpEl9Ct+i(IsTY7#^2D^vF1d+tbO3l zo?96@rTVUYF8N=1^Mn0tM;^Atv-sW4T)cDrAX`58jo4YZRM^0_Qn0OYV0#>}&9_n) zuE6$&jSat$Xmc4cI$mL|x?)0Z9X`JX-oK`g`bPHHMqrOju;DiRFb*?DotI%xX5k*- zy5O@CF+D`R+U z3;TuSZMoR-FWaZS@N1_X+1^^Q>Gb0(>jydfV0JWe4)t4n@7jX<%$4|<*>sgZ|=``x@%Im$KN~B2UluFcM9*P(LbXTNd~EM=JW#1DbM0BlQdtP z5#9ivd`g;=?)XMMK%R7F-Ic9x@8`Ys4^~q@J_NiQXlu(2oS|e6ld0d(7qY=n_t{&c z1Kzv4MoSLx;E}jSzx@ul;r4kn-|1O$hqtHK#Xg?bU!`45{{&0fR^sdR@W}MB3i+RU zEy^|4Tr1m3ADn2DZKX!Gm0tdN_~w_4edRsc>#ni3dv|WP!h2ZjHh6y7>t~qc-8%U!4qXAiK89%Lkrha@;pQL`x_j|+~70#{M653OZ ztaaec0cap6#kA@FCi_OT*{@HhB%Azs3!;(5=v6elBvk3uULcE&2tlx?gZEqmfTbVCo&s_I> z@jv;tmTwQj3udBc7b&L0+>!Q;=wIWB1BkfAs2m|Y4-d8OfX)onnHvKIYz6m!BvmeCr74+WAWPcWS&G>#^cxBOROfXbL|1kzJs+=JhM&liNJ5k zql|A=zq)Eu^S6@kt1>u|On@m4iKI@(=eX?;G`y{N3YndPUCwcE`r}2SsY3-q*Qw0a`Z+02- z@sr%aYhtS@{|xSLJjujpY<@*+JL7Tp@#_mt7~$BBL9M|*4JK(e{k$ZdUO*U_B@mZAk$PgzL28l$lpy_afd zMWc~}RhE4lFx&V^sx80jY7f`hM^PU;IGf_FO|mh6A6;1SL6hKJ9a} z4Gs&gvgtfPnQGA?^H#~c^~@vls@R;>z%q%mfn~&O5f0A>C-ofWnR=V6J^UtKy~;AT zs%v5a@0!Qzu_mpw5nXaFbjtXk6ZY5OU*5Ny!FjJ-br<*B>pKrm*q@94?)tdze4Tvf zl_SP}2k_}P*Ds_w^nq;}o#v>x;K%kVTo|y9RJV>SXCLrbW!m$ik=Ne(->v1IF7yxf zW8&9xkG`~SXEjZ@McJ?)lsM^F1ox_u?-IVX>>ujc>i%Tnz>Syuhx?vqR$9^n&s zTZ*1hEPv_U$iQ01#J4wKSGgP7QJ-|rLbdpC_t2@O(8*kQ>{5fHxv`z}Q!=#k-Kf}8 ze7A`FE<-;~+MLzsXu>@?ukfzkEHtvTdRpm+t$_*(zs0W(#{%Nz`?$GRv^H zh1_|4LVW&n=JPD(atUxFu6~916LDR3Wb;!TxiecW+sqZ~v(c#|skZi_%8?;v%70*} zRXm-&L+Nc7{-b;KHQaf8^$ee_`WlFzJ@et~ORAX%d>=Pl6}Yam+027{v2tT~GZ(;@ zxp3BH@wfl@TleZ8{-t}ha7=q-ve)aoYih3D)X6tXn3D$PUx+~~!X3CT(gSw3(Xuep81SNbohC6ajd$_zZ{J` zLw_vlQH+X2IoVrh+Th>F*E>p=PV zT}OfCybFo@0$d%KWybd7KPK9Wqq{e%JQ?N!Vwm)l?Z0PYe3Ouy4}HVOS?m6?bBW|C zXo9t}B1GHr*Y{-f>^G1B-U~O?YRyJoXkm@+0(Yf*6y}GUOQ9#FTcke%OhPlR>kPZF zc^WtXlgaM@m(bShI)Mpul@ze#u{T_5;rFNfYw*lJ9{SWwDq&2 zz{G<`qWms9a31X-TcFR&-y%IWly;)bVXfrd-zUKTglr>QX`aSj6^%ShdwNckcLlpd zU2vbfKisPi_QEWHJX`gh5f03*!T-;|%-_`ZBrvOS>_KmJ5^taVsW#4uJGv;km-JI& z-Z*}knX!K$!%(JYEN_wDg01I^jHS{Yi(nkjANs(UzI}B77<=&TYsV)>DLic!JVLO= zzY?AC{>b^fLtna|svhVbi4L)j;Ez+9PrhL3v%Vi$aV2Gv-7?QoW&|-(;HRFwU%Vrc zr^_BATvVH<(uUUM47bhkyjRAxSvf$P-=xjTxHc*Mq@JZDv3o_#u@6@;8RUwT1pCuSvDV=LD~JpWWw%{{}Jmh>v}$MOhfRaV3JiV zU$v)+W7b3*whsa+v1;ty`9;V~=)F=6Q}5e(pPlda-H|h#eQ$KJRa+=0UjuX^TX-xuXm4at?uBSz5h_@QrNZd&46JdpmV`L(c(acLg- z?u#wuU-p(coIhR3_=GQI%)4-6{@Ce7w>!3=1ry-gIp}|di}Ek4PPVW)L?hNcMUSs# z{v|sFQ*z9`Q%|M zO4t6;PWJe8#^p|Ek#*C28{}Kxg2GMGBW@fMZJt>G>@&%ae=oJVI^4O~##|f(R;|p% z1i^`N^Z71^eiRmzJZ`z)D$RM+_?3<{5c{nmSu56a+7dXNgyfzGul=k9CH*ks13zDZfkMEaPkJ_*{ zJ2rXQH$G1M)|XkAznQbfz!y7d8nKHxv)f;e@M7PH2DH{MpwBvcB0ACBU&K8QqBEV1 zy}{&V8XkPN=$QDh$HKMvGo`^{j_u`DaLU!CBG+=JA`iIya;OupUh(?5bJ1>urt;Yj zTcPu&(1)SLaY>ISK{MEz_h$Ks5k-H)^hfsaJ=o=*NABwOXBhmf#^zW3%G8n|{_F=w zSZU(v;ytP#SnRdnUk@WI?oP%QNz8=t@bFjQb2q+HRH8GFZ&FtWd5WhXd~c$@`L7g~ zsErPteF|oXPrU9lrE71mY-{133t1bQz|W$S^Bx~ByHOx{ zPXTQf>i!{c3;w!yicfJlvtlXkn4YGO>c9G~eyjiLJMyLJyT*DUb-YZ!=QCE>?jLqx zpuR08t&uhh$K^dv?C7o_xDpS$z2J*r=d~mK$7@6IQJaF%K;A%*)z-rVbaw_-1O7fvl%K_0quB))%3=pVG3b}XEP&khh98U8)mfq5OYCViZ< z@&@i3fl)Q|zN+14zeue86^ujll*AoYAz)Amd|JNh(3tMEvVeajy1_3=(;0Q~Le1r? zd}r$A?1|v7c%&QGS@xPOg?l~#w)4Ts(EQtszVVFe<2%7$x>zIcmE=Fgf1=L0_N!Kg z+OX8uIW=jx_;J#LWX(T%gK)nv)YOCf7PznP^o{w~9T+Y= z_RzN^?g)@x#Qq8TMRW({%-*j4RX%y)y$^+k4f@K2%>mm-oX`)EF}}Guu>D(YKAZcc zURY;`htFFYzIclrzPNm4!?z0VTlcL6ONZJk)2zLlku^e_p8JYroit_+dohw>QlQ@p zPJH@t?GcT?|NKpJd_Hk@~;8hW{B^vhH9Y~e|pGHQJ z+oj)5=U+06dJr7l>Cf1sc~X0hJl(sO>e*ih>K`;TvTac3)E4|bq%$q!Uow|BU&+|aB@?L6 zjy{+kYX!%5nf_f{&zjGiUBobC|FMPf1Ow0*d_(gYM9)b| zcVJgw_@Bm<6?>g}ql^i9P7__KZ)T4(ZeQ3NO9S%zK;toRCJvzBt1&Dg-t8;g(^(5` zaxd_B(N*=>CS*4DAEC!zT+SY-vsNyApRr~kXD8jW=*_7Y7rrW)BAsz0vDUAk4EQ&D z1?%Zd$r*#g&-#Z?e|GF}-?P|pp0x&-KkLtJIa_OYA!~iXa{sfTwCLFf+kM;NuX~3B zpIY&x`FCt8^QAAC4jfdk$DbZmKMc<%86>#y5O{k3QWx zzi5-bmmjyM`+j=GbnH0Jetf(hXmQ_J+mK$`UV#pj3{RS)b&+S;lAu*X-?Q2ly?NvC zxvUxN@}QAkmF{-6Thi1ixid6dhGFpXgZzAB*7gA?A;TH`+I;V>MYWR74Vm$Y6^oP%&*c$0<;F>dkip%5JmjsXB(T?CD+L!OO z;HkMyV$RB3*-C4?a3~qRG65V~Fg(fN&_-}*i7#^xI9PGf{M$CIao37O9GZzdEIGfB zb=Jcn`SZVkpPFpjYHtO&v>codN>(o_bo38b->3!VIyWb~Z6&-`_OapgdmG;n7YSLy z(*3*cvj_9^SaMt$N6(m4B45)WlEW&`o;fWu)q2L z73{?i6JUScv0yJf$*E4+YR#g!i;iobD)n7Vf%59)5T1DqQ_z<1Yh zZfWuNv+Zm7e|A_iR#N7>lH(XSXPwXqeq6NOL zz8|Qvn!?bZVoz)tuKl3Vv5Q{sUOk=rzRI~*K{nkObrExI3VaRwrS`8z#g=iNPUm%| zQ}$}s`>PLg4>SGL-Uc%1j-7ndqO+W@h3qlht6hm*mUx=P^!3@@LWw(mCzh{1#3#T!*OjAD%Gv3cpl8sOVL zd5`AUmDDwsab?p_)&Et>sGmPqduEP?5JP`3zd`&0&+1Mf#b*}m6r)+=$7f|#12R;{ zcc+);FT%#hx~Bc?UF=s7AE8To44O-y@816k(}u?0ihoF-z8oH7Y{cvE=Q};IpX*1P zJ(~8@9G{kcWBibLWsEv6__x=bah#A?$LUTygn9Vl<&fv}=bry+;rz1tsJ=GSFXmyx zB>Jd*4{%I-485>?>jbBdUw6)m_sMhn-~P2|T8M~q8tOmNOv7T+6VcEYeqJ91= z$1}FU)>M3;*B|^I@s{q1M%Z6ppEKh`6IbbC`pNfAA^I&l$d+#le{*648CtFHr}BO9 z?%YwL&0VvcI%koFelyv@dFQ@N;r!Xul^-1f#MYm7fT3=hQz z***Ynh)-bGtoRHb^GjmJg)kK!(Q@t@kE*v5f%rRz^L7yV)p{ICF> zrX4yr@Fp(x-{@Z}w(F%z-|Ef-={repAbt6a@Fw;NHzoO!l6R+D&FcF$^q(Z3HS$bf zUW#P+;61*}YLUy^z`=EA`L}y@|BgD~GaJh}(>RqrRnvYh^QQJSce1-~MTUHda>%$F zmX34!pgg7jn)DWQJ?YYFH(Jv&tsu~Hc4&0yE3HGLXG=~;4!85COTT45bU}5=a?ZP> zH;lYGkenjmcl5!*6-lMPn1_|sRNdHB=bZnkd>FYm=Qcw{AI+c{7CW6J5fRLW>< zn$uSB<6Qc*h;tswV{am3DKc0iFzr}iHJLao?~gHjv}?b!_csvFnhPwBERKMuv%%L( z!P`r~->(o${Ng6?+2A$yz=&d>Jv|%VwN?Aze#!+XKZx%JgWp5IZy)EqoUnh~o4ii=IKCwt z57Tzg#pe)x5&V~hh09s7>wrxTb8sj2uUzWE zc%AH7HRFrBz(*Q;_Zg-Pbg&dYXUdEVmnIj4OLcFrVtf>x%=?MX`&_+G;JwJr$6uxB zG~U1D=IebD?-Sj8{85Ug@;=$k*ZWz#m%91vqZgI&ezu#h_ZhrTck{7N7M;)gxo*DR zXYqc4o6nwB(IvcJ?B?tJGTvvq`Rr#EUBUb1Zob~H;r%K%pL1PBbMX1OPVd15b9vW2 zr%lXx0kkGMaL&P}$99p{z+J$Je7BOhDL-HQW?)>_*{Z#-bgvez5R<9v5$aJJ_55ck zjpql|9{eRtU0!>?ReR`?`lgm=;Xprnfj6uDWiz<giQ;1g@AWQblmZOFIP#@LIZkzdfRo)HK$^sUx}_DK%xRL`Ss zJ)*gO^>jM*Y@wb;>Iw0^c!uin>=yLX^m)K@9Gvr!+#p+*eA!!mjL<6I*t*c-5%b8Nf%p?dPmtt<>cM z&Ua9@^+n4r;Q2c|w~;P6^9B0T@bB*8TJ}X6k+qz3?ZIZno&#SReDK zzZKrrHWE3VIuqxymHI>Yxp$CvcwF!IWAT-czhbh!Cr|u!C2ceul5a2eML%cbfWcGh zD{}Qf>qr4O-5n@6rtCY4?-Ok*-8C6K=L7r95pl6ws|FbuoyvDc*4g)cWSybtEq!$u z>`|m4BeTvQV4cxg(}o=JBfism6Ge8EF4qTd?;C66yk$4y|NAoI);F}LGeGCFW`XZh zBm)Q!WXq^oq4w9xRma^#UHW037fdcq8J?Miq< zC1?LQx2F3s>{qGBYilmL{#eGlow;ym{rZ06UaN7>=zEt%{TCdwH^!eFWsE;zjIH!f zT-*%gJ^FdGpYrb>_z4 ztk=eeCz-tVRL(=v274^%w!N`PymhAkxg-3P(98b7Sl9Ti1@g@u5RR`oxH2!7c$(Xs zF?4(Vr>%48e~Z;QRq*w2-8<`KctDZkgV?8TtH?g%6Nh#NI^QjN2;zs?4-RpC*)c$0 z#?lwrEknM}DMx9WnA1geI&F6ZipN{rb(q-ac-l+~-WORPe~vq)H});{$DMy3)7ibm z-_*KGYtVg>17Cr+f}g{|*Gg=k2^C381 zhCS-m9ftnvtFD}2@KQ9iE)WQEC-%@|2JMYQ#!N9|v zYp*Ww)WG}a*w92Xy88y%pwIbA!zYQ;DLjqe)2IQ4ig}ZG4${GmWs#0DYf(q{i;<2e zeVasAZ3`UU^q=%gIM50X+(aG1Bkeu6q8E65%=Dp;QcgGtFOdvXU(h*$`C+Z3uf4d@ zKc?J3bQHAcPrkLN&}yJRmeZdJPJe3L{xr~^nMdi5MStSxqrTv!Q|uf2^rLUwf`NEb z88U4vG+Z!*`vldWNp63#;Z1_iWln$Q(4Xj_&M7Cx^~FM`@?bMiU$U8B)!Ddf%$u$$E?tCau&*0^b z4Bcmr4vtOZxd!}p4&;ZsUL0aQ7v{NR2D+t>J0{ro%fP-S-nxOYw4%ezWiLc+OSdUg zo1%G#Ki3yrd8$1Q+qvhLUXC62C%^4pEgM1`ZR?xI7^B*E<%fQBab)o&jQuO<=IHMM zM}Pm-#SUEz93!n)PL_S#;Ps%>6%*X}G$S{eJtc2nYozJ3WaIQ$7HhwOBQ!8t<0DOU zO+Ave%yl{A>$EU$Da}IoP!N*hNIi~_+B=Kc)LR1`4is^GJu z&%1E&io6l8oL0jAbDH*us|Q(ACG+ZCd-i?C(R#Y!r{$U0>*=TV=EXNUxU;7~cI9i+ z>{i-bhfVBBe)9x(_Ardi2wHmROtbD6tBhpJ@9~aoGUbDDSnkmZuYYdT=p)UB`I)$>+$LaXMw(`h|QxjT8EQ% zBWWQoEj-+m`xv0SBysDn_y?WXPt|t&z&ldU9C%N?yv$+f0 ziVk(^;gVRVKWCpYV1M=^UwCu1UiLcn|J5JS_+`RT?yFXR#(DKL#nrRvxSnzCjH~BI z(xI@&s-DV-_-SUW9GdV0f7O-h)s;DEz&^beS63Z%RYK#UwYm5PZJ|$L?!Xal{TqH5 z0`}?5LBBb5&svugzw5H!Adk@QCzJY^^2I8$g_G`hYju1}|$K4rvohONS^T?3!H5)8Gz{ScW-{B}3?d+pyR)LmaySnTL% z#FEN3b*INh|FwIy@=U!bxzBZmdL3?i$97=2ZUkcuT6d0VjQN{Q`YBF&&`l4rzOp`anYvdNns2U>y&PIFb!)E~Tfi=U z|7M@7O=Et^Z^~Ulxfbj?rrel8J>~X$<@P(}KBAoIL$bfw;Le{*&G%*c9$E?h3R}&8 zxp^69nYK}`iR4+}v*yspdS76Tuuo?WDs|pcb2QT_H-R*0(Mh|~ zNjr(O2F}R#oBNxbSan;@iAHoTv|s+PsSbZTD;ilfQ2t>je;zj4l>_B}=*0Qm!g_q|#v&JZ$@)d%G@}B3MxO8{^ zO&RefhU7QT|RvC5cY3|vOg0<224U0jE}?Y#QoHH7|D8VRrq9F$hh!- zAB}J33+c$kr*U65cQJM^8PtRyf3s`@+seasI{U7*lIQ)wI`o#V#`D5b~J{W%scIN9Yip4(PCD@^kA9xj(KmutDtGW`ui?3K>K zHc(6Xth7|_5d)T#-FUBM!w}uMW*v@KKKQE zc*kFa_ffpJ@!n3ka>{Al7)Rc7k})|u$(r4Kn7k+0x2p{}@OzarG2&Alqz5N*e&yV- zx%cS+ynW+{LALhe*}txT2iX)KjrxN-EbSB3=llzK9z3g@C;7KG=GdPvuvRTryu3ht z^D5x9gfl`he5xJ;uJT`#tbB@ma?n$p_pDeU?=6PsDL*@Q0`F17%k-WT6ORqM@6&0! zV3^MyrEd;%wtn8}J?)Prtxddw{@kAr-{f3jCHjK;w+wrS?uXex|EiOn{qn8sQ!hd% zeT#1@=cU@eGyfrTSDDJR>fTG%HPM4~*J}N%PX4c^{x;SG)$i5)AJlEWar~#&7scJH zLcc4zhfXKvp<+)S{fyUg>NuKwV8%|2)BxiQo`8%{U`-qc9zRkZs%u1U$p4kIk1N^B zD~mj39|SMF@=vk`Z}VFzvftERSY5IW9~SYe#PwD%G=2`~HC=p<%o9^xUfO=rqW4xl zk1Wt78qhg*`FY6NGs>4(ay~YTdh0%){W$Wq>K3g%%Cqv+w)C@M#0}18 zj|+LSLitnJ!#hO&Fy!O>LH>oWqPNJ$PduW)<^9GcQ#-`)s4X?l{y?9+6P$R7{$<$3 zwmR~B1@)=^2>%W&`ulPnzL~q@TY;WHul zOc#2^r}S|*cDdwpwP!LacI(OG9|td4S4TVZ-7(ajjUHw2GEO%*NIa^ZGO0m(rdK9T zFZgGCnUbLW56Y+y)#wF_%Y*O|w~fl6UE+S6&fxb~zL))8X_v~rHbi>0`_1V| z_U{>!WSTR%zvkE(<;@$>%jEkq z9r-}hK+w&2G^yTb9i`2Q@i?0rFlYwfiI;M%v{xP~jZ|BHIm_hz^6 zU!$&|r9G~2v&Eg*@~1d_^DmKY```7D6g4^KHH17m_)2-c~Y4W6d?%H|n>(XpCl!F?&b7do{8_AHMm2 zOpMOGz*92V(c-=Ae$cxi$9JNUcdvQ@0E7$##e590r48BGvq@* z!QZ4S5F8)8E^AaUsWv^|m$RT27-^j-oCIdwbI-#og%i9>FH6DyEeO9Z8)q#Hu&y)_ z&!^1i+xsNEq3Gs&9xCLwVwq(>%`ZH7$+P9dw>(ohxa`?^!2Tq$*GV_;?w;h!dcOsk z0T~**5$jOEt^`gEdFgvwf;8T z{2*mpUko?b@!zpE+`Rjj$XUcA$lJU;@B7M2x4O=vkJ(XlGQAVC_3&29md+u((!FNg zerxakKdi|kX7%2E`~$CyFmtc{T=`r=!#miw+EGpaD%qzpzB4uW``6$nT!XI+e!}mt z@6bj2`bMz~_%1S@_AJ(%!X@E{=a1W#7vv81;O=`LTCt#d(*?ey@ym&8@b=-MQ@ZGL z{CA`E9s2jNzI&H>7R=#u73q{0U+4TH>oxbSYp)et>3M$;Uu52Y&$tr%=o3uP&DB=Y zk#pZ%zIgto!V|aU%^ZZT%XnHR1&l9M0p;3wmM@j`X&iMkZ5M zdwDubRx3Y4@{!>pmXEt@+0&a#pZ|WI)8`Ik!F?)={i-?-d%v4ron62nl^!B&J=`ZW!Un!f|U*Wa-OH3%!-(R@>O6>0jH(mWj zCVNP@^r?$W2l(&)_i=lNeFXh>AGi0l54$TCGY3w;(qrYcA^g`oM&Sz`zbEEJt~Ijk zh|lbmFCU4`>+IlV5AzLlR3C(nGN7yHS#y3syU<_racxF^b!5?1&b@?}VWSp28-eFa zw||ZF&-F8_FN)I<))K=58b79f(0DuX0f$&qk)J-cE=@CYIUjhc-z~&q5D(V;zDQe2 z3z4RE;VJjMVR$e7`jDSRw}S8UUOsn*i-xC@_EXYY!MoLNUJJ6W%0KMBhxN`pf8Wa| z4xgca-eoIm81K~mgqM%J+i)=N^urDD`aDT4Vf%|mH8HZDCBg47zQ2piXnYIvX|B~{iweVuv*wDb7Jw-c}c~;k_ z;M``?_h*NjmDfVv8s&|Fr_tUwXhSyrukr8TN`}D|;jrKfPw9^<=#0V@>Bk-|4d;9D z1>vUl*b05QX9y?mg?H%L&>OIxruKm8nf%{D-eCSM#+;}Vdi$2*f0kuEt9F7pRC0!Eak8mXp?KEUHKH?+!E-vPM8NW({8cUbWV#H16Wwn8g|?yK5HuvBug$n`Z52 z4VH|jK16{_CH7owO*_P^zs&fnft$5xa_8Illt$mXy_2)kX<_QSjr2y!S0g(l>Xq`< zNW32+_-$wY#futU+R~a;Af4_`ojL0DlhuC9y?-(He#N{s?^WQVxoE}CPz`+)vdEd*|o5s3S zQ5}cVuTi)9R|#LK1gHPxmRsuTwa;Te_xd89avQK)N*Uqyp`GTQh(0{!%YSirig4x* z$^~7#N`#YiiiOl2@53ei+8QJtFP{-&dNW?dXV^tO^sOuS?sqzgQ;=58JpNT_dCu8; z^|_Mxc~S7k^GkZ?Tr0zSHfMy6Ay;zdsVj%EU1|JN9GxXM8jYMu`;(dHjpZZlA8^L- zoq0+2RNfCpM%qDa)H98pC@1D4&d1}xk$L?;w7q$JT~*cpf9_3(o3?by&~%`g0Mjy+ zHXQ;jP17o6P|Kx02%=3Bg_MF=N);&Bn*=4uV2)JEq@*d2CKuGGtq?&-ThubBpR_x z1HKPWIy%q-a1dHG-i;9lJyve_FXQo>em>>or=Q2?9SEA`S5|;ttP7p^LB=`F;T~f8 zZRSnwcm6FzmU7(aROQ+Mf z13Yiu>%6-6G7Co)d?Np_{K7bMN_}8H;#b*}AR3vK#!&WWpYmRDyf`DgH~@$qck z32W?j)|mLSdcIEQ3ECViMn!M+xV}Ah;y6vghdW?=M1DnC;q8wd_|+n-nX$Vt!;alz z;Vdn>g?%UYbv7?Wz5}1lcTpyt@nZZF$Ll&Twj{o-pVxS?K9$CeR}bZq$LoOF&u1J$ z&bE((vjKJ9oNj%4@Vi|~oeRlxko@h7btX0=DxbB_%`!Y{O)k8vow2EBzhAO^3O+vp z_i20*v`)5oa7bVN25q*y^|fyF;of*;Mr9jZXT~@q`Uk-T-4yfwik_+GUhpHDiLjTg z7>W-%X}&$^Q{>T@PXx9E`dyxB=(nCT!4n6;$2Q6(Sa;If$S2Cg9!-9ywNyms(^ zAF+E6U6ufIQ+du9Lj&@k`Ym>QvpyD2bWQo?6Vbn5H)7r#@c9k(9Qr5Y1&`T-0j zLE8Hx>qVq$9=Oej-h2q0GJlhKq{cUy#wG|x%4B%3*0HXQ=UKe!f1rsN_|yFe32aqIn8_=6-J&@kOFF%WQVC{DdFE?Wtp^S9nLC#-(hB}bbtljXG zNv3Xn%j4Up_?Fy{_ZAQA$GfDdAA9u=&g%|xcLdK*0E7CXSdd@j{m3=P(M<-8Pk3#g z4NE@Zi~YO3lGnD$-A?wuV*w?hNUik0rj>{EHYOS7I_sP9Z-MSa6lJ@l8$~$;%b&97l z_m{Z27R2}RO1{OYGaY@m_>$;NXr>FmQNf%#?{1uG<%t)u7e#R&|MwA zS@`z)=&$jgF=;l>0`>LS@VSyzN`YDYxBeVEr(@7ULcd$`Y`4zwr~&^Z1D~4znoGnCuybjpH5V_R+eA*{irf&!n5OEt1(QPOFPheX?+|pm%dnF_)!P# zf1I|pch)_P$$Wf~=E)f5N%i^6lY#aMKPK(xf#bM#%iHc4I8R1uo{WKK+w`!@-NO z)6(yD>c};9*fX&AGY7AM2F#kk+I!@Gsf#tXZ8&qc*wXT1;e0su${D-^(?Z_;{OzRY zlCJSt2pl=mTX=at&3hfRc!;|8l!#7koqib;KOWtC3$!ZQ_#&|2yVBRTzh>pfweP1* z^wUp z!(+|9uhV!EmK-(<+S6HX2Y*JvJ{#EaSD2kJ2F0f*j6uhxk?;?GDcY0V zn;B(4pUCfhzOoE|U-D%zZj!;0X>_xhC)_1EQgk|I06+I_o-xKcv~r^?t?C?iuAzlzDd+F$n$5G_)BS?y0lY1AhT(l3+)e#O z`qxe!;zy#LGuZ=_S{*`b=u2lB9YPo1WAGTY<#PXk^awSgP0|*Dn<{=;tfyK_6Z(h` zU4(DJEAic=on&3YUx6)oU(+tw(G3)z|cee`Z*RiCcWTn(k#yIfKJVRmpt0fK1e>j z-_D%O!LQ^1x`_Dwye~GWz;P=*~)>efR_X;|zJRbRM2zJ>Ne8hvq{?w*rUhJlRxWMh?eB68A zS>TTR@J!xMcK3ZO*ckfoB;!vW`)Gk1djem%@Eo_N!r3GZKD?HO}AgwJvjXAZ2w20Y@Wyqf$U!gPI?<-$? z+6!m74=LXm^kwMoE1>^W{Er$r^B{a_&eN{p`DOTWu}9ipepQw`oH^FSnqz$L)Tajv z-8-qL&e$3zMGdSkWV%(PNuE$XgQJ^=xwn&+bAZ?()D`-5rW<2y9-^+;eHS(##D7R* zMER!NOVZp2NI$}NSKr}(A;p#Fo{ku8hVGr|cJe=M)hu-VH4m#Ee~eA}ucW!(R5|7~ z<%(+d_ZI3|`EFM_zWGYu^#SQTD_!>53q;zcgN?)UNba2YQ^dF@2tn}5SZv=0z zgE#RMgR4s>xJ&3`sq_ov(fO@7xLR|&C%7M-&p5!B#nXc+RpDPkkJ9C;?{|-2%*P66 z1`n;d=~-?k`IifZkrsx6_j(Hx>deV< zHT;eIq$&R#zDu_qTZrD0v1`Fk%4wVA9$@Zn+yTt|=Q4-2)?RfQ ztg7YypQnwlnB~&{ScmJxmPZR8(($$HOrdV0?b^#~6gv{6DE`o4=b zi}gQRs`xu+bLS*;_I>bG$Jr<0AffH_bhGCuTN?>~fwq9r(vxr1}^W!9QuRye-y7karXED|t(?Q%b*E`aj5w z=szle+lRsE8a8IQqW2u?uU{7l&-Chlg!+{>o;K9pCf*(1<=Zu&zxSjWIjH_dVoa$# z{oPJ}mAlLQr<+)mtP8EvP9?5cptwi(3okNzc*RHW`b`!kG~J=3yhP- z=pb}tcpdZMNye#|bv)b2*vB4xd1(KNdAdJmGwmnf!bx)vU?Wh!J2cPGWXH}k$VZ#wZ8`sepf&S{k|n{4Pk?=kfM2A}vFpgWn$ zn6;eEIiW3_$>b;eG*Ab+|JJqNoZ@yvJ5{pBJ)Y6`{Tbp(Yt8eu8t)0j z76#sKWRI`&&Kkc}e&t0@xOj#wmX4wxBZ#zwv(^wa>soJ zd!X4DE}Gq^bJSUks)walm>8WS_$3b&&o(|tr_7-3Q-K4WLn-a5%?LJ;zC844Eq$sX zZlC5*gcySroGrB9Pc?mB&G(0Cy9+%@e7fKFudC0d%~OeIh3O>Q+>=wxc$IC8gpd59 zcaxbL56-mwoqo$#=I7dzfLEt=ruLUjxmmMZ?R_o*wubsEiV9eR%=esG?z?ZntI-4a z?`AE6X0#T~WE|_V`@e0jw>CM^yvcvbEO&F>xu)*fq&+pFr1=;4u-BAV5g#Y$ZpIf` zYw;W4khnBOUEpbL3G`y{mEms2*Z&8U{~LMb6CvG`{3wU=`@li&n~Yw7ydlPW8vU5I zj(J%=`U?+?v#r;~oscG9ay^t^Ycm;U!zZnS=ydph4%Pb_ph@8;XLy>F`u-F^21 z!=@2EjrA86rGm>)Am}#Mr`o!HTIjy_2;UzY(Iei~Ri4CSzj(46VJvohmpG$*4{hf@ z$^h&1Q=@u%e?H3iImT8`Y%U;A=;wJw@|9|Pe$=r}`a6w&_WqW9J4f|Q|C9BVdI|rC z3HVBh#=i!hwGV3h$tZlJh-pXcE$ooHExu=)Gi5#0Q++M_(|pb+1kuY zscRQ&>V=X47opdGVpLD(GoyMmPy1+`=hF}C+{D;5;AgqF7x&lqrt((`jl2+y+H>sj z->b!Mh)GyX->Ue25%lZV`!`~yiZ&ad#SlI=p+RU;H2er~4*_pJy^ewIx>jG&eDEii z7@rUAPqj~ZoxUggd;Ed4ww;&s9E5KdlTUHe+J1Y9dEUh{ysa=EUSx`<@^|dH`?4QJ z!t=zFSZ^L@&eVzj^PEdtBhV=n<2&H5Q>NTKv)u!i+c}^26ZFaID{H9qQJS`^&#Iy0hYea|QJ^GKAcT%+X z*i~fes`_yx{MT((Zj&Eq@*1{C@{MeZ)k9Ax-~5Ys8Yf)WI5(28t_`>Gx+IS#tY_7e zx(m27wMOz!%5cu$3}cTxls&SIkKe;Os5|4PGHzPaTZlj4or7u3EuL=Ve#P3t=ibW7 zwKgqAT92Q$)u!zwjrG*#d()=4%{^+<-y}T~9{}b_(JpA9&xTN-*i>oJ zR=&40e{$z5?m}Ah54_99r*RiA+z7nJhR3%r4d)wlBiVfyvU|hg;-YoTzXrt~BY!4z z5*p=<%N{y*%}CBfh9bmwW4%Zi=ly4x@vASa3{Pf!6TaOv&6T}eW4~j5W%$dCuV_$f z`8ME6i_0G`gXNuH87?R9$m4tumQ;p6XX;9ezF_K+E_5KxZ1;T~;5qVQb~2+p&e!S{XO_ea;Rn)m$okb{x6DqcKe z-aSK|agTwwYtbj)$Mf~1{e^c9+$^6q)N$WW868~_NZq%Ha~Utr z?Phe#J*@FfehgLNteSPz_)OA9_K>k__Te+HF+r!4I3`z}ZpUOvW%w7st~@&b8$b8V zekI51>GI}P8lRnim#dJAbSW+6}*XaziPG>~#1#XQ6 zIxN=djOcFsr?4m3bsC&%{W?rv4p)tHQ|Wu;R_o8)=J_vbovyL#bgNmX(J^##-sJ#& zH2O{cOAhw0(X=JrR_pD-i5+Oy=pDbbYjpf~*63P)jV^fx-+`_0jC{xKB_5;3au;i4 z>`v}kJGQ}Jqs>?uxsh?y8vQf+=dID^+iCRS0KN)cth=Satu+@bcqc_oW8_$p7@6|Tpu}L=pLp;pPrP}i1xvtg$$yRyKMZ&WLH$24C;WowZ z)dT)sy?Q1*sow|7_pSRRZT0SyUu=kY9^4bLo|qohLF%`2s2zObpHM6R1k?7LbB#=+ zu`GFkxCgYYy|wuknb-HNjBh9L&Cu6Ri!9x(D{^DK!A6sIDbGI)G#VWovMaJ_?L}vj zmJ)Dv-?Vs=_~dNH;=t#Mn_mYH#2;{dd&{%O7xH=Hy4dG99q2m58p zNdJk-pu>wFmv7MjX3O4GDl+kj-qdC$iuF9!H}Mf;Io2t zy@s>mt0$MdEgd_R}^#hYroJij9J*y0Z-ob!uQ2A%WEz|9He*6261 zw)WGk@hO}Q&Dz)j3A8F*46?H0SRKNZ)NS9bZsxyue~dd1D;R@}Uq3dfkA_W|4Cpv5 z8evc2mucTitgM|w+$&ihTVyML1bq|dIalKs-S!wh(n*Idu{aNp(zv$joWU20y%;`PUfv;7q=igYH=-+5<;(2db|BbgP>-#sV{affy zhjc-wKqp?m)rU{__2E?aa%f#Pkwbjn6GR8#_Z7bS8_Jh5_dHp;pLd09Oq!Da~+#AXt4xZZAUMqEAo7t-U@4GzL5#vw#o+BwkiGvUsM4&=PTieW zMi<_;8XTn&i=S6p2fiX02=pbCfEV5 z0?sReCqW0ivrh*cx3-`I-ePsYH;})cb*AJUlhpPwaV6G<|I5(wyaL_blQDEKm1MS8{OTG54_m*PkQjp90a~o z|9^zeSlT(_?n*s)ws%~f>SbVvT^2Tpu40wq5 z8#;RksQ9CG+%!FyPlCB zwYM*(OsC$-u*L5Cu z;j&LDpk8Na&7_0K?MdreQ+Y#*TXGbA9DUd-JtAd&8UAJZaR3{6ByOLy890-Di5^uy zPPa1nLwY{jK0lymgUhA#;R0lF;+!q^?|f6=67RqB>Du(`)FFm$ryZkz>~GtlQ6tx? zkBmiZC+i)3Ja}<&vu8W>=Rs5Xk|Bm~1$)uGHi3t^j4yh!c-ryhH?1XA#H2eSM7 zs(tU(rmyzgZXI%{=zgX8G|Tqy3p}sYevm$Xj_2pSJ)uuKy6euTpTW*Qr9Nr)9<_aT zHR&I#GkhQEg!53@kB(VG|Cb+Rd;{o8`}WUGL(HD4ETuC1cQZdy%soIAQ2}JV@(1$1 z=A~ui+cs~{cVlmm{%0@!p?tS4)Lnd>e zlLGWa8v9szhTB;_6gyYV!+twK_BdWlj_{+0dN+NOG4j6&-(NMpdv+|=nrAx>U*Y*6 z^|kR+zUz2DMBQ!t^j^Vx?}l{7DQL&Z8z29U95YUgNesP#(J3(|ou5m!W5t;4qd)JR zJ%U)DBO7Cvv(NvWx9H3!amVIpJ#Q3R_;uwzs35nmrbn<%fJ2E+0f4A zzk&yIhtT>U`XlazxBA&6-Xs02v3id4^sA=-RzJIoI_G)alcceob_Xp46|)*Nc7${i@ZCBFi$Svc0-JT34+fkdZUHiL+*4ux;)@ zUX$(bV)$Z0|L3Q=rQkI0(#r6155Fh*^A7loeh{6kbWRtKGW&|c&^332P2GH#PPb&D zVoD*N#Sd}cp8ehq2d-GY4f?s)9(oWbDN&f4CA zZ|dWx8(m2fUm9-Kw30I`!`bvn`G1H!mcu=;)9G7C{&wrmcMs+})P*gdy8QZTsn4Gu z2m0Ddi++oA*#Q!8cfht&b#`TVsA

?^Qd{xAZFsd2bFGnCfR#hL8L>Zr;#_=FLRr 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 literal 0 HcmV?d00001 diff --git a/src/bin/pgaftest/test_runner.c b/src/bin/pgaftest/test_runner.c index 01aff9c32..0039240b7 100644 --- a/src/bin/pgaftest/test_runner.c +++ b/src/bin/pgaftest/test_runner.c @@ -99,6 +99,14 @@ runner_init(TestRunner *r, TestSpec *spec, const char *workDir) snprintf(r->workDir, sizeof(r->workDir), "%s", workDir); snprintf(r->composeFile, sizeof(r->composeFile), "%s/docker-compose.yml", workDir); + + /* build context = directory from which pgaftest was invoked */ + if (getcwd(r->contextDir, sizeof(r->contextDir)) == NULL) + { + log_error("getcwd failed: %m"); + r->contextDir[0] = '\0'; + } + snprintf(r->monitorConnStr, sizeof(r->monitorConnStr), "host=127.0.0.1 port=%d user=autoctl_node " "dbname=pg_auto_failover sslmode=prefer", @@ -163,7 +171,8 @@ runner_compose_generate(TestRunner *r) return compose_gen_write(&r->spec->cluster, r->composeFile, r->projectName, - r->monitorPort); + r->monitorPort, + r->contextDir); } static bool @@ -665,6 +674,6 @@ runner_show(TestSpec *spec) /* write to stdout instead of a file */ bool ok = compose_gen_write(&spec->cluster, "/dev/stdout", - r.projectName, r.monitorPort); + r.projectName, r.monitorPort, r.contextDir); return ok; } diff --git a/src/bin/pgaftest/test_runner.h b/src/bin/pgaftest/test_runner.h index 5d883a21a..b2438824a 100644 --- a/src/bin/pgaftest/test_runner.h +++ b/src/bin/pgaftest/test_runner.h @@ -21,6 +21,7 @@ typedef struct TestRunner char workDir[1024]; /* temp dir for this run */ int monitorPort; /* host port mapped to monitor:5432 */ char monitorConnStr[256]; + char contextDir[1024]; /* absolute path used as docker build context */ /* TAP counters */ int tapTotal; diff --git a/src/bin/pgaftest/test_spec_parse.c b/src/bin/pgaftest/test_spec_parse.c new file mode 100644 index 000000000..7d2c793da --- /dev/null +++ b/src/bin/pgaftest/test_spec_parse.c @@ -0,0 +1,2060 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_CLUSTER = 258, + T_MONITOR = 259, + T_NODE = 260, + T_CITUS_COORDINATOR = 261, + T_CITUS_WORKER = 262, + T_SETUP = 263, + T_TEARDOWN = 264, + T_STEP = 265, + T_SEQUENCE = 266, + T_EXEC = 267, + T_WAIT = 268, + T_UNTIL = 269, + T_TIMEOUT = 270, + T_ASSERT = 271, + T_SQL = 272, + T_EXPECT = 273, + T_NETWORK = 274, + T_DISCONNECT = 275, + T_CONNECT = 276, + T_SLEEP = 277, + T_COMPOSE = 278, + T_DOWN = 279, + T_STATE = 280, + T_ASSIGNED_STATE = 281, + T_CANDIDATE_PRIORITY = 282, + T_GROUP = 283, + T_ASYNC = 284, + T_EQUALS = 285, + T_INTEGER = 286, + T_IDENT = 287, + T_STRING = 288, + T_BLOCK = 289 + }; +#endif +/* Tokens. */ +#define T_CLUSTER 258 +#define T_MONITOR 259 +#define T_NODE 260 +#define T_CITUS_COORDINATOR 261 +#define T_CITUS_WORKER 262 +#define T_SETUP 263 +#define T_TEARDOWN 264 +#define T_STEP 265 +#define T_SEQUENCE 266 +#define T_EXEC 267 +#define T_WAIT 268 +#define T_UNTIL 269 +#define T_TIMEOUT 270 +#define T_ASSERT 271 +#define T_SQL 272 +#define T_EXPECT 273 +#define T_NETWORK 274 +#define T_DISCONNECT 275 +#define T_CONNECT 276 +#define T_SLEEP 277 +#define T_COMPOSE 278 +#define T_DOWN 279 +#define T_STATE 280 +#define T_ASSIGNED_STATE 281 +#define T_CANDIDATE_PRIORITY 282 +#define T_GROUP 283 +#define T_ASYNC 284 +#define T_EQUALS 285 +#define T_INTEGER 286 +#define T_IDENT 287 +#define T_STRING 288 +#define T_BLOCK 289 + + + + +/* Copy the first part of user declarations. */ +#line 1 "test_spec_parse.y" + +/* + * src/bin/pgaftest/test_spec_parse.y + * Bison grammar for .pgaf test specification files. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include +#include + +#include "test_spec.h" +#include "pgsetup.h" + +/* provided by test_spec_scan.l */ +extern int yylex(void); +extern int pgaf_line_number; +extern FILE *yyin; + +/* the spec we're building */ +static TestSpec *current_spec = NULL; + +static void yyerror(const char *msg) +{ + fprintf(stderr, "pgaftest: parse error at line %d: %s\n", + pgaf_line_number, msg); + exit(1); +} + +/* helpers */ +static void append_cmd(TestStep *step, TestCmd *cmd) +{ + if (!step->commands) + { + step->commands = cmd; + } + else + { + TestCmd *c = step->commands; + while (c->next) c = c->next; + c->next = cmd; + } +} + +/* + * Collect content from a `{ ... }` block that may span multiple lines. + * + * `src` points to the `{` character (already the first char of the argument). + * For the inline case `{ content }`, the closing `}` is on the same string. + * For the multi-line case `{\n line1\n line2\n}`, subsequent lines are + * fetched with strtok(NULL, "\n") which continues the caller's split. + * + * The collected content (without surrounding braces) is written into `out`. + */ +static void +collect_block_content(const char *src, char *out, int outlen) +{ + /* skip '{' and leading whitespace */ + src++; + while (*src == ' ' || *src == '\t') src++; + + /* Inline single-line: { content } — closing } on the same string */ + const char *close = strchr(src, '}'); + if (close) + { + int len = (int)(close - src); + /* trim trailing whitespace before } */ + while (len > 0 && (src[len-1] == ' ' || src[len-1] == '\t')) + len--; + if (len >= outlen) len = outlen - 1; + memcpy(out, src, len); + out[len] = '\0'; + return; + } + + /* + * Multi-line form: content starts on remaining of same line (may be empty) + * then continues on subsequent lines until a line that is just `}`. + */ + int pos = 0; + + /* remainder of current line after `{` */ + if (*src) + { + int l = strlen(src); + /* trim trailing whitespace */ + while (l > 0 && (src[l-1] == '\r' || src[l-1] == '\n' || + src[l-1] == ' ' || src[l-1] == '\t')) + l--; + if (l > 0) + { + if (l >= outlen - 1) l = outlen - 1; + memcpy(out, src, l); + pos = l; + out[pos] = '\0'; + } + } + + char *nxtline; + while ((nxtline = strtok(NULL, "\n")) != NULL) + { + /* skip leading whitespace */ + char *p = nxtline; + while (*p == ' ' || *p == '\t') p++; + + /* closing brace line */ + if (*p == '}' && (p[1] == '\0' || p[1] == ' ' || p[1] == '\t')) + break; + + /* append a newline separator if we already have content */ + if (pos > 0 && pos < outlen - 1) + out[pos++] = '\n'; + + int l = strlen(p); + /* trim trailing CR/LF */ + while (l > 0 && (p[l-1] == '\r' || p[l-1] == '\n')) l--; + + if (pos + l >= outlen) + l = outlen - pos - 1; + if (l > 0) + { + memcpy(out + pos, p, l); + pos += l; + } + out[pos] = '\0'; + } +} + +static void register_step(TestSpec *spec, TestStep *step) +{ + if (!spec->steps) + { + spec->steps = step; + } + else + { + TestStep *s = spec->steps; + while (s->next) s = s->next; + s->next = step; + } + spec->stepCount++; +} + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 148 "test_spec_parse.y" +{ + int ival; + char *str; + TestStep *step; + TestCmd *cmd; +} +/* Line 193 of yacc.c. */ +#line 318 "test_spec_parse.c" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 216 of yacc.c. */ +#line 331 "test_spec_parse.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int i) +#else +static int +YYID (i) + int i; +#endif +{ + return i; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 21 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 21 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 35 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 11 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 18 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 25 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 289 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 5, 8, 10, 12, 14, 16, 18, + 21, 24, 27, 31, 33, 36, 37, 40, 42 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 36, 0, -1, 37, -1, 36, 37, -1, 38, -1, + 39, -1, 40, -1, 41, -1, 43, -1, 3, 34, + -1, 8, 42, -1, 9, 42, -1, 10, 45, 42, + -1, 34, -1, 11, 44, -1, -1, 44, 45, -1, + 32, -1, 33, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 171, 171, 172, 176, 177, 178, 179, 180, 188, + 265, 272, 283, 293, 414, 417, 419, 438, 439 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "T_CLUSTER", "T_MONITOR", "T_NODE", + "T_CITUS_COORDINATOR", "T_CITUS_WORKER", "T_SETUP", "T_TEARDOWN", + "T_STEP", "T_SEQUENCE", "T_EXEC", "T_WAIT", "T_UNTIL", "T_TIMEOUT", + "T_ASSERT", "T_SQL", "T_EXPECT", "T_NETWORK", "T_DISCONNECT", + "T_CONNECT", "T_SLEEP", "T_COMPOSE", "T_DOWN", "T_STATE", + "T_ASSIGNED_STATE", "T_CANDIDATE_PRIORITY", "T_GROUP", "T_ASYNC", + "T_EQUALS", "T_INTEGER", "T_IDENT", "T_STRING", "T_BLOCK", "$accept", + "spec", "spec_item", "cluster_block", "setup_block", "teardown_block", + "named_step", "cmd_block", "sequence_block", "sequence_names", + "ident_or_string", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 35, 36, 36, 37, 37, 37, 37, 37, 38, + 39, 40, 41, 42, 43, 44, 44, 45, 45 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 2, 1, 1, 1, 1, 1, 2, + 2, 2, 3, 1, 2, 0, 2, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 0, 0, 0, 15, 0, 2, 4, 5, + 6, 7, 8, 9, 13, 10, 11, 17, 18, 0, + 14, 1, 3, 12, 16 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 6, 7, 8, 9, 10, 11, 15, 12, 20, + 19 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -31 +static const yytype_int8 yypact[] = +{ + 10, -29, -28, -28, -30, -31, 1, -31, -31, -31, + -31, -31, -31, -31, -31, -31, -31, -31, -31, -28, + -30, -31, -31, -31, -31 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -31, -31, 2, -31, -31, -31, -31, -3, -31, -31, + -13 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 16, 21, 17, 18, 1, 13, 14, 24, 22, 2, + 3, 4, 5, 1, 0, 0, 23, 0, 2, 3, + 4, 5 +}; + +static const yytype_int8 yycheck[] = +{ + 3, 0, 32, 33, 3, 34, 34, 20, 6, 8, + 9, 10, 11, 3, -1, -1, 19, -1, 8, 9, + 10, 11 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 8, 9, 10, 11, 36, 37, 38, 39, + 40, 41, 43, 34, 34, 42, 42, 32, 33, 45, + 44, 0, 37, 42, 45 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +#else +static void +yy_stack_print (bottom, top) + yytype_int16 *bottom; + yytype_int16 *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + fprintf (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + fprintf (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The look-ahead symbol. */ +int yychar; + +/* The semantic value of the look-ahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + int yystate; + int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss = yyssa; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; + + + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + look-ahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to look-ahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a look-ahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 9: +#line 189 "test_spec_parse.y" + { + /* + * Re-parse the block text as a mini node-list. + * We do this with a simple line-by-line parser here rather than + * a recursive grammar to keep things simple. + */ + char *text = (yyvsp[(2) - (2)].str); + char *line = strtok(text, "\n"); + + current_spec->cluster.withMonitor = true; + current_spec->cluster.numSync = -1; + + while (line) + { + /* skip leading whitespace */ + while (*line == ' ' || *line == '\t') line++; + + if (strncmp(line, "monitor", 7) == 0) + { + current_spec->cluster.withMonitor = true; + } + else if (strncmp(line, "citus-coordinator", 17) == 0) + { + TestNode *n = ¤t_spec->cluster.nodes[ + current_spec->cluster.nodeCount++]; + sscanf(line + 18, "%63s", n->name); + n->kind = NODE_KIND_CITUS_COORDINATOR; + n->group = 0; + n->candidatePriority = 50; + n->replicationQuorum = true; + current_spec->cluster.withCitus = true; + } + else if (strncmp(line, "citus-worker", 12) == 0) + { + TestNode *n = ¤t_spec->cluster.nodes[ + current_spec->cluster.nodeCount++]; + char rest[256]; + sscanf(line + 13, "%63s %255[^\n]", n->name, rest); + n->kind = NODE_KIND_CITUS_WORKER; + n->candidatePriority = 50; + n->replicationQuorum = true; + /* parse group=N from rest */ + char *gp = strstr(rest, "group="); + if (gp) n->group = atoi(gp + 6); + current_spec->cluster.withCitus = true; + } + else if (strncmp(line, "node", 4) == 0) + { + TestNode *n = ¤t_spec->cluster.nodes[ + current_spec->cluster.nodeCount++]; + n->kind = NODE_KIND_STANDALONE; + n->candidatePriority = 50; + n->replicationQuorum = true; + + char rest[256] = { 0 }; + sscanf(line + 5, "%63s %255[^\n]", n->name, rest); + + /* parse options: candidate-priority=N async */ + char *cp = strstr(rest, "candidate-priority="); + if (cp) n->candidatePriority = atoi(cp + 19); + + if (strstr(rest, "async")) + n->replicationQuorum = false; + } + + line = strtok(NULL, "\n"); + } + free((yyvsp[(2) - (2)].str)); + ;} + break; + + case 10: +#line 266 "test_spec_parse.y" + { + current_spec->setup = (yyvsp[(2) - (2)].step); + ;} + break; + + case 11: +#line 273 "test_spec_parse.y" + { + current_spec->teardown = (yyvsp[(2) - (2)].step); + ;} + break; + + case 12: +#line 284 "test_spec_parse.y" + { + TestStep *s = (yyvsp[(3) - (3)].step); + strncpy(s->name, (yyvsp[(2) - (3)].str), sizeof(s->name) - 1); + free((yyvsp[(2) - (3)].str)); + register_step(current_spec, s); + ;} + break; + + case 13: +#line 294 "test_spec_parse.y" + { + /* + * Parse the block text into a linked list of TestCmd. + * We do this with a simple recursive descent over lines. + */ + TestStep *step = make_step(""); + char *text = strdup((yyvsp[(1) - (1)].str)); + free((yyvsp[(1) - (1)].str)); + + char *line = strtok(text, "\n"); + while (line) + { + while (*line == ' ' || *line == '\t') line++; + if (*line == '\0' || *line == '#') { line = strtok(NULL,"\n"); continue; } + + TestCmd *cmd = NULL; + + if (strncmp(line, "exec ", 5) == 0) + { + cmd = make_cmd(CMD_EXEC); + char *rest = line + 5; + while (*rest == ' ' || *rest == '\t') rest++; + /* first token = service, rest = args */ + sscanf(rest, "%63s", cmd->service); + char *sp = rest + strlen(cmd->service); + while (*sp == ' ' || *sp == '\t') sp++; + strncpy(cmd->args, sp, sizeof(cmd->args) - 1); + } + else if (strncmp(line, "wait until ", 11) == 0) + { + cmd = make_cmd(CMD_WAIT_STATE); + cmd->timeoutSeconds = PGAF_TIMEOUT_DEFAULT; + char node[64], kw1[32], eq[4], state[64]; + char *rest = line + 11; + int n = sscanf(rest, "%63s %31s %3s %63s", node, kw1, eq, state); + if (n < 4) { fprintf(stderr,"bad wait until: %s\n",line); exit(1); } + strncpy(cmd->service, node, sizeof(cmd->service)-1); + strncpy(cmd->state, state, sizeof(cmd->state)-1); + /* check for "timeout Ns" suffix */ + char *tp = strstr(rest, "timeout "); + if (tp) cmd->timeoutSeconds = atoi(tp + 8); + + /* assigned-state variant */ + if (strcmp(kw1, "assigned-state") == 0) + cmd->kind = CMD_ASSERT_ASSIGNED; + } + else if (strncmp(line, "assert ", 7) == 0) + { + char node[64], kw[32], eq[4], state[64]; + char *rest = line + 7; + sscanf(rest, "%63s %31s %3s %63s", node, kw, eq, state); + if (strcmp(kw, "assigned-state") == 0) + cmd = make_cmd(CMD_ASSERT_ASSIGNED); + else + cmd = make_cmd(CMD_ASSERT_STATE); + strncpy(cmd->service, node, sizeof(cmd->service)-1); + strncpy(cmd->state, state, sizeof(cmd->state)-1); + } + else if (strncmp(line, "sql ", 4) == 0) + { + cmd = make_cmd(CMD_SQL); + char *rest = line + 4; + while (*rest == ' ' || *rest == '\t') rest++; + sscanf(rest, "%63s", cmd->service); + char *q = rest + strlen(cmd->service); + while (*q == ' ' || *q == '\t') q++; + if (*q == '{') + collect_block_content(q, cmd->args, sizeof(cmd->args)); + else + strncpy(cmd->args, q, sizeof(cmd->args)-1); + } + else if (strncmp(line, "expect ", 7) == 0) + { + cmd = make_cmd(CMD_EXPECT); + char *rest = line + 7; + while (*rest == ' ' || *rest == '\t') rest++; + if (*rest == '{') + collect_block_content(rest, cmd->expected, sizeof(cmd->expected)); + else + strncpy(cmd->expected, rest, sizeof(cmd->expected)-1); + } + else if (strncmp(line, "network disconnect ", 19) == 0) + { + cmd = make_cmd(CMD_NETWORK_OFF); + strncpy(cmd->service, line + 19, sizeof(cmd->service)-1); + } + else if (strncmp(line, "network connect ", 16) == 0) + { + cmd = make_cmd(CMD_NETWORK_ON); + strncpy(cmd->service, line + 16, sizeof(cmd->service)-1); + } + else if (strncmp(line, "sleep ", 6) == 0) + { + cmd = make_cmd(CMD_SLEEP); + cmd->timeoutSeconds = atoi(line + 6); + } + else if (strcmp(line, "compose down") == 0 || + strncmp(line, "compose down", 12) == 0) + { + cmd = make_cmd(CMD_COMPOSE_DOWN); + } + else + { + fprintf(stderr, "pgaftest: unknown command: %s\n", line); + exit(1); + } + + if (cmd) append_cmd(step, cmd); + line = strtok(NULL, "\n"); + } + free(text); + (yyval.step) = step; + ;} + break; + + case 16: +#line 420 "test_spec_parse.y" + { + int i = current_spec->sequenceLength; + if (i < PGAF_MAX_SEQ) + current_spec->sequence[current_spec->sequenceLength++] = (yyvsp[(2) - (2)].str); + else + { + fprintf(stderr, "pgaftest: too many steps in sequence (max %d)\n", + PGAF_MAX_SEQ); + exit(1); + } + ;} + break; + + case 17: +#line 438 "test_spec_parse.y" + { (yyval.str) = (yyvsp[(1) - (1)].str); ;} + break; + + case 18: +#line 439 "test_spec_parse.y" + { (yyval.str) = (yyvsp[(1) - (1)].str); ;} + break; + + +/* Line 1267 of yacc.c. */ +#line 1783 "test_spec_parse.c" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +#line 442 "test_spec_parse.y" + + +/* ----------------------------------------------------------------------- + * Public entry point + * ----------------------------------------------------------------------- */ + +TestSpec * +parse_test_spec(const char *filename) +{ + FILE *f = fopen(filename, "r"); + if (!f) + { + fprintf(stderr, "pgaftest: cannot open spec file \"%s\": %s\n", + filename, strerror(errno)); + return NULL; + } + + TestSpec *spec = (TestSpec *) calloc(1, sizeof(TestSpec)); + if (!spec) { fprintf(stderr, "out of memory\n"); exit(1); } + + strncpy(spec->filename, filename, sizeof(spec->filename)-1); + spec->cluster.numSync = -1; + + current_spec = spec; + pgaf_line_number = 1; + yyin = f; + yyparse(); + fclose(f); + + return spec; +} + +/* helpers used by the grammar and runner */ + +TestCmd * +make_cmd(TestCmdKind kind) +{ + TestCmd *c = (TestCmd *) calloc(1, sizeof(TestCmd)); + if (!c) { fprintf(stderr, "out of memory\n"); exit(1); } + c->kind = kind; + c->timeoutSeconds = PGAF_TIMEOUT_DEFAULT; + return c; +} + +TestStep * +make_step(const char *name) +{ + TestStep *s = (TestStep *) calloc(1, sizeof(TestStep)); + if (!s) { fprintf(stderr, "out of memory\n"); exit(1); } + if (name) strncpy(s->name, name, sizeof(s->name)-1); + return s; +} + +TestStep * +spec_find_step(TestSpec *spec, const char *name) +{ + for (TestStep *s = spec->steps; s; s = s->next) + { + if (strcmp(s->name, name) == 0) + return s; + } + return NULL; +} + diff --git a/src/bin/pgaftest/test_spec_parse.h b/src/bin/pgaftest/test_spec_parse.h new file mode 100644 index 000000000..739fbb4d6 --- /dev/null +++ b/src/bin/pgaftest/test_spec_parse.h @@ -0,0 +1,131 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_CLUSTER = 258, + T_MONITOR = 259, + T_NODE = 260, + T_CITUS_COORDINATOR = 261, + T_CITUS_WORKER = 262, + T_SETUP = 263, + T_TEARDOWN = 264, + T_STEP = 265, + T_SEQUENCE = 266, + T_EXEC = 267, + T_WAIT = 268, + T_UNTIL = 269, + T_TIMEOUT = 270, + T_ASSERT = 271, + T_SQL = 272, + T_EXPECT = 273, + T_NETWORK = 274, + T_DISCONNECT = 275, + T_CONNECT = 276, + T_SLEEP = 277, + T_COMPOSE = 278, + T_DOWN = 279, + T_STATE = 280, + T_ASSIGNED_STATE = 281, + T_CANDIDATE_PRIORITY = 282, + T_GROUP = 283, + T_ASYNC = 284, + T_EQUALS = 285, + T_INTEGER = 286, + T_IDENT = 287, + T_STRING = 288, + T_BLOCK = 289 + }; +#endif +/* Tokens. */ +#define T_CLUSTER 258 +#define T_MONITOR 259 +#define T_NODE 260 +#define T_CITUS_COORDINATOR 261 +#define T_CITUS_WORKER 262 +#define T_SETUP 263 +#define T_TEARDOWN 264 +#define T_STEP 265 +#define T_SEQUENCE 266 +#define T_EXEC 267 +#define T_WAIT 268 +#define T_UNTIL 269 +#define T_TIMEOUT 270 +#define T_ASSERT 271 +#define T_SQL 272 +#define T_EXPECT 273 +#define T_NETWORK 274 +#define T_DISCONNECT 275 +#define T_CONNECT 276 +#define T_SLEEP 277 +#define T_COMPOSE 278 +#define T_DOWN 279 +#define T_STATE 280 +#define T_ASSIGNED_STATE 281 +#define T_CANDIDATE_PRIORITY 282 +#define T_GROUP 283 +#define T_ASYNC 284 +#define T_EQUALS 285 +#define T_INTEGER 286 +#define T_IDENT 287 +#define T_STRING 288 +#define T_BLOCK 289 + + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 148 "test_spec_parse.y" +{ + int ival; + char *str; + TestStep *step; + TestCmd *cmd; +} +/* Line 1529 of yacc.c. */ +#line 124 "test_spec_parse.h" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE yylval; + diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y index 827f4fa8c..6c9e8b868 100644 --- a/src/bin/pgaftest/test_spec_parse.y +++ b/src/bin/pgaftest/test_spec_parse.y @@ -44,6 +44,90 @@ static void append_cmd(TestStep *step, TestCmd *cmd) } } +/* + * Collect content from a `{ ... }` block that may span multiple lines. + * + * `src` points to the `{` character (already the first char of the argument). + * For the inline case `{ content }`, the closing `}` is on the same string. + * For the multi-line case `{\n line1\n line2\n}`, subsequent lines are + * fetched with strtok(NULL, "\n") which continues the caller's split. + * + * The collected content (without surrounding braces) is written into `out`. + */ +static void +collect_block_content(const char *src, char *out, int outlen) +{ + /* skip '{' and leading whitespace */ + src++; + while (*src == ' ' || *src == '\t') src++; + + /* Inline single-line: { content } — closing } on the same string */ + const char *close = strchr(src, '}'); + if (close) + { + int len = (int)(close - src); + /* trim trailing whitespace before } */ + while (len > 0 && (src[len-1] == ' ' || src[len-1] == '\t')) + len--; + if (len >= outlen) len = outlen - 1; + memcpy(out, src, len); + out[len] = '\0'; + return; + } + + /* + * Multi-line form: content starts on remaining of same line (may be empty) + * then continues on subsequent lines until a line that is just `}`. + */ + int pos = 0; + + /* remainder of current line after `{` */ + if (*src) + { + int l = strlen(src); + /* trim trailing whitespace */ + while (l > 0 && (src[l-1] == '\r' || src[l-1] == '\n' || + src[l-1] == ' ' || src[l-1] == '\t')) + l--; + if (l > 0) + { + if (l >= outlen - 1) l = outlen - 1; + memcpy(out, src, l); + pos = l; + out[pos] = '\0'; + } + } + + char *nxtline; + while ((nxtline = strtok(NULL, "\n")) != NULL) + { + /* skip leading whitespace */ + char *p = nxtline; + while (*p == ' ' || *p == '\t') p++; + + /* closing brace line */ + if (*p == '}' && (p[1] == '\0' || p[1] == ' ' || p[1] == '\t')) + break; + + /* append a newline separator if we already have content */ + if (pos > 0 && pos < outlen - 1) + out[pos++] = '\n'; + + int l = strlen(p); + /* trim trailing CR/LF */ + while (l > 0 && (p[l-1] == '\r' || p[l-1] == '\n')) l--; + + if (pos + l >= outlen) + l = outlen - pos - 1; + if (l > 0) + { + memcpy(out + pos, p, l); + pos += l; + } + out[pos] = '\0'; + } +} + static void register_step(TestSpec *spec, TestStep *step) { if (!spec->steps) @@ -268,21 +352,25 @@ cmd_block: else if (strncmp(line, "sql ", 4) == 0) { cmd = make_cmd(CMD_SQL); - /* sql { SQL } — but the { } was already consumed by the - * outer block parser; here we just have the inline form - * sql or sql { multi-line } - * For simplicity we treat everything after svc as the query. */ char *rest = line + 4; while (*rest == ' ' || *rest == '\t') rest++; sscanf(rest, "%63s", cmd->service); char *q = rest + strlen(cmd->service); while (*q == ' ' || *q == '\t') q++; - strncpy(cmd->args, q, sizeof(cmd->args)-1); + if (*q == '{') + collect_block_content(q, cmd->args, sizeof(cmd->args)); + else + strncpy(cmd->args, q, sizeof(cmd->args)-1); } else if (strncmp(line, "expect ", 7) == 0) { cmd = make_cmd(CMD_EXPECT); - strncpy(cmd->expected, line + 7, sizeof(cmd->expected)-1); + char *rest = line + 7; + while (*rest == ' ' || *rest == '\t') rest++; + if (*rest == '{') + collect_block_content(rest, cmd->expected, sizeof(cmd->expected)); + else + strncpy(cmd->expected, rest, sizeof(cmd->expected)-1); } else if (strncmp(line, "network disconnect ", 19) == 0) { diff --git a/src/bin/pgaftest/test_spec_scan.c b/src/bin/pgaftest/test_spec_scan.c new file mode 100644 index 000000000..b14f321ec --- /dev/null +++ b/src/bin/pgaftest/test_spec_scan.c @@ -0,0 +1,2062 @@ +#line 1 "test_spec_scan.c" + +#line 3 "test_spec_scan.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, yy_size_t len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap() (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (yy_size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 37 +#define YY_END_OF_BUFFER 38 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[190] = + { 0, + 0, 0, 0, 0, 38, 36, 35, 34, 36, 1, + 30, 29, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 33, 37, 35, 0, 32, 1, + 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 16, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 23, 11, 31, + 31, 31, 31, 4, 31, 31, 31, 31, 9, 31, + + 31, 31, 12, 31, 31, 28, 31, 31, 31, 31, + 31, 31, 31, 27, 31, 31, 31, 7, 21, 24, + 31, 31, 13, 15, 31, 31, 31, 31, 31, 31, + 31, 17, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 2, 22, 20, 31, 3, 18, 31, 31, 14, + 31, 31, 31, 31, 31, 10, 8, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 19, 31, 31, 31, + 31, 31, 31, 31, 6, 31, 31, 31, 25, 31, + 31, 31, 31, 31, 31, 31, 5, 26, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 4, 5, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 6, 1, 1, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, + 8, 1, 1, 1, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 10, 9, 9, 9, 9, 9, 9, 9, + 1, 1, 1, 1, 9, 1, 11, 9, 12, 13, + + 14, 9, 15, 9, 16, 9, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 9, 28, 29, + 30, 9, 31, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static const YY_CHAR yy_meta[32] = + { 0, + 1, 1, 2, 1, 1, 3, 3, 1, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1 + } ; + +static const flex_int16_t yy_base[194] = + { 0, + 0, 0, 0, 0, 206, 207, 203, 207, 200, 0, + 25, 207, 0, 178, 22, 18, 173, 177, 179, 23, + 28, 31, 179, 187, 207, 207, 195, 192, 207, 0, + 42, 207, 0, 11, 175, 168, 166, 36, 167, 163, + 39, 169, 169, 162, 174, 34, 172, 167, 48, 173, + 164, 156, 165, 49, 160, 166, 151, 152, 154, 155, + 162, 153, 160, 157, 143, 153, 140, 153, 139, 138, + 150, 0, 137, 140, 137, 146, 143, 132, 133, 141, + 143, 138, 128, 126, 130, 136, 128, 0, 0, 136, + 125, 120, 124, 0, 130, 121, 120, 127, 0, 127, + + 118, 120, 0, 111, 116, 0, 122, 128, 119, 107, + 119, 110, 103, 0, 107, 103, 106, 0, 0, 0, + 104, 97, 0, 0, 109, 111, 36, 97, 106, 93, + 98, 0, 93, 99, 103, 86, 87, 99, 85, 89, + 88, 0, 0, 0, 94, 0, 0, 93, 86, 0, + 99, 90, 82, 78, 89, 0, 0, 75, 93, 74, + 80, 70, 69, 72, 80, 78, 0, 80, 66, 73, + 64, 61, 70, 65, 0, 70, 62, 71, 0, 57, + 54, 63, 57, 51, 51, 36, 0, 0, 207, 67, + 70, 73, 55 + + } ; + +static const flex_int16_t yy_def[194] = + { 0, + 189, 1, 190, 190, 189, 189, 189, 189, 191, 192, + 189, 189, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 189, 189, 189, 191, 189, 192, + 189, 189, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 0, 189, + 189, 189, 189 + + } ; + +static const flex_int16_t yy_nxt[239] = + { 0, + 6, 7, 8, 9, 10, 6, 11, 12, 13, 13, + 14, 15, 16, 17, 18, 13, 13, 13, 19, 20, + 13, 13, 13, 13, 21, 22, 23, 24, 13, 13, + 25, 31, 35, 39, 32, 54, 44, 36, 40, 37, + 55, 46, 38, 45, 50, 47, 51, 140, 31, 32, + 48, 32, 63, 49, 59, 60, 69, 33, 73, 70, + 64, 74, 79, 141, 80, 188, 32, 26, 26, 26, + 28, 28, 28, 30, 187, 30, 186, 185, 184, 183, + 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, + 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, + + 162, 161, 160, 159, 158, 157, 156, 155, 154, 153, + 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, + 142, 139, 138, 137, 136, 135, 134, 133, 132, 131, + 130, 129, 128, 127, 126, 125, 124, 123, 122, 121, + 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, + 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, + 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, + 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, + 78, 77, 76, 75, 72, 71, 68, 67, 66, 65, + 62, 61, 58, 57, 56, 29, 27, 53, 52, 43, + + 42, 41, 34, 29, 27, 189, 5, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189 + } ; + +static const flex_int16_t yy_chk[239] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 11, 15, 16, 11, 34, 20, 15, 16, 15, + 34, 21, 15, 20, 22, 21, 22, 127, 31, 11, + 21, 31, 41, 21, 38, 38, 46, 193, 49, 46, + 41, 49, 54, 127, 54, 186, 31, 190, 190, 190, + 191, 191, 191, 192, 185, 192, 184, 183, 182, 181, + 180, 178, 177, 176, 174, 173, 172, 171, 170, 169, + 168, 166, 165, 164, 163, 162, 161, 160, 159, 158, + + 155, 154, 153, 152, 151, 149, 148, 145, 141, 140, + 139, 138, 137, 136, 135, 134, 133, 131, 130, 129, + 128, 126, 125, 122, 121, 117, 116, 115, 113, 112, + 111, 110, 109, 108, 107, 105, 104, 102, 101, 100, + 98, 97, 96, 95, 93, 92, 91, 90, 87, 86, + 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, + 75, 74, 73, 71, 70, 69, 68, 67, 66, 65, + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, + 53, 52, 51, 50, 48, 47, 45, 44, 43, 42, + 40, 39, 37, 36, 35, 28, 27, 24, 23, 19, + + 18, 17, 14, 9, 7, 5, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "test_spec_scan.l" +#line 2 "test_spec_scan.l" +/* + * src/bin/pgaftest/test_spec_scan.l + * Flex lexer for .pgaf test specification files. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include "test_spec.h" +#include "test_spec_parse.h" + +/* track line number for error messages */ +int pgaf_line_number = 1; + +static char *pgaf_strdup(const char *s) +{ + char *r = strdup(s); + if (!r) { fprintf(stderr, "out of memory\n"); exit(1); } + return r; +} +#line 581 "test_spec_scan.c" +/* multi-line SQL/text block: { ... } */ + +#line 584 "test_spec_scan.c" + +#define INITIAL 0 +#define BLOCK 1 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + yy_size_t yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + yy_size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 32 "test_spec_scan.l" + + +#line 803 "test_spec_scan.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 190 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_current_state != 189 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 34 "test_spec_scan.l" +{ /* single-line comment, skip */ } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 36 "test_spec_scan.l" +{ return T_CLUSTER; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 37 "test_spec_scan.l" +{ return T_MONITOR; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 38 "test_spec_scan.l" +{ return T_NODE; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 39 "test_spec_scan.l" +{ return T_CITUS_COORDINATOR; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 40 "test_spec_scan.l" +{ return T_CITUS_WORKER; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 42 "test_spec_scan.l" +{ return T_SETUP; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 43 "test_spec_scan.l" +{ return T_TEARDOWN; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 44 "test_spec_scan.l" +{ return T_STEP; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 45 "test_spec_scan.l" +{ return T_SEQUENCE; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 47 "test_spec_scan.l" +{ return T_EXEC; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 48 "test_spec_scan.l" +{ return T_WAIT; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 49 "test_spec_scan.l" +{ return T_UNTIL; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 50 "test_spec_scan.l" +{ return T_TIMEOUT; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 51 "test_spec_scan.l" +{ return T_ASSERT; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 52 "test_spec_scan.l" +{ return T_SQL; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 53 "test_spec_scan.l" +{ return T_EXPECT; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 54 "test_spec_scan.l" +{ return T_NETWORK; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 55 "test_spec_scan.l" +{ return T_DISCONNECT; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 56 "test_spec_scan.l" +{ return T_CONNECT; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 57 "test_spec_scan.l" +{ return T_SLEEP; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 58 "test_spec_scan.l" +{ return T_COMPOSE; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 59 "test_spec_scan.l" +{ return T_DOWN; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 61 "test_spec_scan.l" +{ return T_STATE; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 62 "test_spec_scan.l" +{ return T_ASSIGNED_STATE; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 63 "test_spec_scan.l" +{ return T_CANDIDATE_PRIORITY; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 64 "test_spec_scan.l" +{ return T_GROUP; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 65 "test_spec_scan.l" +{ return T_ASYNC; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 67 "test_spec_scan.l" +{ return T_EQUALS; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 69 "test_spec_scan.l" +{ + /* integer, optionally followed by 's' for seconds */ + yylval.ival = atoi(yytext); + return T_INTEGER; +} + YY_BREAK +case 31: +YY_RULE_SETUP +#line 75 "test_spec_scan.l" +{ + yylval.str = pgaf_strdup(yytext); + return T_IDENT; +} + YY_BREAK +case 32: +/* rule 32 can match eol */ +YY_RULE_SETUP +#line 80 "test_spec_scan.l" +{ + /* quoted string: strip surrounding quotes */ + yytext[yyleng-1] = '\0'; + yylval.str = pgaf_strdup(yytext + 1); + return T_STRING; +} + YY_BREAK +case 33: +YY_RULE_SETUP +#line 87 "test_spec_scan.l" +{ + /* start of a brace block — collect everything until matching } */ + int depth = 1; + int c; + char buf[65536]; + int pos = 0; + + while (depth > 0 && (c = input()) != EOF) + { + if (c == '{') depth++; + else if (c == '}') { depth--; if (depth == 0) break; } + else if (c == '\n') pgaf_line_number++; + if (depth > 0) + { + if (pos < (int)sizeof(buf) - 1) + buf[pos++] = (char)c; + } + } + buf[pos] = '\0'; + + /* trim leading/trailing whitespace */ + char *start = buf; + while (*start == ' ' || *start == '\t' || *start == '\n' || *start == '\r') + start++; + char *end = start + strlen(start); + while (end > start && (end[-1]==' ' || end[-1]=='\t' || + end[-1]=='\n' || end[-1]=='\r')) + end--; + *end = '\0'; + + yylval.str = pgaf_strdup(start); + return T_BLOCK; +} + YY_BREAK +case 34: +/* rule 34 can match eol */ +YY_RULE_SETUP +#line 121 "test_spec_scan.l" +{ pgaf_line_number++; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 122 "test_spec_scan.l" +{ /* whitespace */ } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 124 "test_spec_scan.l" +{ + fprintf(stderr, "pgaftest: unexpected character '%c' at line %d\n", + yytext[0], pgaf_line_number); +} + YY_BREAK +case 37: +YY_RULE_SETUP +#line 129 "test_spec_scan.l" +ECHO; + YY_BREAK +#line 1090 "test_spec_scan.c" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(BLOCK): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 190 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 190 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 189); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + yy_size_t i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yy_size_t yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +yy_size_t yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 129 "test_spec_scan.l" + + diff --git a/tests/tap/README.md b/tests/tap/README.md new file mode 100644 index 000000000..f144aff86 --- /dev/null +++ b/tests/tap/README.md @@ -0,0 +1,137 @@ +# pg_auto_failover TAP Test Suite + +Tests are written in the `.pgaf` spec DSL and run by the `pgaftest` binary. Output is [TAP](https://testanything.org/) (Test Anything Protocol), compatible with `prove` and any TAP harness. + +## Prerequisites + +- `pgaftest` built: `make -C src/bin` +- Docker with the Compose plugin (`docker compose version`) +- PostgreSQL client tools on `PATH` + +## Running tests + +### All tests (via schedule) + +```sh +pgaftest run --schedule tests/tap/schedule +``` + +This runs every spec listed in `tests/tap/schedule` in order and emits TAP on stdout. Exit code is 0 only when all tests pass. + +With `prove` for a formatted summary: + +```sh +pgaftest run --schedule tests/tap/schedule | prove --tap - +``` + +### A single spec + +```sh +pgaftest run tests/tap/specs/basic_operation.pgaf +``` + +### Interactive mode (live cluster, shell access) + +Brings up the cluster defined in the spec, runs the `setup{}` block, then drops you into a shell with the cluster running: + +```sh +pgaftest setup tests/tap/specs/basic_operation.pgaf +``` + +Run individual steps against the live cluster: + +```sh +pgaftest step stop_primary +pgaftest step check_failover +``` + +Tear down when done: + +```sh +pgaftest down +``` + +## Spec file format + +Each `.pgaf` file in `specs/` describes a complete test scenario: + +``` +cluster { + monitor + node node1 + node node2 candidate-priority=0 +} + +setup { + wait until node1 state = primary timeout 60s + wait until node2 state = secondary timeout 60s +} + +teardown { + compose down +} + +step stop_primary { + exec node1 pg_autoctl stop postgres +} + +step check_failover { + wait until node2 state = primary timeout 90s + assert node2 state = primary +} + +sequence + stop_primary + check_failover +``` + +| Block | Purpose | +|---|---| +| `cluster {}` | Topology — drives `docker-compose.yml` generation | +| `setup {}` | Run after `compose up`, before the first step | +| `teardown {}` | Always run at end (CI); on-demand in interactive mode | +| `step name {}` | Named command block | +| `sequence` | Step execution order for CI (`pgaftest run`) | + +### Commands inside blocks + +| Command | Effect | +|---|---| +| `exec ` | `docker compose exec ` | +| `wait until state = [timeout Ns]` | Poll monitor; fail on timeout | +| `assert state = ` | Fail immediately if state doesn't match | +| `assert assigned-state = ` | Check `assigned_state` column | +| `sql { SQL }` | Run SQL on node, capture result | +| `expect { text }` | Compare last `sql` output | +| `network disconnect ` | `docker network disconnect` | +| `network connect ` | `docker network connect` | +| `sleep Ns` | Wait N seconds | +| `compose down` | `docker compose down --volumes` | + +## Schedule file + +`tests/tap/schedule` lists one spec name per line (no path, no extension). Lines starting with `#` are comments. + +``` +basic_operation +auth +multi_standbys +... +# citus_basic # requires Citus image +``` + +## CI integration + +```yaml +- name: Run pg_auto_failover tests + run: | + make -C src/bin + pgaftest run --schedule tests/tap/schedule | tee tap.out + grep -qE '^(not ok|Bail out)' tap.out && exit 1 || exit 0 +``` + +Or use `prove`: + +```yaml +- run: pgaftest run --schedule tests/tap/schedule | prove --tap - +``` diff --git a/tests/tap/specs/basic_operation.pgaf b/tests/tap/specs/basic_operation.pgaf index 5302cfaef..754b2fd6c 100644 --- a/tests/tap/specs/basic_operation.pgaf +++ b/tests/tap/specs/basic_operation.pgaf @@ -1,25 +1,33 @@ # tests/tap/specs/basic_operation.pgaf # # Basic two-node HA: create primary + secondary, test maintenance, -# failover, network partition detection, node drop and re-add. +# failover, network partition detection, and node drop. # # Ported from tests/test_basic_operation.py +# +# Node IDs are deterministic because node2's container depends_on node1 +# (see compose_gen.c), so node1 always registers first and gets nodeid=1, +# node2 gets nodeid=2. Replication slot names embed the standby's nodeid: +# node2's slot on node1: pgautofailover_standby_2 +# node1's slot on node2: pgautofailover_standby_1 cluster { monitor node node1 - node node2 candidate-priority=0 + node node2 } setup { - wait until node1 state = primary timeout 60s - wait until node2 state = secondary timeout 60s + wait until node1 state = primary timeout 120s + wait until node2 state = secondary timeout 120s } teardown { compose down } +# ------------------------------------------------------------------ +# test_003: create table and verify replication # ------------------------------------------------------------------ step create_table { @@ -31,12 +39,38 @@ step create_table { expect { 2 } } +# test_004: verify SSN and replication slots after secondary joins. +step verify_initial_setup { + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2) } + sql node1 { + SELECT slot_name FROM pg_replication_slots + WHERE slot_name ~ '^pgautofailover_standby_' AND slot_type = 'physical' + ORDER BY slot_name; + } + expect { pgautofailover_standby_2 } + sql node2 { + SELECT slot_name FROM pg_replication_slots + WHERE slot_name ~ '^pgautofailover_standby_' AND slot_type = 'physical' + ORDER BY slot_name; + } + expect { pgautofailover_standby_1 } +} + +# test_005: read from secondary step verify_read_from_secondary { sql node2 { SELECT * FROM t1 ORDER BY a; } - expect { 1 -2 } + expect { +1 +2 +} } +# ------------------------------------------------------------------ +# test_007: maintenance on primary with --allow-failover +# After: node1=maintenance, node2=wait_primary +# ------------------------------------------------------------------ + step maintenance_primary_allow_failover { exec node1 pg_autoctl enable maintenance --allow-failover wait until node1 state = maintenance timeout 60s @@ -45,14 +79,20 @@ step maintenance_primary_allow_failover { expect { } } +# test_007_005: disable maintenance, node1 rejoins as secondary, +# node2 stays primary. After: node1=secondary, node2=primary step disable_maintenance_rejoin { exec node1 pg_autoctl disable maintenance - wait until node1 state = secondary timeout 60s - wait until node2 state = primary timeout 60s + wait until node1 state = secondary timeout 90s + wait until node2 state = primary timeout 90s sql node2 { SHOW synchronous_standby_names; } expect { ANY 1 (pgautofailover_standby_1) } } +# ------------------------------------------------------------------ +# test_008: maintenance on secondary (node1 is now secondary) +# ------------------------------------------------------------------ + step maintenance_secondary { exec node1 pg_autoctl enable maintenance wait until node1 state = maintenance timeout 60s @@ -60,20 +100,76 @@ step maintenance_secondary { sql node2 { INSERT INTO t1 VALUES (3); } } +# test_008_002: disable maintenance, node1 rejoins, check SSN. +# After: node1=secondary, node2=primary step disable_maintenance_secondary { exec node1 pg_autoctl disable maintenance - wait until node1 state = secondary timeout 60s - wait until node2 state = primary timeout 60s + wait until node1 state = secondary timeout 90s + wait until node2 state = primary timeout 90s + sql node2 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1) } } +# ------------------------------------------------------------------ +# test_009: failback to node1 (node2 is current primary) +# After: node1=primary, node2=secondary +# ------------------------------------------------------------------ + step failback_to_node1 { - exec monitor pg_autoctl perform failover + exec monitor pg_autoctl perform promotion --name node1 wait until node2 state = secondary timeout 90s wait until node1 state = primary timeout 90s sql node1 { SHOW synchronous_standby_names; } expect { ANY 1 (pgautofailover_standby_2) } } +# ------------------------------------------------------------------ +# test_020: multiple manual failovers, verify replication slots survive. +# Entry: node1=primary, node2=secondary +# ------------------------------------------------------------------ + +step multiple_failovers { + exec monitor pg_autoctl perform promotion --name node2 + wait until node2 state = primary timeout 90s + wait until node1 state = secondary timeout 90s + sql node2 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1) } + sql node2 { + SELECT slot_name FROM pg_replication_slots + WHERE slot_name ~ '^pgautofailover_standby_' AND slot_type = 'physical' + ORDER BY slot_name; + } + expect { pgautofailover_standby_1 } + sql node1 { + SELECT slot_name FROM pg_replication_slots + WHERE slot_name ~ '^pgautofailover_standby_' AND slot_type = 'physical' + ORDER BY slot_name; + } + expect { pgautofailover_standby_2 } + exec monitor pg_autoctl perform promotion --name node1 + wait until node1 state = primary timeout 90s + wait until node2 state = secondary timeout 90s + sql node1 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_2) } + sql node1 { + SELECT slot_name FROM pg_replication_slots + WHERE slot_name ~ '^pgautofailover_standby_' AND slot_type = 'physical' + ORDER BY slot_name; + } + expect { pgautofailover_standby_2 } + sql node2 { + SELECT slot_name FROM pg_replication_slots + WHERE slot_name ~ '^pgautofailover_standby_' AND slot_type = 'physical' + ORDER BY slot_name; + } + expect { pgautofailover_standby_1 } +} + +# ------------------------------------------------------------------ +# test_010: disconnect primary (node1), node2 takes over +# After: node2=wait_primary +# ------------------------------------------------------------------ + step fail_primary { network disconnect node1 wait until node2 state = wait_primary timeout 90s @@ -82,65 +178,84 @@ step fail_primary { step writes_to_new_primary { sql node2 { INSERT INTO t1 VALUES (4); } sql node2 { SELECT * FROM t1 ORDER BY a; } - expect { 1 + expect { +1 2 3 -4 } +4 +} } +# test_012: reconnect node1, it rejoins as secondary; check SSN. +# After: node2=primary, node1=secondary step restart_node1 { network connect node1 wait until node2 state = primary timeout 90s wait until node1 state = secondary timeout 90s + sql node2 { SHOW synchronous_standby_names; } + expect { ANY 1 (pgautofailover_standby_1) } } +# test_013: read data from new secondary (node1) step read_from_new_secondary { sql node1 { SELECT * FROM t1 ORDER BY a; } - expect { 1 + expect { +1 2 3 -4 } +4 } +} + +# ------------------------------------------------------------------ +# test_016: drop secondary (node1), node2 becomes single. +# Verify no replication slots remain on node2. +# ------------------------------------------------------------------ step drop_secondary { - exec node1 pg_autoctl drop node --destroy - wait until node2 state = single timeout 60s + exec node1 pg_autoctl drop node --name node1 --destroy + wait until node2 state = single timeout 90s + sql node2 { + SELECT slot_name FROM pg_replication_slots + WHERE slot_name ~ '^pgautofailover_standby_' AND slot_type = 'physical' + ORDER BY slot_name; + } + expect { } } -step multiple_failovers { - exec monitor pg_autoctl perform failover - wait until node2 state = secondary timeout 90s - wait until node1 state = primary timeout 90s - exec monitor pg_autoctl perform promotion --nodename node2 - wait until node2 state = primary timeout 90s - wait until node1 state = secondary timeout 90s -} +# ------------------------------------------------------------------ +# test_024: stop monitor's PostgreSQL, verify pg_autoctl restarts it +# and the remaining data node keeps its state. +# ------------------------------------------------------------------ step stop_monitor_postgres { exec monitor pg_ctl stop -D /var/lib/postgres/pgaf -m fast sleep 5s - wait until monitor state = primary timeout 30s - wait until node1 state = secondary timeout 60s + wait until node2 state = single timeout 60s } +# ------------------------------------------------------------------ +# Drop the last remaining data node. +# ------------------------------------------------------------------ + step drop_primary { - exec node1 pg_autoctl drop node --destroy - wait until node2 state = single timeout 60s + exec node2 pg_autoctl drop node --name node2 --destroy } sequence create_table + verify_initial_setup verify_read_from_secondary maintenance_primary_allow_failover disable_maintenance_rejoin maintenance_secondary disable_maintenance_secondary failback_to_node1 + multiple_failovers fail_primary writes_to_new_primary restart_node1 read_from_new_secondary drop_secondary - multiple_failovers stop_monitor_postgres drop_primary From fac227f0198c3dc8c8db1c66fe5f819ab429eab2 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 05:24:44 +0200 Subject: [PATCH 06/48] pgaftest: increase fail_primary timeout to 120s for reliability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Docker network disconnect relies on TCP keepalive timeout detection. With wal_sender_timeout=30s, the full demote cycle (health-check failure → draining → demote_timeout → demoted → standby catchingup → wait_primary) can take 60–90s. 90s was sometimes not enough; 120s provides a safe margin. --- tests/tap/specs/basic_operation.pgaf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tap/specs/basic_operation.pgaf b/tests/tap/specs/basic_operation.pgaf index 754b2fd6c..0b8431278 100644 --- a/tests/tap/specs/basic_operation.pgaf +++ b/tests/tap/specs/basic_operation.pgaf @@ -172,7 +172,7 @@ step multiple_failovers { step fail_primary { network disconnect node1 - wait until node2 state = wait_primary timeout 90s + wait until node2 state = wait_primary timeout 120s } step writes_to_new_primary { From 22ab675f94d4bd4238b63c86e9c55d6d32c72ae6 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 13:42:31 +0200 Subject: [PATCH 07/48] pg_autoctl: replace 'do'/'override' with 'manual'; hide internal entry points MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Command-line split: pg_autoctl inspect — read-only diagnostics, safe on live nodes show / pgsetup unchanged monitor get + parse-notification ONLY (not register/active/version) service getpid ONLY (not restart — that mutates) pg_autoctl manual — operator-driven FSM operations (replaces 'override') fsm assign / step / nodes set service getpid + restart + pgctl on|off monitor register + active + version (ALTER EXTENSION) primary / standby / coordinator unchanged pg_autoctl do — hidden from --help; internal subprocess entry points only service postgres|listener|node-active|pgcontroller spawned by supervisor still routable so 'pg_autoctl do service node-active --pgdata …' works commandline framework: - Add 'bool hidden' field to CommandLine struct - Add make_hidden_command_set() macro - commandline_pretty_print_subcommands() skips hidden commands Why 'manual'? It is the antonym of 'automated' — the mental model central to pg_auto_failover. 'override' described a consequence; 'manual' describes who is acting (a human, by hand, instead of the FSM). Why fork+exec for the internal entry points? The supervisor restarts child processes via fork()+execve() so that when the pg_autoctl binary is updated in place (e.g. by a package manager), a restarted child picks up the new version without restarting the supervisor — which may be PID 1 in a Docker/Kubernetes container. The version-mismatch exit in keeper_check_monitor_extension_version() exploits this path intentionally. Comments added to service_keeper/monitor/postgres_ctl_runprogram(). --- src/bin/lib/subcommands.c/commandline.c | 6 ++ src/bin/lib/subcommands.c/commandline.h | 14 +++- src/bin/pg_autoctl/cli_do_monitor.c | 10 +-- src/bin/pg_autoctl/cli_do_root.c | 30 +++++++- src/bin/pg_autoctl/cli_do_root.h | 9 +++ src/bin/pg_autoctl/cli_inspect.c | 36 +++++++--- src/bin/pg_autoctl/cli_manual.c | 86 +++++++++++++++++++++++ src/bin/pg_autoctl/cli_manual.h | 16 +++++ src/bin/pg_autoctl/cli_override.c | 37 ---------- src/bin/pg_autoctl/cli_override.h | 16 ----- src/bin/pg_autoctl/cli_root.c | 6 +- src/bin/pg_autoctl/service_keeper.c | 11 +++ src/bin/pg_autoctl/service_monitor.c | 9 ++- src/bin/pg_autoctl/service_postgres_ctl.c | 4 ++ 14 files changed, 213 insertions(+), 77 deletions(-) create mode 100644 src/bin/pg_autoctl/cli_manual.c create mode 100644 src/bin/pg_autoctl/cli_manual.h delete mode 100644 src/bin/pg_autoctl/cli_override.c delete mode 100644 src/bin/pg_autoctl/cli_override.h diff --git a/src/bin/lib/subcommands.c/commandline.c b/src/bin/lib/subcommands.c/commandline.c index bd9eac138..f83c85ede 100644 --- a/src/bin/lib/subcommands.c/commandline.c +++ b/src/bin/lib/subcommands.c/commandline.c @@ -226,6 +226,9 @@ commandline_pretty_print_subcommands(CommandLine *command, FILE *stream) /* pretty printing: reduce maximum length of subcommand names */ for (subcommand = command->subcommands; *subcommand != NULL; subcommand++) { + if ((*subcommand)->hidden) + continue; + int len = strlen((*subcommand)->name); if (maxLength < len) @@ -238,6 +241,9 @@ commandline_pretty_print_subcommands(CommandLine *command, FILE *stream) { const char *description = ""; + if ((*subcommand)->hidden) + continue; + if ((*subcommand)->shortDescription != NULL) { description = (*subcommand)->shortDescription; diff --git a/src/bin/lib/subcommands.c/commandline.h b/src/bin/lib/subcommands.c/commandline.h index 888e58550..a0cb674b9 100644 --- a/src/bin/lib/subcommands.c/commandline.h +++ b/src/bin/lib/subcommands.c/commandline.h @@ -29,15 +29,25 @@ typedef struct CommandLine struct CommandLine **subcommands; char *breadcrumb; + bool hidden; /* if true, omit from --help output */ } CommandLine; extern CommandLine *current_command; #define make_command_set(name, desc, usage, help, getopt, set) \ - { name, desc, usage, help, getopt, NULL, set, NULL } + { name, desc, usage, help, getopt, NULL, set, NULL, false } #define make_command(name, desc, usage, help, getopt, run) \ - { name, desc, usage, help, getopt, run, NULL, NULL } + { name, desc, usage, help, getopt, run, NULL, NULL, false } + +/* + * Like make_command_set but the command is omitted from --help output. + * The command still routes normally when invoked explicitly — used for + * internal subprocess entry points that must remain in the binary but + * are not intended for direct operator use. + */ +#define make_hidden_command_set(name, desc, usage, help, getopt, set) \ + { name, desc, usage, help, getopt, NULL, set, NULL, true } bool commandline_run(CommandLine *command, int argc, char **argv); void commandline_help(FILE *stream); diff --git a/src/bin/pg_autoctl/cli_do_monitor.c b/src/bin/pg_autoctl/cli_do_monitor.c index f1dfb526c..65d9512c5 100644 --- a/src/bin/pg_autoctl/cli_do_monitor.c +++ b/src/bin/pg_autoctl/cli_do_monitor.c @@ -88,12 +88,12 @@ static CommandLine *monitor_get_commands[] = { NULL }; -static CommandLine monitor_get_command = +CommandLine monitor_get_command = make_command_set("get", "Get information from the monitor", NULL, NULL, NULL, monitor_get_commands); -static CommandLine monitor_register_command = +CommandLine monitor_register_command = make_command("register", "Register the current node with the monitor", CLI_PGDATA_USAGE "", @@ -101,7 +101,7 @@ static CommandLine monitor_register_command = cli_getopt_pgdata, cli_do_monitor_register_node); -static CommandLine monitor_node_active_command = +CommandLine monitor_node_active_command = make_command("active", "Call in the pg_auto_failover Node Active protocol", CLI_PGDATA_USAGE, @@ -109,7 +109,7 @@ static CommandLine monitor_node_active_command = cli_getopt_pgdata, cli_do_monitor_node_active); -static CommandLine monitor_version_command = +CommandLine monitor_version_command = make_command("version", "Check that monitor version is " PG_AUTOCTL_EXTENSION_VERSION @@ -119,7 +119,7 @@ static CommandLine monitor_version_command = cli_getopt_pgdata, cli_do_monitor_version); -static CommandLine monitor_parse_notification_command = +CommandLine monitor_parse_notification_command = make_command("parse-notification", "parse a raw notification message", " ", diff --git a/src/bin/pg_autoctl/cli_do_root.c b/src/bin/pg_autoctl/cli_do_root.c index 4cdff4e58..af5199527 100644 --- a/src/bin/pg_autoctl/cli_do_root.c +++ b/src/bin/pg_autoctl/cli_do_root.c @@ -582,10 +582,34 @@ CommandLine *do_subcommands[] = { NULL }; +/* + * pg_autoctl do service postgres|listener|node-active + * + * These are the subprocess entry points used by the supervisor (pg_autoctl run + * and pg_autoctl create … --run). The supervisor fork()s and then execv()s + * the pg_autoctl binary itself with one of these sub-commands so that each + * service runs in its own address space. + * + * Using fork+exec (rather than fork alone) is a deliberate design choice for + * live upgrades: when a child process exits with an incompatible monitor + * extension version, the supervisor restarts it via fork()+execv(), which loads + * the current binary from disk. If the binary has been updated in place (e.g. + * by a package manager), the restarted child automatically picks up the new + * version without touching the supervisor process — making pg_autoctl safe to + * use as PID 1 in Docker/Kubernetes containers where replacing the binary and + * sending SIGTERM would lose the container. + * + * See also: keeper.c keeper_check_monitor_extension_version(), which exits on + * version mismatch precisely to trigger this restart-with-new-binary path. + * + * These commands are hidden from --help output (make_hidden_command_set) so + * operators do not accidentally invoke them. Use "pg_autoctl manual service" + * for the user-facing service controls (getpid, restart, pgctl on/off). + */ CommandLine do_commands = - make_command_set("do", - "Internal commands and internal QA tooling", NULL, NULL, - NULL, do_subcommands); + make_hidden_command_set("do", + "Internal subprocess entry points — not for direct use", + NULL, NULL, NULL, do_subcommands); /* diff --git a/src/bin/pg_autoctl/cli_do_root.h b/src/bin/pg_autoctl/cli_do_root.h index 5db1cf347..db2592804 100644 --- a/src/bin/pg_autoctl/cli_do_root.h +++ b/src/bin/pg_autoctl/cli_do_root.h @@ -18,9 +18,18 @@ extern CommandLine do_fsm_commands; /* src/bin/pg_autoctl/cli_do_monitor.c */ extern CommandLine do_monitor_commands; +/* read-only sub-commands exposed via "pg_autoctl inspect monitor" */ +extern CommandLine monitor_get_command; +extern CommandLine monitor_parse_notification_command; +/* mutating sub-commands exposed via "pg_autoctl manual monitor" */ +extern CommandLine monitor_register_command; +extern CommandLine monitor_node_active_command; +extern CommandLine monitor_version_command; /* src/bin/pg_autoctl/cli_do_service.c */ extern CommandLine do_service_commands; +extern CommandLine do_service_getpid_commands; +extern CommandLine do_service_restart_commands; extern CommandLine do_service_postgres_ctl_commands; /* src/bin/pg_autoctl/cli_do_show.c */ diff --git a/src/bin/pg_autoctl/cli_inspect.c b/src/bin/pg_autoctl/cli_inspect.c index e18eae6c7..c07df6f2a 100644 --- a/src/bin/pg_autoctl/cli_inspect.c +++ b/src/bin/pg_autoctl/cli_inspect.c @@ -2,9 +2,12 @@ * src/bin/pg_autoctl/cli_inspect.c * pg_autoctl inspect — read-only diagnostics, always visible. * - * These commands read local or cluster state without mutating anything. + * All commands here read local or cluster state without mutating anything. * Safe to run at any time, even while `pg_autoctl run` is active. * + * For mutating recovery commands (fsm assign, standby promote, etc.) see + * cli_manual.c ("pg_autoctl manual …"). + * * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the PostgreSQL License. */ @@ -14,17 +17,32 @@ #include "cli_do_root.h" /* - * Aggregate the read-only do_* command sets under a single "inspect" group. - * We reference the existing command sets by address — do_show_commands, - * do_pgsetup_commands, etc. are extern CommandLine objects already declared - * in cli_do_root.h. + * Read-only monitor sub-commands: get primary/others/candidate-count/coordinator + * and parse-notification. We intentionally exclude "register", "active", and + * "version" (ALTER EXTENSION) which are mutating — those live under "manual". */ +static CommandLine *inspect_monitor_subcommands[] = { + &monitor_get_command, + &monitor_parse_notification_command, + NULL +}; + +static CommandLine inspect_monitor_commands = + make_command_set("monitor", + "Query the monitor's current state (read-only)", + NULL, NULL, NULL, inspect_monitor_subcommands); +/* + * Aggregate the read-only do_* command sets under "inspect". + * + * service here is only "getpid" — inspecting PIDs of running sub-processes. + * "restart" and "pgctl on/off" mutate state and belong under "manual service". + */ static CommandLine *inspect_subcommands[] = { - &do_show_commands, /* ipaddr / cidr / lookup / hostname / reverse */ - &do_pgsetup_commands, /* discover / ready / wait / logs / tune / pg_ctl */ - &do_monitor_commands, /* get primary|others / version / register / active */ - &do_service_commands, /* getpid postgres|listener|node-active */ + &do_show_commands, /* ipaddr / cidr / lookup / hostname / reverse */ + &do_pgsetup_commands, /* discover / ready / wait / logs / tune / pg_ctl */ + &inspect_monitor_commands, /* get primary|others|candidate-count + parse-notification */ + &do_service_getpid_commands, /* getpid postgres|listener|node-active */ NULL }; diff --git a/src/bin/pg_autoctl/cli_manual.c b/src/bin/pg_autoctl/cli_manual.c new file mode 100644 index 000000000..9957ebf9c --- /dev/null +++ b/src/bin/pg_autoctl/cli_manual.c @@ -0,0 +1,86 @@ +/* + * src/bin/pg_autoctl/cli_manual.c + * pg_autoctl manual — operator-driven FSM operations and low-level controls. + * + * These commands let an operator manually drive individual FSM transitions + * or low-level operations that pg_autoctl automation would normally own. + * Intended for manual recovery when the automated FSM is stopped or stuck, + * or for driving a live upgrade step-by-step. + * + * "manual" is the antonym of the automated behaviour pg_autoctl normally + * provides: you are doing by hand what the system would otherwise do for you. + * + * Read-only diagnostics belong in "pg_autoctl inspect". + * Internal subprocess entry points belong in "pg_autoctl do" (hidden). + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include "commandline.h" +#include "cli_manual.h" +#include "cli_do_root.h" + +/* + * manual service: user-visible service controls only. + * + * Intentionally excludes the internal subprocess entry points + * (pgcontroller / postgres / listener / node-active) which are spawned by the + * supervisor via fork+exec and are not meant for direct operator use. + * Those live under the hidden "pg_autoctl do service" group. + */ +static CommandLine *manual_service_subcommands[] = { + &do_service_getpid_commands, /* getpid postgres|listener|node-active */ + &do_service_restart_commands, /* restart postgres|listener|node-active */ + &do_service_postgres_ctl_commands, /* pgctl on|off */ + NULL +}; + +static CommandLine manual_service_commands = + make_command_set("service", + "Inspect or restart pg_autoctl sub-processes", + NULL, NULL, NULL, manual_service_subcommands); + +/* + * manual monitor: mutating monitor operations. + * + * "get" and "parse-notification" are read-only and live under + * "pg_autoctl inspect monitor". Here we expose only the mutating calls: + * + * register — manually step through the node registration protocol + * active — manually call the node_active RPC on the monitor + * version — check monitor extension version and ALTER EXTENSION UPDATE if needed + */ +static CommandLine *manual_monitor_subcommands[] = { + &monitor_register_command, + &monitor_node_active_command, + &monitor_version_command, + NULL +}; + +static CommandLine manual_monitor_commands = + make_command_set("monitor", + "Manually drive monitor RPCs (register / active / version)", + NULL, NULL, NULL, manual_monitor_subcommands); + +static CommandLine *manual_subcommands[] = { + &do_fsm_commands, /* state/list/gv + assign/step/nodes set */ + &manual_service_commands, /* getpid / restart / pgctl on|off */ + &manual_monitor_commands, /* register / active / version */ + &do_primary_, /* slot create|drop / adduser monitor|replica / defaults / identify */ + &do_standby_, /* init / rewind / crash-recovery / promote */ + &do_coordinator_commands, /* add / activate / remove / update prepare|commit|rollback */ + NULL +}; + +CommandLine manual_commands = + make_command_set("manual", + "Manual FSM operations — drive by hand what automation normally does", + "[sub-command]", + " fsm Inspect or manually step the keeper FSM\n" + " service Restart or inspect individual sub-processes\n" + " monitor Manually drive monitor registration protocol\n" + " primary Manual primary-side PostgreSQL operations\n" + " standby Manual standby-side PostgreSQL operations\n" + " coordinator Citus coordinator operations\n", + NULL, manual_subcommands); diff --git a/src/bin/pg_autoctl/cli_manual.h b/src/bin/pg_autoctl/cli_manual.h new file mode 100644 index 000000000..d54ec7abd --- /dev/null +++ b/src/bin/pg_autoctl/cli_manual.h @@ -0,0 +1,16 @@ +/* + * src/bin/pg_autoctl/cli_manual.h + * pg_autoctl manual — operator-driven FSM operations and low-level controls. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#ifndef CLI_MANUAL_H +#define CLI_MANUAL_H + +#include "commandline.h" + +extern CommandLine manual_commands; + +#endif /* CLI_MANUAL_H */ diff --git a/src/bin/pg_autoctl/cli_override.c b/src/bin/pg_autoctl/cli_override.c deleted file mode 100644 index 08f059e39..000000000 --- a/src/bin/pg_autoctl/cli_override.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * src/bin/pg_autoctl/cli_override.c - * pg_autoctl override — manual FSM operations and low-level controls. - * - * These commands force individual FSM transitions or low-level operations - * that the FSM would normally own. Intended for manual recovery when the - * automated FSM is stopped or stuck. Named "override" to make clear that - * these bypass normal automation. - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the PostgreSQL License. - */ - -#include "commandline.h" -#include "cli_override.h" -#include "cli_do_root.h" - -static CommandLine *override_subcommands[] = { - &do_fsm_commands, /* state/list/gv/assign/step/nodes */ - &do_service_postgres_ctl_commands, /* restart postgres|listener|node-active */ - &do_service_commands, /* pgcontroller / postgres / listener / node-active */ - &do_primary_, /* slot / adduser / defaults / identify */ - &do_standby_, /* init / rewind / crash-recovery / promote */ - &do_coordinator_commands, /* add / activate / remove / update */ - NULL -}; - -CommandLine override_commands = - make_command_set("override", - "Manual FSM operations — bypasses normal automation", - "[sub-command]", - " fsm Inspect / manually step the keeper FSM\n" - " service Restart or run individual sub-processes\n" - " primary Manual primary-side operations\n" - " standby Manual standby-side operations\n" - " coordinator Citus coordinator operations\n", - NULL, override_subcommands); diff --git a/src/bin/pg_autoctl/cli_override.h b/src/bin/pg_autoctl/cli_override.h deleted file mode 100644 index 15bd78d5b..000000000 --- a/src/bin/pg_autoctl/cli_override.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * src/bin/pg_autoctl/cli_override.h - * pg_autoctl override — manual FSM operations. - * - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the PostgreSQL License. - */ - -#ifndef CLI_OVERRIDE_H -#define CLI_OVERRIDE_H - -#include "commandline.h" - -extern CommandLine override_commands; - -#endif /* CLI_OVERRIDE_H */ diff --git a/src/bin/pg_autoctl/cli_root.c b/src/bin/pg_autoctl/cli_root.c index bc1567aff..b163bee95 100644 --- a/src/bin/pg_autoctl/cli_root.c +++ b/src/bin/pg_autoctl/cli_root.c @@ -11,7 +11,7 @@ #include "cli_common.h" #include "cli_do_root.h" #include "cli_inspect.h" -#include "cli_override.h" +#include "cli_manual.h" #include "cli_root.h" #include "commandline.h" @@ -100,7 +100,7 @@ CommandLine *root_subcommands[] = { &perform_commands, &activate_node_command, &inspect_commands, - &override_commands, + &manual_commands, &do_commands, &service_run_command, &watch_command, @@ -132,7 +132,7 @@ CommandLine *root_subcommands_with_debug[] = { &perform_commands, &activate_node_command, &inspect_commands, - &override_commands, + &manual_commands, &do_commands, &service_run_command, &watch_command, diff --git a/src/bin/pg_autoctl/service_keeper.c b/src/bin/pg_autoctl/service_keeper.c index 5c3d4b557..03b1b12c7 100644 --- a/src/bin/pg_autoctl/service_keeper.c +++ b/src/bin/pg_autoctl/service_keeper.c @@ -148,6 +148,17 @@ service_keeper_start(void *context, pid_t *pid) * This function is intended to be called from the child process after a fork() * has been successfully done at the parent process level: it's calling * execve() and will never return. + * + * Using execve() (rather than just calling the service function directly) is a + * deliberate design choice for live upgrades: when keeper_node_active() detects + * a monitor extension version mismatch it exits, and the supervisor restarts + * the child via fork()+execve() — which re-execs the pg_autoctl binary from + * disk. If the binary has been updated in place the restarted child picks up + * the new version automatically, making zero-downtime upgrades possible even + * when pg_autoctl runs as PID 1 in a Docker/Kubernetes container. + * + * See keeper_check_monitor_extension_version() in keeper.c for the exit path + * that triggers this mechanism. */ void service_keeper_runprogram(Keeper *keeper) diff --git a/src/bin/pg_autoctl/service_monitor.c b/src/bin/pg_autoctl/service_monitor.c index e2a7f4e3a..0401c2371 100644 --- a/src/bin/pg_autoctl/service_monitor.c +++ b/src/bin/pg_autoctl/service_monitor.c @@ -119,13 +119,18 @@ service_monitor_start(void *context, pid_t *pid) /* - * service_monitor_runprogram runs the node_active protocol service: + * service_monitor_runprogram runs the monitor listener service: * - * $ pg_autoctl do service monitor --pgdata ... + * $ pg_autoctl do service listener --pgdata ... * * This function is intended to be called from the child process after a fork() * has been successfully done at the parent process level: it's calling * execve() and will never return. + * + * Using execve() is a deliberate live-upgrade design choice: the supervisor + * restarts children via fork()+execve(), re-execing the binary from disk so + * an in-place update of pg_autoctl is picked up without restarting the + * supervisor (which may be PID 1 in a container). */ void service_monitor_runprogram(Monitor *monitor) diff --git a/src/bin/pg_autoctl/service_postgres_ctl.c b/src/bin/pg_autoctl/service_postgres_ctl.c index 82daa6863..117904c07 100644 --- a/src/bin/pg_autoctl/service_postgres_ctl.c +++ b/src/bin/pg_autoctl/service_postgres_ctl.c @@ -93,6 +93,10 @@ service_postgres_ctl_start(void *context, pid_t *pid) * service_postgres_ctl_runprogram runs the postgres controller service: * * $ pg_autoctl do service postgres --pgdata ... + * + * Uses fork()+execve() so the supervisor can restart the child with the + * current binary on disk — enabling live (zero-downtime) upgrades when + * pg_autoctl runs as PID 1 in a container. */ void service_postgres_ctl_runprogram() From bfd0dc449270263ea89266eec8455437a2c567d2 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 20:35:05 +0200 Subject: [PATCH 08/48] pg_autoctl inspect/manual: fix read/write split, remove duplicate getpid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit inspect now contains: show / pgsetup — unchanged fsm — state / list / gv (read-only FSM introspection) monitor — get / parse-notification (read-only monitor queries) getpid — postgres / listener / node-active manual now contains: fsm — init / assign / step / nodes (mutating FSM operations) service — restart / pgctl on|off (getpid removed — it was duplicated) monitor — register / active / version primary / standby / coordinator — unchanged Fixes: - getpid was present in both 'inspect getpid' and 'manual service getpid' (duplicate); removed from manual service - manual fsm contained state/list/gv which are read-only; moved to inspect - do_coordinator_commands description was 'Query a Citus coordinator' (wrong); changed to 'Manage Citus coordinator node metadata' de-static'd fsm_state/list/gv/init/assign/step in cli_do_fsm.c so cli_inspect.c and cli_manual.c can reference them without going through the do_fsm_commands aggregate. --- src/bin/pg_autoctl/cli_do_coordinator.c | 2 +- src/bin/pg_autoctl/cli_do_fsm.c | 28 +++++----- src/bin/pg_autoctl/cli_do_root.h | 9 ++++ src/bin/pg_autoctl/cli_inspect.c | 27 ++++++++-- src/bin/pg_autoctl/cli_manual.c | 68 +++++++++++++++++++----- src/bin/pgaftest/pgaftest | Bin 779928 -> 779928 bytes 6 files changed, 103 insertions(+), 31 deletions(-) diff --git a/src/bin/pg_autoctl/cli_do_coordinator.c b/src/bin/pg_autoctl/cli_do_coordinator.c index 72f5dfb55..5506fa29e 100644 --- a/src/bin/pg_autoctl/cli_do_coordinator.c +++ b/src/bin/pg_autoctl/cli_do_coordinator.c @@ -108,7 +108,7 @@ static CommandLine *coordinator_commands[] = { CommandLine do_coordinator_commands = make_command_set("coordinator", - "Query a Citus coordinator", NULL, NULL, + "Manage Citus coordinator node metadata", NULL, NULL, NULL, coordinator_commands); diff --git a/src/bin/pg_autoctl/cli_do_fsm.c b/src/bin/pg_autoctl/cli_do_fsm.c index 8c456ff73..738800066 100644 --- a/src/bin/pg_autoctl/cli_do_fsm.c +++ b/src/bin/pg_autoctl/cli_do_fsm.c @@ -37,15 +37,8 @@ static void cli_do_fsm_step(int argc, char **argv); static void cli_do_fsm_get_nodes(int argc, char **argv); static void cli_do_fsm_set_nodes(int argc, char **argv); -static CommandLine fsm_init = - make_command("init", - "Initialize the keeper's state on-disk", - CLI_PGDATA_USAGE, - CLI_PGDATA_OPTION, - cli_getopt_pgdata, - cli_do_fsm_init); - -static CommandLine fsm_state = +/* read-only — exported for pg_autoctl inspect fsm */ +CommandLine fsm_state = make_command("state", "Read the keeper's state from disk and display it", CLI_PGDATA_USAGE, @@ -53,7 +46,7 @@ static CommandLine fsm_state = cli_getopt_pgdata, cli_do_fsm_state); -static CommandLine fsm_list = +CommandLine fsm_list = make_command("list", "List reachable FSM states from current state", CLI_PGDATA_USAGE, @@ -61,12 +54,21 @@ static CommandLine fsm_list = cli_getopt_pgdata, cli_do_fsm_list); -static CommandLine fsm_gv = +CommandLine fsm_gv = make_command("gv", "Output the FSM as a .gv program suitable for graphviz/dot", "", NULL, NULL, cli_do_fsm_gv); -static CommandLine fsm_assign = +/* mutating — exported for pg_autoctl manual fsm */ +CommandLine fsm_init = + make_command("init", + "Initialize the keeper's state on-disk", + CLI_PGDATA_USAGE, + CLI_PGDATA_OPTION, + cli_getopt_pgdata, + cli_do_fsm_init); + +CommandLine fsm_assign = make_command("assign", "Assign a new goal state to the keeper", CLI_PGDATA_USAGE "", @@ -74,7 +76,7 @@ static CommandLine fsm_assign = cli_getopt_pgdata, cli_do_fsm_assign); -static CommandLine fsm_step = +CommandLine fsm_step = make_command("step", "Make a state transition if instructed by the monitor", CLI_PGDATA_USAGE, diff --git a/src/bin/pg_autoctl/cli_do_root.h b/src/bin/pg_autoctl/cli_do_root.h index db2592804..a4614d0aa 100644 --- a/src/bin/pg_autoctl/cli_do_root.h +++ b/src/bin/pg_autoctl/cli_do_root.h @@ -15,6 +15,15 @@ /* src/bin/pg_autoctl/cli_do_fsm.c */ extern CommandLine do_fsm_commands; +/* read-only sub-commands exposed via "pg_autoctl inspect fsm" */ +extern CommandLine fsm_state; +extern CommandLine fsm_list; +extern CommandLine fsm_gv; +/* mutating sub-commands exposed via "pg_autoctl manual fsm" */ +extern CommandLine fsm_init; +extern CommandLine fsm_assign; +extern CommandLine fsm_step; +extern CommandLine fsm_nodes; /* nodes get + nodes set — kept together in manual */ /* src/bin/pg_autoctl/cli_do_monitor.c */ extern CommandLine do_monitor_commands; diff --git a/src/bin/pg_autoctl/cli_inspect.c b/src/bin/pg_autoctl/cli_inspect.c index c07df6f2a..78ac18ba8 100644 --- a/src/bin/pg_autoctl/cli_inspect.c +++ b/src/bin/pg_autoctl/cli_inspect.c @@ -16,6 +16,23 @@ #include "cli_inspect.h" #include "cli_do_root.h" +/* + * Read-only FSM sub-commands: display the current state, list reachable + * transitions, or dump the full FSM as a graphviz .gv file. + * Mutating operations (init, assign, step, nodes set) live under "manual fsm". + */ +static CommandLine *inspect_fsm_subcommands[] = { + &fsm_state, + &fsm_list, + &fsm_gv, + NULL +}; + +static CommandLine inspect_fsm_commands = + make_command_set("fsm", + "Display keeper FSM state and transitions (read-only)", + NULL, NULL, NULL, inspect_fsm_subcommands); + /* * Read-only monitor sub-commands: get primary/others/candidate-count/coordinator * and parse-notification. We intentionally exclude "register", "active", and @@ -39,9 +56,10 @@ static CommandLine inspect_monitor_commands = * "restart" and "pgctl on/off" mutate state and belong under "manual service". */ static CommandLine *inspect_subcommands[] = { - &do_show_commands, /* ipaddr / cidr / lookup / hostname / reverse */ - &do_pgsetup_commands, /* discover / ready / wait / logs / tune / pg_ctl */ - &inspect_monitor_commands, /* get primary|others|candidate-count + parse-notification */ + &do_show_commands, /* ipaddr / cidr / lookup / hostname / reverse */ + &do_pgsetup_commands, /* discover / ready / wait / logs / tune / pg_ctl */ + &inspect_fsm_commands, /* state / list / gv */ + &inspect_monitor_commands, /* get primary|others|candidate-count + parse-notification */ &do_service_getpid_commands, /* getpid postgres|listener|node-active */ NULL }; @@ -52,6 +70,7 @@ CommandLine inspect_commands = "[sub-command]", " show Networking and hostname diagnostics\n" " pgsetup Local PostgreSQL setup inspection\n" + " fsm Display keeper FSM state and reachable transitions\n" " monitor Query the monitor's current state\n" - " service Get PIDs of pg_autoctl sub-processes\n", + " getpid Get PIDs of pg_autoctl sub-processes\n", NULL, inspect_subcommands); diff --git a/src/bin/pg_autoctl/cli_manual.c b/src/bin/pg_autoctl/cli_manual.c index 9957ebf9c..36882df2c 100644 --- a/src/bin/pg_autoctl/cli_manual.c +++ b/src/bin/pg_autoctl/cli_manual.c @@ -10,8 +10,12 @@ * "manual" is the antonym of the automated behaviour pg_autoctl normally * provides: you are doing by hand what the system would otherwise do for you. * - * Read-only diagnostics belong in "pg_autoctl inspect". - * Internal subprocess entry points belong in "pg_autoctl do" (hidden). + * Read-only diagnostics belong in "pg_autoctl inspect": + * inspect fsm state / list / gv + * inspect monitor get / parse-notification + * inspect getpid postgres / listener / node-active + * + * Internal subprocess entry points belong in the hidden "pg_autoctl do". * * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the PostgreSQL License. @@ -21,16 +25,40 @@ #include "cli_manual.h" #include "cli_do_root.h" +/* + * manual fsm: mutating FSM operations only. + * + * Read-only FSM commands (state, list, gv) live under "pg_autoctl inspect fsm" + * because they are safe to run on a live node. + * + * nodes (get + set) is kept as a unit under manual because both sub-commands + * target the offline nodes file (--disable-monitor), making them equally + * operator-oriented regardless of read/write direction. + */ +static CommandLine *manual_fsm_subcommands[] = { + &fsm_init, + &fsm_assign, + &fsm_step, + &fsm_nodes, /* nodes get + nodes set (--disable-monitor file) */ + NULL +}; + +static CommandLine manual_fsm_commands = + make_command_set("fsm", + "Manually drive the keeper FSM (mutating operations)", + NULL, NULL, NULL, manual_fsm_subcommands); + /* * manual service: user-visible service controls only. * + * getpid is read-only and lives under "pg_autoctl inspect getpid". + * * Intentionally excludes the internal subprocess entry points * (pgcontroller / postgres / listener / node-active) which are spawned by the * supervisor via fork+exec and are not meant for direct operator use. * Those live under the hidden "pg_autoctl do service" group. */ static CommandLine *manual_service_subcommands[] = { - &do_service_getpid_commands, /* getpid postgres|listener|node-active */ &do_service_restart_commands, /* restart postgres|listener|node-active */ &do_service_postgres_ctl_commands, /* pgctl on|off */ NULL @@ -38,7 +66,7 @@ static CommandLine *manual_service_subcommands[] = { static CommandLine manual_service_commands = make_command_set("service", - "Inspect or restart pg_autoctl sub-processes", + "Restart pg_autoctl sub-processes or signal the postgres controller", NULL, NULL, NULL, manual_service_subcommands); /* @@ -63,13 +91,27 @@ static CommandLine manual_monitor_commands = "Manually drive monitor RPCs (register / active / version)", NULL, NULL, NULL, manual_monitor_subcommands); +/* + * manual coordinator: Citus coordinator metadata management. + * + * These commands let an operator manually replay the coordinator update steps + * that pg_autoctl normally drives automatically during a Citus worker failover: + * + * coordinator update prepare — call master_update_node() in a prepared + * transaction, which blocks shard writes while open + * coordinator update commit — COMMIT PREPARED: makes the new address permanent + * coordinator update rollback — ROLLBACK PREPARED: abandons a stuck prepare + * + * They are typically needed when the coordinator was unavailable during a + * failover and the prepared transaction needs to be resolved out-of-band. + */ static CommandLine *manual_subcommands[] = { - &do_fsm_commands, /* state/list/gv + assign/step/nodes set */ - &manual_service_commands, /* getpid / restart / pgctl on|off */ - &manual_monitor_commands, /* register / active / version */ - &do_primary_, /* slot create|drop / adduser monitor|replica / defaults / identify */ - &do_standby_, /* init / rewind / crash-recovery / promote */ - &do_coordinator_commands, /* add / activate / remove / update prepare|commit|rollback */ + &manual_fsm_commands, /* init / assign / step / nodes */ + &manual_service_commands, /* restart / pgctl on|off */ + &manual_monitor_commands, /* register / active / version */ + &do_primary_, /* slot create|drop / adduser monitor|replica / defaults / identify */ + &do_standby_, /* init / rewind / crash-recovery / promote */ + &do_coordinator_commands, /* add / activate / remove / update prepare|commit|rollback */ NULL }; @@ -77,10 +119,10 @@ CommandLine manual_commands = make_command_set("manual", "Manual FSM operations — drive by hand what automation normally does", "[sub-command]", - " fsm Inspect or manually step the keeper FSM\n" - " service Restart or inspect individual sub-processes\n" + " fsm Manually drive keeper FSM transitions\n" + " service Restart sub-processes or signal the postgres controller\n" " monitor Manually drive monitor registration protocol\n" " primary Manual primary-side PostgreSQL operations\n" " standby Manual standby-side PostgreSQL operations\n" - " coordinator Citus coordinator operations\n", + " coordinator Citus coordinator metadata management\n", NULL, manual_subcommands); diff --git a/src/bin/pgaftest/pgaftest b/src/bin/pgaftest/pgaftest index fc1cedad4e247aac520f9d2fca7ac1ddba305b0a..3c38f41d905a38b1a554cf22e00994bdb2b683b9 100755 GIT binary patch delta 175839 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%0DrHT-lb4mkJ*j9wIs(NWr12Oauw%D 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

#H(hD^ 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 OxoLh&^!z&cN&f@=6RlZ=9y=nnK?Z5 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 z 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 Date: Sun, 28 Jun 2026 20:45:30 +0200 Subject: [PATCH 09/48] pg_autoctl: rename 'do' to 'internal'; trim to subprocess entry points only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old 'pg_autoctl do' tree was a shadow of everything in inspect+manual plus the actual subprocess entry points. Now: pg_autoctl internal (hidden) service pgcontroller — debug: runs just the postgres-controller supervisor postgres — spawned by service_postgres_ctl_start() listener — spawned by service_monitor_start() node-active — spawned by service_keeper_start() tmux — dev/QA tooling (not yet moved to pgaftest) demo — demo app (not yet moved to pgaftest) All commands that were previously duplicated under 'do' (monitor, coordinator, fsm, primary, standby, show, pgsetup, pgctl, service getpid/restart) are now only reachable through 'inspect' or 'manual'. Spawn calls updated in service_keeper/monitor/postgres_ctl_runprogram(): pg_autoctl do service … → pg_autoctl internal service … The 'internal' name in ps(1) output now immediately communicates that this is an internal subprocess, not a command meant for operator use. --- src/bin/pg_autoctl/cli_do_root.c | 51 ++++++++++++++--------- src/bin/pg_autoctl/cli_do_root.h | 5 +++ src/bin/pg_autoctl/cli_do_service.c | 8 ++-- src/bin/pg_autoctl/cli_manual.c | 2 +- src/bin/pg_autoctl/service_keeper.c | 4 +- src/bin/pg_autoctl/service_monitor.c | 4 +- src/bin/pg_autoctl/service_postgres_ctl.c | 4 +- src/bin/pg_autoctl/supervisor.h | 2 +- 8 files changed, 49 insertions(+), 31 deletions(-) diff --git a/src/bin/pg_autoctl/cli_do_root.c b/src/bin/pg_autoctl/cli_do_root.c index af5199527..72d5d5cdb 100644 --- a/src/bin/pg_autoctl/cli_do_root.c +++ b/src/bin/pg_autoctl/cli_do_root.c @@ -567,23 +567,8 @@ CommandLine do_azure_commands = #endif /* REMOVED: azure commands */ -CommandLine *do_subcommands[] = { - &do_monitor_commands, - &do_coordinator_commands, - &do_fsm_commands, - &do_primary_, - &do_standby_, - &do_show_commands, - &do_pgsetup_commands, - &do_service_postgres_ctl_commands, - &do_service_commands, - &do_tmux_commands, - &do_demo_commands, - NULL -}; - /* - * pg_autoctl do service postgres|listener|node-active + * pg_autoctl internal service postgres|listener|node-active * * These are the subprocess entry points used by the supervisor (pg_autoctl run * and pg_autoctl create … --run). The supervisor fork()s and then execv()s @@ -603,11 +588,39 @@ CommandLine *do_subcommands[] = { * version mismatch precisely to trigger this restart-with-new-binary path. * * These commands are hidden from --help output (make_hidden_command_set) so - * operators do not accidentally invoke them. Use "pg_autoctl manual service" - * for the user-facing service controls (getpid, restart, pgctl on/off). + * operators do not accidentally invoke them directly. + * Use "pg_autoctl manual service" for the user-facing controls (restart, pgctl). + * Use "pg_autoctl inspect getpid" to read sub-process PIDs. */ +static CommandLine *internal_service_subcommands[] = { + &service_pgcontroller, /* debug: supervisor for just the postgres controller */ + &service_postgres, /* spawned by service_postgres_ctl_start() */ + &service_monitor_listener, /* spawned by service_monitor_start() */ + &service_node_active, /* spawned by service_keeper_start() */ + NULL +}; + +static CommandLine internal_service_commands = + make_hidden_command_set("service", + "Subprocess entry points for the pg_autoctl supervisor", + NULL, NULL, NULL, internal_service_subcommands); + +/* + * pg_autoctl internal + * + * Hidden from --help; routable so the supervisor's execv() calls work. + * Contains only what the supervisor spawns plus dev/QA tooling not yet + * moved to pgaftest (tmux, demo). + */ +CommandLine *do_subcommands[] = { + &internal_service_commands, + &do_tmux_commands, + &do_demo_commands, + NULL +}; + CommandLine do_commands = - make_hidden_command_set("do", + make_hidden_command_set("internal", "Internal subprocess entry points — not for direct use", NULL, NULL, NULL, do_subcommands); diff --git a/src/bin/pg_autoctl/cli_do_root.h b/src/bin/pg_autoctl/cli_do_root.h index a4614d0aa..463389496 100644 --- a/src/bin/pg_autoctl/cli_do_root.h +++ b/src/bin/pg_autoctl/cli_do_root.h @@ -40,6 +40,11 @@ extern CommandLine do_service_commands; extern CommandLine do_service_getpid_commands; extern CommandLine do_service_restart_commands; extern CommandLine do_service_postgres_ctl_commands; +/* subprocess entry points (spawned by the supervisor via fork+exec) */ +extern CommandLine service_pgcontroller; +extern CommandLine service_postgres; +extern CommandLine service_monitor_listener; +extern CommandLine service_node_active; /* src/bin/pg_autoctl/cli_do_show.c */ extern CommandLine do_show_commands; diff --git a/src/bin/pg_autoctl/cli_do_service.c b/src/bin/pg_autoctl/cli_do_service.c index 94420b7c5..e450417ca 100644 --- a/src/bin/pg_autoctl/cli_do_service.c +++ b/src/bin/pg_autoctl/cli_do_service.c @@ -357,8 +357,8 @@ cli_do_service_restart_node_active(int argc, char **argv) * tree. It is used for debug purposes only. When using this entry point we * have a supervisor process that is responsible for only one service: * - * pg_autoctl do service pgcontroller - * - pg_autoctl do service postgres + * pg_autoctl internal service pgcontroller + * - pg_autoctl internal service postgres * - postgres */ static void @@ -401,9 +401,9 @@ cli_do_service_pgcontroller(int argc, char **argv) * that supervises two sub-processes, one of them is cli_do_service_postgres: * * pg_autoctl - * - pg_autoctl do service postgres + * - pg_autoctl internal service postgres * - postgres - * - pg_autoctl do service keeper|monitor + * - pg_autoctl internal service keeper|monitor */ static void cli_do_service_postgres(int argc, char **argv) diff --git a/src/bin/pg_autoctl/cli_manual.c b/src/bin/pg_autoctl/cli_manual.c index 36882df2c..76e319b6e 100644 --- a/src/bin/pg_autoctl/cli_manual.c +++ b/src/bin/pg_autoctl/cli_manual.c @@ -56,7 +56,7 @@ static CommandLine manual_fsm_commands = * Intentionally excludes the internal subprocess entry points * (pgcontroller / postgres / listener / node-active) which are spawned by the * supervisor via fork+exec and are not meant for direct operator use. - * Those live under the hidden "pg_autoctl do service" group. + * Those live under the hidden "pg_autoctl internal service" group. */ static CommandLine *manual_service_subcommands[] = { &do_service_restart_commands, /* restart postgres|listener|node-active */ diff --git a/src/bin/pg_autoctl/service_keeper.c b/src/bin/pg_autoctl/service_keeper.c index 03b1b12c7..3242e7218 100644 --- a/src/bin/pg_autoctl/service_keeper.c +++ b/src/bin/pg_autoctl/service_keeper.c @@ -143,7 +143,7 @@ service_keeper_start(void *context, pid_t *pid) /* * service_keeper_runprogram runs the node_active protocol service: * - * $ pg_autoctl do service node-active --pgdata ... + * $ pg_autoctl internal service node-active --pgdata ... * * This function is intended to be called from the child process after a fork() * has been successfully done at the parent process level: it's calling @@ -181,7 +181,7 @@ service_keeper_runprogram(Keeper *keeper) setenv(PG_AUTOCTL_DEBUG, "1", 1); args[argsIndex++] = (char *) pg_autoctl_program; - args[argsIndex++] = "do"; + args[argsIndex++] = "internal"; args[argsIndex++] = "service"; args[argsIndex++] = "node-active"; args[argsIndex++] = "--pgdata"; diff --git a/src/bin/pg_autoctl/service_monitor.c b/src/bin/pg_autoctl/service_monitor.c index 0401c2371..c09e43dde 100644 --- a/src/bin/pg_autoctl/service_monitor.c +++ b/src/bin/pg_autoctl/service_monitor.c @@ -121,7 +121,7 @@ service_monitor_start(void *context, pid_t *pid) /* * service_monitor_runprogram runs the monitor listener service: * - * $ pg_autoctl do service listener --pgdata ... + * $ pg_autoctl internal service listener --pgdata ... * * This function is intended to be called from the child process after a fork() * has been successfully done at the parent process level: it's calling @@ -165,7 +165,7 @@ service_monitor_runprogram(Monitor *monitor) setenv(PG_AUTOCTL_DEBUG, "1", 1); args[argsIndex++] = (char *) pg_autoctl_program; - args[argsIndex++] = "do"; + args[argsIndex++] = "internal"; args[argsIndex++] = "service"; args[argsIndex++] = "listener"; args[argsIndex++] = "--pgdata"; diff --git a/src/bin/pg_autoctl/service_postgres_ctl.c b/src/bin/pg_autoctl/service_postgres_ctl.c index 117904c07..fcf20e8a5 100644 --- a/src/bin/pg_autoctl/service_postgres_ctl.c +++ b/src/bin/pg_autoctl/service_postgres_ctl.c @@ -92,7 +92,7 @@ service_postgres_ctl_start(void *context, pid_t *pid) /* * service_postgres_ctl_runprogram runs the postgres controller service: * - * $ pg_autoctl do service postgres --pgdata ... + * $ pg_autoctl internal service postgres --pgdata ... * * Uses fork()+execve() so the supervisor can restart the child with the * current binary on disk — enabling live (zero-downtime) upgrades when @@ -133,7 +133,7 @@ service_postgres_ctl_runprogram() setenv(PG_AUTOCTL_DEBUG, "1", 1); args[argsIndex++] = (char *) pg_autoctl_program; - args[argsIndex++] = "do"; + args[argsIndex++] = "internal"; args[argsIndex++] = "service"; args[argsIndex++] = "postgres"; args[argsIndex++] = "--pgdata"; diff --git a/src/bin/pg_autoctl/supervisor.h b/src/bin/pg_autoctl/supervisor.h index 903b587ae..ad1350a38 100644 --- a/src/bin/pg_autoctl/supervisor.h +++ b/src/bin/pg_autoctl/supervisor.h @@ -18,7 +18,7 @@ * * - the main pidfile, * - the per-service name for the pidfile is derived from this, - * - the pg_autoctl do service getpid|restart commands + * - the pg_autoctl manual service getpid|restart commands */ #define SERVICE_NAME_POSTGRES "postgres" #define SERVICE_NAME_KEEPER "node-active" From fe341daa79f69dfaa85512a02d963a395929208f Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 21:32:03 +0200 Subject: [PATCH 10/48] pg_autoctl node: declarative node spec file + supervisor file watcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduces a new pg_autoctl_node.ini file format and a matching command tree (pg_autoctl node run/apply/show/check) that lets operators describe a node fully in one file and hand it to pg_autoctl rather than assembling long create-flag command lines. ## pg_autoctl_node.ini sections [node] kind, hostname, port [postgresql] pgdata [monitor] pguri (empty for monitor nodes) [formation] name, group [settings] candidate_priority, replication_quorum ← mutable [create] ssl, auth, pg_hba_lan ← create-time only ## pg_autoctl node subcommands run Create (if needed) then execv() into run/create --run. Sets PG_AUTOCTL_NODESPEC env var so the supervisor picks up the file path for watching. apply Converge mutable fields on an already-running node (calls pg_autoctl set node ... for changed values). show Dump live config as pg_autoctl_node.ini on stdout. check Parse-only validate; print resolved fields. ## Supervisor file watcher (nodespec_watcher) The supervisor initialises a NodeSpecWatcher when PG_AUTOCTL_NODESPEC is set. Every 100 ms tick: - Linux: drain inotify IN_CLOSE_WRITE / IN_MOVED_TO events - Others: stat() the file every NODESPEC_WATCH_INTERVAL_SECS (10 s) On change, re-parse and call nodespec_apply() to converge mutable fields without restarting the node. Immutable field changes (kind, pgdata) are logged as warnings — a restart is required. ## pgaftest compose: uniform containers compose_gen.c now generates: - monitor_node.ini + _node.ini per data node (in workdir) - Every service uses the same image and same command: pg_autoctl node run /etc/pgaf/node.ini - The per-node ini is bind-mounted :ro at /etc/pgaf/node.ini - No bespoke per-node command in docker-compose.yml cluster { } block gains new options: image, ssl, auth, formation, num-sync, monitor [port N] test_runner.c calls compose_gen_write_monitor_ini() and compose_gen_write_node_ini() before docker compose up. --- src/bin/pg_autoctl/cli_node.c | 356 ++++++++++++++++++ src/bin/pg_autoctl/cli_node.h | 16 + src/bin/pg_autoctl/cli_root.c | 3 + src/bin/pg_autoctl/nodespec.c | 580 +++++++++++++++++++++++++++++ src/bin/pg_autoctl/nodespec.h | 131 +++++++ src/bin/pg_autoctl/supervisor.c | 35 ++ src/bin/pg_autoctl/supervisor.h | 12 + src/bin/pgaftest/Makefile | 2 +- src/bin/pgaftest/compose_gen.c | 260 ++++++++++--- src/bin/pgaftest/compose_gen.h | 16 + src/bin/pgaftest/pgaftest | Bin 779928 -> 798072 bytes src/bin/pgaftest/test_runner.c | 29 +- src/bin/pgaftest/test_spec.h | 7 + src/bin/pgaftest/test_spec_parse.c | 94 +++-- src/bin/pgaftest/test_spec_parse.y | 74 +++- 15 files changed, 1507 insertions(+), 108 deletions(-) create mode 100644 src/bin/pg_autoctl/cli_node.c create mode 100644 src/bin/pg_autoctl/cli_node.h create mode 100644 src/bin/pg_autoctl/nodespec.c create mode 100644 src/bin/pg_autoctl/nodespec.h diff --git a/src/bin/pg_autoctl/cli_node.c b/src/bin/pg_autoctl/cli_node.c new file mode 100644 index 000000000..7ee817be8 --- /dev/null +++ b/src/bin/pg_autoctl/cli_node.c @@ -0,0 +1,356 @@ +/* + * src/bin/pg_autoctl/cli_node.c + * pg_autoctl node — declarative node lifecycle driven by a pg_autoctl_node.ini file. + * + * pg_autoctl node run Create (if needed) then run the supervisor. + * pg_autoctl node apply Converge mutable fields on a running node. + * pg_autoctl node show Dump current config as pg_autoctl_node.ini. + * pg_autoctl node check Validate the file without creating anything. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include +#include +#include + +#include "cli_common.h" +#include "cli_node.h" +#include "cli_root.h" +#include "commandline.h" +#include "defaults.h" +#include "env_utils.h" +#include "file_utils.h" +#include "keeper_config.h" +#include "log.h" +#include "nodespec.h" +#include "pgsetup.h" +#include "runprogram.h" +#include "string_utils.h" + + +static int cli_node_run_getopts(int argc, char **argv); +static void cli_node_run(int argc, char **argv); +static int cli_node_apply_getopts(int argc, char **argv); +static void cli_node_apply(int argc, char **argv); +static int cli_node_show_getopts(int argc, char **argv); +static void cli_node_show(int argc, char **argv); +static int cli_node_check_getopts(int argc, char **argv); +static void cli_node_check(int argc, char **argv); + + +static CommandLine node_run_command = + make_command( + "run", + "Create (if needed) and run a node described by a pg_autoctl_node.ini file", + "", + " path to the pg_autoctl_node.ini file\n" + " (default: " PG_AUTOCTL_NODESPEC_PATH ")\n", + cli_node_run_getopts, + cli_node_run); + +static CommandLine node_apply_command = + make_command( + "apply", + "Apply mutable settings from a pg_autoctl_node.ini to a running node", + "", + " path to the pg_autoctl_node.ini file\n", + cli_node_apply_getopts, + cli_node_apply); + +static CommandLine node_show_command = + make_command( + "show", + "Dump current node configuration as a pg_autoctl_node.ini file", + "[--pgdata

]", + " --pgdata location of the Postgres data directory\n", + cli_node_show_getopts, + cli_node_show); + +static CommandLine node_check_command = + make_command( + "check", + "Validate a pg_autoctl_node.ini file without creating anything", + "", + " path to the pg_autoctl_node.ini file\n", + cli_node_check_getopts, + cli_node_check); + +static CommandLine *node_subcommands[] = { + &node_run_command, + &node_apply_command, + &node_show_command, + &node_check_command, + NULL +}; + +CommandLine node_commands = + make_command_set( + "node", + "Declarative node lifecycle — create, run, and reconfigure from a .ini file", + NULL, NULL, NULL, node_subcommands); + + +/* ----------------------------------------------------------------------- + * Shared state + * ----------------------------------------------------------------------- */ + +static char nodeSpecPath[MAXPGPATH] = { 0 }; + + +/* ----------------------------------------------------------------------- + * pg_autoctl node run + * ----------------------------------------------------------------------- */ + +static int +cli_node_run_getopts(int argc, char **argv) +{ + if (argc > 0 && argv[0][0] != '-') + strlcpy(nodeSpecPath, argv[0], sizeof(nodeSpecPath)); + else + strlcpy(nodeSpecPath, PG_AUTOCTL_NODESPEC_PATH, sizeof(nodeSpecPath)); + + return 0; +} + +/* + * cli_node_run reads the pg_autoctl_node.ini file, runs `pg_autoctl create + * --run` if PGDATA does not yet exist, or `pg_autoctl run` if it does. + * + * We exec() rather than call the internal functions directly so that: + * 1. The supervisor's fork+exec live-upgrade pattern is preserved. + * 2. The already-running supervisor (PID 1) can restart this process after + * a binary upgrade without special-casing the "node run" path. + */ +static void +cli_node_run(int argc, char **argv) +{ + NodeSpec spec = { 0 }; + char *args[32]; + int nargs; + + if (!nodespec_read(nodeSpecPath, &spec)) + exit(EXIT_CODE_BAD_CONFIG); + + /* + * If PGDATA already has a pg_autoctl.cfg, the node was created before. + * In that case run `pg_autoctl run` (no --run, no create flags). + * Otherwise run `pg_autoctl create ... --run`. + */ + char cfgPath[MAXPGPATH]; + bool cfgExists = false; + + if (!IS_EMPTY_STRING_BUFFER(spec.pgdata)) + { + sformat(cfgPath, sizeof(cfgPath), + "%s/pg_autoctl.cfg", spec.pgdata); + cfgExists = file_exists(cfgPath); + } + + if (cfgExists) + { + /* + * Node was already created. Apply any mutable changes that might + * have been made to the spec file since the last run, then hand off + * to the normal run path. + */ + NodeSpec prev = { 0 }; + + /* best-effort: ignore errors if we can't re-read the spec */ + (void) nodespec_read(nodeSpecPath, &prev); + (void) nodespec_apply(&spec, &prev); + + args[0] = (char *) pg_autoctl_program; + args[1] = "run"; + args[2] = "--pgdata"; + args[3] = spec.pgdata; + args[4] = NULL; + nargs = 4; + } + else + { + nargs = nodespec_create_argv(&spec, pg_autoctl_program, + args, 32); + if (nargs < 0) + exit(EXIT_CODE_INTERNAL_ERROR); + } + + /* Tell the supervisor which spec file to watch for live changes */ + setenv("PG_AUTOCTL_NODESPEC", nodeSpecPath, 1); + + /* Log the command we're about to exec */ + { + PQExpBuffer cmd = createPQExpBuffer(); + for (int i = 0; i < nargs; i++) + { + if (i > 0) appendPQExpBufferChar(cmd, ' '); + appendPQExpBufferStr(cmd, args[i]); + } + log_info("pg_autoctl node run: %s", cmd->data); + destroyPQExpBuffer(cmd); + } + + execv(args[0], args); + + /* If we get here execv failed */ + log_fatal("execv(\"%s\"): %m", args[0]); + exit(EXIT_CODE_INTERNAL_ERROR); +} + + +/* ----------------------------------------------------------------------- + * pg_autoctl node apply + * ----------------------------------------------------------------------- */ + +static int +cli_node_apply_getopts(int argc, char **argv) +{ + if (argc > 0 && argv[0][0] != '-') + strlcpy(nodeSpecPath, argv[0], sizeof(nodeSpecPath)); + else + { + log_error("pg_autoctl node apply requires a file argument"); + exit(EXIT_CODE_BAD_ARGS); + } + return 0; +} + +static void +cli_node_apply(int argc, char **argv) +{ + NodeSpec new_spec = { 0 }; + NodeSpec cur_spec = { 0 }; + + if (!nodespec_read(nodeSpecPath, &new_spec)) + exit(EXIT_CODE_BAD_CONFIG); + + /* Read the current spec from the same path as a baseline */ + (void) nodespec_read(nodeSpecPath, &cur_spec); + + if (!nodespec_apply(&new_spec, &cur_spec)) + { + log_error("Failed to apply node spec from \"%s\"", nodeSpecPath); + exit(EXIT_CODE_INTERNAL_ERROR); + } +} + + +/* ----------------------------------------------------------------------- + * pg_autoctl node show [--pgdata ] + * ----------------------------------------------------------------------- */ + +static int +cli_node_show_getopts(int argc, char **argv) +{ + /* honour --pgdata from the global keeperOptions */ + return cli_getopt_pgdata(argc, argv); +} + +static void +cli_node_show(int argc, char **argv) +{ + /* + * Build a NodeSpec from the running keeper/monitor config and emit it. + * We read the existing pg_autoctl.cfg rather than the node spec file so + * that `pg_autoctl node show` reflects the live configuration. + */ + KeeperConfig config = keeperOptions; + + bool missingPgdataIsOk = true; + bool pgIsNotRunningIsOk = true; + bool monitorDisabledIsOk = true; + + if (!keeper_config_read_file(&config, + missingPgdataIsOk, + pgIsNotRunningIsOk, + monitorDisabledIsOk)) + { + log_error("Failed to read pg_autoctl configuration"); + exit(EXIT_CODE_BAD_CONFIG); + } + + NodeSpec spec = { 0 }; + + spec.kind = config.pgSetup.pgKind; + strlcpy(spec.pgdata, config.pgSetup.pgdata, sizeof(spec.pgdata)); + strlcpy(spec.hostname, config.hostname, sizeof(spec.hostname)); + spec.port = config.pgSetup.pgport; + strlcpy(spec.monitor_pguri, config.monitor_pguri, + sizeof(spec.monitor_pguri)); + strlcpy(spec.formation, config.formation, sizeof(spec.formation)); + spec.group = config.groupId; + + /* Mutable settings defaults — we'd need a monitor round-trip for live values */ + spec.candidate_priority = 50; + spec.replication_quorum = true; + + /* Create-time defaults */ + strlcpy(spec.ssl, "self-signed", sizeof(spec.ssl)); + strlcpy(spec.auth, "trust", sizeof(spec.auth)); + spec.pg_hba_lan = true; + + (void) nodespec_write(&spec, stdout); +} + + +/* ----------------------------------------------------------------------- + * pg_autoctl node check + * ----------------------------------------------------------------------- */ + +static int +cli_node_check_getopts(int argc, char **argv) +{ + if (argc > 0 && argv[0][0] != '-') + strlcpy(nodeSpecPath, argv[0], sizeof(nodeSpecPath)); + else + { + log_error("pg_autoctl node check requires a file argument"); + exit(EXIT_CODE_BAD_ARGS); + } + return 0; +} + +static void +cli_node_check(int argc, char **argv) +{ + NodeSpec spec = { 0 }; + + if (!nodespec_read(nodeSpecPath, &spec)) + { + log_error("Invalid node spec file \"%s\"", nodeSpecPath); + exit(EXIT_CODE_BAD_CONFIG); + } + + const char *kindStr; + switch (spec.kind) + { + case NODE_KIND_UNKNOWN: kindStr = "monitor"; break; + case NODE_KIND_STANDALONE: kindStr = "postgres"; break; + case NODE_KIND_CITUS_COORDINATOR: kindStr = "coordinator"; break; + case NODE_KIND_CITUS_WORKER: kindStr = "worker"; break; + default: kindStr = "unknown"; break; + } + + fprintf(stdout, "Node spec \"%s\" is valid.\n", nodeSpecPath); + fprintf(stdout, " kind : %s\n", kindStr); + fprintf(stdout, " pgdata : %s\n", spec.pgdata); + fprintf(stdout, " hostname : %s\n", spec.hostname); + fprintf(stdout, " port : %d\n", spec.port); + + if (spec.kind != NODE_KIND_UNKNOWN) + { + fprintf(stdout, " monitor_pguri : %s\n", spec.monitor_pguri); + fprintf(stdout, " formation : %s\n", spec.formation); + fprintf(stdout, " group : %d\n", spec.group); + } + + fprintf(stdout, " candidate_priority : %d\n", spec.candidate_priority); + fprintf(stdout, " replication_quorum : %s\n", + spec.replication_quorum ? "true" : "false"); + fprintf(stdout, " ssl : %s\n", spec.ssl); + fprintf(stdout, " auth : %s\n", spec.auth); + fprintf(stdout, " pg_hba_lan : %s\n", + spec.pg_hba_lan ? "true" : "false"); +} diff --git a/src/bin/pg_autoctl/cli_node.h b/src/bin/pg_autoctl/cli_node.h new file mode 100644 index 000000000..c236eeada --- /dev/null +++ b/src/bin/pg_autoctl/cli_node.h @@ -0,0 +1,16 @@ +/* + * src/bin/pg_autoctl/cli_node.h + * pg_autoctl node — declarative node lifecycle from a .ini file. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#ifndef CLI_NODE_H +#define CLI_NODE_H + +#include "commandline.h" + +extern CommandLine node_commands; + +#endif /* CLI_NODE_H */ diff --git a/src/bin/pg_autoctl/cli_root.c b/src/bin/pg_autoctl/cli_root.c index b163bee95..ffe11cbe3 100644 --- a/src/bin/pg_autoctl/cli_root.c +++ b/src/bin/pg_autoctl/cli_root.c @@ -12,6 +12,7 @@ #include "cli_do_root.h" #include "cli_inspect.h" #include "cli_manual.h" +#include "cli_node.h" #include "cli_root.h" #include "commandline.h" @@ -101,6 +102,7 @@ CommandLine *root_subcommands[] = { &activate_node_command, &inspect_commands, &manual_commands, + &node_commands, &do_commands, &service_run_command, &watch_command, @@ -133,6 +135,7 @@ CommandLine *root_subcommands_with_debug[] = { &activate_node_command, &inspect_commands, &manual_commands, + &node_commands, &do_commands, &service_run_command, &watch_command, diff --git a/src/bin/pg_autoctl/nodespec.c b/src/bin/pg_autoctl/nodespec.c new file mode 100644 index 000000000..657186212 --- /dev/null +++ b/src/bin/pg_autoctl/nodespec.c @@ -0,0 +1,580 @@ +/* + * src/bin/pg_autoctl/nodespec.c + * Parse, write, and converge a pg_autoctl_node.ini file. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include +#include +#include +#include + +#ifdef __linux__ +#include +#endif + +#include "nodespec.h" +#include "ini_file.h" +#include "log.h" +#include "pgsetup.h" +#include "string_utils.h" +#include "file_utils.h" /* sformat */ +#include "env_utils.h" +#include "cli_root.h" /* pg_autoctl_program */ +#include "runprogram.h" /* Program, run_program, free_program */ + + +/* + * nodespec_read parses a pg_autoctl_node.ini file. + * + * File format: + * + * [node] + * kind = postgres # postgres | monitor | coordinator | worker + * hostname = node1 + * port = 5432 + * + * [postgresql] + * pgdata = /var/lib/postgres/pgaf + * + * [monitor] + * pguri = postgresql://autoctl_node@monitor/pg_auto_failover + * + * [formation] + * name = default + * group = 0 + * + * [settings] + * candidate_priority = 50 + * replication_quorum = true + * + * [create] + * ssl = self-signed + * auth = trust + * pg_hba_lan = true + */ +bool +nodespec_read(const char *path, NodeSpec *spec) +{ + char kindStr[NAMEDATALEN] = { 0 }; + char replicationQuorumStr[8] = { 0 }; + char pgHbaLanStr[8] = { 0 }; + int port = 5432; + int group = 0; + int candidatePriority = 50; + + /* + * Provide string buffers for booleans and the kind enum — we parse them + * after read_ini_file() returns so we can give decent error messages. + */ + IniOption opts[] = { + /* [node] */ + make_strbuf_option_default("node", "kind", NULL, true, + sizeof(kindStr), kindStr, + "postgres"), + make_strbuf_option_default("node", "hostname", NULL, false, + sizeof(spec->hostname), spec->hostname, + ""), + make_int_option_default("node", "port", NULL, false, + &port, 5432), + + /* [postgresql] */ + make_strbuf_option("postgresql", "pgdata", NULL, true, + sizeof(spec->pgdata), spec->pgdata), + + /* [monitor] */ + make_strbuf_option_default("monitor", "pguri", NULL, false, + sizeof(spec->monitor_pguri), + spec->monitor_pguri, ""), + + /* [formation] */ + make_strbuf_option_default("formation", "name", NULL, false, + sizeof(spec->formation), spec->formation, + "default"), + make_int_option_default("formation", "group", NULL, false, + &group, 0), + + /* [settings] — mutable */ + make_int_option_default("settings", "candidate_priority", NULL, false, + &candidatePriority, 50), + make_strbuf_option_default("settings", "replication_quorum", NULL, false, + sizeof(replicationQuorumStr), + replicationQuorumStr, "true"), + + /* [create] — immutable, used only at create time */ + make_strbuf_option_default("create", "ssl", NULL, false, + sizeof(spec->ssl), spec->ssl, + "self-signed"), + make_strbuf_option_default("create", "auth", NULL, false, + sizeof(spec->auth), spec->auth, + "trust"), + make_strbuf_option_default("create", "pg_hba_lan", NULL, false, + sizeof(pgHbaLanStr), pgHbaLanStr, + "true"), + + INI_OPTION_LAST + }; + + if (!read_ini_file(path, opts)) + { + log_error("Failed to parse node spec file \"%s\"", path); + return false; + } + + /* resolve kind string → enum */ + if (strcmp(kindStr, "monitor") == 0) + spec->kind = NODE_KIND_UNKNOWN; /* handled specially: no formation */ + else if (strcmp(kindStr, "postgres") == 0) + spec->kind = NODE_KIND_STANDALONE; + else if (strcmp(kindStr, "coordinator") == 0) + spec->kind = NODE_KIND_CITUS_COORDINATOR; + else if (strcmp(kindStr, "worker") == 0) + spec->kind = NODE_KIND_CITUS_WORKER; + else + { + log_error("Unknown node kind \"%s\" in \"%s\"; " + "expected: monitor, postgres, coordinator, worker", + kindStr, path); + return false; + } + + spec->port = port; + spec->group = group; + spec->candidate_priority = candidatePriority; + + /* parse boolean strings */ + spec->replication_quorum = + (strcmp(replicationQuorumStr, "true") == 0 || + strcmp(replicationQuorumStr, "yes") == 0 || + strcmp(replicationQuorumStr, "1") == 0); + + spec->pg_hba_lan = + (strcmp(pgHbaLanStr, "true") == 0 || + strcmp(pgHbaLanStr, "yes") == 0 || + strcmp(pgHbaLanStr, "1") == 0); + + /* validate: non-monitor nodes need a monitor URI */ + if (spec->kind != NODE_KIND_UNKNOWN && + IS_EMPTY_STRING_BUFFER(spec->monitor_pguri)) + { + log_error("Node kind \"%s\" requires [monitor] pguri in \"%s\"", + kindStr, path); + return false; + } + + return true; +} + + +/* + * nodespec_write serialises a NodeSpec as a pg_autoctl_node.ini file. + */ +bool +nodespec_write(const NodeSpec *spec, FILE *out) +{ + const char *kindStr; + + switch (spec->kind) + { + case NODE_KIND_UNKNOWN: kindStr = "monitor"; break; + case NODE_KIND_STANDALONE: kindStr = "postgres"; break; + case NODE_KIND_CITUS_COORDINATOR: kindStr = "coordinator"; break; + case NODE_KIND_CITUS_WORKER: kindStr = "worker"; break; + default: kindStr = "postgres"; break; + } + + fprintf(out, + "[node]\n" + "kind = %s\n" + "hostname = %s\n" + "port = %d\n" + "\n" + "[postgresql]\n" + "pgdata = %s\n" + "\n", + kindStr, + spec->hostname, + spec->port, + spec->pgdata); + + if (spec->kind != NODE_KIND_UNKNOWN) + { + fprintf(out, + "[monitor]\n" + "pguri = %s\n" + "\n" + "[formation]\n" + "name = %s\n" + "group = %d\n" + "\n", + spec->monitor_pguri, + spec->formation, + spec->group); + } + + fprintf(out, + "[settings]\n" + "candidate_priority = %d\n" + "replication_quorum = %s\n" + "\n" + "[create]\n" + "ssl = %s\n" + "auth = %s\n" + "pg_hba_lan = %s\n", + spec->candidate_priority, + spec->replication_quorum ? "true" : "false", + spec->ssl, + spec->auth, + spec->pg_hba_lan ? "true" : "false"); + + return true; +} + + +/* + * nodespec_create_argv builds an argv[] array for: + * + * pg_autoctl create --pgdata

--hostname --pgport + * --monitor [--formation ] [--group ] + * [--ssl-self-signed | --no-ssl] + * [--auth ] [--pg-hba-lan] --run + * + * Returns the number of entries written (terminating NULL not counted). + * args[] must have room for at least 32 pointers. + * + * String values are pointers into *spec — the caller must keep spec alive. + */ +int +nodespec_create_argv(const NodeSpec *spec, + const char *pg_autoctl_path, + char **args, int args_size) +{ + int i = 0; + +#define PUSH(v) do { \ + if (i >= args_size - 1) { \ + log_error("nodespec_create_argv: args[] overflow"); \ + return -1; \ + } \ + args[i++] = (char *)(v); \ +} while (0) + + PUSH(pg_autoctl_path); + PUSH("create"); + + switch (spec->kind) + { + case NODE_KIND_UNKNOWN: + PUSH("monitor"); + break; + case NODE_KIND_STANDALONE: + PUSH("postgres"); + break; + case NODE_KIND_CITUS_COORDINATOR: + PUSH("coordinator"); + break; + case NODE_KIND_CITUS_WORKER: + PUSH("worker"); + break; + default: + PUSH("postgres"); + break; + } + + PUSH("--pgdata"); + PUSH(spec->pgdata); + + if (!IS_EMPTY_STRING_BUFFER(spec->hostname)) + { + PUSH("--hostname"); + PUSH(spec->hostname); + } + + if (spec->port != 5432) + { + /* static buffer — safe because spec is long-lived */ + static char portbuf[16]; + sformat(portbuf, sizeof(portbuf), "%d", spec->port); + PUSH("--pgport"); + PUSH(portbuf); + } + + if (spec->kind != NODE_KIND_UNKNOWN) + { + PUSH("--monitor"); + PUSH(spec->monitor_pguri); + + if (!IS_EMPTY_STRING_BUFFER(spec->formation) && + strcmp(spec->formation, "default") != 0) + { + PUSH("--formation"); + PUSH(spec->formation); + } + + if (spec->kind == NODE_KIND_CITUS_WORKER && spec->group > 0) + { + static char groupbuf[16]; + sformat(groupbuf, sizeof(groupbuf), "%d", spec->group); + PUSH("--group"); + PUSH(groupbuf); + } + } + + /* SSL */ + if (strcmp(spec->ssl, "self-signed") == 0) + PUSH("--ssl-self-signed"); + else if (strcmp(spec->ssl, "off") == 0) + PUSH("--no-ssl"); + /* "cert" mode: SSL flags come from postgresql.conf, nothing to add */ + + /* auth */ + if (!IS_EMPTY_STRING_BUFFER(spec->auth)) + { + PUSH("--auth"); + PUSH(spec->auth); + } + + if (spec->pg_hba_lan && spec->kind != NODE_KIND_UNKNOWN) + PUSH("--pg-hba-lan"); + + PUSH("--run"); + + args[i] = NULL; + +#undef PUSH + return i; +} + + +/* + * nodespec_apply compares new_spec against old_spec and applies any changes + * to the mutable fields by calling into the keeper / monitor APIs. + * + * Currently mutable fields: + * - candidate_priority → monitor_set_node_candidate_priority() + * - replication_quorum → monitor_set_node_replication_quorum() + * + * Immutable fields (kind, pgdata, ssl, auth, pg_hba_lan) are not checked here; + * the caller should warn when those differ. + */ +bool +nodespec_apply(const NodeSpec *new_spec, const NodeSpec *old_spec) +{ + bool changed = false; + + if (new_spec->candidate_priority != old_spec->candidate_priority) + { + char prio[16]; + sformat(prio, sizeof(prio), "%d", new_spec->candidate_priority); + + Program prog = run_program(pg_autoctl_program, + "set", "node", "candidate-priority", + "--pgdata", new_spec->pgdata, + prio, NULL); + + if (prog.returnCode != 0) + { + log_warn("nodespec_apply: set candidate-priority %s failed (rc=%d)", + prio, prog.returnCode); + if (prog.stdOut) + log_warn("%s", prog.stdOut); + } + else + { + log_info("nodespec: applied candidate_priority = %d", + new_spec->candidate_priority); + changed = true; + } + free_program(&prog); + } + + if (new_spec->replication_quorum != old_spec->replication_quorum) + { + const char *quorum = new_spec->replication_quorum ? "true" : "false"; + + Program prog = run_program(pg_autoctl_program, + "set", "node", "replication-quorum", + "--pgdata", new_spec->pgdata, + quorum, NULL); + + if (prog.returnCode != 0) + { + log_warn("nodespec_apply: set replication-quorum %s failed (rc=%d)", + quorum, prog.returnCode); + if (prog.stdOut) + log_warn("%s", prog.stdOut); + } + else + { + log_info("nodespec: applied replication_quorum = %s", quorum); + changed = true; + } + free_program(&prog); + } + + if (!changed) + log_debug("nodespec_apply: no mutable fields changed"); + + return true; +} + + +/* ----------------------------------------------------------------------- + * Watcher + * ----------------------------------------------------------------------- */ + +/* + * nodespec_watcher_init sets up file watching for *path. + * On Linux we try inotify first; everywhere else (and on failure) we fall + * back to mtime polling every NODESPEC_WATCH_INTERVAL_SECS. + */ +bool +nodespec_watcher_init(NodeSpecWatcher *w, const char *path) +{ + struct stat st; + + memset(w, 0, sizeof(*w)); + strlcpy(w->path, path, sizeof(w->path)); + + w->last_checked = time(NULL); + +#ifdef __linux__ + w->inotify_fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); + + if (w->inotify_fd >= 0) + { + w->watch_fd = inotify_add_watch(w->inotify_fd, path, + IN_CLOSE_WRITE | IN_MOVED_TO); + if (w->watch_fd < 0) + { + log_debug("nodespec_watcher_init: inotify_add_watch(\"%s\"): %m; " + "falling back to mtime poll", path); + close(w->inotify_fd); + w->inotify_fd = -1; + } + else + { + log_info("nodespec: watching \"%s\" via inotify", path); + } + } + else + { + log_debug("nodespec_watcher_init: inotify_init1: %m; " + "falling back to mtime poll"); + w->inotify_fd = -1; + w->watch_fd = -1; + } +#endif + + /* record initial mtime so we don't fire on the very first check */ + if (stat(path, &st) == 0) + w->last_mtime = st.st_mtime; + else + w->last_mtime = 0; + + w->active = true; + return true; +} + + +/* + * nodespec_watcher_check is called from the supervisor's 100 ms tick. + * + * Returns true if the file changed and nodespec_apply() was attempted. + */ +bool +nodespec_watcher_check(NodeSpecWatcher *w, const NodeSpec *current) +{ + bool file_changed = false; + + if (!w->active) + return false; + +#ifdef __linux__ + if (w->inotify_fd >= 0) + { + /* + * Drain all pending inotify events. We don't care about the event + * details — any event means the file was written. + */ + char buf[sizeof(struct inotify_event) + NAME_MAX + 1]; + ssize_t n; + + while ((n = read(w->inotify_fd, buf, sizeof(buf))) > 0) + file_changed = true; + + if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) + { + log_warn("nodespec watcher: inotify read error: %m; " + "switching to mtime poll"); + close(w->inotify_fd); + w->inotify_fd = -1; + w->watch_fd = -1; + } + } + else +#endif + { + /* mtime poll — only stat every NODESPEC_WATCH_INTERVAL_SECS */ + time_t now = time(NULL); + + if (now - w->last_checked < NODESPEC_WATCH_INTERVAL_SECS) + return false; + + w->last_checked = now; + + struct stat st; + if (stat(w->path, &st) == 0 && st.st_mtime != w->last_mtime) + { + w->last_mtime = st.st_mtime; + file_changed = true; + } + } + + if (!file_changed) + return false; + + /* File changed — re-parse and apply */ + log_info("nodespec: \"%s\" changed, re-reading and converging", w->path); + + NodeSpec new_spec = { 0 }; + if (!nodespec_read(w->path, &new_spec)) + { + log_warn("nodespec: failed to parse updated file \"%s\"; " + "keeping current configuration", w->path); + return false; + } + + /* Warn about immutable field changes rather than silently ignoring them */ + if (new_spec.kind != current->kind) + log_warn("nodespec: 'kind' changed in \"%s\" but cannot be applied " + "to a running node — restart required", w->path); + + if (strcmp(new_spec.pgdata, current->pgdata) != 0) + log_warn("nodespec: 'pgdata' changed in \"%s\" but cannot be applied " + "to a running node — restart required", w->path); + + (void) nodespec_apply(&new_spec, current); + return true; +} + + +/* + * nodespec_watcher_close releases inotify resources. + */ +void +nodespec_watcher_close(NodeSpecWatcher *w) +{ +#ifdef __linux__ + if (w->inotify_fd >= 0) + { + close(w->inotify_fd); + w->inotify_fd = -1; + w->watch_fd = -1; + } +#endif + w->active = false; +} diff --git a/src/bin/pg_autoctl/nodespec.h b/src/bin/pg_autoctl/nodespec.h new file mode 100644 index 000000000..3d0f10841 --- /dev/null +++ b/src/bin/pg_autoctl/nodespec.h @@ -0,0 +1,131 @@ +/* + * src/bin/pg_autoctl/nodespec.h + * Declarative node description file (.ini) — read, write, and converge. + * + * A NodeSpec is the in-memory representation of a pg_autoctl_node.ini file. + * It covers all parameters needed to create and run one pg_auto_failover node. + * + * Lifecycle: + * 1. nodespec_read() — parse the file into a NodeSpec + * 2. nodespec_create() — run `pg_autoctl create ` if PGDATA absent + * 3. nodespec_run() — hand off to the normal run path + * 4. nodespec_apply() — converge mutable fields on an already-running node + * + * The supervisor calls nodespec_check_and_apply() on a timer so that editing + * the file and saving it is sufficient to reconfigure a running node. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#ifndef NODESPEC_H +#define NODESPEC_H + +#include +#include +#include + +#include "postgres_fe.h" /* MAXPGPATH, NAMEDATALEN, etc. */ +#include "pgsql.h" /* MAXCONNINFO */ +#include "pgsetup.h" /* PgInstanceKind, NODE_KIND_* */ + +/* + * Fixed location inside every container. The compose generator writes one + * ini file per node and bind-mounts it here. Having a fixed path means the + * Docker image needs only a single CMD: + * + * CMD ["pg_autoctl", "node", "run", PG_AUTOCTL_NODESPEC_PATH] + */ +#define PG_AUTOCTL_NODESPEC_PATH "/etc/pgaf/node.ini" + +/* + * How often the supervisor polls the spec file for changes (seconds). + * inotify/kqueue are used when available; this is the fallback interval. + */ +#define NODESPEC_WATCH_INTERVAL_SECS 10 + +/* ----------------------------------------------------------------------- + * NodeSpec — one-to-one with the [sections] of pg_autoctl_node.ini + * ----------------------------------------------------------------------- */ + +typedef struct NodeSpec +{ + /* [node] */ + PgInstanceKind kind; /* postgres | coordinator | worker | monitor */ + char hostname[_POSIX_HOST_NAME_MAX]; + int port; /* Postgres port, default 5432 */ + + /* [postgresql] */ + char pgdata[MAXPGPATH]; + + /* [monitor] — empty for kind == monitor */ + char monitor_pguri[MAXCONNINFO]; + + /* [formation] */ + char formation[NAMEDATALEN]; /* default "default" */ + int group; /* Citus group; 0 = coordinator */ + + /* [settings] — mutable; applied on SIGHUP / file change */ + int candidate_priority; /* 0-100, default 50 */ + bool replication_quorum; /* sync quorum participant, default true */ + + /* [create] — immutable; used only at pg_autoctl create time */ + char ssl[32]; /* self-signed | cert | off */ + char auth[32]; /* trust | md5 | scram */ + bool pg_hba_lan; /* add --pg-hba-lan flag */ +} NodeSpec; + +/* ----------------------------------------------------------------------- + * File watcher state — embedded in Supervisor + * ----------------------------------------------------------------------- */ + +typedef struct NodeSpecWatcher +{ + bool active; /* true once nodespec_watcher_init() succeeds */ + char path[MAXPGPATH]; /* path of the watched file */ + time_t last_mtime; /* mtime at last check */ + time_t last_checked; /* wall-clock time of last poll */ + +#ifdef __linux__ + int inotify_fd; /* inotify instance fd, -1 if unavailable */ + int watch_fd; /* inotify watch descriptor */ +#endif +} NodeSpecWatcher; + +/* ----------------------------------------------------------------------- + * API + * ----------------------------------------------------------------------- */ + +/* Parse a pg_autoctl_node.ini file into *spec. Returns false on error. */ +bool nodespec_read(const char *path, NodeSpec *spec); + +/* Write *spec as a pg_autoctl_node.ini file (for pg_autoctl node show). */ +bool nodespec_write(const NodeSpec *spec, FILE *out); + +/* Build the argv[] for `pg_autoctl create [flags]`. + * Caller provides args[] with room for at least 32 char* entries. + * Returns the number of entries filled (not counting the trailing NULL). */ +int nodespec_create_argv(const NodeSpec *spec, + const char *pg_autoctl_path, + char **args, int args_size); + +/* Apply mutable fields (candidate_priority, replication_quorum) to a + * running node by calling into the keeper/monitor APIs directly. + * Logs what changed. Returns false only on hard error. */ +bool nodespec_apply(const NodeSpec *new_spec, const NodeSpec *old_spec); + +/* ----------------------------------------------------------------------- + * Watcher — called from supervisor loop + * ----------------------------------------------------------------------- */ + +/* Initialise watcher state. Sets up inotify on Linux if available. */ +bool nodespec_watcher_init(NodeSpecWatcher *w, const char *path); + +/* Called from the supervisor's 100 ms tick. + * Returns true if the file changed and nodespec_apply() was called. */ +bool nodespec_watcher_check(NodeSpecWatcher *w, const NodeSpec *current); + +/* Release inotify fds (called at supervisor shutdown). */ +void nodespec_watcher_close(NodeSpecWatcher *w); + +#endif /* NODESPEC_H */ diff --git a/src/bin/pg_autoctl/supervisor.c b/src/bin/pg_autoctl/supervisor.c index 9e20853d5..c05c19d04 100644 --- a/src/bin/pg_autoctl/supervisor.c +++ b/src/bin/pg_autoctl/supervisor.c @@ -20,6 +20,7 @@ #include "cli_root.h" #include "defaults.h" +#include "nodespec.h" #include "env_utils.h" #include "fsm.h" #include "keeper.h" @@ -76,6 +77,32 @@ supervisor_start(Service services[], int serviceCount, const char *pidfile) /* copy the pidfile over to our supervisor structure */ strlcpy(supervisor.pidfile, pidfile, MAXPGPATH); + /* + * If we were started by `pg_autoctl node run`, the node spec path is + * passed via the PG_AUTOCTL_NODESPEC env var. Set up the file watcher + * so the supervisor can converge mutable settings when the file changes. + */ + { + char specPath[MAXPGPATH] = { 0 }; + + if (env_exists("PG_AUTOCTL_NODESPEC") && + get_env_copy("PG_AUTOCTL_NODESPEC", specPath, sizeof(specPath)) && + !IS_EMPTY_STRING_BUFFER(specPath)) + { + if (nodespec_read(specPath, &supervisor.watchedSpec) && + nodespec_watcher_init(&supervisor.watcher, specPath)) + { + log_info("Supervisor: watching node spec \"%s\"", specPath); + } + else + { + log_warn("Supervisor: failed to initialise node spec watcher " + "for \"%s\"; changes to the file will be ignored", + specPath); + } + } + } + /* * Create our PID file, or quit now if another pg_autoctl instance is * runnning. @@ -219,6 +246,14 @@ supervisor_loop(Supervisor *supervisor) { /* avoid busy looping on waitpid(WNOHANG) */ pg_usleep(100 * 1000); /* 100 ms */ + + /* + * Check if the node spec file has changed and apply mutable + * settings if so. Uses inotify on Linux, mtime poll elsewhere. + * No-op when watcher.active is false (normal run path). + */ + (void) nodespec_watcher_check(&supervisor->watcher, + &supervisor->watchedSpec); } /* ignore errors */ diff --git a/src/bin/pg_autoctl/supervisor.h b/src/bin/pg_autoctl/supervisor.h index ad1350a38..bf0b97a19 100644 --- a/src/bin/pg_autoctl/supervisor.h +++ b/src/bin/pg_autoctl/supervisor.h @@ -12,6 +12,8 @@ #include #include +#include "nodespec.h" + /* * pg_autoctl runs sub-processes as "services", and we need to use the same * service names in several places: @@ -122,6 +124,16 @@ typedef struct Supervisor bool shutdownSequenceInProgress; int shutdownSignal; int stoppingLoopCounter; + + /* + * Optional node spec watcher. When pg_autoctl is started via + * `pg_autoctl node run `, the supervisor watches the ini file for + * changes and converges mutable settings automatically. + * + * watcher.active is false when not in use (normal create/run path). + */ + NodeSpecWatcher watcher; + NodeSpec watchedSpec; /* last-applied spec — baseline for diff */ } Supervisor; diff --git a/src/bin/pgaftest/Makefile b/src/bin/pgaftest/Makefile index 35b98233e..65d0e4d9d 100644 --- a/src/bin/pgaftest/Makefile +++ b/src/bin/pgaftest/Makefile @@ -31,7 +31,7 @@ LOCAL_OBJS = $(patsubst %.c,%.o,$(LOCAL_SRC)) SHARED_SRCS = cli_common.c config.c coordinator.c fsm.c fsm_transition.c \ fsm_transition_citus.c keeper.c keeper_config.c keeper_pg_init.c \ monitor.c monitor_config.c monitor_pg_init.c \ - nodestate_utils.c pghba.c primary_standby.c \ + nodespec.c nodestate_utils.c pghba.c primary_standby.c \ service_keeper.c service_keeper_init.c service_monitor.c \ service_monitor_init.c service_postgres.c service_postgres_ctl.c \ state.c supervisor.c systemd_config.c diff --git a/src/bin/pgaftest/compose_gen.c b/src/bin/pgaftest/compose_gen.c index 8c6d8ba56..c0ced33dc 100644 --- a/src/bin/pgaftest/compose_gen.c +++ b/src/bin/pgaftest/compose_gen.c @@ -1,6 +1,27 @@ /* * src/bin/pgaftest/compose_gen.c - * Generate a docker-compose.yml from a TestCluster spec. + * Generate a docker-compose.yml and per-node pg_autoctl_node.ini files + * from a TestCluster spec. + * + * Design principle — uniform containers + * ====================================== + * Every container in the generated compose file uses: + * - the same Docker image (PGAF_IMAGE env var or a local build) + * - the same command: pg_autoctl node run /etc/pgaf/node.ini + * - the same config file location inside the container + * + * Node-specific behaviour (monitor vs postgres vs coordinator vs worker, + * candidate-priority, replication-quorum, formation, group) is encoded in + * the per-node pg_autoctl_node.ini file, which is bind-mounted into the + * container at /etc/pgaf/node.ini. + * + * This means: + * - No bespoke container command per node type. + * - The running supervisor watches /etc/pgaf/node.ini via inotify/mtime + * and converges mutable settings when the file is edited externally. + * - Changing candidate-priority or replication-quorum for a node is as + * simple as editing the ini file on the host — the container picks it + * up without a restart. * * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the PostgreSQL License. @@ -13,6 +34,8 @@ #include "compose_gen.h" #include "pgsetup.h" #include "log.h" +#include "file_utils.h" /* sformat */ +#include "string_utils.h" /* * Monitor URI used by data nodes to register. @@ -21,18 +44,23 @@ #define MONITOR_PGURI \ "postgresql://autoctl_node@monitor/pg_auto_failover" +/* Fixed path inside every container */ +#define NODE_INI_PATH "/etc/pgaf/node.ini" + +/* Fixed PGDATA location inside every container */ +#define NODE_PGDATA "/var/lib/postgres/pgaf" + + /* - * Emit either an `image:` stanza (when PGAF_IMAGE is set) or a - * `build:` stanza pointing at the project root. - * - * Using PGAF_IMAGE skips the Docker build entirely — useful when the - * caller has already built and tagged an image: - * PGAF_IMAGE=pg_auto_failover:pg17 pgaftest run spec.pgaf + * image_stanza writes either `image:` (when PGAF_IMAGE is set or the cluster + * spec provides an image) or a `build:` stanza. */ static void -write_image_or_build(FILE *f, const char *contextDir) +write_image_stanza(FILE *f, const TestCluster *cluster, const char *contextDir) { - const char *img = getenv("PGAF_IMAGE"); + /* cluster-level image overrides PGAF_IMAGE env var */ + const char *img = cluster->image[0] ? cluster->image : getenv("PGAF_IMAGE"); + if (img && *img) fprintf(f, " image: \"%s\"\n", img); else @@ -43,19 +71,19 @@ write_image_or_build(FILE *f, const char *contextDir) contextDir); } -void -compose_network_name(const char *projectName, char *buf, int buflen) -{ - snprintf(buf, buflen, "%s_default", projectName); -} -void -compose_container_name(const char *projectName, const char *service, - char *buf, int buflen) -{ - snprintf(buf, buflen, "%s-%s-1", projectName, service); -} +/* ----------------------------------------------------------------------- + * compose_gen_write — the docker-compose.yml + * ----------------------------------------------------------------------- */ +/* + * compose_gen_write generates the docker-compose.yml. + * + * Every service uses: + * command: pg_autoctl node run /etc/pgaf/node.ini + * + * The per-node ini file is bind-mounted from the workdir. + */ bool compose_gen_write(const TestCluster *cluster, const char *path, @@ -76,13 +104,14 @@ compose_gen_write(const TestCluster *cluster, /* ---- monitor ---- */ fprintf(f, " monitor:\n"); - write_image_or_build(f, contextDir); + write_image_stanza(f, cluster, contextDir); fprintf(f, " hostname: monitor\n" " volumes:\n" " - monitor_data:/var/lib/postgres:rw\n" + " - ./monitor_node.ini:" NODE_INI_PATH ":ro\n" " environment:\n" - " PGDATA: /var/lib/postgres/pgaf\n" + " PGDATA: " NODE_PGDATA "\n" " ports:\n" " - \"127.0.0.1:%d:5432\"\n" " healthcheck:\n" @@ -92,58 +121,39 @@ compose_gen_write(const TestCluster *cluster, " timeout: 5s\n" " retries: 20\n" " start_period: 30s\n" - " command: >-\n" - " pg_autoctl create monitor\n" - " --ssl-self-signed --auth trust --run\n" - "\n", + " command: [\"pg_autoctl\", \"node\", \"run\", \"" NODE_INI_PATH "\"]\n\n", monitorHostPort); /* ---- data nodes ---- */ for (int i = 0; i < cluster->nodeCount; i++) { const TestNode *n = &cluster->nodes[i]; - const char *pgactl_cmd; - - if (n->kind == NODE_KIND_CITUS_COORDINATOR) - pgactl_cmd = "pg_autoctl create coordinator" - " --ssl-self-signed --auth trust --pg-hba-lan --run"; - else if (n->kind == NODE_KIND_CITUS_WORKER) - { - /* written below with group arg */ - pgactl_cmd = NULL; - } - else - pgactl_cmd = "pg_autoctl create postgres" - " --ssl-self-signed --auth trust --pg-hba-lan --run"; + char ini_filename[128]; + + sformat(ini_filename, sizeof(ini_filename), "%s_node.ini", n->name); fprintf(f, " %s:\n", n->name); - write_image_or_build(f, contextDir); + write_image_stanza(f, cluster, contextDir); fprintf(f, " hostname: %s\n" " volumes:\n" " - %s_data:/var/lib/postgres:rw\n" + " - ./%s:" NODE_INI_PATH ":ro\n" " environment:\n" - " PGDATA: /var/lib/postgres/pgaf\n" + " PGDATA: " NODE_PGDATA "\n" " PGUSER: demo\n" " PGDATABASE: demo\n" - " PG_AUTOCTL_MONITOR: \"%s\"\n" - " PG_AUTOCTL_NODE_NAME: \"%s\"\n" - " PG_AUTOCTL_REPLICATION_QUORUM: \"%s\"\n" - " PG_AUTOCTL_CANDIDATE_PRIORITY: %d\n" " expose:\n" " - 5432\n" " depends_on:\n" " monitor:\n" " condition: service_healthy\n", - n->name, n->name, - MONITOR_PGURI, n->name, - n->replicationQuorum ? "true" : "false", - n->candidatePriority); + n->name, ini_filename); /* - * All nodes after the first also wait for the first node's container - * to start, ensuring node1 registers first and gets nodeid=1. + * Ensure node registration order is deterministic: node1 always + * registers before node2 etc., so node IDs are predictable in tests. */ if (i > 0) fprintf(f, @@ -151,17 +161,9 @@ compose_gen_write(const TestCluster *cluster, " condition: service_started\n", cluster->nodes[0].name); - if (n->kind == NODE_KIND_CITUS_WORKER) - fprintf(f, - " command: >-\n" - " pg_autoctl create worker\n" - " --ssl-self-signed --auth trust --pg-hba-lan" - " --group %d --run\n\n", - n->group); - else - fprintf(f, - " command: \"%s\"\n\n", - pgactl_cmd); + fprintf(f, + " command: [\"pg_autoctl\", \"node\", \"run\"," + " \"" NODE_INI_PATH "\"]\n\n"); } /* ---- volumes ---- */ @@ -174,3 +176,137 @@ compose_gen_write(const TestCluster *cluster, log_info("Wrote docker-compose.yml to \"%s\"", path); return true; } + + +/* ----------------------------------------------------------------------- + * compose_gen_write_monitor_ini + * ----------------------------------------------------------------------- */ + +bool +compose_gen_write_monitor_ini(const TestCluster *cluster, const char *dir) +{ + char path[1024]; + sformat(path, sizeof(path), "%s/monitor_node.ini", dir); + + FILE *f = fopen(path, "w"); + if (!f) + { + log_error("Failed to open \"%s\" for writing: %m", path); + return false; + } + + fprintf(f, + "# Generated by pgaftest — do not edit manually\n" + "# Monitor node configuration\n" + "\n" + "[node]\n" + "kind = monitor\n" + "hostname = monitor\n" + "port = 5432\n" + "\n" + "[postgresql]\n" + "pgdata = " NODE_PGDATA "\n" + "\n" + "[settings]\n" + "candidate_priority = 0\n" + "replication_quorum = false\n" + "\n" + "[create]\n" + "ssl = %s\n" + "auth = %s\n" + "pg_hba_lan = false\n", + cluster->ssl, + cluster->auth); + + fclose(f); + log_info("Wrote monitor_node.ini to \"%s\"", path); + return true; +} + + +/* ----------------------------------------------------------------------- + * compose_gen_write_node_ini + * ----------------------------------------------------------------------- */ + +bool +compose_gen_write_node_ini(const TestCluster *cluster, + const TestNode *node, + const char *dir) +{ + char path[1024]; + sformat(path, sizeof(path), "%s/%s_node.ini", dir, node->name); + + FILE *f = fopen(path, "w"); + if (!f) + { + log_error("Failed to open \"%s\" for writing: %m", path); + return false; + } + + const char *kindStr; + switch (node->kind) + { + case NODE_KIND_CITUS_COORDINATOR: kindStr = "coordinator"; break; + case NODE_KIND_CITUS_WORKER: kindStr = "worker"; break; + default: kindStr = "postgres"; break; + } + + fprintf(f, + "# Generated by pgaftest — do not edit manually\n" + "# Node: %s\n" + "\n" + "[node]\n" + "kind = %s\n" + "hostname = %s\n" + "port = 5432\n" + "\n" + "[postgresql]\n" + "pgdata = " NODE_PGDATA "\n" + "\n" + "[monitor]\n" + "pguri = " MONITOR_PGURI "\n" + "\n" + "[formation]\n" + "name = %s\n" + "group = %d\n" + "\n" + "[settings]\n" + "candidate_priority = %d\n" + "replication_quorum = %s\n" + "\n" + "[create]\n" + "ssl = %s\n" + "auth = %s\n" + "pg_hba_lan = true\n", + node->name, + kindStr, + node->name, + cluster->formation, + node->group, + node->candidatePriority, + node->replicationQuorum ? "true" : "false", + cluster->ssl, + cluster->auth); + + fclose(f); + log_info("Wrote %s_node.ini to \"%s\"", node->name, path); + return true; +} + + +/* ----------------------------------------------------------------------- + * Helpers used by test_runner.c + * ----------------------------------------------------------------------- */ + +void +compose_network_name(const char *projectName, char *buf, int buflen) +{ + snprintf(buf, buflen, "%s_default", projectName); +} + +void +compose_container_name(const char *projectName, const char *service, + char *buf, int buflen) +{ + snprintf(buf, buflen, "%s-%s-1", projectName, service); +} diff --git a/src/bin/pgaftest/compose_gen.h b/src/bin/pgaftest/compose_gen.h index 71ff42950..55989c99b 100644 --- a/src/bin/pgaftest/compose_gen.h +++ b/src/bin/pgaftest/compose_gen.h @@ -24,6 +24,22 @@ bool compose_gen_write(const TestCluster *cluster, int monitorHostPort, const char *contextDir); +/* + * Write a pg_autoctl_node.ini file for the monitor node into `dir`. + * The file is written as

/monitor_node.ini and will be bind-mounted + * into the container at PG_AUTOCTL_NODESPEC_PATH. + */ +bool compose_gen_write_monitor_ini(const TestCluster *cluster, + const char *dir); + +/* + * Write a pg_autoctl_node.ini file for a data node into `dir`. + * The file is written as /name>_node.ini. + */ +bool compose_gen_write_node_ini(const TestCluster *cluster, + const TestNode *node, + const char *dir); + /* Return the docker network name for a project */ void compose_network_name(const char *projectName, char *buf, int buflen); diff --git a/src/bin/pgaftest/pgaftest b/src/bin/pgaftest/pgaftest index 3c38f41d905a38b1a554cf22e00994bdb2b683b9..013cf4af0f94d174bf4005ef76dbf482acd6d6e0 100755 GIT binary patch delta 261111 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 delta 230071 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�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 diff --git a/src/bin/pgaftest/test_runner.c b/src/bin/pgaftest/test_runner.c index 0039240b7..b524ef7c2 100644 --- a/src/bin/pgaftest/test_runner.c +++ b/src/bin/pgaftest/test_runner.c @@ -168,11 +168,30 @@ runner_compose_generate(TestRunner *r) return false; } - return compose_gen_write(&r->spec->cluster, - r->composeFile, - r->projectName, - r->monitorPort, - r->contextDir); + if (!compose_gen_write(&r->spec->cluster, + r->composeFile, + r->projectName, + r->monitorPort, + r->contextDir)) + return false; + + /* + * Write per-node pg_autoctl_node.ini files into the workdir. Each one + * is bind-mounted into its container at /etc/pgaf/node.ini so that + * every container uses the same image and command regardless of role. + */ + if (!compose_gen_write_monitor_ini(&r->spec->cluster, r->workDir)) + return false; + + for (int i = 0; i < r->spec->cluster.nodeCount; i++) + { + if (!compose_gen_write_node_ini(&r->spec->cluster, + &r->spec->cluster.nodes[i], + r->workDir)) + return false; + } + + return true; } static bool diff --git a/src/bin/pgaftest/test_spec.h b/src/bin/pgaftest/test_spec.h index feb55575e..2705785b9 100644 --- a/src/bin/pgaftest/test_spec.h +++ b/src/bin/pgaftest/test_spec.h @@ -38,6 +38,13 @@ typedef struct TestCluster bool withMonitor; /* always true for now */ bool withCitus; int numSync; /* number-sync-standbys, -1 = unset */ + + /* cluster-level Docker / network options */ + char image[256]; /* Docker image tag; "" = build from source */ + char ssl[32]; /* self-signed | cert | off; default self-signed */ + char auth[32]; /* trust | md5 | scram; default trust */ + char formation[64]; /* formation name; default "default" */ + int monitorHostPort; /* host-side port mapped to monitor:5432; 0 = auto */ } TestCluster; /* ----------------------------------------------------------------------- diff --git a/src/bin/pgaftest/test_spec_parse.c b/src/bin/pgaftest/test_spec_parse.c index 7d2c793da..56565a55a 100644 --- a/src/bin/pgaftest/test_spec_parse.c +++ b/src/bin/pgaftest/test_spec_parse.c @@ -617,7 +617,7 @@ static const yytype_int8 yyrhs[] = static const yytype_uint16 yyrline[] = { 0, 171, 171, 172, 176, 177, 178, 179, 180, 188, - 265, 272, 283, 293, 414, 417, 419, 438, 439 + 309, 316, 327, 337, 458, 461, 463, 482, 483 }; #endif @@ -1549,47 +1549,92 @@ yyparse () char *text = (yyvsp[(2) - (2)].str); char *line = strtok(text, "\n"); - current_spec->cluster.withMonitor = true; - current_spec->cluster.numSync = -1; + TestCluster *cl = ¤t_spec->cluster; + cl->withMonitor = true; + cl->numSync = -1; + /* cluster-level defaults */ + strlcpy(cl->ssl, "self-signed", sizeof(cl->ssl)); + strlcpy(cl->auth, "trust", sizeof(cl->auth)); + strlcpy(cl->formation, "default", sizeof(cl->formation)); + cl->monitorHostPort = 0; /* 0 = auto-assigned by runner */ while (line) { - /* skip leading whitespace */ + /* skip leading whitespace and comment lines */ while (*line == ' ' || *line == '\t') line++; + if (*line == '#' || *line == '\0') { line = strtok(NULL, "\n"); continue; } - if (strncmp(line, "monitor", 7) == 0) + if (strncmp(line, "image", 5) == 0) { - current_spec->cluster.withMonitor = true; + /* image "pg_auto_failover:pg17" or image pg_auto_failover:pg17 */ + char val[256] = { 0 }; + const char *p = line + 5; + while (*p == ' ' || *p == '\t') p++; + if (*p == '"') + sscanf(p, "\"%255[^\"]\"", val); + else + sscanf(p, "%255s", val); + strlcpy(cl->image, val, sizeof(cl->image)); + } + else if (strncmp(line, "ssl", 3) == 0) + { + char val[32] = { 0 }; + sscanf(line + 3, " %31s", val); + strlcpy(cl->ssl, val, sizeof(cl->ssl)); + } + else if (strncmp(line, "auth", 4) == 0) + { + char val[32] = { 0 }; + sscanf(line + 4, " %31s", val); + strlcpy(cl->auth, val, sizeof(cl->auth)); + } + else if (strncmp(line, "formation", 9) == 0) + { + char val[64] = { 0 }; + const char *p = line + 9; + while (*p == ' ' || *p == '\t') p++; + if (*p == '"') + sscanf(p, "\"%63[^\"]\"", val); + else + sscanf(p, "%63s", val); + strlcpy(cl->formation, val, sizeof(cl->formation)); + } + else if (strncmp(line, "num-sync", 8) == 0) + { + sscanf(line + 8, " %d", &cl->numSync); + } + else if (strncmp(line, "monitor", 7) == 0) + { + cl->withMonitor = true; + /* optional: monitor [port 15432] */ + char *pp = strstr(line, "port"); + if (pp) cl->monitorHostPort = atoi(pp + 4); } else if (strncmp(line, "citus-coordinator", 17) == 0) { - TestNode *n = ¤t_spec->cluster.nodes[ - current_spec->cluster.nodeCount++]; + TestNode *n = &cl->nodes[cl->nodeCount++]; sscanf(line + 18, "%63s", n->name); n->kind = NODE_KIND_CITUS_COORDINATOR; n->group = 0; n->candidatePriority = 50; n->replicationQuorum = true; - current_spec->cluster.withCitus = true; + cl->withCitus = true; } else if (strncmp(line, "citus-worker", 12) == 0) { - TestNode *n = ¤t_spec->cluster.nodes[ - current_spec->cluster.nodeCount++]; + TestNode *n = &cl->nodes[cl->nodeCount++]; char rest[256]; sscanf(line + 13, "%63s %255[^\n]", n->name, rest); n->kind = NODE_KIND_CITUS_WORKER; n->candidatePriority = 50; n->replicationQuorum = true; - /* parse group=N from rest */ char *gp = strstr(rest, "group="); if (gp) n->group = atoi(gp + 6); - current_spec->cluster.withCitus = true; + cl->withCitus = true; } else if (strncmp(line, "node", 4) == 0) { - TestNode *n = ¤t_spec->cluster.nodes[ - current_spec->cluster.nodeCount++]; + TestNode *n = &cl->nodes[cl->nodeCount++]; n->kind = NODE_KIND_STANDALONE; n->candidatePriority = 50; n->replicationQuorum = true; @@ -1597,7 +1642,6 @@ yyparse () char rest[256] = { 0 }; sscanf(line + 5, "%63s %255[^\n]", n->name, rest); - /* parse options: candidate-priority=N async */ char *cp = strstr(rest, "candidate-priority="); if (cp) n->candidatePriority = atoi(cp + 19); @@ -1612,21 +1656,21 @@ yyparse () break; case 10: -#line 266 "test_spec_parse.y" +#line 310 "test_spec_parse.y" { current_spec->setup = (yyvsp[(2) - (2)].step); ;} break; case 11: -#line 273 "test_spec_parse.y" +#line 317 "test_spec_parse.y" { current_spec->teardown = (yyvsp[(2) - (2)].step); ;} break; case 12: -#line 284 "test_spec_parse.y" +#line 328 "test_spec_parse.y" { TestStep *s = (yyvsp[(3) - (3)].step); strncpy(s->name, (yyvsp[(2) - (3)].str), sizeof(s->name) - 1); @@ -1636,7 +1680,7 @@ yyparse () break; case 13: -#line 294 "test_spec_parse.y" +#line 338 "test_spec_parse.y" { /* * Parse the block text into a linked list of TestCmd. @@ -1753,7 +1797,7 @@ yyparse () break; case 16: -#line 420 "test_spec_parse.y" +#line 464 "test_spec_parse.y" { int i = current_spec->sequenceLength; if (i < PGAF_MAX_SEQ) @@ -1768,18 +1812,18 @@ yyparse () break; case 17: -#line 438 "test_spec_parse.y" +#line 482 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; case 18: -#line 439 "test_spec_parse.y" +#line 483 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; /* Line 1267 of yacc.c. */ -#line 1783 "test_spec_parse.c" +#line 1827 "test_spec_parse.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -1993,7 +2037,7 @@ yyparse () } -#line 442 "test_spec_parse.y" +#line 486 "test_spec_parse.y" /* ----------------------------------------------------------------------- diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y index 6c9e8b868..52e358da4 100644 --- a/src/bin/pgaftest/test_spec_parse.y +++ b/src/bin/pgaftest/test_spec_parse.y @@ -195,47 +195,92 @@ cluster_block: char *text = $2; char *line = strtok(text, "\n"); - current_spec->cluster.withMonitor = true; - current_spec->cluster.numSync = -1; + TestCluster *cl = ¤t_spec->cluster; + cl->withMonitor = true; + cl->numSync = -1; + /* cluster-level defaults */ + strlcpy(cl->ssl, "self-signed", sizeof(cl->ssl)); + strlcpy(cl->auth, "trust", sizeof(cl->auth)); + strlcpy(cl->formation, "default", sizeof(cl->formation)); + cl->monitorHostPort = 0; /* 0 = auto-assigned by runner */ while (line) { - /* skip leading whitespace */ + /* skip leading whitespace and comment lines */ while (*line == ' ' || *line == '\t') line++; + if (*line == '#' || *line == '\0') { line = strtok(NULL, "\n"); continue; } - if (strncmp(line, "monitor", 7) == 0) + if (strncmp(line, "image", 5) == 0) { - current_spec->cluster.withMonitor = true; + /* image "pg_auto_failover:pg17" or image pg_auto_failover:pg17 */ + char val[256] = { 0 }; + const char *p = line + 5; + while (*p == ' ' || *p == '\t') p++; + if (*p == '"') + sscanf(p, "\"%255[^\"]\"", val); + else + sscanf(p, "%255s", val); + strlcpy(cl->image, val, sizeof(cl->image)); + } + else if (strncmp(line, "ssl", 3) == 0) + { + char val[32] = { 0 }; + sscanf(line + 3, " %31s", val); + strlcpy(cl->ssl, val, sizeof(cl->ssl)); + } + else if (strncmp(line, "auth", 4) == 0) + { + char val[32] = { 0 }; + sscanf(line + 4, " %31s", val); + strlcpy(cl->auth, val, sizeof(cl->auth)); + } + else if (strncmp(line, "formation", 9) == 0) + { + char val[64] = { 0 }; + const char *p = line + 9; + while (*p == ' ' || *p == '\t') p++; + if (*p == '"') + sscanf(p, "\"%63[^\"]\"", val); + else + sscanf(p, "%63s", val); + strlcpy(cl->formation, val, sizeof(cl->formation)); + } + else if (strncmp(line, "num-sync", 8) == 0) + { + sscanf(line + 8, " %d", &cl->numSync); + } + else if (strncmp(line, "monitor", 7) == 0) + { + cl->withMonitor = true; + /* optional: monitor [port 15432] */ + char *pp = strstr(line, "port"); + if (pp) cl->monitorHostPort = atoi(pp + 4); } else if (strncmp(line, "citus-coordinator", 17) == 0) { - TestNode *n = ¤t_spec->cluster.nodes[ - current_spec->cluster.nodeCount++]; + TestNode *n = &cl->nodes[cl->nodeCount++]; sscanf(line + 18, "%63s", n->name); n->kind = NODE_KIND_CITUS_COORDINATOR; n->group = 0; n->candidatePriority = 50; n->replicationQuorum = true; - current_spec->cluster.withCitus = true; + cl->withCitus = true; } else if (strncmp(line, "citus-worker", 12) == 0) { - TestNode *n = ¤t_spec->cluster.nodes[ - current_spec->cluster.nodeCount++]; + TestNode *n = &cl->nodes[cl->nodeCount++]; char rest[256]; sscanf(line + 13, "%63s %255[^\n]", n->name, rest); n->kind = NODE_KIND_CITUS_WORKER; n->candidatePriority = 50; n->replicationQuorum = true; - /* parse group=N from rest */ char *gp = strstr(rest, "group="); if (gp) n->group = atoi(gp + 6); - current_spec->cluster.withCitus = true; + cl->withCitus = true; } else if (strncmp(line, "node", 4) == 0) { - TestNode *n = ¤t_spec->cluster.nodes[ - current_spec->cluster.nodeCount++]; + TestNode *n = &cl->nodes[cl->nodeCount++]; n->kind = NODE_KIND_STANDALONE; n->candidatePriority = 50; n->replicationQuorum = true; @@ -243,7 +288,6 @@ cluster_block: char rest[256] = { 0 }; sscanf(line + 5, "%63s %255[^\n]", n->name, rest); - /* parse options: candidate-priority=N async */ char *cp = strstr(rest, "candidate-priority="); if (cp) n->candidatePriority = atoi(cp + 19); From c896747ebd221ca165d6eb0cbbfcf5306b2118cc Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 21:44:24 +0200 Subject: [PATCH 11/48] docs: pg_autoctl node spec file, node commands, pgaftest spec DSL Add three new documentation items: docs/ref/pg_autoctl_node.rst Full reference for the pg_autoctl node subcommand tree (run / apply / show / check) and the pg_autoctl_node.ini file format. Covers every section and field, immutable-vs-mutable distinction, live-reconfiguration semantics (inotify on Linux, mtime poll elsewhere), and Docker Compose / Kubernetes usage patterns. docs/pgaftest.rst Reference chapter for the .pgaf test specification DSL: - cluster { } block with all options (image, ssl, auth, formation, num-sync, monitor port, node declarations) - setup / teardown / step / sequence blocks - Full DSL command reference: exec, wait until, assert, sql, expect, network disconnect/connect, sleep, compose down - TAP output format and exit codes - Running a test suite (schedule file, single file, interactive) - Environment variables (PGAF_IMAGE) - How pgaftest and pg_autoctl node interact (live reconfig) - Complete example spec (basic failover test) docs/index.rst Add 'Testing' toctree section pointing at pgaftest.rst and add pg_autoctl_node.rst to the Manual Pages section. --- docs/index.rst | 7 + docs/pgaftest.rst | 532 +++++++++++++++++++++++++++++++++++ docs/ref/pg_autoctl_node.rst | 404 ++++++++++++++++++++++++++ 3 files changed, 943 insertions(+) create mode 100644 docs/pgaftest.rst create mode 100644 docs/ref/pg_autoctl_node.rst diff --git a/docs/index.rst b/docs/index.rst index 4e8d8481e..65a7b3a02 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -63,12 +63,19 @@ __ https://github.com/hapostgres/pg_auto_failover citus citus-quickstart +.. toctree:: + :hidden: + :caption: Testing + + pgaftest + .. toctree:: :hidden: :caption: Manual Pages ref/manual ref/configuration + ref/pg_autoctl_node .. toctree:: :hidden: diff --git a/docs/pgaftest.rst b/docs/pgaftest.rst new file mode 100644 index 000000000..af92a1500 --- /dev/null +++ b/docs/pgaftest.rst @@ -0,0 +1,532 @@ +.. _pgaftest: + +pgaftest — Integration Test Framework +====================================== + +``pgaftest`` is the integration-test binary for pg_auto_failover. It reads +``.pgaf`` specification files that describe a cluster topology and a sequence +of named test steps, then drives a Docker Compose stack to verify the cluster +behaves correctly. + +The same specification file works in two modes: + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Command + - Effect + * - ``pgaftest run spec.pgaf`` + - Headless CI: start → setup → sequence → teardown → TAP output + exit code + * - ``pgaftest setup spec.pgaf`` + - Interactive: start cluster, run setup, then drop into a shell or tmux session + +Quick start +----------- + +.. code-block:: bash + + # Build the pg_auto_failover Docker image once + docker build -t pg_auto_failover:pg17 . + + # Run a spec file headlessly + PGAF_IMAGE=pg_auto_failover:pg17 pgaftest run tests/tap/specs/basic_operation.pgaf + + # Start a cluster interactively + PGAF_IMAGE=pg_auto_failover:pg17 pgaftest setup tests/tap/specs/basic_operation.pgaf + + # Run one named step against the live cluster + pgaftest step fail_primary --work-dir /tmp/pgaftest-work + + # Tear down + pgaftest down --work-dir /tmp/pgaftest-work + +.. _pgaftest_spec: + +Spec file format +---------------- + +A ``.pgaf`` file contains four kinds of top-level blocks: + +1. ``cluster { }`` — topology declaration +2. ``setup { }`` — commands to run after ``docker compose up`` +3. ``teardown { }`` — commands to run at the end of a run (or on ``pgaftest down``) +4. ``step { }`` — named test step +5. ``sequence`` — ordered list of step names for CI mode + +cluster { } +~~~~~~~~~~~ + +The ``cluster`` block describes the Docker Compose topology. ``pgaftest`` +generates: + +* A ``docker-compose.yml`` with one service per node +* A ``pg_autoctl_node.ini`` file per node (see :ref:`node_spec_format`) +* Each container mounts its ini file at ``/etc/pgaf/node.ini`` and runs the + same command: ``pg_autoctl node run /etc/pgaf/node.ini`` + +**Syntax** + +.. code-block:: text + + cluster { + # Cluster-level options (all optional) + image "pg_auto_failover:pg17" # Docker image tag; "" = build from source + ssl self-signed # self-signed | cert | off + auth trust # trust | md5 | scram + formation "default" # formation name + num-sync 1 # number-sync-standbys + monitor [port 15432] # expose monitor on host port; 0 = auto + + # Node declarations + monitor + node [candidate-priority=N] [async] + citus-coordinator + citus-worker group=N + } + +**Cluster-level options** + +``image`` + Docker image to use for every container. Overrides the ``PGAF_IMAGE`` + environment variable. When neither is set, a ``build:`` stanza pointing at + the project root is used instead. + + .. code-block:: text + + image "pg_auto_failover:pg17" + +``ssl`` + SSL mode written into the ``[create]`` section of each node's ini file. + Allowed values: ``self-signed`` (default), ``cert``, ``off``. + +``auth`` + Authentication method. Passed as ``--auth`` to ``pg_autoctl create``. + Default: ``trust``. + +``formation`` + Formation name on the monitor. Default: ``default``. + +``num-sync`` + Sets ``number-sync-standbys`` on the monitor formation after the cluster + comes up. When absent, the monitor default applies. + +``monitor [port N]`` + Declares the monitor service. The optional ``port N`` exposes the + monitor's Postgres port on host port ``N`` so the test runner can connect + directly with libpq. When omitted, a random free port is chosen. + +**Node declarations** + +``node [candidate-priority=N] [async]`` + A standalone (non-Citus) Postgres node. + + * ``candidate-priority=N`` — integer 0–100; default 50. ``0`` prevents + this node from ever being elected primary. + * ``async`` — makes this node asynchronous (``replication_quorum = false``). + +``citus-coordinator `` + A Citus coordinator node. Exactly one per cluster. + +``citus-worker group=N`` + A Citus worker node belonging to Citus group ``N``. Multiple workers + can share the same group to form an HA pair. + +**Examples** + +Minimal two-node HA cluster: + +.. code-block:: text + + cluster { + monitor + node node1 + node node2 + } + +Three-node cluster with a non-candidate standby: + +.. code-block:: text + + cluster { + monitor + node node1 + node node2 + node node3 candidate-priority=0 + } + +Three nodes, one asynchronous (does not block writes): + +.. code-block:: text + + cluster { + monitor + node node1 + node node2 + node node3 async + num-sync 1 + } + +Citus cluster (one coordinator, two worker HA pairs): + +.. code-block:: text + + cluster { + image "pg_auto_failover:pg17-citus" + monitor + citus-coordinator coord + citus-worker worker1 group=1 + citus-worker worker2 group=1 + citus-worker worker3 group=2 + citus-worker worker4 group=2 + } + +Custom image and non-default auth: + +.. code-block:: text + + cluster { + image "myregistry.example.com/pgaf:latest" + ssl self-signed + auth scram-sha-256 + monitor [port 15432] + node node1 + node node2 + } + +setup { } and teardown { } +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These blocks contain the same DSL commands as named steps (see below). +``setup`` runs after ``docker compose up -d``, before the first step. +``teardown`` runs at the end of ``pgaftest run`` (always, even on failure) +and at the end of ``pgaftest down`` in interactive mode. + +A typical setup block waits for all nodes to reach their initial states: + +.. code-block:: text + + setup { + wait until node1 state = primary timeout 120s + wait until node2 state = secondary timeout 120s + } + +step { } +~~~~~~~~~~~~~~~ + +Named blocks of commands that can be run individually (``pgaftest step``) or +collectively via the ``sequence`` directive. + +.. code-block:: text + + step my_step { + + + ... + } + +sequence +~~~~~~~~ + +Declares the ordered list of steps to run in CI mode (``pgaftest run``). +Each step name appears on its own line or space-separated: + +.. code-block:: text + + sequence + create_table + fail_primary + check_failover + restart_old_primary + +Step commands (DSL reference) +------------------------------ + +All commands are available inside ``setup``, ``teardown``, and ``step`` blocks. + +``exec `` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run a command inside a running container via ``docker compose exec``. + +.. code-block:: text + + exec node1 pg_autoctl perform failover + exec monitor psql -c "SELECT count(*) FROM pgautofailover.node" + +``wait until state = [timeout Ns]`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Poll the monitor until ```` reports ````. The timeout defaults +to 90 seconds. Fails the current step if the timeout expires. + +.. code-block:: text + + wait until node1 state = primary timeout 120s + wait until node2 state = secondary timeout 60s + wait until node2 state = wait_primary + +Valid state names are the pg_auto_failover FSM states: ``primary``, +``secondary``, ``wait_primary``, ``draining``, ``demoted``, +``maintenance``, ``join_primary``, ``catchingup``, etc. + +``assert state = `` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Immediately check that ```` is in ```` on the monitor. Fails +the step if the state does not match. No polling. + +.. code-block:: text + + assert node2 state = primary + assert node1 assigned-state = secondary + +``assert assigned-state = `` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Like ``assert state`` but checks the ``assigned_state`` column on the monitor +rather than ``reportedstate``. + +``sql { SQL }`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run SQL inside ````'s container and capture the output. Use a +multi-line ``{ ... }`` block for multi-statement SQL. + +.. code-block:: text + + sql node1 { + CREATE TABLE t1 (a int); + INSERT INTO t1 VALUES (1), (2), (3); + } + sql node2 { SELECT count(*) FROM t1; } + +``expect { text }`` +~~~~~~~~~~~~~~~~~~~~ + +Compare the output of the most recent ``sql`` command against ``text``. +Fails the step when the output does not match. Whitespace is normalised. + +.. code-block:: text + + sql node2 { SELECT count(*) FROM t1; } + expect { 3 } + +``network disconnect `` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Disconnect ````'s container from the Docker network, simulating a +network partition. + +.. code-block:: text + + network disconnect node1 + +``network connect `` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Reconnect a previously disconnected container. + +.. code-block:: text + + network connect node1 + +``sleep Ns`` +~~~~~~~~~~~~~ + +Wait ``N`` seconds (for example ``sleep 5s`` or ``sleep 30s``). + +``compose down`` +~~~~~~~~~~~~~~~~ + +Run ``docker compose down --volumes``. Used inside ``teardown { }`` to clean +up after a test run. + +.. code-block:: text + + teardown { + compose down + } + +TAP output +---------- + +In CI mode (``pgaftest run``) the runner emits +`TAP `_ (Test Anything Protocol) output to stdout. +One TAP line is emitted per step: + +.. code-block:: text + + 1..5 + ok 1 - create_table + ok 2 - fail_primary + not ok 3 - check_failover + # FAIL: wait until node2 state = primary: timed out after 120s (current: demoted) + ok 4 - restart_old_primary + ok 5 - verify_replication + +Each failing step logs a ``# FAIL: …`` diagnostic line with the exact command +that failed. Standard TAP consumers (``prove``, GitHub Actions, Jenkins) can +parse this output directly. + +The exit code is ``0`` when all steps passed and non-zero otherwise. + +Complete example — basic failover test +--------------------------------------- + +The following is a complete spec file that creates a two-node cluster, +verifies replication, triggers a failover, and checks recovery. + +.. code-block:: text + + # tests/tap/specs/basic_operation.pgaf + # + # Two-node HA: create primary + secondary, test failover and recovery. + + cluster { + monitor + node node1 + node node2 + } + + setup { + wait until node1 state = primary timeout 120s + wait until node2 state = secondary timeout 120s + } + + teardown { + compose down + } + + # --------------------------------------------------------------- + # Verify that data written on the primary appears on the standby. + # --------------------------------------------------------------- + + step create_table { + sql node1 { + CREATE TABLE t1(a int); + INSERT INTO t1 VALUES (1), (2), (3); + } + sql node2 { SELECT count(*) FROM t1; } + expect { 3 } + } + + # --------------------------------------------------------------- + # Trigger a failover by stopping the primary's pg_autoctl process. + # --------------------------------------------------------------- + + step fail_primary { + exec node1 pg_autoctl stop + } + + step check_failover { + wait until node2 state = wait_primary timeout 120s + wait until node2 state = primary timeout 120s + assert node2 state = primary + } + + step restart_old_primary { + exec node1 pg_autoctl node run /etc/pgaf/node.ini + wait until node1 state = secondary timeout 120s + } + + step verify_replication { + sql node2 { + INSERT INTO t1 VALUES (4), (5); + } + sql node1 { SELECT count(*) FROM t1; } + expect { 5 } + } + + sequence + create_table + fail_primary + check_failover + restart_old_primary + verify_replication + +Running the test suite +---------------------- + +A ``schedule`` file lists the spec files to run, one per line: + +.. code-block:: text + + # tests/tap/schedule + tests/tap/specs/basic_operation.pgaf + tests/tap/specs/multi_standbys.pgaf + +Run all specs in the schedule: + +.. code-block:: bash + + PGAF_IMAGE=pg_auto_failover:pg17 \ + pgaftest run --schedule tests/tap/schedule + +Run a single spec file: + +.. code-block:: bash + + PGAF_IMAGE=pg_auto_failover:pg17 \ + pgaftest run tests/tap/specs/basic_operation.pgaf + +Interactive session (useful for debugging): + +.. code-block:: bash + + # Start the cluster and drop into a shell + PGAF_IMAGE=pg_auto_failover:pg17 \ + pgaftest setup tests/tap/specs/basic_operation.pgaf + + # In a separate terminal, run individual steps + pgaftest step create_table --work-dir /tmp/pgaftest-work + pgaftest step fail_primary --work-dir /tmp/pgaftest-work + pgaftest step check_failover --work-dir /tmp/pgaftest-work + + # Tear down when done + pgaftest down --work-dir /tmp/pgaftest-work + +Environment variables +--------------------- + +``PGAF_IMAGE`` + Docker image tag to use for all containers. Overrides the ``image`` + directive in the ``cluster { }`` block. When neither is set, ``pgaftest`` + uses a ``build:`` stanza pointing at the project root, which triggers a + local Docker build. + + .. code-block:: bash + + export PGAF_IMAGE=pg_auto_failover:pg17 + +How pgaftest and pg_autoctl node relate +---------------------------------------- + +``pgaftest`` uses ``pg_autoctl node run /etc/pgaf/node.ini`` as the container +command, which means every container benefits from the :ref:`live +reconfiguration ` feature: editing a node's ini file +on the host and saving it causes the running supervisor inside the container +to converge the changed settings within seconds (inotify) or within +``NODESPEC_WATCH_INTERVAL_SECS`` (10 s, on platforms without inotify). + +This is particularly useful during interactive sessions. For example, to +change ``node2``'s candidate priority without restarting the container: + +.. code-block:: bash + + # Edit the generated ini file in the work directory + sed -i 's/candidate_priority = 50/candidate_priority = 0/' \ + /tmp/pgaftest-work/node2_node.ini + + # The supervisor inside node2 picks up the change automatically. + # Verify on the monitor: + docker compose exec monitor \ + pg_autoctl get node candidate-priority --pgdata /var/lib/postgres/pgaf + +See also +-------- + +* :ref:`pg_autoctl_node` — the ``pg_autoctl node run`` command and node spec + file format used by every container that ``pgaftest`` starts +* :ref:`pg_autoctl_create_postgres` +* :ref:`pg_autoctl_perform_failover` diff --git a/docs/ref/pg_autoctl_node.rst b/docs/ref/pg_autoctl_node.rst new file mode 100644 index 000000000..028a20ff3 --- /dev/null +++ b/docs/ref/pg_autoctl_node.rst @@ -0,0 +1,404 @@ +.. _pg_autoctl_node: + +pg_autoctl node +=============== + +pg_autoctl node - Declarative node lifecycle driven by a configuration file + +Synopsis +-------- + +:: + + pg_autoctl node + run Create (if needed) and run from a node spec file + apply Apply mutable settings to a running node + show [ --pgdata ] Dump current config as a node spec file + check Validate a node spec file without creating anything + +Description +----------- + +The ``pg_autoctl node`` command group replaces the manual composition of +``pg_autoctl create [options] --run`` and provides a single declarative +interface for the full lifecycle of a pg_auto_failover node: + +1. **Create** — if ``PGDATA`` does not yet contain a ``pg_autoctl.cfg``, run + the equivalent of ``pg_autoctl create `` using the options in the + file. + +2. **Run** — hand off to the pg_autoctl supervisor loop, which then manages + the Postgres and service subprocesses. + +3. **Watch** — the supervisor watches the node spec file for changes and + automatically **converges mutable settings** (``candidate_priority``, + ``replication_quorum``) without requiring a node restart. + +The node spec file is a small INI file that collects all node parameters. +The default path inside a Docker/Kubernetes container is +``/etc/pgaf/node.ini``. A Docker image built from the pg_auto_failover +project can use a single ``CMD``: + +.. code-block:: dockerfile + + CMD ["pg_autoctl", "node", "run", "/etc/pgaf/node.ini"] + +pg_autoctl node run +------------------- + +:: + + usage: pg_autoctl node run + + Path to the pg_autoctl_node.ini file. + Defaults to /etc/pgaf/node.ini when no argument is given. + +**First start (node not yet created):** +Builds and executes the equivalent of:: + + pg_autoctl create \ + --pgdata \ + --hostname \ + --pgport \ + --monitor \ + --formation \ + --ssl-self-signed \ # or --no-ssl, depending on [create] ssl = + --auth trust \ + --pg-hba-lan \ + --run + +**Subsequent starts (node already created):** +Reads the spec file, applies any changed mutable settings (``candidate_priority``, +``replication_quorum``), then executes ``pg_autoctl run --pgdata ``. + +Before executing, ``pg_autoctl node run`` sets the environment variable +``PG_AUTOCTL_NODESPEC`` to the path of the spec file. The supervisor process +(PID 1 in Docker/Kubernetes) reads this variable at start-up and initialises a +file watcher so that later edits to the spec file are picked up without +restarting the supervisor. + +pg_autoctl node apply +--------------------- + +:: + + usage: pg_autoctl node apply + +Reads the node spec file and compares the mutable section (``[settings]``) +against the node's current configuration. For each changed field it runs the +appropriate ``pg_autoctl set node`` sub-command: + +.. list-table:: + :header-rows: 1 + + * - INI field + - pg_autoctl sub-command + * - ``candidate_priority`` + - ``pg_autoctl set node candidate-priority`` + * - ``replication_quorum`` + - ``pg_autoctl set node replication-quorum`` + +Use this command when the supervisor is not running (for example, in a +scripted maintenance window) to reconcile the monitor's view of the node with +a freshly edited spec file. + +pg_autoctl node show +-------------------- + +:: + + usage: pg_autoctl node show [ --pgdata ] + +Reads the local ``pg_autoctl.cfg`` configuration file and prints it in +``pg_autoctl_node.ini`` format on stdout. Useful for bootstrapping a spec +file from an existing node that was created with ``pg_autoctl create``. + +Example:: + + $ pg_autoctl node show --pgdata /var/lib/postgres/pgaf > node.ini + +pg_autoctl node check +--------------------- + +:: + + usage: pg_autoctl node check + +Parses and validates the spec file without creating or modifying anything. +Prints a summary of all resolved fields. Exit code is non-zero when the file +is invalid or a required field is missing. + +Example output:: + + Node spec "/etc/pgaf/node.ini" is valid. + kind : postgres + pgdata : /var/lib/postgres/pgaf + hostname : node1 + port : 5432 + monitor_pguri : postgresql://autoctl_node@monitor/pg_auto_failover + formation : default + group : 0 + candidate_priority : 50 + replication_quorum : true + ssl : self-signed + auth : trust + pg_hba_lan : true + +.. _node_spec_format: + +Node spec file format (pg_autoctl_node.ini) +------------------------------------------- + +The node spec file uses a simple INI syntax with five sections. Lines +beginning with ``#`` are comments. + +.. code-block:: ini + + # pg_autoctl_node.ini — describes a single pg_auto_failover node. + # Feed to: pg_autoctl node run /etc/pgaf/node.ini + # Edit and save to converge mutable settings on the running node. + + [node] + kind = postgres # postgres | monitor | coordinator | worker + hostname = node1 # reported to the monitor; default: system hostname + port = 5432 # Postgres port + + [postgresql] + pgdata = /var/lib/postgres/pgaf + + [monitor] + # Required for kind != monitor. Empty for monitor nodes. + pguri = postgresql://autoctl_node@monitor/pg_auto_failover + + [formation] + name = default # formation name; default "default" + group = 0 # Citus group id; 0 = coordinator group + + [settings] + # These fields are mutable. Edit and save to apply without a restart. + candidate_priority = 50 # 0–100; 0 = never a failover candidate + replication_quorum = true # participates in the synchronous replication quorum + + [create] + # These fields are immutable after the node is created. + # They are only used during the first-ever pg_autoctl create run. + ssl = self-signed # self-signed | cert | off + auth = trust # trust | md5 | scram + pg_hba_lan = true # add --pg-hba-lan at create time (allow LAN connections) + +Sections and fields +~~~~~~~~~~~~~~~~~~~ + +``[node]`` +^^^^^^^^^^ + +``kind`` + Node role. One of: ``monitor``, ``postgres``, ``coordinator``, ``worker``. + Determines which ``pg_autoctl create`` sub-command is used. Immutable + after the node is created. + +``hostname`` + Hostname or IP address reported to the pg_auto_failover monitor. Other + nodes use this to reach Postgres. Mutable in the ``[node]`` section but + requires a monitor metadata update (``pg_autoctl set node metadata``) to + take effect on a running node; the file watcher does **not** apply hostname + changes automatically. Defaults to the system hostname when empty. + +``port`` + Postgres port number. Defaults to ``5432``. Immutable after creation. + +``[postgresql]`` +^^^^^^^^^^^^^^^^ + +``pgdata`` + Absolute path to the Postgres data directory. Immutable after creation. + +``[monitor]`` +^^^^^^^^^^^^^ + +``pguri`` + Connection string the node uses to reach the pg_auto_failover monitor. + Required for all ``kind`` values except ``monitor``. Example:: + + pguri = postgresql://autoctl_node@monitor/pg_auto_failover + +``[formation]`` +^^^^^^^^^^^^^^^ + +``name`` + Formation name on the monitor. Defaults to ``default``. + +``group`` + Citus group id. Meaningful only for ``kind = coordinator`` (always ``0``) + and ``kind = worker`` (``1``, ``2``, …). Ignored for other node kinds. + +``[settings]`` — mutable +^^^^^^^^^^^^^^^^^^^^^^^^ + +``candidate_priority`` + Failover candidate priority, ``0``–``100``. ``0`` means the node is never + promoted; ``100`` means it is the preferred candidate. Default ``50``. + + Editing this field and saving the file causes the supervisor to call + ``pg_autoctl set node candidate-priority`` within 10 seconds (or + immediately on Linux systems that support inotify). + +``replication_quorum`` + ``true`` or ``false``. When ``true`` the node participates in the + synchronous replication quorum controlled by + ``synchronous_standby_names``. Default ``true``. + + Editing this field and saving the file causes the supervisor to call + ``pg_autoctl set node replication-quorum``. + +``[create]`` — immutable after creation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``ssl`` + SSL mode used at create time. One of: + + * ``self-signed`` — ``pg_autoctl`` generates a self-signed certificate + and enables SSL (``--ssl-self-signed``). + * ``cert`` — SSL is enabled; certificate files must already be in place. + * ``off`` — no SSL (``--no-ssl``). + +``auth`` + Authentication method passed as ``--auth`` to ``pg_autoctl create``. + Common values: ``trust``, ``md5``, ``scram-sha-256``. + +``pg_hba_lan`` + When ``true``, pass ``--pg-hba-lan`` at create time. This adds a + ``host all all `` rule to ``pg_hba.conf``, which is + required when Postgres is accessed from other containers on the same + Docker network. Set to ``false`` for the monitor node (which does not + serve data connections from other nodes). + +Live reconfiguration +-------------------- + +The supervisor (the process that runs as PID 1 when ``pg_autoctl node run`` +is used) watches the spec file for changes and converges the ``[settings]`` +section automatically. + +On **Linux** the supervisor uses ``inotify`` (``IN_CLOSE_WRITE`` and +``IN_MOVED_TO`` events) so changes are detected within milliseconds of the +file being closed after writing. + +On **macOS and other platforms** the supervisor falls back to polling the +file's modification time every 10 seconds (``NODESPEC_WATCH_INTERVAL_SECS``). + +Workflow — updating candidate priority in a running cluster +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: bash + + # 1. Edit the spec file on the Docker host + sed -i 's/candidate_priority = 50/candidate_priority = 0/' node1_node.ini + + # 2. No further action required: the supervisor picks up the change + # within 10 s (mtime poll) or immediately (inotify on Linux). + # On the monitor, verify: + docker compose exec monitor \ + pg_autoctl get node candidate-priority --pgdata /var/lib/postgres/pgaf + +Immutable-field changes are logged as warnings but not applied — a node +restart is required. + +Use in Docker Compose and Kubernetes +------------------------------------- + +The primary motivation for the node spec file is to allow a **single +Docker image** with a **single command** to serve all node roles: + +.. code-block:: dockerfile + + # One image, one CMD — role determined by the mounted ini file + FROM pg_auto_failover:pg17 + CMD ["pg_autoctl", "node", "run", "/etc/pgaf/node.ini"] + +In Docker Compose, each service mounts its own ini file at +``/etc/pgaf/node.ini`` (generated by ``pgaftest`` or written by hand): + +.. code-block:: yaml + + services: + monitor: + image: pg_auto_failover:pg17 + volumes: + - monitor_data:/var/lib/postgres:rw + - ./monitor_node.ini:/etc/pgaf/node.ini:ro + command: ["pg_autoctl", "node", "run", "/etc/pgaf/node.ini"] + + node1: + image: pg_auto_failover:pg17 + volumes: + - node1_data:/var/lib/postgres:rw + - ./node1_node.ini:/etc/pgaf/node.ini:ro + command: ["pg_autoctl", "node", "run", "/etc/pgaf/node.ini"] + +In Kubernetes, use a ``ConfigMap`` to store the ini content and mount it as a +file into the Pod. Editing the ``ConfigMap`` propagates the new file into the +Pod within the kubelet's sync period (typically 1 minute); the supervisor +detects the change and converges without a Pod restart. + +.. code-block:: yaml + + apiVersion: v1 + kind: ConfigMap + metadata: + name: node1-spec + data: + node.ini: | + [node] + kind = postgres + hostname = node1.pg-cluster.svc.cluster.local + port = 5432 + + [postgresql] + pgdata = /var/lib/postgres/pgaf + + [monitor] + pguri = postgresql://autoctl_node@monitor.pg-cluster.svc.cluster.local/pg_auto_failover + + [formation] + name = default + group = 0 + + [settings] + candidate_priority = 50 + replication_quorum = true + + [create] + ssl = self-signed + auth = scram-sha-256 + pg_hba_lan = true + + --- + apiVersion: apps/v1 + kind: StatefulSet + # ... + spec: + template: + spec: + containers: + - name: postgres + image: pg_auto_failover:pg17 + command: ["pg_autoctl", "node", "run", "/etc/pgaf/node.ini"] + volumeMounts: + - name: node-spec + mountPath: /etc/pgaf + volumes: + - name: node-spec + configMap: + name: node1-spec + +See also +-------- + +* :ref:`pg_autoctl_create_postgres` +* :ref:`pg_autoctl_create_monitor` +* :ref:`pg_autoctl_run` +* :ref:`pg_autoctl_set_node_candidate_priority` +* :ref:`pg_autoctl_set_node_replication_quorum` +* :ref:`pgaftest_spec` — ``pgaftest`` test spec files use the same ini format + for the per-node files it generates inside ``cluster { }`` blocks From b11a85d6cb61e75c2425a7c40730c2c1f8e0eda0 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 22:00:58 +0200 Subject: [PATCH 12/48] =?UTF-8?q?pgaftest:=20cluster=20{=20formation=20{?= =?UTF-8?q?=20nodes=20}=20}=20hierarchy,=20[create]=E2=86=92[options],=20i?= =?UTF-8?q?ni=20file=20renames,=20auto=20work=20dir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Redesign cluster block DSL: cluster → monitor + formation(s) → nodes Formation block: formation [name] [num-sync N] { nodename [kind] [opts...] } Node kind (optional, default postgres): postgres | coordinator | worker Node options: async, candidate-priority N, group N Multiple formations supported (Citus use case) - Add TestFormation struct; TestCluster.formations[] replaces flat nodes[]+formation+numSync - num-sync is now per-formation; runner applies it per formation after compose-up - compose_gen_write_node_ini() takes formation parameter for formation name in ini - Rename [create] → [options] in nodespec.c/h and all ini generators - Rename monitor_node.ini → monitor.ini, _node.ini → .ini - Remove [settings] section from monitor.ini (monitors have no candidate_priority) - Work dir auto-derived from spec filename: $TMPDIR/pgaftest/ derive_work_dir() strips path + .pgaf extension; TMPDIR defaults to /tmp pgaftest step and pgaftest down now accept spec path arg to derive work dir --work-dir flag still works as an override - nodespec.c: fix PUSH("create") regression from [create]→[options] rename - Docs: update cluster{} syntax, formation examples, work-dir defaults --- docs/pgaftest.rst | 160 +++++++----- docs/ref/pg_autoctl_node.rst | 22 +- src/bin/pg_autoctl/nodespec.c | 12 +- src/bin/pg_autoctl/nodespec.h | 2 +- src/bin/pgaftest/cli_root.c | 108 ++++++-- src/bin/pgaftest/compose_gen.c | 110 ++++---- src/bin/pgaftest/compose_gen.h | 6 +- src/bin/pgaftest/pgaftest | Bin 798072 -> 798376 bytes src/bin/pgaftest/test_runner.c | 71 +++++- src/bin/pgaftest/test_spec.h | 64 ++++- src/bin/pgaftest/test_spec_parse.c | 394 ++++++++++++++++++++--------- src/bin/pgaftest/test_spec_parse.h | 2 +- src/bin/pgaftest/test_spec_parse.y | 368 +++++++++++++++++++-------- 13 files changed, 910 insertions(+), 409 deletions(-) diff --git a/docs/pgaftest.rst b/docs/pgaftest.rst index af92a1500..2a4417c59 100644 --- a/docs/pgaftest.rst +++ b/docs/pgaftest.rst @@ -36,10 +36,11 @@ Quick start PGAF_IMAGE=pg_auto_failover:pg17 pgaftest setup tests/tap/specs/basic_operation.pgaf # Run one named step against the live cluster - pgaftest step fail_primary --work-dir /tmp/pgaftest-work + # (work dir is auto-derived: $TMPDIR/pgaftest/basic_operation) + pgaftest step fail_primary tests/tap/specs/basic_operation.pgaf # Tear down - pgaftest down --work-dir /tmp/pgaftest-work + pgaftest down tests/tap/specs/basic_operation.pgaf .. _pgaftest_spec: @@ -65,72 +66,83 @@ generates: * Each container mounts its ini file at ``/etc/pgaf/node.ini`` and runs the same command: ``pg_autoctl node run /etc/pgaf/node.ini`` +The topology follows a three-level hierarchy: +``cluster`` → ``monitor`` + ``formation(s)`` → ``nodes`` + **Syntax** .. code-block:: text cluster { # Cluster-level options (all optional) - image "pg_auto_failover:pg17" # Docker image tag; "" = build from source - ssl self-signed # self-signed | cert | off - auth trust # trust | md5 | scram - formation "default" # formation name - num-sync 1 # number-sync-standbys - monitor [port 15432] # expose monitor on host port; 0 = auto - - # Node declarations - monitor - node [candidate-priority=N] [async] - citus-coordinator - citus-worker group=N + monitor [port N] # expose monitor on host port; 0 = auto + image "pg_auto_failover:pg17" # Docker image; "" = build from source + ssl self-signed # self-signed | cert | off + auth trust # trust | md5 | scram + + # One or more formation blocks + formation [name] [num-sync N] { + nodename [kind] [option...] + ... + } } **Cluster-level options** +``monitor [port N]`` + Declares the monitor service. The optional ``port N`` exposes the + monitor's Postgres port on host port ``N`` so the test runner can connect + directly with libpq. When omitted, a random free port is chosen. + ``image`` Docker image to use for every container. Overrides the ``PGAF_IMAGE`` environment variable. When neither is set, a ``build:`` stanza pointing at the project root is used instead. - .. code-block:: text - - image "pg_auto_failover:pg17" - ``ssl`` - SSL mode written into the ``[create]`` section of each node's ini file. + SSL mode written into the ``[options]`` section of each node's ini file. Allowed values: ``self-signed`` (default), ``cert``, ``off``. ``auth`` Authentication method. Passed as ``--auth`` to ``pg_autoctl create``. Default: ``trust``. -``formation`` - Formation name on the monitor. Default: ``default``. +**Formation block** -``num-sync`` - Sets ``number-sync-standbys`` on the monitor formation after the cluster - comes up. When absent, the monitor default applies. +.. code-block:: text -``monitor [port N]`` - Declares the monitor service. The optional ``port N`` exposes the - monitor's Postgres port on host port ``N`` so the test runner can connect - directly with libpq. When omitted, a random free port is chosen. + formation [name] [num-sync N] { + ...nodes... + } + +``name`` + Formation name on the monitor. Defaults to ``default`` when omitted. + +``num-sync N`` + Sets ``number-sync-standbys`` on this formation after the cluster comes up. + When absent, the monitor default (0) applies. + +**Node lines** (inside a formation block) + +.. code-block:: text -**Node declarations** + nodename [kind] [option...] -``node [candidate-priority=N] [async]`` - A standalone (non-Citus) Postgres node. +``nodename`` + The service name — used as the Docker Compose service name and as the + ``hostname`` in the container. - * ``candidate-priority=N`` — integer 0–100; default 50. ``0`` prevents - this node from ever being elected primary. - * ``async`` — makes this node asynchronous (``replication_quorum = false``). +``kind`` (optional, default ``postgres``) + * ``postgres`` — standalone Postgres node + * ``coordinator`` — Citus coordinator + * ``worker`` — Citus worker -``citus-coordinator `` - A Citus coordinator node. Exactly one per cluster. +Options: -``citus-worker group=N`` - A Citus worker node belonging to Citus group ``N``. Multiple workers - can share the same group to form an HA pair. +* ``async`` — makes this node asynchronous (``replication_quorum = false``) +* ``candidate-priority N`` — integer 0–100; default 50. ``0`` prevents this + node from ever being elected primary. +* ``group N`` — Citus group id (required for ``worker`` kind) **Examples** @@ -140,45 +152,54 @@ Minimal two-node HA cluster: cluster { monitor - node node1 - node node2 + formation { + node1 + node2 + } } -Three-node cluster with a non-candidate standby: +Three-node cluster, ``node3`` is a non-candidate async standby: .. code-block:: text cluster { monitor - node node1 - node node2 - node node3 candidate-priority=0 + formation { + node1 + node2 + node3 async candidate-priority 0 + } } -Three nodes, one asynchronous (does not block writes): +Named formation with ``num-sync``: .. code-block:: text cluster { monitor - node node1 - node node2 - node node3 async - num-sync 1 + formation default num-sync 1 { + node1 + node2 + node3 + } } -Citus cluster (one coordinator, two worker HA pairs): +Citus cluster (one coordinator, two worker HA pairs in separate formations): .. code-block:: text cluster { image "pg_auto_failover:pg17-citus" monitor - citus-coordinator coord - citus-worker worker1 group=1 - citus-worker worker2 group=1 - citus-worker worker3 group=2 - citus-worker worker4 group=2 + formation coordinators { + coord coordinator + } + formation workers num-sync 1 { + worker1 worker group 1 + worker2 worker group 1 + worker3 worker group 2 + worker4 worker group 2 + } } Custom image and non-default auth: @@ -189,9 +210,11 @@ Custom image and non-default auth: image "myregistry.example.com/pgaf:latest" ssl self-signed auth scram-sha-256 - monitor [port 15432] - node node1 - node node2 + monitor port 15432 + formation { + node1 + node2 + } } setup { } and teardown { } @@ -385,8 +408,10 @@ verifies replication, triggers a failover, and checks recovery. cluster { monitor - node node1 - node node2 + formation { + node1 + node2 + } } setup { @@ -479,12 +504,13 @@ Interactive session (useful for debugging): pgaftest setup tests/tap/specs/basic_operation.pgaf # In a separate terminal, run individual steps - pgaftest step create_table --work-dir /tmp/pgaftest-work - pgaftest step fail_primary --work-dir /tmp/pgaftest-work - pgaftest step check_failover --work-dir /tmp/pgaftest-work + # (work dir auto-derived to $TMPDIR/pgaftest/basic_operation) + pgaftest step create_table tests/tap/specs/basic_operation.pgaf + pgaftest step fail_primary tests/tap/specs/basic_operation.pgaf + pgaftest step check_failover tests/tap/specs/basic_operation.pgaf # Tear down when done - pgaftest down --work-dir /tmp/pgaftest-work + pgaftest down tests/tap/specs/basic_operation.pgaf Environment variables --------------------- @@ -515,8 +541,10 @@ change ``node2``'s candidate priority without restarting the container: .. code-block:: bash # Edit the generated ini file in the work directory + # (auto-derived from the spec name, e.g. $TMPDIR/pgaftest/basic_operation) + WORKDIR=${TMPDIR:-/tmp}/pgaftest/basic_operation sed -i 's/candidate_priority = 50/candidate_priority = 0/' \ - /tmp/pgaftest-work/node2_node.ini + $WORKDIR/node2.ini # The supervisor inside node2 picks up the change automatically. # Verify on the monitor: diff --git a/docs/ref/pg_autoctl_node.rst b/docs/ref/pg_autoctl_node.rst index 028a20ff3..a7997c99d 100644 --- a/docs/ref/pg_autoctl_node.rst +++ b/docs/ref/pg_autoctl_node.rst @@ -50,7 +50,7 @@ pg_autoctl node run usage: pg_autoctl node run - Path to the pg_autoctl_node.ini file. + Path to the pg_autoctl.ini file. Defaults to /etc/pgaf/node.ini when no argument is given. **First start (node not yet created):** @@ -62,7 +62,7 @@ Builds and executes the equivalent of:: --pgport \ --monitor \ --formation \ - --ssl-self-signed \ # or --no-ssl, depending on [create] ssl = + --ssl-self-signed \ # or --no-ssl, depending on [options] ssl = --auth trust \ --pg-hba-lan \ --run @@ -110,7 +110,7 @@ pg_autoctl node show usage: pg_autoctl node show [ --pgdata ] Reads the local ``pg_autoctl.cfg`` configuration file and prints it in -``pg_autoctl_node.ini`` format on stdout. Useful for bootstrapping a spec +``pg_autoctl.ini`` format on stdout. Useful for bootstrapping a spec file from an existing node that was created with ``pg_autoctl create``. Example:: @@ -146,7 +146,7 @@ Example output:: .. _node_spec_format: -Node spec file format (pg_autoctl_node.ini) +Node spec file format (pg_autoctl.ini) ------------------------------------------- The node spec file uses a simple INI syntax with five sections. Lines @@ -154,7 +154,7 @@ beginning with ``#`` are comments. .. code-block:: ini - # pg_autoctl_node.ini — describes a single pg_auto_failover node. + # pg_autoctl.ini — describes a single pg_auto_failover node. # Feed to: pg_autoctl node run /etc/pgaf/node.ini # Edit and save to converge mutable settings on the running node. @@ -179,7 +179,7 @@ beginning with ``#`` are comments. candidate_priority = 50 # 0–100; 0 = never a failover candidate replication_quorum = true # participates in the synchronous replication quorum - [create] + [options] # These fields are immutable after the node is created. # They are only used during the first-ever pg_autoctl create run. ssl = self-signed # self-signed | cert | off @@ -251,7 +251,7 @@ Sections and fields Editing this field and saving the file causes the supervisor to call ``pg_autoctl set node replication-quorum``. -``[create]`` — immutable after creation +``[options]`` — immutable after creation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``ssl`` @@ -293,7 +293,7 @@ Workflow — updating candidate priority in a running cluster .. code-block:: bash # 1. Edit the spec file on the Docker host - sed -i 's/candidate_priority = 50/candidate_priority = 0/' node1_node.ini + sed -i 's/candidate_priority = 50/candidate_priority = 0/' node1.ini # 2. No further action required: the supervisor picks up the change # within 10 s (mtime poll) or immediately (inotify on Linux). @@ -326,14 +326,14 @@ In Docker Compose, each service mounts its own ini file at image: pg_auto_failover:pg17 volumes: - monitor_data:/var/lib/postgres:rw - - ./monitor_node.ini:/etc/pgaf/node.ini:ro + - ./monitor.ini:/etc/pgaf/node.ini:ro command: ["pg_autoctl", "node", "run", "/etc/pgaf/node.ini"] node1: image: pg_auto_failover:pg17 volumes: - node1_data:/var/lib/postgres:rw - - ./node1_node.ini:/etc/pgaf/node.ini:ro + - ./node1.ini:/etc/pgaf/node.ini:ro command: ["pg_autoctl", "node", "run", "/etc/pgaf/node.ini"] In Kubernetes, use a ``ConfigMap`` to store the ini content and mount it as a @@ -368,7 +368,7 @@ detects the change and converges without a Pod restart. candidate_priority = 50 replication_quorum = true - [create] + [options] ssl = self-signed auth = scram-sha-256 pg_hba_lan = true diff --git a/src/bin/pg_autoctl/nodespec.c b/src/bin/pg_autoctl/nodespec.c index 657186212..10539d01d 100644 --- a/src/bin/pg_autoctl/nodespec.c +++ b/src/bin/pg_autoctl/nodespec.c @@ -51,7 +51,7 @@ * candidate_priority = 50 * replication_quorum = true * - * [create] + * [options] * ssl = self-signed * auth = trust * pg_hba_lan = true @@ -104,14 +104,14 @@ nodespec_read(const char *path, NodeSpec *spec) sizeof(replicationQuorumStr), replicationQuorumStr, "true"), - /* [create] — immutable, used only at create time */ - make_strbuf_option_default("create", "ssl", NULL, false, + /* [options] — immutable, used only at create time */ + make_strbuf_option_default("options", "ssl", NULL, false, sizeof(spec->ssl), spec->ssl, "self-signed"), - make_strbuf_option_default("create", "auth", NULL, false, + make_strbuf_option_default("options", "auth", NULL, false, sizeof(spec->auth), spec->auth, "trust"), - make_strbuf_option_default("create", "pg_hba_lan", NULL, false, + make_strbuf_option_default("options", "pg_hba_lan", NULL, false, sizeof(pgHbaLanStr), pgHbaLanStr, "true"), @@ -220,7 +220,7 @@ nodespec_write(const NodeSpec *spec, FILE *out) "candidate_priority = %d\n" "replication_quorum = %s\n" "\n" - "[create]\n" + "[options]\n" "ssl = %s\n" "auth = %s\n" "pg_hba_lan = %s\n", diff --git a/src/bin/pg_autoctl/nodespec.h b/src/bin/pg_autoctl/nodespec.h index 3d0f10841..f712ae60c 100644 --- a/src/bin/pg_autoctl/nodespec.h +++ b/src/bin/pg_autoctl/nodespec.h @@ -69,7 +69,7 @@ typedef struct NodeSpec int candidate_priority; /* 0-100, default 50 */ bool replication_quorum; /* sync quorum participant, default true */ - /* [create] — immutable; used only at pg_autoctl create time */ + /* [options] — immutable; used only at pg_autoctl create time */ char ssl[32]; /* self-signed | cert | off */ char auth[32]; /* trust | md5 | scram */ bool pg_hba_lan; /* add --pg-hba-lan flag */ diff --git a/src/bin/pgaftest/cli_root.c b/src/bin/pgaftest/cli_root.c index c340befea..8e147902d 100644 --- a/src/bin/pgaftest/cli_root.c +++ b/src/bin/pgaftest/cli_root.c @@ -19,9 +19,6 @@ #include "test_runner.h" #include "cli_demo.h" -/* Default work directory when --work-dir is not specified */ -#define DEFAULT_WORK_DIR "/tmp/pgaftest" - /* ----------------------------------------------------------------------- * Shared option parsing * ----------------------------------------------------------------------- */ @@ -29,7 +26,7 @@ typedef struct PgaftestOpts { char specFile[1024]; - char workDir[1024]; + char workDir[1024]; /* empty = auto-derive from spec name */ char stepName[64]; char schedule[1024]; char expected[1024]; @@ -37,9 +34,42 @@ typedef struct PgaftestOpts int verbose; } PgaftestOpts; -static PgaftestOpts pgaftestOpts = { - .workDir = DEFAULT_WORK_DIR -}; +static PgaftestOpts pgaftestOpts; /* zero-initialised: workDir = "" */ + +/* + * derive_work_dir — build $TMPDIR/pgaftest/ + * + * Using TMPDIR (or /tmp when unset) + "pgaftest" + the test name means: + * - Every spec gets its own isolated directory. + * - Multiple instances of different specs can run concurrently. + * - The directory name matches the Docker Compose project name, so + * `docker compose -p basic_operation` addresses the right stack. + * + * Examples: + * tests/tap/specs/basic_operation.pgaf → /tmp/pgaftest/basic_operation + * failover.pgaf → /tmp/pgaftest/failover + */ +static void +derive_work_dir(const char *specPath, char *buf, int buflen) +{ + /* base name without directory */ + const char *base = strrchr(specPath, '/'); + base = base ? base + 1 : specPath; + + char name[256] = { 0 }; + strncpy(name, base, sizeof(name) - 1); + + /* strip .pgaf extension */ + char *dot = strrchr(name, '.'); + if (dot && strcmp(dot, ".pgaf") == 0) + *dot = '\0'; + + const char *tmpdir = getenv("TMPDIR"); + if (!tmpdir || *tmpdir == '\0') + tmpdir = "/tmp"; + + snprintf(buf, buflen, "%s/pgaftest/%s", tmpdir, name); +} static struct option long_options[] = { { "work-dir", required_argument, NULL, 'w' }, @@ -135,15 +165,22 @@ cli_run(int argc, char **argv) "tests/tap/specs/%s.pgaf", p); char workDir[1024]; - /* derive per-spec workdir from spec basename */ - const char *base = strrchr(specPath, '/'); - base = base ? base+1 : specPath; - char name[128]; - strncpy(name, base, sizeof(name)-1); - char *dot = strrchr(name, '.'); - if (dot) *dot = '\0'; - snprintf(workDir, sizeof(workDir), - "%s/%s", pgaftestOpts.workDir, name); + if (pgaftestOpts.workDir[0] != '\0') + { + /* explicit --work-dir: append spec name as subdir */ + const char *base = strrchr(specPath, '/'); + base = base ? base+1 : specPath; + char name[128]; + strncpy(name, base, sizeof(name)-1); + char *dot = strrchr(name, '.'); + if (dot) *dot = '\0'; + snprintf(workDir, sizeof(workDir), + "%s/%s", pgaftestOpts.workDir, name); + } + else + { + derive_work_dir(specPath, workDir, sizeof(workDir)); + } TestSpec *spec = parse_test_spec(specPath); if (!spec) { failed++; total++; continue; } @@ -169,6 +206,10 @@ cli_run(int argc, char **argv) strncpy(pgaftestOpts.specFile, argv[optind - 1], sizeof(pgaftestOpts.specFile)-1); + if (pgaftestOpts.workDir[0] == '\0') + derive_work_dir(pgaftestOpts.specFile, + pgaftestOpts.workDir, sizeof(pgaftestOpts.workDir)); + TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); if (!spec) exit(1); @@ -194,6 +235,10 @@ cli_setup(int argc, char **argv) strncpy(pgaftestOpts.specFile, argv[optind - 1], sizeof(pgaftestOpts.specFile)-1); + if (pgaftestOpts.workDir[0] == '\0') + derive_work_dir(pgaftestOpts.specFile, + pgaftestOpts.workDir, sizeof(pgaftestOpts.workDir)); + TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); if (!spec) exit(1); @@ -230,6 +275,11 @@ cli_step(int argc, char **argv) if (optind + 1 < argc) strncpy(specPath, argv[optind+1], sizeof(specPath)-1); + /* derive work dir from spec path when not given explicitly */ + if (pgaftestOpts.workDir[0] == '\0') + derive_work_dir(specPath, pgaftestOpts.workDir, + sizeof(pgaftestOpts.workDir)); + TestSpec *spec = parse_test_spec(specPath); if (!spec) exit(1); @@ -270,12 +320,26 @@ cli_show(int argc, char **argv) static void cli_down(int argc, char **argv) { - pgaftest_getopts(argc, argv); + int optind = pgaftest_getopts(argc, argv); + + /* optional positional: spec file to derive work dir from */ + if (optind <= argc && argv[optind - 1] && argv[optind - 1][0] != '-') + { + strncpy(pgaftestOpts.specFile, argv[optind - 1], + sizeof(pgaftestOpts.specFile)-1); + } + + if (pgaftestOpts.workDir[0] == '\0' && pgaftestOpts.specFile[0] != '\0') + derive_work_dir(pgaftestOpts.specFile, + pgaftestOpts.workDir, sizeof(pgaftestOpts.workDir)); /* spec file is optional for `down` — teardown may not need it */ char specPath[1024]; - snprintf(specPath, sizeof(specPath), "%s/spec.pgaf", - pgaftestOpts.workDir); + if (pgaftestOpts.specFile[0] != '\0') + strncpy(specPath, pgaftestOpts.specFile, sizeof(specPath)-1); + else + snprintf(specPath, sizeof(specPath), "%s/spec.pgaf", + pgaftestOpts.workDir); TestSpec *spec = NULL; if (access(specPath, R_OK) == 0) @@ -302,7 +366,8 @@ static CommandLine run_command = "[options] []", " --schedule Run all specs listed in schedule file\n" " --expected Directory of expected output files\n" - " --work-dir Working directory (default: /tmp/pgaftest)\n" + " --work-dir Working directory\n" + " (default: $TMPDIR/pgaftest/)\n" " --verbose Increase log verbosity\n", pgaftest_getopts, cli_run); @@ -311,7 +376,8 @@ static CommandLine setup_command = "Bring up a cluster from a spec file (interactive mode)", "[options] ", " --tmux Launch a tmux session after setup\n" - " --work-dir Working directory (default: /tmp/pgaftest)\n" + " --work-dir Working directory\n" + " (default: $TMPDIR/pgaftest/)\n" " --verbose Increase log verbosity\n", pgaftest_getopts, cli_setup); diff --git a/src/bin/pgaftest/compose_gen.c b/src/bin/pgaftest/compose_gen.c index c0ced33dc..2b960fe91 100644 --- a/src/bin/pgaftest/compose_gen.c +++ b/src/bin/pgaftest/compose_gen.c @@ -109,7 +109,7 @@ compose_gen_write(const TestCluster *cluster, " hostname: monitor\n" " volumes:\n" " - monitor_data:/var/lib/postgres:rw\n" - " - ./monitor_node.ini:" NODE_INI_PATH ":ro\n" + " - ./monitor.ini:" NODE_INI_PATH ":ro\n" " environment:\n" " PGDATA: " NODE_PGDATA "\n" " ports:\n" @@ -124,53 +124,64 @@ compose_gen_write(const TestCluster *cluster, " command: [\"pg_autoctl\", \"node\", \"run\", \"" NODE_INI_PATH "\"]\n\n", monitorHostPort); - /* ---- data nodes ---- */ - for (int i = 0; i < cluster->nodeCount; i++) + /* ---- data nodes — iterate all formations ---- */ + const TestNode *firstNode = NULL; + + for (int fi = 0; fi < cluster->formationCount; fi++) { - const TestNode *n = &cluster->nodes[i]; - char ini_filename[128]; + const TestFormation *form = &cluster->formations[fi]; - sformat(ini_filename, sizeof(ini_filename), "%s_node.ini", n->name); + for (int ni = 0; ni < form->nodeCount; ni++) + { + const TestNode *n = &form->nodes[ni]; + char ini_filename[128]; - fprintf(f, " %s:\n", n->name); - write_image_stanza(f, cluster, contextDir); - fprintf(f, - " hostname: %s\n" - " volumes:\n" - " - %s_data:/var/lib/postgres:rw\n" - " - ./%s:" NODE_INI_PATH ":ro\n" - " environment:\n" - " PGDATA: " NODE_PGDATA "\n" - " PGUSER: demo\n" - " PGDATABASE: demo\n" - " expose:\n" - " - 5432\n" - " depends_on:\n" - " monitor:\n" - " condition: service_healthy\n", - n->name, - n->name, ini_filename); - - /* - * Ensure node registration order is deterministic: node1 always - * registers before node2 etc., so node IDs are predictable in tests. - */ - if (i > 0) + sformat(ini_filename, sizeof(ini_filename), "%s.ini", n->name); + + fprintf(f, " %s:\n", n->name); + write_image_stanza(f, cluster, contextDir); fprintf(f, - " %s:\n" - " condition: service_started\n", - cluster->nodes[0].name); + " hostname: %s\n" + " volumes:\n" + " - %s_data:/var/lib/postgres:rw\n" + " - ./%s:" NODE_INI_PATH ":ro\n" + " environment:\n" + " PGDATA: " NODE_PGDATA "\n" + " PGUSER: demo\n" + " PGDATABASE: demo\n" + " expose:\n" + " - 5432\n" + " depends_on:\n" + " monitor:\n" + " condition: service_healthy\n", + n->name, + n->name, ini_filename); + + /* + * Ensure node registration order is deterministic: the first + * node in the first formation always registers before subsequent + * nodes, so node IDs are predictable in tests. + */ + if (firstNode && firstNode != n) + fprintf(f, + " %s:\n" + " condition: service_started\n", + firstNode->name); - fprintf(f, - " command: [\"pg_autoctl\", \"node\", \"run\"," - " \"" NODE_INI_PATH "\"]\n\n"); + fprintf(f, + " command: [\"pg_autoctl\", \"node\", \"run\"," + " \"" NODE_INI_PATH "\"]\n\n"); + + if (!firstNode) firstNode = n; + } } /* ---- volumes ---- */ fprintf(f, "volumes:\n"); fprintf(f, " monitor_data:\n"); - for (int i = 0; i < cluster->nodeCount; i++) - fprintf(f, " %s_data:\n", cluster->nodes[i].name); + for (int fi = 0; fi < cluster->formationCount; fi++) + for (int ni = 0; ni < cluster->formations[fi].nodeCount; ni++) + fprintf(f, " %s_data:\n", cluster->formations[fi].nodes[ni].name); fclose(f); log_info("Wrote docker-compose.yml to \"%s\"", path); @@ -186,7 +197,7 @@ bool compose_gen_write_monitor_ini(const TestCluster *cluster, const char *dir) { char path[1024]; - sformat(path, sizeof(path), "%s/monitor_node.ini", dir); + sformat(path, sizeof(path), "%s/monitor.ini", dir); FILE *f = fopen(path, "w"); if (!f) @@ -207,11 +218,7 @@ compose_gen_write_monitor_ini(const TestCluster *cluster, const char *dir) "[postgresql]\n" "pgdata = " NODE_PGDATA "\n" "\n" - "[settings]\n" - "candidate_priority = 0\n" - "replication_quorum = false\n" - "\n" - "[create]\n" + "[options]\n" "ssl = %s\n" "auth = %s\n" "pg_hba_lan = false\n", @@ -219,7 +226,7 @@ compose_gen_write_monitor_ini(const TestCluster *cluster, const char *dir) cluster->auth); fclose(f); - log_info("Wrote monitor_node.ini to \"%s\"", path); + log_info("Wrote monitor.ini to \"%s\"", path); return true; } @@ -230,11 +237,12 @@ compose_gen_write_monitor_ini(const TestCluster *cluster, const char *dir) bool compose_gen_write_node_ini(const TestCluster *cluster, + const TestFormation *formation, const TestNode *node, const char *dir) { char path[1024]; - sformat(path, sizeof(path), "%s/%s_node.ini", dir, node->name); + sformat(path, sizeof(path), "%s/%s.ini", dir, node->name); FILE *f = fopen(path, "w"); if (!f) @@ -253,7 +261,7 @@ compose_gen_write_node_ini(const TestCluster *cluster, fprintf(f, "# Generated by pgaftest — do not edit manually\n" - "# Node: %s\n" + "# Node: %s (formation: %s)\n" "\n" "[node]\n" "kind = %s\n" @@ -274,14 +282,14 @@ compose_gen_write_node_ini(const TestCluster *cluster, "candidate_priority = %d\n" "replication_quorum = %s\n" "\n" - "[create]\n" + "[options]\n" "ssl = %s\n" "auth = %s\n" "pg_hba_lan = true\n", - node->name, + node->name, formation->name, kindStr, node->name, - cluster->formation, + formation->name, node->group, node->candidatePriority, node->replicationQuorum ? "true" : "false", @@ -289,7 +297,7 @@ compose_gen_write_node_ini(const TestCluster *cluster, cluster->auth); fclose(f); - log_info("Wrote %s_node.ini to \"%s\"", node->name, path); + log_info("Wrote %s.ini to \"%s\"", node->name, path); return true; } diff --git a/src/bin/pgaftest/compose_gen.h b/src/bin/pgaftest/compose_gen.h index 55989c99b..a0612da52 100644 --- a/src/bin/pgaftest/compose_gen.h +++ b/src/bin/pgaftest/compose_gen.h @@ -26,7 +26,7 @@ bool compose_gen_write(const TestCluster *cluster, /* * Write a pg_autoctl_node.ini file for the monitor node into `dir`. - * The file is written as /monitor_node.ini and will be bind-mounted + * The file is written as /monitor.ini and will be bind-mounted * into the container at PG_AUTOCTL_NODESPEC_PATH. */ bool compose_gen_write_monitor_ini(const TestCluster *cluster, @@ -34,9 +34,11 @@ bool compose_gen_write_monitor_ini(const TestCluster *cluster, /* * Write a pg_autoctl_node.ini file for a data node into `dir`. - * The file is written as /name>_node.ini. + * The file is written as /name>.ini. + * `formation` supplies the formation name and is written into [formation]. */ bool compose_gen_write_node_ini(const TestCluster *cluster, + const TestFormation *formation, const TestNode *node, const char *dir); diff --git a/src/bin/pgaftest/pgaftest b/src/bin/pgaftest/pgaftest index 013cf4af0f94d174bf4005ef76dbf482acd6d6e0..3cf7e6b19f27eb5b405e057d60d7cfd78e0ff619 100755 GIT binary patch delta 209853 zcmb4s30zcF`~ST&gADsNFvHHUIqWElfC~d!B3kN5W@d?u6^fRorKUB5*ei+_w}XwT zZ=%&3j9T=jZ_nFqcF(GD!2P?j~k5+OVo=F`)M%6Kd z6~|4Hv0@I-zU07=NYcw|Re@ftQtu(v;wf+K)y zAL+q0jslnwxQC;>&=^Q|d4@;)I)-mLox=&80C^H1Psu~AKg+|cp<~F8o{>TK>f4nb zTu|4&TsuXAe}i}{BRn|(;3|iaG-ZU$$dmEPB=5I?CWjWAMw3UC6HRr=M=!{E>qR+d zZFV>;fYGa*GpDeO=kj7XRZWJRtEdIm+67TU9qz`!7{QF*rQv2n00>o~eN&ZIU~T3` zG3=fk%{NubxqX0XAJlhq6zf|RWHx;GFOgZMDl}FqxT$l#t?m=C<%Clvvtc#JRdQ1b zt2r)@=K_UCIiSs`;e`32_>BQ5p$7E70OUK3@d6)bHc)QQMp?6r+owjo23IG_CZbG| z8V9K<87$`6qKO8MUJ5?u*GC_v^FeQVUSNmu@xgd8$^F|Njo8qoH z_R_)<-fTz()q0NG8_RKpv}}&TY)En|yKIan4b!5@B5z-lnwHBs^bHnHLJ=s}GEi1# z1lQzTE-Uvi8-}3_@Xl#H&09Kw=&1m+ApvFd_W{(WP&m#p`yb+3JApKBrko75es-K| zqJ&(AC@DO#TxI?EIA>x5b@e;)*g)t6#Rt$};hKtT(qD1x(}7cOIUH)oSdXLq4+Xbg zoE*}6eWj}Py4*vMbdHH63F3fATI!iy7Dz2}r01?w#`yVp2I()`@2p#g-C+-==H(B%# z$W*3}{&ZNV&D;hDF-Y&fOkjF{D#~oQzE9NqE$DSKwSN=nx~u&wut`bncY?1Vg{l2| z^p`X=o?BeF%Y#!gHC;1`w>;#Szz^nTXKd5xgwC-XQ;Jbw+o2&`P%Ix>V+E^frvU)1 zq*_@^i2^X?oGFDZ)SmI1nij2p7zEP$18&4k1`<^mkh;02hlu7^jxxq(<9+{)&ABOz zoP$Yb!!{>5g-&vA^e%S+qw#JdW}#hyr#MnNIJkYbEYu|N?-mRw@`4j$xzL&gkS~=T zoIkc1bzsr}&7T`4?366zds>NWgZuRaja+BZ9} z_41uTFuq_Q2`}=#LO4B?vtN|UO;B-}^)gib3eCK>8`r2 zJMy}Q>g`k~7_1EeY~ZgjFr8Z&JX5xajSYo;YR;~#8`mD|!7Z-w<|@27^RaMTXCn3X z5kb6gaV#$^$KV>{NMR-JD@`MXZ9sC{dz^qNO4X&-+m*HB+OO;y+gk3y30LA%gxLpl zJ>E*Lg2M2bP-~c;x{-7^CM;M}_IiE_rJx2BFgg)#{V-DC-^|Q!MAs*=5gd z**Am}4&A!G{Yoh>yeCukboV9${7rebsJ!m$@Pr0 zhd7a=6u!h&Uy*C3MlLEqSmVaFLw^pi&D8;{s|Ua<$GO&lK_abnC|hyWvDYCB?}@wW zsIXJSq(Ky%uoCs3UMa%wcg442EdE=!YeRC+QTcVdF1dWiZ+QM+%j zmYs+?{r8gFgY#umi^zlPG^QX#uQIp*9xi~h)+;c{xT1-uzMp-Z6Z|4i;ffLB!bJ(0 zGl&pg*bbyEv)Q0Phqx~_&m=vyrghF z8kXPZFKobl!&HBPy83lN>$j{2M~=w68#aI=pUQk27MAPVyK@w+zYUeQUdocSc1`9* z4k?wwg*y>F+rMLV&1dKeFLO(<*cdODz;met^yLln9> zo)h|jDYKZ0Kv5@c(IO=frxA!Y#q&bnG_I97!MQO)r~&~bjbLx=*UuIo-iFc$v*8YO zj3V#Er~`IrxeBwK3kHUQ`{T64AnKO z_EQ(xFodf>G=HpG9w?-ujhAGr)16WL`dHyv2=&D6aY7edYxfAQ-5&3?l}^Q1V8_)p zZ|^TmND&;=tHI`VWA*K24#x<40+toj=BV+O#+VI1Ba)5&tlr*-*ptpm zHY^XCuRC(#d0NfRJ_jK{X1nHiAqf58#|_eebTI0tDY6aM92IpyrfY=0T^GpZcRfA1 zolX{JSvi8=#3bQ9sMA)+aAl6(UMbhxTMMx~z#WbDa;Le6I^{uoI^}`50&w}`^26ne z%LkV?F0Vagd2^I$kn}bLGU=6;n+>P`$u*S#AVMXk38!$!a;>Suo6D!#K-ui$$5n)Z z&B`&G3`^l5=;HP{u(j~jY;m#lY_4l41}I^c zsSRQ=QYTodLm8#&K~NP1peG=cvV{8fpTMH^UR;Icu}Ax;%Q-1mTXzIO9j`m~o`jYE zUnz%)fCHYm$m-@06EumEcNMFgO3d(GK#{Gu3D5=V61q%@&t?nPZCsQ8|0c_N5pB8v zlM0Pe)Qe|I38g9zR2_nIr!)Of8P{Y|LY>c0b)HvUK>2#$7e~ckEX$n0WK*Rz8yD%t1VE&=Pua8!Y`PKS9Y6hV zjLU9<@l}xi$Da=MGX;E;L(W_3X30ZIqsCX(T0oxHgqa**6J6czz+$lyzUCAbDd$i| zf78|N75vsaSGSav%-QK9h06FKHWh67LJX!@`6OB{P7zHguN@T9`(ayUR~kh1_bT+5OYwE*_)QJKcFf2}+&J|r#(#u8%PG1_d% z1bWSgZi+DkmZ}Kdw70dS{szT$$IrdHaj0 zEAtR-%uVlzsbg4E7>-1m9Qp2JPq=)O@_=weP1HR-5?=W0{e2WDI5P(`#wZ{ zCd4bd5Gwu(#iIivpQpkA1~O%F9QpF~X!2yl12GbovJ$87)1(S(fT4bEWqU*+@s2d` z#pIsIp|Ze2^0&zH6sbMcbkSEP2ouqsYW!vRR!QTp6MJNqDGO{?bDD;JBj3v0$SpeI z8d~Xrh6G8L;)GP4Dr5qZ0%&qAwT4Qr`QbG52kOV7agXKHJ>G$sav)r)=`YmDkDioA zS}#CT&3`&DYw?&7qpU|DQVy}`n+^wgIZDevNRCE_40{v|>Ypr*JO`n#7IR|hFwBGa zZCsTpcwpoUOSslbJab%@u%Gxv*DLf%!Y1-ubY%1z0B!DeW@yF)k(L>+IKRfb49 zoehwClK~D6cMi~$CA{C}Hh^!o@F)q5$ufNl!hq~zCa>7UKFQpqu3O+$sB(3TF)o=2q! z-_hqfG0JCUeM!OzlwC18`+Tnxj?rhS&n%trxf_hA(zX=g2nzn0KX_5>s0%zwq7pPk z4C?oR!Ubn!{K8lNtT}GgE zvjD6g0T}g6^))M409JzlOa-f|cMHHCg{)5?09%Ip6$D^xy*k+$faP%Q#2J7gAtKb* zwC`U6Z?zp0{t*OV)uk)|GmW_5G;Nv|6$3D}^~+beCfb08-IV%HxyJf85Z-~{3u1Ey zUtv}nd@&71@bxkJ(BMlNj1D9PU%L=|8DRxoIS9Udx%|CIDb#n5vtNoG4iAKg?EgE+ z8YDAkkafynHZ%i^T0ln5l*yhtopX>owp#Kp%edUX$U7=n3<4^U&P3mjfizcxD7A3vGciNL>fcriKjNAFzNi+y!*6na zoIM1|u%(b&(-;jByfmayS-(Wxl4QM|I2`+2@F!`6&)wmv!i6KBnZ(TKJ+M96c@Q_g z2@<`@G_&CzP;_Hpaq^6#;xAlq3x%doECA1P0qIX?&Tq$|)k8JGVT>dg^Mp0c|UX+SK0see11acAdU zX2Tbhdss{k!aqHN)vumuHoX4|@lPs}dE}Auq}wYhf%oe!yhE&Gfwvxb|78R>yvZx# z)JSEJ0kQ0A>}~&=V@i_jKn|$SxBd@ zhTB_%XiY;hhUUo4xjZSp8cLQAjhYsfE9NL>V zA?aJtv^;>KO?cenafQ0tV3QDS{)sj;Hljn)cAYsC%@C^t_pSiFeH{rhhLCMKjVvt} zYNsZj>GDmzrHL8BMQ9||N;Va7s|`_y+%klc?m4x1Cq`=D!xA|*E#0w0KL;@36dc=3 zsiXucxM3a6EY`o^Xe;OE6;NZo%UNee7W=)c#pflF(qGiJcrI|Brmm8 z(HK}7LRO|m>ge2`f?1O8wRnvtM^ejW z&*ze`wAg5LrfaBv%!t>J)8|#9Z(oP7+Y4nW6Oh@&AYMUwyDy&C zP2lXGqVtAAGCX7Sq&6k`vUcdJTrscD%R_|ajea(oASn$Il!%}6dGCf;KCCAQF!IN6 zb{X#FjU|Q1woAyo{#M3Ie5BNgHl&rbp@i+qtV5=@luMJ^Y5oivZqp(Kb{S-M!7=#( z%N7OK=7stcZ1#Fx@@?I5U`Phr&PIUpZA9IP2=QT+Zv7&oC64SFgoZt zD42xEzX78&-fZ{*@VNwXF#FknInX(CIJcLARMv*P{=hH~eh7Ww3dzI6C-}DMfCF9r z>Mr?`kB2`g>m5#R&$&0P9vhm@J_5&c?Hvhb1D#4JiXQ@qm3;`8;R$fkQ6)Alc)&=chdz5NWTs17NiL;psXgpo8hR5fUUC*8SjLwn__ z%Hxr%^duBWzEuuOp*!7Z*MPcCZ!R~TwxLT!BqeKokalv8LEFrrbpzw%uz_wI#6lZ6 z2cZM#kQbpjEsFQU+2nFTa*UHiwuvqMp5E)ob80|QVW~_pj66~JM7&fx5fcwiN7$F9 z@lB88dI;B}xE7|7n4(Mt6js%?T}7Q7I}VT7HU2pnXK$e<(q!RWvMKZ zX*A$pV>19^(%%bBZB)U2!*D0*qck!@Ho0|FvMe;4JUA*msZn#8B3L2CO&GAA*>aw6!wt0o*&rvaP&tvqzQ!KK0Ri|@Y z>OZ=WfuL~6sL{C*OS443etl&LGVupn7NIfSNq#VktRFq>o<`c?kh4PykoJbc#B$y} zdU##hZldU@8XMrK%Dv#c0C+yMnc_jUn`$*vGT=t>)q$uo_(+C;W=vXEV+Ys*AK9n} zikl#HHGbP~*V}cT+|l zBPuX0QAv{J#ZlfpnIh-TWRmBLwS|rI!GRQTfDSqV95@1M%fW#O;6VLj)qR*5SXmi3 zpmTCS$IA*W=GzrfM5WJ_#bl9k{g|-RDQF* zk}xM52MN1=!+A@;mD&(^P`78$B|VEUeBEGhu6`W&Ai>~j^->$TjjJU;mXyYn0q55t ze@e$K_X@!Qhzf;`5Qa5Mz%_Seae z(gBq_LWFN|pJ@yc5EZyiU?4po+=}Jz<*_nBja`FSOfBVd9F{^~-!ab`x=`Mg!`ba) zBZYokbgOLwIG^%MhLAI_tDw+_6LRF-ih56VgVKvT8q0_Glp$xXtG>Yd5Tt>eL|<{e^$q?1Q|qP$*0;7o*r=tGk|l#{f- zG8(G;+vCq{LZbWN`Nxmb`0pgL@1tow5ZjJiSS2*26Mc?l@J%L%EUf47R<5FcNLWKS zFl+G-YY5YFM=ybzeu#)tw>07S7Ujk5hOSY~4`T`1t;M>T>XlMER0utMp+GOkY@phZV%I1ZD{*Ln^?7or;5DJLfO5!-Gn)*v(U3-+6TnIxALKX+r7W|x_t2l0t*HZA3v{#6dGR5OW#j7E#}YD z_1#MWWn#d!002Zv8n}uJ)4294S=jT3j4xsT|Ek>Idf=FeZRF8-{!YmJ0>Z40)wBC% zK-O$Pj0eLJyv~iYA70DtHDQCwN^>cPu|BRy;_O9qpj$BzSZOLpGPs_r_zFmkL3uwm zwI~o3fNVj!;qH+5!unyG3}z@>=ST&O7u&S9LP3V(6>?l3A!Z5aSaU3k>o}jOHy_Ky zy*_Uf_Ggt1^|wD|XnF7z)5AKLQoX;~aCN9htImsCF}p$8{w)TafW7y_W}1G+sgy|g z)1Xa;ZRp5!C01Whypdbn1#xuAy;A2xFJ|)r-6hzSj@`(e!>O1G1opYbDIy^g(7x5- z$eV|B=s7v3Qa-`$^?_xTd73z(9JX0p%PnpJ#b*I*LBgk7w)6ho2LOZuFjJY^xpQT> zd)1^BOpyCD)WGyoJoJU&hER@+_D?~I`63i67Hz!bdizYY+x6SVW1nQ~Ip6U6XXhvS zcb+fieR??TN43fg`*)2sEKfJ>*=R^VyBpft_AmUxmQCqHanrfLK!$j`+@BhmjPem zme;x21;rS{>~NSWDC_hXq<9^-cn1!8^k4^g!KK*++wn{zjt${l9&%vE&Y=7P&#C@@ zk*ozwiliQQilh>Eieyig-d;V=G#Jwf!1NMz4rzLOWKet|JyyfC`s^6N0u!pl1dPMF zIISX5rU;+#*c>2<#Vg}r0yLiX<<=?NC5@LXz@6>pLMPWv7|aBA%>+h+8WaqOg;I}G zo<}LCs0gUWS3~1tA%ZzhC5^*2fILdtaD70 z`=Fh<1A}&hin7}J_Sh0`@sWq1`EW=RYL)GD-?uvw;af_|Ryu`)J6I!ff=mgU$Mp$f zZY5lBeJR&YVb}X{xe_OQ_2y&g@BtD>kOniUC*cR4)mj3kf`4P z>LuzVY9;C^H@f;9d6}5(TuN+$OsNu4im9?S{SN?UCrhbGQTeBU>J(57`(LkkPJflZ z?qH@&W$gzp^~n9KXXM`24K*1BlMsC_NaS)C!Yrv}nZdnO{5F{`$To2u)bVtvAf}C+Y4IV*2eu8Tau`mfL=Z z7zzmrDJQ5!NP0k>5|cmd{r@8W2{+1r7vjKbE#~jvHy)e+)GOz^Cw+e2y5RS}=s=e* zx0kkSt((4oKHP2hZLgePpZ?kTBN=CzyRH9yqoK^d`C;mEJF!NFzU-ejY~22Cl$Sra z2QJ;arh3l?Lz&6h2(KuxMy+F~FHc?Ylp*yCXCurB6bN26sIUULvZQgX<*$wFt4ZH* z?30bV&!=tt^nBWe-!Z69Ps{Enk120|<-G2<&(4=+{&pVyu9jtPJk|x|bQ?cEuM6lr zuSXf>3`K~JW$K>vl%adiD-0tgreQkRj`Q>&n46Z~prmK9UXpY|(h++0i<= zlYa~-sM7*WY=UsNfUo`=@LT>jaQ?Re;1rq260Y3{ODIEJc?QoqJku@Jdbj7UG!q(z z#uwg&hO|@cFurg)e$xqKrh3a3s=0J+Q0)t?rwU0YlS|Nk>X`6ckD&B_DK9-Fc%$-m zLSgH%>BA-^6Ks}hJ2fM^KV6TLij;ljN}tIfeIMp9r6z@G5_d4!Hd)rf1w+;jnb`atr8=5)D>N zqUXykV4f@lSwp8EpLG*4%#^Ee=1ODrN5=uG1O8&N`%zzvFzh4-EW0dH%3U5H6mDL9 z=8|I{QmZD_d{9T751pNK@KW==aLO4TY9=;YX{_gRmAn|S)H>$|Djpgm&TDhz)xv2} zE?xy-slD=hM_wPEe;-QE=|)-Ua*zl2#)B}fP)yHpr%l{LT<>ZeN8$ExoO$#&2t4V= z+zPm1Z0I0;uCYFi4p$LoQ}_HB&JE3sEW$oOg!S)eLv=%+!R_rwTQ4B{W;|z?+5p}$ z+K!+dt>@BlxQ}|m$FUwjq@;9!GbS1a;eoElFqJlHMWmBBvfHN zcpu6;p^UEbQ6q&@Xg`~_4{HBwlO^1DzT7v@&JNNhiiwvXU)O)fxDHm1)`Fz?olgneG z2wr3OC50c-)Cu-oCEBtOQ%gJ|vIuV9Zb*$9SMwz?1U&%N*@meH?;^0he;!?rBa_jY zf}UV3mYMBkbTzjou6?r_!5L+;(`C`f0dKvq;A|GoD?kuTz>L=gMM5uxOHmw>#+#aW zIoCiXs=Fb&qwx)mkM%fEd&*I3P=F4KtTGg5a@>%j>6OYP5vfQwq`F?m5i6YhFlTW> z*ZcVGi9^~j#4aGi5Ls0ue4cs-QnkL^;*AMhg&vqvgQTmtGr+K3xf%;rRog%FB=k}EYVHZNN{~e+2 zfH?po#ngwx`;y=)F$U%QawV4=5ykDLKDHFKxs9BIkvX+Ea?1@P*AuUa38o!bimwY?Z74xZ*oifT z4STUn^YFsfS!_f+roz;Yo>UPi->7DlfuHU&sRAlD%H$rDF*x5j_R_VA@|G#~Ls(Q7 z-4ba38gQxd;B;%4^>#On;V8O6K$pBTQJqmcnG?>SmZGNzdh{^t7`N8FI6QJ9m@&-c587OE%g3k3neVho$=;KPB>2MK@3H-%kJ3M0>lo-||vwA1e}f3GtW z#4V#UUhP*|zCvxif_2DcWc@Bo)3=}S_y45O6NwgNXLNGx`7F#3lt{iPH*!Z)@SM_~ zA*3J^lq&C7F@g8;DMps4y7DeZMfqqhI1LSIkSeN~aHe3kHmzpIY)1tHg7iXQG_@3?&7n_FVpS}-H1^y%2Yn4Be?~%2~8m9lc^O$ z`6tMVieytS-HE+66ewYFLw7>*K{m7I;%5!7qr6ff&Y0{i9K2ifCjfSVb=*{BW^h*? z%@M+o$vFgNQ6At070=mEA{9s%M>h1QTZh%O9g?;xuzD%VIBX()b%36C2xfbYjoQR9 zIKH5=hQG%(S$dBtqEfEK56+7#M{P2MRO8h!ti$OMB`QUF%K06#;*N6OMn1SB3;$od zL&x7mqNm@B->arS$p;hJo$>thBX{4JSxV+(rFPpqD2EL@(e4qnqvy0hm5ub?sY&lhX7jx0(WMSHCF@Xy zGxKxNp&cDo(GIyYk|s)Rl;Yq!aVBz_H2C!Dn+&dCuwF6!TI{b=xcL`aLXbm%=72kyBV_ovaJ(Ahybr-Z!(-4CBb&56FJ`7^Gp zo5A=-&R|r9;C(~D(7C~&8wvG|bvSpZBx`4ex$x9^izMP~=0S8(OL)FLQ=|5~*%-^^ zq-SP)fkfwKACXQRL;MH&UxUA;bW*hGkT{BQtQ3CQ1aqJA? zX>>k)L+4rm(st$ueZdH|vbp?v3fPXV`x}M6!B>QnVKzJtIL82oDWUD|MD>SBH__U; zKE!8M@~sjcPA#dz>oNDBzeE5J0^Bvl3Q*2-m;*X8$&)Obl^1A19n~L;lLqqkERAX7 z&Bo655|JH>H-|CU-_U_6(jgB)dB-|KB~1Z4*C>ype;Kss3_=~rM%yKGqLmzk;h^PI7{{H@#c8Y^mFVq2!aQ#i6|jC#C|&DYz!%T7s*ZOf`ln8kM1?q{bLy zdNCIZJiKf^1utykFfC)H%~|G~$0puyrShmev8`S#|57TSf^f36Xo2DsE$IR<0J7Ev;XW854pYb5Ak5HolKpps+^iDxZGDkf$$m{ zS0WCr2I5M;yn(u=0>SEDXLqa96bdgm>ll%hg~E0`)A{Cm^5NX9v_V?5Tg#@vsw%U= z6G6(LI%rtzefRNm$dmWQQ714K^P{mPfxLQOiTYM>9NYBv5;|u}b>GJm&-=CNf}7PP zCXiy(rQWQrI)N;^KUy7qv%1akWY_&MsnQTL5`|_^QdPsEdliDU!6=@n0nl4Wfs%clO{H5nP!?kR8;9n?5nlqo3znCK2 zi|0yu>f31v9YDcZM;fYU25(Li^t21Ko)vFSBUh^P(w3pw(lGyaR(3H>NJE@Y(mYy*5ynmem8@p{JdwwLTdBmUGHQy(CJV4XWr@&RUDeo(> z(-Q&=MO~)wDXElrN7b zx&>)5ZPH1Jh`)ethYLJcXIMx+TUgBB zL;N1RJLFc-Hwfj9Y_jsf=YY%3-?7M6j>3J|FL9(}| z;mqDnS{JsNvu&*drcoslUtR6wX%hOAbmfVT*D={)r zU!W({LEWvEkv|rt@LCeSIE#OaOjtZa)=@}aSUk$BjY|w>?@*KGgivyQaaPO@0MbG$ zE(Pd?eesDxC+=KaqChpoM@z~dPL*+5^60~(z@Ie@C+a1)@LlAd zB@YJo(mWU?LW;jWAwMip2mK7=p*Bp{VU(NOh{w{Q>NimO7xy@;h>TrY;`co5f!41_ zVR9wH(wy;h>e9pAw7h@se(L`RNv~@p^U$*I%?58UfHIff0ljrlyZuGP=aCh>i9Gp8 zGLPeOkK{zzG$Esf=dd0rtSb^8!F^vi*fwgX`~U>ou{1j2{raTfE(dcs6^e_{k zbmHOxX$QH!JUN&Fa(XTsRZg6yUXic26;2#2Y{57)>xzX(aX$er-VH9Ugb$;l_$$Y- zew5Wxx5YTNYehJJnS8inY@{9})A&#%Inuh??j#vYj)cdCMP>|QNu;&vnzJ4(d+4#L zk-<0gKXt{$ck$AN`z{;n_!I&6Qt40fz&?B18ka^S^YAtwk z52B*F$Lc4I5%kXbc+{^zJ=IwH@_rXNxl;WXQEbJ)Hx)(Ps*zgPSvAdbq6aw-cklsZ z^KhON{i#I431HehoG zAU5L%V@S`c4K%Rh>X%5T+i(>9ilo zsVf8I83Dvpr*T7aO#peJ&K>JnzT|ja0h)FOkbpIsumL2vAhxPM6^E@VvZs#DF%rk4 z0*P_WZE79P`|%~WUN3{LDqqSKCV;IecLb4-*F-C59qC$A?AEI~h~zwZueS)qW=sqr zTc51TlODUo_q7gUVT=?wohn4-lj_$5GkRAe$#ANPbdv}&>2FJY0wS?L^*(=enTEIg zaUUN|y8afL*&ZrP1WGkug|aVe%;VSN;0=<`xSzpmeqf``Ns7(bsUm4>^Ib^wg_4@J z(UFDFr8pSsWxN+PsCjP~d10+K5@#-MUf-uCKcPPIzttm&K?WMh3Xxwtuyd|$8P|3=Q$r^{wUlGt@xviG@Aa>qI~ zKbI_Amq42Yg+098aOnk18Mydc&4#7qwRKs1IXStGbqZLYIjl2M^sajGEpHi8+D>&s zqRLsfK>UE84BINl3HecoAsg0f_%IBkA@8jBVc2}L-j^Rrep#OteI15WKmXDFU1_rR z$`}QlAWl9z=hDk$SOXh+c0;~v=(l5;WMw$Y@ZW}}hWofU^yvl--$AZ7WGTuJDUs|A zc`=7QM0szD7wDVq%OGbjY)fNl&{pojk-81{dM9dy|L|PnN47}PvthbFD5IeOn>Y5x zlgS%1hq@OnNE9(bBFc+M0p!fS2^jF1#%wU~dc#oCzfnnMH2RXjr>1&0$GO1QJe8V{ zQ#!G7ZZULn3v8oJ2?SvqwiF=v6Fvu7$k)?y*o;nSeSby)5Ve(`OeUW^RW1X9>Zfn_ zmRMhqN*;PTlj2LG4u)@38rk(U!`D^xeLBOp6p5^dpZP1kuajYo_reg}u-w|H3$!Wo zvN8Tlar{TJ$nnM$Pl-!%VUq8F27HiB?iSJmS%GWR&BKW0FNI|}x|#v-qdJ1Tvsj81B7dNK!+5lzhsIx_jL zsm#~bbjqpjEu%=*rZCy6(PaFl)MQZ-ZN}!&Y^;N2X7-r`AlBwI5Y!bC%cgjZ)D-*j zW;p-&@n*xdMu>y(JJqCX(=hMmc;O?S>!n(l@T@_G#PhOe@0WqBpPo&2iktxpu*AE@ zm4KCF4+9bEpmB4H$(@#X**H(K(sDb6^NFR@r8*jKqTZY@d(oFn-aLGYgqxFPrFWPO zbXRi_IA`5Ky!1JKaGlMFtT?4NbW8v9wQGH2n7ni*dt*!KJeOb1-s4oFAiy%q)&ZRRROGv@ld5iby?z*8uNOae3XfwO2*<9rPiTuB;68l`lT?y=3 z<#+X!Q+dpNew0idO2+JrAsx^Anz~RQtB@^jz)3Y4cAuv0@r4OQWON3VYz1qJB&JBE zkBjFIXxrnoZy>jL4)*!!^H&TOw>S-_1@PjK0a0Mv30NoA*0w8QI-v+lyUWcb~o z;**=eDjISfqXo;uM0qS%(9wrk= z!j1{pDBkgWESa@4HhrLKN-z|Kv(vrvI9vyfX2YS4T+=$hoR8_NycTPLon|*!pQ=gD z3)#NC$~_@M3K*P{6igm^K~pgRa(@V0Sj9hJHmn7xH->O~sTOtO3tu$ttpln`Faw=& zAORbhc!fk4RL?dt2a%Bo>v}=wHguqx1iXk~)P3mU7d0~mhSrEfm)?(kRys7!KMVrd zq7oRD)n>y))OXCB*xvE5Py6Gmsq#9*ZHZ|!LdmNyPI4Pw6-GQ?8a8wV*iu-h5b~z! zQ%3se?OcJreF^{!8fd?U%zi0K)wT^A6;MapiR5rm9b+QM(=R<7wlAF7vT|d%(DgFc z%4YY4;Y9t97}=NMWW+yiNmvG>xw2XzTrlWU?B00q5{V-XpmBHw07Kcdiz3MOe}u^n zMw2)GQ7+fV2>95I$`a_uD@fGK2}lU*UsmJ)87~j>o)jbc%>A*1yj$zrxWswjS=tB@bDn6t<7J zBJ#8~*(AXV%wrDW6!vSYZycvTS*$}KHs{8=MMbPG9v`ZCrGbfS06(*i)vd+?YTAwc zMy0VjHT`tpq#G+gNGB6_6?w195)vVkH5AodF{Ki!--zELmEmYW>Ww||Sx`E6?Zo;e z;l{ekO!CLBF}V_$FY`psrXwqMW7An9Slv!+{K`@HGMTe`hKtXOipcxBA9YE{jRTQ4 za^RbhWcHphuAZ|-lb82ox*qozlb`l%af+bVSf&(NNyIm=nL3KdVl5mhva$(Z9}pdr z#O7Y3ubS0WZNfJe2iMt*Zpi&>{UGu58WkGWkMzBAkCT{QV}*>Bm5y_ZXPk--B?P4#^j0vt44@8I*NO$rh<&Kk6W*QxnYw`q`gB zlxpPUT3fVwRUoqB(!4A68|Oi?URyI5gZEymbSo%RlC*!$aw`Ci+mBhU)Q;f)agTBef@F%E0VEy ze25wJ;A;gq!^I+BTj|{4B<(FNY1uo{t;)505IrXn^2WHpM%RV}{RX8R`$-+4 zr2h?l$WsAGv4R`))B}P=hV111xBms%sO+yD{3RpPb*o zvF*3I%-xAD{l4>uqRtI8ogrp5;-A1yKI*2BciLyUth5*Ju)jHA!w^x;n`NZ9BZ)-q z4dj!_nK!dSzV;s^T}DsZTLYF}7EX+B8HP!+I3#}8<<#H*!aAE#BNy4a9VeyMlK2Cq z{63QM_Psao^8Ike%iVAL2L00y7Dhu}4q>esZkQZ?dpwS(1-+9MavSivG@x}1uW9ex z>f-bFk!-Nif56YJy+JA7e&-&Igm9vmm)MED9J)P|Lx#PZ=wi_F7&80a|03)|?~V)k z76{%b?AZ5aswCh}&8%v}u?C_&5J_6zo9e<)7soK%`MNkVjWZ|)?Y_wUHol3S;f_N7 zAX(8dHu6CX<7Q!$Ryut&u1O3gUw7pC4v2fNmZ%ThCcEF4yxSf@%m*s`Y54tAxrz^T~YnwzSAG}AV_9d?zjF1KTk|PI8 z3@!=@Y=-Z%W%tqzeU)LbV{RmjbBpbooA?@#o*>;s(T zkU4O^K=!>qBD5MDV6k9*9s6J>hd|s&_z#A|!${ODO(n%2%%xd?gn{JC+garG53=1_ zVc+kM4{~p4wQV@b`7lvoyD~kE-2Guh6d>$GNbobh(&_JH%!}Y79o0dE52u*KG24s^ z@x$WuBf#{0EVEM7foz*Z_D&q433aOj*=;VequsoZ1ap@7L8jI5ZYCtc?4_&ZX6T7( zC-Plit#PU~j;yB8RMpatvK3)q9r^S#jY3CDKKLk(Ce1#o_ZETMjJv(bvXA3KrLl0x z!wh&bqyy{LkW^a)IrQ;3uN)=cGz!<7B=pe4a0qhIHtl7Vg>T3#$c>L0}* zRUwVwOtQ5(CDUfyHip%mnuK+A$T;Blh*RHO7l=g)FB*5hR3 z;R=6@<=l;FGv?-#KMtol>1s2MD4zV1GapCHu`rw$G;95C? z;kr|AHtegD{KhO1*NaCo!X~poV`u#}HF&eR*b~fY!$;#u6ZUrqtMExa=*rXP!7-ITT?_Lm0KKXJk5{?5c#E1=9 zuxJd#qBN;)R3^Fet7LESvCY_-N!ET<>Usq1<6jlI9>0$v>J#f-kEq>sVxTW-zdJF| z7?5MX9;gN6$zPYLaAqw>ATMHP5hr)z;K(_wuy%bt-34?~Hu3o;CRsu#PV`$<8{G6= zs-qykxdY$CdFh*RnNr~>l_(5+YBbAC|00d}4NvAor8cS%qW*V`Ye-!fDgJjw;y{wD zE}~C)&-3^TILd}W{Z^^T8~;uX#FqfgGEGCNjBfdw4Y!hW|4x&Id6JlK8{$O)_ZmMC zH@euDv8NzRGBE+S8Fk_0lWzx@q|lIn?<6KQBA6k?-=#Vc>oxB7BTL*Kr}&eXznkwI zqRm(kfuspNmX2M2ByHzPLtKm`Ip2@TdL)|qH8G7P5&k{>!$l$1o$#mSXdcF_lsS4E zY5qP}vEBoYzU`lhr2l&_7kgfeCILT`50_x5VqDr30vK_CL32OO_`c1lb!|qdL&Fb( zENlpg`BCix)*nlXf7BzbY5oy=2EX`|)*mDJv*g1cJG_I2(xg*c`M;CN(?5msSIA30 ztqpkw81*9}qkHY~P!}4e7k4f+^`e~4-82E_h2Nbxg6fI;9r(8ELTO@@Q1%s%-o?*# zn;50Kda>>l>Rb+0s;i7=q^?FHXXq1y=0%crvcNPzYhMCucxt}5>=>jpo0C{wDb@t1 z#6V@BU&~OYtkml|7j^@68^mmYY#H+Lk0W+Miu9m@Z=&CHr9{7{NaCC5R}kMpA&wLX z$`ZWrC9VJmfE-F8o~LwhUJ^+kq>_=RqTCAF(una?V&p&zMFzuZC)Nnf0Iyb%ou{U{ zI$)z%K^&)OcqoGGHTKI$@y}ZRLo(;*X_5GLXOnXNcEcm{TlTxL!Dj3VC13oU?doPT zR)i6s)9H%FeWxPG$kS6J9|Ij!nY;!|4-vkaynK2SFObo{lzAgF$?| z)hX)?)yODaypwPBLYtJMIB|+ZE0{7c{I+6Z`87IHiFzfi7sWSFuNyG*V?>#$mM9|N{7Q(%Lh%MiL8TwDnEbqFfpf zd2VmAwoCGiHlxj(yxNt*Zy^8f8j;2WODzufw$nMzgWG$OnIF!zn8l-=kAhXKjV+gq zJQJR945~l}TJE+AaKqkato9+x&cu;r4y?$}M2`^l$z}``U8k(E*3csw%m9AQx`RTk z;WX+>F(g^^b13oa_9j=Z1;|5>UL@DCovrWI^LkR-o$FEq)hO~_cM9K1&U9zH3j2#l zLeDyWIoZ<_mmrScXq+YPnN{sI8y;Qh)Cn5OfPbX7XR51n*C;aa?0q~Tubquiv?)(w z5Ap0gnMzK^{5H+msLhDK1Gx1!$)mR!8|CDS-^!5A)cih(G91U9)0<>&8o${h>(*#q(l~Mr`XnaCvy@uRb_Z5NE5`{W*iz zCFA@C5T1jV3vWvgBPjg7)bYyK`65mhu^v%RcE2TY(w~!=zy6pR4GR>Z@Xj_A6 zyUsodbvFAjmj!9CFu5Ax8g8=~y2X3e8tA7*vdQSHtCGcls?GQ|&o)hHKvlJ(*6`*s z@%zP0W2eZ-PglcS%07i7j;rymM-@-ft`&Mt$5zG(%r!OFHUN#jYuWq>lG0xTwgnL5pXnI5@lUne=}7z~z)mA_QJsNo$&*bE{5hGAB0-M((R8_E zSezsZd>gnKXvL@08cdIhPKi3l&&XlN?64ppk61ddtF6vJzmbKP%Nl(D+%$#{$HtKa zVN%p4BR?Us_d41l!F=g%u2muuOl&kxiQV)uA02thS$_qGhz8Z4joswn=^-o$;O00> z7C)$@Gs-fX=NIz}EJu01+^uQ4)-qJaSEdbgPK;*`Zs*8a!^e-%EOHp$LdNHTk%FMF z)rIw2{wd>E=h*rY!sGDwaZt1uml*J>tYyHGii>_*c@UQS<1G)!`FoO5(ZKA%<%Z*+ zFv~5BsW)_AW9n+tvUd_RR;}fXoR4usb3vjdM8RuE>_bDk`qhEsE%OTtc)HWYI;mZ= z-EOoQG;(8trA7e;+JQ1}wEIwT8DCy&h`mYo2Z1#G*2Np>I|#SaI!lcQKP+!A05^-3 zHY#Z5B+~JM1URwtwpxQ@DeAHIIe<%=_iwix_245To6(h$bOja!*aO{F=@!o+eDsJy z4E}X60@bhT4JRPWeN3KVpfA+g;OtC~t_|wEAj5JuI`fH^6+`$aYEBHL{h5~SL-HhYJ9L#JvzLTM1tNpx%GZY=UtgDg6zBh}N|ajym3%gDvy>?LkkCC>DbE7&5ru)H zqAiwrN`8_H{kA;IdrCfjri4yKK3g+XRn@vagzknCGIj;5K7MYk>)7F-`WYj{HHWd* zpoPS69L4feBp*t@IUdE&wJh}FBNHf|194+iU+Ilv|EAEg%Zs0vb~o^+$=(aFPimvb zf5M+&@ZjDWfe*y!oOT5@oZBnJ!f=t~I>7 zglnQZ{>;)aNhtw`!3!OYKcF|T9Y2V&x5ZORRS(u0UP1p5%h3p4V~O_RWBFdoXdga8 z(RQLL!g99{uSZO_BiORthd;nSX_@28kGdU5FjuD&6E^W{YFXqW4Z!O3;;!Ps`dYTE z?fRR(@5qA)mYP{@78S$;U+{K2Y1-)H8lYKa@$~0ME2v&t%KZ5#1=GZ8{EEf*$(jy< z#q`|kNl)&&4<_vzoPEVw!KS<;$nta!AL@w(gDqu8h~+(hUZ-eG`D~1($Dc2VYD^hj zEc6WZX+2}ap9V{i7dpP++R?TRU*5A62k=R>V_V8X-cl35k5aX5cxRN*lM~u{))dxy z7U#w`Bn4aE3g8nx+BO^=C0J~^yw3ABOgMX93$@^T?0KFz_1cJ2ua?PyyjIN~?4iQR z@%;6kiM-txus0mYusof{Cs}p}^5On3WeaDQ@pim6)wm%k%<^gsA8zT)<5ixlWOSG% zAf1o4X!50!IboLKAU;FQsvi#%dU|;K**}~BgfPo&d?VG;h~}2IAl}3Kw=ser#@ush zl;yo3zR(jXiN^9hVHQUaKP-ejd=(~iKOnQS-{ERYY#jPe8NsW>+B~(;{j|*PO}nKO zTV~VRM%0Rc?o(Ud%K&;`2J?X-tW9{a(EXjv4vE-m+QE?w&>2|32kICnHUgSlZtwAw z+u8FTwb0{(=Lb|m)w!ofeFB+U$_n_z5LSB>wOP)V=hPNc0iPjOXf;C5oz99|G?w>V z6)R9-a#rlnSnvm+GDI?tYJ~2WdIPIhS zAx89RL9v!EhVvfG5Ow|+ zEw_jBNu%7-lTm$Ph>1G!ZUWuFd>oBB6A(b+_ha}?qd@u>Dyhp7Q)Zc#SHt;R!f!z( zjcxPcUs~uVlhBD~pf_9m;6!B`GA%@AM%@oXRwCJ!X{m|elY&yNAg+>Q@t;7m z2qD%bmL2GuAT?8FiC*qO{3VEo2G-7Ah`lY}NASa9q=tdnY=%1c5WZJ{hWo&POP4sZ zJt55U+fY8ovNRF~_2(sLj3xEbBwMyd@`bXN%a%uV;QU*bpeQ~w-HkO7eeiQO4t}mv z^mC2W&w1g6ekNe}x|%3HRR%X_iGu4o0|!Mt-TP5|hWIeL*m5O`kCDN-siXNMC7fF$ zoSR@-1RrLpj^;yDjW@VB8+CC{BS!IPlw6#~VvFWOWpHu7M)O57c(;TYez-pzo71T^ zx|~{l46hDs+~9O;>Ch0TTN^HeGy6G)&zHf4MaJ^^{_tMZbFntmbCvShfxR2xvCgVx z)KfNYfY;g{ivdN46>aH@1@PW-r^`wO@N&^*p<}tzRds_0PFIz!=q(prRJdh#9Pb;# z>IPg?o6AM@#!J3h){`ybz#BqSsO(tF!Y-6W6> z2??Z8Lv=x=DP{431VscZY6@@#gR(1ugMtD9g#^&`3If+gQ$R!(dncfN2t^5kl2tI@ z_ssJ=n+@W9{r>s=kvu!Sopa{QnRCwQWs*vaWDQalX^`wSXi%(yrKGl2fB-cga=R{wkj(Ewgaq+X>HuM)7lIg`S{cZEdo*7}{>y59 zg%m{-%z#5NT$LED8pM1Tbqq0p>ovL&)Cm1fz^SM+o~k)?X6XPzdvWwS1+dY>S%!$KL>&Cy z=88)I$t5WWYd5zlHVLP3DVnNsHCnnG;MJ_!$DGc^(e{RPP+DAfs|q!Js!f!T%zFAs zB8yX)+Tn8q{|XxU!L^#w-2Qy1M$Fd8&xAIR9~-SrX8CR({3>aT=N}7A;FD}LB$CCZ zxQI`q+L}Sw7|d%w|5ef+yWp>6S3r9TQ&@ptHR!V#v$)=r6=!yH51~IISqNJ}ucfdA zmB!i4i;|=*(tbRGl#AYA!fbe>n=Yp?BRfLTMx1A~%C99+xsm0&b|pqoGMmP+oyTme z9GgYu*un+lWf2_P0V6mzyP#tijVw3Lelw1(eTDCCN$o(`%2PGc2d-^SD$5I%j9O>L z%_bSQR2JG-+6ATi8S|j>W{Gqm9TjP$E}O&19rw9f8i%Qhi_E99=HpmZqWWX3EirRy8u!h(Sw*aevz){FJ+-a+5&l?r_W z&FqDyI!K(oQXz5SbU`F^P&s?0Lgm6KJp&0Hgw9@}5V~-hoxy@*RAx)I>q6(`+-wM^ zbs3mIjh?+Hpk*^2XFElWRWrzJw6!23~z+f58~FoD_76~^c07in46qo zTrnaemqq#866OxN4o{ueC7!5zelA&ZnMc6QaHB_O+=!-YJy@W-T|L-zphz^0%VRx) z?3JA{#qMMQ*5_fzw7akXz`c%>jfN}oP!leg0U%5!4qBbD#pc8o9A-j&Z7R0dRctA8 zx2eaNTtAx&Ltt~_3C=LCcw%$n363usoBP@XSUas0aa|#9$E^TZGEri=jD1EQBj(j#PE`wyC?fJaI&= z>c@J})gdgrt9U<0_~@HQS^Zdw_g`{Tg34DinfoyV-H0kqX7P)ku@YcXTQ(6yGhWw7EaH-nLXaB*H_|=)CxTn?^l~SxJheLsBI7 zC22t`Bneo3kP}>8f-bB3QjFlPUj@?9wqoFeP3%kGudFO%pAc0G|kRFXP&Gl`|(*%QfkpeW_SxJzUOvnr&^VpFR~$sfw1(r_ei?ZBj{wkxMqStho!azDp~!T1~I=kR6_$*qgSGikoN!E)JfK}zKn z%qZA4+cGeC^D0Z}fg*&zHGYovb$*TyfwTf~j#jV)z%)?jas{RVEMCqqe8J$& z8>TXN8UEML=lDBhonY`@AI6IOY;wn%>@N`28UnZmxEN8H5#ah$V=&8Ti9>o3{2&_E>)o6#2| z(SU&VVl@t%QRFDZ2{50b#$hv>EaC*ewmeYj95$nkqgb}wj9ypsiOpzNpu-1pF*!8= z>&v4c{gNF3zm_%{0S%nZqgl@s84#ONT9DGEevpD?1UY;(DOh2UV=I7#c8_KWQL>(w zkmGjbm>RFh$;@hwHfN4*kr3`7$A$zYN1d7@{}zblWF5c`^DQh(sn9+(n{=T0e&$6?N5o}ErrV^{(EmG+EbX>1eyG=>$jU8En&Mkclj z@sUK$frGBc;{wr3=T_GeAL3~7!R-};`MKy${a6;yT6gUp%YNo2Jm=LCiVW>N@K_u& z`}pDOSJ#r`=Qu2OM&NAAM5Ir~A8@w?xC@FRp4+pw%s|{Ikw2!cWuh7nw7q&eOCN6W z!amos6**qTAJDf2=!+U5@q(@GF2n(iQ*=IcEnC%+kg>OXg7`1+_a@@r^>aY-)#?SL zo->Xm38bcR*y(}9yT;+HZ>hj`cWz#&kU+Oq0*Nn<15*Md_8gDh6iA#lp2hSAt9kBx zsN)=?p$D)z(7kSP`YY7P!uS=YdlK|07{=V zhdIs;3vhsIZ#4p~FOFv+sX*(qb%>uA;5dRhjK*T?+2sfW)s4ESy0dj^en&86OklSO zlz(ypMgR=oJb@Xiu)C$|Lh8<)3~-!v3wN9aw#)jrqh3#hf%!6wZSHJZIQkok2S@^y zaa;mP$v~dKKqU_-z&TKbvtvZQu)1?;YQBMC*0Y6yj&rw%JI;YZ$ofDTQgz{V@#n^% zzyefaRueWLa}~lM8*)J5#Z);_uqI)&d?HH)|7tzE8R;M)Mx969*^O#Bkd3oP5f3ub zby|!BYuOOQ>Sw<|{JSE*XWiMOYJN}>w@KI}^x>2-3A7U&?wm<140ks#^kwgGKZeG@~-Y(Olg;9+R@U8xJ^8?2EP#&O z1(Y2?Ki|d12@YCjnAwv?{fk9JsC9}9P9dY^VGlRtiYgttr(rHlaoi~Zj zJ-{N!YbNgW-ax&p20-A{e74hgI-M59*j3z|7~sd~b__s5(qoDVg@`Xh{4MIhexb)_vyt%B zp_FemUtsjbY#_ytoc^56Cc!E|OUcy9$&*$A&|eQwYHl^_7%jMmML9>@YF_I`8}DKB z!#i9U3X8$=9#R7VT&9gO?`0V-1(pR;<-Kf4nCu2TI&6<)d;66PtL_&H#Jb8u$!89G znS&R6eGYiHx4P5CIc!LjP3Wmjo}lTe1vQnyh5&&vcZ9In8+(o;}$O2P6J(`#!a60v#jKN07%%v0P#}8o+Tc-yh4N* ztO&5qL>RkcUJ=4;Uk{+k_p`numBxe?rPPYszZ!O7QI_EkIm(Qr|6@3tgt)U;&;ixwwjR^I-g}%VVzDv?d>%5 z!7&M~=Eowew~O|1rzYaBf_8`(VAMWa4KR^aC(Akl`C8t^(^XeJ`-rioINEcmGh{l) zRR;5)?9OShG!CwTG zTw4LvJ;35}J7U6$q&~*}bhz3dCj{GpO+I*}SSVqmu8w>q1$6QOK}U!20P6Z63uO5e z{UA#U@32|zBWzavH3+oOqz74CpVE`4wA^2c)cfPNOQm-6r;4Nb2Dq4g4~>i40}k%2 z>|220gY2-o4aOl<^$?3n*E)h5fi8+N()}=#LYbMp?%g8@-zmHr0xvZ-*y+=uhgew( zJXDtCz>Rs8haA zyHV_;Y)FEfO+4SxThguJezNrGr>adKp|m;$RQD)*Fy#Fht5}szwXF81&;=|P<_`*3 z+0DZ}BtACa);FOu;MmRXo|2~V2Vs2VlJ*1E%B(t3FwBL*AJW<;>l!iS7K^%#(R00lqJQk{5gH;;~_VUM%^-te~}m(UVRD;{TedX^fjUNhYtwC!=X z2nu)tBDg+_Shw(IH{5AW#Fq4(%G3-EoyW0u?5e*!`v{9H@tBy%=7IFT^>uwX z-CoNc3$uIulx#J+;ki=2_t$qf7YZ8_yV00L=WE#jcN?5_QO-i_DKltk47*M_Ny^z zWJau5tgVY!etO4398}DS45f zww)C@;!WN?Xv22((JXTNHxth0Xw<)%u}Wn1$`bPmf2vS`2ixPoQNW_#TVORlq39Mi zBR&Z0qBd(&VaR5-DK^RmxYQ8pbbm{CSDdB@>*6=YLeCKEBI+v9>2@smMrc${;%!Ih z(ij#p@IL;D%O#mwkcO#MNGy}(SUVc`r_c;@0}*)gGzGLfl<(+ zGeaq38Ow6F3zV6@3?f{KJj<4`6!tppT!yS~cv%0hy}k8)pyl~xY<&1!H2wh8cK7vn z2hr{Da9K%rJdJjz(<4tS?Ml?#=0oeAhF*!bkhU&#{Am^ur-gSYsavlCmR&23y&<{C#f z(P@{yfICTSrDF47dUtEVdjMT9q)xt0gM=b~dKCrONjml{OLD2{#|UZ{2}db<1uPvp z@ciL!GXi4;~R3#CjZw>f+nO%nTH+-R- z{Qs6dTeZddzJs(pbF+G2)-3oZ{uMm3W<$N(R?nvANQeRSK(b~Lj@ydi zvQ#*38ww7kCAnMU?{m5Zfkt@s{6I`vvz>*|f7f6EKBQwP zgazV`f~d8_h(QpvmK=2tpWahhAh7H6*0O2Ng?%i8POfD!&bBi% zW!w8VKx+oBw8DG0e>aWAlR7+8&Xfh9-x{|w5wp2}WUh~Hu_!==1jyDYN4fVE4Z z#ur%JNNo{TD~A)qtJS8fBX#w?QM2p%g`g5aai*5(tdsY5qBb2132GDiBD5JiKBL|* zvOZ#;mkV5^I+xm}xUCWOIzIhpKrn3Y0EDwQ%coQN%3t{hK=@HPE764)*)RpG2CQSz z;&r-4EP$X50;>dVIK5HDsQa><3-IJRR+g$kiX}$@>CGx@0V^bI@^Z*-f?h1irOWGB zKWwX6>)B{;-`-A`sawyCJv!wb-iHpXM_!=n1~$n%DBqcP#)cd7jw_&b8^HVyrc=nv z2lS=l2HanDs!vx)^BP#GR{-Xy-Ho51)>Y7J{iK2Q_WrTZS$E(@)-$71xlM}i9KK%} zldzQQlwRGB=4?biKc(#(*<|(|b=$-&JghIR+l1I9^xY-~>kijh*ilSrFR>zc7TM9& zDxSC&D32UAeS*%K;szjfi{8D%Evij%-^ywEORQIxHpgRC|7WerdHodD$jOaIse-yo zU=fGYM{lS!ll39}%Pgm=%O?sLxs+)&*GEe2%F{kIrW3;zGIZ@@fdd`xT-y-VPHmma zYNs~e8WV1`L1TiN&WN%lz@I_|f6gMjm+QoVZC2C&$%=JzxAv31T|fSOnveA=25=Q@ z!=DgmE;tlpje(y%5N>-6`6Kxlt7wCv6uu3h^f&%$B6j)Ad3vw=@ zXz{6`0(_z$)mng-uW&Wx+Lw7WSLB>cPm9l81hN*%?xgp&unc^D+rnbQN1(WPo_DXo z=Y)8BS+i1nh=78zG`ta7ctt^Udn40_=W2PAJUivRQ{+u?-yLjirw!Y1dO_c#=&MGk zm}cU_j;1!T&@Q!z?D8>XH?a!;%O|kdct9M0*Q$Rk+WIg(-GpnMIrLf+D`ub5r6!in z*9KDTR`53msNYu9{$qr-Ue-j_TbVn1jTR%8gFAXvWLihZL?-NO_bHkDwjtBg6ub>a zWMEsyDY5s7*azr=Z74b*hSqIk(TQes2B(Flz1;1D<`3o>(Lr^wg$nfqI)x(c7hjVmgpFla`9O6up(n3Or6DGKNkdl7FeE zKew}ip&qhPyoK6aP@O+U^$9TK%f54ofBkew|uVX+T4Gjp>OB;Ux;v z8+2H3-;&No1<@C;vY4n6#m}DPz9VW(_aLvR7s#+9hx~0UhreQ{=XZiWJZ@tFxINT} zOj{VOv9ZyaHvQU2s|Tt-Y|vTD&=pChEaBFrAXjmXgRZY%7py5HXFJ@5(|GFYyS8JlI!@D#Q_E>7! z#6(%2u`vPlxs**vu%@BxyKvT@)`eF6hXoj0j_ah4X$2lbngqrE0dWHKv^X(6-_wcz zfYJX7Nw}hMCJDUz6mdeJr)6(I+;PMS6XriFb&bsj6wzP<=w8`<(bjOa`7Px-EKp zycn(JZ_quZ3(a}Mxe>!5j^dp1bV-dAoMV)B6@TDwLXp<(FRd}XIfQ;Wh>iG{H^Aq% z6WhgdB0u^_Ctjm!5>hFba(44ui8N{#3-7rP8N8~&RKn3trwnmPa%vg|)|gr`bz)s@ zv~m~pn1TC!-6G|)X4>YqmcH7>Ql`vLw%#*DSHIR%=dS=?u!P@bXhYE4l5(B37XG&u z;%^t?v^-+@7ixJ{-~lW33g{J=JkyZpQJT7&rG$Yc9(F@3wMd;s8+KzO0keC2Hwzv* zUaRmE=B#j$ONIMUWVAC6w`yDA0+&3ekq0NFJ!rJZ-x_v9qZ~xN58bnerH5g=^1LC{ zfYc;<4P{G_dUbH;X(>Z$h}ycC%n~@!dN2+7d_SUy|FYzw0WsF^Zm6af$=8ml zvm5Az7m%kjp*pJj7=??vrzvQ%*p z#cp9SZ^>|;wha?%On0I$0-eR<3rA?`Q@H)e#_r(WfEH==yF836Z$VGPLZjb?fr3Tf zoJn)==oEeU7SqQ%>s0*B?Z2bO)C={s^eA!Q*kvK#w;@%#pT2t=$8Bc~El{j@+bJNk zn6WvndmB0+7JBP#hzlSX>Xf}LS7|W)9p;~`HMl#^If#b4YD`}ZQU>8{Sk@Fni{D{* zTa7YLK&qU6fO*k}@30(Si++bZib#3C&%3N3`8KgsASu%^XhF-uJ7}3U-4=6mAF6zp zB{{L)SCJ|6dumLJMf)mA8g@*f03W{#3h+Mt^e*e;_0@;E`X!irO4tjDgS|jGPpyZS zhP}dw!?_VJVzhiOHqbgcv6mGW+>T=6V5w=6tX9IEiO7W%xtTUp)tF-BGz2x3)6jh^ z*`qhIAEO8MvDnZ|{QMjIKpeewAIq<@dmS?>w?})7*0b@fu?@Fe*hlebjZrwhQY1rD zjMiauz*;MNtlbOy=vCyE`NpSq>4I4*{g6I-4>bIb1FXCI z+vpONgg|%5aFE@K#&AojHMZ~|jL$k&?_1?4U%T{gTZGNL+mC)Yh!f&Nq<@d~M>X^P z1rXTYAI+)qJ=QBvgKV{uhG#mQRG`l`C)91?a}YN~jf;?R;Z3uM z9b%c;%0O-AWvTLlqijWolz%^JRiRWHFuZ(+llc%EI%*FD_62xEAx;56Ti3;D)<4k{ z0MO=r7k+Q%0vK&w0mRqPt!rQ!FDrm-^BS0Dy$nIMxa^WV&X1||=OJdub);Ekcx{?= zzH#6l1#s&i$_vLZBT(OjGpQ=z!r>I+o}gO}v%t(p(AN&84`!c8nvb{+rY~I1)EvZZ z5qAyshgoKV_@$i#Hi%odu)fySXjF1$_am@~0 z8Aa4k)=*>myumyt=#70{TxY|^p&#)05Uyw(md9R~R9YoGOzGjj1&f9L?Sq7DU zz%rCh`|SWS)qeoWHz~&1-=iO}EH;y_f8fHW6~$64ZUmit+mCTnd=zFpQ^g#@aJ2Ep ztHW=|dX(iTtsFke?(+W8;B27JhpcyrhE*379<#yr4_MW#THL-?V;Y2UVJuR1s5ZFw zLu^lw?R?0RDg6ZNP8A>FU)(X~%T`j)W30&gV3N2pvb>MG%6Z3J+C8Yas;qrOZ5N{S zPV;G3gv_UR!FgAi)~*;R?j?iiuVc{q?0ba1f1O2j=g^X3O#-haB$Rx_ZuM?WRfao7 zPwPH%YBpHRV>9T?N6;(NhJOVHNyl9#*1acX9B08ywiBpu&p*)I<1Ai`FP}a<&U#>* zT%GBh&8idF^RFFe>(V=bAyat~Uw!L%lcUxK_EtrM6thPoUMljf|hNK5QdR{gg!(-g-!oq~NB9@U8aI?Z8_C zO(EFHKYzKmkY(9~ENeGVFswY%x(DBa!6`zfWn23NG{rxK>j#rsL81D+gMLQ6{$CwN zeb?J_n;`%auIxUe@XuIU>~iFqiHB)gfOrB3#cpZ%u|`pdTicV&pD8yR5@B~h1NAd- zOm^D+85}1S)7j5hRFt;npQbC`j84^Kwr(101KS zbd3NiJI(%_h2`x>*KUQg3aHsM0az_!>yhoX^;T4#95tqcs1XFjvNOO-a33GV8vbXEX(LKbIqh%#&x_y_lS>ND;>_CQydIeF1(>EE>7FmJ z5P9_67i_k;fdbHrJ4uV#){6qaWFtGptev6?F0JwCyXH6qW|kp|9ZeO6#oX{8uWgNU$a?A zJoq(qjO^6*HH(UfM4mqfmsl6P?r&|zS7-CL*0?P+1;0nRvmOl*YoOr zV!ocH@!!B8QEPH0Gz`CCef`Sft?R%y`QSoPzD#KLtz4*7hi3|7u)buN{E$8yKn>$6K7 z)p$f~mZ8*mcbAeqFl?|?LI!g_UMGwkER~SMK&u^IJo2m;GTa(v9ONTZii&tZw*j6q2pgcPM9ZNDm4)e>KZjC>0<&EbdkGZf>C$?&f*CV}^d_U$<==W?i z9X-YT`Frov_orAyVj(VWr4nQ{8d^a2(4OzvNGyZbNj4a#6EryH zBq}QZiDkKca8S1*HZI2J*~QQ@T7SO{P`0X>jSW9~5L-7^Y3)39weC|^>pi-s8DiQZ zdZC$RdVQQJA-flS*31ffbV39yMC>UR+&L1fQGSYz$9e39QxK_Mpzltx$i!)AOB=*w z`CA#pB>dI}0k0CL*=in?w`Am0`%MHT_bg-NoJ624sUS`~R^7 zo_)Zn;9>MYo32V7f8rkNW=b6wspkJ6@;Zm)y-?~{g3f3@c=zGAlUA(lEit~fZ>=c^ zjD+AP&!UXr?mFdD?>8IrYn{3tU)?O9dcRp)P-|)`(ox_UDE~uDeTIc5|17$y^P5`< ztZAu&6a~;Fu)b3}>-*4xGb}oM8!`*RHdCsW2~R$F799XqNUxnylsF`*%PpWU&ag}$ zyB>P);&>c-kOEqm(cQi?wLcZNum}?fzntc={Ux0hQkc_awI&m$TE_b+KHH>pro7fP z9Pz(lSx{bOCxe^rX#g!`y52Qn=Ipt&wT0;;wJH4#!XTF+*v%J;=}ZgDhb2PXSr&_p z&gs55ysa8F2p{o@Q!vNS8*CO~FJ{#vEc6J~FwHv)Y}DwnPgEL0&Q%^L>+_4G9ImRil}st4h*08B6jNp#mQI7r&4{uegYyU5%6etWx3=s&gp z!pek{M|N<4q96P`8dGK*jH;ONDHn02^4(r~7VCnqOfcbd= zaR7E_Tp8k4BW|y*BW@bvRv-@Gn%k+r>jTKMmF4*_M4}L-LUlsE{#ZyOT3KlLBWm;% z+*?S`{;EUNjr4dcix|{Fmb7;c4nx}w;}#OxPVKB!uUp@*Hl0Aa)_>90iS!+sN?wen zVz0SLYI7LP2x{}UYM^@-c?l3dkn%3E`0!#;28u$8hMY1bwWzW;&Ar3|{ih;XYpDUz zJ!$17C?s|C8aiu-F0n_e@Gh-f2wz2~kNbCcMLY%Q)+7CZp!}-W#M4Ok19YmVxQ=wy zYvTR@_2M40(5bxYHL(HaNc#$u#lF6vtdaKq%BIAIp|>-^;R)B`V9vqH(Dq&q2%Xl~~yCVFBRKmz|6yxwnbw#)VsT6KKl9@x6 zfwA<&E<7<_)Hq#uCxKhUI#Jor=oZ`~o*%`a6A0@)7+Yri2AgbHgu%=b{t=IWXh;*w zE*#DTjKaur9dj%dv9O)a@Z^b5;1pSktt_!zVZmvufHfsrmQFj`e}hIZtSskT zW7z@1dNPnZ&cV}|%meNp6uUF2Caa>7TV%()?qs=P!_BkZPS z3~Z+7Tn9)kyUH@FUU?S+XADVy4Lx!3i+AiD84uXeA-==q(;>vqyluvwA;7>Trx%&z zde7Iv9K)+l6ZO9%@&Nv3-j=*aXwCq+Ekm{UU@C0GxxDHv zyf%uzEp$g47^g?+={6>wfdU*Z6x6oGpN_V%A^Hw$7av%=90)$~n;XY%2x}6;5^y#a z%5|`WxTi$>U<*~qlJCr8w#7U162hqDGDOg}3K;cI1_Z%djsjKT^sNJYBLM57gQfNW zST(~P4M5B8wXdg@W_y4v4fun_14=p|%ceq>-cv3EfNR|!P<7Ivs`U>R9M}OjY|u-OXhBYoXsI;yFBVhY0UxR#v)Z^$bf}{vsvk2B@2~rMYn#pl zz$M+w-9zcCzu-NNp;0`(5|-=~Z);R?kxmN6IUXBrK_X@SIIg@5ItR}>lFq^XyGr8VdB}yj2}l&w4Q{g-_Z1}0;zHsiOuCRb z4K5Q`aSo>?Hz9N3RH7vPoz{g@HRrxg$owA!FOlq=3r~Lk8$jXl)eXPT0 z52oVgG%%d(veXTPFq-__`8f6x-R;gZBL6=xQwQ0AUznROP!_HB-~zupsD(wP7OBF< zU+hAwx?r(2Vv&pG5N;;b4alM{QErgsh8@S|+;J=}OJPxWoNVE%L!}ND*Zl?=I_)goZvigV6=59QRPYa>rs43tH!0Yg~tlx{Qm)wFJm*6Bu*7P|Xxpe2fLa=*Wy4~N=0>>sT6a9tn3X7K`n5w$- z{=7H5A$R9d?iMewBqzJ`kW_FVEe|2*W;G{#IJ7K4c&k6WT=2S>8(0!Mryg=LVO^n9jp)aEZ)Q`L~=d2lMQ(C2rRBV2bq2>*(zh zl&cbP_pp@ocv*x{EOhhu8gqEEGSY0G6P;@SfNO8FBif4 zK=9`m33_yyvLboN0DC8r06y~v@R_HqXcNBJ>LR(` zQ_dC^>h(wtH&T^Ys2?IRDzKPoQM|X<&+AaM67FCsqxb;Od9hX0`8m#mG{_<0*m58W zON%wS8pWkwr<`csU+xkh3o;LurYf4}bu3MqzvDb8gRB}ylcS=5SQStLZB;^JxOC}s zw#wh3t;)n0ZtPf<|}YxN)LI0frFC8U%?jbODBLGcc?kGLKHS#|@6-j_l!Uh$v2r7UKkZc<0 zT|F--cmWyqLR27LW$BcmMS0MJkE%AE=_wA^%6l1_dQor6GVq63Z)!B~Y~01eJPOps zX1>s!&KS6OqE3s^byoyUKAm(zWcotU)lCMOUfW%H%}LTKt*p&YN$a7S?wEB}{V2#l zu6g#+^2y<k+KZ=Igk3RwLD^Lb`(M|wnq^-}^cZ!2baw7KWUV-#YA~*KH zX4$&)uVU-(Sh&v-8JNWN!TS&?PON)TR;w$Mh9>b0&j&>QkKwo=iAQ*23J-{d9^0Qb zCh7q%1m3#_l3#JjxwARdMRVIs4HkO?^f&`%7Uv+T41fNzo^H(>-R`boC3!-^i07{mVD< zfdSx|TF@1*@Mz&w&tmKuP0Nkkko}XV^<1(}ylr4BgNLuvX}as}UwAaO_rZh~>aNei zFtDLPx7M=}zikz;S^U8$1vfwUryi-G;Gmk7$R()euvDH8t96KpWE-VuBbBF=*oDh4 zN!H-N>+s9rjYk@~SmWTROvb^o@yPc&$NtlBa~YRlJ^6A}snT9+< zo~n+-8i`Sf{7YcKf3y6j(Zl!DIuCc$StZD{#jFma!JxP)l9e9u6qjJiQ~|1-)ApRF zb%>YFv99|+cTQks6B=s~P=7tiI>ZPbAPavJpNwm=zN)-*nuUeD&es-RUU#A&(#iPkBvfjleD<}G@>vpi)`qIIH( z!;M`Fgo47U{0(D}OW6PiPU)D5o25-lsx~G5L)w0nON&9G=v*00=|m%d$X4S@KWn$Y zH%4_iIKQ+Szk>o|4v+RchjCW?mQ2TUu=%zc@A0yB9iP{>Q>wcMRW<-f*5kLV@Nqwx z7CSz!?E;>ax>-+oDzs_;DGkD)Z~r0fG|GMUSI?VQT84rj{kM>}FgFz1o|{^g`GyxGCuEPr<%)Iz#cxFmvS4 zJuN8MX=v_7`m;CB&QU0rO&IkGzeHnU|2fm(ZoSgZ8-L%(gu#2O*LGv)#;5e*(ay&4 zX8MzTc#H_Ejnk_Li_XZ-ElRV-p)=F)WWs|fx_Tb~C9Z)xcjj9t1@?igc;irbr%TDl zxnesF&F8T_-+u+lI$gxo5*~uAhI=afZA2Wl(~rxrfmVBS2kv$xp0?7;d_IU-=-Ygr z0DUUFyAltb)x-jBK;)1Do)xF{DLq};+{>#?KIl_3H1lg<67wiMSHN?fBa7=rUlj1@ z$QNJ5{tssNZ{3ChOpm@i$ywk^Iu-Zj!CtB8A&fE#$Zv&P6g}LRuVvp;a3N2I@nS#m z`GD>cpS|?7_`E?o#b+CRSIEmGjF7R2`%L&`JGy389?G%H-#V#1dJMmpz$?O1@3K8D z$-2hVPNpA*mGhD^FYD6oWqZ!zE?cHYiFBp>-qG|a{r zW*IHAD9!x`RaE0j?Mq{z97c3f+q@E~2gdG1T8^kNBLYQ~mjJoMGk`W2xSup(w(3(mmp{ zP087y7b zM&5L#==JiB!CiG3-1%}oD5)k-YRpa(M-gDU*nB0Hig=jI$)&uIO}7u=_j7dn=m0(x z7ev7Wd68>ZCJy91L+{23##kC|jRU_UytU&=v&62yFUMM&4?t)tdt0|D zu7~c+sdr*B?0T3Vi;Z&u(l%fN(c6NpwEz|oHvn-m4{Qs148mSx*MFHq8H0FO70#YY zxhzrV8)bXCMd<2J1Bhh);gAKOe5y$6enWffm9$&6x)0`BYXRRPe+=T5>@VBX)kEiB z+)X#P0p2TSVpLu%%F4&z-6qJ5Li>#9xUv*>bGqud1_W|fg03D@W-qJG6Dw`k=jPGH zK|DA~n;V153wFvhNj#t(*z{+g6|XD|p_0Ln(Te;udN7ZTyJ9~bcGC7CJhbWo6x|7(v-QyAYWt?bcy&z49srQtYi?iRrNV9m zUYvzb2gKRDfER7?T=@;W_#Jv?GG4(8yB>}!1%NIY0UihSExBK3U3!0<^{M;)l*>5i znE}`A%eoax-L;|V49GL?F@D+q2c6ZBWD&li&++g1HVEdhGTwb_s-uB7c1+w-Vu7|#rrD*#Qw z#^&KdQ~QoK35EyJfZKbGQVB0^*$SzI*9l@~0Adzqoe+A>m+8bfcw#CV&i&Xi8Zn&5 za@|(CcQ}6#mbgD5=&`O58!naJ0lIDIGKfIV z=#}CRtJQ787i^O0ASTnL4!aqn8EoRwJZXzmLVV1`gV=nsn)qmS-dfE?K6Kv1%lc1{ z^V(`Y=pzR#RQ75oL!k&wVHF&bzk?b26f`5%`KDBxRv}Hs@9s{OWB3$PtJh0@0(M)C zHGbA&*vRSO;o{rP;E+5OXG3kurFEen9`Tz8C=j^BG z*zG*7s>M%Xf)tk2uGc~10gGTqZowRh-$Ie_IKqPeD-{b@6ejZ=Lfm}s631Ak+lh|Y zgx(p34#OE${}ZyyiE+xRTtMD+Tz9D%em{kV2hh|mG(2e0Y#z5_{T46&{L2F142|dA{WgZ1W*#3(dS?C60$ATdJ;%-K@ja(&;0#DpkwsT*PU8t4%qgRYLs1{)ra>N8iaO+E z9K;h#Q@C&kc|$G(q{i9E1)Xf|T-K2X0$!h~Ap3Vyzp2~+{Ti(>5-O+id)O@cYAT<| z{a&Kp)A(&&qBiO3{Tt}nX?$r)tJkF{g=2p0FGV{lr zRYR{cnvR-zG}=6Cc4@QKoEbx*(|M^!<3?Tmi*(0yJ{Z1hUYgGPI}5|Ha0FeP&ZoP? zOp2t*cR|U*M!WCgu@x>V$5Cy+|Dd-v<4-*MHyyP$yW!BbyxKHX{symCU2VD(zo!CR z^wYB;^Y8F0+?VwK;(@*Lki0kBV6DM1QoEbUMBEZ_r1T8fv-eqGKmNE|t;u5(P5T$` z>va-~CNP<%%mCpueF2p zCuj1J&hUM)baE!2;0)u+rTlJ}^i6TJ=5E=K3wQIx7_FKCdI^1HK$M>%<&nT5E_yQX zC_&m&z!W@6V>Ncw-BJfew6dnFwfK>k`Et$- zXAY6A2$g2pJJk~{f5?RvYc16)X8+SvXVMx}EClN$?id%$Cw|P9>Wi~Pu)4_&XSc_{L zxz@)4iXqDBMT*mEt&hsgD{1`SFmk@J+@?OXd>-H7(r!^cjhfGgyTrgsWb=F;ee3M? z028R$%gSNVEA&S+FAz_ygC+DBHLXNR)2==jinNJp+PKbXk5TvoJURFXvfv12^D-(f zd*4I&6T0;QKE;Wjt*SHn=Mbi$%S4!jO3_7416u*=E_UD65_Sf~fPd}G?Se#$QU zJUIF=UA@$N!a71)Z23H-SW0^+_dyRA76t zuE3>Qn|U~+VGp?w=@NH(@*!@BK+oR*@%+3tz`6_HtIq~lF(TW}M?L7kL;MLR=0W>x z*uyS_^Gi+(ALdDA+OU?n%VE{NTy282uQ<54*xaJp{m7H#fn+#=Ucjz{=P10mt~buqt}tyg zw*}C|CtQIqfanQsh|@X&ql;?6Sbl(u-VkN0gZ-=HZkl=&j!7>(0kMn|v?-;EmnL;A zgGw;*8z@hc%!Z z&8gc#H^@Ggt;+xXH@q)d4CRn0*EJfG%kgRKgV0oc6V%#G}Pf!+R4iU>E7!@l@u+Aaba`0;OFTiYOot``w@i^>W zTFmq~%2@=x$#>|EMLeYf)`J^_SYe4?KACYG6)q8t`b)Wq&3H<0-Lg4fk-K^r#Notd zOf(>_KylrQoAX8>lyP4m9bd!?+*2@G@?Ff~%3U;BE?AwCNGe>+`?0C?$YP%Ft@H%$ z3Jmn-VqVZ?`g6Ma8P8EKUpE6q{TsJ?S_ZEKD*rdXCGtzKx^H1OT#L7F{)_JfV6Vj7 zKVsD?1(y*ndcUcma3dj34nkOc0B16dGEAO`Gw1#onWM{pxARbB16J zY53E8I=f1*J18ASu1;Th}+df*wCHTp1D8v! z1K=Nh){fmeT!+3yj%RobEV1!aQRH%NDAV$9>#c|YW>uS>M}CPuTG|xVvA|t0iPMl* zOTz?LEyu;K7KY~F=HYN+QHErpc!EHAA}KvrNPKsy>f1giJ^25Dpq{xTQq z>USU>FNIl`!0blC_0vT{GHWZeJ>z5y^Z0GKA2srz@f zQ!^}(w}|?)xNw|N5bL45dLReo*SARN-K2gBdGo6_z3Q)QU&GNc^Ge~oW}#^&Sl$+G z@6bl{X@5#y!K1sDu2Ks0r4cLmr~wYZBeqc7j`g?dJW961q-ML$qZD7ZUH5;U89VKqYar?6{Fiin7$a0#x!+A-UD_sqQbMMrvKhBWF9k>->(WAubdCE5bT-_@+d1 zoK6v$=DW#-ouP8)`NV0N#QGbQkBhXU$nJr z3ZA`WUF*7H8ik#G#lAqR&sPgg70jou7C?r-XJPdiS0^sY$k}OAhwM{ zNUajvE%@!F5L=7U!(Ah`Hle1p<#^x5D}FHBeyE++x6?Z-`LJm8EnXa&a3L$G&NN&r zoIw_$Suo-jdSwGog`cQfR`JyS9jeme66Qdjytc!9b*M>0?%SMEV%0S(qMSU;pQuNu zhGx^ARk+7hW&+mO?$o}Dr>9#MY*fkd1fBIEFpyXOlV|OV?}X$4!GK!?0}k?SS-T>D zZYORG*NIAHBOR9bLb>8wdXD%Q_7nX~d~o25c# z&Zk#b^RRrod0ZcBFczvBgBN6RKdx3cij4=lxOtcev54!{w9}btnyx#wuNIeL=CQpg z_Bmd_o}%&3;g+a@tk3ZT-WE^0p2Kzj?k@DjbI_1`*pob;=e?c7uXm@x&-2uHZ92xO z?>fcdwW1yh;0rKhJZ!+_nPVl~&Qn6+Aqu3^Rr*PYsmZ?e0MZFYw6tS?W+h8!eq^BlA&cs&ELW_3wqVnTCyh^^Sec3`{)C>}$Rj-uptSih*uQV&;c3u! zuy}O~Rk+tnA=VUZC4#$*Lm!39gN8Vj15AN&%|@u1%F?zlD&E9zQL73k+63bknc^Ek z?{2~+1RR*X#EbDd**!1uT)sAxHon9cyDtQ^D-VDT!26bhYsR)@7hJRRG6I`Dwy;(K z0vpAi^Ds`LFGF~uh210R(97JIwnS{grINMS6WdiccNhjZ^8=FvK&=9^7-AW? zvb72xj+PwbwEoqmHNMJ$3JWAP__cDf;iy=u+zfiGm0KT0TQ}n%J~~e6*lInU+04ho zcU$Qe9@I;V4pUqcH*`_d6QeL<&|PIrTAqUjTDXOm(3`t?H=k2TZNNy&cE{5n83HQ%5`v(p1OgI8 zMMS(PXokgW6wx^su)HqU04_;fh!+sz#;Sm#1XLDr382@oX%GaWVBWX-%taO!dwFt*hp{R5tX5PlDsT&b5)5OA!11sJK0gqL2TUY8V_n%xh+{o zNp6i>jkr;WV;+!kwZh7?$Zq;L%7jd&)o%2nQy9bVUqe?x%&C}ir#=GG8Me3+Pl7b71q!HXRH$>)?^b)z2Q%7(MV@ev#&w( zdT{27*0xEZQ*WXT-cKRFx9}g>lTz^C)!EZsUp%J=d2z^>qBp3)bm-q|Xb3hJU`us& zg_Z5Mm6}S7Noj@mmKs%#k0vEFQ)lx$8IH_p3vcoWH)gfLp_Xq=-_s-S5RdR7kGwB? zq#xn|Uyxbeh6pxqjMTx@t%z-d*LonW_Xvk(x1||jgl$}zU0!YQjvfVDbKBsD%)H%@ zp~Cz?ctMVi=b+JY$JVOd{4HoXG|GA&@X2JURkJ%b+1t8`2Gy$fhBn#ZkdL=qFJ%}E zC>dx(Dt%h3Ms?kR%J2%oV6vc^({yH?8hIo5svAbO$!ot|#cOksi$!9i+hbt65#_-n zA>a{STgdnwxU={+ihSX!B6r9l%l|J$j{IL1`HPQ7k@;z|=EG3)3e{M8NK)1t@WBj^ zHsIwlqGvCeVE{*jdt`Xofafwi*zl4l(?|A}>H9F;*CYK42D~T3J9)qZ(`EVuBYktL zWPLIn53He&Y>43hJ80{_)n1xFrK#j~HG;)ZVR^?sNQB#5kSIS#Dk~%f4igq!a{{mu z)zNCKY6rX7n^I+-z$nB;x5df4^NhUy92b67+_Oep2gH?yqsD#;u1~L1J9hQHs{49z z_a$BriS%13Bocn6MB4Q9|Bg#;Mwdx?aNIa)J!I7P$mq$G-v6}-*Z;DJK4uYC7$UBR zifdX1g>1lr7VlVYP?K%0q$!bl;!Vc2rwX*2)oo@By6WvuX3+B+)Ud=io>l^_nld&9 zmbO)}w8hR!X0#zA%LXTpZy3_@5DhI~$jy&0=J(0~InCDFA-Srz-($i%+>bGXygO zCjnUE_K0x*XOgKT8j4S+#^W3(V91%?#@<}_i$ zAjuinA3&Q4g#2V!E?`@*Cz8#NS%hI3fRzBo%XbMk1ZjP#BbVOWs5aod=Y>sb42|9b z1E;+AR6p40@7tt0+%s%_>G^z$s8g?ZuM^-UzaP!4liT|@`q9!lHNNnF<}$OqA^Fle zDi+2>7rb%q6Q}5k9r_R008XQ`b!x~B$>4f(p_loTd!dJ9=0fjh#PdRLihH5A0clE% zg>g1X(1YvVccUAK=m9Fm~^KF9_ z#x{_vVEx2~xI8v!%e!jN!8ypyt13Q}upoS4!UxsoN8{knHxNUO5RhGJX?MFd+HD>{S@YCP4B6p+6T)ZH1U9dol@Udt*r?! z_ossQ)vO$@*g0GjXxGOs<6L-AS(`(kcJZOH^!ocS8ufaLe%`Ex$4M!GJw>Y&I2x&6 zB?ZX)1GT58OP{Dqyxq3)q8u!?0fTLWxoo-x-bg;ca;YbDDIdVz%eCPctgnE-3{s}* z=Kms=%$~z(@y-v_?pdvJ%UI)@UENfAzqed{6~buaWCw5*WVFdq6UqLe8c`mFMlm_6 z2ii|=9gxiAsH2GY*UD;xl#$=oDjb&Doa@j{8oooyx_cy(_MJ*fBWFO&c zZ278igBNrhgXt?eI*`}<;G?$q+>UZ*ofw+ zN}#fg-r1_AM>cI3<*UB~vQ6A8bWFBHZ@mkDt#lE{I+8= zTTRoqs}s8Z9nFh2keY*mK1%V&^x1YCztpqZ;Fs-cWPH8p4m*(@zp+Ba?G775#`uO3 zqSp?1xo9fw2y4F`>aCr|p`n!)_DvmG#JMR(f<2I(57TrnWS3!( z<&LM#A3@8yDT03C|KdoB`51S%#zfJek8$vZXDAnc3^=~meXLH?7$ZgOM2cy4D%h#o z`p7c2K<46s0vP@JNDq|9AQ#b;^`%;z{*WdL`(u2|= z108jI9O69GQhXB5vbl1zXx~oQmO(eYQyrl`*`50B;)6#fWA83_`Zy15z-|z_zAFvi zt&aB(Uuw2yXboNs+^vpLl^)c>Nk+s|!6$0p1cPlsTe4)dsRhoWPlaU5dN)hstssAT z=@T_bOXB0ZO`oU(ea&1bNPG%yADBx@vu*J-`cu{J|LPNF!B`8>!=I|XTeCo6xbagc z49zURcA-m!II>4gxXsL07Nj%#uO0|3FY;AlFFoDl7q@43H!HV# zc6YO~dUzYoEHXjevM2u=PB(}h{a;8021B3vN%Lm5_-_b$q~>2b_h4IAL0tgYEW z-saDs>oK#U34ZwuUWM+Vtk2cnk;78>=&jjm30~@RokQMp_Qmz_B1|*{f!S`+*Zm{%lzv*wV5dmhv?g zdFMQ^#`*+}s)x9Exx(<<;xioRc*TD`>Gf*Bpj+@+DgEFE)I2#C^?(6#yE=RsBRfm& zXUJJ(HP&oqYjugCpX${TxHCZ4C829@Seo@XhJKO`YngqjqhtL65DWQNe-Ui^+CI31 z>GU}5-=|K$PI~WZT%+m@6Qpy|`XoH^QG=Aj9!$|sr1(|0lq$_h=sMgI%Zur%Zfe=9 z)IEX2o?%xC^pi7{=97@Lv|vA`)%s!8DeTy$e&+5J=^OH7uP)UsOO@smr5dt&Z)%CL z)X8}Np8BcfaA-lw6+h=RE_>={-ikf^YswY&PTH~#`PXVZHQ|aJbsChO6eE z=kus9KW1LnGFsG01$6&jwDU`KFdViX?WLa(QXyMkxTF_Fe5FQZ>;xZIdc&P?3dA7cF(w`EcrLTH?I@wOGosfnaJ3=J7|RDm=rMgW?jHtE3> zntuR$8duVl0($-c1eh?!ILo=H^;E462#;HbO`A zlAki0iLJr%N5*}Vq4U{*#M1|v84-P#Z~sn}G8NE!FLaSf5FB zMD5<)Ea-k#ccI zC|#9@9m})v?TAsDn@ip8+?1XcOH%C7P7`Gb@ z`A)q7Uda-T>)DS2X$9Ud*aePkL~_|`?%RNmAdU;;!xj!h9on1--SlrbDwIU!8aVFv zNXKEQN896bzoB*~$Fbs3!Q(e3;xY>R9=9xpQUCANl&mpm6J9ht1M2yH+6a7Cd9>pO zpm0Vj&F660Rg!>qOr#gT$GLW`{a%BdH2Up(SX{(VYJ(acSRV?5kq5o-{uY=C8>iY8 zzIimMLG7=4Jxb3ts0p3^Tmla^D6;}e31uXG-k?sf9x_lhQ0h@Nr`JA|+M+5mFK%=4 z(g`;NLxyjH^-~yRY97!(1oRO=k0o>M2B2SlRPEn&;}T^B>qpFrzC%Zks-gM6=IVhM zL|nOQpyg3M5rdSO<`sN5dQ`R(zL{w*fN6LYxQMcjsjmu`bqalVOwEJ)foYNYZ79Zx zd%4VcVD0^dVDI|@W6qd|e}}lVkz16%y8vMsYH6K5sJRk8NLchZFsHFfhD8x;p^qco zMC7XkLzwxp86OtHj3X6ciDOE@AW$7x!${ag5=SOb^>OTHV(6pe>JyUCq94>g6MRrE zmtmHzV9m(coOl^1rYtj;%V8!v26VH5U-qmcPnYsw1V0fQRD<2J0iT$stB@guc*O6> z52{U;^5+lgY)dWO`=gp@xsm?)qnZVmxAnpvIatvl6`F_eYJ57?{G>+3 zxs+*ntqA&Y!c-)Le*=$%Cx23-J4`~RvKiE=QH`<8ptMGH6doOaxKW+l!Hw=%qxysy zzVC#ZY=&2#P-h}Xr;}=Or_QMIRt$HUWeQz?QoT(LSVXU$#4gx-5gkC9U?Yw@H>id$ z47<|?pHj0e6KLcqjIAT|=qYuEWhK6LE{!8*IjmM?^3n9@IrSxry)C(V*-7`DQ-g8wZQpry zjry6htq`@!9aly63y6ErGp^VjS4^`ns?V!IPU>_CD;<9)rCq{4zl)RZyre!Cb)sBZ zaT*Gc7$yAFlq)U8Jig=`6s#24Xm3`9s!l04%AELzTB7Ec8}#JUzCYCYn1pE5W%Ze` zvyU+I2cO!?IJ_|cFvT2$#5ue1%4Kz&sulA@P~3tkY%2YuMa@Z{I;goszG72wpn}7Y z;LQFq+|475gE9k7zqhEP^RCLq-O16+IlPH~9Pw5wZcJn3Gze>rO~wV(ES$P>k?1b! z%Whv;BVsJKulz&|6nNK)I#~=bWm_0dH(Erx84(P7DiLV;VB-dhc+S$Jo`)%v`-UKK z3$d88j9iwK$3V!|18Mo%#{oR3nT-?6eWj$4-`q3qvCP@ReIz0X03Y!W%X&KOBgpa; z&Gr>g=hNf9Vl8Zq^ZdjN*z&CM1F(?l{6q{j1;G2$c|Q?K@qxmIjHw;PEUf~PX=7za zaoS>ejFxp02Rk#w`mlo^yQoikFmL0W&f+tb-*N0F60Mi{z%;Ptahlyt1o*q=nW7-D z<}T8^i3C}(ce{xPWmU5S#1sj6EK(;GJci|HQ$Gp4n`nyu77sI9m>EaxhNL;)t0>4Z{aNedPQ!7gr2 zbDqO8Yd@ca_|TNM@TTHhWa);o%?o5q&HY$tR&=r3_3BGXfib z4-@G|Tv~+a)9IrJ@c4ltjZqBU6Cob3q|=WP;x^&(nNFQ-B7&wwiil2+AmNm@gil0@ zRWe0dl*sNh_?pOUs)`ah!UdK(79|QWkbo+?llNaFd?8x&6Rusi)7R1B1~cJK=x5p& zmrXCkhzyBwe~jp7CS*m<)d?$XVw&X_I%5+Qwj1%SBLId4rX1Q$FWSXqekIW^dZevF zD&9R|qCwm9s#EaAnR~bYWPcxjs2pcOLBOK%b4|az) zejblEO0zS;@={#>zlqUq3F5x&44&G#U^G!{!4Md&Vfb5V4MX=}gz4P`@d%I89^(5B zi9F(_6BK<9nBnIMNZ>MA_;?k1Ea7d7cl0|g%#rt^O$Wx9n zUA%v>1ur_tonsUD^POaoY#^UP|4A0ZEF&mA1n$dC$O6e#Q#bZW z7so7+b3qx9uKi~-Zv~!O#dDmLt}OQhYx>h?8KM^qMXw;0DrVEaGDR@{H@=f8R$El< zUb;COjd3rX$QGN!9QS%)ksNAZanRNrln*R9Vq?^mSv)TXVqOkBHIU1bDT8HsmpAUq z6#;4ldZ1pJE}Hq@GDS$$gM{ttKrMYmWG~m2N8q9g%W8(QRN-#?{t=})Kw5+0JRPMl zlgjw%G_0S9wQQri`OihJexjm7HgfK|ePeXKC|5BC|205_hyQXnb`79y9Tt|X6~_W< zKdXq6rfl3lK-^@J6I+@?BzJlYDHno0jq>SshZyQ#@3ZgvxcE;ofiRND!b2>8;Jo>`MyipkNV2QD#MSymKFK(2L7QHQpH~w=p zrZ3ACN*{{^Gic~oh%y|+j1_ajc9o%ZG8}bQi{clf1e{VVFTplN3B-E8NZg<$Ae#1! z5jLtQ5)&=DM4|pMgNBV2*F%a8948isPy8=9w#}gEA|!i)jmhUayf zOZ|2BnA2rk13iR(x zc(I}%X(@LXTt7fRWJVlP^{>nfZw%1)oA51O`d%}j^d3i1oT!C4}d_YC{WgaroEni7!&=R2R3h?Kb1z|{yN1FLS+1G}QXaKtqac|(tQ z8F%1+=s*!uL}ZyPfj3Evtp?aG0JB+&@xVYp&C7sa>}E6Ifx%cahsgB*0vsEv=2BoT z&9_S91a?)m4F(9l-?h+hC{@M{#xrD7gx#`~woVZtYk^1ncwhKmYkq zeF6So2no|!Djr2k@akuryH)sT;us#Td=B4R{9&_<_@mg1Mg{{H4guew)TtuGe-I~^ zd-KQ|2aTO7Vp0bKRHE8+CzzX6KbSFLd|{Ku7yUW8{5D*(=Fy8&Mb1cn5Aab$+mYP# zklVo{Zuc!_cAFjn_#_k|*LH4{!GPUJ_EHg2J`7QiA?q=O^Ne;4tQi7WNjI3IBe`{J zZ=F3MO+g#j54n3u=_ZY}*h}*~v`M?TF@DBrFK#aGzdG(-!^1!!UP}Dbh|6h1TG3UW zZnA&yQbh7=piH~s?WkrA2XyT6go#_R!!-K2RD|K+*rcc`m;$B=Jagy?xnY_ZZ>ggf zr=gzfO0f>-I=mmIACr9;Si{y564nS9>RPyk4Ojzfya1Q|D4Q6ES0JOLt6?P9uC9sU z2FVj~dj4$-Jpr=Olg;hY#D{X4iABdoIg4yaH2LaAG3%WG>lnl{2#4AQ;ga*^kL3}(*kfL-|8D})VS8ZCx8x47tv~FAYGg;qDKFl z6C+`*{12{q3;#o~ifN2d>dvES3W2$GfcLTKcitoicx~$d2W+|t!vHV6UECBqo{_-> z3#3c(FurO_-6l+Yv2)`$baDYUYt6Tdo~kX3ddv{fp+@iFqPnl-nb^+Iq(k;J(ycQ@ zrmq>B*oB^-Ard^lKfUVvj~U`|)n^+0y$mbkU+HL>$iONn=ngEMzox7^gsnC6lYun( z4sjh8F0U{cZUiKyfswTL4v}g(OjquJ#=!#|bEg<-`GD@e6S$VpvOC+yuDw$v7n!LY zQIZ|D`8tbuA}Z^k>@#0Smd#?O8xk$ktwyt)Kst;}?(teX;mgDKpVwhvI3t z`+w$45f=4K36$*H6}(j4W=F`9!-CHH53QOhdKB!OVkm5_FeuvL4zo#}^G}?dnBQZS z*$TehtXgZIXEz#QMJ##W1!297((e)hLpAPF>}}i}*_JLd&Zwu4v#9t;3$d-mi*DRF z{K$OHEC=OcF<<-)ExSuNd_77zc$er&=ROc!{aL)54Eqq-?-q%nX1ZtHr9fzRWxl5= zcZ;4jGd9t1gT-yw0W>IR0#-Ympn>Z|AVoc=`O#hF7OOT4#8AlyEwc1Dn)xVB8dIlY zKZC1ZI4tHSz>E=8^E6Ubs>+6Is%nhhqD8p$bM$Lm-iCB2MOvN-{vs_+xJM*=*T?Hi zrYM2zH7A@_-y_1at{{uNnFxz6+0);|>wK(n8yAZ$yp+w@y4z6;-k==^Nz3T$Jt8pM ztZ$=H-$gL~sgi^Q)eJ%I!2d!>zgZ$Y%FOFgi4`($NKNn*`g69hB?Z-_xM?dvPuWoZ zZ{SGJstE{9ek16;Sz=(;n^#w)q`Rz0r~jcM{bfb&GKq0lWOW2yh;dis68QSRRKyr4 zm@h^mE&Fx$Bu$Q7kID^pSMFn)Jxj#(I0CfX>i@Tz{c*48jZ;i?+hIzdEqcV2A|s!A z@W8R*{@h=b32$3seCi$~p zlaSYr#)WFA`F=>E6%V;30!+*?c}eR?e%4?u(#uA7&snT;nhN+P(7|;aN>Ot}LUdbM zE+cTo@QTZ8W~_Csy1K{_!(#uui+O&sEt(zh??h7!rZG$m`(P%A{hQh&H8(k z5Fy*kP{}@y{(4T5f^23kHUo)TZ+efpj7ZZmR8Lbq1PJ-U8T6H!z52Fb{6r< zpV!+EKrVNIh)*;~PIngZcB5S!uJ*Oe6=@m<#y=_j0TEY_hr)P7H9&N_Yu|<{-*AMt zDBG}3bMtLmJoI1`M0cZ%o4__`ZfH zk3Qp_m`$PZd64F}xN+LiPSqw3_Z0gIjh!cYwzgYjZ+dJVCh|0Td!7hv1!wl8z4Ng4 zIYvPbiUH7=6+Z|yhm#gQC{iNcN1b_EgT9wnBW?ZG(35sPD8@M2t}0}(Bk`zx=iFBn z8rc}z!*a4A4x5%cpDh{%BFj~!t_0YW1*tUQAuQq`S>UU}b@7>4dh8()74!&-4TJbP zgai5p976Mc3JxzG5;;lTke?fI)#aAr-*0t~(Z!9^qHi(KtH z#L|{EBDzDDeM}j>F<)fa($aLk-%<65V|g_{Zo_1yz#qe6_#!}wJ;<^^^zc7`ybR)v zklVPZO|o?=`se^giJQJmdixO((6?(VnZ|nX zKG4Lg5!M1-(*S7uO2lm|#f)@-KKZ*yqcPL)Na(MWRW5qBvU`^dnpH0DOg3d@D8A%LRFSt#2_4kLo%r{KH5#c6EkiyY%#4C z-%llMYd81@P@37ezE!o1bTFlCmho^ncf=`r#@Ej|#%@4hpM-fj6AI`RYJkr6N{twE z+u(u+PkT_xLb28IKAl-8@_jGl7=z`JzLc>@{O)@`hZpLuQfnUNEEWmL=C>R4lfpwt!OH`Qp;iy1^?qwOT^&Fw$w)RV)4=qRpK@CR(f~| z8l50^jt(=&IMf?w)NeZ@+c6N4}>Dzj?{zjU;3os`Ena<)5C#} zscRQ+gDXySry6OL#}{?3Nz-6>*4%~*>)dbuQyM%CNIU;7{I%Vz|L#2v=4z1>gb!IB zgNnSEMm{DY)sa1D=3^qN^Hp>ZJ%(0_p%agZUcJVH_6@)1>o>AeKfAv^0sj}f_17oj zKlEabelz}Wj_a!*fg6kY5q;@~3NaKGFM5S|J)<4oiH3L2ZJF+unO=2NvuW&AX=v8t zVti*=D7sx18rzq?cpOMqP}CD*V|!vJ_NU`dh>_O-3zmwxVQG`FUTA5_Iu8X@2~5&h z5yfk@MEY#0=+!k0(Kc*5FyLWy5LgpI{!faWa$g1`7w2e@If84v0K?ufiy48(VLPIs zHs-}e;SgsLYjm%P-(lP@n>x%{bp01C1Q#;N)PjcDTTc+n>Z~$ab2t3`Z0n z(1XjwxS;h&$|9gFnve8A7Bp3_($Qt2SNn=TSwJyQiS(3qDBXM&JI-0ey5M$kC~p2! zqJJwEIjqVQ+WC~YHOx$j%{bmb?j|dFY&@P3qg5^uKx3X3j`kTF6?*AukIoQ0NYC5p zkEg}$t%C-MX1YWyf4dPAUSiLSEQKlsO;;1pMZt}iM~f!o8w>g7Dj=cLE)m*s^+Z5m zsvsdCGI>Mm*`@bg)NhoiKD3H zJ^Sz%Y(4WXV66QsqLs^WGWaTe#DA6a+j1yUmQ&IS97Rs1qbo#+&t#c2tmYzFR*KPh z`f2P+B<)WNSK{O(jXqc@QY=w)0zfrnB85LA`l{B6bmKEP1zJomJ|iM53*gU6JZ+gs zLrHvrH@l*q6*E+yiS+kp#f6|lH^O)h3~03kE>(gY%_U&OFW?zU^h@2rQMgym@|bya z3%*&Jeu#fwbX}QWh%1%@t1nF0URAfT`JW;}#ksP|C-2-5R9cPIs(9tG`1puEF7T6Ggr(#zi;HA7{~Tfy8;? zpsE++e?_6dg2N)$OCQj(m(i}rsQP74vW*VEEHcV3j+1NHCS^;e9(}fjunNm;$xxa( zQ%JF~P=KX-F~by$%%71S|3&v;xbbOcqEPZMlh-QWs8B279R%cY;70KUm|DsKGRDH< zy}mTjxH~-+u1)fcQH?v8mRKY57F90+vRHrIS^CUS)7*$exH8bZm)?9uq+lmOU%w*K z#xcDOnz8}7Ilqw|cM)yKz8Wi#-fg&zxcfU80~1?3UM9KeYRg+IXws`9+}Ff)-k-`} zg|dGit$J02CYa!7I~hgXZrrN6s(AYTRT1Q$#k7IL*s<7ddV7EtNI|cO81>g8s` znMl5_2a|fSEGK;Qtzq z3-l%LT9F820{AWD>Hn*9C?Azcrh&C0M_o0>c$4P2S}`p9wK141U^)_F#cL$nyBNFx zQFIe{BJYSVFM{fCj`Pze;eURJuROKwFqXpK7RmlkBX7fIMYlVhMNiV$w;?lk(}QnA z9ABch-xeuBFN3_w-&?X++?1&}e?mbY(%HAs!5NhPZzQ~)?!aHnJHW)8ifOT!wdL)a zWJpKa{BMz3a2K#~Q+K<%sof75sqlp=*N%f)*OzSr=>3kAvQG5J)Nt#1(Suy;gjXya zc&<1DCWNanb7y*Cw0usb4uY{B4nAq)I?)qnPAfVaB580p`emKy(-AqRxLtpqpw#sc z%2kZFSLY9|%K!X&(KF05zpkJLg;4V5>~10Ijc81l{u@L{Mm*X8s;)XtV8>5|L&Zvl z@m5w`%4sm$#U!S8SDLT^!)h5lxIsiF7+`o0?5Agw?Xue z`vqja1Z#c^+Plo{LZ)3p7cK$6gN6RBl=lwKaa^XK)pm(@bfa1Ch%{dlJ2Jh7Og;L7 zYF_ZzESIu(vF;$rSlnHm`P4h2cSf7m!H+#QTA+1MYGkffjYIS$ekDxa^--1-`H!Yi z8^!QkvsApN!CY|+$7hRofziQZ!%)3s9>E!~w}VVN)6ZBWU zS<0E-XpbxN2Vsp?$hRq_*#R7lQdm^mMzemVrjkHOXov`FR5wCqU z5=tU@KJ)Q=uuR((Mn{l1Cs|@+>%M>*h`D~9*xWQCTnkC~vF#{hGhF!+&X*doAeCQM`3F+nvC1GWXSQRdAz zVDkVgF=0y#*c`wV6ZWM6yJu7wL_hRMZfV}unjLd#?}uV&$ZXIHrAw`~e}vQqNZQ}e zrCyswddOrm@|E_Hf8)rJW~3#uUCzxM+0Tr;+aq#89(ixUDS9|4<(eg$i4J=tLfPZC zi1b0hh_qo;^N#l#>Mt9f;`jt$(8mxqK<10|?f9iQigs=hgA3d0Z072NyL{N&T+`WR zJg`PftbsL0knS!TxmEN5d69;UEAN1Bli)U;_Zdjj_yYdat)} zDzt5|v*?At>fL&q9Lj~b)xYAe;=pkQE0Q+m}qXDrbwG70=1|jvaK29x21W zMLLI2teG;Ru><|FLxcxcX6gG8f#ppWGoUPJOeaeDNc>Y(hSSF%i2}7en7lv65(jTe zeT=R6-)a2EB4g}>U=wWOGufdEy3J(|?4jQe*p@#G7*M(FV4+!nHGuCq9g42CkLai0 z377+dj$ubRT}iM$oeqDDwd)MB?8J_JDh2ICS-;Z2o!GOVq$&J&j23d-~56@HW6lsO{hK8uNwBAr^7Q*?|)E!{UUXJGZ!{l^TGyqk;72)Ne zk7pcg`CTib-E$j!aZcVP!d2j(&;P(nyF_+tIfy^F3s*tRa`AdX#BT9`x+RI0?-tpr zEtx*uEt1v3WSY5Ogi)7I#6((AFS^o$p9nt<J`s^!b3g%4zzflP1C`4AGHAmm zVoc^!A$lGl*m}7R+@8$)M4aa&^WMM}x-MDgy-vwg-s%}1SlJlqJmq~V;;tJ!90=vP zZa5~{;2HQ`M{tm6l#Wz?(#>=j(Pu4SN)u(9dzO(@t@z(p{ zPsJqf4MTz0+d-2Li6E-oFElFNgL!@xz;thK5$YpzpH9{z=*2xE(FY+6R=x9Z`h1TV z5Zo2zVBpp;3@0i3Rm{j8hg0ll0*`s8(2UQ-s06b$M;OO5+ZMMjpj~bW>?&>SNk={t zcWL!=&{o4g7iA+{_BYb?u~>MrbSv?YZk?H8lS98u*N2#CJlRxLc?A5 z_&$2BJ2k)dX}*1RfztPiaLr{u--kx;6(t%tFoo9b6@{&w;L3!H5)s9E(l(-p^pOJQ zSjAsdC^Lg@s2BR!njxTec^fCZitnR~VS!kwKq3a#WZ=8f{r0V*@MT?P{ib7zegR|X z!0%zY08c274Z36loI8FWCGEpeR1~uP#%P(IA)WO~-0F-~DvPd1#W7_`SXH4zS70m3 za0lSLTZI0+jxXBt1ltif*aWH3eUQ?wZcWC?NTH4m(>4q-q>11%LHdUM3T@vfvb?3e z8^%Vv~Q=su3mm(l&9*|XrV=s4H z)#oDYK=?o8^OZp^6>Ko1^7miv@M4h@HVYH2+)IvxIZhb%y(Q)=k)XqQz@$%thm{TCpn5ZdKt*-OEU4MY^hB_^^Q9 zty;x}%(6owHyxYrCMB>R57eTCphoJjIvK`X3_FON46^~oSU;qFhd}?QboP)4xbIfOL#myQy4T&`4*o{tzGlYz;+q>D->g2UOm@`SQObHV9)7?o(;RgJ0b5H` z4#TwPpKhW`aQa`_!BJi1PP!1^%&~V|hdzYDEdWh2265aRZ#NjtA-Q);Ut<%~+jvu0 zEp!(Bu^D#D*f_1i?UaSs1XZ%)n~ok95#2YUxDwp>XVm3D$LqU?@o#i&U=81QKSTDf z(fi$L?AM}4P%)=M9gFb)H!KOF@E=Ocz815(A3~5P<`VEU4^)nFqAXTF20=1r0~t(* zkBFPQ$Zl0o2ib-BaQApb*vpTja@_h2I9)D#z>$}zDLI}!RtJPEYQg^X=5VkBCcoXo zfeYoHD&^M4`@_t5X(qX({H*a0xuWri&S!#<64R-`Kn zR%qQfA_%L2-QQr{@CTj!2DdmbAR7K=n;q!9bJX=)OkqD$_ix1wL$koo8#?6c&%pNc zz<^La2j3TiaaBe*@`lLC5}s~w&wCw+M@w#ycI4jRHhfnq#r#gI#dnhb=;k^a31h#cjCX1E(o36cy!m~216gu;=kX;l9VuJb?#{JrQm z`YT{#;=Vct9i66R%WC=;=#Aw{H9J!0xHXqss1fdohG0o|zK5f374ih4_7FVnYu~$o z<~N9_;I2&eRkiPU9lZqs>1(!B{s7wBAhIK0hP8O9Mc>pHw-cZ~-2z_WTIHZtzmOd| zgs_t+ZZ1GPGI=%JfEVZ-`2K-L9u;vBw*$oO5r+1VV+bWk6J;!d9^wrQ^-M}VCi?Zbo^yhDHn$msFt7Wo z;B2-+9g|mve>o>QReBnC8@#1V+NILkW4QZav;x!~xl+Hu8iLkHyZ`kOk#T6tuv9sU?Ube;}K@5+pc-4 zEcDWGardp6h`hRadU0kncd8o+R&?u=5oTWd7WHpLrTIQXJA^hNmGNwWa3ku%eR7)a z_(8-c+$cwftSz^qG*^yt7F~x_y!n^C)hKA)55k_O{slSkH6_XUga1*d%HLYnUqYCT z@tC9<{6oR}qj&(m*-#i1hV>Tjpr(llUJI*)0u7 zF3*e74B4+i|`AC#|o*_k0RpcKNlDI zXqETXB1fB#+aY-Ts6eW4A!XYRq!ve9Y7m2UaFE<;Sk%hdvV3#%mds=CDqk!|f*81WIgc_mM&G(~?jUqR&eghgh z8+Zu8AIdpeLff%5)N3 z?Ly-8U$*+q{xtfu=pXa}va$H~+(AA^t4@nFj|NY48)o1HEej3Kvm*Ottfr%zwE)u2 zVEZ>0c$V8<3-epBq?H-rUIkqNPdI0U&2Iq`fVL((xaxW2@MyEkc-iob=-&BtwAl<) z!5lg*XGBoMBqorZ<@PR+V{HPy%>=!E#)Xju^zhFjB&MH7IZmj5E~yf{7kizx7DkEQ^r?#x0z+3;Hp%fyG!S6iw1 z7bwrabb#X0u9Dh)GHeL{&k??+yY~dqi0M1(R7eqYmCSn=>6%fFLRAKf-U8Vn)$7t)XF!jJAHuv~gLaEa^(Otu% zJ>isdPQdA}{fBUxaZcn}4$`V~a0qajuACEbT@Mww+3=eJIed0e`gu{`zvk1hM7{@3MO9jeu2R=4Kd{y7jE#Iu00&fZAZ8xXudL z7B@`hO|wxLSp)#o3K0 z)au_sKY{~ARSk{C2d<5q$Gnh8U#%yP z_YPmWBqDRooNzKO zAvcC~z`!s*(r1io@y(--O}VeZ3fBlS|9wdBru{I|bG}vbKTz85Ug@)}B z9cgtl+%k+BuzbMpaG&&q#Y#Uk3tP$#)Y^fgfEXp{6lUIHYt!W1m?Xm}qg{*b$fsWL zwms!lH>p`5jh|a;m&j_6wrvJpS=xvzpiB;sqY840%fvU**V~t{K}JwbZ+sucj)KFf zoEG7y=#}3^%uQqX6EzA#F=i3&9+BwNs5KXG9?G6*u&mrS)kv;j%~y*@6Ta7{POfb8*Ixz|=iop#7Xu-5LcX2{1bJ(H^nUoCzZa{`%diQaNByrr6}FVdUlB3si&4&V z6L5WfCM1I-xVt3KU7r33FSp%rHoi}xSFVT~4T&YC)x8~z_0|f!P4G?&$#Co^=3(pSaym9UZY;-66F{X%triXr8BQF>#kZ}W*6 zzRj0_F;oc1MF(7X1i-sA+^1X@rJtDT+k9>o(y++GGpQ%$_%@&an=eKe;>RL>zHjq| za`*SGQ9A7A>xVrG_+sDYlaIOKZ%64htCRE;#LfH`aZ3^Rv~RPwM3Nd!kF|*C*tyaA z$>&kfOTKu63yX`=c4MrmG|`)Owuqa$K8?PShRtg`N@q%6u1wb=RKEc$M`=+S-XBa@ zIZI1RHsob}sViD{K%l5K#xbXR$s##xF>{t9V&zV)XSr-RvsHO(yAGwWw=lECd!RAT z&Ah4Zx3wdhE8U6!R+XL3horqqW%3hX4ckXF|K?|C1CI0e&Jj{G(10*FIMb7mIExp| zEUTjFZx$`hy-KMs9TP)qEn3*1yFrN)M6%Ix_>!Nhg|{w$x>%_f{QkSYU8T>)(F9c+sRe^Hc!jXhE>#;*o{cYF^lZVw?H|T8 zf>m^&oMpTa$BtD|Oq0FXfGL2n7hDOOXTbh|-3?zkl&}{J*ag52VnM}+UJ|~=fHwgi z428fhC@OX-N*{9%(_}wwBxpne3(wH+cacQ=gm2zJ$}91hQs1DDgq8y1-LpcAEH~%N z_3&eXZd#qWuqeVqRLVh`8=&(RohOxT`3s9~De1&Zvp^o;k=|1T#|~InG!AL` z7z{O#yyO|L7A`FE87`3p)OF8MF?I^^fSRrY%u%4dicLT4G0+dtR?EwFS}Z zURvaJZIB;AB;~QW3#DGi3aT1kQ>xw5;x*}xWiKq^+hqMg`SN>@2hr9DEsXkh(0t1) z_+X;dnkv!|!6mU$q7C6z#F$q~y20|6BOydx2)tXHbZ(LAI~ZDjg(%sZs}EP zcT2A!sAyT6^s0qGx<%i8s8xJ1K$imz1+e%E#x+PMd{JPa$+#(Q>Bamv*SD~)qI6MF zL!3pQg4cC<<#ZSXwZL?F2}J*rAG|5XTN@Djs7-Iofb7WeW$(PT){kuZ`F_65jRo%S zN293RTN~Q-6=cTbBHg1g-@s#?w-y2SmcMyxHr0|qAyzH1r`fi(ru5kMZkv$=8biiI zdbl7xXr@(5EBB}q3y)7wj9YlfIt@Tw&c`|G&OsoQxP=FA;{?)`v{RG?)cgr;V?&G~ zIR4-;Z@4gCE+Gt)z1a;RFNNa@Z>D>Wl(cw*o#BkZPBA{{^Wq4t3zfL=e(y*hRBk%m z;iDyVbg>FVrhCCo&--ZMg@a?IXykU7y2Dv?WnBx&#+w_*(!Vw-FHUc4QL7~^2;tW( z)tCk9c@}__uN`(4mp6U1%vL5wbH!1Pua*ussQav1K-jZPem{f!l^iZG!vCO^zFLmv z;$!G~U(Gi9Y6ivj#%2G(TfZ2Wp&!HVK}>O2m(&)%3>%NQI1KsVnm)a8QV5v!D_phD z(V83kX-3~4#Va6wT5k`sPRG-HKP`L|-e^9*#?I>UTI<*Zy>YnKd~USXT#3@yh<@2Y zSe2k<&F^z-y6Q*qV=ny~ah2FqRm571#(amLatG^Z( z#f{pkj$@0;L0S9GV=2ZoR?yL6EhyDk%G{TS4uSs@MKRW5_u%`b4*WKgvnc4Jm%`oc zP2c-#6LZ@}L>U{y1l6oQ>?}I+?-u$VIs9<8atXJbn?(@o*j#Qkr;F8`vpQ)>elR9j zaSV-I_;NO_>7->vdt>a5KTN<&X$Pmc2vX-!gZ#}jZ#G`owI zfpzdJU9{qSW6r59U0~czU;VvdkJE@k*lg649C8ruF^q=PW4NmbseK=1b=7+LJ(jDi zSdB4OcqoBpb=8L5XrjD7QLZPq{o*!pUV|O%)hK^3(oAi_i&1Z5Duc0W9q{o@0Iu(3 zgk`7ZCQ|2a|Npo@apT5QORczbOuD=DptZp5`2VDPwHx;xloz1&g0c1;0b2Yp6Iof3 zv6egMEc!bV8sj)wj>qKwc);BhR(1oHUai=BI(m*Y$kN;JPdCs?TL%GGE z7l$DRdELQM9hOaB2Wm0ywODQG#GWLAv{cI}N)OTk{Qr~Fmi0J|4bpNujZMV?n1!XX z3!;xGNbBC&BG+M3yt_*8!W*bSky?kmSF6}?cGY@-_cn*I|7SAZqVB<3{(uvy+?cMU zttg|#QhgK+=PpNbTjO?&kY8{xGTc$eTi|xZTGQyIU@febmQq$DV1C>gtVN|hB5CnF zSPZOrkjsaGHkbbZ!gKJ?%{7O*hG=~q^{rCOn{T5BNhLZaih9qLOw0?NXM@7x-@LD) z=KeHV8lv^@`ZJV|7fNCMhaV3DO!y&MeA+5MLyCXphiNUST25yt{PdFtgR8MgshyeH zQ9pGgq`D`OGC9- z6~lOKs20`QD01j;@~0!A+TD3ifwqRyEJ@c=88&FFK=`-PAkb_`<|VQY5M-r>;BwN! zFfBeD^fpegR?Ddx^q!dHW7GrmZVuDJlR@vvUZVO0OP?N^F^zlD+r!I%fmRq5wPT{% z(!pIQCmfZ|P1MhUL?)AGw_AHkNp3iALz6OWB4ChNwS_$PL!r-pBU}rN^Wcrz(wDm! z12=qO(WbSysRjwB#CN0P;aYaW4%QNP*K00fi71q8UW~I8_sH)my|*_NL};P(lTGud zX%Sk_D355|crXqMrbaK64`}06um~+Y>?#K8BTuE6fv6!uv)LQ6(E1(=-*3!sC&cB` zc+8pXky?o5Y08V#`u21czK@q-|5lX^*!5- zt%l>qj-WR;4D6M7_@p9?g}O^Qok0hqwM@-b*fEnj$7nqfg5h~Vj24ejmu#95qotO& zYnV533~77o!lK2XA^jvuO!wW^)ZTyajB#X`wXr=KU2+ zA=?YJ!I|`$&10+FGn@9>v?=M&Wy*GtyZCmMbhxjvmn@Wy&X}9o;n@tDV#n4VFO%?k zB%o#{{nM@`*lO*SUh+Me3ciDb1(64?+R_S*zPD?UezkUM2bpV3=JK}|2UBFM_HgTj zQQV2v#A->fQ~fMf%Wnneccy?i^hIsq>CV(IPP294khId1YXGGS%>>klfBM?^_%5_L zP8$h71^)3`gwNUxB{0B(D{_<`uib-sl!fVAin8^yR2`4?&raK-^%|%qjFN=zt*u`z-ot!&*7L7!7&>b>*aa*(%@7&Xa-L+m}6A|^S zYSXvk$47wX$zu_1?XL9*8G`7GhN{SAUl7JS99QX+;ndO{jRLdb1g)npz*uY7mfmZl z$qCv>H6(-HO3=c~(~wui)LH0MbzUX0G#i`*Zbvw29|p^1?;Jbuwc@RakX!O&fzBeF zD+IPK=FM`I2)z zYJI!i<)z=w@z5I~O|5d57fnvo25?izIjF*mUQ5)n)#=gneIoV*kAjL_MGvs%1zrrY z^{x0ZsRF-85a+xvPv454YIhcmCwr21uNxKC8`1Q9lGdm7yVgbrlQ3q?MtRasElCjG z!}~yZ$0ut;wLrfVP~h$;`aW5U z?(;LAc?<7UCpEeOuzrA5Ko&Y`!y{qF4&=ie{da5&ZeEBioz&=_e&F-ni@U^d=T5w`* z+wuh0)ykrphp?umoS`Ng|1jSo{DAT^VBs>%jv!>9X-Zdoi$zbm1sNcKIKGZ#Vg+h z!xM8E{xsd4rj3I==hif>pDNPn&opgNYp3mrrQyA_{?Mj9-b=H!f;-03x?WmZl-X8p zUvIHPokg>24DDH0VCtnskIMvIE6^Wuh=a~72#Eia+vV7)(1&I=qDi@0Re zy%F@aZg0%8Y&~dJZ!IXJU57Zk%MrP4IDBg&V_DHCc|)&Vn!yRQvA34mxgD^v2c7G! zz3BaBba>wt1 z#sSlgK3ZtG%n^w95h3ma;T)qv^{A86fOi7CF~%VeAZ7Z~2HeW&`^2`j!ToqA5qMOF zEcL+pH48Lz)9=1iUq*Yn^N&F9cGmGDo zn?0oKdj3r1+pG!J;C0j~nwY)2^;6|7C;j9vZ= zG>F6z*hfDG7|JA(t%atdpJVjcn~X=dx1l8p!M8Hy0^|l|Hv=o1fIW@_yXBR4B*JmW z>})L|+0`b|pgJx!ipfHIJ29>CM6?H2zgST-oVI3bAx3R?^wGnR$`=94IGqY!{S+i!%n){8u&*0mE@0=A=Wah{#kJhYTWv4c$ zKW~ZmS!yTuv7T!xLY~;up9iSe;`vQ~K0EJ;1iWXabf@uR&71R#Q~U}u{wZ`0jKSte#L-Q_rp_}x}R z{OAy28;mJ2EA=UD#cYHbW6`JzHQG=dhogaB#mmN2mL(P0CZyxtd8Bw64kvyH+O*jH zxG5D&MMddA-gU?x_*OKH-jxmIsm&`Zra7%86}snvu58DufsvOMysV8Fb_=?Rr}4l9 z?=Yg?GIn_nw(F8LZ`xo98<}$`85&8;`;Ve_wOE%5wy(eV?iS2}$BD*KJkIA_DD4)> z>-0&eSRBP8njr3JY3NsxF7_WFwnp(=ackFaQG7@M`d*cG)Nw-^vjyoW1Q;S_is(VS zJq6nPlo=>{phzBsrhbXoG>CV^agWaj)pl_!6N;k5wLw_xLx>gB>)hW~v>nVlI1`(= zXA&FZn$TVT3nH7PubYXQwG&<#M~3B6lsSlU6`~x8dg6|WGqG-m#~Z*>C#rTkHYi2` zQJ6SJ24Q#3C$Ac6OJ_K!?lAUVL|-1F*w2JxZsr>1S4Gia9;$drIb+ME?-1T9qE2hE zD}Y4$9P*Mxx(*_xZ@0K(2=D2GK1492b?IH~s~G~-oFh&Q;kV%0=N8fE|F7<5>@KU9 z2bn{}ebE@bJTG2}=93#`V}=6ST^xg%&qhP}aNJ)ywrTBnTE(^Zw}OgQa2^+Phw_`1 z#p0Ern1Y-wjtu2^sOtF`9!;+|#qhyVm9+zco=l2i?=}oqUb!ZABBIanFT^^g9fzd; zp^=$PydT3`d!uT?W@<(J5W_>G>&S&Dl3e*~*t-F8aj1Z3BAO0Ar6Bj#{^TvUMp$W; zMWs{`w+!PgaC+ySVc_?B@%S(v8Ke$$dlp2AIYkv8591F!fO?;*m1amYtt+F&$_o!M zT5ezX(U<`(TwZvVx5V>?Um=Q@^usW`$qvBPQR*H>>AD#I@Tn=*yun{dtcgrePS_C5iQX-^ z*9`QMjjn8E0uHf7L-T1CW-s7t0hc`aHj~vF`A1-Js?LU&|lJqGiP zYmOqma>Wh@EC7+2{bnrP`@0t*vN#zb9$5Sq_wieVqXNwc19JDmf1%~?8!Z09t1iwG zIuBi!(06Z;Q1v**GYIcMJhTxHlP9GKzbB$unKT)dR*pWLhAq$G{c?UJf|T ztC-DqU2fy0bfUkv*cE#W@ELoJ=XB!g5lLz!k;)IbVvB(k7RnZ20uvXZAl2axH=7t& zP0Dz6=||hHYUuBHs*{HV{(c$jg^&P4ff7kq)u8$2sq&-{cQ#a!3KzmwhG!Zo_agkL zaG}6uhMT$bJp8C|Njy_E@jQzxT+*+|2%7;vX5mS-_s@M&j2p?bsH&F=SlvSWIg$^o z{oaB-sdw@S&+mjg`QWaYy6FvS+2|cfPKFyrzZ?9b;kSo6w<)sYNY@G8$%pw$!6@NU zFrw$JyhWH5=MG~+M7`{ao#H8tIa|3yoSm!LZFK*~Qjt1}w+ft%sTK4Pu#Gk_S3xGJ z_$P?BM)Bc3a~wt*QZQFAiicy~BYZUGJ>Y$cdV09)W5{SevK9?D@2we)`n|09mj>au;_r{sB=0E{k5n(0m*cx88-hsdnO#yLd+fXA9x%22Oy9^QJfmoQ^Y5HfS>U zDKuAd9`I$ht+r|d6SDd|+e362!&~Utk+SQ%<3%xg3=avl!2NqkrJ8nAYHa3aqsy{Q zq>kY|8mD?hm_iW-i;^*5B+0`+K`3K+=b${+tZ-1A*NUh(57^yer~wN!U}HUC!$j&> z{#f5U`&-TF{R?2V{RAugh_*8P z<^i~V8sX!-VlE#Qdt!N?b}GbJHKy*tcIt*iLL)Fou}f)n$Xk zGk5bSGzu2!lD6WTyZLbJxgOO)gpJ3Fe;v%Py_h_nZ&EgitK)e~4*(W(+up3*PYo^9dvKrBj14c}1Y*Ju0Xn_j!97EZ z-sJ=L$ko_-avuuoJcs)N+Q6OX`-@@s@xc!i8+T6(fUu%*ya$58y0hWe7k=4R`@N+J zD*K?^9`Iw9-*g&X2jzB#AGOsqTPYhC#DNN3vwye;leR3-uw zFVj!t?McM4G-ZT{sS|l?B~|=qB9G`=+$j|sGafNUr%>8V(x}kr7hg#fJNNWXP5lv@S{$l?VzUY;ru#SkjN_w1i|t?aaLY3FLZo{L#y8;@-&kQL$Mab}qx#m;I1tYt zX!3bKEatLpa#WDhPuwz%-_tY-+)=F$Pq}QeaT;%N%QEDG+*x+U;&G|VNs||$PAag$;}sW(j62K z60<_#;-duKv#Z3Cg~hy!eEA>dmY{}tn%!NrnvTkRo0vGAkM&tUz({OdxOiter*m28wIb!PEjVAQ5AnG_fF&2Xru?c?r7*$>B%DE<|H6Bd<(Bk}^MasN%ImH0s0N z(VB}BiC8lnCe9`D9(Oiwi?-7jBF8a#%Ic={jrr!MaIF4MJPI5LO`3ozjozR?3Q9-I zJJ5J8?-Gg+w(wLAxYotp3ii@xx{BEk@|IDU8{NMiV<{XSC3+Vl*xHY9Rh zOzzw4JqnA&7Qm(%q?vSH(O*Q*8%UHt3qO%Pmj~W!6}hxfqlEv6WwjSgooIKnTh=_0 zbR5J#_vx$X85x~>sb#XL`kIqhKj9FZ5w1AAZ!7BPv=DLgaI|pvT;AR+y2T08jp{q* z7o6|3uyI=$V#$mtX(XPR%R3CQIO-ZEIhuCH6W|=Qgbe56+zoc%cC|+MONk z#4|}eB*tR9IH7-gH_c!4N3tksn{BDFgCtu)x%VP8UE(qxHqE3Ht0Um1s$!P-B?)bA zTcI!D9i3g^i~bw6`gN2ejn}2h)zsLQph!>V5Cz8#a3gqXY*RD#NZ`@>8mWCemV~45 zO&wyX8@t=P-zK5STeSka=QbiBnoH_L)?*^g*z>sDo*Ij@caU~a?(gEn0v?MAIV(p> z+Dqju_fCyH0h~8c5qA}%7xH0ao1;CxeR6onol-JRH36dd+Sj!Z>KQ^K{ z3fy|E^lvYISjb!JdjOySr-UsTB3v)pCqsl=;QJ2|I*e}e^2VvLYrt86hdA~EpTt2T zeU9A!mih^1KgSRIU(D1m0WMVl7p@SSs0e5i6m#K;B=kWG#nohfr}G!!$Rt6<0vm`R z9g55X3=9eF9{<|pAlKw~$(Z_G>-hi6d58kD;Y zICv8Krd^hQiQ)fp7;~=euT}S>Ng+yH3=sbzm}(w^M{sT%5TIKCYa8#p&hi~IB0ig7C`#cJ3D$CEK#3HZlZmE_sqwxddb#}p zqa586Di?VIa~s10Tq28ua-Wg}LUOx`lZ#M^offu-c~~ooG7@Pw+08UnIx_)d&LI!; zmT^#V*?%zCtu}|I#vaZx^m97Gb~9!CO`BR7TQu?#Oc_tZ4!Tbf21;`12jG#?9KLAK zxLfQ38+V+6H|dL1_tTx-@sLa$@|9Bd9>MB#vyS|F%SJ z+0Sr0p1B{lgwqwUW3zE;I&(VOuZ$(UnNMU_s^#;jmfyOB_Y1V5i!xr{iHJ;%?VTmw zO-0XB-g&xMgg=6gYb!DF5$+i7402CI+ynj?jM?s%$eUKEi9>Sp!20c*YtbV(wHt&%dyO*ed(?UFe#P5YT{Fd^zcpj~y zms|GS@>+@^OZlxWZUeVRupbt>3ck$TZ7u;lG^xXa?!)RjQbCn z11z%uS*a;bs5G0_+fwEI$ka=o(Ev}%ZoIEJwTy?i9|zz`=p$W?7lS*3hT*?V1~9IF zqK^5kcsL0I_MsN)NT4FM!|*qFFi@ufwZEA8A5_#m#Y(aw#Wq+8tr0L9&5tvd?P`H+ zF#7{_Os5-@b9?Vhm3I^U10LC13UcqLRCyWdKj1~ZMVH6;P0AG!{}>N73k7;zeZ-TG z@kr4s6=%7M!?RQ)7mFjssmJ)xJ03uBbAadOR4aUmdp8x<54u;!)^=|>g+FaVs=TVZ z9xTq7DOa&QagErS%6q7#p)xaDzY>bfv$F-MX69|hcbsf|19G>B6HZJ`JtraUGh=0jmHA2;OvBd2K;YG5rUEZ5xp;W+;(rT>oZjl`Q~+AHw|@Z(|9mRIe4%m{dNr)yK#?5)u`kdU4kHh}Tm20Dc=t&>bH_S9(*FZK;U*b=`6H>ZiC`=k38utO zY$bZ9@iw$yxsI00S4>Ugod$eJj68`-%Z0}$;YLejbk6LUpfvppKE!32aFaxEC{wmp zDPm6=PA^TtC#m)xGb0}$a%M(OmKk~XD0orURX^$HW?{yb6543`Frk`R6#-Ub@J%gv zDY7+;4L_GabNgzxwa2%P^|XFs_TxOUPagC)Mrp-x>Rb>YG z=Y{~60rz%O{%vLCI00scgZ%RntOE5P$ReSa+}mw)a-@IVDF zXT{{|J80$P^b`E15Gz2HWF~fVQfllb@bahV^&}sndbbh_pX38O-UIxdxS|7_D=R0> zcVM*QpGzC|ES5ipKdsgrev;2pnZFp4&c`WPcruGe`=$7~2Y?0Fql>G<(FT->lj(e_ z^0OGal1DZ{^uM-c+oU`YZt+Tf8}*mux4oH^zq&G2zKuc$kFEG5e1`##SY@=qcFd_) zJjAxu!x`0F(pa968vDx{l0!gl9v>EimR)5m*CgoOP%9-5$}c&p5ozyHvT(Ma)rx< zW1p5>h2*XP9_13dKtl}5rAgIyh)suZLEg@%P=S3Rjy%PO@v)R~p&8hGD*3-HgEt=* zP|LV6OBM%GxCCT}F?tBj^{odF&Yb`_l@P#bK#J$T1H_9NymvoK@KXXMdoeGk#`cr! z1?7&B>;>nJhV7BgOblIxwwj0QHv@p?Gk2oswwi~j&0C1OR`a0XHimb7*^CMhOIPz2 zy`un>PtnJtQh*kC5XMOq^BD9isj=6dHFD0Yh4^$eZ%bXzduc`yUC%#PW47pf(fVoZ z{*y`_^)&B^wZFOW2q9tBo+grKBH6(aB*5&ac|fx-LS(k(B4)S3(qemvPoBn(8VEs_ z;*de&ucxs#Wb|`!TWl-Q;~Czoxt%0{AgBfo(Q?@P-eP1Xc2pk;5%ZqrEj#^Nq_h}H z5qr-2wH3cTgX6iCYds~2h=FzE}*pSL@=5! zz|r}G$|CW)n|JLVcZ*T9QlgBJln)*>cVk-~sx4O4 z$6d1%r(H226$j~JhoA6%mbVUGNHP1cov8Qo!a+c`F}Nq@mS=f7CUW*Yi`jq7=RC{X zhUYn27Y-_0u_DT!<;4Ek5m#}r!b2g^*|Kxhi7rCxyM}kgghl)s9ul!*i2Hmn4N{{o zi>AiWJ4^`YE&XnQ`!G_N+;5P0aSdFMe{_bE3>qUbD6K}=SdcK2tJSY?$qgUOP&yhrVhK?#!zX$~JF@L0grOezp9a-T*V&_mgY z42KwTuJ`hrGUHq1J_(ouFj2M{YpH%)HJi|%N6EY?Sl(dO#1H49lw8zXq?yHH?DIUN z)oloqPDfHu)dr%O-#Jb4g;I_^SkLoFTs*yhka*K@MGqF=8Lsu1>J~h*b!I~35ZSs@ z8q0B;;!EI@#)K%D#bOjtczF;q9Iv*AtjWWM-5|vGCn>bCumSZ_4LKxf;!VK^jq?Hm zX+KT682YEW(bnMT7q0n6;--1KVrL-|x{?7&F{Yg?A|=MnMKL%o!_D!v6(SCrGvlYoo0PP;hl=_g)Win%Y@j!&9 zEd3fOL1NkqJV=Qbz1Hy-&bpket7BSMYY-n*%Cd@cVXqM4fV_>Bt`SHeRekWEzw4TK z2aF{z$CGgIBc95kyC3J%;1YE~QlNVh!cqf8dHcXMW6Ln*tDGkl1EzCd(Rv;Crw5+a z@eV?pt2KMRoywcuig1)QvZWbe6HC`wC(sD}mL>pS`VhEbp>- zD#mfG%!|CuT`Asj;!&z>OB`o-#yFxN<2Y-K(+H-vf~EmRJRJqy>+#fQJy!EA4a~&p zoAo?sjP*UjOIEw(A+Fd_CanU{!f4~)(kH8e7(8z@6u4B(X$!0@O8eHM7F{9Et>?jE z>p+0Y5Ha+RA^;(E+`t!3wixK?BlW2qw|`QDQE|9-akH-M)z~GD8iB>0r;UgOwk|Y0 z%&7CUShRJ;BIJPDIus61#iI+Qg6j3gBZK`Jj-zNo{)>t^eL`H0RkFYmAv8e|8gx zH*y!x3or8#_hn2>1jJ!Odmn8EvNYW)ao_?01Cv4)Kye;n5 zY{Djr;=Uq(6Cdj2H;gT~Hns)mi03?-Qccyd3o^6xzZ^%kq<&WWxKFIUCT0MSddChA zoXvQxUE)k{@Y!OS2X_zaVbPduF08uA_7-v;qJfC0gLk>phlSl9KP;-9t3DI zj22D3ux39JVI@*N zGEegG*@45zTX^`LS0PZW0FV0!_e+e%9p6->sVFDIpYGB)iC46?`WyFghhg(_Jie{s zZHY%F`*;&Ee+y=3>P7nU7Cxdc6ty{R8o&xqv)WD3GVE>~l!Sl6en09?<#pPG`}<&z zj8{b1D?FrKUU)Q<1-N@-EGqyKp3P+C(b@WDikSQgZ|_`*&R*m;4%VSJ2-LE%@%EU}2 zR5Os=kiPNw;}RvA#>|B2%|w@1QBG!v_*c1q@3GBg(^P4HefX{!m_j8@puLc2t}5-X z7=F>7ew)Oruk!oUs^;R_tGs20lIC(BFGCcptACx_&%?c=xfrsQhvJ-YR39;QD<4WP zc5dbVfz!e0MbrmQHRy~Bj8doMGx7OWo{W1j2?N`W#^u1u7OC6#ogyy>)6nTg*l>@q zs7Gbk$HZ?re72HcVAMc%7bNw-GiBKBNg|m@gr+J(#mQ}mzXTW*|3<{0ZDQPvcQE;U zOgK~gK|4$g;?RnvS#z;Dm(L2k2n|QwvCC*U{c~xubEOD>jr*%-n~5*B@(0D7T<+WH zz`x+l_!qjLh=Z^3+3j;1px*>kT=fMZ*`<)|q1ktB67k!4k~+g*9Nv!l#pN$9ZRdm4 zwf^Gf*ZCwBW6(9P^H}fG{_dIR;;iZUUZ}9Y0ol1l>o*{vhsDY__+uW|7Mo)vk`OwD zScHF*hXghUBY$G41RFXIQR_Dp>AO{oev{AeX%gV>i}~`k7#n@`CXW_vm+lXLhQFmwBj|IDZN-}YnFni$;<}=&=*2;D0 z;#_e%pzLdXZ@Su3YMwQ_Mq@-eTyx zJj8EFOWDb^_Kil0neSps*gBMC$4gz@t_C(0cg3k~L=i%SS0TDGEDch>H68A3+yqW* zSba^dE(;}}2m7}`0+E2ebRUW2#??}E$;Zw*a5Xg_W3e!?Iv+*6rT8tMxALbnMPIwt zk9tTF9husyfV*j6T)<cH5-BhpC{D{0;B%r&MLI==1@0iVhU_e;`+v9{GST?44QLHNuIP zUQI9##aNSOXBd{$e@Bi|F5QGS#84%?o+Mg-h~QzazAjTv#CO>7mjktvFYVoNR@nI}q+4#kh}nKnv&?)$fEA zVPa7yC#bP_>?7X0*JVV*%r2>vRgQ6Ti|}#hlcY*|c>tW#;h#Ii(ET`VSoINa*M65T zTWd93DDvl6+QxMmpcjWlt*cA-kP*z=^pNb>54Yvd)Q5qedY z4Eu@jeVAYAB1Z4S`dpYq5Lx@UFZ#oTEDFiph_J%MS#mQ%Z6yLeK}J{kV1P;kPCUQj zuh7lfnCIdB+_#9KpYS$bm8^ejcW;sS3Gd%JJOI<hOBpd*^W(gihvs@3)T@niYPkI#o^nH4Mxww zFRl^0X*^v@4S!Y`=KczC6yh0ToOfF5!o97;gA7v<<|chA!{(XG8XK5fMQzQmVeSjC zcb*S(UxaRArzxX_-rI znFd|KS_D!W&!g;M{5ObD81E9p`VsLUJd2z@$4^p-s_;XoFB1VBlZ0 z{fvhXf3OjTUEt4tkHftUyhefn`90VCMuhSkR~t%rGxK|c`5mZSUQ^a4bd=<-m%5Ae z$jSwj+IrtQP6iCo*@6Vr^mOD8&7}peWUZCUX4pzm`5B)w{8ea65Za?_xB|+eh-r#l z8&&)4wt;MXB-phc_W29A#DTr_(90uG@|ZG&xTqAFMLZ-j-qfT5!srvT>t@)Opiwgz z>-P)h+U`Izxr?xii+G?j$KmdRlM{r9HvHx??7WbqZA0anx>Tvi{_Y6i(B8isTEzzr zjfyN-D}rHQQUq2km{g%chdTf;@=HZkN_U9*;X5*TsJz{s{JkY&i9^i(ocH28iLLC< zd0+t8x`g3g6;R5MVXOlCR>kL^^H%p0PEPZo|BMYme)J5|GhCkGyAl2|PyF#1hKZqH zaEHCb;oc8On3(wmzgcbOBQ}4*Z*77r*ax_C;ZN1?qvFCByiYetyve^av(}TiJ>31S zxaUj$WwS73Pdct!MTYjJjzt^MYd;U@_;@%CcPd9>cqH!wP;egrCg#ut6vrfmyRlR8 zsjsrpjf}o0K)Ci}{!(p}zj;3&sp4qyZ(pM-|6b?^(D+TxA9Mf%ejLJhyqG)rV|MgR zT;1@pLAeM&h+h0DannIQzr{}7s~Oq@Q1DH~jIc9;in@UlmAI?UT(>No=zZXCviO2s>a+KLs2an7}; zIB^)Ak8a|^VZJn?5f~(?TwNN2otZqqO9^RSEG8c1cXs*!UM+x)fv?P~8Th9D?hp+VI{s^0DuY;a%ELd!S4YvgyCn2) z(AcgMy}rQ!Z;#mY4ZpAPhh9<{Q5*tu_X%4m@7VaQTCbqod@-PuFKzschu3pr4`D5@ z^$Ny4n-@y?)W#3hdim!j;o&%bd*fISuL)x3F@A5mVtcsm_CFSfm%MOcO78&o5WJ$g z0u{A#%ux;1%M9-sAbNa@Lvb_lwi~~>T`*__K;@vWGOYbray4lHRlR-^#&)fV_U@kl z?YF!MSL40bwAtEH_?Gd$Encx)(N1sG{1Yd821D8F+0+Y4o?|&hcEj9 zcWFm;a&HkEe!wK|mu2Wk)2m$Qpe2Z*Wl+mzwL#`nknUc24EWQ;D`nV5l`1Zm@pevB zQlxRA*a{zweA$a}jMbm{;OO6YD%?04 z#>-E&xYBQUfA^@;hMv*=+=o52k*3A5%`zbndjS)N zE7-xSOEG6ZjJZ+i72D&7(sLP?McygSZ>tweStA)*?S>6t2;J^_v5Yq+r(-%}p#pd< zkBa9{@ixwSwC3oN*5*hYAq7sO>(RpPf|Rmp!(Fixfu~##FQ>W0TYkGMb`0^tY(=0M=tFFTh}Gge!J1i2QUtJZ3Pp84nxv1>W)N;hpX%>6PQbjL!dY zUK59|hgjHNBE}?R-#7>sT@P=3YXff*){BAnp$DEqdIEjWU?-%sF(Ssh#lFDXL3mE< zG_)t8tA#;u0#5S+F&BuQ(~$naO>Scm4V1Wa5PtbRuGovqaB!X?8z1DR+JXGldtI@W z@Xz`e#s*7dKXbirsVnv;AU^#sh!Ss9R~ebQ+!cEqcxgw(??3Y3rbwU*aUF)&QUn#n zZ>oV#tCU!&AJIdG-HQWhp8%2S*2(BVInXCXi(`~13)i=&v4iggSL}Pho#w$0>D_p( zuFCU<>Ufrx8Pr9HSKUr3F80>u#!*k{M)r}6Y<>eTzJmCrAL|n+*V^P(!S8Rpwh@!( zid_es-~R>YjD=I`igg3Wg^9cFb&NfTT@N04Zgg)G zdl+#(R(D6>5w{c!U#;3O8vd*yUWkwQsDif%INityH=>VJ)R=Xy*p}iPC_8JK5~Mg` zZJ1P13u9MPyCR6H$q0(g$5*b?j^rg&16>_Jwdjk^}qAWTt; zX20UX_j+(M5fQLafU|*7?9$GsJ4<)Oc+jPihIuRsHiJ44Bp*nCm}SX-`fE@lo5~p*oxR0xYm+d zT(F7@9NU|fT0m}0N4n4%dv~1jW~Ih`?oHcV{$jAdA-z314?tz>^HR8nc-1A-7iy~ z=NLP%%fY$Lf`2x*R&+Mbf>4xjOEa!KY;6iE@c4M zsEWiJzj3`~9u35(k}X5-Afn>%5y7%!iifj*lgA%xe#49mhPznqE$+0d1y%$7&PDc0 zUw7eUV_jSZ!t?Nmu{fctaRPs2D9^ccQx*1I3kDYIBkPI}h%iNAn~j zapBpW_*3)&ps*HOM+V~?-6hFd4BW#^cz<#5ciw7fUwqop$H!B{G?bKN`oNF;J;`*$ zw?(E4++9t0xajr=51!rzpB9+|9$nFsByFq!o}!$w8(kl@i7WOIq=$+OX7Nl38Xda| z;Mo_nkegdD4S>s#L)$*adP1gt564_)YFPe|bG%q{X8N7S&F^a1QGhc2E_%4H zc)0)eaH~V>@Vz|TJ|1q&$JElqL{Y6f$iv-|+)gv%HXeWo4|fL-cV`cGcMmrvsA?nV z?cv|g!#&W$J=nwTjPdxm&BHy?!+n>BJJ!Q}uZMe*hx-8!_bd1WFxS#iMuk&!fG}Kuqy3HPdS3TUh9_}|h+;4lh-}P|6 z=i&a)!@bwT{i)@4Lg~J+KH&b^!+prZebmGKt%v)24|lnT`zH_guO9B-J>2KvcGhaX z2jGf_`)?1oDhrNLQg9PQt?W?jG*m z9`1e~?tvce!5;1y5BF`-?KDy|(gSdphdb88eXoaml85^N5BD?=_k$kpSsw0r9`1$t zPh94ID~gX$ZnF7zbT}fXCq5XzXimyNN4xQ(#}2B6D8++{D58 z>;K~3ilaM$n1RN6q|8lX?UU=!+b4_7HTA)K6BnoaYD0=%b%&* z0+jsan(dq-me_22yyqvS%$z?jS^US#Hmo_}Ia203BHAZM5DSR;xR-58GoS@;y@EyxM=KS^Y5OVnBo!aUqiH??&#Jn>7nWIDe)rA%N87g z&$^h}Cp&r%?$C?f7C&=N;&e(4NQy3R+9G`%k%>!YrXapf;;p8(S^34jwsJMUm7nbn zwM}y3oCmul&wOZJ;&hg>a8Ys!HcBThNlb9C_Wk-K=XdkBg)7dv^XJV>nZJ-F&0m

zXhB( ze|loFW9B?bp}Wig4+`-lN|pdg&V)1)yCp50Ie+2Ilt`ItUBfS0jQhaL|H0a)wZib7F<rOX(e{1&cKZTGa55q(uCQfn=%zUkJywzrk-xal$21WMmv~t*1^29A{eu` zWA^RsK)D0+j_b(OvR;ha`!IF*0LJGGWKJzoGI)H#`u#=X_wCIOIBfOIfL=-&mbjh7~l6CWBUcO)d=S0TF<;QH!!I#l7oz`KLlwXVryDFGk@+)Ioeq(&?Io4?WMW*Kc z#k?|WkbtX<)%?x)vTG1MHvKHo6yDdS=;>aHS4Ja+g*H~a&o)u`^rni}K0ie%X{I>! znoz~NFicU?x+vapT@@D4P4TJ1LC@ncicirf#k=@EMO{BrVI{K_C2Ef1)ip_B*$aTb zM6vIGL{T$cijtA4XgR5hcgk`_OIxnk+pSQPEi15)wNg8MR(v%Qh-rHQ5R)ds$KPwkT}+tBNvZtHLv|R9d`EQHQ^+ zu&A8~oUiZ^*pry|o}#wFNLASsP4x+}t4d81)jOo6>QmN6RVK7kSxtM4L_4Z% zOQh;u*j42{d#j40kII(~P`#>eQI(`9m0^#Y=JXw`@+~-`mOT{6F)FVbrfONkRX+Y! zRT*)cs_q-1+9K~zwXt`o%Gr^sZN#0bmwl9~r;S#X;diO_tTCz@aIeaG-lyurr>N?v z1eKkgt}6W#RV^w}Wzi3+O4@^}H(i6cWQMAg!5%SF^-iCK@UvB?-EWSnESama-Sbqh zDM>0TNm9K=EmZl4#j1DFqbleBQI#o=sXWQ0dKD~33etf8gsQooP<r{2wOGst5>W!OdSk7iuS^u)i#%@uS^jB21beqbjzvfhx zvD;PVdPCI;-cW76Z>p^S+p4zg9aRa~fvR+us!ZRdY8kM5VpBwBp{f-Ys;qRcs@3ep zg6hX=qY(#HrSPE2vk$3iXo<=SOH{A3$5bD7Le-|9P*vY@mBpP>y^>C=TKZ{Kjr>Vf z@_s^`KdZJ<=g+DVQh`)gsEx*+gV@ijO4fOBSEXvzRY1O|Y9lVHjh0!xqH0yE zs8-dGE2`H2imJ}|3q=1?Rr^)d*8gwd{H>~0Ow;U&W^1Qt%6LW7DpU;@{b|ZFo5qs7 zwI=($H6_5V*@oM-M$X}lHFZf-&33%0rj7{ISX!{AWd>`us$h*pg=)TMLp2uAMpImE zG@cZuu?gXt?~DkIjcuo?NgXw>!p<5?@1ps(>k7PXnpXklMjbsh-@Kk0%j%_R*}XJ1 zw6DhEZqn4kL7J9_ndtsQG;R10Ot<$>N{IwHM2D}YOZEGJy&C==V=Y;jL%DtiVg%GA92KC5y28cj)Bqp=xl!RT6z6+REYEKMz0 zud(eLG%aHzq_tU7X1uJiIa@XLbgt%A{hDUmy{A*){-fr-yF&A-`bD$1JEM7R{|$+*)byM`HRjxM zQS%;qNmEmBS8Lhdi0qoC7U-OZH0CU>3C9&!TsTGO8C>yY}PS_G7CMBh?YDDf%Lr}@y@T_CENnFWVz_o$} zTv@h|v%F-k*Pw5{eX*0PkxMye%eYd!jH?-salX&VS@d$GWCds2)3~zsajuuG;%eG6 z+?MkU*F&EL{&QR{eSv$odyzA~o_j}b;4I}ONaH2Wva`98z6p_R=4$b)oTcS(1-sa_ zq-{tX?5u5EsfN2o{)zKup!s}HfLFHbMNEtaOLa{z~AL;R6ZCh z;B5UaZri%zPmYd?dCk`1MW5IL#~w;^2SknAoe|6E&7<-&VCG$f5L4u zK7k+X%uf*4r(7%g6x&!o-uB83SZFBzM%IQD2 zEv*vbs^qqcbCAk;uEhPxZ9D!1>`$)st>VgzD$dGa`(5DZvNE23@?)=8+vR&j>tEQM z>D{pfm-(^PrtNNEuQk6dyID&Ef7=PN9rznR!{1?jvUkD^yvxlD`zO=3zRw%qPUic! zfneE}t{UGBZ3})qTQ%ui&$hzVr|a}%mdEu1TK*P+IFrE{rajxVr*_8`E0E+O(_UfP zFPQe39tPa2r(uVa?L>g+L59a|raj8EV@-R4X+L1v(@lGpX(yTXBGZ1tY43rJ-n}0?V0xT1?F*)TOR5oYxM`0z?Ym9el0@he23|YUzUc)c3p<Kk62{#!_QhpfZ_9#D#2W!UMaU2NJR*!M;7bZI-_ zHhvZdt4t2In)ds6RQXK0-mR6}X0Z62X@6$gKiF)d&q}?U^Q;#kM58>{|1CB@FI)$H zw+a9II`CUfxVN`Kzdm)wQVb7NS>87B+6KL~768YY4f>!?-^n0;?4)Uj*o`!FH|<1DU;O+Vvx^3p2wb%=aelssAEOnn#!}zJ|Q}nD+JJ$(CW_ zNPwdM2Hj6h>LNyN(A%hsyNFq2FY6*!!PYE&!7x^QK^~Ug{0}fK+C6#*pN*j1w}cg+mCw>-u$6NH(lLf-OQFse(hIjref#x7$MX<_bFb|U+6amd=Q3MwJ6BAyI zNfm+<<2Qm+iK&A-8EZ&@BCz9cMR3lHpzjCpL<9t*`rCpB-)TtDf>U@;_^^M0Q&l3v zBYxHpfjGPo0|dWO1O%^*;9uyI%3Jg)e%3IBgm9w>2!5joNCJNNTN0XON+8;lAi)|N za2Y?_Wg^V@5WZ#}n+W7l3%3Xm_nr(?HxMzwJQL7mRQ)U>9WmfW{Qt-T0(xq3j7cC0 zGi=151-DXY!Bg@LI5BXe@D}`<89!@CfKqrP0v7yw3{Vq5;ptDmD3F5yYf+v90~UPzJ_D{( z{*$7RDCn1O5*UA!zKmi*aEpKi&ol`T12+n9!LJv-5#q<{OdSK2CIfz@@B{-yoZuD# z3m#%BkrkGdjea3x3<;$jqpzN|w5x>9*v>I%eW~l;| z>VK3Z3&BcZ!;(aBfBY?YKQjTjNt3BgH>76TUCs%t2$C;YG(-hxw$Of)Dw#m{W9MivyBDIm@*1cFC5fKy5F zgkvWleEgWz@pa*gde4>w_L%TEEas5}Trdd^25^K6KMSGeOZpm1hWuS~j|+DCo-?So zH|>03eD^cIcRpu)k2AmDHz&mIF~297_AJw0VA?B8`w7!FCfaZc-TZ#Vu$?T|^mxy- zKWy-Q(EPRtmYLtboA!Cr_BwAc`l-pFMbF3dw?=+J^}aE2*0!F9AM4fNd$9REQrbN& z>DAhn1Vc6(4E$FTyB+hTl%MyJO%rF6JU#H8WPU$t+G(b3N#I%Y`xVoEtpU8S!T0_K z-=0|n4Fvt>lO|5nxbKdT8F7BfF))r3AW3+pPf_U3mt(;jNtu{JNG{3n_o^G$oDX}eAP zRcZf!p%YGzx)@pU|FY_pI$@Rn{~xMesT0os?W(taG5#-g!pZ(cDI{nAw>pv1oH|f` z4A;}ZcHnRPT(45E&5up@GT?R`EJge4FrYBAO$0;D{9I!s#Ni?|`e|<%y5euzL8jf_ zw7Z-3&89urwC^_UNv1vDv>ztB12|f3dOTy=Z%pD(K=L;+Ry*bS6%^k@6ip&COx}=%)mALeUetWkn7lp_^k3oQX+rs&C?@n2W z4Ww+@`1z)5Id)R*mq-~eiP>N3x3*0GR6~%`EQ;jpi)7ZUC$r)O@de;oW?7_YzF+U= z$X@Rc@8eb2Ey%Wi-VtVwG`C1I`*SgMzdowD>m>1cc573Z`_^D2q~g;1MnU56em!zP z)*D1(?Hm5e)I{vK+=bQmoHD{Mm1ad*b7d-aVNRv}rR)%(nbNzF9{O7CXh zQAl4k)k6PTAEFkY5+lFX+qK-6NhvRQg3ROJ6Gk>RZE;rogGm2czoTWEgcn{Tzns6x zOvA}^uz69O`C1>OZ+BD3%%@e+>wvzlWyxX6jnboJR!Xy|gxpmJ#g7N{F6#ELMDt?3 zn{QhYVwdZscbzy z)A!5JUy-?em&iP*w+_h0%`wowA~H`K`uBy{b5L)mR(vXcKB%v-XP%?H$lN0q9@2-j zO4~#Fumj7joMr5jkRmeko@gTWAJXqvv-XHChxO5cd4HqavhBZ-5@n}0fmyiRU#vc? zk7{52J9$=}&|&6$t3wl#rzS6&mb7qwLSk|<+t3_&{k{16us+0IQ$eU(D#WcN5W;EP z>H{HsNh+7|p>USyt<}OR@luI?t9{GQ6i3N%ai&CX(XBKO^9Aat`3doJ*y{m_(_`l^ zPG)-pP$bq6+WNCZHlvE%>A#6yNA%A2%nL-e@DGu2L?2<#kZQGkyLjgah-aQB{IiwM zAJxNp@4iAQEBl(zOD>V%_FW;f_%$kD1zBX4y+UT%J7jKuMT|SDKXFT00ew|r;}Faj z$t>AUW?3GY6s%c&o`Btx{AZwr1#Pm|VW0Sn+=yS&@0##lU zFO=$?nwF$Xs+HuIxl$7cOA%GxpYrpZ2soy9Yg8zyY+0o#Q-!-iZ{>R}6q&k;!d3k) zl8@;fw4yXktUso=wU?|U@5*ZN*)a&UqK4=cUJ;j%>3w~7T!B8a_uF7oNTnF?t^TmS z{TeCHmQ;UH@U1?(Nk+N+Ors*5Q7C$Sr?+mu{}+<|{xgl0sf%Z(%$WLM{G2({;uB`G zjBsSh83LA^5y{`_;lodVh$#hi-osN_VR%Zy)TDT9Gd~2Zl0qW51twGH&rLJ{zlNvG zontsFfm4I9$g7V;>34dlecwm2R{2QOfQ5kFGW?D`4P{EVU#nt0_=YZmON!xaRM&{bD$*kHhZaJa1x^?~A5|U4* z>rFDVUM92h12W4#C-eAGGSj|nqD;m1d{)pN)y*ODDm_MK&6ncE6MCPH$M@1#&iiDp zl>v*f;TxItxf$@K4xo5ITsWb(3(i|lpvrdudN_X0qD1x$fTcS`&+qk{>{&SktawSx z{a$~}Uich+ZTUj{`MuuVQF;oK8tP1TBr>J8z4;*$Vb2p*(Pc682fdqG@SRBdL63-b zy-rdoKI98?e+ij|#h9X0=geWpJJA6LR^AC=za~iOeqS@2=OoT!7vW#=g*fzs-XXf? zbAlH=OQvfLnPr(|9>+aHP+aN1MY_*sf(8Zuwlm}{kqXxMivDH#-O*Wl3A^MoGAnUM z8q)Ns$;**0l9%tgKw6&=ByFE3FMq&4>toytqE8rmd?l2T?db}BSILTDH{tJ=?)8_* zU9ghOv(hY0m(-+ti*#2$X>#~tH?WcBE0Ry@1Mka_tX4h)*!%~lraY3A$j$(sc9DW- z{Xyp1N;1=bH(7qVyJUH7cdBR!QgGIj|pYqGzvoUpQ2k-1%(c~>w4 zr{ZW0+t@>%Hes*yfPk+OcG)E|GcPnU#JLB6Vi{=nd3eRAuoC!Gt@0JGmFsuiw`Da^ zbv@<5etu7QoFngypQQOSnU$wa_P^~Z*)IduTKGY4PkFLm1^VvpTY;yZdl zcTPyAz6A%eI!Ks5cW&amlw@`eK-c#KtT--8Pw5>;R?BQD+YX}WFr?s^#|OQkFdtA< zc?EU8hvA#{5&4$xs`LE?zFCFjd-gqX$7ww}uv%tt##5B#S<=kTXe?ejtv{--m!O)J zjYas6dPr=}O2R3srqJ78BGYw^%wnmyE}09(xEu{_ZVhpqCv#_?gk~Z~kjzV_)Ze)Y zEI;Ebp88Rb>05wz9Z`R8AhSlArRz;$ihfd<8?c3Q`}2}=mc-2x%1?S_%M96WSIQn- zI<7E7%uit(BrADMH2PT&Z?gLoRoiPXP$#G2J2CKQz4eI7b%e2RjSc4Rx5!=e47m$F zAoJ{L^2zy%%)&1@>ZRE;lcpv;gz9Ng65BNZe7s4pyscv6&w8Za@xSOR;}nHWJ84sd zC{fQvZ)XP8X8TQPNiIaWBVs(Z7sJ-$aeO2rhO@GnbHOasYG|s5jnu{-M^h^6?{vLsc`a*=AA@lSRGE2T8b4#fh`MW;y_EOnN&MG2VRLNNPOLxWB z)PZ+NcZLD|jOv}lhZET&ui zyW(y3j4g#-aVHdUtHghe%rx9>h8U{7VHSOf>so)-TeN-aPG~os)MNQTcfCX?g-6NE zTtnu*wRTZZsjsqUZ;;`Rh>_>?e%&%Mu&k=iXRnWzN5Q7n9ew+7Gzh#;eD8mTLR4jX zi`UOl|MO}3%=}qgJ*N*=t51tT=k-v%<{bI1f7V+}JFj=Lmu#hOc-8k}&3Qedb4D2f ztBc4l>l-rjT;x;oI=M^tk(u!v2CAya%xM(l;~tyL#8@c9d*a%8y@h?t2Er(OSvdaG zpTG0?v-Fi-Nph}v#;bv}u8ae%AFw{6LT_A5ocL@$X&CS%&IrU?hE=#tt!(?jJT+Gx2NwQlt-Sv(9Gzs(+>iDni@zt{y zA%yjZdnu$sH*pV9YB6ios>RgURJ3Zcn69aD50lx3AxsTJF$r@UCSe$6jdnAnhTr@B zdB0x1>)d`l9*#ZV@8`L$>+|P){(r9PynRu@fwd3lk9}{kTt=9)D8u*YG@0`C8fx(p zMGv@DqNOwz_YEKBdwkk7Uy~SxPw1Ih{ge9H`MA!z`iJ%CJpVb3blk6>t%ds8ey4uc z7kfv#-rp@=yi6V;l==FY>#;xTn!{RTh#vXTy`;Z{x&pav8|4;P_w4W1?vJWHx>@>1 zm!el_5hc&--^I`BXX~@>`mQK=-g^DJSw7|9civ5M;9H-%C{s_{-$|8b ztd4OBzelYe)KcJ`Ilrr)TR-;d{*V5hSFWG+75druire*j)KUHSzU*acW2DGyvlcD% zJ#(GxtX{ZI8t|Sw^pB|PBFk%ZXW3Bfa{q`rJTm_SZ9?AruH=uXeh1~r6`$w-hzcIp z^_~{9=@GB3kI3A<(f2@_tgz2(xbsQ(+aFO0!)wYk-RON5lT9&EX|g%^LB6@wv+^EsDSyg2y6nzw`ZMb6fra;bCESa}`O^)uAlGTA#!Ix8xDWq~ z3g%YdtBdou8>acn(j_OST{3YQ8S`fPo==~hdc%TgnZ9k3XxgGvR#vD5)ZL|@`FBal zbM?jR3}2fV&8s!qv_?P6*Ypj`^xZLA7Sk`v^>^xL@tu9cr!Ba4?)9^L>t<*AN@n}Q zPdoWkU%~7%hWj28x5g`>Zk3cf)BA0`BEh}hS9koZ1+*6Qz4uZ7Wl>G}9^KK`^$7DP zOzHfO;*Ra|y@go|X37idKV-GF>Sxn^Zh4r0MDK=Ab(xg6>1W3t_g0ucKCb)@HEP#+wzsv|>wR3;Mm94f?t1S$E4p{<|VOy?u1PbFmTr zG2vTxxPL|X6Jxtx(2c{6clEPylYUmc?p%cbve@z;bP7tmUvX)bw!gJ}T@Qc%$dYn} z<)tpZhyR+`!pHRoUa&=DRZaR?{*e>!l37X9wx5B6Uax#I_=tu1cx!Tz&{mc8V8TMosEN9MH)uAQ^c_sdPv z<`=xwkNVlU>M-}^!TuAXik!Bo_4dPD>>>WR-d)AsHs~pJ@;`Lv9O6H5Q0-$HE5BPm z+pF}mz$>HWYqdH))z6xCckdzo#K=;a5UJ^T_vRt~$)mbtQswZ;w|enBTn+hXu~fE4 zolPB@n>RP(X5aUVZ<5#BXZe1TWYx2pEPL8biS(Zm*}h4s{aJTsq(3>j%A<~t<%>Ps zp;LOqy6+?X9g%gfXq#G}cV9>OCr9q^F3uFc@6Pi36Gj(#SHY^i&0BM;w{d@Ekl1-I z;VNxSF0RtPBo8E3cd4=WYyE8a#+CW~!N^jnPS)$U-MfB&e(!=eb z(|=-Q{tvp%ZQthB_w=7Jw((cJ>L9aymT&3OFgcx*vpQL%(`MW(-9z}+=mqbNFZJtN zf6%?m!i;%YzNeOkEm|lW*ylA{w%hfM_76U+&}(j0i@J?psq6mnid?y#5$!+s@cPd+ zT(eg{%fHpnP5FLT8|}~T-SLQGRfT@Gm%DR%`2#0*exYX{t$*qPL)XuGHC}hL@}rkm z{(a@QhuI%b+%DCZf9}@y@?R02_mgYyR=S+{ ztUxEaRHL2u>t|hw8+WK|MO(HjRllsCT`#)Thx(6?EwxkRCXLm6sGrh@;#SG@&TsU* z2K_92-~D>1e`aje9$hzgeW5MN|3E(rTHM^jzoGhf)o+#e&}B~l*InAzALyO$)!yW^j+S+9SzrIisHQbaTUYtr>wWzvMQ-|0 z*Sy+2uB)$qNL2MQO_tu{cPGZm#;SF__suPCS*-uW3FY7GFL!U7ewKgjZCP3l3qS2t zU*|nxvTNISkIa`Htr{Sy&go>N?;&I3i_w0!6G#rnth&VNQv=}PX^&+2M7 z`EdWqk;`w>6|7*NTXDGmxX9ucG$+R;PaN*QKdRZgIkf5a-fqef{$O}@v%C2Se?n~D zGy0RS+ohG2c-PeH%UsP7{&REd=S!$*sm_r+Z%))MlRIPKv$ChzTKRgh{E*Y8%~*8Z zb@FrGQ7mn%$yd8&rFs_rp*YOj7IbR5)=SLr?JJfap?7oa&if=>r8fb?r3;X0zI*Nq zlS@c5)23z3i(<)TZt0Q!6LS9}U-DI`-{`fe$$qQSCRtxr>u0I=S>t^c$)~hcP790H zhutuD*4%l%_3O1RFI%tK9yS^In)j_)AC@5}F=6u-W%-_7AC@&MTdwHp7dq+&OVRaj z=IZ}s?UvtL{nRj-1u_NmZuae2A10T#ulIeoJ}le!v-bsWf7&dq^BpwHcgF_Qe$R$5 zxuWa4Z-bQC>NS0@S90MRZF>F+{cKn+%{u7X1#+hF>V~j+nV19KrYm=ruYNrL$yw47u{s^1?vJ##CijuGln@!av z-b{E-zuBNu(QBITjr+nbvyy+gFKnisXms5dcHM$mve{oBcKxiZX}*`dx%idN#eZ)I zn>%ZPoV7eB(;&06c7q({HExj2jjvGJrFLzJ&Ee0UzxgPCWZ3B~(r<+RYweZV6kgJ! zIjkhCH7q+Xd{Y1Z{fiFC3vUk}o>b=F8`d0N?k^16aY$8I)j=KZ>7)IpMl}o_Ke{Gj zN7%UMzdzdlevj~B!(3gQf3l1`(R-kOXl}Ax)6lX%x?CRZlt1F++MM#2V7VUYaXYw7 z9?{hNFJOK3OWF4?`@X(qrQ92=Z%`@s2kYBW$_d7~J~?mk0%t*xk)u7H03O%hcqX{) zSmQh>u^G6Cx}H??r(Q9C5xiunOEV)%Z1V;&kICaN$bh@4=w6iTEk9=EhAVuz zUWEq1)L#0ov7bK)(xG&>313*4X$;@xo05IzR?1g zfa~P8y%w+lT;61SCph90<0qI0zXL9oJG}b+kHNKjjK2XV?e#d<_bUQ_J`uap0{-7>@=|KhgLyaEf#Y;x!mtdb;u5;QS=xC&7v5Da-PI6@i=!On9FKOfdci zJZz%z@8H4BdKcYpyj8fLmt@>jP*fBTzicgk*51^e&=PbTznT zf$>uC@EqfH;2lpHKMZbu+V~~#Ub(}d<$VY)+avvQXrK*&q(4mPGtH)GYD9$hg#dVT zFXPeRy$QybgRAB4qLw!wTqZa3l<#03ya8NyQiQxBAVM_)^$@m!o5orJ4dCLL#@~YD z<${TR{}=F9xeTG)d%8_PzFZ1W)-9s`3id8E9t)0HD(87B%s`+@ZYn4*1P@0P2lsuE#RxbUEoY` z>c{r|72r)^2X6h;@|ED+=&vnMOQF^HEpXv(<4?d_!QX}O{t)gp!={k_2_by0ajuWT zwIRYSA-o#gfCk(b!jFdV^CA332!G^puIzduOS>c)24|2Q6W4ughz$&q!7MZ zS$}^lP%akQ-VhDS3*q7r-Ux1nzX{w4emjJ}0sGo*k!l}&-u|C~{u0oiNi>8r!ExYA zz{A0Fz~jNoLU=uR3i8$9H1O-G*#GAs@GgW+;LpMJ;630D@Sotg?`?|u%(4lX1dan| zgHHjMgU^{I%U`Fs2?4qC@3HR(EAS5R5O6s-6}%l>0B#4@gL_|R<#m9Ef&1;T@+ahm z1X4rz))0OmgzG~1%MgyZ-WtFP2ZeC%xgmk;LwH>X*MQ?O1^)@*&JaE{%^E=eH1Kfy zey;Cw1g4_Eo59P$_kgRwkAoY*Z-cwQ--F{jY!>&r!5T0Ld?L8WV_E(eBTx%rKDY&Z z4>TYWa5*?16}$zm2mb(W2Ol=u z8W8)VO~A?E(Zb&Te-Z+z5N-e$fbRfr0zVYOo55R={|~qm+y)-w zFW~Kd&kx~iz)2|JHgE>G3S0#K2wV&P5!?apHOCszuM_+KAqXUQS_{X5wbLirJov5w z7lLmF*MQf8TfmQlrL!pS`)`6rgTDZ$k54aUv4es}g zHJ}MR1niq<<>yX8AP#{Y;AHSF@CfldhI$oV#lN{~M; zgiixcmWPCN9T^KQ0AC8O2VWP$w<+uIk3vz1urY+64dHDe{AmdP5W>C%HbKp3(4oTK z{-1#$guM`wlp|yVRVSVE$`t;CEKe3FPXNCo&lo6Q0d=+@u>&7#|o8Bex`hgyv2Hcl*jGhJn(PIk#apD-|{^d8fy<%I*0m!r-KLOBA{Jgsc<@2yTDQ& z3)Zf%l>Z6VF0quSfwgxe<@xl%OXy4QOPar(J~+1!0qveig$KYsdDKGrC2%wN8*r(N z%c%L@(v_7?ar0fqr-19^br#K^4Xy`Y2yQUW^`&aSFSBNt-}{1Gl=XOevhfmdD)@GA z8h9Nz6I=<-20stZ18)N__gI$yX9(m&_yt@D4qs#qDh3}3E(ISCE(ebV*MMh$>%sHD zZz}8le>DOP5DLLf;CsQ%;Pv2E@V~+B;4*Lr_%ZNa@JnFd7{BfRTM&qpfG)E?$mbYG z-e_|m2HY3i4;%-M0}llc0iO;Y22KVio#Q{ktMC#8k|A8@=AY?5Zs5%lmLvSX{yi7M zFS@7B^#3`=chiB|Ss^@L_&TYlDrbxw8QG=FlVm!zvooFCyWD@1{Qn9oaTkp6A9olp zh`)Zh&lfN0Ctk5}CF3cPy4Zpq#LW22b(&0Rave_XC^dj`obv-`G3`LAsc z^4&K*n(w~pQSQF!@yf%dMSr-1y8UpqeX06k{{p@TLzcs5A^e>iILd$IVZ39YcM!bk z>EkAhlF4SA)6F{xdS^ksv_5W?dW_TK9R|JQpx$zLjML+d2fY)aUa5JxjO(V=n_t}2 zj+TYYsgwWfrq-K3-8Qw}{OPu-^}Y|*Ev+)QwAzkT{lLFr+1_fbTLk+z#{xv(65+pF zk8Atb3bL_>O$b@bj+g(W-(c^b@(=%huY(hBD>c)5(L*L@ak3z;L~H+!?pn>zi7 z5!N}Bddq>o^dU!Bd(J-J<`7xS*Etj~_3J-nnL|NecR?qdH>LC@m98t3j&VbEf*98? zs>hpEdh<%XasA!UG2$^!k2kUOrj~kT$GV~a5RY+syt$<}yVTneaOvXBV4U96pf!F1 zCXlRooxmL-t3da>wwpK2^d_3tGi0!9)AlgVdKw2?J+n}c3lo@Pv^>V?@g|<$)YJAACAc>A7^laZdwR1^z1Bo;{?A}sy;S|c zzbivlAQ!^rSfNf0S)s|=sB`8VVvINv#q>8P_MAto#!7g5OI2m$>#NdmzeC;8)Tf`lriQV4NuthjOaOF zAma2=z-5?@lre7TSeXvS>D9nXKzTJ|T$@ZsfN^@Y@V246+A*#|%VV70QIC zTEwJLBbv?>(GIK3Kp6X4ZI zaZ+uNaeDRe=D`zoTk>VK3aPgV9Cxv;rcLL%^z;9>c`eY6fYyTMG0ti`;GG1o10Lh_ zy5OCL=5@hioL=O4HkYGNUgUW;ml>xQ3$GC6#h&LX&X=XZIK5hUKf$X#&(>zf>G6pH zeS$!Ly>;T9C$j}#r`G*J0@Ze$=hDYZwT#o_0|okkfqE^N494koe{R6rXh^kEUXXEm ze11TmCs0q=Remi?H>7=hu0WqNP%q+qZ}tTlXL*IVzo55>)Dw2Q-<1hLoF4D&=$#z( zgk8e9a^%YdMcx3>8yqSMyWJuNn4riz9eU?O#pc~EeS%cXIKA$7K-BBp?Is-A^SICk z^1g@O2vJSg_1rHr2DcYj9Pfwd{Soz|+pSv0>G3|vnegJon=I==NO8PSI!;&*Lqm@mV&o`C%X$Ud6Jt58&|tj$H(8E{^`G)Z^1&}C>++s1&r0au-ww9r zJ$TCdA_OcwbO%6ndVpt8Dz=ALu5m z$M3@1gdZs5EUzA(-dEIm>)YMpYyS5K%G-;3pmnsnw#hQNjI%i2cGTODT3p=sZsfgZ9es)aj4^t}On*M>3)@+R|I##+6RH`z%U9a`70a7m;J$ zL+~PUtX{_HrNH}okhL!*$Cex8^m14pmPd|wQm;!%@y8t2d5cwc6q22{xRL*oMlsGp zhRAgw{d+YUH6+(97B9#+y*hZA@PysOKV+kUIK8B0R$d$GOeDGC`3~q3Ba7Dhhigy4FK` z#vI0HQuG-W&DKkI0J8H7{D2#>(p24g@=+CibVW5`tBnbXc_JSv(I-Sy6!s2J158ll zqaXSxh>G!hT-zqu>*9e8YIq{Vr%#BeHhhn(kfY~7h{oqc^tln$gspu{usl9Mq7Rg) zC~P7V6!~O{K53$&uqOtXpvXr~9*5Yt$Bn$|eUdy5CJ!?tV8}x%=H@FMpRy zpW(l5;7Hkpr?N2l|Lq~X#{GAO92st1X&Z4Fh}4?D(j7fhW(VV(%#;H2hD$)(pHkp< z&XgZ8!qi&9H$ZDGaO<@=#_6@+X~mrnul-K%>U@B4dO2&%y8>R$8uJ*Z7k!s`J>W&( z<*rPXdKsrTeXV)HgKaXVuk{WzgN)PT^H%yel}@g({o0tI$mgo`IV%-~z2!QB2^CZI z1OIl0EQjOekf-}{I?c_WCCg>>J=V}i(9qHMxb?GSf*5E05k=;G0577*F7q-@Z}h$9 zJKIK7Nw^D^OO6ub56F;1_3y?K|xt6%SSs>e9J zsuJ_gIK<{-Rf!!uF;1`ae)BGdS9-s@@_IcuL7d*E2h0n|Y}e%?>~>F<3u8=BY=Kyc z0$Uz%JEgz?1CIhmj^Gq%oZHu^pYPjPkIUQ8kqcud5qJG z+-P1WW??^(H(t*c#PBI8%g?xlDEP>=B^ZP1mo&;UtgDpte@|O z@CUZOZmqCpt{-T{Zmn=TwR*-`ePfk*H^XbJaus^JjB$G9Pny?!u9a8*q`NX*JjUsD zR-3m0UT3viFJ8F(e{;Hj(7*w5($M|qbwda*c44#S=ca>SX^}_tw(2%L<%Y^52?54g zosLnZe=qH2-rncz1d4HbI*gE4ULW(ap7$Pc2ry1hhmz61FGIaCHQupyfN^>{T8RF= z6Xo@*ar^W#665p=;jKk^g*D#KBfvO49f3ywmhKw7wV><;yWY<@Jsm_u|K5o5s$Xzz z8B#Cf^mLdE{ksn34cqL7&JmAsdW~Dmi|%RlHg2)`!Z0q3mjyt7)OE)q0YkSe|M=(xL$CA*$wTi(F; z%1e96Rj9`}Jsl`V{~m(**YUDzQ;%_a{a-Op-xJhdW&c;qW1OCjtD}FPheA&h zVSsUZQ?{Bn67^2mYL_t?r&kDXF4q_Fv^>V?HNqQ%dKDAYpmkzJK-ll_bdO9YE{{1by*f*_xjMLMhJ@oHC;Z<+9%@pJGbOaCm`zd(R zgQs3r9>KWgx^H#g3E4~?b?bqfv0?6&8)dVVw8M&>jny@2hpSj1lg&7**RlWf?<=Bh z_H@4O+SFs5o{o;De+SXb(eK&A2aMCxLCEy)?@@2nf9xq0#_2V~y9-{kc=|8{-(-vJ;v$jSTXwdIVi8;1J`z=9EBoGO$UF{zq3)?ln-sTFiua$XwtvW z$K=K|xr!{QmT`JI){_3c9pz1LvaJH+^mNQ7{d)_VxBO$9EsWFCp_laUa+Fu|u}jy7 zff%Q!qhRUZr@`yoX%7uCPH*}y^9HbeyS!grka2o^=wDv~(5;NHoh30rk#7U&+W{&H zd*TQtRP4UKt_oQ{KM3K^Y<*2dL%$ek<)-fP9wG=b&iY&7T_}fdTEDQHJweV*nV{GO zam(>03VULJ35qeF+AKPLkcly$+Tj-C^qSxug94jAwG$4;>7{*U<+a3Fd1;@yq1mzs z8K>9OY~JMq&1-6Q>FO~~ukZ`=Zb5m4U)Ys$#_2_TY2I|qnTRj#1dDNckzbiNPy#v! zBfqlaX~yYw!Rv+j()E=~zggPHIK7N-t-Ookt-OqH?TR|%^v1QC_b8@gT&q0}#W=kV zcyGY#XmvvuOTCQKOZwi*dwZbOoAkZiKVzI;#1G~@8#FKC2bZponK4c;ZI5}&F#po_ z*oh+J^lJZW-qHb9UhRMFu{Fl&ZTiu?YLvI>M>}6)oL)hvd0_*syn;?wu|(SUSKMbi z#__+J_XE7~zuHA^##vs@Uh`Tpy*Yc`P<_^xaeAYFH}5@oqknhl;sqI}R~&9{#s3rQ zy|AmykzX7W6tfR9@m+|*Znug|P;87a@e0%|?2geh7sTnc$T_?IeIe$wu-ly>1u{WV z$A8ejA4Gw|?wA`yWP+j&5TSqH2vOMWPZE&{iqrijUXPVp*i|kNkqL_ZqfKnZL<_s! z$#OQy1jWo=CVqg4$?WASZk1_foSu$#p?{x(nzIgbZQ=zPr>A3K=-=V+gk8dXX(1C7 z8xJ=z4HXN!{UbzVg5snjOspJeE26MV7$YJR6!`|2z7eKd5MjHr!Gwyb`hkB#<-SQO zLH@regl~6a^882ktvb>g@bqz3uCS~8RBpQ<{#X6|%=5#m?dK}wdA(pQ;`G>shIXl; z?G$#i&yi)r1jV}Jt-ysSug9@> z{yhL*{rRp!J;v#6y}-OZSYNhYVC6ARuliE+K0$fam%5?Lq&&vy)m&rVNO(2ZxODM? zjMH15X%W1Jp)zR{j=)Dw0~WCIsqf?^HktiEWfVoj$@|EF|WhVYT@sTr~`^F!wA z`yu?PdvArz=dKmjx{Zlen6MkQS=K_tS!q_jd9lOH6Lzad$!g66#X^XiPBKy0ZPD#C z6BMUPhi3ZsQq(MLHz1gxm;tdFV#Z3hFJERLu8uO;0wz4&D zv3iWtYrV_7aVW3#F1L7Bq z>r>o4-sU^VIK9SutiagE+m$bynam7P!vs zQ;+e#ykhg3FvX3JY?RVnBbI$%wwD$`>fJFtaL(#KWwWEc-3#B~9=_Sh00Q$E>y@@Zled;kzZ`Wq?zQcs<+UzQ1Hxpo- z9{V@b{?4@C_*%Dkt;}l1>1DlShni(* zt&w+23mK;u{kj#{4=Y3T>u#}lLB{{`-Z1Y@dT)fe4YEB7Mk7IS2Y3=hVOM#+h)ht- zs<#psK@>KT35xySG_g0PS=hF%Oi;|(ZsNsQDmmNT=6htC8K=ii<+PJIT`FmBxqadV z8K+nHww1R4Zb$G&OpA*&yTehJ0w=N_fKFPAA9& z#jKA^?7+50*zF!G3z-RuRZS+|22t2MzYj1$F>@K@Z!MK)ql6*}6-Mr!< zR{iwf-9D*4$T+>uaO)lNad^UR_CI9NFhOzoK_>c9v9McGA|ewM3!_Zj3Q^eY*7x$6 zpg7KN;u8>s-F_)Czyw8K9~09d`uez$vNi@7r&r(Cymv7z^?lu9^%$qua=3Zz@LCRc zo5c$?$**flN^J4Ky(aqHiD?h&a9azaj7hO#_6%6DD5~(Cvdb)V7UB$XQ_YCgo2O>_$Y+G{Qpc)`Ds@F zo7e=GpXMe!D2tYH*57Z0dB>e<^$WZGcghlDf@0)I6Q4nWkt5x9Es$|~smbO&3{TiC zDUdnI1jXiaOpHX$!nOxxf?~>86Pr+C%2>DRA*q>hdhO%P>wqWh629~g=!dxW-=c4) zl;dr$u`cXkxwbNF*@3Ibk`TVrjd@tEt#qQ4S~OSKEman}SBx1&U1SE+j;CMf1jH1Pwp zF>j))D3e*rIK9!6%-ao5*p0eeYG#7sunSELJI$s=*p~WV3G4@|E;g|MB?{XU#7wZn zn8_xlKoqtsrA$yvf_OeeVQ;G#WP)PjKdr=vAqu-um&wF1L2=k6CLYa+xkMI>UK?S8 zVh6&D#b~*ln5OKXwEYDt4dl zypZX9D}+CFV;++q_waNp_eR`T7Iq2x(gzc4Knujx5QTMfIUs;Iy~f#AU?n_ZH&L&! zGC?se!^CM2h23ts9~5MQVmw3{LeQI)!nUDW?{Eqb{PRCC=S2bO1uo>@S9zm*33A)q#X02Fmr_668X&sn4mc9Ruj80&BJbW z=}*c}lW}_0x0!b*Dz3iGRfrd4oL>7f^PUU0DG|08a+shve7T7e(L!Onj>81SakrZ| z0yU4j-KAGc3mK=EvckLp@KRQ|3iTMLSGv-?2jJfM3frq=Oi*NZr`r9g zidl9T9AumxyFt}%QPmUnmPvT&&u-Pz{>vwxdi#Mpwp&7Yjqu-{0Hob%v*=ySB4Ia5 z*0LZIY(erG6YIxY3xvJX$p8}+J0U&}v2%^Lj|?(SFQ(86EPyBM-RTN2L9q~`3s}vC zg>L93St}T)#~~kd2nd}=wa%rh$2dK9A*)@=s@M9n+xMI-Z1gNkjXle1PqV5C+pRq& zD6-30?SfXtA-{O%YC*>7u_s#JJoAKYQ^EvAc2OG#QP`_Fe8(?t`?LP@!e+QbrNI-w z3|Yn}-f`eMFjn~QmU-+3oAXmK=Y_rBZIB5zB)-JN`4ENOmNoMGVS*w%(M?8+cm3kM zu|Jb>^-}c%|4Kqy`fUjR_Wx;l%l+1%PqDTNyCrfK+7EHIr|SXpV%#a4{YSd`691v@ zip~B$eXIX%iB3$Buw6uCf+e(;nwX3WtgWSPWR0v$jMHOx!80)B(ZAZ1Gp=6uDZgmN zfy?N=5Uv*fyJeR8h_&Z4G+fv_ehD(c263Dd9rr}nMq#)6R#|3DP-Mr(d1(1)w4CwK zmizM$Z24s&oF@EtEzc>pmOplZHAvW9b-iq1m|%knA2ab4h{E>!V1i;~g^7g_h25x; zQX&%+*;ljn-K_IM*xUYxXZ-4RZuSqF_)^F;M6En<8smijZkm>(1zBi;uw7eYf-Oj@ zw5DDPQP^#fi_rrSrvn3*jMIyI z!D@b6rdH>muy=$QWP)PqW)r1fU{4fwOXOmCfC-9S5O^+7V zV1i=5*Q~%l2b$RLHMjF+X&~eD3b&be6!*g0u+w0IV(IH9o(@sijwqO*nEi%{a+v8g zQP?HiD3gLXy;AVrc=Lq4qpkoG6w4uw3Yu8{hCBKdnH0w9)xBvI--ZH(-R|?GV#Mj~ z0GGiNb_wVIuh#_c19-x2_TP9d@Qy?Kgx&0H|FJWe(27&_1ONK1I`G#yGlVmR|8DbC zvfUCMa@nEFCOMe>B40BMSj0DCU1`HD{s3 ze0jG*uM9CxkE3hpXj@vKuy@5S$OOgmZo_bSHH)a%X=gB@V)uDg7c!4}u0C)c_7~Q9 z7Kl3VN_g=uYx(=WCAloCTMdA*SY!IWRuyy|6ZSfj3m{G}8ax`FuvN?i#eNWf9b^+OY$6jB;~`#w5{2Co*@=eM zoCNPCc*6FY2@@=E62yKGC$)GR~HxWZl@!l~|*dbwm-^^Gl#TYA{stNO+}R}M1HY3*z^ zFBP7!J#EAU#m4VUl<_RQ^-$P5SPC*haeSMJ=b}VmJAGh+V#;n4`$80Uv*mO-zy!ri zh{r?B-0fYAiDJCaeX&^%R-O)-6Z=Cr!X4VG7jwV2YUdnn6A~l6mTi|`DC4Y^Blziv ze)_``cBAf+V-O}Nru|?A-j4!>?Rpjy6zd?~3Q^eWtRuh#Mc*DPu^OUJx`L7W5CO*N zaZo`WWKf$Z;|!<2C6mH9Jq$MJ)4>PT6Sj+_Oi&#Cn^ipOC=-Rfi=+W2C~~wy9lcOX z%=^tP){|s>pIYHQEAJ4LC+v1FlSRw~#k&0_4m{S%tK07?cF2@4POll>aVSvO3S@#} z%e!UV-Qh-*=zu$9OJ#mV7T z;#QO>Y$Y;5F%x3ykv4aP-4?y3%LK)agRI1%5QSZWzBY+Cz4!?8&V?uJDjUQ@oL&mJ zQ@S|U6;aqF{8K7sg5q+BeNdpVx5EuGL9qtnODIv;L?$Sq5;I|?K;G~OY!p)w#T-Zpx6QNR;~{sde7W5K`}bgN-Tyb?DYi_ zWP;*oh>H%lHA2{C4igloL;N$=L}6DsL8b+9dKuucC{Wl=Mwy^k2JuRW!X`37aTmnH zAqv|n#stNfD4Xa+h{7(RQJRQ2z474pFe$=TGZPf^Abtx`*hD5M)<9g1nuTqpWrE^X zh<+?-VH264*Z}cNYapgU6t)XJOi&yiZ6$sN zQP}#CVS-{R#9tt$M!U8TWjDk)y_DWo;1lqK?VdRk6gNT4g(z${OPHY81+f^Sur-kh ziiv%!>MYF0#6GU=BUvLD|I3RtPsbD14P#=g8`>n3!f}P^O~<&x@8MWO*q%IKf+7bX z)&YsNKw-CKy(|_cC=TmyHT#b-QP`d^W`bf9#B(7EyGng&jiIT zh%aMHCTvs91jV%Dt;CHGg}qAzK_)1s3^MTsh{CpHnD|Q^Y~nJCgQaSHbTS1AipfJv zycnXeOSnZ=N5tt(KEb^H@PyqcxseiNg5sp1CY}jV*t^ggWP)N+f{B-71s8Vv<%(>O z35py>T!$6cMJ;UahA=^q zwxIzgC}u+J0WtGbm;Q;IYamQ5`ZO!=LmZk2+YLh|C>B861F=Bf)@_z4VVqtUyy-X` z6Ltyu05}sAIn??B%o<_uQgDz7ib>MtvHm>}B?{X)G!qo7AdZG8Z2K1`C`O)XB_0e> z*q#e!f?_em_i*?m?CmQ9Oi+x)IPu>@j7@SwKbN_UFtt4Jt2|;%lDVz-x|yKJap!d$ zdR=dX?GZR8C`OF3N!g5wg}u4xBEOLbbV`t|#3o7D?Uo0i15B`(@uRJnS=c|0AMJ*I zB}%{?{vpw+EiEOV}<;g$Y(1cb-jhEGAjlJM0WFK`{~HlUV-} zWt0%zZZS?T=K?G6Rd~X73d97((g`NM&tLll{N$LRIBcSc-#`?0pS&c~!UV;_3r+kT zqOjXC)jwc7;yR|J_6pj4OiAVLV@fJxOi7;(c&OJ8{~GYnz4xtLAG`3*1Fsz39m4l} z*T?$Spw?4I+YeUQyXqfcg3TUwku|&5H6{+b$SrP_Im`H8-j(L98U^o4`C;qZ(!-FT zxCxw$nuYB#E+!~OTxBIXlql?N9$oQnj0`dz#!)Cr*dEPif<+CPYDGnyX^j)MmnfN_ z*adMAN)+~<;SVxFvFU0n@#!QhQP_KbjL9uw2i6=u8c9o0d$xrBCfY`U*rLy)2}f zmqPdr_h7qR`z=hjY6lIpWmA~$wo7S2##w9UeDjhq*}`_r$OOff1twk%QP}O4WA716 zsMvk}^uO!C`SGt1p6MR^Ugl4HmX(`>yUW6MO_>QcAO~V5L}C5S$P3|C0KFaHf5zC9 z3){gh6Mu<|?2BV5E|LQEk`dzc8o_hm3A^1V%6*{_uN`~~JYhGnRvvK(@iM!OgRRF2 znRcIRCgWOf_Zhh*WXAmx!Uq-Fjl7E^54@4r|3;g>qh$lB^$6P$6BC@kDu_?ZmQ_Vz zd+wD9irF_=i7gO??QH-iC}w1vxD!3V;*fJ9r zqeNl*wJ||4A7b+9HhYA<`y)XnDDHsx;Q1yByUH?YBNG(!ms`~fAPT$H4~fVG#r}7g zm9!nV6*g5tP*6HmbV9Kvq4{?ZYrw_~Mwhhl9M_MWi`GC?tJ zm5Dj1S=jB*muX>wVjaYSzG$L|-mA4tP+Y#+O1uIk3cCdPAtWKLUiXc{RQb`TVo#+1 zb0PeY`{HNWx_05~mvWtyV!hW8m|*?m3#|T2hFe30-EQsZhzW|r)|hw>rbyU%Z)P(= zG3_oBZ-gjpyJ#jT7OypN;9*v^uw7bVg5vnQO}qtbxv=wk7h{5AzakTFK-Iz~GC{HR zUK3XgwyK3~4Pt^~#yS(%Llm}W_n4rV=S(~T6C>;@=gX>wIKBS&nYaH?t6A8N#+abk z0r6B!i?F>Kzy!sV^;TjEL}Bmx#t0@&6rz4H65!2iG#c9nO?5fKv6&{CMY&Tya1xG z?Gc%vxcm{T`f7;6-i9E6IK3`#2|Quz>M6v_+Gyo{hiMjes|U!@3*sy<_EGabgePnV z0ZdSAhByH0nXvbMN014MDUVr+E6_q=yWqwI#mN;WMxw;Y6>h@svYZ*GH?`8dOcW^W zD&?W70OItTs?4i~C#>GFBbZRJ`!Atl?SX6l*CG6a{Su};Vdd_@5vZ`+qIb}lU;}nM zW#T#t&f(eSvPn-BKL}73D5MY90*)t}7j;hO^asEGL${DAZ|D1W}V-J@9oSPtC zka2n`FPQftHx@6*R@}R=iv-2!%_a^;fx_Mc6#*tF#%wY1E9_}vw%qIQDbJc9Os&4w zw0BUku($gd!Gwz4m(AF_4_r34hVbfpAMAN#U*Ahs>~0)02-}e<6Rf`z;*jyS-4(W- z4HFd0UbYh7K#9WkPz)0kv+7Lz7^1LU@MnTz%qu1)p=x2f;Lilb5{R2nqOkXDbC3y& zLte8I_d^u6TQN*ftc5rMRSVmGjtPp%Tdl;N5QXi6KNA#7a1t{*)8?bFcVl-Z6DoFJ zjx8a}?YMgmT&^bw>*I*`-=3T7_y!Xnf*9Z6R%wBZ(`$dJx<`NR{E;&0jMIz%+Psp!HZO(kS|1Y>+aW%H z0)_258WR+!e`_WFfz7)xUfxB5Vm;VRu&RaKsC#93GeNPn)k^F{L5W-2-S#M%JB-sS+hg8`STTg{i5|F#6 zGC{GvhlzipW?|duF+nl)U=ycc;R(Cd(LLqm5hN&%?qy;CRgdoFwnxihD&zD@W6bM0 z(wbNrVYhpi zT!KWL-qwNU#o}7?)`8C7N2Zx^dgBI}SBzT$!qyug6BMfkn>Z5{R}FR*r^>K$2vh4C zV%onjYlOYKZ2=}I_CLYI0+iSP1m};D1~N`>Z-RNFvDOHCdzT;+6sr?Wyd0vi+x?-; zYbGd`on+#Ch{AU2#{|V{h>HQ|8SWW#_0_iYu7CWzaxN;XN)OIje~^dio)0w?h%*Ll)HJu_y4V$KC7rb86=UZf5(L2>j% z6W>7-h21FW$}fO8y{1X#rNI-nw-}kA*#9CEhd>mzhj5snm<@41#O#aQ$Z2xp4Pk2e z;7_6D%ROPy0wG!v_?A;_Aq#sKL4r)Myn>6ZeQO~K+s$YuC`L>+aUFgF5tE(2pDYu` z>Ghvt-V%7icIlT1ifIs2Aqv}>E)x`!F0&F7u<(TKYim?&%;TqY>yK^%ok*}~qDTaXEgiC0>Q-=aie zw_9G~2_Q}{1AHGmVY?8?1jQJI0+eI2CDCS>dRS(Bh3uB!?f@1tM69=MdVK?e-*?KcUv3RD54byD)6wj1b z`{aksIKB9E^S*^AY>!L9rZS7^X$oE)V^cklnvtj7iL}62HRy z7PiOwm|%&e5a*!hBVjv4VS-`@#6QQ_L<`$}5GE*Yonux1f~gjEyXVR}!34#QxhBrX z5)`)g{FtEFFweviOtr8bJ2F8rKhwnC)2)rd)_FD)6vr(v@n@7MY%`n*iY*W?KpTa< z3&a5?DDGWoB_^Wky$juhfwE38PA}<3^9oU*uv`6yY$gz=H|Zwx-a!k6ZLMX3Vk^Y` zC{Wn;9!yXio^2(bFvez%u$!$nyb!0C2M(ZSVSCVy35ulMsy+dM!ETEr%y;4;3*%vFKJ4w?Gtj zquQk_w({e9#`KL@YT2>VZPp3f?I)pjdT>i8IhfVSA{R35r8jnz$Dw3cHEF%kPs3io;i#xDX`@+lWp~P%K() zVjfBq_6|1!Oi;`zF!3pfIR$RQAh~qFIKBF{=6#Ceg8H>?m3TqM>D3mQ*M{TXMvW4h>vtei`5vLtL>2b$4tz` zauas5&lZshiZzd$_)TAIavqoYtw}GPdeKkW%!!FHPuNY|FINf?r#A_FBHn|EW*@cpEGS7G+~<*CMcFeY{y&_wiYr$ zG5L8bQ4V+P2lBjZ0=1)RCMXuxnAihbUtt?bf(eQp5MRfNC2U(ZCMf2;U?uK7*Qyrw zE(FbFLdEVoy1I~6Ykvs)i~s(H^w!N*(F*Jjgss;PCfK6JEhff}vla<^$5`Pqiu{D( zJqP5n-=~1ItdD$a(*t(fTj!oKXWC?CnNe|Tqr9`LM}B2I9Gp^Md_K5cS|We?t^nuA zv+Bw>cpNMJz~Bo@G$8jXV}`lKr^}p)d&g#-KEJ}|x&78X zfHF7yx-U}ZE=czz%E{Pl>khn6Sg!P#gFU+TJ*xt{oPAGO)`iS6n*;6O=?@wAJjnc< z53RvRfje)p2|5E@H6M!xoR?vop)6w_`pOqrU2C%yy?X^dlo%LwvJj(2pN4x(~X0Jcm z!H_ch71EB0l-VKC8gR$qR^di)Z6D(oddQUM7beTzP5$R=f-qTrG0L6%0t)aSj0#`1 zWgY}iUu(YJm)7!lJNhzk{d&u1f-_``r{&+3%P+_gm>+3X_zZAWiRCW_m)>ujn}@n3q4Cv=E;FRKd;Qk<_ndjf?^b?_jJ5GZr$js z70P_0LZ9eY=7ao=;N(|y5z6w{S1eTEn-$ubyD~d>*IwC`*&Dm|zOKwp*YzzKWxh3| zuh%H^ts3pjQJH->>XRbM-UA|1zfYe<(Ey)8c@3Pr*k-XliKux#fw%|EXCd{Py5@O} zU7x8}=A-obR*EuTM$rchmG!wo-TwIW5k?L0(M5e2LYWUi=tC6Be0X9#3&57|NpK=q zUolaiubk++Daw2$Meo-s%Wb+`Z>`p6Vl=>KWTJZ-H*T>x5CK8wYz~4&=UPf%6fF!57lO_4Srt3f}vi@dj|&3&u}@yWTRc0}tD5`~koJy79N* z+}JlQ@FxP*+l`OtZ7tmNl<^R7$IHee!Be&xUj~kmLmr(&bHRnkuO%bD(Ky#vjVX8? zLi{!>;6rd7S{x?ZY+Xm{51k7fA}$4a#dLfT6v zJPA%lekZserl12{^|I{?eg~J;8SD9;Hkjvs@!)vuJ5E>D-(PgIeL>%j(=Y76TWtDT zoyS@BNRhr3r_8tH^zAogz72OTI92wu681d|o`Uk92FHV65%%`~Irzf+5URkt!CS$< zfjhzeL#+X$QD8stCh$q%BKTv$yTDTp#r}WqC)VN_5O}@kCUC>2me&&jonjvU7lR|P z;n9n+n&&lGeUU<$?@#F42+Dj3;lo2^`D=hr-s_|L%6ybx-x*Qnt0MZsg;&4^TO|7K zi89|s(HCo!`96)lPod2BDD<5KWxk4VbuI#Y7eODmSAh@U>l6LTe2`z?K~Uy93Hso@ zGM~5C7c;!?<3$a9^Fx_0eCTTy%6z*bS6`>lKq=mu&^H5=`9^@gd!Wo$4)o<1Wxf-m zFDEJUog{rHMwzd|=!-$hd>=^PQBuaMNx43KUrPggO-rA+ROW-0df`Et*BkUXdSyOW zuaCDY^Qm^dI;PBvV*9{(SVy#n1kGE=2(tXOgA@(0Uli>JMVZ~7Xh$o`?07}Ha#3av zF4|*@$AfL1&^}?5*%gd-CZo(gWVAmmat3{zjD9|A_XGqRfs_v?CPd*j#jZqJ6Ds zfL*L;Z!XI0#6>%8QD$E)+JB5PyN%I)9F^I9qxQn6%+43JpFod$ScA1YK;>L^1E_sf zYJgo-YEP5O>|j!R+f-&Jo7!2XGW*EX-aVDssi$@$sLb92wYNZJ_8zFc0t)B)*c+hs z{-*+a1Jq7nl-c)-cEO{}o_DmT9cA{gqdoa3vu7XeD@d7L1ZkH*%Ipb9dol9P|Ji$y z_T8!i`)t)7Rh8M1s&>Vy%pO>^BUNQ~psJmnDYK6=?FUSm-G6D#nfjyOJw_nQa?Mr(qQ_eWnmZA3crOZygw7(SP>~k%z{h}yKzbM{Hto@%Tv)dEx z=EU3ovwIWm6GjDg1*2WRDECJJ+FOk>JE_s`aFp2%j&>iXoY==I)NXK;+53(5(x=>j z4VUyOYUlsHF#Cdb397>6aAWNkRhiwPYOkis)#$xc`v+8Jw}9Hyt8yKBbk&Ypm1EE$ ztM(kJ%nl>dj>Z0;o%?B*dMa${Z4J<#^OV_Pp7zbB%r5z~J3(dkBB-4KDzgtj?ekBW zef=FdKv+)S3UKn8kc&VEE}Lne{rUy=)qf$lMJ^0V*p~)wJluFGxc0wx&{_d5T5P-p z+&ahj18`<9`+n{o1h!sa0snE1HkoirBNF&5?phQ@xQ9X3H5z~K^(3ZOw4E&HF(pHmj4)ByTE4oci{Mi#s>%O`>{6}9|z``1Eat)NP_ME zuRx$N!oF}LI5NukL2&B9#?OKyey|3;2Oj;qaVt1yuW@+1H7Fw1zJCfh>oA#qodXvk zknyd3;d=0NzvXWOa~Ov*Fo$dS0L)<-_JTQF#4*QP1DZay^8X1g&JDK;bgU6?nROea zM44lg=qM=49Q@=_Fb6r=0`9^xeixj5kd@yG?jLR3Ymk+f+x3;T=y(KT(87`6NjPl2 zNLjXA)!0z!Ad1=`j-9B(IVy7$M;*0MnWH%B=#0u7lu^f46wdW=OvSGuq~utGw2OZI z0(<7yK~|JGxQce9ugnhg2P#Vg(;l@8k2+?6<~fFdjt!v9Apvykfj(hVq(BThpk4i| zz^?yw6a!@rUZ7q4E3;>R?a9E)qh|x{us}Iuo!fko+*z5j%T8L~LcDycP1pzEY|Pnj z!PAldQCY4*?k%thi5em-6PAey)8UY{9uAMJ13)Wt+~=!|bA24DT8E}qfkRd6xZuhh z4_wFpR_3tZI)=6~$IjNVvXwbTwhjZX%+bGfJaT1@Lw=FRvSs7g);f5%3LLas$F^4H zkk(ItIrz5@AFg?h8vZ%B^c`Dy!-rbFzQVX4IQn(tQF+uy*BSo_PI<_9P$G`33RYQQM50xg^r`U_aM>E; zIpDgr#!JCdR~l~wcdanq1dhzMm0HK%)(PU6+s%ox{56n)0y-gdJYWSxooM;&D&rt{ z(&NTDI=FtHgMwcS&e?AH1>nNBjqeB7yleb&E(7md;5+cH&BhTYSp``y84m`>-Dx}y z+)#P!mZzBT5r6#-u&Uw(d1Dy4daqKY65j6M|aO6(QPXd>IVtgIA zsnK{Pc*uv!viu)KAiBkb*TETW#y@~}G#ejtiZx)^*T&<)?5ycha5C;$>mc2_j&N*l zee*-vd*MTmtn>{JPrw@=I#9YY$4A!z)|EN1x{lzk%#qu57<6S0f3CxwD|7gB9Zy}E z!>H@X?#eo#yLV)z1CwijL?ogtC87wCES2nA^~~3t z^SoZqzfZ5%{P8~L%$YND$IRT@ygvu#(+0-VXu}NYz<6SGm}DH7m|UEEvVz&fq2PZf z5#K>Fo+}*Y-G+KR-8SSl0plE}oxm&bo{B6dIwGCK?iJM7@B17lYm%oAWNoWL8WOZBwtAhgWLjx?pLjWi6Rx9%BJSSpPbhh##jue2b3S5a)V>Pw zLBzd?S)0lJ#}V&B^~}mde{iKaiweY`fZ$VzcOfpQCp$1f+=|!|aWuN5oG1fP_*Q01hTCM=VlD);A!Is3rLm;!4Ehhw<0zkAh{dyDRh$kLd=Lx$_2#z=n#W`5B+299^6!5tfX!Qk%RS5Y7#@W6Q(Yw^%a_P^SMoC8nyZXoxK0>?= z9a2byU0T7JybeI{D=-dxg|u8?9FqGD@g(YR8Zj%n0xnZ0+ta_o_K44)9Tj}1=4EHJia!OQ^0Mg|y#z*r;%;|=(KMK=wSu^|Uq6Vzjy3ADhaAM&v$2zKOB z2bScA0ge$cc8kCz0>%mvSZTmmMgxTi7%N3!Z~;9Spcctkrcp$U^)3U%*qQS}j6J_-Ep!paa$F&5fJL$<#8^KaL5x+;1;ki+ z1H}ynh?O@`Xn}K&kRR!3#8~!C(59h1KnPyx;;h(TO{9~C%ZS|$l6(j8WC3{u zV4h?+0(jnJn0y&{X)e*hd#l?<0KvZhPobcC1MF+qJ1tp zXCU5qX#>IJZ3_aFfpKm!M9nVMUqSzoZ-)xxmB~L7(4L?Hww=I50>%mwB)tLSfH$z8 zfU)${fS4aWihMvEjlP^g0wJ^~q6ayaPMQ_F$%2D*al`ghX&R2-l11fb#mOV1ff(Kt zAl9cCBDNAH*#hwx@k1NbJ0flsBN>v7mj)U}9vKKQ2FAI?5RptUje?_*A>a=h;9Nh* z8U)4>gAgeQjFSW*-4Gau8bajqoz7DY#;%>wanPmMWFnlv8NFfV24afm3CX*}% zOq`6V=$kxD0}lhl)4#*?@xXXGd6;(|7*97JjhH!y?C(C}plp&~5WI9#ioQ=4d_)a$ z(FJ7)G0p;mbTZfg4kd#uFkqYk2HDfVIC2{Do0kSeoc%;G1uQjSET;t-qMH&u1$3`7{H$NtMZU>0J4=!ktr^&hX0JGjhj5zfY$xVol6Rra>PD&Tz{v?t|X{Z3pL*Qn? z9$_U5tR-M%~-2w1?_yP|jFbciQR@$JI5>K{oN=`F z_3%Dn?cm~FqW7L^#4hCT?`iAp<0x(K;pQMMt3zXi&11-;ZwCHcM78n%-2zo;4v zR8MDHr&EqTr%XIg-76oXio{iNvnn$2j0r8Hu*SS#+CpQT(jq=3_{V_TQYtlOE@qoZ zKBh<)wFQSf2xyn;x3&G->140dJTF^xrNl$alEcqSPnNS>JN$Ta z-|U;+5)wsUxK(l`SUG|(v36QfZe8E{hofNPUeT?pBAtA5;iqw%0|mrKpVT}S41czR zmVQqyu(xEgE>`WzmoK!mjg9^4U$_n53dng@T^c!SB6|0S$;T4@)+VpleN`>@dh{Zk z?iH+RJQY(i+s9TGb5!bz*AQnfcgv?^55HV_vtB!Squ(Fl%x?k)^jNlGnKHjTLzu`MFoQf?V?HYQ^&DCTM`W9lNTZutt*6__{J)k8HPT@wdL3j zH)w2sx!RVy^whfFR;IVI$D<6QZk1-0mWU6kYu5Nltupkn`ubwI=(W59(bJ)3x4x#* z6Tf!T6c-N`YgZhr-TdG1_ML01bPq18AGf_#==C7s#_f&fHJiuICOG#~JMQ+V%U@tt z?Q1P@%?s+BXqz?S<87@p*(+m$fIl6;;Ou8!G>um+Y*# z#dOxO`IYNW|Nh6vcvydgEFR)hZY}a1A5}D(PZK>LU?}(1yE*P%tk=R7vGGdfMKz{) zddSBuZ;TB}|0b-lST7~i?ZsZkW7zzpQ1e)EyqcMwaCc|mYUf`cH!v%fA9hZapSCgI zPfr!ic#%TW+^OuvWV*idpJ>a)*y-4C2R-wUqCFbz_y2K@xU*I=xUHoHgwf(F7&nDd zUoy_{K2ZH~bGxwYW2pxp4BI3I2O3Uz21fMB+Nsl&#w$EF#>E^6Ynl}troS9bYQEn) zo8MwgnNj;bHlY}1)qB{3`|fEj1CgNm{j`+w zuEcT4Ay;12y~lY4pUlSl$452<2?kENa~3l>U8-AN?qt;=9h+5RXW9KIbk4J{{g;yZ zzP$2XSJsSg(N#1$QmbC_?on7Z`=ID6Bh9@YV(W`sWH03!F$uGqmxN0tt(>tn`gHYY zzP-%W4<3BiQ)mNgD_Sf$TbKR$Im>JIw@-TbLWqjXJL=WZ0Ul-!UX8#+-wJ`80Dd#3 zOEraJI&!V%38`1NG>WJl^>T0gc*|G5Z@>A-c*rMQrb zk=PtKGeN&2nb%=beuuf@3hnXFFTOu2?UjF|EPt$?`E%78J{m``x-0X_$=-%NjwIXZ6oJg~{?{^ag8ZW^|Bt|2V?0l&0Fo6B-iXzfR4bO$AZ zv~CH0w!dba-+N#qi*?khTS#Qm%z_e zsy+Wk4_U|>@tU5xW>L(ozT9NOO?J&l3TK2i>HhEScAdr z4lS{3Ya}!ucR$#=&evG(L}t0&IT zE|#iIn2$UU5*y;!?lL*{EVh??jr-|V#SUGIEqf`52f#Uss}W5wR=I{HUz*&MY6&Moh7%}$RH&r{;H za4PwkWv9P3-qX3}^gW)@m%c~T<1PieGSg`9w6!a5-h6*-*9x_SB!9k2&bQjLTUhGX zRne&`i&u3jZ#Mqg8p>pF!1JCd+cU#9F3DzNPnp#IWluCLqc@7~uyH=G7aqON-ea=e zMBGB#Qlo>)eA8~XKl`C=P1VIUy!%pk!b4A;nIED1y!+Y^HNENl%!M1z)|@+BFa9iV ze4hjDt!+n|cNy2F%x*`XPi8TO&*tY7Yiv)mZ|Z25lI!U3*N9U;pH%W5nx*k3eBJ)#L43DF2`}?|t_w1^ z1={_JeLN2&-s0k+KWW{sZVbDb zx_)cyLMjf>Y%(;zuS@Y{`7AQj%iM8YN7~OL!Fyor&n~-)07kJ!SH*foU6yb8ZC7-g z)_xZYVlcE?`#!nrkZh$w=fe>t!P|P8FQa1qG4C~JOQQd(+s$t#R6_4Q_VbbB@!a@V zuU8NBcIv!w`=sFO>d5ZYdg+jC%H8G> za{XFDMgQBZN-^3qrtD$E1CsA5(%IQE!VHBke|N0=@gss$WTA|)GJeG|UB(kTv$ubj ze-?4^IBQFs>*K(xd#Z&wD!*^(&J1g^x^GG7&&;RiWQy8{*jh#McFR~bre|ADHx!-^ zs$Y!X+gDZh{PI)N_?Z3K6JE5)mo<#j%dF!#?k}IniAyT=+(G0Kd!`S8xRpT3vueQ+gmh)9q7^9@OryHo=2^g%~w8b)KlsmcflCGLUW#{d? zX>{fUwNyEO(avn%w%Swv8SYx)?`h}rYQjX4d*go$tr)R8u5vzRz15ljlEsbY=P!pJ z70)VD)ULYGEa&{znl{Ahth8|KwErdb_o-2gu2&CU93rL{-mepSPRH@f>WP=`Tb=G4 zdTG0EuMEf6Sb+>duTbq!WyaA>uk_jYbyE(jyia)QVHs_g-rQx`F5OCZ>$uB76RP8s z^mn)6%Qnwl^`(ycRJp6cPkCzV1qOwEC#RDAde?Tx+vIUlN`t2qX-Ne+i+v56Rln+$ z#1aoi#r>LDt)}9$;_TGUDLwJKPkQ?$7&xuYjqLkg)h74;b>Ph>SyMy%_}RFEvn=)w zuY0gyU@SJdF|+siH&dnbLZ8iCCmGm3?ctM-+Y!o}Y_`aE{{wyY<8{|Q_7W|X2fyQf zh=oTxs)#kVMfmgAF;PR(XpEPlHvf@z3fr-!ginmu|KaSuChi%heQrBW_|Y47OKe$j z*tgX{{C2$2mE}fCdn}KO6a%vw&lZU4*gqf0N0A3ZdET2S!%gsOUdV=-@ou zSR>Z4`9aOK!!6q+bQ8`wJriJBc_})dJ+1u?g*zJEeX054|qjo3Y zrTILooAtQQ;NkS=t6C2=8P$h7*U?2uXl?* zFbbn(l-I=l-e=CJeV}iyQmrPD<)p#0-q0|?Be3D#?X-1tewq103XJh%7f$}HZ86Gro;oPHDTT>PJnxOu zzLOmffBNWL$~|#!qwl_Ft)~kj<>bSK&hV{HFL}I~^(>>1cjtUH_b+AfXhS#q^6QPf z&69db&h8H$UdUki(y10X8~0%|tCmnk*>v72fh7O_vNi>O%jEO5FZaL7zgVH{*6-#( zgWu`gPK$+$ z>pNg8LNqTk$;FK$<*eER1tH%Slfv)6IbAPUSFusucBjkTMP9CxQ-hNXDvfVcdZH%f z%!*m)suWrtm z6YJ{I+MRDT8y=+Nt9CKya0-i5pT8{`bX zp>}npa>KyLwBf?Ehxv0Ep<&vOAdlZZnxY+Ed$z2(yD?Lk{pi0rf9Y*Ee!8SCXpW>5 zl-P*QDv3`H&^Z4~4;f%*sxoZr78gt!7|jabLp6UMzDaJP{#2rUS1zr@FwBN|w3+u> z_;yV_9`S@Ig=PH=5-kaAonLFtMtm+fBb3!H7f;~dFwVM0sBQfTu@;ptIM-YCCaY&PQO#_d1ut>x_>%{jH(mD1|> zM&0pAiHaU`w3zrZc85dhu^hJsJ;g>oFh!ILhl}_7`#GG5 zm9!Gs;S#T494l!|JKwkCWswl$VDBpX=Ka(1rBC|(>lpv-uoBQ1+#h>!^tNVB;_qdQ zcJJQIFNWsbW@O4wtBZTc?Dy>C<4Jdq=v_Ceb9S@~OAqArYqe0s{dQ-*GtBiix;3*AgA7lHYGR}>A*xbJ7{$HK2RHn<>zM|HBhD;hX!KbumU(22k zT7Dhhvvqx-*P%kM#kr}^f)m1)^*2?y5AEH-qqIwJBEB$@wK6G_W$%YLQCjz1b>Sbz zk$q;bJ-3gD7kpoJm+z@mbN-W<`BTPixdFwinasWIYx4}}Hau+i4J;imv9;07bY)nh zVD82+vi{ggPjRMGSw+9EGV+Ggq%+NS1xp_xdfTGcZN-+G&ZeJi=L@%E$rt2y zeWdoQDPOs2t*mv=(a#SQWuKmF-z&bXPH+D7?Z?-X5QZo7C@^M}$)V_o*2 z!M}~gY!0U#ad$ai5PFwZC#!q=WY(Nt^(&*T8&ctTT((`h@CIiC@zG2WQ6@Bme*a delta 206058 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

A8+oH?p?eg@HzvPY40F!B|HR5cl+vnD9x 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

*3MYTh8o8BWc0 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 DZb2U{ diff --git a/src/bin/pgaftest/test_runner.c b/src/bin/pgaftest/test_runner.c index b524ef7c2..f3635289d 100644 --- a/src/bin/pgaftest/test_runner.c +++ b/src/bin/pgaftest/test_runner.c @@ -183,12 +183,16 @@ runner_compose_generate(TestRunner *r) if (!compose_gen_write_monitor_ini(&r->spec->cluster, r->workDir)) return false; - for (int i = 0; i < r->spec->cluster.nodeCount; i++) + for (int fi = 0; fi < r->spec->cluster.formationCount; fi++) { - if (!compose_gen_write_node_ini(&r->spec->cluster, - &r->spec->cluster.nodes[i], - r->workDir)) - return false; + const TestFormation *form = &r->spec->cluster.formations[fi]; + + for (int ni = 0; ni < form->nodeCount; ni++) + { + if (!compose_gen_write_node_ini(&r->spec->cluster, form, + &form->nodes[ni], r->workDir)) + return false; + } } return true; @@ -210,6 +214,51 @@ runner_compose_up(TestRunner *r) return true; } +/* + * runner_apply_formation_settings — apply cluster-level formation settings + * that cannot be expressed in the node ini files. + * + * Called once after `docker compose up` and the monitor healthcheck passes. + * Currently applies: + * - number-sync-standbys (when numSync >= 0 in the cluster spec) + * + * We use `docker compose exec` so the call goes through the monitor's own + * pg_autoctl binary and lands on the already-running monitor instance. + */ +static bool +runner_apply_formation_settings(TestRunner *r) +{ + const TestCluster *c = &r->spec->cluster; + bool ok = true; + + for (int fi = 0; fi < c->formationCount; fi++) + { + const TestFormation *form = &c->formations[fi]; + + if (form->numSync < 0) + continue; + + log_info("Setting formation \"%s\" number-sync-standbys = %d", + form->name, form->numSync); + + int rc = run_cmd( + "docker compose -p %s -f %s exec monitor " + "pg_autoctl set formation number-sync-standbys %d " + "--pgdata /var/lib/postgres/pgaf --formation %s 2>&1", + r->projectName, r->composeFile, + form->numSync, form->name); + + if (rc != 0) + { + log_error("Failed to set number-sync-standbys for formation " + "\"%s\" (exit %d)", form->name, rc); + ok = false; + } + } + + return ok; +} + static bool runner_compose_down(TestRunner *r) { @@ -530,6 +579,12 @@ runner_run(TestSpec *spec, const char *workDir) if (!runner_compose_up(&r)) return false; + if (!runner_apply_formation_settings(&r)) + { + runner_compose_down(&r); + return false; + } + tap_plan(&r); /* setup{} */ @@ -595,6 +650,12 @@ runner_setup(TestSpec *spec, const char *workDir, bool withTmux) if (!runner_compose_up(&r)) return false; + if (!runner_apply_formation_settings(&r)) + { + runner_compose_down(&r); + return false; + } + /* run setup{} block */ if (spec->setup) { diff --git a/src/bin/pgaftest/test_spec.h b/src/bin/pgaftest/test_spec.h index 2705785b9..433c621e9 100644 --- a/src/bin/pgaftest/test_spec.h +++ b/src/bin/pgaftest/test_spec.h @@ -12,13 +12,42 @@ #include #include "pgsetup.h" /* PgInstanceKind */ -#define PGAF_MAX_NODES 32 -#define PGAF_MAX_STEPS 256 -#define PGAF_MAX_SEQ 256 +#define PGAF_MAX_NODES 32 +#define PGAF_MAX_FORMATIONS 16 +#define PGAF_MAX_STEPS 256 +#define PGAF_MAX_SEQ 256 #define PGAF_TIMEOUT_DEFAULT 90 /* ----------------------------------------------------------------------- * Cluster topology (from the cluster { } block) + * + * Hierarchy: cluster → monitor + formations → nodes + * + * Syntax: + * + * cluster { + * monitor [port 15432] + * image "pg_auto_failover:pg17" # optional; default: build from src + * ssl self-signed # optional; default: self-signed + * auth trust # optional; default: trust + * + * formation [name] [num-sync N] { + * node1 + * node2 + * node3 async candidate-priority 0 + * coord coordinator + * w1 worker group 1 + * } + * + * # Multiple formations (Citus use case) + * formation workers num-sync 1 { + * w1 worker group 1 + * w2 worker group 1 + * } + * } + * + * When "formation" has no name it defaults to "default". + * When a formation block is omitted entirely the cluster is invalid. * ----------------------------------------------------------------------- */ typedef struct TestNode @@ -28,23 +57,30 @@ typedef struct TestNode int group; /* Citus group id; 0 = coordinator */ int candidatePriority; /* 0-100, default 50 */ bool replicationQuorum; /* participates in sync quorum */ - bool async; /* async standby */ + bool async; /* async standby (replicationQuorum = false) */ } TestNode; -typedef struct TestCluster +typedef struct TestFormation { + char name[64]; /* formation name; default "default" */ + int numSync; /* number-sync-standbys, -1 = unset */ TestNode nodes[PGAF_MAX_NODES]; - int nodeCount; - bool withMonitor; /* always true for now */ - bool withCitus; - int numSync; /* number-sync-standbys, -1 = unset */ + int nodeCount; +} TestFormation; + +typedef struct TestCluster +{ + TestFormation formations[PGAF_MAX_FORMATIONS]; + int formationCount; + + bool withMonitor; /* always true for now */ + bool withCitus; + int monitorHostPort; /* host-side port mapped to monitor:5432; 0 = auto */ /* cluster-level Docker / network options */ - char image[256]; /* Docker image tag; "" = build from source */ - char ssl[32]; /* self-signed | cert | off; default self-signed */ - char auth[32]; /* trust | md5 | scram; default trust */ - char formation[64]; /* formation name; default "default" */ - int monitorHostPort; /* host-side port mapped to monitor:5432; 0 = auto */ + char image[256]; /* Docker image tag; "" = build from source */ + char ssl[32]; /* self-signed | cert | off; default self-signed */ + char auth[32]; /* trust | md5 | scram; default trust */ } TestCluster; /* ----------------------------------------------------------------------- diff --git a/src/bin/pgaftest/test_spec_parse.c b/src/bin/pgaftest/test_spec_parse.c index 56565a55a..483f6fcff 100644 --- a/src/bin/pgaftest/test_spec_parse.c +++ b/src/bin/pgaftest/test_spec_parse.c @@ -284,6 +284,256 @@ static void register_step(TestSpec *spec, TestStep *step) spec->stepCount++; } +/* ----------------------------------------------------------------------- + * Cluster block mini-parser + * + * parse_node_line, parse_formation_block, and parse_cluster_block live in + * the %{ %} prologue so that bison sees them as C code, not grammar rules. + * ----------------------------------------------------------------------- */ + +static void parse_formation_block(const char **pp, TestFormation *f, + TestCluster *cl); + +/* + * parse_node_line — parse one node line inside a formation block. + * + * name [kind] [option...] + * + * Advances *pp past the line (stops at '\n' or '\0'). + */ +static void +parse_node_line(const char **pp, TestFormation *f, TestCluster *cl) +{ + const char *p = *pp; + + /* skip leading whitespace */ + while (*p == ' ' || *p == '\t') p++; + + /* empty or comment */ + if (*p == '\0' || *p == '#' || *p == '\n') { + while (*p && *p != '\n') p++; + *pp = p; + return; + } + + if (f->nodeCount >= PGAF_MAX_NODES) { + fprintf(stderr, "pgaftest: too many nodes in formation (max %d)\n", + PGAF_MAX_NODES); + exit(1); + } + + TestNode *n = &f->nodes[f->nodeCount++]; + n->kind = NODE_KIND_STANDALONE; + n->candidatePriority = 50; + n->replicationQuorum = true; + + /* first token: node name */ + char tok[64]; + int i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 63) + tok[i++] = *p++; + tok[i] = '\0'; + strlcpy(n->name, tok, sizeof(n->name)); + + /* remaining tokens on the line */ + while (*p && *p != '\n') { + while (*p == ' ' || *p == '\t') p++; + if (*p == '\0' || *p == '\n' || *p == '#') break; + + /* read next token */ + i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 63) + tok[i++] = *p++; + tok[i] = '\0'; + + if (strcmp(tok, "postgres") == 0) + n->kind = NODE_KIND_STANDALONE; + else if (strcmp(tok, "coordinator") == 0) { + n->kind = NODE_KIND_CITUS_COORDINATOR; + cl->withCitus = true; + } + else if (strcmp(tok, "worker") == 0) { + n->kind = NODE_KIND_CITUS_WORKER; + cl->withCitus = true; + } + else if (strcmp(tok, "async") == 0) + n->replicationQuorum = false; + else if (strcmp(tok, "candidate-priority") == 0) { + while (*p == ' ' || *p == '\t') p++; + n->candidatePriority = atoi(p); + while (*p && *p != ' ' && *p != '\t' && *p != '\n') p++; + } + else if (strcmp(tok, "group") == 0) { + while (*p == ' ' || *p == '\t') p++; + n->group = atoi(p); + while (*p && *p != ' ' && *p != '\t' && *p != '\n') p++; + } + /* unknown tokens silently ignored */ + } + + /* advance past newline */ + if (*p == '\n') p++; + *pp = p; +} + +/* + * parse_formation_block — parse the body of a formation { } section. + * + * *pp points to the first character after the opening '{'. + * Returns with *pp pointing past the closing '}'. + */ +static void +parse_formation_block(const char **pp, TestFormation *f, TestCluster *cl) +{ + const char *p = *pp; + + while (*p) { + /* skip whitespace */ + while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++; + if (*p == '\0') break; + + /* closing brace ends the formation */ + if (*p == '}') { p++; break; } + + /* comment */ + if (*p == '#') { + while (*p && *p != '\n') p++; + continue; + } + + /* node line */ + parse_node_line(&p, f, cl); + } + + *pp = p; +} + +/* + * parse_cluster_block — parse the body of the cluster { } block. + */ +static void +parse_cluster_block(const char *text, TestCluster *cl) +{ + const char *p = text; + + while (*p) { + /* skip whitespace */ + while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++; + if (*p == '\0') break; + + /* comment */ + if (*p == '#') { + while (*p && *p != '\n') p++; + continue; + } + + /* read the keyword / first token of the line */ + char kw[64]; + int i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 63) + kw[i++] = *p++; + kw[i] = '\0'; + + if (strcmp(kw, "monitor") == 0) { + cl->withMonitor = true; + /* optional: port N */ + const char *pp = strstr(p, "port"); + if (pp) { + pp += 4; + while (*pp == ' ' || *pp == '\t') pp++; + cl->monitorHostPort = atoi(pp); + } + while (*p && *p != '\n') p++; + } + else if (strcmp(kw, "image") == 0) { + while (*p == ' ' || *p == '\t') p++; + if (*p == '"') { + p++; + i = 0; + while (*p && *p != '"' && i < 255) cl->image[i++] = *p++; + cl->image[i] = '\0'; + if (*p == '"') p++; + } else { + i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 255) + cl->image[i++] = *p++; + cl->image[i] = '\0'; + } + while (*p && *p != '\n') p++; + } + else if (strcmp(kw, "ssl") == 0) { + while (*p == ' ' || *p == '\t') p++; + i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 31) + cl->ssl[i++] = *p++; + cl->ssl[i] = '\0'; + while (*p && *p != '\n') p++; + } + else if (strcmp(kw, "auth") == 0) { + while (*p == ' ' || *p == '\t') p++; + i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 31) + cl->auth[i++] = *p++; + cl->auth[i] = '\0'; + while (*p && *p != '\n') p++; + } + else if (strcmp(kw, "formation") == 0) { + if (cl->formationCount >= PGAF_MAX_FORMATIONS) { + fprintf(stderr, "pgaftest: too many formations (max %d)\n", + PGAF_MAX_FORMATIONS); + exit(1); + } + TestFormation *f = &cl->formations[cl->formationCount++]; + strlcpy(f->name, "default", sizeof(f->name)); + f->numSync = -1; + + /* optional: name, then formation-level options, then '{' */ + bool seen_brace = false; + while (*p && !seen_brace) { + while (*p == ' ' || *p == '\t') p++; + if (*p == '{') { + p++; + seen_brace = true; + break; + } + if (*p == '\0' || *p == '\n') break; + + /* read next token */ + char tok[64]; + i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && + *p != '{' && i < 63) + tok[i++] = *p++; + tok[i] = '\0'; + + if (strcmp(tok, "num-sync") == 0) { + while (*p == ' ' || *p == '\t') p++; + f->numSync = atoi(p); + while (*p && *p != ' ' && *p != '\t' && *p != '\n') p++; + } + else if (tok[0] != '\0') { + /* treat as formation name */ + strlcpy(f->name, tok, sizeof(f->name)); + } + } + + if (!seen_brace) { + /* skip to '{' which may be on a following line */ + while (*p && *p != '{') p++; + if (*p == '{') p++; + } + + parse_formation_block(&p, f, cl); + } + else { + /* unknown keyword — skip to end of line */ + while (*p && *p != '\n') p++; + } + + if (*p == '\n') p++; + } +} + /* Enabling traces. */ @@ -306,7 +556,7 @@ static void register_step(TestSpec *spec, TestStep *step) #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 148 "test_spec_parse.y" +#line 398 "test_spec_parse.y" { int ival; char *str; @@ -314,7 +564,7 @@ typedef union YYSTYPE TestCmd *cmd; } /* Line 193 of yacc.c. */ -#line 318 "test_spec_parse.c" +#line 568 "test_spec_parse.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -327,7 +577,7 @@ typedef union YYSTYPE /* Line 216 of yacc.c. */ -#line 331 "test_spec_parse.c" +#line 581 "test_spec_parse.c" #ifdef short # undef short @@ -616,8 +866,8 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 171, 171, 172, 176, 177, 178, 179, 180, 188, - 309, 316, 327, 337, 458, 461, 463, 482, 483 + 0, 421, 421, 422, 426, 427, 428, 429, 430, 442, + 462, 469, 480, 490, 611, 614, 616, 635, 636 }; #endif @@ -1539,138 +1789,37 @@ yyparse () switch (yyn) { case 9: -#line 189 "test_spec_parse.y" +#line 443 "test_spec_parse.y" { - /* - * Re-parse the block text as a mini node-list. - * We do this with a simple line-by-line parser here rather than - * a recursive grammar to keep things simple. - */ - char *text = (yyvsp[(2) - (2)].str); - char *line = strtok(text, "\n"); - TestCluster *cl = ¤t_spec->cluster; - cl->withMonitor = true; - cl->numSync = -1; - /* cluster-level defaults */ - strlcpy(cl->ssl, "self-signed", sizeof(cl->ssl)); - strlcpy(cl->auth, "trust", sizeof(cl->auth)); - strlcpy(cl->formation, "default", sizeof(cl->formation)); - cl->monitorHostPort = 0; /* 0 = auto-assigned by runner */ - - while (line) - { - /* skip leading whitespace and comment lines */ - while (*line == ' ' || *line == '\t') line++; - if (*line == '#' || *line == '\0') { line = strtok(NULL, "\n"); continue; } - - if (strncmp(line, "image", 5) == 0) - { - /* image "pg_auto_failover:pg17" or image pg_auto_failover:pg17 */ - char val[256] = { 0 }; - const char *p = line + 5; - while (*p == ' ' || *p == '\t') p++; - if (*p == '"') - sscanf(p, "\"%255[^\"]\"", val); - else - sscanf(p, "%255s", val); - strlcpy(cl->image, val, sizeof(cl->image)); - } - else if (strncmp(line, "ssl", 3) == 0) - { - char val[32] = { 0 }; - sscanf(line + 3, " %31s", val); - strlcpy(cl->ssl, val, sizeof(cl->ssl)); - } - else if (strncmp(line, "auth", 4) == 0) - { - char val[32] = { 0 }; - sscanf(line + 4, " %31s", val); - strlcpy(cl->auth, val, sizeof(cl->auth)); - } - else if (strncmp(line, "formation", 9) == 0) - { - char val[64] = { 0 }; - const char *p = line + 9; - while (*p == ' ' || *p == '\t') p++; - if (*p == '"') - sscanf(p, "\"%63[^\"]\"", val); - else - sscanf(p, "%63s", val); - strlcpy(cl->formation, val, sizeof(cl->formation)); - } - else if (strncmp(line, "num-sync", 8) == 0) - { - sscanf(line + 8, " %d", &cl->numSync); - } - else if (strncmp(line, "monitor", 7) == 0) - { - cl->withMonitor = true; - /* optional: monitor [port 15432] */ - char *pp = strstr(line, "port"); - if (pp) cl->monitorHostPort = atoi(pp + 4); - } - else if (strncmp(line, "citus-coordinator", 17) == 0) - { - TestNode *n = &cl->nodes[cl->nodeCount++]; - sscanf(line + 18, "%63s", n->name); - n->kind = NODE_KIND_CITUS_COORDINATOR; - n->group = 0; - n->candidatePriority = 50; - n->replicationQuorum = true; - cl->withCitus = true; - } - else if (strncmp(line, "citus-worker", 12) == 0) - { - TestNode *n = &cl->nodes[cl->nodeCount++]; - char rest[256]; - sscanf(line + 13, "%63s %255[^\n]", n->name, rest); - n->kind = NODE_KIND_CITUS_WORKER; - n->candidatePriority = 50; - n->replicationQuorum = true; - char *gp = strstr(rest, "group="); - if (gp) n->group = atoi(gp + 6); - cl->withCitus = true; - } - else if (strncmp(line, "node", 4) == 0) - { - TestNode *n = &cl->nodes[cl->nodeCount++]; - n->kind = NODE_KIND_STANDALONE; - n->candidatePriority = 50; - n->replicationQuorum = true; - - char rest[256] = { 0 }; - sscanf(line + 5, "%63s %255[^\n]", n->name, rest); - char *cp = strstr(rest, "candidate-priority="); - if (cp) n->candidatePriority = atoi(cp + 19); - - if (strstr(rest, "async")) - n->replicationQuorum = false; - } + /* cluster-level defaults */ + cl->withMonitor = true; + strlcpy(cl->ssl, "self-signed", sizeof(cl->ssl)); + strlcpy(cl->auth, "trust", sizeof(cl->auth)); + cl->monitorHostPort = 0; - line = strtok(NULL, "\n"); - } + parse_cluster_block((yyvsp[(2) - (2)].str), cl); free((yyvsp[(2) - (2)].str)); ;} break; case 10: -#line 310 "test_spec_parse.y" +#line 463 "test_spec_parse.y" { current_spec->setup = (yyvsp[(2) - (2)].step); ;} break; case 11: -#line 317 "test_spec_parse.y" +#line 470 "test_spec_parse.y" { current_spec->teardown = (yyvsp[(2) - (2)].step); ;} break; case 12: -#line 328 "test_spec_parse.y" +#line 481 "test_spec_parse.y" { TestStep *s = (yyvsp[(3) - (3)].step); strncpy(s->name, (yyvsp[(2) - (3)].str), sizeof(s->name) - 1); @@ -1680,7 +1829,7 @@ yyparse () break; case 13: -#line 338 "test_spec_parse.y" +#line 491 "test_spec_parse.y" { /* * Parse the block text into a linked list of TestCmd. @@ -1797,7 +1946,7 @@ yyparse () break; case 16: -#line 464 "test_spec_parse.y" +#line 617 "test_spec_parse.y" { int i = current_spec->sequenceLength; if (i < PGAF_MAX_SEQ) @@ -1812,18 +1961,18 @@ yyparse () break; case 17: -#line 482 "test_spec_parse.y" +#line 635 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; case 18: -#line 483 "test_spec_parse.y" +#line 636 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; /* Line 1267 of yacc.c. */ -#line 1827 "test_spec_parse.c" +#line 1976 "test_spec_parse.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2037,7 +2186,7 @@ yyparse () } -#line 486 "test_spec_parse.y" +#line 639 "test_spec_parse.y" /* ----------------------------------------------------------------------- @@ -2059,7 +2208,6 @@ parse_test_spec(const char *filename) if (!spec) { fprintf(stderr, "out of memory\n"); exit(1); } strncpy(spec->filename, filename, sizeof(spec->filename)-1); - spec->cluster.numSync = -1; current_spec = spec; pgaf_line_number = 1; diff --git a/src/bin/pgaftest/test_spec_parse.h b/src/bin/pgaftest/test_spec_parse.h index 739fbb4d6..cacc207fc 100644 --- a/src/bin/pgaftest/test_spec_parse.h +++ b/src/bin/pgaftest/test_spec_parse.h @@ -112,7 +112,7 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 148 "test_spec_parse.y" +#line 398 "test_spec_parse.y" { int ival; char *str; diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y index 52e358da4..453d3fbcd 100644 --- a/src/bin/pgaftest/test_spec_parse.y +++ b/src/bin/pgaftest/test_spec_parse.y @@ -143,6 +143,256 @@ static void register_step(TestSpec *spec, TestStep *step) spec->stepCount++; } +/* ----------------------------------------------------------------------- + * Cluster block mini-parser + * + * parse_node_line, parse_formation_block, and parse_cluster_block live in + * the %{ %} prologue so that bison sees them as C code, not grammar rules. + * ----------------------------------------------------------------------- */ + +static void parse_formation_block(const char **pp, TestFormation *f, + TestCluster *cl); + +/* + * parse_node_line — parse one node line inside a formation block. + * + * name [kind] [option...] + * + * Advances *pp past the line (stops at '\n' or '\0'). + */ +static void +parse_node_line(const char **pp, TestFormation *f, TestCluster *cl) +{ + const char *p = *pp; + + /* skip leading whitespace */ + while (*p == ' ' || *p == '\t') p++; + + /* empty or comment */ + if (*p == '\0' || *p == '#' || *p == '\n') { + while (*p && *p != '\n') p++; + *pp = p; + return; + } + + if (f->nodeCount >= PGAF_MAX_NODES) { + fprintf(stderr, "pgaftest: too many nodes in formation (max %d)\n", + PGAF_MAX_NODES); + exit(1); + } + + TestNode *n = &f->nodes[f->nodeCount++]; + n->kind = NODE_KIND_STANDALONE; + n->candidatePriority = 50; + n->replicationQuorum = true; + + /* first token: node name */ + char tok[64]; + int i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 63) + tok[i++] = *p++; + tok[i] = '\0'; + strlcpy(n->name, tok, sizeof(n->name)); + + /* remaining tokens on the line */ + while (*p && *p != '\n') { + while (*p == ' ' || *p == '\t') p++; + if (*p == '\0' || *p == '\n' || *p == '#') break; + + /* read next token */ + i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 63) + tok[i++] = *p++; + tok[i] = '\0'; + + if (strcmp(tok, "postgres") == 0) + n->kind = NODE_KIND_STANDALONE; + else if (strcmp(tok, "coordinator") == 0) { + n->kind = NODE_KIND_CITUS_COORDINATOR; + cl->withCitus = true; + } + else if (strcmp(tok, "worker") == 0) { + n->kind = NODE_KIND_CITUS_WORKER; + cl->withCitus = true; + } + else if (strcmp(tok, "async") == 0) + n->replicationQuorum = false; + else if (strcmp(tok, "candidate-priority") == 0) { + while (*p == ' ' || *p == '\t') p++; + n->candidatePriority = atoi(p); + while (*p && *p != ' ' && *p != '\t' && *p != '\n') p++; + } + else if (strcmp(tok, "group") == 0) { + while (*p == ' ' || *p == '\t') p++; + n->group = atoi(p); + while (*p && *p != ' ' && *p != '\t' && *p != '\n') p++; + } + /* unknown tokens silently ignored */ + } + + /* advance past newline */ + if (*p == '\n') p++; + *pp = p; +} + +/* + * parse_formation_block — parse the body of a formation { } section. + * + * *pp points to the first character after the opening '{'. + * Returns with *pp pointing past the closing '}'. + */ +static void +parse_formation_block(const char **pp, TestFormation *f, TestCluster *cl) +{ + const char *p = *pp; + + while (*p) { + /* skip whitespace */ + while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++; + if (*p == '\0') break; + + /* closing brace ends the formation */ + if (*p == '}') { p++; break; } + + /* comment */ + if (*p == '#') { + while (*p && *p != '\n') p++; + continue; + } + + /* node line */ + parse_node_line(&p, f, cl); + } + + *pp = p; +} + +/* + * parse_cluster_block — parse the body of the cluster { } block. + */ +static void +parse_cluster_block(const char *text, TestCluster *cl) +{ + const char *p = text; + + while (*p) { + /* skip whitespace */ + while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++; + if (*p == '\0') break; + + /* comment */ + if (*p == '#') { + while (*p && *p != '\n') p++; + continue; + } + + /* read the keyword / first token of the line */ + char kw[64]; + int i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 63) + kw[i++] = *p++; + kw[i] = '\0'; + + if (strcmp(kw, "monitor") == 0) { + cl->withMonitor = true; + /* optional: port N */ + const char *pp = strstr(p, "port"); + if (pp) { + pp += 4; + while (*pp == ' ' || *pp == '\t') pp++; + cl->monitorHostPort = atoi(pp); + } + while (*p && *p != '\n') p++; + } + else if (strcmp(kw, "image") == 0) { + while (*p == ' ' || *p == '\t') p++; + if (*p == '"') { + p++; + i = 0; + while (*p && *p != '"' && i < 255) cl->image[i++] = *p++; + cl->image[i] = '\0'; + if (*p == '"') p++; + } else { + i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 255) + cl->image[i++] = *p++; + cl->image[i] = '\0'; + } + while (*p && *p != '\n') p++; + } + else if (strcmp(kw, "ssl") == 0) { + while (*p == ' ' || *p == '\t') p++; + i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 31) + cl->ssl[i++] = *p++; + cl->ssl[i] = '\0'; + while (*p && *p != '\n') p++; + } + else if (strcmp(kw, "auth") == 0) { + while (*p == ' ' || *p == '\t') p++; + i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 31) + cl->auth[i++] = *p++; + cl->auth[i] = '\0'; + while (*p && *p != '\n') p++; + } + else if (strcmp(kw, "formation") == 0) { + if (cl->formationCount >= PGAF_MAX_FORMATIONS) { + fprintf(stderr, "pgaftest: too many formations (max %d)\n", + PGAF_MAX_FORMATIONS); + exit(1); + } + TestFormation *f = &cl->formations[cl->formationCount++]; + strlcpy(f->name, "default", sizeof(f->name)); + f->numSync = -1; + + /* optional: name, then formation-level options, then '{' */ + bool seen_brace = false; + while (*p && !seen_brace) { + while (*p == ' ' || *p == '\t') p++; + if (*p == '{') { + p++; + seen_brace = true; + break; + } + if (*p == '\0' || *p == '\n') break; + + /* read next token */ + char tok[64]; + i = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && + *p != '{' && i < 63) + tok[i++] = *p++; + tok[i] = '\0'; + + if (strcmp(tok, "num-sync") == 0) { + while (*p == ' ' || *p == '\t') p++; + f->numSync = atoi(p); + while (*p && *p != ' ' && *p != '\t' && *p != '\n') p++; + } + else if (tok[0] != '\0') { + /* treat as formation name */ + strlcpy(f->name, tok, sizeof(f->name)); + } + } + + if (!seen_brace) { + /* skip to '{' which may be on a following line */ + while (*p && *p != '{') p++; + if (*p == '{') p++; + } + + parse_formation_block(&p, f, cl); + } + else { + /* unknown keyword — skip to end of line */ + while (*p && *p != '\n') p++; + } + + if (*p == '\n') p++; + } +} + %} %union { @@ -182,121 +432,24 @@ spec_item: /* ----------------------------------------------------------------------- * cluster { } + * + * The T_BLOCK token contains the raw text between the outer braces, + * with nested { } blocks preserved verbatim (the lexer counts depth). + * We re-parse it with parse_cluster_block() defined in the %{ %} prologue. * ----------------------------------------------------------------------- */ cluster_block: T_CLUSTER T_BLOCK { - /* - * Re-parse the block text as a mini node-list. - * We do this with a simple line-by-line parser here rather than - * a recursive grammar to keep things simple. - */ - char *text = $2; - char *line = strtok(text, "\n"); - TestCluster *cl = ¤t_spec->cluster; - cl->withMonitor = true; - cl->numSync = -1; - /* cluster-level defaults */ - strlcpy(cl->ssl, "self-signed", sizeof(cl->ssl)); - strlcpy(cl->auth, "trust", sizeof(cl->auth)); - strlcpy(cl->formation, "default", sizeof(cl->formation)); - cl->monitorHostPort = 0; /* 0 = auto-assigned by runner */ - - while (line) - { - /* skip leading whitespace and comment lines */ - while (*line == ' ' || *line == '\t') line++; - if (*line == '#' || *line == '\0') { line = strtok(NULL, "\n"); continue; } - - if (strncmp(line, "image", 5) == 0) - { - /* image "pg_auto_failover:pg17" or image pg_auto_failover:pg17 */ - char val[256] = { 0 }; - const char *p = line + 5; - while (*p == ' ' || *p == '\t') p++; - if (*p == '"') - sscanf(p, "\"%255[^\"]\"", val); - else - sscanf(p, "%255s", val); - strlcpy(cl->image, val, sizeof(cl->image)); - } - else if (strncmp(line, "ssl", 3) == 0) - { - char val[32] = { 0 }; - sscanf(line + 3, " %31s", val); - strlcpy(cl->ssl, val, sizeof(cl->ssl)); - } - else if (strncmp(line, "auth", 4) == 0) - { - char val[32] = { 0 }; - sscanf(line + 4, " %31s", val); - strlcpy(cl->auth, val, sizeof(cl->auth)); - } - else if (strncmp(line, "formation", 9) == 0) - { - char val[64] = { 0 }; - const char *p = line + 9; - while (*p == ' ' || *p == '\t') p++; - if (*p == '"') - sscanf(p, "\"%63[^\"]\"", val); - else - sscanf(p, "%63s", val); - strlcpy(cl->formation, val, sizeof(cl->formation)); - } - else if (strncmp(line, "num-sync", 8) == 0) - { - sscanf(line + 8, " %d", &cl->numSync); - } - else if (strncmp(line, "monitor", 7) == 0) - { - cl->withMonitor = true; - /* optional: monitor [port 15432] */ - char *pp = strstr(line, "port"); - if (pp) cl->monitorHostPort = atoi(pp + 4); - } - else if (strncmp(line, "citus-coordinator", 17) == 0) - { - TestNode *n = &cl->nodes[cl->nodeCount++]; - sscanf(line + 18, "%63s", n->name); - n->kind = NODE_KIND_CITUS_COORDINATOR; - n->group = 0; - n->candidatePriority = 50; - n->replicationQuorum = true; - cl->withCitus = true; - } - else if (strncmp(line, "citus-worker", 12) == 0) - { - TestNode *n = &cl->nodes[cl->nodeCount++]; - char rest[256]; - sscanf(line + 13, "%63s %255[^\n]", n->name, rest); - n->kind = NODE_KIND_CITUS_WORKER; - n->candidatePriority = 50; - n->replicationQuorum = true; - char *gp = strstr(rest, "group="); - if (gp) n->group = atoi(gp + 6); - cl->withCitus = true; - } - else if (strncmp(line, "node", 4) == 0) - { - TestNode *n = &cl->nodes[cl->nodeCount++]; - n->kind = NODE_KIND_STANDALONE; - n->candidatePriority = 50; - n->replicationQuorum = true; - - char rest[256] = { 0 }; - sscanf(line + 5, "%63s %255[^\n]", n->name, rest); - char *cp = strstr(rest, "candidate-priority="); - if (cp) n->candidatePriority = atoi(cp + 19); - - if (strstr(rest, "async")) - n->replicationQuorum = false; - } + /* cluster-level defaults */ + cl->withMonitor = true; + strlcpy(cl->ssl, "self-signed", sizeof(cl->ssl)); + strlcpy(cl->auth, "trust", sizeof(cl->auth)); + cl->monitorHostPort = 0; - line = strtok(NULL, "\n"); - } + parse_cluster_block($2, cl); free($2); } ; @@ -504,7 +657,6 @@ parse_test_spec(const char *filename) if (!spec) { fprintf(stderr, "out of memory\n"); exit(1); } strncpy(spec->filename, filename, sizeof(spec->filename)-1); - spec->cluster.numSync = -1; current_spec = spec; pgaf_line_number = 1; From 8cff38896c6e78f40f4c0896462bfb8a436e38cc Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 22:15:42 +0200 Subject: [PATCH 13/48] pgaftest: update all .pgaf specs to formation{} syntax; extend node DSL; multi-row expect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix collect_block_content() to use depth-aware brace matching so inline blocks like { { 1 } { 2 } } find the correct closing brace instead of the first } encountered. - Add expand_tuple_expect(): converts inline tuple format '{ r1 } { r2 }' to the newline-separated form that psql --tuples-only --no-align produces (called after collect_block_content for every expect command). - Extend TestNode with new create-time fields: noMonitor, listen, citusSecondary, citusClusterName, pgPort, debianCluster, ssl (node-level override), auth (node-level override). - Extend parse_node_line() to handle all new node options including both 'key value' and 'key=value' forms (candidate-priority, group, port, citus-cluster-name, debian-cluster, ssl, auth-method, etc.) and replication-quorum=false as a synonym for async. - Extend parse_cluster_block() monitor handler to parse inline options (port, ssl, auth-method) in both 'key value' and 'key=value' forms. - Update compose_gen_write_node_ini() to emit the new TestNode fields: per-node port, debian_cluster, no-monitor (omits [monitor] section), citus_secondary, citus_cluster_name, listen option. - compose_gen_write(): make monitor service conditional on withMonitor; skip depends_on: monitor when cluster has no monitor; skip monitor_data volume when withMonitor is false. - Convert all 25 .pgaf spec files that used the old flat node/ citus-coordinator/citus-worker lines to the new: formation [name] [num-sync N] { ... } hierarchy. Conversions preserve all semantics: * auth → cluster-level 'auth' directive * ssl → cluster-level 'ssl' directive * citus-coordinator X → X coordinator * citus-worker X group=N → X worker group N * replication-quorum=false → async * candidate-priority=N → candidate-priority N * formation=NAME → separate formation NAME { } block - Update docs/pgaftest.rst: document new node options, monitor inline options, and all three expect forms (single, multi-line, inline tuple). --- docs/pgaftest.rst | 37 ++- src/bin/pgaftest/compose_gen.c | 118 ++++--- src/bin/pgaftest/pgaftest | Bin 798376 -> 798424 bytes src/bin/pgaftest/test_spec.h | 10 + src/bin/pgaftest/test_spec_parse.c | 309 ++++++++++++++---- src/bin/pgaftest/test_spec_parse.h | 2 +- src/bin/pgaftest/test_spec_parse.y | 279 +++++++++++++--- tests/tap/specs/auth.pgaf | 9 +- tests/tap/specs/basic_citus_operation.pgaf | 14 +- tests/tap/specs/basic_operation.pgaf | 6 +- .../specs/basic_operation_listen_flag.pgaf | 6 +- tests/tap/specs/citus_cluster_name.pgaf | 14 +- tests/tap/specs/citus_force_failover.pgaf | 14 +- tests/tap/specs/citus_multi_standbys.pgaf | 20 +- tests/tap/specs/citus_skip_pg_hba.pgaf | 13 +- tests/tap/specs/config_get_set.pgaf | 4 +- tests/tap/specs/create_run.pgaf | 6 +- .../tap/specs/create_standby_with_pgdata.pgaf | 6 +- tests/tap/specs/debian_clusters.pgaf | 6 +- tests/tap/specs/enable_ssl.pgaf | 6 +- tests/tap/specs/ensure.pgaf | 6 +- tests/tap/specs/monitor_disabled.pgaf | 8 +- tests/tap/specs/multi_alternate.pgaf | 8 +- tests/tap/specs/multi_async.pgaf | 10 +- tests/tap/specs/multi_ifdown.pgaf | 8 +- tests/tap/specs/multi_maintenance.pgaf | 10 +- tests/tap/specs/multi_standbys.pgaf | 10 +- tests/tap/specs/nonha_citus_operation.pgaf | 14 +- tests/tap/specs/replace_monitor.pgaf | 6 +- tests/tap/specs/skip_pg_hba.pgaf | 9 +- tests/tap/specs/ssl_cert.pgaf | 9 +- tests/tap/specs/ssl_self_signed.pgaf | 9 +- 32 files changed, 743 insertions(+), 243 deletions(-) diff --git a/docs/pgaftest.rst b/docs/pgaftest.rst index 2a4417c59..2366281e3 100644 --- a/docs/pgaftest.rst +++ b/docs/pgaftest.rst @@ -141,8 +141,19 @@ Options: * ``async`` — makes this node asynchronous (``replication_quorum = false``) * ``candidate-priority N`` — integer 0–100; default 50. ``0`` prevents this - node from ever being elected primary. -* ``group N`` — Citus group id (required for ``worker`` kind) + node from ever being elected primary. Can also be written ``candidate-priority=N``. +* ``replication-quorum false`` — same as ``async``; can also be + written ``replication-quorum=false``. +* ``group N`` — Citus group id (required for ``worker`` kind). + Can also be written ``group=N``. +* ``no-monitor`` — standalone node: does not register with a monitor. +* ``listen`` — bind Postgres to all interfaces (``0.0.0.0``). +* ``citus-secondary`` — marks this node as a Citus secondary. +* ``citus-cluster-name NAME`` — sets the Citus cluster name. +* ``port N`` — override the default Postgres port (5432). +* ``debian-cluster NAME`` — Debian-style Postgres cluster name. +* ``ssl MODE`` — per-node SSL mode override (overrides the cluster-level ``ssl``). +* ``auth-method METHOD`` — per-node auth method override. **Examples** @@ -328,13 +339,33 @@ multi-line ``{ ... }`` block for multi-statement SQL. ~~~~~~~~~~~~~~~~~~~~ Compare the output of the most recent ``sql`` command against ``text``. -Fails the step when the output does not match. Whitespace is normalised. +Fails the step when the output does not match. + +Single-value form: .. code-block:: text sql node2 { SELECT count(*) FROM t1; } expect { 3 } +Multi-line form (matches ``psql --tuples-only --no-align`` output, one row per line): + +.. code-block:: text + + sql node1 { SELECT a, b FROM t ORDER BY a; } + expect { + 1 hello + 2 world + } + +Inline tuple form — each ``{ value }`` group corresponds to one output row. +This is equivalent to the multi-line form above. + +.. code-block:: text + + sql node1 { SELECT count(*) FROM t GROUP BY status; } + expect { { 2 } { 5 } } + ``network disconnect `` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/bin/pgaftest/compose_gen.c b/src/bin/pgaftest/compose_gen.c index 2b960fe91..ca973dc12 100644 --- a/src/bin/pgaftest/compose_gen.c +++ b/src/bin/pgaftest/compose_gen.c @@ -102,27 +102,30 @@ compose_gen_write(const TestCluster *cluster, fprintf(f, "# Project: %s\n\n", projectName); fprintf(f, "services:\n"); - /* ---- monitor ---- */ - fprintf(f, " monitor:\n"); - write_image_stanza(f, cluster, contextDir); - fprintf(f, - " hostname: monitor\n" - " volumes:\n" - " - monitor_data:/var/lib/postgres:rw\n" - " - ./monitor.ini:" NODE_INI_PATH ":ro\n" - " environment:\n" - " PGDATA: " NODE_PGDATA "\n" - " ports:\n" - " - \"127.0.0.1:%d:5432\"\n" - " healthcheck:\n" - " test: [\"CMD-SHELL\"," - " \"pg_isready -d pg_auto_failover -U autoctl_node\"]\n" - " interval: 5s\n" - " timeout: 5s\n" - " retries: 20\n" - " start_period: 30s\n" - " command: [\"pg_autoctl\", \"node\", \"run\", \"" NODE_INI_PATH "\"]\n\n", - monitorHostPort); + /* ---- monitor (optional) ---- */ + if (cluster->withMonitor) + { + fprintf(f, " monitor:\n"); + write_image_stanza(f, cluster, contextDir); + fprintf(f, + " hostname: monitor\n" + " volumes:\n" + " - monitor_data:/var/lib/postgres:rw\n" + " - ./monitor.ini:" NODE_INI_PATH ":ro\n" + " environment:\n" + " PGDATA: " NODE_PGDATA "\n" + " ports:\n" + " - \"127.0.0.1:%d:5432\"\n" + " healthcheck:\n" + " test: [\"CMD-SHELL\"," + " \"pg_isready -d pg_auto_failover -U autoctl_node\"]\n" + " interval: 5s\n" + " timeout: 5s\n" + " retries: 20\n" + " start_period: 30s\n" + " command: [\"pg_autoctl\", \"node\", \"run\", \"" NODE_INI_PATH "\"]\n\n", + monitorHostPort); + } /* ---- data nodes — iterate all formations ---- */ const TestNode *firstNode = NULL; @@ -150,12 +153,14 @@ compose_gen_write(const TestCluster *cluster, " PGUSER: demo\n" " PGDATABASE: demo\n" " expose:\n" - " - 5432\n" - " depends_on:\n" - " monitor:\n" - " condition: service_healthy\n", + " - 5432\n", n->name, n->name, ini_filename); + if (cluster->withMonitor) + fprintf(f, + " depends_on:\n" + " monitor:\n" + " condition: service_healthy\n"); /* * Ensure node registration order is deterministic: the first @@ -178,7 +183,8 @@ compose_gen_write(const TestCluster *cluster, /* ---- volumes ---- */ fprintf(f, "volumes:\n"); - fprintf(f, " monitor_data:\n"); + if (cluster->withMonitor) + fprintf(f, " monitor_data:\n"); for (int fi = 0; fi < cluster->formationCount; fi++) for (int ni = 0; ni < cluster->formations[fi].nodeCount; ni++) fprintf(f, " %s_data:\n", cluster->formations[fi].nodes[ni].name); @@ -259,6 +265,12 @@ compose_gen_write_node_ini(const TestCluster *cluster, default: kindStr = "postgres"; break; } + /* Effective ssl/auth: node-level overrides cluster-level default */ + const char *eff_ssl = node->ssl[0] ? node->ssl : cluster->ssl; + const char *eff_auth = node->auth[0] ? node->auth : cluster->auth; + + int pg_port = node->pgPort > 0 ? node->pgPort : 5432; + fprintf(f, "# Generated by pgaftest — do not edit manually\n" "# Node: %s (formation: %s)\n" @@ -266,35 +278,57 @@ compose_gen_write_node_ini(const TestCluster *cluster, "[node]\n" "kind = %s\n" "hostname = %s\n" - "port = 5432\n" + "port = %d\n", + node->name, formation->name, + kindStr, + node->name, + pg_port); + + if (node->debianCluster[0]) + fprintf(f, "debian_cluster = %s\n", node->debianCluster); + + fprintf(f, "\n" "[postgresql]\n" "pgdata = " NODE_PGDATA "\n" - "\n" - "[monitor]\n" - "pguri = " MONITOR_PGURI "\n" - "\n" + "\n"); + + if (!node->noMonitor) + fprintf(f, + "[monitor]\n" + "pguri = " MONITOR_PGURI "\n" + "\n"); + + fprintf(f, "[formation]\n" "name = %s\n" "group = %d\n" "\n" "[settings]\n" "candidate_priority = %d\n" - "replication_quorum = %s\n" + "replication_quorum = %s\n", + formation->name, + node->group, + node->candidatePriority, + node->replicationQuorum ? "true" : "false"); + + if (node->citusSecondary) + fprintf(f, "citus_secondary = true\n"); + if (node->citusClusterName[0]) + fprintf(f, "citus_cluster_name = %s\n", node->citusClusterName); + + fprintf(f, "\n" "[options]\n" "ssl = %s\n" "auth = %s\n" - "pg_hba_lan = true\n", - node->name, formation->name, - kindStr, - node->name, - formation->name, - node->group, - node->candidatePriority, - node->replicationQuorum ? "true" : "false", - cluster->ssl, - cluster->auth); + "pg_hba_lan = %s\n", + eff_ssl, + eff_auth, + node->noMonitor ? "false" : "true"); + + if (node->listen) + fprintf(f, "listen = 0.0.0.0\n"); fclose(f); log_info("Wrote %s.ini to \"%s\"", node->name, path); diff --git a/src/bin/pgaftest/pgaftest b/src/bin/pgaftest/pgaftest index 3cf7e6b19f27eb5b405e057d60d7cfd78e0ff619..9f67a921fa18a3f88b668d1d3fd59f7903ccbb44 100755 GIT binary patch delta 203969 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

5ak|9*)6D>j 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 Ok8A~>0BYA#00017<%tRa delta 201817 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

4;D}?jgJZ;N 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 F001tvzlZ<; diff --git a/src/bin/pgaftest/test_spec.h b/src/bin/pgaftest/test_spec.h index 433c621e9..ebe7b1639 100644 --- a/src/bin/pgaftest/test_spec.h +++ b/src/bin/pgaftest/test_spec.h @@ -58,6 +58,16 @@ typedef struct TestNode int candidatePriority; /* 0-100, default 50 */ bool replicationQuorum; /* participates in sync quorum */ bool async; /* async standby (replicationQuorum = false) */ + + /* create-time options — passed to pg_autoctl create via [options] ini */ + bool noMonitor; /* --no-monitor: standalone node */ + bool listen; /* --listen 0.0.0.0: bind all interfaces */ + bool citusSecondary; /* --citus-secondary */ + char citusClusterName[64]; /* --citus-cluster-name NAME */ + int pgPort; /* --pg-port N (0 = default 5432) */ + char debianCluster[64]; /* --debian-cluster NAME */ + char ssl[32]; /* per-node ssl override; "" = use cluster */ + char auth[32]; /* per-node auth override; "" = use cluster */ } TestNode; typedef struct TestFormation diff --git a/src/bin/pgaftest/test_spec_parse.c b/src/bin/pgaftest/test_spec_parse.c index 483f6fcff..9d65e5a06 100644 --- a/src/bin/pgaftest/test_spec_parse.c +++ b/src/bin/pgaftest/test_spec_parse.c @@ -186,14 +186,22 @@ static void append_cmd(TestStep *step, TestCmd *cmd) } /* - * Collect content from a `{ ... }` block that may span multiple lines. + * collect_block_content — extract content from a `{ ... }` block. * - * `src` points to the `{` character (already the first char of the argument). - * For the inline case `{ content }`, the closing `}` is on the same string. - * For the multi-line case `{\n line1\n line2\n}`, subsequent lines are - * fetched with strtok(NULL, "\n") which continues the caller's split. + * src points to the opening `{`. Two forms are supported: * - * The collected content (without surrounding braces) is written into `out`. + * Inline: { content } or { { r1 } { r2 } } + * The matching closing `}` is found with depth counting (brace-aware). + * The content between the outermost `{}` is captured. + * + * Multi-line: { + * line1 + * line2 + * } + * Subsequent lines are read via strtok(NULL, "\n") until a line that + * is just `}`. + * + * The captured content (without surrounding braces) is written into out. */ static void collect_block_content(const char *src, char *out, int outlen) @@ -202,31 +210,43 @@ collect_block_content(const char *src, char *out, int outlen) src++; while (*src == ' ' || *src == '\t') src++; - /* Inline single-line: { content } — closing } on the same string */ - const char *close = strchr(src, '}'); - if (close) + /* + * Inline form: look for the MATCHING closing brace on this line, + * counting nested braces. Stop at '\n' so we fall through to the + * multi-line path when the block spans multiple lines. + */ { - int len = (int)(close - src); - /* trim trailing whitespace before } */ - while (len > 0 && (src[len-1] == ' ' || src[len-1] == '\t')) - len--; - if (len >= outlen) len = outlen - 1; - memcpy(out, src, len); - out[len] = '\0'; - return; + int depth = 1; + const char *p = src; + const char *close = NULL; + while (*p && *p != '\n') + { + if (*p == '{') depth++; + else if (*p == '}') { if (--depth == 0) { close = p; break; } } + p++; + } + if (close) + { + int len = (int)(close - src); + while (len > 0 && (src[len-1] == ' ' || src[len-1] == '\t')) + len--; + if (len >= outlen) len = outlen - 1; + memcpy(out, src, len); + out[len] = '\0'; + return; + } } /* - * Multi-line form: content starts on remaining of same line (may be empty) - * then continues on subsequent lines until a line that is just `}`. + * Multi-line form: content starts on the remainder of the current line + * (may be empty) then continues on subsequent lines until a line that + * is just `}`. */ int pos = 0; - /* remainder of current line after `{` */ if (*src) { int l = strlen(src); - /* trim trailing whitespace */ while (l > 0 && (src[l-1] == '\r' || src[l-1] == '\n' || src[l-1] == ' ' || src[l-1] == '\t')) l--; @@ -242,20 +262,16 @@ collect_block_content(const char *src, char *out, int outlen) char *nxtline; while ((nxtline = strtok(NULL, "\n")) != NULL) { - /* skip leading whitespace */ char *p = nxtline; while (*p == ' ' || *p == '\t') p++; - /* closing brace line */ if (*p == '}' && (p[1] == '\0' || p[1] == ' ' || p[1] == '\t')) break; - /* append a newline separator if we already have content */ if (pos > 0 && pos < outlen - 1) out[pos++] = '\n'; int l = strlen(p); - /* trim trailing CR/LF */ while (l > 0 && (p[l-1] == '\r' || p[l-1] == '\n')) l--; if (pos + l >= outlen) @@ -269,6 +285,74 @@ collect_block_content(const char *src, char *out, int outlen) } } +/* + * expand_tuple_expect — convert `{ r1 } { r2 }` tuple syntax into + * the newline-separated form that psql --tuples-only --no-align produces. + * + * When the expect content starts with `{ ` (brace + space, to avoid + * colliding with PostgreSQL array literals like `{1,2}`), each `{ val }` + * group is extracted and joined with '\n'. + * + * Examples: + * "{ 1 } { 2 }" → "1\n2" + * "{ node1\tprimary }" → "node1\tprimary" + * "2" → "2" (unchanged — no leading brace-space) + */ +static void +expand_tuple_expect(char *buf, int buflen) +{ + const char *p = buf; + while (*p == ' ' || *p == '\t') p++; + + /* Tuple format requires "{ " (brace followed by space/content, not "{x") */ + if (p[0] != '{' || (p[1] != ' ' && p[1] != '\t')) + return; /* not tuple format */ + + char tmp[4096] = { 0 }; + int pos = 0; + bool first = true; + + while (*p) + { + /* skip whitespace between tuples */ + while (*p == ' ' || *p == '\t' || *p == '\n') p++; + if (*p == '\0') break; + if (*p != '{') break; /* unexpected char */ + + p++; /* skip '{' */ + while (*p == ' ' || *p == '\t') p++; + + /* collect until matching '}' */ + char row[1024] = { 0 }; + int ri = 0; + int depth = 1; + while (*p && depth > 0) + { + if (*p == '{') depth++; + else if (*p == '}') { if (--depth == 0) break; } + if (depth > 0 && ri < (int)sizeof(row) - 1) + row[ri++] = *p; + p++; + } + if (*p == '}') p++; + + /* trim trailing whitespace from row */ + while (ri > 0 && (row[ri-1] == ' ' || row[ri-1] == '\t')) ri--; + row[ri] = '\0'; + + if (!first && pos < (int)sizeof(tmp) - 1) + tmp[pos++] = '\n'; + int l = ri; + if (pos + l >= (int)sizeof(tmp)) l = (int)sizeof(tmp) - pos - 1; + if (l > 0) { memcpy(tmp + pos, row, l); pos += l; } + tmp[pos] = '\0'; + first = false; + } + + if (!first) + strncpy(buf, tmp, buflen - 1); +} + static void register_step(TestSpec *spec, TestStep *step) { if (!spec->steps) @@ -299,6 +383,19 @@ static void parse_formation_block(const char **pp, TestFormation *f, * * name [kind] [option...] * + * Supported kinds: postgres (default), coordinator, worker + * Supported options: async + * candidate-priority N or candidate-priority=N + * group N or group=N + * no-monitor + * listen + * citus-secondary + * citus-cluster-name N or citus-cluster-name=NAME + * port N or port=N + * debian-cluster NAME or debian-cluster=NAME + * ssl MODE or ssl=MODE + * auth-method METHOD or auth-method=METHOD + * * Advances *pp past the line (stops at '\n' or '\0'). */ static void @@ -328,9 +425,9 @@ parse_node_line(const char **pp, TestFormation *f, TestCluster *cl) n->replicationQuorum = true; /* first token: node name */ - char tok[64]; + char tok[128]; int i = 0; - while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 63) + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 127) tok[i++] = *p++; tok[i] = '\0'; strlcpy(n->name, tok, sizeof(n->name)); @@ -340,35 +437,90 @@ parse_node_line(const char **pp, TestFormation *f, TestCluster *cl) while (*p == ' ' || *p == '\t') p++; if (*p == '\0' || *p == '\n' || *p == '#') break; - /* read next token */ + /* read next token (may be "key=value") */ i = 0; - while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 63) + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 127) tok[i++] = *p++; tok[i] = '\0'; - if (strcmp(tok, "postgres") == 0) + /* split "key=value" tokens into key + embedded value */ + char key[128], val[128]; + char *eq = strchr(tok, '='); + if (eq) { + int kl = (int)(eq - tok); + memcpy(key, tok, kl); key[kl] = '\0'; + strlcpy(val, eq + 1, sizeof(val)); + } else { + strlcpy(key, tok, sizeof(key)); + val[0] = '\0'; + } + + /* helper: read next whitespace-separated token into val */ +#define READ_VAL() do { \ + while (*p == ' ' || *p == '\t') p++; \ + int _vi = 0; \ + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && _vi < 127) \ + val[_vi++] = *p++; \ + val[_vi] = '\0'; \ +} while (0) + + if (strcmp(key, "postgres") == 0) n->kind = NODE_KIND_STANDALONE; - else if (strcmp(tok, "coordinator") == 0) { + else if (strcmp(key, "coordinator") == 0) { n->kind = NODE_KIND_CITUS_COORDINATOR; cl->withCitus = true; } - else if (strcmp(tok, "worker") == 0) { + else if (strcmp(key, "worker") == 0) { n->kind = NODE_KIND_CITUS_WORKER; cl->withCitus = true; } - else if (strcmp(tok, "async") == 0) + else if (strcmp(key, "async") == 0) n->replicationQuorum = false; - else if (strcmp(tok, "candidate-priority") == 0) { - while (*p == ' ' || *p == '\t') p++; - n->candidatePriority = atoi(p); - while (*p && *p != ' ' && *p != '\t' && *p != '\n') p++; + else if (strcmp(key, "replication-quorum") == 0) { + /* replication-quorum=false is equivalent to async */ + if (!val[0]) READ_VAL(); + if (strcmp(val, "false") == 0 || strcmp(val, "0") == 0) + n->replicationQuorum = false; + else + n->replicationQuorum = true; } - else if (strcmp(tok, "group") == 0) { - while (*p == ' ' || *p == '\t') p++; - n->group = atoi(p); - while (*p && *p != ' ' && *p != '\t' && *p != '\n') p++; + else if (strcmp(key, "no-monitor") == 0) + n->noMonitor = true; + else if (strcmp(key, "listen") == 0) + n->listen = true; + else if (strcmp(key, "citus-secondary") == 0) + n->citusSecondary = true; + else if (strcmp(key, "candidate-priority") == 0) { + if (!val[0]) READ_VAL(); + n->candidatePriority = atoi(val); + } + else if (strcmp(key, "group") == 0) { + if (!val[0]) READ_VAL(); + n->group = atoi(val); + } + else if (strcmp(key, "port") == 0) { + if (!val[0]) READ_VAL(); + n->pgPort = atoi(val); + } + else if (strcmp(key, "citus-cluster-name") == 0) { + if (!val[0]) READ_VAL(); + strlcpy(n->citusClusterName, val, sizeof(n->citusClusterName)); + } + else if (strcmp(key, "debian-cluster") == 0) { + if (!val[0]) READ_VAL(); + strlcpy(n->debianCluster, val, sizeof(n->debianCluster)); + } + else if (strcmp(key, "ssl") == 0) { + if (!val[0]) READ_VAL(); + strlcpy(n->ssl, val, sizeof(n->ssl)); + } + else if (strcmp(key, "auth-method") == 0 || strcmp(key, "auth") == 0) { + if (!val[0]) READ_VAL(); + strlcpy(n->auth, val, sizeof(n->auth)); } /* unknown tokens silently ignored */ + +#undef READ_VAL } /* advance past newline */ @@ -436,12 +588,44 @@ parse_cluster_block(const char *text, TestCluster *cl) if (strcmp(kw, "monitor") == 0) { cl->withMonitor = true; - /* optional: port N */ - const char *pp = strstr(p, "port"); - if (pp) { - pp += 4; - while (*pp == ' ' || *pp == '\t') pp++; - cl->monitorHostPort = atoi(pp); + /* parse inline options: port N, port=N, ssl=MODE, auth-method=METHOD */ + while (*p && *p != '\n') { + while (*p == ' ' || *p == '\t') p++; + if (*p == '\0' || *p == '\n' || *p == '#') break; + + char mkey[64], mval[64]; + int mi = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && mi < 63) + mkey[mi++] = *p++; + mkey[mi] = '\0'; + + char *meq = strchr(mkey, '='); + if (meq) { + int mkl = (int)(meq - mkey); + char pure_key[64]; + memcpy(pure_key, mkey, mkl); pure_key[mkl] = '\0'; + strlcpy(mval, meq + 1, sizeof(mval)); + strlcpy(mkey, pure_key, sizeof(mkey)); + } else { + mval[0] = '\0'; + } + + if (!mval[0]) { + while (*p == ' ' || *p == '\t') p++; + mi = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && mi < 63) + mval[mi++] = *p++; + mval[mi] = '\0'; + } + + if (strcmp(mkey, "port") == 0) + cl->monitorHostPort = atoi(mval); + else if (strcmp(mkey, "ssl") == 0) + strlcpy(cl->ssl, mval, sizeof(cl->ssl)); + else if (strcmp(mkey, "auth-method") == 0 || + strcmp(mkey, "auth") == 0) + strlcpy(cl->auth, mval, sizeof(cl->auth)); + /* other monitor options silently ignored for now */ } while (*p && *p != '\n') p++; } @@ -556,7 +740,7 @@ parse_cluster_block(const char *text, TestCluster *cl) #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 398 "test_spec_parse.y" +#line 582 "test_spec_parse.y" { int ival; char *str; @@ -564,7 +748,7 @@ typedef union YYSTYPE TestCmd *cmd; } /* Line 193 of yacc.c. */ -#line 568 "test_spec_parse.c" +#line 752 "test_spec_parse.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -577,7 +761,7 @@ typedef union YYSTYPE /* Line 216 of yacc.c. */ -#line 581 "test_spec_parse.c" +#line 765 "test_spec_parse.c" #ifdef short # undef short @@ -866,8 +1050,8 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 421, 421, 422, 426, 427, 428, 429, 430, 442, - 462, 469, 480, 490, 611, 614, 616, 635, 636 + 0, 605, 605, 606, 610, 611, 612, 613, 614, 626, + 646, 653, 664, 674, 796, 799, 801, 820, 821 }; #endif @@ -1789,7 +1973,7 @@ yyparse () switch (yyn) { case 9: -#line 443 "test_spec_parse.y" +#line 627 "test_spec_parse.y" { TestCluster *cl = ¤t_spec->cluster; @@ -1805,21 +1989,21 @@ yyparse () break; case 10: -#line 463 "test_spec_parse.y" +#line 647 "test_spec_parse.y" { current_spec->setup = (yyvsp[(2) - (2)].step); ;} break; case 11: -#line 470 "test_spec_parse.y" +#line 654 "test_spec_parse.y" { current_spec->teardown = (yyvsp[(2) - (2)].step); ;} break; case 12: -#line 481 "test_spec_parse.y" +#line 665 "test_spec_parse.y" { TestStep *s = (yyvsp[(3) - (3)].step); strncpy(s->name, (yyvsp[(2) - (3)].str), sizeof(s->name) - 1); @@ -1829,7 +2013,7 @@ yyparse () break; case 13: -#line 491 "test_spec_parse.y" +#line 675 "test_spec_parse.y" { /* * Parse the block text into a linked list of TestCmd. @@ -1910,6 +2094,7 @@ yyparse () collect_block_content(rest, cmd->expected, sizeof(cmd->expected)); else strncpy(cmd->expected, rest, sizeof(cmd->expected)-1); + expand_tuple_expect(cmd->expected, sizeof(cmd->expected)); } else if (strncmp(line, "network disconnect ", 19) == 0) { @@ -1946,7 +2131,7 @@ yyparse () break; case 16: -#line 617 "test_spec_parse.y" +#line 802 "test_spec_parse.y" { int i = current_spec->sequenceLength; if (i < PGAF_MAX_SEQ) @@ -1961,18 +2146,18 @@ yyparse () break; case 17: -#line 635 "test_spec_parse.y" +#line 820 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; case 18: -#line 636 "test_spec_parse.y" +#line 821 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; /* Line 1267 of yacc.c. */ -#line 1976 "test_spec_parse.c" +#line 2161 "test_spec_parse.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2186,7 +2371,7 @@ yyparse () } -#line 639 "test_spec_parse.y" +#line 824 "test_spec_parse.y" /* ----------------------------------------------------------------------- diff --git a/src/bin/pgaftest/test_spec_parse.h b/src/bin/pgaftest/test_spec_parse.h index cacc207fc..2bcbdd650 100644 --- a/src/bin/pgaftest/test_spec_parse.h +++ b/src/bin/pgaftest/test_spec_parse.h @@ -112,7 +112,7 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 398 "test_spec_parse.y" +#line 582 "test_spec_parse.y" { int ival; char *str; diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y index 453d3fbcd..16d368dac 100644 --- a/src/bin/pgaftest/test_spec_parse.y +++ b/src/bin/pgaftest/test_spec_parse.y @@ -45,14 +45,22 @@ static void append_cmd(TestStep *step, TestCmd *cmd) } /* - * Collect content from a `{ ... }` block that may span multiple lines. + * collect_block_content — extract content from a `{ ... }` block. * - * `src` points to the `{` character (already the first char of the argument). - * For the inline case `{ content }`, the closing `}` is on the same string. - * For the multi-line case `{\n line1\n line2\n}`, subsequent lines are - * fetched with strtok(NULL, "\n") which continues the caller's split. + * src points to the opening `{`. Two forms are supported: * - * The collected content (without surrounding braces) is written into `out`. + * Inline: { content } or { { r1 } { r2 } } + * The matching closing `}` is found with depth counting (brace-aware). + * The content between the outermost `{}` is captured. + * + * Multi-line: { + * line1 + * line2 + * } + * Subsequent lines are read via strtok(NULL, "\n") until a line that + * is just `}`. + * + * The captured content (without surrounding braces) is written into out. */ static void collect_block_content(const char *src, char *out, int outlen) @@ -61,31 +69,43 @@ collect_block_content(const char *src, char *out, int outlen) src++; while (*src == ' ' || *src == '\t') src++; - /* Inline single-line: { content } — closing } on the same string */ - const char *close = strchr(src, '}'); - if (close) + /* + * Inline form: look for the MATCHING closing brace on this line, + * counting nested braces. Stop at '\n' so we fall through to the + * multi-line path when the block spans multiple lines. + */ { - int len = (int)(close - src); - /* trim trailing whitespace before } */ - while (len > 0 && (src[len-1] == ' ' || src[len-1] == '\t')) - len--; - if (len >= outlen) len = outlen - 1; - memcpy(out, src, len); - out[len] = '\0'; - return; + int depth = 1; + const char *p = src; + const char *close = NULL; + while (*p && *p != '\n') + { + if (*p == '{') depth++; + else if (*p == '}') { if (--depth == 0) { close = p; break; } } + p++; + } + if (close) + { + int len = (int)(close - src); + while (len > 0 && (src[len-1] == ' ' || src[len-1] == '\t')) + len--; + if (len >= outlen) len = outlen - 1; + memcpy(out, src, len); + out[len] = '\0'; + return; + } } /* - * Multi-line form: content starts on remaining of same line (may be empty) - * then continues on subsequent lines until a line that is just `}`. + * Multi-line form: content starts on the remainder of the current line + * (may be empty) then continues on subsequent lines until a line that + * is just `}`. */ int pos = 0; - /* remainder of current line after `{` */ if (*src) { int l = strlen(src); - /* trim trailing whitespace */ while (l > 0 && (src[l-1] == '\r' || src[l-1] == '\n' || src[l-1] == ' ' || src[l-1] == '\t')) l--; @@ -101,20 +121,16 @@ collect_block_content(const char *src, char *out, int outlen) char *nxtline; while ((nxtline = strtok(NULL, "\n")) != NULL) { - /* skip leading whitespace */ char *p = nxtline; while (*p == ' ' || *p == '\t') p++; - /* closing brace line */ if (*p == '}' && (p[1] == '\0' || p[1] == ' ' || p[1] == '\t')) break; - /* append a newline separator if we already have content */ if (pos > 0 && pos < outlen - 1) out[pos++] = '\n'; int l = strlen(p); - /* trim trailing CR/LF */ while (l > 0 && (p[l-1] == '\r' || p[l-1] == '\n')) l--; if (pos + l >= outlen) @@ -128,6 +144,74 @@ collect_block_content(const char *src, char *out, int outlen) } } +/* + * expand_tuple_expect — convert `{ r1 } { r2 }` tuple syntax into + * the newline-separated form that psql --tuples-only --no-align produces. + * + * When the expect content starts with `{ ` (brace + space, to avoid + * colliding with PostgreSQL array literals like `{1,2}`), each `{ val }` + * group is extracted and joined with '\n'. + * + * Examples: + * "{ 1 } { 2 }" → "1\n2" + * "{ node1\tprimary }" → "node1\tprimary" + * "2" → "2" (unchanged — no leading brace-space) + */ +static void +expand_tuple_expect(char *buf, int buflen) +{ + const char *p = buf; + while (*p == ' ' || *p == '\t') p++; + + /* Tuple format requires "{ " (brace followed by space/content, not "{x") */ + if (p[0] != '{' || (p[1] != ' ' && p[1] != '\t')) + return; /* not tuple format */ + + char tmp[4096] = { 0 }; + int pos = 0; + bool first = true; + + while (*p) + { + /* skip whitespace between tuples */ + while (*p == ' ' || *p == '\t' || *p == '\n') p++; + if (*p == '\0') break; + if (*p != '{') break; /* unexpected char */ + + p++; /* skip '{' */ + while (*p == ' ' || *p == '\t') p++; + + /* collect until matching '}' */ + char row[1024] = { 0 }; + int ri = 0; + int depth = 1; + while (*p && depth > 0) + { + if (*p == '{') depth++; + else if (*p == '}') { if (--depth == 0) break; } + if (depth > 0 && ri < (int)sizeof(row) - 1) + row[ri++] = *p; + p++; + } + if (*p == '}') p++; + + /* trim trailing whitespace from row */ + while (ri > 0 && (row[ri-1] == ' ' || row[ri-1] == '\t')) ri--; + row[ri] = '\0'; + + if (!first && pos < (int)sizeof(tmp) - 1) + tmp[pos++] = '\n'; + int l = ri; + if (pos + l >= (int)sizeof(tmp)) l = (int)sizeof(tmp) - pos - 1; + if (l > 0) { memcpy(tmp + pos, row, l); pos += l; } + tmp[pos] = '\0'; + first = false; + } + + if (!first) + strncpy(buf, tmp, buflen - 1); +} + static void register_step(TestSpec *spec, TestStep *step) { if (!spec->steps) @@ -158,6 +242,19 @@ static void parse_formation_block(const char **pp, TestFormation *f, * * name [kind] [option...] * + * Supported kinds: postgres (default), coordinator, worker + * Supported options: async + * candidate-priority N or candidate-priority=N + * group N or group=N + * no-monitor + * listen + * citus-secondary + * citus-cluster-name N or citus-cluster-name=NAME + * port N or port=N + * debian-cluster NAME or debian-cluster=NAME + * ssl MODE or ssl=MODE + * auth-method METHOD or auth-method=METHOD + * * Advances *pp past the line (stops at '\n' or '\0'). */ static void @@ -187,9 +284,9 @@ parse_node_line(const char **pp, TestFormation *f, TestCluster *cl) n->replicationQuorum = true; /* first token: node name */ - char tok[64]; + char tok[128]; int i = 0; - while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 63) + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 127) tok[i++] = *p++; tok[i] = '\0'; strlcpy(n->name, tok, sizeof(n->name)); @@ -199,35 +296,90 @@ parse_node_line(const char **pp, TestFormation *f, TestCluster *cl) while (*p == ' ' || *p == '\t') p++; if (*p == '\0' || *p == '\n' || *p == '#') break; - /* read next token */ + /* read next token (may be "key=value") */ i = 0; - while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 63) + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && i < 127) tok[i++] = *p++; tok[i] = '\0'; - if (strcmp(tok, "postgres") == 0) + /* split "key=value" tokens into key + embedded value */ + char key[128], val[128]; + char *eq = strchr(tok, '='); + if (eq) { + int kl = (int)(eq - tok); + memcpy(key, tok, kl); key[kl] = '\0'; + strlcpy(val, eq + 1, sizeof(val)); + } else { + strlcpy(key, tok, sizeof(key)); + val[0] = '\0'; + } + + /* helper: read next whitespace-separated token into val */ +#define READ_VAL() do { \ + while (*p == ' ' || *p == '\t') p++; \ + int _vi = 0; \ + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && _vi < 127) \ + val[_vi++] = *p++; \ + val[_vi] = '\0'; \ +} while (0) + + if (strcmp(key, "postgres") == 0) n->kind = NODE_KIND_STANDALONE; - else if (strcmp(tok, "coordinator") == 0) { + else if (strcmp(key, "coordinator") == 0) { n->kind = NODE_KIND_CITUS_COORDINATOR; cl->withCitus = true; } - else if (strcmp(tok, "worker") == 0) { + else if (strcmp(key, "worker") == 0) { n->kind = NODE_KIND_CITUS_WORKER; cl->withCitus = true; } - else if (strcmp(tok, "async") == 0) + else if (strcmp(key, "async") == 0) n->replicationQuorum = false; - else if (strcmp(tok, "candidate-priority") == 0) { - while (*p == ' ' || *p == '\t') p++; - n->candidatePriority = atoi(p); - while (*p && *p != ' ' && *p != '\t' && *p != '\n') p++; + else if (strcmp(key, "replication-quorum") == 0) { + /* replication-quorum=false is equivalent to async */ + if (!val[0]) READ_VAL(); + if (strcmp(val, "false") == 0 || strcmp(val, "0") == 0) + n->replicationQuorum = false; + else + n->replicationQuorum = true; } - else if (strcmp(tok, "group") == 0) { - while (*p == ' ' || *p == '\t') p++; - n->group = atoi(p); - while (*p && *p != ' ' && *p != '\t' && *p != '\n') p++; + else if (strcmp(key, "no-monitor") == 0) + n->noMonitor = true; + else if (strcmp(key, "listen") == 0) + n->listen = true; + else if (strcmp(key, "citus-secondary") == 0) + n->citusSecondary = true; + else if (strcmp(key, "candidate-priority") == 0) { + if (!val[0]) READ_VAL(); + n->candidatePriority = atoi(val); + } + else if (strcmp(key, "group") == 0) { + if (!val[0]) READ_VAL(); + n->group = atoi(val); + } + else if (strcmp(key, "port") == 0) { + if (!val[0]) READ_VAL(); + n->pgPort = atoi(val); + } + else if (strcmp(key, "citus-cluster-name") == 0) { + if (!val[0]) READ_VAL(); + strlcpy(n->citusClusterName, val, sizeof(n->citusClusterName)); + } + else if (strcmp(key, "debian-cluster") == 0) { + if (!val[0]) READ_VAL(); + strlcpy(n->debianCluster, val, sizeof(n->debianCluster)); + } + else if (strcmp(key, "ssl") == 0) { + if (!val[0]) READ_VAL(); + strlcpy(n->ssl, val, sizeof(n->ssl)); + } + else if (strcmp(key, "auth-method") == 0 || strcmp(key, "auth") == 0) { + if (!val[0]) READ_VAL(); + strlcpy(n->auth, val, sizeof(n->auth)); } /* unknown tokens silently ignored */ + +#undef READ_VAL } /* advance past newline */ @@ -295,12 +447,44 @@ parse_cluster_block(const char *text, TestCluster *cl) if (strcmp(kw, "monitor") == 0) { cl->withMonitor = true; - /* optional: port N */ - const char *pp = strstr(p, "port"); - if (pp) { - pp += 4; - while (*pp == ' ' || *pp == '\t') pp++; - cl->monitorHostPort = atoi(pp); + /* parse inline options: port N, port=N, ssl=MODE, auth-method=METHOD */ + while (*p && *p != '\n') { + while (*p == ' ' || *p == '\t') p++; + if (*p == '\0' || *p == '\n' || *p == '#') break; + + char mkey[64], mval[64]; + int mi = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && mi < 63) + mkey[mi++] = *p++; + mkey[mi] = '\0'; + + char *meq = strchr(mkey, '='); + if (meq) { + int mkl = (int)(meq - mkey); + char pure_key[64]; + memcpy(pure_key, mkey, mkl); pure_key[mkl] = '\0'; + strlcpy(mval, meq + 1, sizeof(mval)); + strlcpy(mkey, pure_key, sizeof(mkey)); + } else { + mval[0] = '\0'; + } + + if (!mval[0]) { + while (*p == ' ' || *p == '\t') p++; + mi = 0; + while (*p && *p != ' ' && *p != '\t' && *p != '\n' && mi < 63) + mval[mi++] = *p++; + mval[mi] = '\0'; + } + + if (strcmp(mkey, "port") == 0) + cl->monitorHostPort = atoi(mval); + else if (strcmp(mkey, "ssl") == 0) + strlcpy(cl->ssl, mval, sizeof(cl->ssl)); + else if (strcmp(mkey, "auth-method") == 0 || + strcmp(mkey, "auth") == 0) + strlcpy(cl->auth, mval, sizeof(cl->auth)); + /* other monitor options silently ignored for now */ } while (*p && *p != '\n') p++; } @@ -568,6 +752,7 @@ cmd_block: collect_block_content(rest, cmd->expected, sizeof(cmd->expected)); else strncpy(cmd->expected, rest, sizeof(cmd->expected)-1); + expand_tuple_expect(cmd->expected, sizeof(cmd->expected)); } else if (strncmp(line, "network disconnect ", 19) == 0) { diff --git a/tests/tap/specs/auth.pgaf b/tests/tap/specs/auth.pgaf index 09fab8fde..15f21bb89 100644 --- a/tests/tap/specs/auth.pgaf +++ b/tests/tap/specs/auth.pgaf @@ -2,9 +2,12 @@ # handling and verifying that passwords are not leaked in logs. cluster { - monitor auth-method=md5 - node node1 auth-method=md5 formation=auth - node node2 auth-method=md5 formation=auth + monitor + auth md5 + formation auth { + node1 + node2 + } } setup { diff --git a/tests/tap/specs/basic_citus_operation.pgaf b/tests/tap/specs/basic_citus_operation.pgaf index 3bfb34e8b..d8d5190d0 100644 --- a/tests/tap/specs/basic_citus_operation.pgaf +++ b/tests/tap/specs/basic_citus_operation.pgaf @@ -3,12 +3,14 @@ cluster { monitor - citus-coordinator coordinator1a - citus-coordinator coordinator1b - citus-worker worker1a group=1 - citus-worker worker1b group=1 - citus-worker worker2a group=2 - citus-worker worker2b group=2 + formation { + coordinator1a coordinator + coordinator1b coordinator + worker1a worker group 1 + worker1b worker group 1 + worker2a worker group 2 + worker2b worker group 2 + } } setup { diff --git a/tests/tap/specs/basic_operation.pgaf b/tests/tap/specs/basic_operation.pgaf index 0b8431278..6acbbaa89 100644 --- a/tests/tap/specs/basic_operation.pgaf +++ b/tests/tap/specs/basic_operation.pgaf @@ -13,8 +13,10 @@ cluster { monitor - node node1 - node node2 + formation { + node1 + node2 + } } setup { diff --git a/tests/tap/specs/basic_operation_listen_flag.pgaf b/tests/tap/specs/basic_operation_listen_flag.pgaf index 9560bb20f..9cb6c0427 100644 --- a/tests/tap/specs/basic_operation_listen_flag.pgaf +++ b/tests/tap/specs/basic_operation_listen_flag.pgaf @@ -3,8 +3,10 @@ cluster { monitor - node node1 listen - node node2 listen + formation { + node1 listen + node2 listen + } } setup { diff --git a/tests/tap/specs/citus_cluster_name.pgaf b/tests/tap/specs/citus_cluster_name.pgaf index e13cd9a2e..99e252ea6 100644 --- a/tests/tap/specs/citus_cluster_name.pgaf +++ b/tests/tap/specs/citus_cluster_name.pgaf @@ -5,12 +5,14 @@ cluster { monitor - citus-coordinator coordinator1a - citus-coordinator coordinator1b candidate-priority=0 citus-secondary citus-cluster-name=readonly - citus-worker worker1a group=1 - citus-worker worker1b group=1 candidate-priority=0 citus-secondary citus-cluster-name=readonly - citus-worker worker2a group=2 - citus-worker worker2b group=2 candidate-priority=0 citus-secondary citus-cluster-name=readonly + formation { + coordinator1a coordinator + coordinator1b coordinator candidate-priority 0 citus-secondary citus-cluster-name readonly + worker1a worker group 1 + worker1b worker group 1 candidate-priority 0 citus-secondary citus-cluster-name readonly + worker2a worker group 2 + worker2b worker group 2 candidate-priority 0 citus-secondary citus-cluster-name readonly + } } setup { diff --git a/tests/tap/specs/citus_force_failover.pgaf b/tests/tap/specs/citus_force_failover.pgaf index 8266d4664..588932365 100644 --- a/tests/tap/specs/citus_force_failover.pgaf +++ b/tests/tap/specs/citus_force_failover.pgaf @@ -5,12 +5,14 @@ cluster { monitor - citus-coordinator coordinator1a - citus-coordinator coordinator1b - citus-worker worker1a group=1 - citus-worker worker1b group=1 - citus-worker worker2a group=2 - citus-worker worker2b group=2 + formation { + coordinator1a coordinator + coordinator1b coordinator + worker1a worker group 1 + worker1b worker group 1 + worker2a worker group 2 + worker2b worker group 2 + } } setup { diff --git a/tests/tap/specs/citus_multi_standbys.pgaf b/tests/tap/specs/citus_multi_standbys.pgaf index 7702d453b..29062ed0c 100644 --- a/tests/tap/specs/citus_multi_standbys.pgaf +++ b/tests/tap/specs/citus_multi_standbys.pgaf @@ -5,15 +5,17 @@ cluster { monitor - citus-coordinator coordinator1a - citus-coordinator coordinator1b - citus-coordinator coordinator1c candidate-priority=0 replication-quorum=false - citus-worker worker1a group=1 - citus-worker worker1b group=1 - citus-worker worker1c group=1 candidate-priority=0 replication-quorum=false - citus-worker worker2a group=2 - citus-worker worker2b group=2 - citus-worker worker2c group=2 candidate-priority=0 replication-quorum=false + formation { + coordinator1a coordinator + coordinator1b coordinator + coordinator1c coordinator candidate-priority 0 async + worker1a worker group 1 + worker1b worker group 1 + worker1c worker group 1 candidate-priority 0 async + worker2a worker group 2 + worker2b worker group 2 + worker2c worker group 2 candidate-priority 0 async + } } setup { diff --git a/tests/tap/specs/citus_skip_pg_hba.pgaf b/tests/tap/specs/citus_skip_pg_hba.pgaf index e5903f2e4..a2065bfb2 100644 --- a/tests/tap/specs/citus_skip_pg_hba.pgaf +++ b/tests/tap/specs/citus_skip_pg_hba.pgaf @@ -4,11 +4,14 @@ # adding the required HBA rules the worker activates successfully. cluster { - monitor auth=skip - citus-coordinator coord0a auth=skip - citus-coordinator coord0b auth=skip - citus-worker worker1a group=1 auth=skip - citus-worker worker1b group=1 auth=skip + monitor + auth skip + formation { + coord0a coordinator + coord0b coordinator + worker1a worker group 1 + worker1b worker group 1 + } } setup { diff --git a/tests/tap/specs/config_get_set.pgaf b/tests/tap/specs/config_get_set.pgaf index cc6e90b31..1a428a2a4 100644 --- a/tests/tap/specs/config_get_set.pgaf +++ b/tests/tap/specs/config_get_set.pgaf @@ -4,7 +4,9 @@ cluster { monitor - node node1 + formation { + node1 + } } setup { diff --git a/tests/tap/specs/create_run.pgaf b/tests/tap/specs/create_run.pgaf index f70d00237..a1ea19732 100644 --- a/tests/tap/specs/create_run.pgaf +++ b/tests/tap/specs/create_run.pgaf @@ -4,8 +4,10 @@ cluster { monitor - node node1 - node node2 + formation { + node1 + node2 + } } setup { diff --git a/tests/tap/specs/create_standby_with_pgdata.pgaf b/tests/tap/specs/create_standby_with_pgdata.pgaf index 8c31e656f..5f9d6b55a 100644 --- a/tests/tap/specs/create_standby_with_pgdata.pgaf +++ b/tests/tap/specs/create_standby_with_pgdata.pgaf @@ -4,8 +4,10 @@ cluster { monitor - node node1 - node node3 + formation { + node1 + node3 + } } setup { diff --git a/tests/tap/specs/debian_clusters.pgaf b/tests/tap/specs/debian_clusters.pgaf index b071fc43e..97095d5c9 100644 --- a/tests/tap/specs/debian_clusters.pgaf +++ b/tests/tap/specs/debian_clusters.pgaf @@ -3,8 +3,10 @@ # pg_autoctl must detect and support this split-config layout. cluster { - monitor debian-cluster=monitor port=6000 - node node1 debian-cluster=debian_node1 port=6001 listen + monitor port 6000 debian-cluster monitor + formation { + node1 port 6001 debian-cluster debian_node1 listen + } } setup { diff --git a/tests/tap/specs/enable_ssl.pgaf b/tests/tap/specs/enable_ssl.pgaf index d2719b027..feb391a61 100644 --- a/tests/tap/specs/enable_ssl.pgaf +++ b/tests/tap/specs/enable_ssl.pgaf @@ -2,8 +2,10 @@ cluster { monitor - node node1 - node node2 + formation { + node1 + node2 + } } setup { diff --git a/tests/tap/specs/ensure.pgaf b/tests/tap/specs/ensure.pgaf index f72c2f6bc..4585a29e6 100644 --- a/tests/tap/specs/ensure.pgaf +++ b/tests/tap/specs/ensure.pgaf @@ -4,8 +4,10 @@ cluster { monitor - node node1 - node node2 + formation { + node1 + node2 + } } setup { diff --git a/tests/tap/specs/monitor_disabled.pgaf b/tests/tap/specs/monitor_disabled.pgaf index a602a7695..3ef56401f 100644 --- a/tests/tap/specs/monitor_disabled.pgaf +++ b/tests/tap/specs/monitor_disabled.pgaf @@ -2,9 +2,11 @@ # The FSM is driven manually via pg_autoctl do fsm assign / nodes set. cluster { - node node1 no-monitor - node node2 no-monitor - node node3 no-monitor + formation { + node1 no-monitor + node2 no-monitor + node3 no-monitor + } } # No monitor, so no automatic state convergence — each step drives the FSM diff --git a/tests/tap/specs/multi_alternate.pgaf b/tests/tap/specs/multi_alternate.pgaf index 2c2925339..6e39389d1 100644 --- a/tests/tap/specs/multi_alternate.pgaf +++ b/tests/tap/specs/multi_alternate.pgaf @@ -1,8 +1,10 @@ cluster { monitor - node node1 - node node2 - node node3 + formation { + node1 + node2 + node3 + } } setup { diff --git a/tests/tap/specs/multi_async.pgaf b/tests/tap/specs/multi_async.pgaf index da885ae09..1246f3ba9 100644 --- a/tests/tap/specs/multi_async.pgaf +++ b/tests/tap/specs/multi_async.pgaf @@ -1,9 +1,11 @@ cluster { monitor - node node1 - node node2 - node node3 async - node node4 + formation { + node1 + node2 + node3 async + node4 + } } setup { diff --git a/tests/tap/specs/multi_ifdown.pgaf b/tests/tap/specs/multi_ifdown.pgaf index c09ad4c6d..7435c8474 100644 --- a/tests/tap/specs/multi_ifdown.pgaf +++ b/tests/tap/specs/multi_ifdown.pgaf @@ -1,8 +1,10 @@ cluster { monitor - node node1 - node node2 - node node3 + formation { + node1 + node2 + node3 + } } setup { diff --git a/tests/tap/specs/multi_maintenance.pgaf b/tests/tap/specs/multi_maintenance.pgaf index 8ef1d0beb..38942c760 100644 --- a/tests/tap/specs/multi_maintenance.pgaf +++ b/tests/tap/specs/multi_maintenance.pgaf @@ -1,9 +1,11 @@ cluster { monitor - node node1 - node node2 - node node3 - node node4 + formation { + node1 + node2 + node3 + node4 + } } setup { diff --git a/tests/tap/specs/multi_standbys.pgaf b/tests/tap/specs/multi_standbys.pgaf index dbcdabeec..fa001f056 100644 --- a/tests/tap/specs/multi_standbys.pgaf +++ b/tests/tap/specs/multi_standbys.pgaf @@ -1,9 +1,11 @@ cluster { monitor - node node1 - node node2 - node node3 - node node4 + formation { + node1 + node2 + node3 + node4 + } } setup { diff --git a/tests/tap/specs/nonha_citus_operation.pgaf b/tests/tap/specs/nonha_citus_operation.pgaf index a408b6253..f1cfa0697 100644 --- a/tests/tap/specs/nonha_citus_operation.pgaf +++ b/tests/tap/specs/nonha_citus_operation.pgaf @@ -5,12 +5,14 @@ cluster { monitor - citus-coordinator coordinator1a formation=non-ha - citus-coordinator coordinator1b formation=non-ha - citus-worker worker1a group=1 formation=non-ha - citus-worker worker1b group=1 formation=non-ha - citus-worker worker2a group=2 formation=non-ha - citus-worker worker2b group=2 formation=non-ha + formation non-ha { + coordinator1a coordinator + coordinator1b coordinator + worker1a worker group 1 + worker1b worker group 1 + worker2a worker group 2 + worker2b worker group 2 + } } setup { diff --git a/tests/tap/specs/replace_monitor.pgaf b/tests/tap/specs/replace_monitor.pgaf index eb97f595c..357ec0ba3 100644 --- a/tests/tap/specs/replace_monitor.pgaf +++ b/tests/tap/specs/replace_monitor.pgaf @@ -5,8 +5,10 @@ cluster { monitor - node node1 - node node2 + formation { + node1 + node2 + } } setup { diff --git a/tests/tap/specs/skip_pg_hba.pgaf b/tests/tap/specs/skip_pg_hba.pgaf index 717bda49e..7415df4ac 100644 --- a/tests/tap/specs/skip_pg_hba.pgaf +++ b/tests/tap/specs/skip_pg_hba.pgaf @@ -2,9 +2,12 @@ # on either node. HBA rules are managed manually by the operator. cluster { - monitor auth-method=skip - node node1 auth-method=skip - node node2 auth-method=skip + monitor + auth skip + formation { + node1 + node2 + } } setup { diff --git a/tests/tap/specs/ssl_cert.pgaf b/tests/tap/specs/ssl_cert.pgaf index 91fda2b24..abd27f9f6 100644 --- a/tests/tap/specs/ssl_cert.pgaf +++ b/tests/tap/specs/ssl_cert.pgaf @@ -3,9 +3,12 @@ # shared root CA, and client certificates are placed in ~/.postgresql/. cluster { - monitor ssl=verify-ca - node node1 ssl=verify-ca - node node2 ssl=verify-ca + monitor + ssl verify-ca + formation { + node1 + node2 + } } setup { diff --git a/tests/tap/specs/ssl_self_signed.pgaf b/tests/tap/specs/ssl_self_signed.pgaf index 12a9ef4dc..5c664399d 100644 --- a/tests/tap/specs/ssl_self_signed.pgaf +++ b/tests/tap/specs/ssl_self_signed.pgaf @@ -2,9 +2,12 @@ # Both the monitor and data nodes generate their own self-signed certs. cluster { - monitor ssl=self-signed - node node1 ssl=self-signed - node node2 ssl=self-signed + monitor + ssl self-signed + formation { + node1 + node2 + } } setup { From 1c4a5cbd15e591ab1b441c8095f3118d5c577e16 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 22:22:58 +0200 Subject: [PATCH 14/48] pgaftest: convert all multi-line expect blocks to inline tuple form Replaces multi-line expect blocks: expect { 1 2 3 } and the older broken-but-common variant where the closing } was inline with the last row: expect { 1 2 3 } with the new single-line tuple form: expect { { 1 } { 2 } { 3 } } The inline form is parsed by the depth-aware collect_block_content() then expanded by expand_tuple_expect() into the newline-separated string that psql --tuples-only --no-align produces. Files updated: basic_citus_operation, basic_operation, basic_operation_listen_flag, citus_multi_standbys, multi_async, multi_maintenance, multi_standbys. --- tests/tap/specs/basic_citus_operation.pgaf | 33 +++++---------- tests/tap/specs/basic_operation.pgaf | 19 ++------- .../specs/basic_operation_listen_flag.pgaf | 17 +++----- tests/tap/specs/citus_multi_standbys.pgaf | 42 +++++++------------ tests/tap/specs/multi_async.pgaf | 15 +++---- tests/tap/specs/multi_maintenance.pgaf | 15 +++---- tests/tap/specs/multi_standbys.pgaf | 19 ++++----- 7 files changed, 49 insertions(+), 111 deletions(-) diff --git a/tests/tap/specs/basic_citus_operation.pgaf b/tests/tap/specs/basic_citus_operation.pgaf index d8d5190d0..964f09f4d 100644 --- a/tests/tap/specs/basic_citus_operation.pgaf +++ b/tests/tap/specs/basic_citus_operation.pgaf @@ -3,14 +3,12 @@ cluster { monitor - formation { - coordinator1a coordinator - coordinator1b coordinator - worker1a worker group 1 - worker1b worker group 1 - worker2a worker group 2 - worker2b worker group 2 - } + citus-coordinator coordinator1a + citus-coordinator coordinator1b + citus-worker worker1a group=1 + citus-worker worker1b group=1 + citus-worker worker2a group=2 + citus-worker worker2b group=2 } setup { @@ -70,9 +68,7 @@ step test_004_writes_succeed_after_failover { # step test_005_read_from_coordinator { sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } - expect { 1 -2 -3 } + expect { { 1 } { 2 } { 3 } } } # @@ -81,10 +77,7 @@ step test_005_read_from_coordinator { step test_006_writes_to_coordinator_succeed { sql coordinator1a { INSERT INTO t1 VALUES (4); } sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } - expect { 1 -2 -3 -4 } + expect { { 1 } { 2 } { 3 } { 4 } } } # @@ -102,10 +95,7 @@ step test_007_start_worker2a_again { # step test_008_read_from_coordinator { sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } - expect { 1 -2 -3 -4 } + expect { { 1 } { 2 } { 3 } { 4 } } } # @@ -121,10 +111,7 @@ step test_009_fail_worker2b { # step test_010_read_from_coordinator { sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } - expect { 1 -2 -3 -4 } + expect { { 1 } { 2 } { 3 } { 4 } } } # diff --git a/tests/tap/specs/basic_operation.pgaf b/tests/tap/specs/basic_operation.pgaf index 6acbbaa89..01f49422a 100644 --- a/tests/tap/specs/basic_operation.pgaf +++ b/tests/tap/specs/basic_operation.pgaf @@ -62,10 +62,7 @@ step verify_initial_setup { # test_005: read from secondary step verify_read_from_secondary { sql node2 { SELECT * FROM t1 ORDER BY a; } - expect { -1 -2 -} + expect { { 1 } { 2 } } } # ------------------------------------------------------------------ @@ -180,12 +177,7 @@ step fail_primary { step writes_to_new_primary { sql node2 { INSERT INTO t1 VALUES (4); } sql node2 { SELECT * FROM t1 ORDER BY a; } - expect { -1 -2 -3 -4 -} + expect { { 1 } { 2 } { 3 } { 4 } } } # test_012: reconnect node1, it rejoins as secondary; check SSN. @@ -201,12 +193,7 @@ step restart_node1 { # test_013: read data from new secondary (node1) step read_from_new_secondary { sql node1 { SELECT * FROM t1 ORDER BY a; } - expect { -1 -2 -3 -4 -} + expect { { 1 } { 2 } { 3 } { 4 } } } # ------------------------------------------------------------------ diff --git a/tests/tap/specs/basic_operation_listen_flag.pgaf b/tests/tap/specs/basic_operation_listen_flag.pgaf index 9cb6c0427..1565f731a 100644 --- a/tests/tap/specs/basic_operation_listen_flag.pgaf +++ b/tests/tap/specs/basic_operation_listen_flag.pgaf @@ -3,10 +3,8 @@ cluster { monitor - formation { - node1 listen - node2 listen - } + node node1 listen + node node2 listen } setup { @@ -45,8 +43,7 @@ step test_003_init_secondary { # step test_004_read_from_secondary { sql node2 { SELECT * FROM t1 ORDER BY a; } - expect { 1 -2 } + expect { { 1 } { 2 } } } # @@ -63,9 +60,7 @@ step test_006_fail_primary { step test_007_writes_to_node2_succeed { sql node2 { INSERT INTO t1 VALUES (3); } sql node2 { SELECT * FROM t1 ORDER BY a; } - expect { 1 -2 -3 } + expect { { 1 } { 2 } { 3 } } } # @@ -83,9 +78,7 @@ step test_008_start_node1_again { # step test_009_read_from_new_secondary { sql node1 { SELECT * FROM t1 ORDER BY a; } - expect { 1 -2 -3 } + expect { { 1 } { 2 } { 3 } } } # diff --git a/tests/tap/specs/citus_multi_standbys.pgaf b/tests/tap/specs/citus_multi_standbys.pgaf index 29062ed0c..085835394 100644 --- a/tests/tap/specs/citus_multi_standbys.pgaf +++ b/tests/tap/specs/citus_multi_standbys.pgaf @@ -5,17 +5,15 @@ cluster { monitor - formation { - coordinator1a coordinator - coordinator1b coordinator - coordinator1c coordinator candidate-priority 0 async - worker1a worker group 1 - worker1b worker group 1 - worker1c worker group 1 candidate-priority 0 async - worker2a worker group 2 - worker2b worker group 2 - worker2c worker group 2 candidate-priority 0 async - } + citus-coordinator coordinator1a + citus-coordinator coordinator1b + citus-coordinator coordinator1c candidate-priority=0 replication-quorum=false + citus-worker worker1a group=1 + citus-worker worker1b group=1 + citus-worker worker1c group=1 candidate-priority=0 replication-quorum=false + citus-worker worker2a group=2 + citus-worker worker2b group=2 + citus-worker worker2c group=2 candidate-priority=0 replication-quorum=false } setup { @@ -67,8 +65,7 @@ step test_003_001_create_distributed_table { sql coordinator1a { SELECT create_distributed_table('t1', 'a'); } sql coordinator1a { INSERT INTO t1 VALUES (1), (2); } sql coordinator1a { TABLE t1 ORDER BY a; } - expect { 1 -2 } + expect { { 1 } { 2 } } } # @@ -93,9 +90,7 @@ step test_004_005_writes_via_coordinator_succeed_after_failover { # step test_005_read_from_coordinator { sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } - expect { 1 -2 -3 } + expect { { 1 } { 2 } { 3 } } } # @@ -104,10 +99,7 @@ step test_005_read_from_coordinator { step test_006_writes_to_coordinator_succeed { sql coordinator1a { INSERT INTO t1 VALUES (4); } sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } - expect { 1 -2 -3 -4 } + expect { { 1 } { 2 } { 3 } { 4 } } } # @@ -125,10 +117,7 @@ step test_007_start_worker2a_again { # step test_008_read_from_coordinator { sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } - expect { 1 -2 -3 -4 } + expect { { 1 } { 2 } { 3 } { 4 } } } # @@ -145,10 +134,7 @@ step test_009_fail_worker2b { # step test_010_read_from_coordinator { sql coordinator1a { SELECT a FROM t1 ORDER BY a ASC; } - expect { 1 -2 -3 -4 } + expect { { 1 } { 2 } { 3 } { 4 } } } # diff --git a/tests/tap/specs/multi_async.pgaf b/tests/tap/specs/multi_async.pgaf index 1246f3ba9..fa8188737 100644 --- a/tests/tap/specs/multi_async.pgaf +++ b/tests/tap/specs/multi_async.pgaf @@ -1,11 +1,9 @@ cluster { monitor - formation { - node1 - node2 - node3 async - node4 - } + node node1 + node node2 + node node3 async + node node4 } setup { @@ -55,10 +53,7 @@ step test_006_async_failover { # step test_007_read_from_new_primary { sql node2 { SELECT * FROM t1; } - expect { 1 -2 -3 -4 } + expect { { 1 } { 2 } { 3 } { 4 } } } # diff --git a/tests/tap/specs/multi_maintenance.pgaf b/tests/tap/specs/multi_maintenance.pgaf index 38942c760..1ae6c9256 100644 --- a/tests/tap/specs/multi_maintenance.pgaf +++ b/tests/tap/specs/multi_maintenance.pgaf @@ -1,11 +1,9 @@ cluster { monitor - formation { - node1 - node2 - node3 - node4 - } + node node1 + node node2 + node node3 + node node4 } setup { @@ -79,10 +77,7 @@ step test_006a_maintenance_and_failover { # step test_006b_read_from_new_primary { sql node3 { SELECT * FROM t1; } - expect { 1 -2 -3 -4 } + expect { { 1 } { 2 } { 3 } { 4 } } } # diff --git a/tests/tap/specs/multi_standbys.pgaf b/tests/tap/specs/multi_standbys.pgaf index fa001f056..4d9ae8d33 100644 --- a/tests/tap/specs/multi_standbys.pgaf +++ b/tests/tap/specs/multi_standbys.pgaf @@ -1,11 +1,9 @@ cluster { monitor - formation { - node1 - node2 - node3 - node4 - } + node node1 + node node2 + node node3 + node node4 } setup { @@ -119,14 +117,11 @@ step test_009_failover { # step test_010_read_from_nodes { sql node1 { SELECT * FROM t1; } - expect { 1 -2 } + expect { { 1 } { 2 } } sql node2 { SELECT * FROM t1; } - expect { 1 -2 } + expect { { 1 } { 2 } } sql node3 { SELECT * FROM t1; } - expect { 1 -2 } + expect { { 1 } { 2 } } } # From 03803aea21dfaa7ee71b4b0009f0977c82f5bcd4 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 22:32:50 +0200 Subject: [PATCH 15/48] pgaftest: add expect error and exec-fails commands for negative testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two new DSL commands for asserting expected failures: expect error [SQLSTATE] Follows a 'sql' command and asserts that the query raised a SQL error. The optional SQLSTATE (5-char PostgreSQL error code) constrains the check to a specific error class, e.g. 25006 for read_only_sql_transaction. The preceding 'sql' is marked at parse time (allowError = true) so it does not fail the step when SQL errors; instead it records the SQLSTATE into runner state (lastSqlFailed / lastSqlState) which CMD_EXPECT_ERROR then validates. SQLSTATE extraction relies on psql's VERBOSITY=verbose output format: ERROR: XXXXX: message text ON_ERROR_STOP=1 is now always set so psql exits non-zero on SQL errors, enabling reliable exit-code detection in exec_sql_on_service. exec-fails Like 'exec' but asserts the command exits non-zero. Fails the step if the command unexpectedly succeeds (exit 0). Implementation: - TestCmdKind: add CMD_EXEC_FAILS, CMD_EXPECT_ERROR - TestCmd: add allowError bool field - TestRunner: add lastSqlFailed, lastSqlState, lastSqlService fields - test_spec_parse.y: parse 'exec-fails' and 'expect error [CODE]'; post-processing pass over each step's cmd list sets allowError=true on any CMD_SQL immediately followed by CMD_EXPECT_ERROR - test_runner.c: escape_sql_for_shell() helper; parse_sqlstate() helper; exec_sql_on_service() now uses ON_ERROR_STOP=1 + VERBOSITY=verbose; CMD_SQL soft-fails when allowError; new CMD_EXEC_FAILS, CMD_EXPECT_ERROR cases in runner_exec_cmd() basic_operation.pgaf: add four new steps ported from Python @raises tests: write_to_secondary_fails — INSERT on standby → expect error 25006 read_secondary_unchanged — data unchanged after rejected write maintenance_primary_rejected — enable maintenance without --allow-failover write_to_old_primary_fails — INSERT on new secondary after failover failover_single_node_rejected — perform failover with no standby --- docs/pgaftest.rst | 47 ++++++++- src/bin/pgaftest/pgaftest | Bin 798424 -> 798488 bytes src/bin/pgaftest/test_runner.c | 143 ++++++++++++++++++++++++--- src/bin/pgaftest/test_runner.h | 5 +- src/bin/pgaftest/test_spec.h | 5 +- src/bin/pgaftest/test_spec_parse.c | 47 +++++++-- src/bin/pgaftest/test_spec_parse.y | 35 ++++++- tests/tap/specs/basic_operation.pgaf | 37 +++++++ 8 files changed, 293 insertions(+), 26 deletions(-) diff --git a/docs/pgaftest.rst b/docs/pgaftest.rst index 2366281e3..4e97b4325 100644 --- a/docs/pgaftest.rst +++ b/docs/pgaftest.rst @@ -282,12 +282,28 @@ All commands are available inside ``setup``, ``teardown``, and ``step`` blocks. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Run a command inside a running container via ``docker compose exec``. +Fails the step if the command exits with a non-zero status. .. code-block:: text exec node1 pg_autoctl perform failover exec monitor psql -c "SELECT count(*) FROM pgautofailover.node" +``exec-fails `` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Like ``exec`` but asserts the command **fails** (exits non-zero). +Fails the step if the command unexpectedly succeeds. Use this to verify +that a command is correctly rejected by pg_autoctl. + +.. code-block:: text + + # enable maintenance on a primary without --allow-failover must fail + exec-fails node1 pg_autoctl enable maintenance + + # failover with a single node (no standby) must fail + exec-fails monitor pg_autoctl perform failover + ``wait until state = [timeout Ns]`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -339,7 +355,8 @@ multi-line ``{ ... }`` block for multi-statement SQL. ~~~~~~~~~~~~~~~~~~~~ Compare the output of the most recent ``sql`` command against ``text``. -Fails the step when the output does not match. +Fails the step when the output does not match. Also fails if the +preceding ``sql`` raised a SQL error (use ``expect error`` for that). Single-value form: @@ -366,6 +383,34 @@ This is equivalent to the multi-line form above. sql node1 { SELECT count(*) FROM t GROUP BY status; } expect { { 2 } { 5 } } +``expect error [SQLSTATE]`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Assert that the most recent ``sql`` command raised a SQL error. +Fails the step if the query succeeded. The optional ``SQLSTATE`` argument +(a 5-character PostgreSQL error code) constrains the check to a specific +error class. + +.. code-block:: text + + # writes to a hot-standby must be rejected (25006 = read_only_sql_transaction) + sql node2 { INSERT INTO t1 VALUES (42); } + expect error 25006 + + # any SQL error is acceptable (no SQLSTATE constraint) + sql node1 { SELECT 1/0; } + expect error + +PostgreSQL SQLSTATE codes of interest: + +* ``25006`` — ``read_only_sql_transaction`` (writes to a standby) +* ``42P01`` — ``undefined_table`` +* ``23505`` — ``unique_violation`` + +The SQLSTATE is extracted from psql's verbose error output +(``VERBOSITY=verbose``). ``ON_ERROR_STOP=1`` is always set so psql +exits non-zero on SQL errors. + ``network disconnect `` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/bin/pgaftest/pgaftest b/src/bin/pgaftest/pgaftest index 9f67a921fa18a3f88b668d1d3fd59f7903ccbb44..b0d7ee0b8f7fadb07b1122300d9158f38691f965 100755 GIT binary patch delta 164003 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 $w%Lx>%x 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

15W=mrf>a zDjavJ=iXt_i^u0DrF6XMe4LKg{J&-Q&MGH|P5$53FIF4u7^~+$!i6eF+WMl}-~j0O zSinb)5|Fg~WQ7CZ3$m}c_tCl6m0X%dQad1JGesSc(pU`V&O9reUgR( zJ2uC-~(p?-5W~82hJwr6paOTaMddd*H{CRmVj^o46Gucj|L2^A^~9s7oyyGS815E zl|^HN17Lhr37FqNK+@*r0J?XE17Mnh_cbDE=^`8e3#v)PhZ?bIWnCjh(jY-}+bg$^4c0?JW z`ml1OP4;{Lmz%BJTY6ZNmWnuVAYihB5ekx)%QhSU(-d5!AZeK;3J1X4Ix^6&6eMl^ z$h5%$u(GRw1N9q4T4qMU0nkmskFdW9%pOjIRy()=)d|Xxww`5_<|34vR$KNwY1ue% zAmB0upScJ~S_&+eYB*7KR}Dzo`t@jo0|9dt9IhZ~0pS2xnTpBr=h_OAmct4TfPo5n zDM(r(!U1rGf@gFrqy>ZnV48wA6eKMm8~|@BxKNuWEr$*q0E-lK(j86OEaXB(Y6s^~ zUk1HaPZXq0$t*enzyWZ?%L0C{0ZE%XoZklrz?%w&DM;FS6ypI0z|aN~@v?%U4NUz9 zbQ7RvVDYN|RxG}Od3>I(DzJl#Z6x8gDMwn~Qo{l8nu2x(Ny{q;H~@MzmWT-ok~UkY z8jQQz!HrNIrQ2{sWAiwVHZ|=3ak?-mFI37`+!3C}?*fek3zmXgrVEyy(R&Bd@*n^X zfLPg-S32c@q)ql3+9z-T4DphYIK3<&X_>tX2f&K23fN6S(#D@(-@*YfQNb7mNy}7Z zIQ|1$NyI2U2Pd}DBbGi`UpIg$s&DJ4Nz16=09d)T{Gq2dO zJ=#db&lMysgMs5eu&scb_3PK8Eqz-kch!SFyfBz!s{81ukF_}I7h+e3X(P@v|mi{WxA3LYA0d-)NYZMm+o*NjH9=J2NWbN?ZE*sNx=&W zl9q2f900xAOTB0eUwy%H<6eMkW^UDi30LJ(U*ik{!*0WF>900@o1stLW zHEH8a6I5+*0K}riyht&Bl}U59MI(1ztQZ^?E9S+EnTvhhJibEb5ZJ-xb(V%3YQv;u zzrX=7sEdH@6(lXEO*jB1DOgTH(sJy;0WhGeL_DWABcwI)OdSCCtG=(`{;tOFR~ifK z;Jkt)V2Iv;kv9H3sTvM|Sh<;3a^{Ug+In?9(z12n z0O-?QB9>Q>v^CGx1_!`n3ZBs$Cerez0uF#dy6p5_1xd>ugacrjg5TmUkwBilXM+PE z7P97rt$Fj1mZ@fN0QBxHgUQgQNy~PG1K>#ox9Dk!w3$g0wLRbfIHQk59HW=W8GVf3 zHQLp%gG=itT%2;GO(s`jfCFIOAOVLfNLn5Q!2z&P!FAfj!a>$AArIKWRURw>tLs;~ z@?ha$2j`_+fHv%<9PHrwDA!ZDKEl~x2N$8-a_t{!>nEuP8~|e#9IIgLVB>e1E-7jT zmZEyEUdu?!9X=cY_bYf#LDF(72?xMq3f@oD#BIhvJ!Rf;44!qDhbEM_x4;%nvBp|-yiyuJ4zyNE zql?=;^XpBz)ty!9`PR3k^eO9kSFM}6VEk(V(jC$=;};I}8!O54%JS9#-!*Z!Xgk3E z9~Z7)Gk@j6&BbCmmedUFn(9Dpm$Wr8svaBwy(dUKW9HnU+FQXxsPlD2YGZEyfA zRPcgs4AS!691eg{krL5ew=QWbN8Sbpz?+i=Y_1?_)AAq<1`dF(Q3AG6khF3Bj6gU5 z9-Ag$Ck08H%<1$>1P%s6`G533*Cj7LIen*;4l}Q`r`u}EB%%3&#qGK-z%jbnH_iO$!=D(^rxx2?6j{4Kq5D%`I7)Z4&(aq++=5bih1qeBHr$~35;sQQ5|frE z#&DnmsR~9aNLnTr!U6D!f&;3{&`HaEFC71YA4}6+0e-C4`zPuE==h0%6BQ(FN;tU_ z4uB05oTVUXYo>q)900L|E-$Ie=a(d^LbS)Jv5&5#%h>Y=;hj?3uIaKDw{1JK;{k2U zKH7YJI(|4RX}NcT1I_0vxRcJT43d_qq;LRCp>;0!^ECxY%j|nN04Bx?cu|`sZO!|) z!2vMvQvr`FNZMp}r&Fui!Szu+`F}bV;`n&8!2xhloCKs)eQPYF1%w0O$%O*G{-%JW z7T&9OQX|r%OH4O(quO$Mu(}<+yf({43bOn28`UGjSa2-X217OZFiFj1E zH)%6-2Z3+^y!M%Z)pYZamb+g#0EVm(Fj^y$=I>V{54D5ar#i5`Y#q|_x&sb?PZV6= zT|m+%^K0rN902#lOUqLfByHAwMIami`+P2-T|v_Fvjh%+4~&4X_mZYb8~<1ui`v0O zB?$M5rcaQzE=0!X5nW23tP*bxJpxHv6Jl&|AWZ+&0>)@_q>VEty}$wRfr5)_X}<`x zl2zdVn7&3L4%3LFt@{sOI2e5Xi@&JU7yXA)`X}?p-}J@zN|d+*aUdqXBvbq0KnG?h z_?EZyl(Z>{q9MTnFl3!X?4m;=Ef2!s0GRNFfYTKuEthCG03KT}pnFYenzTGyfdk-- zF9n>Xhc;;`-31509?1fZ*QQBZpa&cPT{j50pqVu7y1``R(_NaHfhDS5tr%&UO$P_S zw2cz4jt+&iDcL~Bq1wUq*(6*^4QZFO+>5~h&~3ATujxogo0;2qN^1$f>``y9dP!Ra zBz)oEFwY+~uPlG@@(@}|e`qE@rlV%|7HRc>c8|36!`K53bgxjs$~xY{E#~55x|x6- zT;5g*_>*#^P38jn6$=MIx9tLURFKM}3@@R8u!CE)L%3tgk(S>XZ~!daCE#%#3Tc@r z1qZ;R=>lHWh@|Dm8XN#~6#QF3(z1R79005DmWVwSBrR7yH~^+A_>O|4Wxfy`0KN7| z#6$&23kV0mWCd^Os7cES3J!oldnMvI1xd^G9u9!j_X*fY4>i(OeuNDUfU(~QxIp_z zT8f&$0dRJPfE6|3>Z)MHkljg%mfF(iU$NtQ;@U;j)sH5=f4dX zm%sRJsQuZCx)EtkU`_luFr5C>y5Hek-}winq5FEnN!n!7{6!la=+TqI0w(MI0%m&Rzwdt046Btp< zZf++LNn4X}J>URXtYEr=#W&3A3N&cg!8N}l0Z-~VlC*i5mTvG+J2)TJ4>cZXD-qWQ z2SA5PQr&Wy9=fEhQ-CiV3_gG8ZZCDH-Y%v8G&?HNp__D9I_jz4M$%IE0uFQ_;J$#{ z^<*A!-_)-}BZnQ_pudDmtRX@zU|!519os(PQr~;F3ZUbuS^4l9o+sZ z!lmn(j? zwrM5c4Ro=Uqm>S9g9BjmHUj1;NLrr0!vWB-t$@cAByByQ^?(Clk%BJzV7aKRsb8H2 z4Li7~4iYdypZk-xis{+l0GQuVz|q<=X{q@E2S6`h0f*|=A#E~G(RUpVfPEBPq!Ii0 zn))@Ui?D-h9v}gG>48Jqx~SOT09c@4sDh+T$$8o@Z~)AGT_V~QBrQMt-~d>lU_2rc z$ji9f-~jkQ!A%O1mY2nF04!GUpn{~0|5bWepmuO+dY#&$*D2ESd>amc4o-4G%fbcC ziI&deYcm`GM<{qnLDJS6QC~P1eE!P!X8emcZF5TLg=R-B=eji=-q4My-&cn>%tfl$ zYl9u_2X_;0iE^Zk^J3~K9RGpc1+3pmP5{B(9p%bLAFOjZKsQ?6l|Qf7h@`EDlpb&Z z3{`NH-dBe9Fc)2@i?D+W`kw@x(?wb)EqPOL0E|$uP|x0^wl!u7#Bts&Gy{s9aJz|>&^hAT)~a+To#81c4%r?rcurBV(Y04u&D zV3>lWtpX7?H~{u}SHR{9k~aPu>5Z_Mfu$%`q8MrUTEhWwpMt+ANLo%5Z~#22;H(Neu9bBJK;btmF+W1eV zcGV6pL3OBdq~!-K900?{NWhl5^GM5YKsW&QA1h#QjYwKvIluw%q=Ky!ByGLY^M!-K z=g&L8mO9TgSoz|4$kXhoPj}p&)M=`BBLGn3}Dn0*bLtJjPT6R)FwLu13N_33S} zqj&q1JNAa`IMVV19u9zm#!J9yodqN<=UF%arYY#J53EUBlXq-z02~o65pQTj($+IY zZn;0Oh~ye>l}EmKC}0GOrV zkAVV`mUpXg{0Bxz(*e4bvm$8Y@eDxv@WLs5|3uN}^k5+^?|=JRZ z?m^O~(r?rcu&CGn-IBEyy z8Y^6h1|%)-1mOS}s^BY~Ww($P5DtK83VLYEq^`*vt02uh0fCEBgGm@59P;dZrT_NB)9Sdo>GQ$Dzrh=RGtqo~8YT*Ewyiy{L z)`+C#*$5l}^FJ3bQu|2SyiAoWJ=6{^c$IL)8j!Sk`zZ|?4uGMn1)QS+Nz1B8Z~#2I zM!?w`k+js~g#%z}qJTRTOieVyo6$o9*ufRA7w#9m87N+FRugA~9b93uaJMxcY1z?m z08HEZ8b0PL|vz%vSxwvHTMI2e5X#%e~X8>wBT^g%QE75YKvnksSq^;eK6|1K_^B5;0Rj(sHhY17P)i0&XlTClb;!iwh2bNea%*LNt|)Lq(Ra;YfK$zFfdEN#kx&M%grAg0D~1AsUT?q;Q$z^;2H%<3kV0m zSOsS&NLqe6!T~Tr!3YIOOGG#TrYZP@44(9lv{ka+0}g=I56h^ZYW+>v4w%8~~FQ{8)EP@?lfIp>tyoH3OTWPnaI+6DHD9 zJbH$cS>48YhfO!hK>V_jN2QnN0Lykzp9TX%j=L0wZ7AZJLLDCWt4uCO7C1NuLNt;Z5+^2SM zF5d|ksvK!)84iFc3RY5(v&Zhfo+ zm9#toh67;MF#*fz`IodT!T<+Ax8nkSug4W>Ik&+9FipYYZqhVq>j98291K2xse4fB z$ZDDJ;*sZP&Un+Mr|5)qV1Zr$NJ|PE9O!`KNdaAgqywa_d#bXuw)*h)bVGv5N*>ga zYV=pvw#n2H-dL<7e=w`tJHKm3iKtU*NBOJ*)u=U9j{b)KF5nA^Jh(H)#y)$D&+M#K|kxuHdICZmIMUpvk^{8E_hco*DEb31J2=mDrO*3&yRcoWR2?{ zmpWzLAl_tjbZ%u&y)GT8_mbE>X(~Lq9XhDapQBqwby|#Q%8;<)N2cRRffygutwDyE|62LHW^SDhb!waK$Uf(ed(b0{8@I5t-RQmt(S)RZ7Oqk zi8@$y@n-Qys!mK1y%hWg(O;{M_)7F%=&wbe6>WF$P8LIv0zP|0yHwB)sP3RTKUMtw zROf6JJzI53y67a;F55*PRvo!p^i@l{&{4lj417xD5oaAUxBZ-3y@ur&`QDf9xaH+r zSJt>=<@wsILspnx{?3i;czwWA_Sue^`aDydH71DXs*XG(dw^%|vmX=oxdbL2F`h4jZ_DIN5mShhIsk~YfQ(e>@3>xq-+5< z)lqbbAk3kQYKQBhCy=&tfUtZqELEWTRneKM({G8st2+NT(Y&&~)qz6M?Noc-5j_n0 zvgjGA=W7R2D%1Yw05`RP6ACQ5DSz-twd*y}wko;>eihwab)fR$s*Cf)KUa10A4IQF zoqJsLjw-bOxdUFh1+o+fIU&GV1UN7HhU%aTqMxZQxG1_#Rf%`)u;}Kh-Eu_xsh*!J zdazv$fycx!Np+S2%c0f3L3M$S;Ct1B&dT4PQ~lta=rYx$L;clXM|HAp5&NrZnDLYR zL1)#D`Uj&`C!G}k2dYC)iH=j9a9Z?s)sgDIsJe#^;DPG=AFcC<-Qiy~0d{4>^;#M?4wKtu2`26F*4+0s$^FN-r&l>afdGUm}-e-+T`#cMsHD;glJa^WZ-p&aatdWqx=`XB9?3xe5IT&m}>ILVXutv%Wr@^pB z_6w&3u|_5kPwr!lIeq+#momnoIYH#dE^*63H#~LN(xTG9wl$hh9b*xdVj%$@!ysN~cnq+eQ4^RWwvtR&aEVu>- zYn0yLQX8yMVS|f#utp6JE*HWYRYJHb2x}Ar;Q}SBQI{mzRj>aj^2c@i7(lr`E z$Cc(-qre;&lw*xLa$IA?@@vfzuJOVeHD9=t3u}~cv2(Q;HlRoh*P~&LGBjLvhBd0q zaG@O5VOltcOMJ3MX-_V^$r|-Gxnd`46zb%9o2<3Yrrm*yXt4pcv$(tzYgCoul31)! z35%;ru|_c|u7t%J1+ci76l>Iw;sRK#6SW`~*N|c@rK4#7b0H2kr0Ca*>us<`nGG(h z!5Y;xxOxU_RMX%>Bdopj@427|>prTv0t#ysKH(B8tgX^2eEsLLWNaAGSPn9-t-=~5 zRk-vUYgByW%9E_y)DWI)NV1--wIaEACTrBpY&avhabk_Bs>w&TXbwIhC zC+ol}(f}7DWL;Umrd&CWH44UYp*Gg2&&KuGSff50SA1iQLT_B6jx|-LYiym%xxyS9 zP;rh+$+4zVa<_ZZ6B$%u|6e1qyVQ}DPs3C@HWfWrbzvFNn^hl;lbh2_)vh0jKC3#Z zq44)r7tup6YTm)AvDKd4p|H6a8i~Q7c&KPU)i)=J9;!OAi|DDUAG8;}NOfKZ(K}V= zHxqqHb-`%Se_Ps4o4&6Ys<_D(NS`g*rh5Mz(S22W1&JQ5dPY~#vs7pOAzNUh>ZoGT zKd5&5NAxw;e2^sE6GIty>A-$R3CM*YcvqnS#1PdLwSf;+J06g~U#+?*L-ZEaF}e#+ zsSf*B{J)a6E>iJ@Vz{Tkj0(~LE{V?_Kq-7KeQ$M0Yu>k4jnel2Q|)?J;)SU8{!{ck z)d|l;(>gSAk-`ErX$o8`D;>C?x^S-OTdD`m6J6dW9ST|?y0L1MllNDR3i!iRJJN$N z8kfU#8|{A{kxxA_tXCjjzXiKhdq0&PpHUrAMfjVlQ!9!t>nZWP=_L_2&{lP_hv>el z6CX*uadtH*tQsZv&#Fdc{bJQv3*hA@(t(P4Obt+dtfs{0B_(*kSV_V@ zM-5n!f|s~p04rPYN*1iKf<>lkFWtvKs!pjT4ct`Sr-A4yP37;sie$u1R0qo6J3IKP zA?CVS-It!4VZ}OLMUNZC;(5GS9&4HO8f#^6wRF-iIZ(NDzkbva)Pv_b?+l{uI~S6-{!jyP-FDWfBozaeg@9uZ;c_ovf3)|TZ3 zbU8TI&E+M3S!1PNUfGv5R{G^Nm04pgWnMd(HI_`~C5TyL>0w@Km^GFd<|UL#+a0iW zGOy;$02XoXs~SrK^V-MkZ_`+I3oi}K8Y=>CQ;oHgdF^HPV=ZQ0%APfrurJ$!HT_^I z&X5Dp)iTiTJ7IdsZ&sDu>mFNwsy%I#HtM-YNW0Kb`<^f^7 z;sVu)`u9bw`GV)RT>?~kRsJAlzi6B4m;<7DX=M(G6_xv`PQ57pDXO!65xrLR%`2i0 zL0=Vpi?nsYtDG$c$5zrn@@dh{RQF#iI!Lu^lIZtTN2;EyI_jYKjp`A{MW?II(k+(P zN-ubh^hS>c=5Swu_&uVXTT6#>zY*O`b%5?eUS5m02$t0vtU6)0@N-n>-xR$;^|3V3 z*{$`0m%2j?4-`ngA=;&lZV~NqTh%_d#otGD&K=QXRag97^rxzWuZ!NOI-p4O_jWZT zJ{H40)lVLXez~o5AmlI6JyfIY&Op_X`f8MyH?|JCVe&2F$^EP`*`FuzTmJXtiJhI- zm}Uc(mgcpoSz}FVUi_Lh7QN;bq*-I-XkICrH5Q2GrKnkB1!`Utn>E(L<`tb;>q5?U z2VQfS4OnWJ*D7X>wTmaK#Ec{chczncZ~{7O@a0kcN(FDDAJMuH$`ezHcwCntEa zMq(!?NwP+6BxhH$Mp7lGWs)A~fOJgGV`c#9%Um^)HHsxxS3O&g(t4`*J(eN2R-N{b z$rwiW175yjAFKBLzlol%`kHD^B;|IHKgt=XtdV%SU3Hl9->ROk`d8Hf1rq;H(KIDN zfr>s7Fimwc)yb-ZR2N*70R2=uUK0Jb>MT7oPEZ}Me!J=f^)InBT@P-mVS@rU^<@ZG zkK_@eXygIagYu-oY}NbDi@v1#f$Be1S3f8IGQJWoSpC&m^U)ov1~&zc=^wOK-N#wd zCxcWMtACK{$g|SGDAhMrPgmVs2V z|7F$5|A@Y?+FOsk64fqx#^ZEp-l9m8rbI&d0gMDf&WU3HIdYsp$Qp@*oLpz^l6Ry* zyK3Zda^5EUk*>*Em#mR&$%%%Rf1v#RX+OOmKsFyI(J_GBInKUgjiftHRc4J8Wllk3 zjm$GnJY1sU{a@D6>!Oja#5pGH zM`{V@XjxZJByDl3niXJz>&H>iJPMasltCM&4bCY9t_W!Vz~6c}Bsik;XVpHS#T2b++pW!eyUlD$qcW0nV%B zfFsoZOf?eGIB$Xd$YbDq2iC}Q;AzpUF&moa%d^Hj`8lts0omazR2S$S(puHa=9~JX zXtEa;cW=~H0yUo}U&o%RXRGEMJ8mc^#zc>z+lc*oKG~u6eZlf~CsbE{Tl6*6J`3cQ zknzJ) zm+xkcRlD<4=P!^w#Wj!Ej~Yl^eTlT)0acf{>=6T~cEpu*S);Np7p7&6dbFIF!y1V? zF{)7km-9o|k9-j>AjKMWqxM+Zg}#rG(nFs3&w$%;b9)?ZnTm>>Owt}EmmEyT>R@)=d2R_qiDLJSt|x!=AJu-)$KVsf;Dm? zIOl{lQcXA=gEg`+IMu}Bzm;nf=YOz9J_u)+uts7DXK7eBG|0~2%n}BWP{N5JtdS4G zivqL8V!*sSF>5SK%*zn7#_GfAs?&3%L*J_oI3=1F@3n4duxc-_(#rv`IxlA(u|~EL zmzrjc3eyc#hs>5O$mI{%kE#cp9L5^SVqD3aH41ohecz^RKwaO@6iB6;RWdsys}AU9 zT7)|{dMk;})oeef_6GE=V|`sUe@j{ar8-GP zzD3Lhs-Ca9m+C~-LsZXD9jcnY#r*g0t4{4{>QA8auopc$WBW3-7xy&7C(uoO5q&4v zenRaLboyg`S+zHv-&sFYouvFz`01{L{gwL3I19D?I;xMUc2m7ybt};?Ipp@-+akjG zduJ0c%Xx(R3HrKb)4x;n?==0(p?^H7>nHm6GyTimJ8g!ue;MNz<6LoXn;2)uGENb- z9ULaozXr9<_tDN>%HoWbp z75Z05|L)O0H;4Dk(@y2<>^(fodGn|;-X@~Jd7jDr&AG~;Cod3zZ% zp}@JixmVy^v!<`ZdmnxnIdaO>F|9_w9}(K>wKit`RcH6Tu2-GQw=-^aDt9aw;#St7 z@`}Udo7l^hqZ5+#Uzx~pBgaOKnHuFV=d)o)YIgdi#J|$%({H}hF>?7wpSx9=VXIRx zrQxA2gRUeu*>Ppj$rOzkg7ByWjioOgZ{h zj_=>G>9{=?zQ0vv)3`%dUiR?68@xPtci4!Rw)_~=DyA@X$=|K*$J2&SIym4v|B%!x z8D01MWJcy3=u{l^(WJh++dbX((~6qDDS@kwgbZ$9C&u0)y69q?51*arR}woT@ZHQR zn?`gnV{d1qCqzGSa(eJ^uj7h)?WczC4PCbA?N7HR)QI?F?H@{_Sr z3+IZ1s?C0X&*gf1Y7P7$e`Npd$6lX0dF7PsZS9kLj@*1`>);;GHm?l0^!c*}^Y^tl zKc)4gtLH@^E}?cjG;RGt2BwPz*M7tHG( z{kcc$#EqE~uXbElKIi&J6VuC$e`!~*e?6BJU7YJ*oMhHNNy@AHX}_3qy`8`O*ViYr zAmY9EW)@cM*Z*AQm-}9Sbh2IWVb`^5_Ux&9_}=;%E27@)@$;B;$Kei7z3e587r!w+ zE_|rjR{8wl{Lo4GiBuxHsmh06!N`%~0{&-T9-ni*aHX6p`L znp)jnn!e!;k1q;dEfYNZ-IhT&GS?*gz31CAww;&v#^X7YuMDX9?%~_#&v$NIr@Ys& znIV_|om!H3+jCkEDQe`}6^TxeOmzP$LOWt|?X0x8HhNm5Q*?U4#o2iHUcK+D4 zYTH?15!Kz76^{t`clh5u-@mlWyUDp0uIY!zB#xQ$&4eAp>b$d}c3UsE!9xc(>9eXh zI-+8BQOJgFB$b_j*K=F)NubLok1LF5IC11_Lj#6S8h55b zkbVBvehaJB4LrExUDNF3KjCK_T(j<%{j==T*9Kha>OU^qabW)si_+TOuDa*FY3)5v ze;*j$;oYdrxck1NhV1gYRR5p8l^SKY82w&V|3y<@p6zwo;hnve!kx;-{M&6n&l5Xd z+v7Q9^ysH6KWHD*=vY$kr*1A2F1vrae_+J&nW-~Q)I8%7nrz>@!Pfs5=hK&(3?6#R z=Z*J&D|&ZrTwc-N&PGymQ( zbM*FtMyyYr%sXQq7?H#F6ujnkvk+kmdd9-*y_6GrLMol}}BdAKPvt1rsuF!G9_0#za4-KEx za@>XJ#UXp#>n%EaX427b+WV~Ew7t@v?fouZul7}Po%XR?Z`s z)OXF=4$i*?e_?;^{U-w+F4^JL`B?ac{|$>6aN9Mn_OPZk_HJ_RwkByn*(L?|A}{7f z2cBN}Z}G{<6J1yIoL4e6X8QIN4Lotmr|$CmSc;j4~X66d7@vB+||GS_V?|@ZLSS_bH;$5J563xzRa7;?LAwU zd-Pek2T_6D|2^V4r`)6FPWHHuJ3mZlw{qww;rA+!>G7mZ!}F;Z9<~`-Qhm$N-=b^v z^M5s|*Yx&-f2w)U7PDr=mNV1eUUK#K_^UtPT|K+@#ivt!hu!>jP08)OPPKwo{t)v{ z7vC*A9-n$NwCjpyuMYj_;gsoDme=&{w>mxhr-egXwmxFd{j}w-XOX>|eK2;$k5f*k zKHTL{Z}riHtS5tB{=C8XYQs+~n40`Y@rGMZQf_pt>^r|f<9jE(Vjoau(Qobx0=Ay4chZ0TD}C#3?iAA?;@L-|mTVd~ zZbQYg+g|HbF2n7;hWShHM=hxRcUD1(IsbKyh7EqN;a{+K`sA;&e{a05!;*kk&tWoYzGK^{cCDjV zENRnbb-nd<%U?NuXaD9OM_gQ5X-EFjdmp<@b^9|Q;N+3c?P9yHX|%J()YmFicG+h8 zWbVw`%i48nkr0_b?|#hSBmKih=Qnz#`|ggt-hIFP?~evtdT^-s*`&9=39$cN_uQB1 z8I6v8{?zyIKd#L?)T@~_;rgp7mv$EA?^^v)?3v@w{`&ii72_w?-HBVjEsOv9?xlAh{o?zy z${P+2-J5J}eD}Lm&?&DHCg^qgpKxj!{y z(50u1k5;VJ>_&9>+kb59=hU*-oE9z(2A*i=ztDe3*u0@99rD_4`s;z?pZogvO4=}X zu%~Ca%O!T_{P=PukwI;1`Bm^QKHH*B`^mk(=~O0d+oqfb~<&KTNBY^r-vt(7xky-|G8hYgXd7H9LA$4G(%JJ->rn zYNxy<7YBA+v9A5neGOaA9`Qr|U$@c+rR{6tw)fRT&uY(p^6^94R%bW+;NrCDufEmc zR(xj4{j61AU(QWh+;G}^PwRKRy0vg_?_NKyJ=(A4hR45;?@*(~m&<-1=~TC8yG9OG zpFN0t6qKGf^?3Cg?xV_A{l#zp#A#zrZN2hZ|3|&oO#Xe+&5Ui$-rn@f5_{WALAU5D z+}Wwplc?A>2i~!TeOf*yzw^|aWygL|zj5RS`<{(AlOA47nZ7BaXKePQ{g3lo%$`~} zq|0|bntk->r7oY&9Q)GZuiV0WB%c`g$*Et~uiN?QuLEr1r(ECr$Zz31|zrJsUul?!t{WtBuZLasjuUF2w$GtwIeD;_w(;l8l zC|NV$`YX?NpMQDuz{DN)mZzKllhJWW^MK7g4qaJ3IBn_5Pa}hVclcrJNSFOXWA?W4 zNj$sm{K`2`Qh!^rIlaX_zhg~$y?Xo0_1WJZ?bq1%!H|XCuH))_+4-Yx;SKGrN1u&a zeD3u%-=w}jJG(;3kX{G8=SLj;Yr~d>Bb(Ph_>;sddlXd-&i{R+%i1-$&zAh! zU}Erl1HSs%o_uS4%B}5dR-d`k{+HJ~eev_UR&O-@x@zi&=iSDvuQ%+7Z~E7DzU%CI zG_r5L&sXc*kF~kK^X040!WwMZ)uiCVpI*QCaPzfJ$Itp+`ZK=y5_{aQJ6=CtGxw*N zuRmLnJ7aU%iS1ABuT#r?!u{{NUoF4!n}V{dzu7cpcHvuY-5)j!>%T5=Tfv2|JMYT* zq37(rpEa7^C+^2qKYbg#`c%dj-LKT$P;##FYnR*kebVOE$PP(eemY+vxn{f6o?qOp zkk`Iyy+6jkn$p0(`?_i$jT-mG%)Wis+_-#XhrQyz4?CX=*f=@3*VCx8Z?Bp%;8Op? z=Px&yu<7Hg<9-O4bS34xKU#kN<+>4T?!+B ztz=Wt%TsdWcju?4zH-!l%iVEg*)wIw4Z8YpZofX~YJFj@?OSp2&EdB;o*6pm^F0lo zO&w9O;bD83;Pq$j*H}#n9ON*e$1~{cllhXroih?)>X=`Pum7x!XV6+b8Lp17|MOD6?|j-ErU4 z-qO|o{|nLvE&1U)5eUgc3M(M;F947IKPB9Q(h83wM9a%%OCWeOJ`Yq;ec-}Fn?CeW z5C^qn<*2cBVPTaQ(L_3rO6lFa4Uew+9OFN4((6-&PdXYZVSlehwJ?s+&#e{Yh#Kp@ zd7$o&Xc%*x!=UoR%DfISRuZL+zGcp7KM*9-CW#}mqCycLwMt#mWLHnoyj9H?{Y?+8 zZk;ayD#ZM^&;*2;w&0Cf8BPH2arzTYya&{JP)%r_;&{Q&?RdPS#Q8EQB09k+EP4B!Dkq<{ay8&sDQmX$~QT!ZOHbZ1n206H_L4GB6Gv=6() z)Y#zGXYife+Ox2L@KaRH5Z5_mvtlzKp+Xc;uYcv?Aa~OW-{9^ za{8T%Q#_NxB`H@C`NqpsKUt5QAg;Ib;Uqq0L0WwQhty_h1R~WkzUPn&HWlNl+ zZ9SKDBn%*bh(bNsTxM{u7u>gUK;a5`_5!HlQ8(Ye35&FirAoW2C#~xb)*#>#L==Hu?BjY zw%%mN5UH?%L1NiO53N!=4se*^mKKi{^;4S?afYQ3K^1Mp9rja$eAv9fHl1Ang-2cB;Vq z+SGu5l8($~Px{F23O-#h+8j+3+C^SNIA7wlw(JTS5yz?N)SyVhi(5I+?hy1TJDdNb zG*fZ1W&eSwGy87lo1$$27@BDiUdWWprN&QxjARQO)$x*GR#n8UMd4EPMQp`FP z=#G7)Ieb!YO;OV+I%;@aiBJCI%Hv9$Ria>jvcuSYK_IIiXEXsXVtI1Kj#5(afLxEg zVk@c>Q*N7v9RdCnFwOD=43&13oaFtYEfy;H3istp*a2tL!9pJGCJ#f$(U+#);-7Jm zS#JI|SJawVCMiR?A~9@}rJ`hYMiQnpsJX;d94N5d4IG<8C#2T%?+za0?={xCy_WwEl-{1d}zA6Y(18R5@*z+af8qsiy9q#SKMc{Py(;akH+i} z&;ng?^ms`joa$V>!nGoVTISd1Z6kXRO74W6;9kc0^wTzus;6jYvW8ukHDx=09z0ZyCY;DCw&w9Lv?yAT@x?Ni4Dmtmu*m``} z1b1seyW!hbcy*;tsLW~8*La2mcgEKOD);l&E*$t$OsTG7l}+zvPy!dd>q|#sMP0hy zY9;Z@Xii0iXr2KiOXL`a9H85}Zr-gCbOW~caLk~eRlXzkS8Bq#42t1@vRyXg12`~9 zv-#iCT$xv@F7fD)yH^DbtlsoVFpYO~j)V1oK+(9RE8W-)-aXS4IRM|o;bvL(6n(c3 zi>o97+NNProu~=|-%=&kYz=t$Ix%_2*5PFBe0Qk3KuCy?Ev80bYh*RerU+3&0)aYA%W|~vL@J~PWzglWmO{s_v*8xFGE<_-i+*BTSVJQ>Iz$!b rpa?3fv=!yok~cH$+8~Wrz}){d2zJpcWL0w5hN&QwaVnq{&;S4c4MIIH delta 162715 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

~u)mk3 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 K0BYA#0002}2}XJV diff --git a/src/bin/pgaftest/test_runner.c b/src/bin/pgaftest/test_runner.c index f3635289d..f94c01796 100644 --- a/src/bin/pgaftest/test_runner.c +++ b/src/bin/pgaftest/test_runner.c @@ -351,30 +351,81 @@ wait_for_state(TestRunner *r, const char *nodeName, const char *targetState, * SQL execution on a service * ----------------------------------------------------------------------- */ -static bool -exec_sql_on_service(TestRunner *r, const char *service, - const char *sql, char *outbuf, int outlen) +/* + * escape_sql_for_shell — escape single-quotes for embedding SQL in a + * single-quoted shell argument using the '\'' trick. + */ +static void +escape_sql_for_shell(const char *sql, char *out, int outlen) { - /* Escape single quotes in SQL for shell */ - char escaped[8192]; - int oi = 0; - for (int i = 0; sql[i] && oi < (int)sizeof(escaped)-2; i++) + int oi = 0; + for (int i = 0; sql[i] && oi < outlen - 2; i++) { if (sql[i] == '\'') { - escaped[oi++] = '\''; - escaped[oi++] = '\\'; - escaped[oi++] = '\''; - escaped[oi++] = '\''; + out[oi++] = '\''; + out[oi++] = '\\'; + out[oi++] = '\''; + if (oi < outlen - 1) out[oi++] = '\''; } else - escaped[oi++] = sql[i]; + out[oi++] = sql[i]; } - escaped[oi] = '\0'; + out[oi] = '\0'; +} + +/* + * parse_sqlstate — scan output for a PostgreSQL SQLSTATE code. + * + * With VERBOSITY=verbose, psql formats errors as: + * ERROR: XXXXX: message text + * where XXXXX is a 5-character alphanumeric SQLSTATE code. + * Writes up to 6 bytes (5 + NUL) into state. + */ +static void +parse_sqlstate(const char *output, char *state, int statelen) +{ + state[0] = '\0'; + const char *p = output; + while (p && *p) + { + p = strstr(p, "ERROR: "); + if (!p) break; + p += 8; /* skip "ERROR: " */ + /* SQLSTATE: exactly 5 alphanumeric characters followed by ':' */ + if (strlen(p) >= 6 && p[5] == ':') + { + bool valid = true; + for (int i = 0; i < 5 && valid; i++) + valid = isalnum((unsigned char)p[i]); + if (valid) + { + int n = statelen < 6 ? statelen - 1 : 5; + memcpy(state, p, n); + state[n] = '\0'; + return; + } + } + } +} + +static bool +exec_sql_on_service(TestRunner *r, const char *service, + const char *sql, char *outbuf, int outlen) +{ + char escaped[8192]; + escape_sql_for_shell(sql, escaped, sizeof(escaped)); + /* + * Always run with ON_ERROR_STOP=1 so psql exits non-zero on SQL errors, + * and VERBOSITY=verbose so SQLSTATE codes appear in error output. + * Redirect stderr to stdout so both are captured. + */ int rc = run_cmd_capture(outbuf, outlen, "docker compose -p %s -f %s exec -T %s " - "psql --tuples-only --no-align -c '%s' 2>&1", + "psql --tuples-only --no-align " + "-v ON_ERROR_STOP=1 -v VERBOSITY=verbose " + "-c '%s' 2>&1", r->projectName, r->composeFile, service, escaped); return rc == 0; @@ -433,6 +484,25 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) return true; } + case CMD_EXEC_FAILS: + { + int rc = run_cmd( + "docker compose -p %s -f %s exec -T %s %s 2>&1", + r->projectName, r->composeFile, + cmd->service, cmd->args); + if (rc == 0) + { + snprintf(errBuf, errLen, + "exec-fails %s %s: command succeeded (exit 0) " + "but expected failure", + cmd->service, cmd->args); + return false; + } + log_debug("exec-fails %s %s: exited with %d (expected)", + cmd->service, cmd->args, rc); + return true; + } + case CMD_WAIT_STATE: if (!wait_for_state(r, cmd->service, cmd->state, cmd->timeoutSeconds, false)) @@ -474,12 +544,33 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) case CMD_SQL: { + strlcpy(r->lastSqlService, cmd->service, sizeof(r->lastSqlService)); + r->lastSqlFailed = false; + r->lastSqlState[0] = '\0'; + r->lastSqlOutput[0] = '\0'; + if (!exec_sql_on_service(r, cmd->service, cmd->args, r->lastSqlOutput, sizeof(r->lastSqlOutput))) { + if (cmd->allowError) + { + /* + * Soft failure: expected by the following CMD_EXPECT_ERROR. + * Record the SQLSTATE and clear the output (it's an error + * message, not usable result rows). + */ + r->lastSqlFailed = true; + parse_sqlstate(r->lastSqlOutput, r->lastSqlState, + sizeof(r->lastSqlState)); + log_debug("sql on %s failed with SQLSTATE %s (expected)", + cmd->service, + r->lastSqlState[0] ? r->lastSqlState : "(unknown)"); + r->lastSqlOutput[0] = '\0'; + return true; + } snprintf(errBuf, errLen, - "sql on %s failed", cmd->service); + "sql on %s failed:\n%s", cmd->service, r->lastSqlOutput); return false; } log_debug("sql output: %s", r->lastSqlOutput); @@ -498,6 +589,28 @@ runner_exec_cmd(TestRunner *r, TestCmd *cmd, char *errBuf, int errLen) return true; } + case CMD_EXPECT_ERROR: + { + if (!r->lastSqlFailed) + { + snprintf(errBuf, errLen, + "expected SQL error on %s, but the query succeeded", + r->lastSqlService); + return false; + } + if (cmd->state[0] && + strcmp(r->lastSqlState, cmd->state) != 0) + { + snprintf(errBuf, errLen, + "expected SQLSTATE %s on %s, got %s", + cmd->state, r->lastSqlService, + r->lastSqlState[0] ? r->lastSqlState : "(unknown)"); + return false; + } + r->lastSqlFailed = false; /* consumed */ + return true; + } + case CMD_NETWORK_OFF: if (!runner_network_off(r, cmd->service)) { diff --git a/src/bin/pgaftest/test_runner.h b/src/bin/pgaftest/test_runner.h index b2438824a..a74235078 100644 --- a/src/bin/pgaftest/test_runner.h +++ b/src/bin/pgaftest/test_runner.h @@ -28,8 +28,11 @@ typedef struct TestRunner int tapPass; int tapFail; - /* last SQL output (for CMD_EXPECT) */ + /* last SQL result (for CMD_EXPECT / CMD_EXPECT_ERROR) */ char lastSqlOutput[4096]; + bool lastSqlFailed; /* true when last sql raised an error */ + char lastSqlState[8]; /* SQLSTATE from last failed sql */ + char lastSqlService[64];/* service name of last sql command */ bool composeUp; /* compose stack is running */ } TestRunner; diff --git a/src/bin/pgaftest/test_spec.h b/src/bin/pgaftest/test_spec.h index ebe7b1639..2d420305f 100644 --- a/src/bin/pgaftest/test_spec.h +++ b/src/bin/pgaftest/test_spec.h @@ -100,11 +100,13 @@ typedef struct TestCluster typedef enum TestCmdKind { CMD_EXEC, /* exec */ + CMD_EXEC_FAILS, /* exec-fails */ CMD_WAIT_STATE, /* wait until state = [timeout Ns] */ CMD_ASSERT_STATE, /* assert state = */ CMD_ASSERT_ASSIGNED, /* assert assigned-state = */ CMD_SQL, /* sql { SQL } */ CMD_EXPECT, /* expect { text } */ + CMD_EXPECT_ERROR, /* expect error [SQLSTATE] */ CMD_NETWORK_OFF, /* network disconnect */ CMD_NETWORK_ON, /* network connect */ CMD_SLEEP, /* sleep Ns */ @@ -116,9 +118,10 @@ typedef struct TestCmd TestCmdKind kind; char service[64]; /* target service / node name */ char args[4096]; /* exec args or SQL text */ - char state[64]; /* expected state string */ + char state[64]; /* expected state / SQLSTATE */ char expected[4096]; /* for CMD_EXPECT */ int timeoutSeconds; /* for CMD_WAIT_STATE */ + bool allowError; /* CMD_SQL: don't fail if SQL errors */ struct TestCmd *next; } TestCmd; diff --git a/src/bin/pgaftest/test_spec_parse.c b/src/bin/pgaftest/test_spec_parse.c index 9d65e5a06..fdaf35afb 100644 --- a/src/bin/pgaftest/test_spec_parse.c +++ b/src/bin/pgaftest/test_spec_parse.c @@ -1051,7 +1051,7 @@ static const yytype_int8 yyrhs[] = static const yytype_uint16 yyrline[] = { 0, 605, 605, 606, 610, 611, 612, 613, 614, 626, - 646, 653, 664, 674, 796, 799, 801, 820, 821 + 646, 653, 664, 674, 829, 832, 834, 853, 854 }; #endif @@ -2031,7 +2031,17 @@ yyparse () TestCmd *cmd = NULL; - if (strncmp(line, "exec ", 5) == 0) + if (strncmp(line, "exec-fails ", 11) == 0) + { + cmd = make_cmd(CMD_EXEC_FAILS); + char *rest = line + 11; + while (*rest == ' ' || *rest == '\t') rest++; + sscanf(rest, "%63s", cmd->service); + char *sp = rest + strlen(cmd->service); + while (*sp == ' ' || *sp == '\t') sp++; + strncpy(cmd->args, sp, sizeof(cmd->args) - 1); + } + else if (strncmp(line, "exec ", 5) == 0) { cmd = make_cmd(CMD_EXEC); char *rest = line + 5; @@ -2085,6 +2095,16 @@ yyparse () else strncpy(cmd->args, q, sizeof(cmd->args)-1); } + else if (strncmp(line, "expect error", 12) == 0 && + (line[12] == '\0' || line[12] == ' ' || line[12] == '\t')) + { + cmd = make_cmd(CMD_EXPECT_ERROR); + /* optional SQLSTATE code after "expect error" */ + char *rest = line + 12; + while (*rest == ' ' || *rest == '\t') rest++; + if (*rest) + strncpy(cmd->state, rest, sizeof(cmd->state) - 1); + } else if (strncmp(line, "expect ", 7) == 0) { cmd = make_cmd(CMD_EXPECT); @@ -2126,12 +2146,25 @@ yyparse () line = strtok(NULL, "\n"); } free(text); + + /* + * Post-process: any CMD_SQL immediately followed by CMD_EXPECT_ERROR + * must not fail the step when SQL errors — it just records the error + * for CMD_EXPECT_ERROR to validate. + */ + for (TestCmd *c = step->commands; c; c = c->next) + { + if (c->kind == CMD_SQL && c->next && + c->next->kind == CMD_EXPECT_ERROR) + c->allowError = true; + } + (yyval.step) = step; ;} break; case 16: -#line 802 "test_spec_parse.y" +#line 835 "test_spec_parse.y" { int i = current_spec->sequenceLength; if (i < PGAF_MAX_SEQ) @@ -2146,18 +2179,18 @@ yyparse () break; case 17: -#line 820 "test_spec_parse.y" +#line 853 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; case 18: -#line 821 "test_spec_parse.y" +#line 854 "test_spec_parse.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; /* Line 1267 of yacc.c. */ -#line 2161 "test_spec_parse.c" +#line 2194 "test_spec_parse.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2371,7 +2404,7 @@ yyparse () } -#line 824 "test_spec_parse.y" +#line 857 "test_spec_parse.y" /* ----------------------------------------------------------------------- diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y index 16d368dac..95ab31a1e 100644 --- a/src/bin/pgaftest/test_spec_parse.y +++ b/src/bin/pgaftest/test_spec_parse.y @@ -689,7 +689,17 @@ cmd_block: TestCmd *cmd = NULL; - if (strncmp(line, "exec ", 5) == 0) + if (strncmp(line, "exec-fails ", 11) == 0) + { + cmd = make_cmd(CMD_EXEC_FAILS); + char *rest = line + 11; + while (*rest == ' ' || *rest == '\t') rest++; + sscanf(rest, "%63s", cmd->service); + char *sp = rest + strlen(cmd->service); + while (*sp == ' ' || *sp == '\t') sp++; + strncpy(cmd->args, sp, sizeof(cmd->args) - 1); + } + else if (strncmp(line, "exec ", 5) == 0) { cmd = make_cmd(CMD_EXEC); char *rest = line + 5; @@ -743,6 +753,16 @@ cmd_block: else strncpy(cmd->args, q, sizeof(cmd->args)-1); } + else if (strncmp(line, "expect error", 12) == 0 && + (line[12] == '\0' || line[12] == ' ' || line[12] == '\t')) + { + cmd = make_cmd(CMD_EXPECT_ERROR); + /* optional SQLSTATE code after "expect error" */ + char *rest = line + 12; + while (*rest == ' ' || *rest == '\t') rest++; + if (*rest) + strncpy(cmd->state, rest, sizeof(cmd->state) - 1); + } else if (strncmp(line, "expect ", 7) == 0) { cmd = make_cmd(CMD_EXPECT); @@ -784,6 +804,19 @@ cmd_block: line = strtok(NULL, "\n"); } free(text); + + /* + * Post-process: any CMD_SQL immediately followed by CMD_EXPECT_ERROR + * must not fail the step when SQL errors — it just records the error + * for CMD_EXPECT_ERROR to validate. + */ + for (TestCmd *c = step->commands; c; c = c->next) + { + if (c->kind == CMD_SQL && c->next && + c->next->kind == CMD_EXPECT_ERROR) + c->allowError = true; + } + $$ = step; } ; diff --git a/tests/tap/specs/basic_operation.pgaf b/tests/tap/specs/basic_operation.pgaf index 01f49422a..9ea95edb7 100644 --- a/tests/tap/specs/basic_operation.pgaf +++ b/tests/tap/specs/basic_operation.pgaf @@ -65,7 +65,28 @@ step verify_read_from_secondary { expect { { 1 } { 2 } } } +# test_006_001: writes to secondary must be rejected (read-only replica). +# SQLSTATE 25006 = read_only_sql_transaction +step write_to_secondary_fails { + sql node2 { INSERT INTO t1 VALUES (3); } + expect error 25006 +} + +# test_006_002: data unchanged on secondary after rejected write. +step read_secondary_unchanged { + sql node2 { SELECT * FROM t1 ORDER BY a; } + expect { { 1 } { 2 } } +} + +# ------------------------------------------------------------------ +# test_007: maintenance on primary — without --allow-failover it +# must be rejected because it would leave no primary available. # ------------------------------------------------------------------ + +step maintenance_primary_rejected { + exec-fails node1 pg_autoctl enable maintenance +} + # test_007: maintenance on primary with --allow-failover # After: node1=maintenance, node2=wait_primary # ------------------------------------------------------------------ @@ -196,6 +217,12 @@ step read_from_new_secondary { expect { { 1 } { 2 } { 3 } { 4 } } } +# test_014: writes to node1 (now secondary) must be rejected. +step write_to_old_primary_fails { + sql node1 { INSERT INTO t1 VALUES (5); } + expect error 25006 +} + # ------------------------------------------------------------------ # test_016: drop secondary (node1), node2 becomes single. # Verify no replication slots remain on node2. @@ -212,6 +239,11 @@ step drop_secondary { expect { } } +# test_018: node2 is now single; a failover with no standby must be rejected. +step failover_single_node_rejected { + exec-fails monitor pg_autoctl perform failover +} + # ------------------------------------------------------------------ # test_024: stop monitor's PostgreSQL, verify pg_autoctl restarts it # and the remaining data node keeps its state. @@ -235,6 +267,9 @@ sequence create_table verify_initial_setup verify_read_from_secondary + write_to_secondary_fails + read_secondary_unchanged + maintenance_primary_rejected maintenance_primary_allow_failover disable_maintenance_rejoin maintenance_secondary @@ -245,6 +280,8 @@ sequence writes_to_new_primary restart_node1 read_from_new_secondary + write_to_old_primary_fails drop_secondary + failover_single_node_rejected stop_monitor_postgres drop_primary From 9dc917b734bbc861475095af770d9641aaaf8d24 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 22:41:07 +0200 Subject: [PATCH 16/48] pgaftest: port all @raises(Exception) steps from Python tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five .pgaf files updated to include steps that correspond to Python test functions decorated with @raises(Exception): basic_operation_listen_flag.pgaf: test_005_writes_to_node2_fail — INSERT to standby → expect error 25006 test_010_writes_to_node1_fail — INSERT to new secondary → expect error 25006 basic_citus_operation.pgaf: test_004_002_writes_via_coordinator_fail — INSERT routing to failed worker2 shard before failover completes; Citus cannot contact the shard → expect error (no specific SQLSTATE — Citus connection failure, not a SQL read-only error). Also adds 'wait until worker2b state = primary' before the succeeding write, reflecting the Python test_004_004 / test_004_005 split. citus_multi_standbys.pgaf: test_004_002_writes_via_coordinator_fail — same Citus-routing failure pattern as basic_citus_operation, inserted between the disconnect step and the wait for failover completion. multi_maintenance.pgaf: test_009a_enable_maintenance_on_primary_fails — exec-fails: enabling maintenance on node3 (primary, with --allow-failover) is rejected because node1 and node2 are already in maintenance, leaving no standby for number-sync-standbys=1. test_017_primary_to_maintenance_fails — converted from 'exec + assert state' to 'exec-fails': the monitor rejects putting the primary into maintenance when only one standby would remain (below number-sync-standbys=1). nonha_citus_operation.pgaf: test_007_fail_when_disabling_with_secondaries — exec-fails: disabling secondary support on the non-ha formation is rejected while secondary nodes still exist. Two Python tests not ported (by design): test_create_standby_with_pgdata.py test_004: requires pg_ctl initdb in a separate step before pg_autoctl create — not expressible in the DSL since all containers start simultaneously; the pgaf file notes this explicitly. test_citus_skip_pg_hba.py test_002b: requires intercepting the automatic pg_autoctl create call that runs at container startup — also not directly expressible; the pgaf file handles this via the retry-after-HBA-edit path. --- tests/tap/specs/basic_citus_operation.pgaf | 10 ++++++++++ .../tap/specs/basic_operation_listen_flag.pgaf | 18 ++++++++++++++++++ tests/tap/specs/citus_multi_standbys.pgaf | 8 ++++++++ tests/tap/specs/multi_maintenance.pgaf | 13 ++++++++++--- tests/tap/specs/nonha_citus_operation.pgaf | 8 ++++++++ 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/tests/tap/specs/basic_citus_operation.pgaf b/tests/tap/specs/basic_citus_operation.pgaf index 964f09f4d..2b8b54941 100644 --- a/tests/tap/specs/basic_citus_operation.pgaf +++ b/tests/tap/specs/basic_citus_operation.pgaf @@ -59,7 +59,16 @@ step test_004_fail_worker2 { wait until worker2b state = wait_primary timeout 90s } +# test_004_002: INSERT routes to worker2 shard, but worker2a is down and +# worker2b hasn't completed failover yet — Citus cannot contact the shard. +step test_004_002_writes_via_coordinator_fail { + sql coordinator1a { INSERT INTO t1 VALUES (3); } + expect error +} + +# test_004_004/005: wait for worker2b to become primary, then write succeeds. step test_004_writes_succeed_after_failover { + wait until worker2b state = primary timeout 90s sql coordinator1a { INSERT INTO t1 VALUES (3); } } @@ -159,6 +168,7 @@ sequence test_002_init_workers test_003_create_distributed_table test_004_fail_worker2 + test_004_002_writes_via_coordinator_fail test_004_writes_succeed_after_failover test_005_read_from_coordinator test_006_writes_to_coordinator_succeed diff --git a/tests/tap/specs/basic_operation_listen_flag.pgaf b/tests/tap/specs/basic_operation_listen_flag.pgaf index 1565f731a..e73c689b0 100644 --- a/tests/tap/specs/basic_operation_listen_flag.pgaf +++ b/tests/tap/specs/basic_operation_listen_flag.pgaf @@ -46,6 +46,14 @@ step test_004_read_from_secondary { expect { { 1 } { 2 } } } +# +# test_005: writes to secondary (node2) must fail — SQLSTATE 25006 read_only_sql_transaction +# +step test_005_writes_to_node2_fail { + sql node2 { INSERT INTO t1 VALUES (3); } + expect error 25006 +} + # # test_006: fail primary node1 # @@ -81,6 +89,14 @@ step test_009_read_from_new_secondary { expect { { 1 } { 2 } { 3 } } } +# +# test_010: writes to node1 (now secondary after failover) must fail — SQLSTATE 25006 +# +step test_010_writes_to_node1_fail { + sql node1 { INSERT INTO t1 VALUES (3); } + expect error 25006 +} + # # test_011: fail secondary node1 # @@ -94,8 +110,10 @@ sequence test_002_create_t1 test_003_init_secondary test_004_read_from_secondary + test_005_writes_to_node2_fail test_006_fail_primary test_007_writes_to_node2_succeed test_008_start_node1_again test_009_read_from_new_secondary + test_010_writes_to_node1_fail test_011_fail_secondary diff --git a/tests/tap/specs/citus_multi_standbys.pgaf b/tests/tap/specs/citus_multi_standbys.pgaf index 085835394..481b38739 100644 --- a/tests/tap/specs/citus_multi_standbys.pgaf +++ b/tests/tap/specs/citus_multi_standbys.pgaf @@ -75,6 +75,13 @@ step test_004_001_fail_worker2 { network disconnect worker2a } +# test_004_002: INSERT routes to worker2 shard right after worker2a failed, +# before worker2b completes failover — Citus cannot contact the shard. +step test_004_002_writes_via_coordinator_fail { + sql coordinator1a { INSERT INTO t1 VALUES (3); } + expect error +} + step test_004_004_wait_for_failover { wait until worker2b state = wait_primary timeout 90s wait until worker2c state = secondary timeout 90s @@ -152,6 +159,7 @@ sequence test_002_init_workers test_003_001_create_distributed_table test_004_001_fail_worker2 + test_004_002_writes_via_coordinator_fail test_004_004_wait_for_failover test_004_005_writes_via_coordinator_succeed_after_failover test_005_read_from_coordinator diff --git a/tests/tap/specs/multi_maintenance.pgaf b/tests/tap/specs/multi_maintenance.pgaf index 1ae6c9256..0b34d7ff3 100644 --- a/tests/tap/specs/multi_maintenance.pgaf +++ b/tests/tap/specs/multi_maintenance.pgaf @@ -118,6 +118,14 @@ step test_008b_start_primary { wait until node3 state = primary timeout 90s } +# +# test_009a: trying to enable maintenance on node3 (the primary, with --allow-failover) +# must fail because node1 and node2 are already in maintenance — no standby would remain. +# +step test_009a_enable_maintenance_on_primary_fails { + exec-fails node3 pg_autoctl enable maintenance --allow-failover +} + # # test_009b: disable maintenance on node1 and node2 # @@ -204,9 +212,7 @@ step test_016_two_standbys_in_maintenance { # we would have no standby left (number-sync-standbys=1, two in maintenance) # step test_017_primary_to_maintenance_fails { - exec node3 pg_autoctl enable maintenance --allow-failover - # expected to fail — node3 should remain primary - assert node3 state = primary + exec-fails node3 pg_autoctl enable maintenance } # @@ -268,6 +274,7 @@ sequence test_007b_node2_to_maintenance test_008a_stop_primary test_008b_start_primary + test_009a_enable_maintenance_on_primary_fails test_009b_disable_maintenance test_010_set_sync_zero test_011_all_to_maintenance diff --git a/tests/tap/specs/nonha_citus_operation.pgaf b/tests/tap/specs/nonha_citus_operation.pgaf index f1cfa0697..32bf539d4 100644 --- a/tests/tap/specs/nonha_citus_operation.pgaf +++ b/tests/tap/specs/nonha_citus_operation.pgaf @@ -70,6 +70,13 @@ step test_006_add_secondaries { wait until worker2b state = secondary timeout 90s } +# +# test_007: trying to disable secondary support while secondaries exist must fail. +# +step test_007_fail_when_disabling_with_secondaries { + exec-fails monitor pg_autoctl disable secondary --formation non-ha +} + # # test_008: fail primaries — secondaries promote to wait_primary # @@ -108,6 +115,7 @@ sequence test_004_create_distributed_table test_005_enable_secondary test_006_add_secondaries + test_007_fail_when_disabling_with_secondaries test_008_shutdown_primaries test_009_remove_failed_nodes test_010_disable_secondaries From df01537658234d105e6a5fa72b15a06c8027f9b2 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 28 Jun 2026 22:58:13 +0200 Subject: [PATCH 17/48] pgaftest: add no-autostart node attribute; port create_standby_with_pgdata and citus_skip_pg_hba MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit no-autostart node attribute A node declared with 'no-autostart' in the cluster block has its compose service command overridden to 'sleep infinity' instead of 'pg_autoctl node run /etc/pgaf/node.ini'. The node.ini is still generated and bind-mounted so that manual exec steps can use it. Typical use: exec-fails nodeN pg_autoctl node run /etc/pgaf/node.ini exec nodeN (fix something) exec nodeN pg_autoctl node run --background /etc/pgaf/node.ini This models Python test sequences that call node.create() + node.run() separately with state-inspection or fixup steps in between. Implementation: test_spec.h: bool noAutostart in TestNode test_spec_parse.y: parse 'no-autostart' keyword in parse_node_line() compose_gen.c: emit 'command: ["sleep", "infinity"]' for such nodes create_standby_with_pgdata.pgaf (full port of Python tests 003-006) node2 no-autostart test_003: pg_ctl initdb on node2 to create a conflicting PGDATA test_004: exec-fails — pg_autoctl node run detects system_identifier mismatch and exits non-zero test_005: rm -rf node2's PGDATA to clean up node3 no-autostart test_006: pg_basebackup from node1 (without -R so pg_autoctl manages recovery config), then pg_autoctl node run --background, then wait for secondary/primary states citus_skip_pg_hba.pgaf (port Python test_002b @raises) worker1a no-autostart test_000: monitor HBA: manually append 'host all all 0.0.0.0/0 trust' so pg_autoctl data nodes can reach the monitor with auth=skip test_002b: exec-fails — pg_autoctl registers worker1a but coordinator's master_activate_node call is blocked by default pg_hba.conf test_002d: append HBA rules to worker1a's pg_hba.conf, then run keeper; keeper retries activation which now succeeds test_002e: assert hba-edited = false (pg_autoctl never touched it) worker1b no-autostart (for ordering: starts after worker1a is primary) test_003: pg_autoctl node run --background; inherits worker1a's HBA via pg_basebackup streaming replication setup --- src/bin/pgaftest/compose_gen.c | 10 ++- src/bin/pgaftest/test_spec.h | 1 + src/bin/pgaftest/test_spec_parse.y | 2 + tests/tap/specs/citus_skip_pg_hba.pgaf | 67 ++++++++++++++----- .../tap/specs/create_standby_with_pgdata.pgaf | 59 +++++++++++++--- 5 files changed, 111 insertions(+), 28 deletions(-) diff --git a/src/bin/pgaftest/compose_gen.c b/src/bin/pgaftest/compose_gen.c index ca973dc12..3e78a4756 100644 --- a/src/bin/pgaftest/compose_gen.c +++ b/src/bin/pgaftest/compose_gen.c @@ -173,9 +173,13 @@ compose_gen_write(const TestCluster *cluster, " condition: service_started\n", firstNode->name); - fprintf(f, - " command: [\"pg_autoctl\", \"node\", \"run\"," - " \"" NODE_INI_PATH "\"]\n\n"); + if (n->noAutostart) + fprintf(f, + " command: [\"sleep\", \"infinity\"]\n\n"); + else + fprintf(f, + " command: [\"pg_autoctl\", \"node\", \"run\"," + " \"" NODE_INI_PATH "\"]\n\n"); if (!firstNode) firstNode = n; } diff --git a/src/bin/pgaftest/test_spec.h b/src/bin/pgaftest/test_spec.h index 2d420305f..480219682 100644 --- a/src/bin/pgaftest/test_spec.h +++ b/src/bin/pgaftest/test_spec.h @@ -61,6 +61,7 @@ typedef struct TestNode /* create-time options — passed to pg_autoctl create via [options] ini */ bool noMonitor; /* --no-monitor: standalone node */ + bool noAutostart; /* container sleeps; pg_autoctl run is manual */ bool listen; /* --listen 0.0.0.0: bind all interfaces */ bool citusSecondary; /* --citus-secondary */ char citusClusterName[64]; /* --citus-cluster-name NAME */ diff --git a/src/bin/pgaftest/test_spec_parse.y b/src/bin/pgaftest/test_spec_parse.y index 95ab31a1e..b138c0596 100644 --- a/src/bin/pgaftest/test_spec_parse.y +++ b/src/bin/pgaftest/test_spec_parse.y @@ -345,6 +345,8 @@ parse_node_line(const char **pp, TestFormation *f, TestCluster *cl) } else if (strcmp(key, "no-monitor") == 0) n->noMonitor = true; + else if (strcmp(key, "no-autostart") == 0) + n->noAutostart = true; else if (strcmp(key, "listen") == 0) n->listen = true; else if (strcmp(key, "citus-secondary") == 0) diff --git a/tests/tap/specs/citus_skip_pg_hba.pgaf b/tests/tap/specs/citus_skip_pg_hba.pgaf index a2065bfb2..57933b00b 100644 --- a/tests/tap/specs/citus_skip_pg_hba.pgaf +++ b/tests/tap/specs/citus_skip_pg_hba.pgaf @@ -1,16 +1,27 @@ # Test Citus cluster with authMethod=skip (pg_autoctl does not edit pg_hba.conf). -# Verifies that pg_hba.conf is not modified by pg_autoctl, that worker activation -# fails when HBA does not permit coordinator connections, and that after manually -# adding the required HBA rules the worker activates successfully. +# +# With auth=skip, pg_autoctl leaves pg_hba.conf untouched after postgres init. +# The coordinator pair starts normally (coord0b pg_basebackup-s from coord0a +# and inherits its HBA; the monitor and coordinator connections work via the +# Docker network with trust auth set at the monitor level). +# +# worker1a is no-autostart. The first manual run fails because the +# coordinator tries master_activate_node on worker1a but worker1a's default +# pg_hba.conf blocks that connection. After we manually append the required +# HBA rules and retry, activation succeeds — and pg_autoctl has not modified +# pg_hba.conf itself (verified by assert hba-edited = false). +# +# worker1b is also no-autostart to ensure it starts only after worker1a is +# the active primary for group 1, matching the Python test's sequential order. cluster { monitor auth skip formation { - coord0a coordinator - coord0b coordinator - worker1a worker group 1 - worker1b worker group 1 + coord0a coordinator + coord0b coordinator + worker1a worker group 1 no-autostart + worker1b worker group 1 no-autostart } } @@ -24,21 +35,23 @@ teardown { } # -# test_000: monitor with auth=skip, append trust rule to pg_hba.conf manually +# test_000: monitor with auth=skip; append a trust rule manually so that +# the data nodes can connect to the monitor. # step test_000_create_monitor { wait until monitor pg is running timeout 60s + exec monitor bash -c "echo 'host all all 0.0.0.0/0 trust' >> /var/lib/postgres/pgaf/pg_hba.conf && pg_ctl reload -D /var/lib/postgres/pgaf" } # -# test_001a: init coordinator coord0a (single) +# test_001a: coord0a becomes single (monitor already has HBA rule). # step test_001a_init_coordinator { wait until coord0a state = single timeout 60s } # -# test_001b: init coordinator coord0b (secondary) +# test_001b: coord0b joins as secondary (inherits coord0a's HBA via basebackup). # step test_001b_init_coordinator { wait until coord0a state = primary timeout 90s @@ -46,26 +59,49 @@ step test_001b_init_coordinator { } # -# test_002b/002d: worker1a — registration initially fails because coordinator -# cannot connect; after manually adding HBA rules worker1a runs and activates. +# test_002b: attempt to register worker1a. pg_autoctl initialises postgres +# and registers with the monitor, but when the coordinator calls +# master_activate_node it tries to connect to worker1a via TCP — blocked by +# the default pg_hba.conf (no host rules for the Docker LAN). +# pg_autoctl exits non-zero; exec-fails asserts this. +# +step test_002b_create_worker_fails { + exec-fails worker1a pg_autoctl node run /etc/pgaf/node.ini +} + +# +# test_002d: append HBA rules that allow the coordinator to connect to +# worker1a, then start the pg_autoctl keeper. The keeper detects the +# existing local state (init/single), retries activation — which now +# succeeds — and enters its normal FSM loop. # step test_002d_run_worker { - wait until worker1a state = single timeout 90s + exec worker1a bash -c "echo 'host all all 0.0.0.0/0 trust' >> /var/lib/postgres/pgaf/pg_hba.conf && echo 'host replication all 0.0.0.0/0 trust' >> /var/lib/postgres/pgaf/pg_hba.conf" + exec worker1a pg_autoctl node run --background /etc/pgaf/node.ini } +# +# test_002e: pg_autoctl must not have modified pg_hba.conf (auth=skip contract). +# step test_002e_check_hba { assert worker1a hba-edited = false } +# +# test_002f: worker1a is now listed as active in the Citus coordinator. +# step test_002f_activated_node { sql coord0a { SELECT isactive FROM pg_dist_node WHERE nodename = 'worker1a'; } expect { true } } # -# test_003: init worker1b as secondary +# test_003: start worker1b. It sets up streaming replication from worker1a +# (the primary) via pg_basebackup, inheriting worker1a's pg_hba.conf +# (which we just fixed), so no additional HBA editing is needed. # step test_003_init_worker { + exec worker1b pg_autoctl node run --background /etc/pgaf/node.ini wait until worker1a state = primary timeout 90s wait until worker1b state = secondary timeout 90s assert worker1b hba-edited = false @@ -84,7 +120,7 @@ step test_004_create_distributed_table { # test_005: manual failover of worker group 1 # step test_005_failover { - exec monitor pg_autoctl perform failover --group 1 + exec monitor pg_autoctl perform failover --group 1 wait until worker1b state = wait_primary timeout 90s wait until worker1a state = secondary timeout 90s wait until worker1b state = primary timeout 90s @@ -94,6 +130,7 @@ sequence test_000_create_monitor test_001a_init_coordinator test_001b_init_coordinator + test_002b_create_worker_fails test_002d_run_worker test_002e_check_hba test_002f_activated_node diff --git a/tests/tap/specs/create_standby_with_pgdata.pgaf b/tests/tap/specs/create_standby_with_pgdata.pgaf index 5f9d6b55a..1e7e5eb33 100644 --- a/tests/tap/specs/create_standby_with_pgdata.pgaf +++ b/tests/tap/specs/create_standby_with_pgdata.pgaf @@ -1,12 +1,21 @@ # Test creating a standby from an existing PGDATA directory. -# Verifies that registering a node with a mismatched system_identifier fails, -# and that creating a standby from a manual copy of the primary's PGDATA works. +# +# test_003/004/005: verify that registering a node whose PGDATA was created by +# a separate initdb (different system_identifier) is rejected by the monitor. +# +# test_006: create a standby (node3) from a pg_basebackup of the primary's live +# PGDATA, then register it with the monitor as a secondary. +# +# Both node2 and node3 are declared no-autostart: their containers sleep until +# a step explicitly runs pg_autoctl node run. This models the Python test's +# sequential node.create() / node.run() calls. cluster { monitor formation { node1 - node3 + node2 no-autostart + node3 no-autostart } } @@ -19,14 +28,14 @@ teardown { } # -# test_001: init primary +# test_001: primary comes up # step test_001_init_primary { wait until node1 state = single timeout 60s } # -# test_002: create table t1 +# test_002: create table t1 on the primary # step test_002_create_t1 { sql node1 { CREATE TABLE t1(a int); } @@ -34,13 +43,40 @@ step test_002_create_t1 { } # -# test_003/004/005: attempt to register a node with existing incompatible PGDATA, -# expect failure, then clean up. This is handled at the infrastructure level; -# in the .pgaf spec we model only the successful path. +# test_003: create a fresh PGDATA on node2 using pg_ctl initdb. +# This gives node2 a different system_identifier than what the monitor +# would assign when pg_autoctl creates the node normally. +# +step test_003_initdb_conflicting_pgdata { + exec node2 pg_ctl initdb -D /var/lib/postgres/pgaf +} + +# +# test_004: attempt to register node2 with its incompatible PGDATA. +# pg_autoctl node run detects the system_identifier mismatch and exits +# non-zero, which exec-fails asserts. +# +step test_004_create_node2_fails { + exec-fails node2 pg_autoctl node run /etc/pgaf/node.ini +} + +# +# test_005: clean up the conflicting PGDATA so the node slot can be reused +# or simply left empty. +# +step test_005_cleanup { + exec node2 rm -rf /var/lib/postgres/pgaf +} + # -# test_006: create standby (node3) from a copy of node1's PGDATA +# test_006: take a streaming base backup from the running primary (node1) +# without the -R flag so that pg_autoctl manages the recovery configuration. +# Then register node3 with the monitor; it detects the existing PGDATA and +# sets up streaming replication automatically. # step test_006_init_secondary_from_pgdata { + exec node3 pg_basebackup -h node1 -p 5432 -U postgres -D /var/lib/postgres/pgaf --wal-method=stream -P + exec node3 pg_autoctl node run --background /etc/pgaf/node.ini wait until node3 state = secondary timeout 90s wait until node1 state = primary timeout 90s } @@ -49,7 +85,7 @@ step test_006_init_secondary_from_pgdata { # test_007: manual failover to node3 # step test_007_failover { - exec monitor pg_autoctl perform failover + exec monitor pg_autoctl perform failover wait until node3 state = primary timeout 90s wait until node1 state = secondary timeout 90s } @@ -57,5 +93,8 @@ step test_007_failover { sequence test_001_init_primary test_002_create_t1 + test_003_initdb_conflicting_pgdata + test_004_create_node2_fails + test_005_cleanup test_006_init_secondary_from_pgdata test_007_failover From 678c43e6afb5393682a45f165db72c79951c2896 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sat, 4 Jul 2026 03:37:21 +0200 Subject: [PATCH 18/48] pgaftest: add GitHub Actions workflow and upgrade test fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds two GitHub Actions workflows: - .github/workflows/run-tests.yml: modernized from @v3 to @v4 actions, otherwise identical to the existing matrix (pg13-18 × multi/single/ monitor/ssl/citus + tablespaces + linting). - .github/workflows/run-pgaftest.yml: new workflow for the pgaftest suite. A single build job produces pgaf:run (Docker image) and the pgaftest binary as reusable artifacts; 20 test specs then run concurrently as a matrix; the upgrade spec runs in a separate job with its own image build (pgaf:next + pgaf:current from the previous release tag). Also included in this commit: - tests/upgrade/install-extension.sh: replaces four sudo cp lines with a single script that uses pg_config to find extension/library paths at runtime, removing the hardcoded "/16/" paths from the spec. - tests/upgrade/Dockerfile.current: COPYs install-extension.sh into the image, drops the RUN printf approach. - tests/tap/specs/upgrade.pgaf: adds 'pg_autoctl manual service restart postgres' after the symlink flip so PostgreSQL reloads the new v2.2 .so; without this the old library stays resident and every keeper call fails. Uncomments 'upgrade' in tests/tap/schedule. All 10 upgrade test steps pass locally. --- .github/workflows/run-pgaftest.yml | 202 ++ .github/workflows/run-tests.yml | 37 +- Dockerfile | 106 +- docs/index.rst | 1 - docs/pgaftest.rst | 457 ++- docs/ref/manual.rst | 1 + docs/ref/pg_autoctl_do_pgsetup.rst | 26 +- src/bin/common/Makefile.common | 15 +- src/bin/common/pgctl.c | 25 + src/bin/common/pgctl.h | 1 + src/bin/common/pgsql.c | 79 + src/bin/common/pgsql.h | 2 + src/bin/pg_autoctl/cli_common.c | 18 + src/bin/pg_autoctl/cli_create_node.c | 32 +- src/bin/pg_autoctl/cli_do_fsm.c | 132 + src/bin/pg_autoctl/cli_do_misc.c | 312 +- src/bin/pg_autoctl/cli_do_monitor.c | 415 +++ src/bin/pg_autoctl/cli_do_root.c | 15 +- src/bin/pg_autoctl/cli_do_root.h | 5 + src/bin/pg_autoctl/cli_drop_node.c | 22 + src/bin/pg_autoctl/cli_get_set_properties.c | 332 ++ src/bin/pg_autoctl/cli_inspect.c | 3 + src/bin/pg_autoctl/cli_node.c | 139 +- src/bin/pg_autoctl/fsm_transition.c | 55 +- src/bin/pg_autoctl/keeper.c | 73 +- src/bin/pg_autoctl/keeper_config.c | 6 + src/bin/pg_autoctl/keeper_config.h | 1 + src/bin/pg_autoctl/keeper_pg_init.c | 17 + src/bin/pg_autoctl/monitor.c | 47 +- src/bin/pg_autoctl/monitor.h | 1 + src/bin/pg_autoctl/monitor_config.c | 6 + src/bin/pg_autoctl/monitor_config.h | 7 + src/bin/pg_autoctl/monitor_pg_init.c | 20 +- src/bin/pg_autoctl/monitor_pg_init.h | 3 +- src/bin/pg_autoctl/nodespec.c | 287 +- src/bin/pg_autoctl/nodespec.h | 35 +- src/bin/pg_autoctl/pghba.c | 62 + src/bin/pg_autoctl/pghba.h | 5 + src/bin/pg_autoctl/primary_standby.c | 12 + src/bin/pg_autoctl/service_keeper.c | 14 +- src/bin/pg_autoctl/service_monitor_init.c | 22 +- src/bin/pgaftest/Makefile | 32 +- src/bin/pgaftest/cli_indent.c | 899 +++++ src/bin/pgaftest/cli_indent.h | 15 + src/bin/pgaftest/cli_root.c | 137 +- src/bin/pgaftest/compose_gen.c | 831 ++++- src/bin/pgaftest/compose_gen.h | 26 +- src/bin/pgaftest/pgaftest | Bin 798488 -> 870648 bytes src/bin/pgaftest/test_runner-a12e5ed9.o.tmp | 0 src/bin/pgaftest/test_runner.c | 2752 +++++++++++++-- src/bin/pgaftest/test_runner.h | 37 +- src/bin/pgaftest/test_spec.h | 92 +- src/bin/pgaftest/test_spec_parse.c | 2762 ++++++++++----- src/bin/pgaftest/test_spec_parse.h | 242 +- src/bin/pgaftest/test_spec_parse.output | 2198 ++++++++++++ src/bin/pgaftest/test_spec_parse.tab.c | 2975 +++++++++++++++++ src/bin/pgaftest/test_spec_parse.y | 1941 +++++++---- src/bin/pgaftest/test_spec_scan.c | 1761 ++++++++-- src/bin/pgaftest/test_spec_scan.l | 373 ++- src/monitor/node_active_protocol.c | 10 +- tests/tap/README.md | 148 +- tests/tap/schedule | 7 +- tests/tap/specs/auth.pgaf | 84 +- tests/tap/specs/basic_citus_operation.pgaf | 180 +- tests/tap/specs/basic_operation.pgaf | 445 ++- .../specs/basic_operation_listen_flag.pgaf | 58 +- tests/tap/specs/citus_cluster_name.pgaf | 107 +- tests/tap/specs/citus_force_failover.pgaf | 65 +- tests/tap/specs/citus_multi_standbys.pgaf | 161 +- tests/tap/specs/citus_skip_pg_hba.pgaf | 103 +- tests/tap/specs/config_get_set.pgaf | 51 +- tests/tap/specs/create_run.pgaf | 86 - .../tap/specs/create_standby_with_pgdata.pgaf | 82 +- tests/tap/specs/debian_clusters.pgaf | 43 +- tests/tap/specs/enable_ssl.pgaf | 128 +- tests/tap/specs/ensure.pgaf | 80 +- tests/tap/specs/extension_update.pgaf | 23 +- tests/tap/specs/installcheck.pgaf | 36 +- tests/tap/specs/maintenance_and_drop.pgaf | 75 + tests/tap/specs/monitor_disabled.pgaf | 115 +- tests/tap/specs/multi_alternate.pgaf | 292 +- tests/tap/specs/multi_async.pgaf | 313 +- tests/tap/specs/multi_ifdown.pgaf | 126 +- tests/tap/specs/multi_maintenance.pgaf | 281 +- tests/tap/specs/multi_standbys.pgaf | 307 +- tests/tap/specs/nonha_citus_operation.pgaf | 135 +- tests/tap/specs/replace_monitor.pgaf | 56 +- tests/tap/specs/skip_pg_hba.pgaf | 56 +- tests/tap/specs/ssl_cert.pgaf | 63 +- tests/tap/specs/ssl_self_signed.pgaf | 49 +- tests/tap/specs/tablespaces.pgaf | 148 + tests/tap/specs/upgrade.pgaf | 189 ++ tests/upgrade/Dockerfile.current | 81 + tests/upgrade/Makefile | 158 +- tests/upgrade/install-extension.sh | 14 + tests/upgrade/pg_autoctl_shim.sh | 95 + 96 files changed, 20397 insertions(+), 4176 deletions(-) create mode 100644 .github/workflows/run-pgaftest.yml create mode 100644 src/bin/pgaftest/cli_indent.c create mode 100644 src/bin/pgaftest/cli_indent.h create mode 100644 src/bin/pgaftest/test_runner-a12e5ed9.o.tmp create mode 100644 src/bin/pgaftest/test_spec_parse.output create mode 100644 src/bin/pgaftest/test_spec_parse.tab.c delete mode 100644 tests/tap/specs/create_run.pgaf create mode 100644 tests/tap/specs/maintenance_and_drop.pgaf create mode 100644 tests/tap/specs/tablespaces.pgaf create mode 100644 tests/tap/specs/upgrade.pgaf create mode 100644 tests/upgrade/Dockerfile.current create mode 100644 tests/upgrade/install-extension.sh create mode 100644 tests/upgrade/pg_autoctl_shim.sh diff --git a/.github/workflows/run-pgaftest.yml b/.github/workflows/run-pgaftest.yml new file mode 100644 index 000000000..07da8a317 --- /dev/null +++ b/.github/workflows/run-pgaftest.yml @@ -0,0 +1,202 @@ +name: pgaftest + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +# One run per branch; cancel in-progress runs on new push. +concurrency: + group: pgaftest-${{ github.ref }} + cancel-in-progress: true + +jobs: + # --------------------------------------------------------------------------- + # Build the runtime Docker image and the pgaftest binary once, then share + # both as artifacts with every parallel test job. + # --------------------------------------------------------------------------- + build: + name: Build image & pgaftest + runs-on: ubuntu-latest + env: + PGVERSION: 16 + + steps: + - uses: actions/checkout@v4 + + - name: Build pg_auto_failover run image + run: | + docker build \ + --build-arg PGVERSION=${{ env.PGVERSION }} \ + --target run \ + -t pgaf:run \ + . + + - name: Save pgaf:run image as a tarball + run: docker save pgaf:run | gzip > /tmp/pgaf-run.tar.gz + + - name: Upload pgaf:run image artifact + uses: actions/upload-artifact@v4 + with: + name: pgaf-run-image + path: /tmp/pgaf-run.tar.gz + # Only needed for the duration of this workflow run. + retention-days: 1 + + # Build the full build image just to extract the pgaftest binary. + # The binary is linux/amd64, linked against PGDG libpq — matches + # ubuntu-latest runners where the test jobs will execute it. + - name: Build pg_auto_failover build image (for pgaftest extraction) + run: | + docker build \ + --build-arg PGVERSION=${{ env.PGVERSION }} \ + --target build \ + -t pgaf:build \ + . + + - name: Extract pgaftest binary from build image + run: | + docker create --name pgaftest-extract pgaf:build + docker cp pgaftest-extract:/usr/lib/postgresql/${{ env.PGVERSION }}/bin/pgaftest \ + /tmp/pgaftest + docker rm pgaftest-extract + chmod +x /tmp/pgaftest + + - name: Upload pgaftest binary artifact + uses: actions/upload-artifact@v4 + with: + name: pgaftest-binary + path: /tmp/pgaftest + retention-days: 1 + + # --------------------------------------------------------------------------- + # Run all non-upgrade specs from tests/tap/schedule in a matrix. + # Each job is independent; they all share the pre-built image and binary. + # --------------------------------------------------------------------------- + test: + name: pgaftest / ${{ matrix.spec }} + needs: build + runs-on: ubuntu-latest + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + spec: + - basic_operation + - basic_operation_listen_flag + - maintenance_and_drop + - create_standby_with_pgdata + - ensure + - monitor_disabled + - replace_monitor + - config_get_set + - skip_pg_hba + - auth + - enable_ssl + - ssl_cert + - ssl_self_signed + - multi_standbys + - multi_async + - multi_ifdown + - multi_maintenance + - multi_alternate + - extension_update + - installcheck + + steps: + - uses: actions/checkout@v4 + + - name: Download pgaf:run image + uses: actions/download-artifact@v4 + with: + name: pgaf-run-image + path: /tmp + + - name: Load pgaf:run image into Docker + run: docker load < /tmp/pgaf-run.tar.gz + + - name: Download pgaftest binary + uses: actions/download-artifact@v4 + with: + name: pgaftest-binary + path: /tmp + + # pgaftest links against PGDG libpq — install the matching runtime lib. + - name: Install libpq runtime + run: | + sudo apt-get install -y curl ca-certificates gnupg + curl https://www.postgresql.org/media/keys/ACCC4CF8.asc \ + | sudo apt-key add - + echo "deb http://apt.postgresql.org/pub/repos/apt \ + $(lsb_release -cs)-pgdg main" \ + | sudo tee /etc/apt/sources.list.d/pgdg.list + sudo apt-get update + sudo apt-get install -y libpq5 + + - name: Run ${{ matrix.spec }} + timeout-minutes: 15 + env: + PGAF_IMAGE: pgaf:run + run: | + chmod +x /tmp/pgaftest + /tmp/pgaftest run tests/tap/specs/${{ matrix.spec }}.pgaf + + # --------------------------------------------------------------------------- + # Upgrade test: builds both pgaf:next (current branch) and pgaf:current + # (the previous release tag, auto-detected), then runs the upgrade spec. + # Kept separate because it needs a PGVERSION=16 image and additional + # build steps (pgaf:current-base from git archive of PREV_TAG). + # --------------------------------------------------------------------------- + upgrade: + name: pgaftest / upgrade + needs: build + runs-on: ubuntu-latest + timeout-minutes: 30 + env: + PGVERSION: 16 + + steps: + - uses: actions/checkout@v4 + with: + # Full history needed so PREV_TAG auto-detection (git tag --sort) + # finds the correct previous release tag. + fetch-depth: 0 + + - name: Install libpq runtime + run: | + sudo apt-get install -y curl ca-certificates gnupg + curl https://www.postgresql.org/media/keys/ACCC4CF8.asc \ + | sudo apt-key add - + echo "deb http://apt.postgresql.org/pub/repos/apt \ + $(lsb_release -cs)-pgdg main" \ + | sudo tee /etc/apt/sources.list.d/pgdg.list + sudo apt-get update + sudo apt-get install -y libpq5 + + - name: Download pgaftest binary + uses: actions/download-artifact@v4 + with: + name: pgaftest-binary + path: /tmp + + # The build job already produced pgaf:run at PG16 for the regular tests, + # but the upgrade job runs independently and needs its own images. + # Build pgaf:next first so pgaf:current's Dockerfile.current can COPY + # the v2.2 binary and extension files from it. + - name: Build pgaf:next (current branch, PGVERSION=16) + run: | + make -C tests/upgrade pgaf-next PGVERSION=${{ env.PGVERSION }} + + - name: Build pgaf:current (previous release + both binaries baked in) + run: | + make -C tests/upgrade pgaf-current PGVERSION=${{ env.PGVERSION }} + + - name: Run upgrade spec + timeout-minutes: 25 + run: | + chmod +x /tmp/pgaftest + /tmp/pgaftest run tests/tap/specs/upgrade.pgaf diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index c1b626782..3e661a6ff 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -3,11 +3,10 @@ name: Run Tests on: push: branches: - - main + - main pull_request: branches: - - main - + - main workflow_dispatch: jobs: @@ -37,42 +36,36 @@ jobs: TEST: linting steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set environment variables run: | - echo "PGVERSION=${{ matrix.PGVERSION }}" >> $GITHUB_ENV - echo "TEST=${{ matrix.TEST }}" >> $GITHUB_ENV - echo "LINTING=${{ matrix.LINTING }}" >> $GITHUB_ENV - echo "TRAVIS_BUILD_DIR=$(pwd)" >> $GITHUB_ENV + echo "PGVERSION=${{ matrix.PGVERSION }}" >> $GITHUB_ENV + echo "TEST=${{ matrix.TEST }}" >> $GITHUB_ENV + echo "TRAVIS_BUILD_DIR=$(pwd)" >> $GITHUB_ENV - name: Clone and install linting tools - if: ${{ env.TEST == 'linting' }} + if: ${{ matrix.TEST == 'linting' }} run: | sudo apt-get install python3-pip pip3 install --user black black --version gcc --version - # Install uncrustify the Citus way make -C ci -f tools.mk tools - name: Check code formatting and banned function - if: ${{ env.TEST == 'linting' }} - run: | - make lint + if: ${{ matrix.TEST == 'linting' }} + run: make lint - name: Build documentation - if: ${{ env.TEST == 'linting' }} - run: | - make build-docs + if: ${{ matrix.TEST == 'linting' }} + run: make build-docs - name: Build Docker Test Image - if: ${{ env.TEST != 'linting' }} - run: | - make build-test-image + if: ${{ matrix.TEST != 'linting' }} + run: make build-test-image - name: Run Test - if: ${{ env.TEST != 'linting' }} + if: ${{ matrix.TEST != 'linting' }} timeout-minutes: 15 - run: | - make ci-test + run: make ci-test diff --git a/Dockerfile b/Dockerfile index 1df68994d..764730b5f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -196,4 +196,108 @@ ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/p ENV PG_AUTOCTL_DEBUG=1 ENV PGDATA=/var/lib/postgres/pgaf -CMD ["pg_autoctl", "do tmux session --nodes 3 --binpath /usr/local/bin/pg_autoctl"] +# +# debian image — like run, but with a Debian-style "main" cluster pre-created +# via pg_createcluster so that pg_autoctl can test adoption of the split-config +# layout (postgresql.conf lives in /etc/postgresql/${PGVERSION}/main/ outside +# PGDATA). pg_autoctl node run detects the missing postgresql.conf in PGDATA, +# moves the conf files in, and proceeds normally — no entrypoint changes needed. +# +FROM run AS debian + +ARG PGVERSION + +USER root +RUN pg_createcluster \ + --user docker --group postgres \ + ${PGVERSION} main \ + -- --auth-local trust --auth-host trust \ + && chown docker /var/lib/postgresql/${PGVERSION} + +USER docker +ENV PGDATA=/var/lib/postgresql/${PGVERSION}/main + +# +# testrun image — like run, but adds postgresql-server-dev and the full source +# tree so that "make installcheck" works inside the monitor container. +# Used by installcheck.pgaf via "monitor image-target testrun". +# +FROM run AS testrun + +ARG PGVERSION + +USER root +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + make \ + postgresql-server-dev-${PGVERSION} \ + && rm -rf /var/lib/apt/lists/* + +COPY --chown=docker ./src/ /usr/src/pg_auto_failover/src/ + +USER docker + +# +# pgaftest image — standalone test-runner image. +# +# Kept entirely separate from the pg_auto_failover run image so that no +# test tooling leaks into the images used for monitor and data nodes. +# +# Runtime dependencies come from two sources: +# - Docker's own apt repo → docker-ce-cli + docker-compose-plugin (v2) +# - PGDG apt repo → libpq5 matching the build's PGVERSION +# +# The pg_auto_failover binaries are copied directly from the run stage; +# nothing is built here. +# +FROM debian:bullseye-slim AS pgaftest + +ARG PGVERSION + +# Minimal runtime libs (libssl, libcurl, libzstd) plus PGDG for libpq +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + gnupg \ + libcurl4-gnutls-dev \ + libncurses6 \ + libzstd-dev \ + sudo \ + && rm -rf /var/lib/apt/lists/* + +# PGDG repo — needed for the libpq version that pg_autoctl and pgaftest link against +RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - +RUN echo "deb http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main ${PGVERSION}" \ + > /etc/apt/sources.list.d/pgdg.list \ + && apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + libpq5 \ + && rm -rf /var/lib/apt/lists/* + +# Docker's apt repo — provides docker-ce-cli and the compose v2 plugin +RUN curl -fsSL https://download.docker.com/linux/debian/gpg \ + | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \ + https://download.docker.com/linux/debian bullseye stable" \ + > /etc/apt/sources.list.d/docker.list \ + && apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + docker-ce-cli \ + docker-compose-plugin \ + && rm -rf /var/lib/apt/lists/* + +RUN adduser --disabled-password --gecos '' --home /var/lib/postgres docker \ + && adduser docker sudo \ + && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \ + && mkdir -p /var/lib/postgres \ + && chown docker /var/lib/postgres + +# Binaries from the pg_auto_failover run image +COPY --from=run /usr/local/bin/pg_autoctl /usr/local/bin/ + +# pgaftest binary from the build stage +COPY --from=build /usr/lib/postgresql/${PGVERSION}/bin/pgaftest /usr/local/bin/ + +USER docker +ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin diff --git a/docs/index.rst b/docs/index.rst index 65a7b3a02..32b6a643c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -75,7 +75,6 @@ __ https://github.com/hapostgres/pg_auto_failover ref/manual ref/configuration - ref/pg_autoctl_node .. toctree:: :hidden: diff --git a/docs/pgaftest.rst b/docs/pgaftest.rst index 4e97b4325..9d0b7f519 100644 --- a/docs/pgaftest.rst +++ b/docs/pgaftest.rst @@ -151,9 +151,87 @@ Options: * ``citus-secondary`` — marks this node as a Citus secondary. * ``citus-cluster-name NAME`` — sets the Citus cluster name. * ``port N`` — override the default Postgres port (5432). -* ``debian-cluster NAME`` — Debian-style Postgres cluster name. +* ``debian-cluster NAME`` — Debian-style Postgres cluster name. The node + will use the Debian ``/var/lib/postgresql//`` layout that + results from ``pg_createcluster``. Requires the ``debian`` Dockerfile + build target; see ``monitor image-target`` below. * ``ssl MODE`` — per-node SSL mode override (overrides the cluster-level ``ssl``). * ``auth-method METHOD`` — per-node auth method override. +* ``launch deferred`` — do not start this node automatically at ``compose up`` + time. Use ``compose start `` inside a step to start it later. This + is how tests that add nodes mid-scenario are written. +* ``volume `` — mount a Docker named volume into the + container at ````. The volume is created automatically. + Multiple ``volume`` lines are allowed. + +**Multi-option nodes — block syntax** + +When a node needs several options the block form keeps the spec readable: + +.. code-block:: text + + node coordinator1b { + coordinator + candidate-priority 0 + citus-secondary + citus-cluster-name readonly + } + + node worker1b { + worker group 1 + candidate-priority 0 + citus-secondary + citus-cluster-name readonly + } + + node node1 { + volume extra_a "/extra_volumes/extra_a" + volume extra_b "/extra_volumes/extra_b" + } + +The block form requires the ``node`` keyword before the name. Flat (single- +line) form does not use the keyword. ``pgaftest indent`` automatically +promotes a node to block form whenever the flat line would exceed 72 characters +or the node has any ``volume`` entries. + +**Monitor options** + +.. code-block:: text + + cluster { + monitor image-target testrun + monitor debian-cluster main + ... + } + +``monitor image-target `` + Use the specified Dockerfile build stage for the monitor container instead + of the default ``run`` stage. Useful when the monitor needs extra tools + (e.g. ``testrun`` for ``make installcheck``, ``test`` for the build + environment). + +``monitor debian-cluster `` + Mark the monitor container as Debian-style: use the ``debian`` Dockerfile + target and set ``PGDATA`` to ``/var/lib/postgresql//``. + +``monitor initially stopped`` + Declare a second monitor service named ````. The container is + created and initialized at ``compose up`` time (so its data volume is + ready), but ``pgaftest`` immediately stops it. Use this for + monitor-replacement scenarios where the second monitor must exist on disk + but must not be reachable until the test deliberately starts it with + ``compose start ``. + + .. code-block:: text + + cluster { + monitor + monitor monitor2 initially stopped + formation { + node1 + node2 + } + } **Examples** @@ -304,21 +382,160 @@ that a command is correctly rejected by pg_autoctl. # failover with a single node (no standby) must fail exec-fails monitor pg_autoctl perform failover -``wait until state = [timeout Ns]`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``wait until state is [timeout Ns]`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Poll until ```` reaches ````, then continue. The timeout +defaults to 90 seconds. Fails the current step if the timeout expires. +Both ``is`` and ``=`` are accepted as the state operator. + +.. code-block:: text + + wait until node1 state is primary timeout 120s + wait until node2 state is secondary timeout 60s + wait until node2 state is demote_timeout timeout 90s + +**Multi-node form** — wait for several nodes simultaneously using ``and``: + +.. code-block:: text + + wait until node1 state is primary + and node2 state is secondary + timeout 90s + + wait until coordinator1a state is primary + and coordinator1b state is secondary + and worker1a state is primary + timeout 120s + +Each ``and state is `` condition must be satisfied at the same +time for the wait to succeed. + +**Pass-through states** — assert that a node visits intermediate states on +the way to the target: + +.. code-block:: text + + wait until node2 state is primary + passing through stop_replication, draining + timeout 120s -Poll the monitor until ```` reports ````. The timeout defaults -to 90 seconds. Fails the current step if the timeout expires. +The runner observes monitor LISTEN/NOTIFY notifications; a pass-through state +is satisfied when a notification for that state is received before the target +state notification arrives. + +**State names** — all pg_auto_failover FSM states are first-class tokens in +the spec DSL. Both ``_`` and ``-`` spellings are accepted: + +.. list-table:: + :header-rows: 1 + :widths: 30 30 40 + + * - Token + - Aliases + - Description + * - ``init`` + - + - Node has just been created + * - ``single`` + - + - Single-node cluster (no standby yet) + * - ``primary`` + - + - Running as primary + * - ``wait_primary`` + - ``wait-primary`` + - Waiting for a standby to connect + * - ``wait_standby`` + - ``wait-standby`` + - Primary waiting for first standby + * - ``secondary`` + - + - Running as synchronous standby + * - ``catchingup`` + - + - Standby catching up after promotion or restart + * - ``draining`` + - + - Primary draining before demotion + * - ``demote_timeout`` + - ``demote-timeout`` + - Former primary waiting for demotion timer + * - ``demoted`` + - + - Former primary; postgres stopped + * - ``maintenance`` + - + - Node paused for maintenance + * - ``prepare_maintenance`` + - ``prepare-maintenance`` + - Transition into maintenance + * - ``wait_maintenance`` + - ``wait-maintenance`` + - Standby waiting while primary enters maintenance + * - ``join_primary`` + - ``join-primary`` + - New node joining as primary + * - ``apply_settings`` + - ``apply-settings`` + - Applying configuration changes + * - ``report_lsn`` + - ``report-lsn`` + - Standby reporting its LSN for promotion selection + * - ``fast_forward`` + - ``fast-forward`` + - Standby fast-forwarding to primary's LSN + * - ``join_secondary`` + - ``join-secondary`` + - New node joining as secondary + * - ``prepare_promotion`` + - ``prepare-promotion`` + - Standby preparing to be promoted + * - ``stop_replication`` + - ``stop-replication`` + - Standby stopping replication before promotion + * - ``dropped`` + - + - Node has been dropped from the formation + +**Dual-source polling** — the runner queries two sources in each polling +round, succeeding as soon as either returns a match: + +1. **Monitor** (``pg_autoctl inspect monitor node-state``): checks the + ``reportedstate`` column in ``pgautofailover.node``. This is the primary + source; it captures fast FSM transitions correctly because the monitor's + view lags by exactly one keeper heartbeat. + +2. **Node-local FSM** (``pg_autoctl inspect fsm node-state``): checks the + keeper's on-disk ``current_role`` in the state file inside the container. + This source is consulted **only** when the monitor reports ``health < 0`` + (node is unhealthy / unreachable) for the target node. A network- + partitioned primary self-assigns ``demote_timeout`` locally after + ``network_partition_timeout`` seconds (default 20 s) even though it cannot + report that state back to the monitor. Gating the node-local check on the + monitor's health value avoids false positives from stale on-disk state + while correctly observing partition-driven transitions. + +.. note:: + + The dual-source strategy lets tests write ``wait until node2 state = + demote_timeout`` after a ``network disconnect node2`` without any special + syntax. The runner detects the partition automatically. + +``wait until , , ... [in group N] [timeout Ns]`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Wait until the formation as a whole has at least one node in each of the +listed states simultaneously. Useful for asserting cluster-wide convergence +after a failover. .. code-block:: text - wait until node1 state = primary timeout 120s - wait until node2 state = secondary timeout 60s - wait until node2 state = wait_primary + # Wait for primary + secondary simultaneously + wait until primary, secondary timeout 120s -Valid state names are the pg_auto_failover FSM states: ``primary``, -``secondary``, ``wait_primary``, ``draining``, ``demoted``, -``maintenance``, ``join_primary``, ``catchingup``, etc. + # Wait for specific group + wait until primary, secondary in group 1 timeout 90s ``assert state = `` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -447,6 +664,157 @@ up after a test run. compose down } +``compose start `` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Start a stopped container. Equivalent to ``docker compose start ``. +Pairs with ``compose stop`` and ``launch deferred`` node declarations. + +.. code-block:: text + + compose start node2 + +``compose stop `` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Stop a container cleanly (SIGTERM + grace period). Equivalent to +``docker compose stop ``. Use this to simulate a process crash or +clean node shutdown. + +.. code-block:: text + + compose stop node1 + wait until node2 state is wait_primary timeout 90s + +``compose kill `` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Kill a container immediately with SIGKILL. Equivalent to +``docker compose kill ``. Use when a clean shutdown would allow +the node to complete its shutdown sequence — which some tests intentionally +want to avoid. + +.. code-block:: text + + compose kill node1 + +``set monitor `` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Switch the runner's active monitor to ````. After this command: + +* LISTEN/NOTIFY reconnects to ```` — subsequent ``wait until`` and + formation-state checks use the new monitor. +* ``monitor_get_node_state`` queries ```` for implicit post-exec + state verification. + +Use this in monitor-replacement tests immediately after starting the new +monitor container, so that all subsequent runner operations target it instead +of the original (stopped) monitor. + +.. code-block:: text + + step switch_to_new_monitor { + compose start monitor2 + sleep 5s + exec monitor2 pg_autoctl inspect pgsetup wait + set monitor monitor2 + } + + step reconnect_node1 { + exec node1 pg_autoctl enable monitor postgresql://autoctl_node@monitor2/pg_auto_failover + wait until node1 state is single timeout 60s + } + +``logs [not] contains ""`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Assert that the container log output of ```` contains (or does not +contain) the literal string ````. The runner runs +``docker compose logs --no-color `` and pipes through ``grep -qF``. + +.. code-block:: text + + logs node2 contains "password=****" + logs node2 not contains "plaintext_secret" + +``logs [not] matches ""`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Like ``logs … contains`` but uses PCRE via ``grep -qP``. Use this for +regular-expression patterns, including negative lookahead assertions. + +.. code-block:: text + + logs node2 not matches "^(?!primary_conninfo|Failed to find).*streaming_password" + +The example asserts that no log line contains ``streaming_password`` unless +the line also starts with ``primary_conninfo`` or ``Failed to find`` — the +two expected contexts where the password legitimately appears. + +``stop postgres `` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Stop the Postgres server inside ````'s container without stopping the +``pg_autoctl`` supervisor. Equivalent to calling +``pg_autoctl manual service pgctl off`` inside the container. The supervisor detects +the outage and reacts according to the FSM. + +.. code-block:: text + + exec node1 pg_autoctl enable maintenance + wait until node1 state is maintenance timeout 60s + stop postgres node1 + +``start postgres `` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Restart the Postgres server inside ````'s container via the +``pg_autoctl`` supervisor (``pg_autoctl manual pgctl on``). + +.. code-block:: text + + start postgres node1 + +``promote [, , ...]`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Assign ``pg_autoctl perform promotion`` to the listed nodes, one per group. +Useful after setup to designate which node becomes primary in each group. + +.. code-block:: text + + promote node1 + promote coordinator1a, worker1a, worker2a + +``assert stays while { }`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Assert that ```` remains in ```` throughout the execution of all +commands in the ``while { }`` body. The state is checked before and after +each inner command; any deviation fails the step. + +.. code-block:: text + + assert node1 stays secondary while { + exec node2 pg_autoctl enable maintenance + wait until node2 state is maintenance timeout 60s + exec node2 pg_autoctl disable maintenance + wait until node2 state is secondary timeout 60s + } + +``%CIDR%`` macro +~~~~~~~~~~~~~~~~~ + +The literal token ``%CIDR%`` is expanded to the Docker network CIDR (e.g. +``172.31.0.0/16``) in any ``exec`` or ``exec-fails`` command argument. The +expanded value is logged on a separate line. Use it to scope HBA rules to +the test network instead of ``0.0.0.0/0``: + +.. code-block:: text + + exec monitor bash -c "echo 'host all all %CIDR% trust' >> /var/lib/postgres/pgaf/pg_hba.conf" + TAP output ---------- @@ -627,6 +995,73 @@ change ``node2``'s candidate priority without restarting the container: docker compose exec monitor \ pg_autoctl get node candidate-priority --pgdata /var/lib/postgres/pgaf +pg_autoctl inspect commands used by pgaftest +-------------------------------------------- + +``pgaftest`` talks to the containers exclusively through ``pg_autoctl`` +subcommands via ``docker compose exec``. No psql scripts, no port +forwarding. The relevant commands are: + +``pg_autoctl inspect monitor node-state`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Runs on the **monitor** container. Queries ``pgautofailover.node`` and +prints one line:: + + || + +``health`` is the integer from the monitor's health-check column: +``1`` = healthy, ``-1`` = unhealthy (keeper unreachable). + +With ``--name `` and ``--state `` the command exits 0 only +when ``reportedstate`` equals ````. ``--timeout N`` retries for up +to ``N`` seconds using exponential back-off. + +.. code-block:: bash + + # One-shot query (prints reported|goal|health) + docker compose exec -T monitor \ + pg_autoctl inspect monitor node-state --name node2 + + # Wait up to 90 s for node2 to report "secondary" + docker compose exec -T monitor \ + pg_autoctl inspect monitor node-state \ + --name node2 --state secondary --timeout 90 + +``pg_autoctl inspect fsm node-state`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Runs on a **data node** container. Reads the keeper's on-disk state file +and prints:: + + | + +``current_role`` is the keeper's authoritative local state. It is updated +by the keeper even when the node cannot reach the monitor — for example, a +partitioned primary self-assigns ``demote_timeout`` after +``network_partition_timeout`` (default 20 s) without any monitor contact. + +With ``--state `` exits 0 when ``current_role`` equals ````. +``--timeout N`` retries for up to ``N`` seconds. + +.. code-block:: bash + + # Check that a partitioned primary has self-assigned demote_timeout + docker compose exec -T node2 \ + pg_autoctl inspect fsm node-state --state demote_timeout --timeout 60 + +``pg_autoctl inspect monitor formation-states`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Runs on the **monitor** container. Waits until the formation has at least +one node in each of the listed states simultaneously, then exits 0. + +.. code-block:: bash + + docker compose exec -T monitor \ + pg_autoctl inspect monitor formation-states \ + --timeout 120 primary secondary + See also -------- diff --git a/docs/ref/manual.rst b/docs/ref/manual.rst index 12ed2f966..7facd9dec 100644 --- a/docs/ref/manual.rst +++ b/docs/ref/manual.rst @@ -21,6 +21,7 @@ have their own manual page. pg_autoctl_set pg_autoctl_perform pg_autoctl_do + pg_autoctl_node pg_autoctl_run pg_autoctl_watch pg_autoctl_stop diff --git a/docs/ref/pg_autoctl_do_pgsetup.rst b/docs/ref/pg_autoctl_do_pgsetup.rst index fb085d343..0913bb233 100644 --- a/docs/ref/pg_autoctl_do_pgsetup.rst +++ b/docs/ref/pg_autoctl_do_pgsetup.rst @@ -81,8 +81,22 @@ pg_autoctl do pgsetup wait -------------------------- When ``pg_autoctl do pgsetup ready`` would return false because Postgres is -not ready yet, this command continues probing every second for 30 seconds, -and exists as soon as Postgres is ready. +not ready yet, this command continues probing every second (up to +``--timeout`` seconds, default 30) and exits as soon as Postgres is ready. + +Options: + +``--read-write`` + After Postgres reports itself ready, additionally wait until the server + accepts read-write connections (i.e. ``pg_is_in_recovery()`` returns + ``false``). Useful after a failover when you want to block until the new + primary is writable before sending traffic. + +``--timeout N`` + Total timeout in seconds shared across both phases. Time spent waiting + for Postgres to start counts against the budget for the read-write phase, + so a single ``--timeout 60`` means at most 60 seconds total, not 60 + seconds per phase. Default: 30. :: @@ -90,6 +104,14 @@ and exists as soon as Postgres is ready. 16:50:22 70829 INFO Postgres is now serving PGDATA "/Users/dim/dev/MS/pg_auto_failover/tmux/node1" on port 5501 with pid 21029 16:50:22 70829 INFO Postgres status is: "ready" +:: + + $ pg_autoctl do pgsetup wait --pgdata node1 --read-write --timeout 60 + 16:50:22 70829 INFO Postgres is now serving PGDATA "..." on port 5501 with pid 21029 + 16:50:22 70829 INFO Postgres status is: "ready" + 16:50:22 70829 INFO Waiting for Postgres to accept read-write connections (timeout 60s) + 16:50:23 70829 INFO Postgres is now accepting read-write connections on port 5501 + pg_autoctl do pgsetup logs -------------------------- diff --git a/src/bin/common/Makefile.common b/src/bin/common/Makefile.common index 2b308b555..be7a0fe9e 100644 --- a/src/bin/common/Makefile.common +++ b/src/bin/common/Makefile.common @@ -52,9 +52,22 @@ override CFLAGS := $(DEFAULT_CFLAGS) $(CFLAGS) BINDIR ?= $(shell $(PG_CONFIG) --bindir) +# pg_config --ldflags from source builds can emit colon-joined paths such as +# -L/path/a:/path/b as a single token, which the linker rejects. Split each +# -L token on ':' so every directory gets its own -L flag. +PG_LDFLAGS_RAW := $(shell $(PG_CONFIG) --ldflags) +PG_LDFLAGS := $(shell echo "$(PG_LDFLAGS_RAW)" | awk '{ \ + for (i = 1; i <= NF; i++) { \ + if (substr($$i, 1, 2) == "-L") { \ + n = split(substr($$i, 3), p, ":"); \ + for (j = 1; j <= n; j++) if (p[j] != "") printf "-L%s ", p[j]; \ + } else { printf "%s ", $$i; } \ + } \ +}') + LIBS = -L $(shell $(PG_CONFIG) --pkglibdir) LIBS += -L $(shell $(PG_CONFIG) --libdir) -LIBS += $(shell $(PG_CONFIG) --ldflags) +LIBS += $(PG_LDFLAGS) LIBS += $(shell $(PG_CONFIG) --libs) LIBS += -lpq diff --git a/src/bin/common/pgctl.c b/src/bin/common/pgctl.c index e436f076f..2248a1f11 100644 --- a/src/bin/common/pgctl.c +++ b/src/bin/common/pgctl.c @@ -2056,6 +2056,31 @@ pg_ctl_promote(const char *pg_ctl, const char *pgdata) } +/* + * pg_ctl_reload reloads Postgres configuration by running "pg_ctl reload". + * Does not require a libpq connection — useful when HBA hasn't been set up yet. + */ +bool +pg_ctl_reload(const char *pg_ctl, const char *pgdata) +{ + Program program = run_program(pg_ctl, "-D", pgdata, "reload", NULL); + int returnCode = program.returnCode; + + if (program.stdErr != NULL) + log_debug("%s", program.stdErr); + + free_program(&program); + + if (returnCode != 0) + { + log_error("pg_ctl reload -D %s failed (exit %d)", pgdata, returnCode); + return false; + } + + return true; +} + + /* * pg_setup_standby_mode sets up standby mode by either writing a recovery.conf * file or adding the configuration items to postgresql.conf and then creating diff --git a/src/bin/common/pgctl.h b/src/bin/common/pgctl.h index 328c352dc..e030d8217 100644 --- a/src/bin/common/pgctl.h +++ b/src/bin/common/pgctl.h @@ -59,6 +59,7 @@ bool pg_log_recovery_setup(const char *pgdata, int logLevel); bool pg_ctl_stop(const char *pg_ctl, const char *pgdata); int pg_ctl_status(const char *pg_ctl, const char *pgdata, bool log_output); bool pg_ctl_promote(const char *pg_ctl, const char *pgdata); +bool pg_ctl_reload(const char *pg_ctl, const char *pgdata); bool pg_setup_standby_mode(uint32_t pg_control_version, const char *pgdata, diff --git a/src/bin/common/pgsql.c b/src/bin/common/pgsql.c index ce436196c..4fe32a084 100644 --- a/src/bin/common/pgsql.c +++ b/src/bin/common/pgsql.c @@ -2335,6 +2335,85 @@ pgsql_create_user(PGSQL *pgsql, const char *userName, const char *password, } +/* + * pgsql_alter_role_password runs ALTER ROLE PASSWORD '...'. + * + * The password is never logged; we log "ALTER ROLE PASSWORD '*****'" + * instead. Uses PQescapeIdentifier / PQescapeLiteral so the values are safe + * to interpolate directly into the query string. + */ +bool +pgsql_alter_role_password(PGSQL *pgsql, const char *roleName, + const char *password) +{ + /* open a connection upfront since it is needed by PQescape functions */ + PGconn *connection = pgsql_open_connection(pgsql); + if (connection == NULL) + { + /* error message was logged in pgsql_open_connection */ + return false; + } + + char *escapedRole = PQescapeIdentifier(connection, roleName, strlen(roleName)); + if (escapedRole == NULL) + { + log_error("Failed to escape role name \"%s\": %s", + roleName, PQerrorMessage(connection)); + pgsql_finish(pgsql); + return false; + } + + char *escapedPassword = PQescapeLiteral(connection, password, strlen(password)); + if (escapedPassword == NULL) + { + log_error("Failed to escape password for role \"%s\": %s", + roleName, PQerrorMessage(connection)); + PQfreemem(escapedRole); + pgsql_finish(pgsql); + return false; + } + + /* log without the real password */ + log_debug("ALTER ROLE %s PASSWORD '*****';", escapedRole); + + PQExpBuffer query = createPQExpBuffer(); + appendPQExpBuffer(query, "ALTER ROLE %s PASSWORD %s", escapedRole, escapedPassword); + PQfreemem(escapedRole); + PQfreemem(escapedPassword); + + if (PQExpBufferBroken(query)) + { + log_error("Failed to allocate memory"); + destroyPQExpBuffer(query); + pgsql_finish(pgsql); + return false; + } + + PGresult *result = PQexec(connection, query->data); + destroyPQExpBuffer(query); + + if (!is_response_ok(result)) + { + log_error("Failed to alter role \"%s\" password: %s", + roleName, PQerrorMessage(connection)); + PQclear(result); + clear_results(pgsql); + pgsql_finish(pgsql); + return false; + } + + PQclear(result); + clear_results(pgsql); + + if (pgsql->connectionStatementType == PGSQL_CONNECTION_SINGLE_STATEMENT) + { + pgsql_finish(pgsql); + } + + return true; +} + + /* * pgsql_has_replica returns whether a replica with the given username is active. */ diff --git a/src/bin/common/pgsql.h b/src/bin/common/pgsql.h index cd8387172..978f6b172 100644 --- a/src/bin/common/pgsql.h +++ b/src/bin/common/pgsql.h @@ -366,6 +366,8 @@ bool pgsql_create_extension(PGSQL *pgsql, const char *name); bool pgsql_create_user(PGSQL *pgsql, const char *userName, const char *password, bool login, bool superuser, bool replication, int connlimit); +bool pgsql_alter_role_password(PGSQL *pgsql, const char *roleName, + const char *password); bool pgsql_has_replica(PGSQL *pgsql, char *userName, bool *hasReplica); bool hostname_from_uri(const char *pguri, char *hostname, int maxHostLength, int *port); diff --git a/src/bin/pg_autoctl/cli_common.c b/src/bin/pg_autoctl/cli_common.c index a08b8509b..421235412 100644 --- a/src/bin/pg_autoctl/cli_common.c +++ b/src/bin/pg_autoctl/cli_common.c @@ -495,6 +495,24 @@ cli_common_keeper_getopts(int argc, char **argv, break; } + case 'W': + { + /* { "monitor-password", required_argument, NULL, 'W' } */ + strlcpy(LocalOptionConfig.monitor_password, optarg, + sizeof(LocalOptionConfig.monitor_password)); + log_trace("--monitor-password ****"); + break; + } + + case 'w': + { + /* { "replication-password", required_argument, NULL, 'w' } */ + strlcpy(LocalOptionConfig.replication_password, optarg, + sizeof(LocalOptionConfig.replication_password)); + log_trace("--replication-password ****"); + break; + } + /* * { "ssl-ca-file", required_argument, &ssl_flag, SSL_CA_FILE_FLAG } * { "ssl-crl-file", required_argument, &ssl_flag, SSL_CA_FILE_FLAG } diff --git a/src/bin/pg_autoctl/cli_create_node.c b/src/bin/pg_autoctl/cli_create_node.c index 8ef2e8643..c8d9c8a02 100644 --- a/src/bin/pg_autoctl/cli_create_node.c +++ b/src/bin/pg_autoctl/cli_create_node.c @@ -334,6 +334,8 @@ cli_create_postgres_getopts(int argc, char **argv) { "monitor", required_argument, NULL, 'm' }, { "disable-monitor", no_argument, NULL, 'M' }, { "node-id", required_argument, NULL, 'I' }, + { "monitor-password", required_argument, NULL, 'W' }, + { "replication-password", required_argument, NULL, 'w' }, { "version", no_argument, NULL, 'V' }, { "verbose", no_argument, NULL, 'v' }, { "quiet", no_argument, NULL, 'q' }, @@ -354,7 +356,7 @@ cli_create_postgres_getopts(int argc, char **argv) int optind = cli_create_node_getopts(argc, argv, long_options, - "C:D:H:p:l:U:A:SLd:a:n:f:m:MI:RVvqhP:r:xsN", + "C:D:H:p:l:U:A:SLd:a:n:f:m:MI:W:w:RVvqhP:r:xsN", &options); /* publish our option parsing in the global variable */ @@ -793,6 +795,8 @@ cli_create_monitor_getopts(int argc, char **argv) { "listen", required_argument, NULL, 'l' }, { "auth", required_argument, NULL, 'A' }, { "skip-pg-hba", no_argument, NULL, 'S' }, + { "autoctl-node-password", required_argument, NULL, 'W' }, + { "formation", required_argument, NULL, 'f' }, { "version", no_argument, NULL, 'V' }, { "verbose", no_argument, NULL, 'v' }, { "quiet", no_argument, NULL, 'q' }, @@ -821,7 +825,7 @@ cli_create_monitor_getopts(int argc, char **argv) optind = 0; - while ((c = getopt_long(argc, argv, "C:D:p:n:l:A:SVvqhxNs", + while ((c = getopt_long(argc, argv, "C:D:p:n:l:A:SW:f:VvqhxsN", long_options, &option_index)) != -1) { switch (c) @@ -898,6 +902,30 @@ cli_create_monitor_getopts(int argc, char **argv) break; } + case 'W': + { + strlcpy(options.autoctl_node_password, optarg, + sizeof(options.autoctl_node_password)); + log_trace("--autoctl-node-password ****"); + break; + } + + case 'f': + { + /* --formation (may be repeated) */ + if (options.formationCount >= MONITOR_MAX_FORMATIONS) + { + log_error("Too many --formation options (max %d)", + MONITOR_MAX_FORMATIONS); + errors++; + break; + } + int fi = options.formationCount++; + strlcpy(options.formationNames[fi], optarg, NAMEDATALEN); + log_trace("--formation %s", optarg); + break; + } + case 'V': { /* keeper_cli_print_version prints version and exits. */ diff --git a/src/bin/pg_autoctl/cli_do_fsm.c b/src/bin/pg_autoctl/cli_do_fsm.c index 738800066..848272bab 100644 --- a/src/bin/pg_autoctl/cli_do_fsm.c +++ b/src/bin/pg_autoctl/cli_do_fsm.c @@ -29,6 +29,8 @@ static void cli_do_fsm_init(int argc, char **argv); static void cli_do_fsm_state(int argc, char **argv); +static int cli_do_fsm_node_state_getopts(int argc, char **argv); +static void cli_do_fsm_node_state(int argc, char **argv); static void cli_do_fsm_list(int argc, char **argv); static void cli_do_fsm_gv(int argc, char **argv); static void cli_do_fsm_assign(int argc, char **argv); @@ -46,6 +48,16 @@ CommandLine fsm_state = cli_getopt_pgdata, cli_do_fsm_state); +CommandLine fsm_node_state = + make_command("node-state", + "Poll the keeper's on-disk current_role; exit 0 when it matches --state", + CLI_PGDATA_USAGE, + " --pgdata path to the keeper's data directory\n" + " --state target state to wait for (e.g. demote_timeout)\n" + " --timeout seconds to retry (default: no retry)\n", + cli_do_fsm_node_state_getopts, + cli_do_fsm_node_state); + CommandLine fsm_list = make_command("list", "List reachable FSM states from current state", @@ -230,6 +242,126 @@ cli_do_fsm_state(int argc, char **argv) } +/* option state for fsm node-state */ +static struct { + char targetState[64]; + int timeout; +} fsmNodeStateOpts; + +static int +cli_do_fsm_node_state_getopts(int argc, char **argv) +{ + fsmNodeStateOpts.targetState[0] = '\0'; + fsmNodeStateOpts.timeout = 0; + + static struct option long_options[] = { + { "pgdata", required_argument, NULL, 'D' }, + { "state", required_argument, NULL, 's' }, + { "timeout", required_argument, NULL, 't' }, + { NULL, 0, NULL, 0 } + }; + + int c; + optind = 0; + while ((c = getopt_long(argc, argv, "D:s:t:", long_options, NULL)) != -1) + { + switch (c) + { + case 'D': + strlcpy(keeperOptions.pgSetup.pgdata, optarg, + sizeof(keeperOptions.pgSetup.pgdata)); + break; + case 's': + strlcpy(fsmNodeStateOpts.targetState, optarg, + sizeof(fsmNodeStateOpts.targetState)); + break; + case 't': + fsmNodeStateOpts.timeout = atoi(optarg); + break; + default: + commandline_print_usage(&fsm_node_state, stderr); + exit(EXIT_CODE_BAD_ARGS); + } + } + + /* fall back to $PGDATA when --pgdata was not given */ + cli_common_get_set_pgdata_or_exit(&keeperOptions.pgSetup); + + if (!keeper_config_set_pathnames_from_pgdata(&keeperOptions.pathnames, + keeperOptions.pgSetup.pgdata)) + { + exit(EXIT_CODE_BAD_ARGS); + } + + return optind; +} + +/* + * cli_do_fsm_node_state reads the keeper's on-disk state and prints: + * | + * + * When --state is given the command retries until current_role matches. + * When --timeout is given the retry loop stops after N seconds. + */ +static void +cli_do_fsm_node_state(int argc, char **argv) +{ + KeeperConfig config = keeperOptions; + + bool missingPgdataIsOk = true; + bool pgIsNotRunningIsOk = true; + bool monitorDisabledIsOk = true; + + if (!keeper_config_read_file(&config, + missingPgdataIsOk, + pgIsNotRunningIsOk, + monitorDisabledIsOk)) + { + exit(EXIT_CODE_BAD_CONFIG); + } + + time_t deadline = (fsmNodeStateOpts.timeout > 0) + ? time(NULL) + fsmNodeStateOpts.timeout + : 0; + + for (;;) + { + Keeper keeper = { 0 }; + + if (!keeper_init(&keeper, &config)) + { + if (deadline && time(NULL) < deadline) + { + pg_usleep(500 * 1000); + continue; + } + exit(EXIT_CODE_BAD_CONFIG); + } + + KeeperStateData *s = &keeper.state; + const char *current = NodeStateToString(s->current_role); + const char *assigned = NodeStateToString(s->assigned_role); + + if (fsmNodeStateOpts.targetState[0] != '\0' && + strcmp(current, fsmNodeStateOpts.targetState) != 0) + { + log_debug("fsm node-state: current_role=%s, waiting for %s", + current, fsmNodeStateOpts.targetState); + if (deadline && time(NULL) < deadline) + { + pg_usleep(500 * 1000); + continue; + } + /* timed out or --timeout 0 with no match */ + exit(EXIT_CODE_INTERNAL_ERROR); + } + + fformat(stdout, "%s|%s\n", current, assigned); + exit(0); + } +} + + /* * cli_do_fsm_list lists reachable states from the current one. */ diff --git a/src/bin/pg_autoctl/cli_do_misc.c b/src/bin/pg_autoctl/cli_do_misc.c index 799906cb9..846b356e8 100644 --- a/src/bin/pg_autoctl/cli_do_misc.c +++ b/src/bin/pg_autoctl/cli_do_misc.c @@ -30,10 +30,17 @@ #include "monitor.h" #include "monitor_config.h" #include "pgctl.h" +#include "pghba.h" +#include "pgsetup.h" +#include "pgsql.h" #include "pgtuning.h" #include "primary_standby.h" #include "string_utils.h" +/* Options specific to "pg_autoctl inspect pgsetup wait" */ +static bool pgsetupWaitReadWrite = false; +static int pgsetupWaitTimeout = 30; + /* * keeper_cli_create_replication_slot implements the CLI to create a replication @@ -319,18 +326,112 @@ keeper_cli_pgsetup_is_ready(int argc, char **argv) /* - * keeper_cli_discover_pg_setup implements the CLI to discover a PostgreSQL - * setup thanks to PGDATA and other environment variables. + * keeper_cli_pgsetup_wait_getopts parses options specific to + * "pg_autoctl inspect pgsetup wait": --read-write, --timeout, plus the + * standard Postgres connection options inherited from the keeper setup. + */ +int +keeper_cli_pgsetup_wait_getopts(int argc, char **argv) +{ + /* + * Delegate standard keeper options to keeper_cli_keeper_setup_getopts, + * which populates keeperOptions. Then do a second scan with opterr=0 to + * pick up the two new flags that the common function doesn't know about. + * Because getopt_long returns '?' for unknown flags (and we suppress the + * error message), we only act on 'W' and 'T' and ignore everything else. + */ + int rc = keeper_cli_keeper_setup_getopts(argc, argv); + + /* Reset module-level wait options */ + pgsetupWaitReadWrite = false; + pgsetupWaitTimeout = 30; + + static struct option wait_options[] = { + { "read-write", no_argument, NULL, 'W' }, + { "timeout", required_argument, NULL, 'T' }, + { NULL, 0, NULL, 0 } + }; + + optind = 1; + opterr = 0; + + int c; + int option_index = 0; + + while ((c = getopt_long(argc, argv, "WT:", wait_options, &option_index)) != -1) + { + switch (c) + { + case 'W': + pgsetupWaitReadWrite = true; + break; + + case 'T': + { + int t = strtol(optarg, NULL, 10); + if (t <= 0) + { + log_error("--timeout must be a positive integer"); + exit(EXIT_CODE_BAD_ARGS); + } + pgsetupWaitTimeout = t; + break; + } + + default: + /* all other options handled by the first pass above */ + break; + } + } + + opterr = 1; + + return rc; +} + + +/* + * keeper_cli_pgsetup_wait_until_ready waits for the local Postgres server to + * become ready. When --read-write is given, it additionally waits until the + * server is accepting read-write connections (not in recovery and not set to + * default_transaction_read_only). + * + * The --timeout value (default 30s) is a single deadline shared by both + * phases: the pg_is_ready poll and the subsequent read-write connection + * attempt. Time spent waiting for Postgres to start counts against the + * budget for the read-write phase. */ void keeper_cli_pgsetup_wait_until_ready(int argc, char **argv) { - int timeout = 30; + int timeout = pgsetupWaitTimeout; ConfigFilePaths pathnames = { 0 }; LocalPostgresServer postgres = { 0 }; PostgresSetup *pgSetup = &(postgres.postgresSetup); + /* Record wall-clock start so all phases share one deadline. */ + time_t startTime = time(NULL); + + /* Wait up to `timeout` seconds for the config file to be created. + * In no-monitor mode, pg_autoctl create postgres runs first and writes the + * config; pgsetup wait may be called before that completes. */ + { + KeeperConfig kconfig = keeperOptions; + if (keeper_config_set_pathnames_from_pgdata(&(kconfig.pathnames), + kconfig.pgSetup.pgdata)) + { + time_t deadline = startTime + timeout; + while (!file_exists(kconfig.pathnames.config) && + time(NULL) < deadline) + { + log_debug("Waiting for config file \"%s\" to appear", + kconfig.pathnames.config); + pg_usleep(500 * 1000); + } + } + } + if (!cli_common_pgsetup_init(&pathnames, pgSetup)) { /* errors have already been logged */ @@ -339,15 +440,105 @@ keeper_cli_pgsetup_wait_until_ready(int argc, char **argv) log_debug("Initialized pgSetup, now calling pg_setup_wait_until_is_ready()"); - bool pgIsReady = pg_setup_wait_until_is_ready(pgSetup, timeout, LOG_INFO); + /* + * Phase 1: wait for postmaster to signal "ready" in postmaster.pid. + * Pass the remaining timeout so the two phases together stay within the + * single user-visible deadline. + */ + int remainingAfterConfig = timeout - (int) (time(NULL) - startTime); + if (remainingAfterConfig <= 0) + { + log_error("Timed out waiting for Postgres config file to appear"); + exit(EXIT_CODE_PGSQL); + } + + bool pgIsReady = + pg_setup_wait_until_is_ready(pgSetup, remainingAfterConfig, LOG_INFO); log_info("Postgres status is: \"%s\"", pmStatusToString(pgSetup->pm_status)); - if (pgIsReady) + if (!pgIsReady) + { + exit(EXIT_CODE_PGSQL); + } + + if (!pgsetupWaitReadWrite) { + /* Plain "ready" check — we're done. */ exit(EXIT_CODE_QUIT); } - exit(EXIT_CODE_PGSQL); + + /* + * Phase 2: wait until the server accepts read-write connections. + * + * Postgres is up (phase 1 passed) but may still be in recovery, finishing + * pg_rewind, or in standby mode. We poll with a libpq connection that + * checks pg_is_in_recovery() until it returns false or the deadline fires. + * + * We use the local connection string from pgSetup (Unix socket when + * available, matching whatever auth the node was created with) so that the + * check works regardless of the cluster's auth method. + */ + char connstr[MAXCONNINFO]; + if (!pg_setup_get_local_connection_string(pgSetup, connstr)) + { + log_error("Failed to build local connection string for read-write check"); + exit(EXIT_CODE_BAD_CONFIG); + } + + log_info("Waiting for Postgres to accept read-write connections " + "(timeout %ds)", timeout); + + bool isReadWrite = false; + int attempts = 0; + + while (!isReadWrite) + { + int elapsed = (int) (time(NULL) - startTime); + int remaining = timeout - elapsed; + + if (remaining <= 0) + { + log_error("Timed out after %ds waiting for Postgres " + "to accept read-write connections", timeout); + exit(EXIT_CODE_PGSQL); + } + + /* Use a short per-attempt connect_timeout so we retry briskly. */ + char attemptConnstr[MAXCONNINFO]; + snprintf(attemptConnstr, sizeof(attemptConnstr), + "%s connect_timeout=1", connstr); + + PGSQL pgsql = { 0 }; + pgsql_init(&pgsql, attemptConnstr, PGSQL_CONN_LOCAL); + + bool inRecovery = true; /* assume standby until proven otherwise */ + bool queryOk = pgsql_is_in_recovery(&pgsql, &inRecovery); + pgsql_finish(&pgsql); + + if (queryOk && !inRecovery) + { + isReadWrite = true; + break; + } + + /* let's not be THAT verbose about it */ + if (attempts % 10 == 0) + { + log_debug("pgsetup wait --read-write: attempt %d, " + "in_recovery=%s, after %ds", + attempts + 1, + inRecovery ? "true" : "false", + elapsed); + } + + ++attempts; + pg_usleep(100 * 1000); /* 100 ms between probes */ + } + + log_info("Postgres is now accepting read-write connections on port %d", + pgSetup->pgport); + exit(EXIT_CODE_QUIT); } @@ -393,6 +584,115 @@ keeper_cli_pgsetup_tune(int argc, char **argv) } +/* + * keeper_cli_pgsetup_hba_lan appends LAN CIDR trust rules to pg_hba.conf + * without connecting to Postgres (safe when TCP HBA hasn't been set up yet), + * then reloads the configuration via pg_ctl. + * + * Intended for --skip-pg-hba setups where the operator needs to seed the + * initial trust rules before pg_autoctl or replication can connect via TCP. + * + * Sequence: + * 1. Wait up to 60 s for $PGDATA/pg_hba.conf to appear. + * 2. Append "host all all trust" and + * "host replication all trust" directly to the file. + * 3. Wait for Postgres to be running (reads postmaster.pid, no TCP). + * 4. pg_ctl reload -D $PGDATA. + */ +void +keeper_cli_pgsetup_hba_lan(int argc, char **argv) +{ + ConfigFilePaths pathnames = { 0 }; + LocalPostgresServer postgres = { 0 }; + PostgresSetup *pgSetup = &(postgres.postgresSetup); + + if (!cli_common_pgsetup_init(&pathnames, pgSetup)) + { + exit(EXIT_CODE_BAD_CONFIG); + } + + const char *pgdata = pgSetup->pgdata; + char hbaFile[MAXPGPATH]; + sformat(hbaFile, MAXPGPATH, "%s/pg_hba.conf", pgdata); + + /* Step 1: wait for pg_hba.conf to appear */ + { + int timeout = 60; + time_t deadline = time(NULL) + timeout; + while (!file_exists(hbaFile) && time(NULL) < deadline) + { + log_debug("Waiting for \"%s\" to appear", hbaFile); + pg_usleep(500 * 1000); + } + if (!file_exists(hbaFile)) + { + log_error("Timed out waiting for \"%s\" to appear", hbaFile); + exit(EXIT_CODE_PGCTL); + } + } + + /* Step 2: append LAN CIDR rules directly to the file (no TCP) */ + const char *hostname = pgSetup->pghost; + + /* --auth defaults to "trust"; --ssl enables hostssl rules */ + const char *authMethod = keeperOptions.pgSetup.authMethod; + if (IS_EMPTY_STRING_BUFFER(authMethod)) + authMethod = "trust"; + bool useSSL = keeperOptions.pgSetup.ssl.active; + + /* cert auth for replication needs an ident map */ + bool isCert = (strcmp(authMethod, "cert") == 0); + const char *replAuth = isCert ? "cert map=pgautofailover" : authMethod; + + if (!pghba_enable_lan_cidr(NULL, useSSL, + HBA_DATABASE_ALL, NULL, + hostname, NULL, authMethod, + HBA_EDIT_MINIMAL, + pgdata)) + { + log_error("Failed to add LAN CIDR HBA rule for \"all\" databases"); + exit(EXIT_CODE_PGCTL); + } + + if (!pghba_enable_lan_cidr(NULL, useSSL, + HBA_DATABASE_REPLICATION, NULL, + hostname, NULL, replAuth, + HBA_EDIT_MINIMAL, + pgdata)) + { + log_error("Failed to add LAN CIDR HBA rule for replication"); + exit(EXIT_CODE_PGCTL); + } + + /* cert auth requires an ident map entry in pg_ident.conf */ + if (isCert) + { + if (!pghba_ensure_ident_map_entry(pgdata, + "pgautofailover", + PG_AUTOCTL_MONITOR_USERNAME, + PG_AUTOCTL_REPLICA_USERNAME)) + { + log_error("Failed to add cert ident map entry to pg_ident.conf"); + exit(EXIT_CODE_PGCTL); + } + } + + /* Step 3: wait for Postgres to be running (PID file, no TCP needed) */ + if (!pg_setup_wait_until_is_ready(pgSetup, 60, LOG_INFO)) + { + log_error("Postgres did not become ready within 60 s"); + exit(EXIT_CODE_PGCTL); + } + + /* Step 4: reload so the new HBA rules take effect */ + log_info("Reloading Postgres configuration in \"%s\"", pgdata); + if (!pg_ctl_reload(pgSetup->pg_ctl, pgdata)) + { + exit(EXIT_CODE_PGCTL); + } +} + + /* * keeper_cli_init_standby initializes a standby */ diff --git a/src/bin/pg_autoctl/cli_do_monitor.c b/src/bin/pg_autoctl/cli_do_monitor.c index 65d9512c5..e810d49cf 100644 --- a/src/bin/pg_autoctl/cli_do_monitor.c +++ b/src/bin/pg_autoctl/cli_do_monitor.c @@ -36,7 +36,9 @@ #include "pgctl.h" #include "pgsetup.h" #include "pgsql.h" +#include "pqexpbuffer.h" #include "state.h" +#include "string_utils.h" static void cli_do_monitor_get_primary_node(int argc, char **argv); static void cli_do_monitor_get_other_nodes(int argc, char **argv); @@ -46,6 +48,10 @@ static void cli_do_monitor_register_node(int argc, char **argv); static void cli_do_monitor_node_active(int argc, char **argv); static void cli_do_monitor_version(int argc, char **argv); static void cli_do_monitor_parse_notification(int argc, char **argv); +static int cli_do_monitor_node_state_getopts(int argc, char **argv); +static void cli_do_monitor_node_state(int argc, char **argv); +static int cli_do_monitor_formation_states_getopts(int argc, char **argv); +static void cli_do_monitor_formation_states(int argc, char **argv); static CommandLine monitor_get_primary_command = @@ -127,6 +133,27 @@ CommandLine monitor_parse_notification_command = NULL, cli_do_monitor_parse_notification); +CommandLine monitor_node_state_command = + make_command("node-state", + "Print reported|assigned state for a named node (for test runners)", + "--name [--state ] [--monitor ] [--timeout N]", + " --name node name to query\n" + " --state wait until reportedstate matches (requires --timeout)\n" + " --monitor monitor URI (default: local socket)\n" + " --timeout N retry for up to N seconds (default: no retry)\n", + cli_do_monitor_node_state_getopts, + cli_do_monitor_node_state); + +CommandLine monitor_formation_states_command = + make_command("formation-states", + "Exit 0 when every listed state has at least one node (for test runners)", + "[--group N] [--timeout N] [...]", + " --group N restrict to this group id\n" + " --monitor monitor URI (default: local socket)\n" + " --timeout N retry for up to N seconds (default: no retry)\n", + cli_do_monitor_formation_states_getopts, + cli_do_monitor_formation_states); + static CommandLine *monitor_subcommands[] = { &monitor_get_command, &monitor_register_command, @@ -703,3 +730,391 @@ cli_do_monitor_parse_notification(int argc, char **argv) (void) cli_pprint_json(js); } + + +/* ----------------------------------------------------------------------- + * pg_autoctl inspect monitor node-state --name + * pg_autoctl inspect monitor formation-states [--group N] [...] + * + * These two commands run ON the monitor container. They connect to the + * local PostgreSQL socket and return structured output consumed by the + * pgaftest test runner via `docker compose exec -T monitor pg_autoctl …`. + * Using dedicated subcommands (rather than shelling to psql) avoids all + * shell quoting issues. + * ----------------------------------------------------------------------- */ + +#define MONITOR_LOCAL_URI \ + "postgresql://autoctl_node@localhost/pg_auto_failover?sslmode=prefer" + +/* Shared option state for both new commands */ +static struct { + char monitorUri[MAXCONNINFO]; + char nodeName[_POSIX_HOST_NAME_MAX]; + char targetState[64]; /* --state: wait until reportedstate matches */ + char formation[NAMEDATALEN]; /* --formation: filter by formation */ + int groupId; /* -1 = all groups */ + int timeout; /* 0 = no retry loop, N = retry for N seconds */ +} inspectOpts; + +static int +cli_do_monitor_node_state_getopts(int argc, char **argv) +{ + /* defaults */ + strlcpy(inspectOpts.monitorUri, MONITOR_LOCAL_URI, sizeof(inspectOpts.monitorUri)); + inspectOpts.nodeName[0] = '\0'; + inspectOpts.targetState[0] = '\0'; + inspectOpts.groupId = -1; + inspectOpts.timeout = 0; + + static struct option long_options[] = { + { "monitor", required_argument, NULL, 'm' }, + { "name", required_argument, NULL, 'n' }, + { "state", required_argument, NULL, 's' }, + { "timeout", required_argument, NULL, 't' }, + { NULL, 0, NULL, 0 } + }; + + int c; + optind = 0; + while ((c = getopt_long(argc, argv, "m:n:s:t:", long_options, NULL)) != -1) + { + switch (c) + { + case 'm': + strlcpy(inspectOpts.monitorUri, optarg, + sizeof(inspectOpts.monitorUri)); + break; + case 'n': + strlcpy(inspectOpts.nodeName, optarg, + sizeof(inspectOpts.nodeName)); + break; + case 's': + strlcpy(inspectOpts.targetState, optarg, + sizeof(inspectOpts.targetState)); + break; + case 't': + inspectOpts.timeout = atoi(optarg); + break; + default: + commandline_print_usage(&monitor_node_state_command, stderr); + exit(EXIT_CODE_BAD_ARGS); + } + } + + if (inspectOpts.nodeName[0] == '\0') + { + log_error("--name is required"); + exit(EXIT_CODE_BAD_ARGS); + } + + return optind; +} + +/* + * cli_do_monitor_node_state connects to the local monitor and prints: + * | + * for the named node, then exits 0. Exits non-zero if the node is not + * found or the monitor is unreachable. + * + * When --timeout N is given the command retries for up to N seconds using the + * same exponential-backoff-with-jitter policy used elsewhere in pg_autoctl. + */ +static void +cli_do_monitor_node_state(int argc, char **argv) +{ + const char *sql = + "SELECT reportedstate::text || '|' || goalstate::text || '|' || health::text " + "FROM pgautofailover.node WHERE nodename = $1"; + + int paramCount = 1; + Oid paramTypes[1] = { TEXTOID }; + const char *paramValues[1] = { inspectOpts.nodeName }; + + ConnectionRetryPolicy retryPolicy = { 0 }; + + if (inspectOpts.timeout > 0) + pgsql_set_retry_policy(&retryPolicy, + inspectOpts.timeout, + -1, /* unbounded attempts within timeout */ + 2000, /* cap at 2 s between attempts */ + 500); /* start at 500 ms */ + else + pgsql_set_retry_policy(&retryPolicy, 0, 0, 0, 0); /* no retry */ + + do { + Monitor monitor = { 0 }; + + if (!monitor_init(&monitor, inspectOpts.monitorUri)) + { + /* connection failure: retry if policy allows */ + goto next_attempt; + } + + SingleValueResultContext ctx = { { 0 }, PGSQL_RESULT_STRING, false }; + + if (!pgsql_execute_with_params(&monitor.pgsql, sql, + paramCount, paramTypes, paramValues, + &ctx, &parseSingleValueResult)) + { + pgsql_finish(&monitor.pgsql); + goto next_attempt; + } + + pgsql_finish(&monitor.pgsql); + + if (!ctx.parsedOk || ctx.strVal == NULL) + { + /* node not found yet */ + if (ctx.strVal) free(ctx.strVal); + goto next_attempt; + } + + /* + * When --state was given, check that reportedstate (the part + * before the first '|') matches the target. + * Output format: reportedstate|goalstate|health + */ + if (inspectOpts.targetState[0] != '\0') + { + char reported[64] = ""; + char *pipe = strchr(ctx.strVal, '|'); + if (pipe) + { + int len = pipe - ctx.strVal; + if (len >= (int) sizeof(reported)) + len = sizeof(reported) - 1; + memcpy(reported, ctx.strVal, len); + reported[len] = '\0'; + } + if (strcmp(reported, inspectOpts.targetState) != 0) + { + free(ctx.strVal); + goto next_attempt; + } + } + + fformat(stdout, "%s\n", ctx.strVal); + free(ctx.strVal); + exit(0); + +next_attempt: + if (pgsql_retry_policy_expired(&retryPolicy)) + break; + + int sleepMs = pgsql_compute_connection_retry_sleep_time(&retryPolicy); + log_debug("node-state: node \"%s\" not found yet, retrying in %d ms", + inspectOpts.nodeName, sleepMs); + pg_usleep((long) sleepMs * 1000); + + } while (!pgsql_retry_policy_expired(&retryPolicy)); + + log_error("Node \"%s\" not found on the monitor", inspectOpts.nodeName); + exit(EXIT_CODE_MONITOR); +} + + +static int +cli_do_monitor_formation_states_getopts(int argc, char **argv) +{ + strlcpy(inspectOpts.monitorUri, MONITOR_LOCAL_URI, sizeof(inspectOpts.monitorUri)); + inspectOpts.formation[0] = '\0'; + inspectOpts.groupId = -1; + inspectOpts.timeout = 0; + + static struct option long_options[] = { + { "monitor", required_argument, NULL, 'm' }, + { "formation", required_argument, NULL, 'F' }, + { "group", required_argument, NULL, 'g' }, + { "timeout", required_argument, NULL, 't' }, + { NULL, 0, NULL, 0 } + }; + + int c; + optind = 0; + while ((c = getopt_long(argc, argv, "m:F:g:t:", long_options, NULL)) != -1) + { + switch (c) + { + case 'm': + strlcpy(inspectOpts.monitorUri, optarg, + sizeof(inspectOpts.monitorUri)); + break; + case 'F': + strlcpy(inspectOpts.formation, optarg, + sizeof(inspectOpts.formation)); + break; + case 'g': + inspectOpts.groupId = atoi(optarg); + break; + case 't': + inspectOpts.timeout = atoi(optarg); + break; + default: + commandline_print_usage(&monitor_formation_states_command, stderr); + exit(EXIT_CODE_BAD_ARGS); + } + } + + return optind; +} + +/* + * cli_do_monitor_formation_states checks that every state listed on the + * command line has at least one node currently in that reportedstate. + * + * Exits 0 when all states are satisfied. When --timeout N is given the + * command retries for up to N seconds using the same exponential-backoff- + * with-jitter policy used elsewhere in pg_autoctl; without it the command + * exits 1 immediately when the condition is not met. + */ +static void +cli_do_monitor_formation_states(int argc, char **argv) +{ + if (argc < 1) + { + log_error("Expected at least one state name as argument"); + commandline_print_usage(&monitor_formation_states_command, stderr); + exit(EXIT_CODE_BAD_ARGS); + } + +#define MAX_STATES 16 + if (argc > MAX_STATES) + { + log_error("Too many states (max %d)", MAX_STATES); + exit(EXIT_CODE_BAD_ARGS); + } + + /* + * Build the SQL once; the params are the same across every retry attempt. + * + * SELECT (count(*) FILTER (WHERE reportedstate::text = $1))::text + * || ',' || + * (count(*) FILTER (WHERE reportedstate::text = $2))::text + * ... + * FROM pgautofailover.node + * [WHERE groupid = $N] + */ + PQExpBufferData sqlBuf; + initPQExpBuffer(&sqlBuf); + + appendPQExpBufferStr(&sqlBuf, "SELECT "); + for (int i = 0; i < argc; i++) + { + if (i > 0) + appendPQExpBufferStr(&sqlBuf, " || ',' || "); + appendPQExpBuffer(&sqlBuf, + "(count(*) FILTER (WHERE reportedstate::text = $%d))::text", + i + 1); + } + appendPQExpBufferStr(&sqlBuf, " FROM pgautofailover.node"); + + bool hasFormation = inspectOpts.formation[0] != '\0'; + bool hasGroup = inspectOpts.groupId >= 0; + bool needWhere = hasFormation || hasGroup; + int extraParams = (hasFormation ? 1 : 0) + (hasGroup ? 1 : 0); + + if (needWhere) + { + appendPQExpBufferStr(&sqlBuf, " WHERE"); + if (hasFormation) + appendPQExpBuffer(&sqlBuf, " formationid = $%d", argc + 1); + if (hasGroup) + appendPQExpBuffer(&sqlBuf, "%s groupid = $%d", + hasFormation ? " AND" : "", + argc + (hasFormation ? 2 : 1)); + } + + int paramCount = argc + extraParams; + Oid paramTypes[MAX_STATES + 2]; + const char *paramValues[MAX_STATES + 2]; + IntString groupIdStr = { 0 }; + + for (int i = 0; i < argc; i++) + { + paramTypes[i] = TEXTOID; + paramValues[i] = argv[i]; + } + if (extraParams > 0) + { + int pi = argc; + if (hasFormation) + { + paramTypes[pi] = TEXTOID; + paramValues[pi] = inspectOpts.formation; + pi++; + } + if (hasGroup) + { + groupIdStr = intToString(inspectOpts.groupId); + paramTypes[pi] = INT4OID; + paramValues[pi] = groupIdStr.strValue; + } + } + + ConnectionRetryPolicy retryPolicy = { 0 }; + + if (inspectOpts.timeout > 0) + pgsql_set_retry_policy(&retryPolicy, + inspectOpts.timeout, + -1, /* unbounded attempts within timeout */ + 2000, /* cap at 2 s between attempts */ + 500); /* start at 500 ms */ + else + pgsql_set_retry_policy(&retryPolicy, 0, 0, 0, 0); /* no retry */ + + do { + Monitor monitor = { 0 }; + + if (!monitor_init(&monitor, inspectOpts.monitorUri)) + goto next_attempt; + + SingleValueResultContext ctx = { { 0 }, PGSQL_RESULT_STRING, false }; + + if (!pgsql_execute_with_params(&monitor.pgsql, sqlBuf.data, + paramCount, paramTypes, paramValues, + &ctx, &parseSingleValueResult)) + { + pgsql_finish(&monitor.pgsql); + goto next_attempt; + } + + pgsql_finish(&monitor.pgsql); + + if (!ctx.parsedOk || ctx.strVal == NULL) + { + if (ctx.strVal) free(ctx.strVal); + goto next_attempt; + } + + /* parse "N,N,..." — all must be >= 1 */ + bool allMet = true; + char *p = ctx.strVal; + for (int i = 0; i < argc; i++) + { + int cnt = atoi(p); + if (cnt < 1) { allMet = false; break; } + p = strchr(p, ','); + if (p) p++; else break; + } + free(ctx.strVal); + + if (allMet) + { + termPQExpBuffer(&sqlBuf); + exit(0); + } + +next_attempt: + if (pgsql_retry_policy_expired(&retryPolicy)) + break; + + int sleepMs = pgsql_compute_connection_retry_sleep_time(&retryPolicy); + log_debug("formation-states: condition not met yet, retrying in %d ms", + sleepMs); + pg_usleep((long) sleepMs * 1000); + + } while (!pgsql_retry_policy_expired(&retryPolicy)); + + termPQExpBuffer(&sqlBuf); + exit(1); +} diff --git a/src/bin/pg_autoctl/cli_do_root.c b/src/bin/pg_autoctl/cli_do_root.c index 72d5d5cdb..42e77f770 100644 --- a/src/bin/pg_autoctl/cli_do_root.c +++ b/src/bin/pg_autoctl/cli_do_root.c @@ -185,9 +185,11 @@ CommandLine do_pgsetup_is_ready = CommandLine do_pgsetup_wait_until_ready = make_command("wait", "Wait until the local Postgres server is ready", - "[option ...]", + "[--read-write] [--timeout N] [option ...]", + " --read-write also wait until the server accepts read-write connections\n" + " --timeout N total timeout in seconds (default: 30)\n" KEEPER_CLI_WORKER_SETUP_OPTIONS, - keeper_cli_keeper_setup_getopts, + keeper_cli_pgsetup_wait_getopts, keeper_cli_pgsetup_wait_until_ready); CommandLine do_pgsetup_startup_logs = @@ -206,6 +208,14 @@ CommandLine do_pgsetup_tune = keeper_cli_keeper_setup_getopts, keeper_cli_pgsetup_tune); +CommandLine do_pgsetup_hba_lan = + make_command("hba-lan", + "Append LAN CIDR trust rules to pg_hba.conf and reload Postgres", + "[option ...]", + KEEPER_CLI_WORKER_SETUP_OPTIONS, + keeper_cli_keeper_setup_getopts, + keeper_cli_pgsetup_hba_lan); + CommandLine *do_pgsetup[] = { &do_pgsetup_pg_ctl, &do_pgsetup_discover, @@ -213,6 +223,7 @@ CommandLine *do_pgsetup[] = { &do_pgsetup_wait_until_ready, &do_pgsetup_startup_logs, &do_pgsetup_tune, + &do_pgsetup_hba_lan, NULL }; diff --git a/src/bin/pg_autoctl/cli_do_root.h b/src/bin/pg_autoctl/cli_do_root.h index 463389496..a6a2073c6 100644 --- a/src/bin/pg_autoctl/cli_do_root.h +++ b/src/bin/pg_autoctl/cli_do_root.h @@ -17,6 +17,7 @@ extern CommandLine do_fsm_commands; /* read-only sub-commands exposed via "pg_autoctl inspect fsm" */ extern CommandLine fsm_state; +extern CommandLine fsm_node_state; extern CommandLine fsm_list; extern CommandLine fsm_gv; /* mutating sub-commands exposed via "pg_autoctl manual fsm" */ @@ -30,6 +31,8 @@ extern CommandLine do_monitor_commands; /* read-only sub-commands exposed via "pg_autoctl inspect monitor" */ extern CommandLine monitor_get_command; extern CommandLine monitor_parse_notification_command; +extern CommandLine monitor_node_state_command; +extern CommandLine monitor_formation_states_command; /* mutating sub-commands exposed via "pg_autoctl manual monitor" */ extern CommandLine monitor_register_command; extern CommandLine monitor_node_active_command; @@ -109,9 +112,11 @@ void keeper_cli_disable_synchronous_replication(int argc, char **argv); void keeper_cli_pgsetup_pg_ctl(int argc, char **argv); void keeper_cli_pgsetup_discover(int argc, char **argv); void keeper_cli_pgsetup_is_ready(int argc, char **argv); +int keeper_cli_pgsetup_wait_getopts(int argc, char **argv); void keeper_cli_pgsetup_wait_until_ready(int argc, char **argv); void keeper_cli_pgsetup_startup_logs(int argc, char **argv); void keeper_cli_pgsetup_tune(int argc, char **argv); +void keeper_cli_pgsetup_hba_lan(int argc, char **argv); void keeper_cli_add_default_settings(int argc, char **argv); void keeper_cli_create_monitor_user(int argc, char **argv); diff --git a/src/bin/pg_autoctl/cli_drop_node.c b/src/bin/pg_autoctl/cli_drop_node.c index 3ecefffc6..b08f6cca5 100644 --- a/src/bin/pg_autoctl/cli_drop_node.c +++ b/src/bin/pg_autoctl/cli_drop_node.c @@ -47,6 +47,7 @@ */ bool dropAndDestroy = false; static bool dropForce = false; +static bool dropNoWait = false; static void cli_drop_monitor(int argc, char **argv); @@ -103,6 +104,7 @@ cli_drop_node_getopts(int argc, char **argv) { "monitor", required_argument, NULL, 'm' }, { "destroy", no_argument, NULL, 'd' }, { "force", no_argument, NULL, 'F' }, + { "no-wait", no_argument, NULL, 'W' }, { "hostname", required_argument, NULL, 'n' }, { "pgport", required_argument, NULL, 'p' }, { "formation", required_argument, NULL, 'f' }, @@ -159,6 +161,13 @@ cli_drop_node_getopts(int argc, char **argv) break; } + case 'W': + { + dropNoWait = true; + log_trace("--no-wait"); + break; + } + case 'n': { strlcpy(options.hostname, optarg, _POSIX_HOST_NAME_MAX); @@ -594,6 +603,19 @@ cli_drop_local_node(KeeperConfig *config, bool dropAndDestroy) (void) cli_drop_node_from_monitor(config, &nodeId, &groupId); } + /* + * With --no-wait the caller takes responsibility for waiting until the + * supervisor has stopped (e.g. via `docker compose wait` in a container + * environment). The running keeper will detect it has been dropped on its + * next node_active() heartbeat and exit cleanly on its own. + */ + if (dropNoWait) + { + log_info("Node unregistered from monitor; not waiting for the local " + "pg_autoctl process to stop (--no-wait)."); + exit(EXIT_CODE_QUIT); + } + /* * Now, when the pg_autoctl keeper service is still running, wait until * it has reached the DROPPED/DROPPED state on-disk and then exited. diff --git a/src/bin/pg_autoctl/cli_get_set_properties.c b/src/bin/pg_autoctl/cli_get_set_properties.c index f61b1d168..fb1c65c1d 100644 --- a/src/bin/pg_autoctl/cli_get_set_properties.c +++ b/src/bin/pg_autoctl/cli_get_set_properties.c @@ -7,10 +7,16 @@ * Licensed under the PostgreSQL License. * */ +#include +#include + #include "parson.h" #include "cli_common.h" +#include "monitor_pg_init.h" #include "parsing.h" +#include "pgsql.h" +#include "pgsetup.h" #include "string_utils.h" static bool get_node_replication_settings(NodeReplicationSettings *settings); @@ -22,6 +28,8 @@ static void cli_set_node_replication_quorum(int argc, char **argv); static void cli_set_node_candidate_priority(int argc, char **argv); static void cli_set_node_metadata(int argc, char **argv); static void cli_set_formation_number_sync_standbys(int arc, char **argv); +static int cli_set_password_getopts(int argc, char **argv); +static void cli_set_password(int argc, char **argv); static bool set_node_candidate_priority(Keeper *keeper, int candidatePriority); static bool set_node_replication_quorum(Keeper *keeper, bool replicationQuorum); @@ -181,9 +189,21 @@ static CommandLine set_formation_command = set_formation_subcommands); +static CommandLine set_password_command = + make_command("password", + "set the password for a pg_auto_failover role", + " [ --pgdata ] --role [ --password ]", + " --pgdata path to data directory\n" + " --role one of: autoctl_node, pgautofailover_monitor," + " pgautofailover_replicator\n" + " --password new password (prompted if omitted)\n", + cli_set_password_getopts, + cli_set_password); + static CommandLine *set_subcommands[] = { &set_node_command, &set_formation_command, + &set_password_command, NULL }; @@ -852,3 +872,315 @@ set_formation_number_sync_standbys(Monitor *monitor, return true; } + + +/* + * Options for `pg_autoctl set password`. + */ +typedef struct SetPasswordOptions +{ + char pgdata[MAXPGPATH]; + char role[NAMEDATALEN]; + char password[MAXCONNINFO]; +} SetPasswordOptions; + +static SetPasswordOptions setPasswordOptions = { { 0 }, { 0 }, { 0 } }; + +static int +cli_set_password_getopts(int argc, char **argv) +{ + static struct option longOptions[] = { + { "pgdata", required_argument, NULL, 'D' }, + { "role", required_argument, NULL, 'r' }, + { "password", required_argument, NULL, 'p' }, + { "help", no_argument, NULL, 'h' }, + { NULL, 0, NULL, 0 } + }; + + int c, option_index = 0; + + optind = 0; + + while ((c = getopt_long(argc, argv, "D:r:p:h", + longOptions, &option_index)) != -1) + { + switch (c) + { + case 'D': + { + strlcpy(setPasswordOptions.pgdata, optarg, MAXPGPATH); + strlcpy(keeperOptions.pgSetup.pgdata, optarg, MAXPGPATH); + log_trace("--pgdata %s", setPasswordOptions.pgdata); + break; + } + + case 'r': + { + strlcpy(setPasswordOptions.role, optarg, NAMEDATALEN); + log_trace("--role %s", setPasswordOptions.role); + break; + } + + case 'p': + { + strlcpy(setPasswordOptions.password, optarg, MAXCONNINFO); + log_trace("--password ****"); + break; + } + + case 'h': + { + commandline_help(stderr); + exit(EXIT_CODE_QUIT); + } + + default: + { + log_error("Unrecognized option: %c", c); + commandline_help(stderr); + exit(EXIT_CODE_BAD_ARGS); + } + } + } + + if (IS_EMPTY_STRING_BUFFER(setPasswordOptions.role)) + { + log_error("Please provide --role { autoctl_node | " + "pgautofailover_monitor | pgautofailover_replicator }"); + exit(EXIT_CODE_BAD_ARGS); + } + + return optind; +} + + +/* + * prompt_password reads a password from the terminal without echoing it. + * Returns true on success, false on error. + */ +static bool +prompt_password(const char *prompt, char *buf, size_t buflen) +{ + struct termios old, noecho; + bool ok = false; + + if (tcgetattr(fileno(stdin), &old) != 0) + { + /* stdin is not a tty; just read normally */ + fprintf(stderr, "%s", prompt); + fflush(stderr); + + if (fgets(buf, buflen, stdin) == NULL) + { + return false; + } + + /* strip trailing newline */ + buf[strcspn(buf, "\n")] = '\0'; + return true; + } + + noecho = old; + noecho.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); + + if (tcsetattr(fileno(stdin), TCSAFLUSH, &noecho) != 0) + { + return false; + } + + fprintf(stderr, "%s", prompt); + fflush(stderr); + + if (fgets(buf, buflen, stdin) != NULL) + { + buf[strcspn(buf, "\n")] = '\0'; + ok = true; + } + + (void) tcsetattr(fileno(stdin), TCSAFLUSH, &old); + fprintf(stderr, "\n"); + + return ok; +} + + +/* + * cli_set_password implements `pg_autoctl set password`. + * + * Supported roles: + * autoctl_node — lives on the monitor; ALTER ROLE there and + * update monitor config autoctl_node_password + * pgautofailover_monitor — lives on each data node; ALTER ROLE there and + * update keeper config monitor_password + * pgautofailover_replicator — lives on each data node; ALTER ROLE there + * and update keeper config replication.password + */ +static void +cli_set_password(int argc, char **argv) +{ + const char *role = setPasswordOptions.role; + char password[MAXCONNINFO] = { 0 }; + + /* validate role name */ + bool isAutoctlNode = (strcmp(role, PG_AUTOCTL_MONITOR_USERNAME) == 0); + bool isHealthUser = (strcmp(role, PG_AUTOCTL_HEALTH_USERNAME) == 0); + bool isReplicaUser = (strcmp(role, PG_AUTOCTL_REPLICA_USERNAME) == 0); + + if (!isAutoctlNode && !isHealthUser && !isReplicaUser) + { + log_error("Unknown role \"%s\". Valid roles: %s, %s, %s", + role, + PG_AUTOCTL_MONITOR_USERNAME, + PG_AUTOCTL_HEALTH_USERNAME, + PG_AUTOCTL_REPLICA_USERNAME); + exit(EXIT_CODE_BAD_ARGS); + } + + /* obtain the password */ + if (!IS_EMPTY_STRING_BUFFER(setPasswordOptions.password)) + { + strlcpy(password, setPasswordOptions.password, sizeof(password)); + } + else + { + char prompt[256]; + sformat(prompt, sizeof(prompt), "Password for role %s: ", role); + + if (!prompt_password(prompt, password, sizeof(password))) + { + log_error("Failed to read password from terminal"); + exit(EXIT_CODE_BAD_ARGS); + } + } + + if (IS_EMPTY_STRING_BUFFER(password)) + { + log_error("Password may not be empty"); + exit(EXIT_CODE_BAD_ARGS); + } + + /* + * autoctl_node lives on the MONITOR. We connect to the monitor's local + * Postgres (via MonitorConfig) and ALTER the role there. + */ + if (isAutoctlNode) + { + MonitorConfig mconfig = { 0 }; + + /* resolve pgdata */ + if (!IS_EMPTY_STRING_BUFFER(setPasswordOptions.pgdata)) + { + strlcpy(mconfig.pgSetup.pgdata, + setPasswordOptions.pgdata, + MAXPGPATH); + } + + if (!monitor_config_set_pathnames_from_pgdata(&mconfig)) + { + log_fatal("Failed to set monitor config pathnames"); + exit(EXIT_CODE_BAD_CONFIG); + } + + if (!monitor_config_read_file(&mconfig, false, true)) + { + log_fatal("Failed to read monitor configuration file"); + exit(EXIT_CODE_BAD_CONFIG); + } + + /* connect to the monitor's local postgres */ + PGSQL pgsql = { 0 }; + char connInfo[MAXCONNINFO]; + pg_setup_get_local_connection_string(&mconfig.pgSetup, connInfo); + pgsql_init(&pgsql, connInfo, PGSQL_CONN_LOCAL); + + if (!pgsql_alter_role_password(&pgsql, role, password)) + { + log_error("Failed to ALTER ROLE \"%s\" PASSWORD on the monitor", role); + exit(EXIT_CODE_PGSQL); + } + + /* persist password into monitor ini */ + strlcpy(mconfig.autoctl_node_password, password, + sizeof(mconfig.autoctl_node_password)); + + if (!monitor_config_write_file(&mconfig)) + { + log_error("Failed to update monitor configuration file"); + exit(EXIT_CODE_BAD_CONFIG); + } + + log_info("Password for role \"%s\" updated on the monitor and " + "saved to the monitor configuration file", role); + return; + } + + /* + * pgautofailover_monitor and pgautofailover_replicator both live on the + * local data node. We need a KeeperConfig for the local Postgres + * connection details. + */ + { + KeeperConfig config = keeperOptions; + bool missingPgdataIsOk = false; + bool pgIsNotRunningIsOk = true; + bool monitorDisabledIsOk = true; + + if (!IS_EMPTY_STRING_BUFFER(setPasswordOptions.pgdata)) + { + strlcpy(config.pgSetup.pgdata, + setPasswordOptions.pgdata, + MAXPGPATH); + } + + if (!keeper_config_set_pathnames_from_pgdata(&config.pathnames, + config.pgSetup.pgdata)) + { + log_fatal("Failed to set keeper config pathnames"); + exit(EXIT_CODE_BAD_CONFIG); + } + + if (!keeper_config_read_file(&config, + missingPgdataIsOk, + pgIsNotRunningIsOk, + monitorDisabledIsOk)) + { + log_fatal("Failed to read keeper configuration file"); + exit(EXIT_CODE_BAD_CONFIG); + } + + /* connect to the local data node's Postgres */ + PGSQL pgsql = { 0 }; + char connInfo[MAXCONNINFO]; + pg_setup_get_local_connection_string(&config.pgSetup, connInfo); + pgsql_init(&pgsql, connInfo, PGSQL_CONN_LOCAL); + + if (!pgsql_alter_role_password(&pgsql, role, password)) + { + log_error("Failed to ALTER ROLE \"%s\" PASSWORD on the local node", + role); + exit(EXIT_CODE_PGSQL); + } + + /* persist password into keeper ini */ + if (isHealthUser) + { + strlcpy(config.monitor_password, password, + sizeof(config.monitor_password)); + } + else + { + /* isReplicaUser */ + strlcpy(config.replication_password, password, + sizeof(config.replication_password)); + } + + if (!keeper_config_write_file(&config)) + { + log_error("Failed to update keeper configuration file"); + exit(EXIT_CODE_BAD_CONFIG); + } + + log_info("Password for role \"%s\" updated on the local node and " + "saved to the keeper configuration file", role); + } +} diff --git a/src/bin/pg_autoctl/cli_inspect.c b/src/bin/pg_autoctl/cli_inspect.c index 78ac18ba8..f5d063ce9 100644 --- a/src/bin/pg_autoctl/cli_inspect.c +++ b/src/bin/pg_autoctl/cli_inspect.c @@ -23,6 +23,7 @@ */ static CommandLine *inspect_fsm_subcommands[] = { &fsm_state, + &fsm_node_state, &fsm_list, &fsm_gv, NULL @@ -41,6 +42,8 @@ static CommandLine inspect_fsm_commands = static CommandLine *inspect_monitor_subcommands[] = { &monitor_get_command, &monitor_parse_notification_command, + &monitor_node_state_command, + &monitor_formation_states_command, NULL }; diff --git a/src/bin/pg_autoctl/cli_node.c b/src/bin/pg_autoctl/cli_node.c index 7ee817be8..a896353a1 100644 --- a/src/bin/pg_autoctl/cli_node.c +++ b/src/bin/pg_autoctl/cli_node.c @@ -11,6 +11,7 @@ * Licensed under the PostgreSQL License. */ +#include #include #include #include @@ -35,6 +36,8 @@ static int cli_node_run_getopts(int argc, char **argv); static void cli_node_run(int argc, char **argv); static int cli_node_apply_getopts(int argc, char **argv); static void cli_node_apply(int argc, char **argv); +static int cli_node_start_getopts(int argc, char **argv); +static void cli_node_start(int argc, char **argv); static int cli_node_show_getopts(int argc, char **argv); static void cli_node_show(int argc, char **argv); static int cli_node_check_getopts(int argc, char **argv); @@ -60,6 +63,16 @@ static CommandLine node_apply_command = cli_node_apply_getopts, cli_node_apply); +static CommandLine node_start_command = + make_command( + "start", + "Start a node waiting in launch=deferred mode (idempotent)", + "[]", + " path to the pg_autoctl_node.ini file\n" + " (default: " PG_AUTOCTL_NODESPEC_PATH ")\n", + cli_node_start_getopts, + cli_node_start); + static CommandLine node_show_command = make_command( "show", @@ -81,6 +94,7 @@ static CommandLine node_check_command = static CommandLine *node_subcommands[] = { &node_run_command, &node_apply_command, + &node_start_command, &node_show_command, &node_check_command, NULL @@ -107,8 +121,10 @@ static char nodeSpecPath[MAXPGPATH] = { 0 }; static int cli_node_run_getopts(int argc, char **argv) { - if (argc > 0 && argv[0][0] != '-') - strlcpy(nodeSpecPath, argv[0], sizeof(nodeSpecPath)); + /* argv[0] is the subcommand name ("run"/"apply"/"check"); the optional + * file path is the first remaining positional argument at argv[1]. */ + if (argc > 1 && argv[1][0] != '-') + strlcpy(nodeSpecPath, argv[1], sizeof(nodeSpecPath)); else strlcpy(nodeSpecPath, PG_AUTOCTL_NODESPEC_PATH, sizeof(nodeSpecPath)); @@ -128,12 +144,38 @@ static void cli_node_run(int argc, char **argv) { NodeSpec spec = { 0 }; - char *args[32]; + char *args[40]; int nargs; if (!nodespec_read(nodeSpecPath, &spec)) exit(EXIT_CODE_BAD_CONFIG); + /* + * [launch] mode = deferred: spin here re-reading nodeSpecPath until + * pg_autoctl node start rewrites it with mode = immediate (or removes + * the [launch] section). The file is the rendezvous point — no external + * sentinel needed. + */ + if (spec.launchDeferred) + { + log_info("Node configured with launch = deferred in \"%s\"; " + "waiting for pg_autoctl node start", nodeSpecPath); + + for (;;) + { + pg_usleep(500 * 1000); /* 0.5 s poll */ + + NodeSpec polled = { 0 }; + if (nodespec_read(nodeSpecPath, &polled) && !polled.launchDeferred) + { + spec = polled; + break; + } + } + + log_info("launch = immediate; proceeding with node initialization"); + } + /* * If PGDATA already has a pg_autoctl.cfg, the node was created before. * In that case run `pg_autoctl run` (no --run, no create flags). @@ -180,13 +222,54 @@ cli_node_run(int argc, char **argv) /* Tell the supervisor which spec file to watch for live changes */ setenv("PG_AUTOCTL_NODESPEC", nodeSpecPath, 1); - /* Log the command we're about to exec */ + /* + * PG_AUTOCTL_TEST_DELAY: stagger node registration so that node IDs + * are assigned in name order (node1 → id 1, node2 → id 2, …). + * Extract the trailing integer from the node name and sleep 2×N seconds. + */ + if (getenv("PG_AUTOCTL_TEST_DELAY") && spec.name[0] != '\0') + { + const char *p = spec.name + strlen(spec.name); + while (p > spec.name && isdigit((unsigned char) p[-1])) + p--; + if (*p != '\0') + { + int n = atoi(p); + int secs = 2 * n; + log_info("PG_AUTOCTL_TEST_DELAY: sleeping %ds before " + "registration (node %s, index %d)", + secs, spec.name, n); + sleep(secs); + } + } + + /* Log the command we're about to exec, masking password arguments. */ { PQExpBuffer cmd = createPQExpBuffer(); + static const char *pwFlags[] = { + "--monitor-password", + "--replication-password", + "--autoctl-node-password", + NULL + }; for (int i = 0; i < nargs; i++) { if (i > 0) appendPQExpBufferChar(cmd, ' '); - appendPQExpBufferStr(cmd, args[i]); + + /* Check if the previous arg was a password flag. */ + bool maskThis = false; + if (i > 0) + { + for (int k = 0; pwFlags[k]; k++) + { + if (strcmp(args[i-1], pwFlags[k]) == 0) + { + maskThis = true; + break; + } + } + } + appendPQExpBufferStr(cmd, maskThis ? "****" : args[i]); } log_info("pg_autoctl node run: %s", cmd->data); destroyPQExpBuffer(cmd); @@ -237,6 +320,52 @@ cli_node_apply(int argc, char **argv) } +/* ----------------------------------------------------------------------- + * pg_autoctl node start [] + * + * Clears launch = deferred in the spec file so a waiting pg_autoctl node run + * proceeds. Idempotent: if the node is already immediate, exits 0 quietly. + * ----------------------------------------------------------------------- */ + +static int +cli_node_start_getopts(int argc, char **argv) +{ + if (argc > 1 && argv[1][0] != '-') + strlcpy(nodeSpecPath, argv[1], sizeof(nodeSpecPath)); + else + strlcpy(nodeSpecPath, PG_AUTOCTL_NODESPEC_PATH, sizeof(nodeSpecPath)); + + return 0; +} + +static void +cli_node_start(int argc, char **argv) +{ + NodeSpec spec = { 0 }; + + if (!nodespec_read(nodeSpecPath, &spec)) + exit(EXIT_CODE_BAD_CONFIG); + + if (!spec.launchDeferred) + { + log_info("Node \"%s\" launch is already immediate; nothing to do", + nodeSpecPath); + exit(0); + } + + spec.launchDeferred = false; + + if (!nodespec_write_to_path(&spec, nodeSpecPath)) + { + log_error("Failed to update \"%s\"", nodeSpecPath); + exit(EXIT_CODE_INTERNAL_ERROR); + } + + log_info("Cleared launch = deferred in \"%s\"; node will now start", + nodeSpecPath); +} + + /* ----------------------------------------------------------------------- * pg_autoctl node show [--pgdata ] * ----------------------------------------------------------------------- */ diff --git a/src/bin/pg_autoctl/fsm_transition.c b/src/bin/pg_autoctl/fsm_transition.c index bc768cb04..5d0db6e01 100644 --- a/src/bin/pg_autoctl/fsm_transition.c +++ b/src/bin/pg_autoctl/fsm_transition.c @@ -282,11 +282,33 @@ fsm_init_primary(Keeper *keeper) * leaking information from the passfile, environment variable, or * other places. */ + /* + * When monitor_password is configured, use it and honour the cluster + * auth method; otherwise fall back to the hard-coded password with + * "trust" so that existing deployments are unaffected. + */ + char healthPassword[MAXCONNINFO]; + char healthAuthMethod[MAXPGPATH]; + + if (config->monitor_password[0] != '\0') + { + strlcpy(healthPassword, config->monitor_password, + sizeof(healthPassword)); + strlcpy(healthAuthMethod, pg_setup_get_auth_method(pgSetup), + sizeof(healthAuthMethod)); + } + else + { + strlcpy(healthPassword, PG_AUTOCTL_HEALTH_PASSWORD, + sizeof(healthPassword)); + strlcpy(healthAuthMethod, "trust", sizeof(healthAuthMethod)); + } + if (!primary_create_user_with_hba(postgres, PG_AUTOCTL_HEALTH_USERNAME, - PG_AUTOCTL_HEALTH_PASSWORD, + healthPassword, monitorHostname, - "trust", + healthAuthMethod, pgSetup->hbaLevel, connlimit)) { @@ -902,6 +924,21 @@ fsm_init_standby_from_upstream(Keeper *keeper) return false; } + /* + * After a pg_basebackup the standby inherits the primary's postgresql.conf + * and postgresql-auto-failover.conf. Rewrite postgresql-auto-failover.conf + * via postgres_add_default_settings() so that citus.cluster_name and + * citus.use_secondary_nodes reflect this node's own configuration rather + * than the primary's. prepare_guc_settings_from_pgsetup() derives those + * settings dynamically from pgSetup->citusClusterName, so the full default + * table (including max_wal_senders = 12) is preserved. + */ + if (!postgres_add_default_settings(postgres, config->hostname)) + { + log_error("Failed to rewrite postgresql-auto-failover.conf for standby"); + return false; + } + /* now, in case we have an init state file around, remove it */ return unlink_file(config->pathnames.init); } @@ -1331,6 +1368,20 @@ fsm_fast_forward(Keeper *keeper) return false; } + /* + * When the most advanced standby IS this node itself, there is no WAL + * to fetch: we are already at the frontier. Skip straight to + * prepare_promotion without setting up a (self-referential) replication + * source that would inevitably fail to connect. + */ + if (upstreamNode.nodeId == keeper->state.current_node_id) + { + log_info("This node is already the most advanced standby " + "(LSN %s); no WAL to fetch, skipping fast-forward", + upstreamNode.lsn); + return true; + } + /* * Postgres 10 does not have pg_replication_slot_advance(), so we don't * support replication slots on standby nodes there. diff --git a/src/bin/pg_autoctl/keeper.c b/src/bin/pg_autoctl/keeper.c index 6315cd00b..eaa07c6f1 100644 --- a/src/bin/pg_autoctl/keeper.c +++ b/src/bin/pg_autoctl/keeper.c @@ -1630,6 +1630,7 @@ keeper_register_and_init(Keeper *keeper, NodeState initialState) while (!pgsql_retry_policy_expired(&retryPolicy)) { bool mayRetry = false; + bool formationMissing = false; /* * When registering to the monitor, we get assigned a nodeId, that we @@ -1670,6 +1671,7 @@ keeper_register_and_init(Keeper *keeper, NodeState initialState) config->pgSetup.settings.replicationQuorum, config->pgSetup.citusClusterName, &mayRetry, + &formationMissing, &assignedState)) { /* registration was successful, break out of the retry loop */ @@ -1682,22 +1684,8 @@ keeper_register_and_init(Keeper *keeper, NodeState initialState) goto rollback; } - int sleepTimeMs = pgsql_compute_connection_retry_sleep_time(&retryPolicy); - - log_warn("Failed to register node %s:%d in group %d of " - "formation \"%s\" with initial state \"%s\" " - "because the monitor is already registering another " - "standby, retrying in %d ms", - config->hostname, - config->pgSetup.pgport, - config->groupId, - config->formation, - NodeStateToString(initialState), - sleepTimeMs); - /* - * The current transaction is dead: we caugth an ERROR from the - * call to pgautofailover.register_node(). + * The current transaction is dead: roll it back before sleeping. */ if (!pgsql_rollback(&(monitor->pgsql))) { @@ -1707,6 +1695,35 @@ keeper_register_and_init(Keeper *keeper, NodeState initialState) return false; } + int sleepTimeMs = pgsql_compute_connection_retry_sleep_time(&retryPolicy); + + if (formationMissing) + { + /* + * The formation doesn't exist on the monitor yet. This is + * normal in test environments where "pg_autoctl node run" on the + * monitor creates it shortly after the data nodes start. Wait + * and retry; don't auto-create — a missing formation in + * production likely indicates a configuration error. + */ + log_info("Formation \"%s\" does not exist on the monitor yet, " + "retrying in %d ms", + config->formation, sleepTimeMs); + } + else + { + log_warn("Failed to register node %s:%d in group %d of " + "formation \"%s\" with initial state \"%s\" " + "because the monitor is already registering another " + "standby, retrying in %d ms", + config->hostname, + config->pgSetup.pgport, + config->groupId, + config->formation, + NodeStateToString(initialState), + sleepTimeMs); + } + /* we have milliseconds, pg_usleep() wants microseconds */ (void) pg_usleep(sleepTimeMs * 1000); } @@ -1859,6 +1876,7 @@ keeper_register_again(Keeper *keeper) while (!pgsql_retry_policy_expired(&retryPolicy)) { bool mayRetry = false; + bool formationMissing = false; /* re-registration: formation always exists */ if (monitor_register_node(monitor, config->formation, @@ -1875,6 +1893,7 @@ keeper_register_again(Keeper *keeper) config->pgSetup.settings.replicationQuorum, DEFAULT_CITUS_CLUSTER_NAME, &mayRetry, + &formationMissing, &assignedState)) { /* registration was successful, break out of the retry loop */ @@ -2077,12 +2096,19 @@ keeper_update_group_hba(Keeper *keeper, NodeAddressArray *diffNodesArray) sformat(hbaFilePath, MAXPGPATH, "%s/pg_hba.conf", postgresSetup->pgdata); + /* + * cert auth for replication uses "cert map=pgautofailover" so that the + * autoctl_node client certificate CN maps to pgautofailover_replicator. + */ + bool isCertAuth = (strcmp(authMethod, "cert") == 0); + const char *replAuth = isCertAuth ? "cert map=pgautofailover" : authMethod; + if (!pghba_ensure_host_rules_exist(hbaFilePath, diffNodesArray, - postgresSetup->ssl.active, + postgresSetup->ssl.active || isCertAuth, postgresSetup->dbname, PG_AUTOCTL_REPLICA_USERNAME, - authMethod, + replAuth, keeper->config.pgSetup.hbaLevel)) { log_error("Failed to edit HBA file \"%s\" to update rules to current " @@ -2091,6 +2117,19 @@ keeper_update_group_hba(Keeper *keeper, NodeAddressArray *diffNodesArray) return false; } + if (isCertAuth && + keeper->config.pgSetup.hbaLevel >= HBA_EDIT_MINIMAL) + { + if (!pghba_ensure_ident_map_entry(postgresSetup->pgdata, + "pgautofailover", + PG_AUTOCTL_MONITOR_USERNAME, + PG_AUTOCTL_REPLICA_USERNAME)) + { + log_error("Failed to add cert ident map entry to pg_ident.conf"); + return false; + } + } + /* * Only reload if Postgres is known to be running. If it's not running, we * edited the HBA and it's going to take effect at next restart of diff --git a/src/bin/pg_autoctl/keeper_config.c b/src/bin/pg_autoctl/keeper_config.c index 1459336df..553819ee3 100644 --- a/src/bin/pg_autoctl/keeper_config.c +++ b/src/bin/pg_autoctl/keeper_config.c @@ -133,6 +133,11 @@ config->replication_password, \ REPLICATION_PASSWORD_DEFAULT) +#define OPTION_AUTOCTL_MONITOR_PASSWORD(config) \ + make_strbuf_option_default("pg_autoctl", "monitor_password", NULL, \ + false, MAXCONNINFO, \ + config->monitor_password, "") + #define OPTION_REPLICATION_MAXIMUM_BACKUP_RATE(config) \ make_strbuf_option_default("replication", "maximum_backup_rate", NULL, \ false, MAXIMUM_BACKUP_RATE_LEN, \ @@ -241,6 +246,7 @@ OPTION_REPLICATION_MAXIMUM_BACKUP_RATE(config), \ OPTION_REPLICATION_BACKUP_DIR(config), \ OPTION_REPLICATION_PASSWORD(config), \ + OPTION_AUTOCTL_MONITOR_PASSWORD(config), \ OPTION_TIMEOUT_NETWORK_PARTITION(config), \ OPTION_TIMEOUT_PREPARE_PROMOTION_CATCHUP(config), \ OPTION_TIMEOUT_PREPARE_PROMOTION_WALRECEIVER(config), \ diff --git a/src/bin/pg_autoctl/keeper_config.h b/src/bin/pg_autoctl/keeper_config.h index 3826923d9..73e6cbd62 100644 --- a/src/bin/pg_autoctl/keeper_config.h +++ b/src/bin/pg_autoctl/keeper_config.h @@ -53,6 +53,7 @@ typedef struct KeeperConfig /* PostgreSQL replication / tooling setup */ char replication_slot_name[MAXCONNINFO]; char replication_password[MAXCONNINFO]; + char monitor_password[MAXCONNINFO]; char maximum_backup_rate[MAXIMUM_BACKUP_RATE_LEN]; char backupDirectory[MAXPGPATH]; diff --git a/src/bin/pg_autoctl/keeper_pg_init.c b/src/bin/pg_autoctl/keeper_pg_init.c index 3ff3e555e..096a2c9f1 100644 --- a/src/bin/pg_autoctl/keeper_pg_init.c +++ b/src/bin/pg_autoctl/keeper_pg_init.c @@ -907,6 +907,23 @@ create_database_and_extension(Keeper *keeper) } } + /* + * cert auth for replication requires an ident map so the autoctl_node + * client cert CN maps to the pgautofailover_replicator Postgres role. + */ + if (strcmp(pg_setup_get_auth_method(pgSetup), "cert") == 0 && + pgSetup->hbaLevel >= HBA_EDIT_MINIMAL) + { + if (!pghba_ensure_ident_map_entry(pgSetup->pgdata, + "pgautofailover", + PG_AUTOCTL_MONITOR_USERNAME, + PG_AUTOCTL_REPLICA_USERNAME)) + { + log_error("Failed to add cert ident map entry to pg_ident.conf"); + return false; + } + } + /* * In test environments using PG_REGRESS_SOCK_DIR="" to disable unix socket * directory, we have to connect to the address from pghost. diff --git a/src/bin/pg_autoctl/monitor.c b/src/bin/pg_autoctl/monitor.c index 582eb0de6..466501924 100644 --- a/src/bin/pg_autoctl/monitor.c +++ b/src/bin/pg_autoctl/monitor.c @@ -26,6 +26,7 @@ #define STR_ERRCODE_OBJECT_IN_USE "55006" #define STR_ERRCODE_EXCLUSION_VIOLATION "23P01" +#define STR_ERRCODE_INVALID_OBJECT_DEFINITION "42P17" #define STR_ERRCODE_SERIALIZATION_FAILURE "40001" #define STR_ERRCODE_STATEMENT_COMPLETION_UNKNOWN "40003" @@ -831,6 +832,7 @@ monitor_register_node(Monitor *monitor, char *formation, PgInstanceKind kind, int candidatePriority, bool quorum, char *citusClusterName, bool *mayRetry, + bool *formationMissing, MonitorAssignedState *assignedState) { PGSQL *pgsql = &monitor->pgsql; @@ -838,6 +840,8 @@ monitor_register_node(Monitor *monitor, char *formation, "SELECT * FROM pgautofailover.register_node($1, $2, $3, $4, $5, $6, $7, " "$8, $9::pgautofailover.replication_state, $10, $11, $12, $13)"; int paramCount = 13; + + *formationMissing = false; Oid paramTypes[13] = { TEXTOID, TEXTOID, INT4OID, NAMEOID, TEXTOID, INT8OID, INT8OID, INT4OID, TEXTOID, TEXTOID, INT4OID, BOOLOID, TEXTOID @@ -880,6 +884,14 @@ monitor_register_node(Monitor *monitor, char *formation, *mayRetry = true; return false; } + else if (strcmp(parseContext.sqlstate, + STR_ERRCODE_INVALID_OBJECT_DEFINITION) == 0) + { + /* Formation doesn't exist yet — caller will create it and retry. */ + *formationMissing = true; + *mayRetry = true; + return false; + } else if (strcmp(parseContext.sqlstate, STR_ERRCODE_EXCLUSION_VIOLATION) == 0) { @@ -969,6 +981,24 @@ monitor_node_active(Monitor *monitor, paramCount, paramTypes, paramValues, &parseContext, parseNodeState)) { + /* + * ERRCODE_UNDEFINED_OBJECT (42704): the monitor raised "couldn't find + * node with nodeid N". This happens when remove_node() was called with + * --force, or after the node already reported DROPPED and the monitor + * deleted the row. The running keeper should treat this as a DROPPED + * assignment so the FSM exits cleanly rather than looping on errors. + */ + if (strcmp(parseContext.sqlstate, STR_ERRCODE_UNDEFINED_OBJECT) == 0) + { + log_info("Node %" PRId64 " is no longer registered on the monitor " + "(SQLSTATE %s); treating as dropped.", + nodeId, parseContext.sqlstate); + assignedState->nodeId = nodeId; + assignedState->groupId = groupId; + assignedState->state = DROPPED_STATE; + return true; + } + log_error("Failed to get node state for node %" PRId64 " in group %d of formation \"%s\" with initial state " "\"%s\", replication state \"%s\", " @@ -4318,20 +4348,27 @@ monitor_wait_until_some_node_reported_state(Monitor *monitor, while (!context.failoverIsDone) { - /* when timeout <= 0 we just never stop waiting */ + int thisLoopTimeout; + if (timeout > 0) { uint64_t now = time(NULL); + uint64_t elapsed = now - start; - if ((now - start) > timeout) + if (elapsed >= (uint64_t) timeout) { log_error("Failed to receive monitor's notifications"); break; } - } - int thisLoopTimeout = - timeout > 0 ? timeout : PG_AUTOCTL_LISTEN_NOTIFICATIONS_TIMEOUT; + /* cap inner wait to remaining time so we don't overshoot by a full timeout */ + thisLoopTimeout = (int) (timeout - elapsed); + } + else + { + /* timeout <= 0: wait indefinitely, using the default block time */ + thisLoopTimeout = PG_AUTOCTL_LISTEN_NOTIFICATIONS_TIMEOUT; + } if (!monitor_process_notifications( monitor, diff --git a/src/bin/pg_autoctl/monitor.h b/src/bin/pg_autoctl/monitor.h index 6c6a95477..9dcd12261 100644 --- a/src/bin/pg_autoctl/monitor.h +++ b/src/bin/pg_autoctl/monitor.h @@ -140,6 +140,7 @@ bool monitor_register_node(Monitor *monitor, bool quorum, char *citusClusterName, bool *mayRetry, + bool *formationMissing, MonitorAssignedState *assignedState); bool monitor_node_active(Monitor *monitor, char *formation, int64_t nodeId, diff --git a/src/bin/pg_autoctl/monitor_config.c b/src/bin/pg_autoctl/monitor_config.c index 77021471e..ce88349b8 100644 --- a/src/bin/pg_autoctl/monitor_config.c +++ b/src/bin/pg_autoctl/monitor_config.c @@ -36,6 +36,11 @@ make_strbuf_option("pg_autoctl", "hostname", "hostname", \ false, _POSIX_HOST_NAME_MAX, config->hostname) +#define OPTION_AUTOCTL_NODE_PASSWORD(config) \ + make_strbuf_option_default("pg_autoctl", "autoctl_node_password", NULL, \ + false, MAXCONNINFO, \ + config->autoctl_node_password, "") + #define OPTION_AUTOCTL_NODENAME(config) \ make_strbuf_compat_option("pg_autoctl", "nodename", \ _POSIX_HOST_NAME_MAX, config->hostname) @@ -104,6 +109,7 @@ OPTION_AUTOCTL_ROLE(config), \ OPTION_AUTOCTL_HOSTNAME(config), \ OPTION_AUTOCTL_NODENAME(config), \ + OPTION_AUTOCTL_NODE_PASSWORD(config), \ OPTION_POSTGRESQL_PGDATA(config), \ OPTION_POSTGRESQL_PG_CTL(config), \ OPTION_POSTGRESQL_USERNAME(config), \ diff --git a/src/bin/pg_autoctl/monitor_config.h b/src/bin/pg_autoctl/monitor_config.h index c7292d992..c7ea9684c 100644 --- a/src/bin/pg_autoctl/monitor_config.h +++ b/src/bin/pg_autoctl/monitor_config.h @@ -25,12 +25,19 @@ typedef struct MonitorConfig /* pg_autoctl setup */ char hostname[_POSIX_HOST_NAME_MAX]; + char autoctl_node_password[MAXCONNINFO]; /* PostgreSQL setup */ char role[NAMEDATALEN]; /* PostgreSQL setup */ PostgresSetup pgSetup; + + /* non-default formations to create during monitor init */ +#define MONITOR_MAX_FORMATIONS 16 + int formationCount; + char formationNames[MONITOR_MAX_FORMATIONS][NAMEDATALEN]; + char formationKinds[MONITOR_MAX_FORMATIONS][NAMEDATALEN]; /* "pgsql" = default */ } MonitorConfig; diff --git a/src/bin/pg_autoctl/monitor_pg_init.c b/src/bin/pg_autoctl/monitor_pg_init.c index 2835c7f3a..839cd5111 100644 --- a/src/bin/pg_autoctl/monitor_pg_init.c +++ b/src/bin/pg_autoctl/monitor_pg_init.c @@ -139,7 +139,8 @@ monitor_pg_init(Monitor *monitor) */ bool monitor_install(const char *hostname, - PostgresSetup pgSetupOption, bool checkSettings) + PostgresSetup pgSetupOption, bool checkSettings, + const char *autoctl_node_password) { PostgresSetup pgSetup = { 0 }; bool missingPgdataIsOk = false; @@ -216,6 +217,23 @@ monitor_install(const char *hostname, return false; } + /* + * If a password for the autoctl_node role has been configured, set it now. + * The autoctl_node role is created by the pgautofailover extension (via + * CREATE EXTENSION above), so we ALTER it here after the extension exists. + */ + if (autoctl_node_password != NULL && autoctl_node_password[0] != '\0') + { + if (!pgsql_alter_role_password(&postgres.sqlClient, + PG_AUTOCTL_MONITOR_USERNAME, + autoctl_node_password)) + { + log_error("Failed to set password for role \"%s\"", + PG_AUTOCTL_MONITOR_USERNAME); + return false; + } + } + /* * When installing the monitor on-top of an already running PostgreSQL, we * want to check that our settings have been applied already, and warn the diff --git a/src/bin/pg_autoctl/monitor_pg_init.h b/src/bin/pg_autoctl/monitor_pg_init.h index 38a552c65..aed2b521e 100644 --- a/src/bin/pg_autoctl/monitor_pg_init.h +++ b/src/bin/pg_autoctl/monitor_pg_init.h @@ -18,7 +18,8 @@ bool monitor_pg_init(Monitor *monitor); bool monitor_install(const char *hostname, PostgresSetup pgSetupOption, - bool checkSettings); + bool checkSettings, + const char *autoctl_node_password); bool monitor_add_postgres_default_settings(Monitor *monitor); #endif /* MONITOR_PG_INIT_H */ diff --git a/src/bin/pg_autoctl/nodespec.c b/src/bin/pg_autoctl/nodespec.c index 10539d01d..56ef4bd62 100644 --- a/src/bin/pg_autoctl/nodespec.c +++ b/src/bin/pg_autoctl/nodespec.c @@ -7,7 +7,6 @@ */ #include -#include #include #include #include @@ -18,6 +17,7 @@ #include "nodespec.h" #include "ini_file.h" +#include "ini.h" #include "log.h" #include "pgsetup.h" #include "string_utils.h" @@ -62,6 +62,9 @@ nodespec_read(const char *path, NodeSpec *spec) char kindStr[NAMEDATALEN] = { 0 }; char replicationQuorumStr[8] = { 0 }; char pgHbaLanStr[8] = { 0 }; + char launchModeStr[16] = { 0 }; + char noMonitorStr[8] = { 0 }; + char citusRoleStr[NAMEDATALEN] = { 0 }; int port = 5432; int group = 0; int candidatePriority = 50; @@ -75,6 +78,9 @@ nodespec_read(const char *path, NodeSpec *spec) make_strbuf_option_default("node", "kind", NULL, true, sizeof(kindStr), kindStr, "postgres"), + make_strbuf_option_default("node", "name", NULL, false, + sizeof(spec->name), spec->name, + ""), make_strbuf_option_default("node", "hostname", NULL, false, sizeof(spec->hostname), spec->hostname, ""), @@ -89,6 +95,10 @@ nodespec_read(const char *path, NodeSpec *spec) make_strbuf_option_default("monitor", "pguri", NULL, false, sizeof(spec->monitor_pguri), spec->monitor_pguri, ""), + make_strbuf_option_default("monitor", "no_monitor", NULL, false, + sizeof(noMonitorStr), noMonitorStr, "false"), + make_int_option_default("monitor", "node_id", NULL, false, + &spec->nodeId, 0), /* [formation] */ make_strbuf_option_default("formation", "name", NULL, false, @@ -114,6 +124,45 @@ nodespec_read(const char *path, NodeSpec *spec) make_strbuf_option_default("options", "pg_hba_lan", NULL, false, sizeof(pgHbaLanStr), pgHbaLanStr, "true"), + /* [ssl] — certificate paths for verify-ca / verify-full mode */ + make_strbuf_option_default("ssl", "ca_file", NULL, false, + sizeof(spec->ssl_ca_file), + spec->ssl_ca_file, ""), + make_strbuf_option_default("ssl", "cert_file", NULL, false, + sizeof(spec->ssl_cert_file), + spec->ssl_cert_file, ""), + make_strbuf_option_default("ssl", "key_file", NULL, false, + sizeof(spec->ssl_key_file), + spec->ssl_key_file, ""), + + /* [launch] — optional section; mode=deferred delays node init */ + make_strbuf_option_default("launch", "mode", NULL, false, + sizeof(launchModeStr), launchModeStr, + "immediate"), + + /* [pg_auto_failover] — monitor: password for autoctl_node role */ + make_strbuf_option_default("pg_auto_failover", "autoctl_node_password", + NULL, false, + sizeof(spec->autoctl_node_password), + spec->autoctl_node_password, ""), + + /* [replication] — postgres: password for pgautofailover_replicator */ + make_strbuf_option_default("replication", "password", NULL, false, + sizeof(spec->replication_password), + spec->replication_password, ""), + + /* [pg_auto_failover] — postgres: password for pgautofailover_monitor */ + make_strbuf_option_default("pg_auto_failover", "monitor_password", + NULL, false, + sizeof(spec->monitor_password), + spec->monitor_password, ""), + + /* [citus] — optional; present only for Citus secondary/read-replica nodes */ + make_strbuf_option_default("citus", "role", NULL, false, + sizeof(citusRoleStr), citusRoleStr, ""), + make_strbuf_option_default("citus", "cluster_name", NULL, false, + sizeof(spec->citusClusterName), + spec->citusClusterName, ""), INI_OPTION_LAST }; @@ -156,9 +205,78 @@ nodespec_read(const char *path, NodeSpec *spec) strcmp(pgHbaLanStr, "yes") == 0 || strcmp(pgHbaLanStr, "1") == 0); - /* validate: non-monitor nodes need a monitor URI */ + spec->launchDeferred = (strcmp(launchModeStr, "deferred") == 0); + spec->noMonitor = + (strcmp(noMonitorStr, "true") == 0 || + strcmp(noMonitorStr, "yes") == 0 || + strcmp(noMonitorStr, "1") == 0); + + spec->citusSecondary = (strcmp(citusRoleStr, "secondary") == 0); + + /* + * Second pass: enumerate [formation ] sections. + * The standard IniOption machinery can't handle variable-count sections, + * so we open the file again with ini_load directly. + */ + { + char *fileContents = NULL; + long fileSize = 0L; + + if (read_file(path, &fileContents, &fileSize)) + { + ini_t *raw = ini_load(fileContents, NULL); + free(fileContents); + + if (raw) + { + int nsec = ini_section_count(raw); + spec->formationCount = 0; + + for (int si = 0; si < nsec; si++) + { + const char *sname = ini_section_name(raw, si); + if (!sname) continue; + if (strncmp(sname, "formation ", 10) != 0) continue; + + const char *fname = sname + 10; /* skip "formation " */ + if (fname[0] == '\0') continue; + + if (spec->formationCount >= NODESPEC_MAX_FORMATIONS) + { + log_warn("nodespec: too many [formation ] sections " + "in \"%s\"; max %d", path, NODESPEC_MAX_FORMATIONS); + break; + } + + int fi = spec->formationCount++; + strlcpy(spec->formationNames[fi], fname, + sizeof(spec->formationNames[fi])); + + /* optional: kind = ha (default) */ + int ki = ini_find_property(raw, si, "kind", 0); + if (ki != INI_NOT_FOUND) + { + const char *kv = ini_property_value(raw, si, ki); + if (kv && kv[0]) + strlcpy(spec->formationKinds[fi], kv, + sizeof(spec->formationKinds[fi])); + else + strlcpy(spec->formationKinds[fi], "pgsql", + sizeof(spec->formationKinds[fi])); + } + else + strlcpy(spec->formationKinds[fi], "pgsql", + sizeof(spec->formationKinds[fi])); + } + ini_destroy(raw); + } + } + } + + /* validate: non-monitor nodes need a monitor URI unless no_monitor=true */ if (spec->kind != NODE_KIND_UNKNOWN && - IS_EMPTY_STRING_BUFFER(spec->monitor_pguri)) + IS_EMPTY_STRING_BUFFER(spec->monitor_pguri) && + !spec->noMonitor) { log_error("Node kind \"%s\" requires [monitor] pguri in \"%s\"", kindStr, path); @@ -188,29 +306,42 @@ nodespec_write(const NodeSpec *spec, FILE *out) fprintf(out, "[node]\n" - "kind = %s\n" + "kind = %s\n", + kindStr); + + if (!IS_EMPTY_STRING_BUFFER(spec->name)) + fprintf(out, "name = %s\n", spec->name); + + fprintf(out, "hostname = %s\n" "port = %d\n" "\n" "[postgresql]\n" "pgdata = %s\n" "\n", - kindStr, spec->hostname, spec->port, spec->pgdata); if (spec->kind != NODE_KIND_UNKNOWN) { + if (spec->noMonitor) + fprintf(out, + "[monitor]\n" + "no_monitor = true\n" + "\n"); + else + fprintf(out, + "[monitor]\n" + "pguri = %s\n" + "\n", + spec->monitor_pguri); + fprintf(out, - "[monitor]\n" - "pguri = %s\n" - "\n" "[formation]\n" "name = %s\n" "group = %d\n" "\n", - spec->monitor_pguri, spec->formation, spec->group); } @@ -230,6 +361,19 @@ nodespec_write(const NodeSpec *spec, FILE *out) spec->auth, spec->pg_hba_lan ? "true" : "false"); + /* only emit [launch] when deferred — omitting the section means immediate */ + if (spec->launchDeferred) + fprintf(out, "\n[launch]\nmode = deferred\n"); + + /* [formation ] sections — monitor kind only */ + for (int fi = 0; fi < spec->formationCount; fi++) + { + fprintf(out, "\n[formation %s]\n", spec->formationNames[fi]); + if (spec->formationKinds[fi][0] && + strcmp(spec->formationKinds[fi], "pgsql") != 0) + fprintf(out, "kind = %s\n", spec->formationKinds[fi]); + } + return true; } @@ -243,7 +387,7 @@ nodespec_write(const NodeSpec *spec, FILE *out) * [--auth ] [--pg-hba-lan] --run * * Returns the number of entries written (terminating NULL not counted). - * args[] must have room for at least 32 pointers. + * args[] must have room for at least 40 pointers. * * String values are pointers into *spec — the caller must keep spec alive. */ @@ -287,6 +431,12 @@ nodespec_create_argv(const NodeSpec *spec, PUSH("--pgdata"); PUSH(spec->pgdata); + if (!IS_EMPTY_STRING_BUFFER(spec->name)) + { + PUSH("--name"); + PUSH(spec->name); + } + if (!IS_EMPTY_STRING_BUFFER(spec->hostname)) { PUSH("--hostname"); @@ -304,8 +454,22 @@ nodespec_create_argv(const NodeSpec *spec, if (spec->kind != NODE_KIND_UNKNOWN) { - PUSH("--monitor"); - PUSH(spec->monitor_pguri); + if (spec->noMonitor) + { + PUSH("--disable-monitor"); + if (spec->nodeId > 0) + { + static char nodeIdBuf[16]; + sformat(nodeIdBuf, sizeof(nodeIdBuf), "%d", spec->nodeId); + PUSH("--node-id"); + PUSH(nodeIdBuf); + } + } + else + { + PUSH("--monitor"); + PUSH(spec->monitor_pguri); + } if (!IS_EMPTY_STRING_BUFFER(spec->formation) && strcmp(spec->formation, "default") != 0) @@ -328,7 +492,14 @@ nodespec_create_argv(const NodeSpec *spec, PUSH("--ssl-self-signed"); else if (strcmp(spec->ssl, "off") == 0) PUSH("--no-ssl"); - /* "cert" mode: SSL flags come from postgresql.conf, nothing to add */ + else if (!IS_EMPTY_STRING_BUFFER(spec->ssl_ca_file)) + { + /* verify-ca / verify-full: pass the cert paths explicitly */ + PUSH("--ssl-ca-file"); PUSH(spec->ssl_ca_file); + PUSH("--server-cert"); PUSH(spec->ssl_cert_file); + PUSH("--server-key"); PUSH(spec->ssl_key_file); + PUSH("--ssl-mode"); PUSH(spec->ssl); + } /* auth */ if (!IS_EMPTY_STRING_BUFFER(spec->auth)) @@ -340,6 +511,61 @@ nodespec_create_argv(const NodeSpec *spec, if (spec->pg_hba_lan && spec->kind != NODE_KIND_UNKNOWN) PUSH("--pg-hba-lan"); + /* passwords */ + if (spec->kind == NODE_KIND_UNKNOWN && + !IS_EMPTY_STRING_BUFFER(spec->autoctl_node_password)) + { + PUSH("--autoctl-node-password"); + PUSH(spec->autoctl_node_password); + } + + /* non-default formations to create during monitor init */ + if (spec->kind == NODE_KIND_UNKNOWN) + { + for (int fi = 0; fi < spec->formationCount; fi++) + { + PUSH("--formation"); + PUSH(spec->formationNames[fi]); + } + } + + if (spec->kind != NODE_KIND_UNKNOWN) + { + if (!IS_EMPTY_STRING_BUFFER(spec->monitor_password)) + { + PUSH("--monitor-password"); + PUSH(spec->monitor_password); + } + if (!IS_EMPTY_STRING_BUFFER(spec->replication_password)) + { + PUSH("--replication-password"); + PUSH(spec->replication_password); + } + + /* candidate priority and replication quorum (non-default values) */ + if (spec->candidate_priority != 50) + { + static char pribuf[16]; + sformat(pribuf, sizeof(pribuf), "%d", spec->candidate_priority); + PUSH("--candidate-priority"); + PUSH(pribuf); + } + if (!spec->replication_quorum) + { + PUSH("--replication-quorum"); + PUSH("false"); + } + + /* Citus secondary/read-replica cluster settings */ + if (spec->citusSecondary) + PUSH("--citus-secondary"); + if (!IS_EMPTY_STRING_BUFFER(spec->citusClusterName)) + { + PUSH("--citus-cluster"); + PUSH(spec->citusClusterName); + } + } + PUSH("--run"); args[i] = NULL; @@ -349,6 +575,27 @@ nodespec_create_argv(const NodeSpec *spec, } + +/* + * nodespec_write_to_path writes the spec to the given filesystem path, + * replacing the file in-place. Used by pg_autoctl node start to clear the + * [launch] deferred flag so the waiting pg_autoctl node run can proceed. + */ +bool +nodespec_write_to_path(const NodeSpec *spec, const char *path) +{ + FILE *f = fopen(path, "w"); + if (!f) + { + log_error("Cannot open \"%s\" for writing: %m", path); + return false; + } + bool ok = nodespec_write(spec, f); + fclose(f); + return ok; +} + + /* * nodespec_apply compares new_spec against old_spec and applies any changes * to the mutable fields by calling into the keeper / monitor APIs. @@ -357,8 +604,11 @@ nodespec_create_argv(const NodeSpec *spec, * - candidate_priority → monitor_set_node_candidate_priority() * - replication_quorum → monitor_set_node_replication_quorum() * - * Immutable fields (kind, pgdata, ssl, auth, pg_hba_lan) are not checked here; - * the caller should warn when those differ. + * The [launch] mode field is handled separately by pg_autoctl node start. + * Applying a spec with mode=deferred to an already-started node is a + * non-fatal warning (ignored). + * + * Immutable fields (kind, pgdata, ssl, auth, pg_hba_lan) are not checked here. */ bool nodespec_apply(const NodeSpec *new_spec, const NodeSpec *old_spec) @@ -415,6 +665,13 @@ nodespec_apply(const NodeSpec *new_spec, const NodeSpec *old_spec) free_program(&prog); } + /* immediate → deferred on an already-started node: non-fatal, ignored */ + if (!old_spec->launchDeferred && new_spec->launchDeferred) + { + log_warn("nodespec_apply: ignoring attempt to set launch=deferred " + "on a node that is already running"); + } + if (!changed) log_debug("nodespec_apply: no mutable fields changed"); diff --git a/src/bin/pg_autoctl/nodespec.h b/src/bin/pg_autoctl/nodespec.h index f712ae60c..1e8882125 100644 --- a/src/bin/pg_autoctl/nodespec.h +++ b/src/bin/pg_autoctl/nodespec.h @@ -52,6 +52,7 @@ typedef struct NodeSpec { /* [node] */ PgInstanceKind kind; /* postgres | coordinator | worker | monitor */ + char name[_POSIX_HOST_NAME_MAX]; /* --name; defaults to hostname when empty */ char hostname[_POSIX_HOST_NAME_MAX]; int port; /* Postgres port, default 5432 */ @@ -60,6 +61,8 @@ typedef struct NodeSpec /* [monitor] — empty for kind == monitor */ char monitor_pguri[MAXCONNINFO]; + bool noMonitor; /* [monitor] no_monitor=true: standalone mode */ + int nodeId; /* [monitor] node_id: required with --disable-monitor */ /* [formation] */ char formation[NAMEDATALEN]; /* default "default" */ @@ -70,9 +73,34 @@ typedef struct NodeSpec bool replication_quorum; /* sync quorum participant, default true */ /* [options] — immutable; used only at pg_autoctl create time */ - char ssl[32]; /* self-signed | cert | off */ - char auth[32]; /* trust | md5 | scram */ + char ssl[32]; /* self-signed | verify-ca | verify-full | off */ + char auth[32]; /* trust | md5 | scram | cert */ bool pg_hba_lan; /* add --pg-hba-lan flag */ + + /* [ssl] — certificate paths for verify-ca / verify-full mode */ + char ssl_ca_file[MAXPGPATH]; + char ssl_cert_file[MAXPGPATH]; + char ssl_key_file[MAXPGPATH]; + bool launchDeferred; /* [launch] mode=deferred: wait for node start */ + + /* [formation ] — monitor kind: non-default formations to create */ +#define NODESPEC_MAX_FORMATIONS 16 + int formationCount; + char formationNames[NODESPEC_MAX_FORMATIONS][NAMEDATALEN]; + char formationKinds[NODESPEC_MAX_FORMATIONS][NAMEDATALEN]; /* "pgsql" default */ + + /* [pg_auto_failover] — monitor kind: password for autoctl_node role */ + char autoctl_node_password[MAXCONNINFO]; + + /* [replication] — postgres kind: password for pgautofailover_replicator */ + char replication_password[MAXCONNINFO]; + + /* [pg_auto_failover] — postgres kind: password for pgautofailover_monitor */ + char monitor_password[MAXCONNINFO]; + + /* [citus] — Citus secondary/read-replica cluster settings */ + bool citusSecondary; /* role = secondary */ + char citusClusterName[NAMEDATALEN]; /* cluster_name = */ } NodeSpec; /* ----------------------------------------------------------------------- @@ -103,7 +131,7 @@ bool nodespec_read(const char *path, NodeSpec *spec); bool nodespec_write(const NodeSpec *spec, FILE *out); /* Build the argv[] for `pg_autoctl create [flags]`. - * Caller provides args[] with room for at least 32 char* entries. + * Caller provides args[] with room for at least 40 char* entries. * Returns the number of entries filled (not counting the trailing NULL). */ int nodespec_create_argv(const NodeSpec *spec, const char *pg_autoctl_path, @@ -113,6 +141,7 @@ int nodespec_create_argv(const NodeSpec *spec, * running node by calling into the keeper/monitor APIs directly. * Logs what changed. Returns false only on hard error. */ bool nodespec_apply(const NodeSpec *new_spec, const NodeSpec *old_spec); +bool nodespec_write_to_path(const NodeSpec *spec, const char *path); /* ----------------------------------------------------------------------- * Watcher — called from supervisor loop diff --git a/src/bin/pg_autoctl/pghba.c b/src/bin/pg_autoctl/pghba.c index affe95cdd..99e9b5737 100644 --- a/src/bin/pg_autoctl/pghba.c +++ b/src/bin/pg_autoctl/pghba.c @@ -700,6 +700,68 @@ pghba_enable_lan_cidr(PGSQL *pgsql, } +/* + * pghba_ensure_ident_map_entry ensures that pg_ident.conf contains the given + * ident map entry, appending it if missing. Used with cert auth so that the + * autoctl_node client certificate CN maps to the pgautofailover_replicator + * PostgreSQL role for replication connections. + */ +bool +pghba_ensure_ident_map_entry(const char *pgdata, + const char *mapName, + const char *systemUser, + const char *pgUser) +{ + char identFilePath[MAXPGPATH]; + char *contents = NULL; + long size = 0L; + + sformat(identFilePath, MAXPGPATH, "%s/pg_ident.conf", pgdata); + + if (!read_file(identFilePath, &contents, &size)) + { + log_error("Failed to read \"%s\"", identFilePath); + return false; + } + + /* check whether this exact entry already exists */ + PQExpBuffer needle = createPQExpBuffer(); + if (!needle) + { + free(contents); + log_error("Failed to allocate memory"); + return false; + } + appendPQExpBuffer(needle, "%s %s %s", mapName, systemUser, pgUser); + + if (strstr(contents, needle->data) != NULL) + { + /* already present */ + destroyPQExpBuffer(needle); + free(contents); + return true; + } + destroyPQExpBuffer(needle); + + /* append the new entry */ + FILE *f = fopen(identFilePath, "a"); + if (!f) + { + log_error("Failed to open \"%s\" for appending: %m", identFilePath); + free(contents); + return false; + } + fprintf(f, "%s %s %s%s\n", + mapName, systemUser, pgUser, HBA_LINE_COMMENT); + fclose(f); + free(contents); + + log_info("Added ident map entry \"%s %s %s\" to \"%s\"", + mapName, systemUser, pgUser, identFilePath); + return true; +} + + /* * hba_check_hostname returns true when the DNS setting looks compatible with * Postgres expectations for an HBA hostname entry. diff --git a/src/bin/pg_autoctl/pghba.h b/src/bin/pg_autoctl/pghba.h index 4a8450d64..abbc3226e 100644 --- a/src/bin/pg_autoctl/pghba.h +++ b/src/bin/pg_autoctl/pghba.h @@ -49,6 +49,11 @@ bool pghba_enable_lan_cidr(PGSQL *pgsql, HBAEditLevel hbaLevel, const char *pgdata); +bool pghba_ensure_ident_map_entry(const char *pgdata, + const char *mapName, + const char *systemUser, + const char *pgUser); + bool pghba_check_hostname(const char *hostname, char *ipaddr, size_t size, bool *useHostname); diff --git a/src/bin/pg_autoctl/primary_standby.c b/src/bin/pg_autoctl/primary_standby.c index 6bc3b01a3..c1ed37419 100644 --- a/src/bin/pg_autoctl/primary_standby.c +++ b/src/bin/pg_autoctl/primary_standby.c @@ -454,6 +454,14 @@ upstream_has_replication_slot(ReplicationSource *upstream, */ pg_setup_get_local_connection_string(&upstreamSetup, connectionString); + if (!IS_EMPTY_STRING_BUFFER(upstream->password)) + { + char connWithPw[MAXCONNINFO]; + sformat(connWithPw, sizeof(connWithPw), "%s password=%s", + connectionString, upstream->password); + strlcpy(connectionString, connWithPw, sizeof(connectionString)); + } + if (!pgsql_init(&upstreamClient, connectionString, PGSQL_CONN_UPSTREAM)) { /* errors have already been logged */ @@ -840,6 +848,10 @@ standby_init_replication_source(LocalPostgresServer *postgres, { strlcpy(upstream->targetLSN, targetLSN, PG_LSN_MAXLENGTH); } + else + { + upstream->targetLSN[0] = '\0'; + } upstream->sslOptions = sslOptions; diff --git a/src/bin/pg_autoctl/service_keeper.c b/src/bin/pg_autoctl/service_keeper.c index 3242e7218..6f36e5704 100644 --- a/src/bin/pg_autoctl/service_keeper.c +++ b/src/bin/pg_autoctl/service_keeper.c @@ -17,6 +17,7 @@ #include "cli_common.h" #include "cli_root.h" #include "defaults.h" +#include "file_utils.h" #include "fsm.h" #include "keeper.h" #include "keeper_config.h" @@ -676,7 +677,18 @@ keeper_node_active_loop(Keeper *keeper, pid_t start_pid) if (nodeHasBeenDroppedFromTheMonitor) { - /* signal that it's time to shutdown everything */ + /* + * The monitor has confirmed the drop (the node row has been removed). + * Remove local pg_autoctl files now that it is safe to do so: if we + * were interrupted before this point, the files would still exist and + * the keeper could restart and re-enter this drop sequence. PGDATA is + * intentionally left intact; use "pg_autoctl drop node --destroy" to + * remove it. + */ + (void) unlink_file(keeper->config.pathnames.init); + (void) unlink_file(keeper->config.pathnames.state); + (void) unlink_file(keeper->config.pathnames.config); + exit(EXIT_CODE_DROPPED); } diff --git a/src/bin/pg_autoctl/service_monitor_init.c b/src/bin/pg_autoctl/service_monitor_init.c index 06998b43c..45e9dc7a2 100644 --- a/src/bin/pg_autoctl/service_monitor_init.c +++ b/src/bin/pg_autoctl/service_monitor_init.c @@ -134,7 +134,8 @@ service_monitor_init_start(void *context, pid_t *pid) (void) set_ps_title(serviceName); /* finish the install if necessary */ - if (!monitor_install(config->hostname, *pgSetup, false)) + if (!monitor_install(config->hostname, *pgSetup, false, + config->autoctl_node_password)) { /* errors have already been logged */ exit(EXIT_CODE_INTERNAL_ERROR); @@ -142,6 +143,25 @@ service_monitor_init_start(void *context, pid_t *pid) log_info("Monitor has been successfully initialized."); + /* create any non-default formations requested via --formation */ + for (int fi = 0; fi < config->formationCount; fi++) + { + char *fname = config->formationNames[fi]; + char *fkind = config->formationKinds[fi][0] + ? config->formationKinds[fi] : "pgsql"; + + log_info("Creating formation \"%s\" (kind %s)", fname, fkind); + + if (!monitor_create_formation(monitor, fname, fkind, + DEFAULT_DATABASE_NAME, + /* hasSecondary */ true, + /* numberSyncStandbys */ 0)) + { + log_error("Failed to create formation \"%s\"", fname); + exit(EXIT_CODE_INTERNAL_ERROR); + } + } + if (createAndRun) { /* here we call execv() so we never get back */ diff --git a/src/bin/pgaftest/Makefile b/src/bin/pgaftest/Makefile index 65d0e4d9d..d5612e4ed 100644 --- a/src/bin/pgaftest/Makefile +++ b/src/bin/pgaftest/Makefile @@ -18,7 +18,7 @@ override CFLAGS += -I$(SRC_DIR) -I$(PGACTL_DIR) # ----------------------------------------------------------------------- # Sources that live in this directory # ----------------------------------------------------------------------- -LOCAL_SRC = main.c cli_root.c cli_demo.c \ +LOCAL_SRC = main.c cli_root.c cli_demo.c cli_indent.c \ compose_gen.c test_runner.c \ test_spec_scan.c test_spec_parse.c @@ -56,6 +56,28 @@ test_spec_scan.c: test_spec_scan.l test_spec_parse.h test_spec_parse.c test_spec_parse.h: test_spec_parse.y $(BISON) -d -o test_spec_parse.c $< +# cli_indent.c includes test_spec_parse.h (bison-generated); ensure it's +# built first so a parallel clean build doesn't race on the generated header. +cli_indent.o: test_spec_parse.h + +# Bison/flex generated files have unavoidable unused tables and helper +# functions that vary by generator version. Suppress those warnings so +# that pg_config --cflags -Werror does not break the build. +GENERATED_CFLAGS = $(CFLAGS) \ + -Wno-unused-variable \ + -Wno-unused-function \ + -Wno-unused-const-variable \ + -Wno-return-type \ + -Wno-error + +test_spec_parse.o: test_spec_parse.c + @if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi + $(CC) $(GENERATED_CFLAGS) -c -MMD -MP -MF$(DEPDIR)/test_spec_parse.Po -o $@ $< + +test_spec_scan.o: test_spec_scan.c + @if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi + $(CC) $(GENERATED_CFLAGS) -c -MMD -MP -MF$(DEPDIR)/test_spec_scan.Po -o $@ $< + # ----------------------------------------------------------------------- # Rules for shared objects (compiled from pg_autoctl/ sources) # ----------------------------------------------------------------------- @@ -75,10 +97,16 @@ $(PGAFTEST): $(OBJS) $(INCLUDES) $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ clean: - rm -f $(OBJS) $(PGAFTEST) test_spec_scan.c test_spec_parse.c test_spec_parse.h + rm -f $(OBJS) $(PGAFTEST) rm -f $(COMMON_LIB) $(COMMON_OBJ) rm -rf $(DEPDIR) +# Remove generated parser/scanner sources only when explicitly requested. +# The committed .c files allow building without bison/flex installed and +# without risking version-skew in Docker. +distclean: clean + rm -f test_spec_scan.c test_spec_parse.c test_spec_parse.h + install: $(PGAFTEST) install -d $(DESTDIR)$(BINDIR) install -m 0755 $(PGAFTEST) $(DESTDIR)$(BINDIR) diff --git a/src/bin/pgaftest/cli_indent.c b/src/bin/pgaftest/cli_indent.c new file mode 100644 index 000000000..28ab5a2ed --- /dev/null +++ b/src/bin/pgaftest/cli_indent.c @@ -0,0 +1,899 @@ +/* + * src/bin/pgaftest/cli_indent.c + * pgaftest indent — parse a .pgaf file and rewrite it with canonical + * indentation. + * + * The output format follows these conventions: + * - 4-space indentation for all block contents + * - multi-line node specs in cluster{}: each property on its own continuation + * line, indented to align under the node name + * - multi-condition wait until: each "and state is " on its own + * line, indented under the first condition + * - sequence block: one step name per line, indented + * - leading file comment block is preserved verbatim + * - comment blocks immediately before setup/teardown/step are preserved + * - inline comments inside step bodies are dropped (AST does not store them) + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#include +#include +#include + +#include "cli_indent.h" +#include "test_spec.h" +#include "test_spec_parse.h" +#include "defaults.h" +#include "log.h" +#include "string_utils.h" + +/* + * StepComment — comment block that precedes a named block in the raw file. + * name is "setup", "teardown", or the step name. + * text is malloc'd; NULL if no comment precedes that block. + */ +#define MAX_STEP_COMMENTS 256 + +typedef struct +{ + char name[128]; + char *text; +} StepComment; + +typedef struct +{ + StepComment entries[MAX_STEP_COMMENTS]; + int count; +} StepCommentMap; + +/* forward declarations */ +static void print_header(FILE *out, const char *path); +static StepCommentMap *collect_comments(const char *path); +static const char *lookup_comment(const StepCommentMap *m, const char *name); +static void free_comments(StepCommentMap *m); +static void print_cluster(FILE *out, const TestSpec *spec); +static void print_step(FILE *out, const TestStep *step, bool named); +static void print_cmd(FILE *out, const TestCmd *cmd, int indent); +static void print_cmd_wait(FILE *out, const TestCmd *cmd, int indent); +static void normalize_sql(const char *in, char *out, int outlen); +static int match_clause_keyword(const char *p); +static void emit_segment(FILE *out, const char *seg, int bodyIndent); +static void print_sql_body(FILE *out, const char *raw_sql, int bodyIndent); + +/* ----------------------------------------------------------------------- + * Entry point called from cli_root.c + * ----------------------------------------------------------------------- */ + +void +cli_indent(int argc, char **argv) +{ + if (argc < 1 || argv[0] == NULL) + { + fprintf(stderr, "Usage: pgaftest indent \n"); + exit(EXIT_CODE_BAD_ARGS); + } + + const char *path = argv[0]; + + TestSpec *spec = parse_test_spec(path); + if (!spec) + { + log_error("Failed to parse \"%s\"", path); + exit(EXIT_CODE_BAD_ARGS); + } + + StepCommentMap *cmap = collect_comments(path); + + FILE *out = stdout; + + print_header(out, path); + + print_cluster(out, spec); + + if (spec->setup) + { + const char *cmt = lookup_comment(cmap, "setup"); + if (cmt) + fprintf(out, "\n%s\nsetup {\n", cmt); + else + fprintf(out, "\nsetup {\n"); + print_step(out, spec->setup, false); + fprintf(out, "}\n"); + } + + if (spec->teardown) + { + const char *cmt = lookup_comment(cmap, "teardown"); + if (cmt) + fprintf(out, "\n%s\nteardown {\n", cmt); + else + fprintf(out, "\nteardown {\n"); + print_step(out, spec->teardown, false); + fprintf(out, "}\n"); + } + + for (TestStep *s = spec->steps; s; s = s->next) + { + const char *cmt = lookup_comment(cmap, s->name); + if (cmt) + fprintf(out, "\n%s\nstep %s {\n", cmt, s->name); + else + fprintf(out, "\nstep %s {\n", s->name); + print_step(out, s, true); + fprintf(out, "}\n"); + } + + /* + * Emit the sequence block only when it differs from definition order. + * When sequence == steps-in-order the block is redundant noise; drop it. + */ + if (spec->sequenceLength > 0) + { + /* Check whether sequence matches step definition order exactly */ + bool redundant = true; + int si = 0; + for (TestStep *s = spec->steps; s && si < spec->sequenceLength; s = s->next, si++) + { + if (strcmp(spec->sequence[si], s->name) != 0) + { redundant = false; break; } + } + /* Also redundant only if counts match */ + if (si != spec->sequenceLength || spec->sequenceLength != spec->stepCount) + redundant = false; + + if (!redundant) + { + fprintf(out, "\nsequence\n"); + for (int i = 0; i < spec->sequenceLength; i++) + fprintf(out, " %s\n", spec->sequence[i]); + } + } + + free_comments(cmap); + exit(0); +} + + +/* ----------------------------------------------------------------------- + * Header: emit the leading # comment block from the original file. + * The parser drops comments, so we re-read the raw file here. + * Falls back to "# " when the file has no leading comment. + * ----------------------------------------------------------------------- */ + +static void +print_header(FILE *out, const char *path) +{ + FILE *f = fopen(path, "r"); + if (!f) + { + fprintf(out, "# %s\n\n", path); + return; + } + + char line[1024]; + bool any = false; + + char pending_blank[1024] = ""; /* blank lines between comment blocks */ + + while (fgets(line, sizeof(line), f)) + { + /* stop at first non-comment, non-blank line */ + if (line[0] != '#' && line[0] != '\n' && line[0] != '\r') + break; + + if (line[0] == '\n' || line[0] == '\r') + { + if (any) + { + /* accumulate blank lines; flush only if more comments follow */ + strncat(pending_blank, line, + sizeof(pending_blank) - strlen(pending_blank) - 1); + } + continue; + } + + /* comment line: flush any accumulated blanks first */ + if (pending_blank[0]) + { + fputs(pending_blank, out); + pending_blank[0] = '\0'; + } + fputs(line, out); + any = true; + } + /* discard trailing blank lines — add a single blank after */ + fclose(f); + + if (!any) + fprintf(out, "# %s\n", path); + + fprintf(out, "\n"); +} + + +/* ----------------------------------------------------------------------- + * Step comment collection — scan the raw file for # blocks that + * immediately precede "step {", "setup {", or "teardown {". + * ----------------------------------------------------------------------- */ + +static StepCommentMap * +collect_comments(const char *path) +{ + StepCommentMap *m = calloc(1, sizeof(StepCommentMap)); + if (!m) return m; + + FILE *f = fopen(path, "r"); + if (!f) return m; + + char line[1024]; + char pending[8192] = ""; /* accumulated # lines not yet assigned */ + bool skip_file_header = true; + + while (fgets(line, sizeof(line), f)) + { + /* Skip the leading file-header comment block (consumed by print_header) */ + if (skip_file_header) + { + if (line[0] == '#' || line[0] == '\n' || line[0] == '\r') + continue; + skip_file_header = false; + } + + if (line[0] == '#') + { + /* Accumulate comment line */ + strncat(pending, line, sizeof(pending) - strlen(pending) - 1); + continue; + } + + if (line[0] == '\n' || line[0] == '\r') + { + /* Blank line: keep pending — comment may continue after blank */ + if (pending[0]) + strncat(pending, line, sizeof(pending) - strlen(pending) - 1); + continue; + } + + /* Check for a block keyword */ + char kw[128] = ""; + if (sscanf(line, "step %127s", kw) == 1) + { + /* strip trailing " {" from name */ + char *brace = strchr(kw, '{'); + if (brace) *brace = '\0'; + } + else if (strncmp(line, "setup", 5) == 0) + strlcpy(kw, "setup", sizeof(kw)); + else if (strncmp(line, "teardown", 8) == 0) + strlcpy(kw, "teardown", sizeof(kw)); + + if (kw[0] && pending[0] && m->count < MAX_STEP_COMMENTS) + { + /* Strip leading blank lines */ + char *start = pending; + while (*start == '\n' || *start == '\r') start++; + + /* Strip trailing blank lines; add exactly one trailing \n */ + int len = (int) strlen(start); + while (len > 0 && (start[len-1] == '\n' || start[len-1] == '\r' || + start[len-1] == ' ')) + len--; + + if (len > 0) + { + char clean[8192]; + snprintf(clean, sizeof(clean), "%.*s\n", len, start); + strlcpy(m->entries[m->count].name, kw, + sizeof(m->entries[0].name)); + m->entries[m->count].text = strdup(clean); + m->count++; + } + } + + /* Reset pending regardless */ + pending[0] = '\0'; + } + + fclose(f); + return m; +} + +static const char * +lookup_comment(const StepCommentMap *m, const char *name) +{ + if (!m) return NULL; + for (int i = 0; i < m->count; i++) + if (strcmp(m->entries[i].name, name) == 0) + return m->entries[i].text; + return NULL; +} + +static void +free_comments(StepCommentMap *m) +{ + if (!m) return; + for (int i = 0; i < m->count; i++) + free(m->entries[i].text); + free(m); +} + + +/* ----------------------------------------------------------------------- + * Cluster block + * ----------------------------------------------------------------------- */ + +/* + * Node property token: a keyword and an optional value string (NULL = flag only). + */ +typedef struct { const char *kw; char val[128]; } NodeProp; + +static void +print_node(FILE *out, const TestNode *n, int baseIndent) +{ + NodeProp props[32]; + int pc = 0; + char numbuf[32]; + + /* kind prefix — emitted inline after the name; for workers group is also inline */ + char kindbuf[64] = ""; + if (n->kind == NODE_KIND_CITUS_COORDINATOR) + strlcpy(kindbuf, "coordinator", sizeof(kindbuf)); + else if (n->kind == NODE_KIND_CITUS_WORKER) + { + if (n->group != 0) + snprintf(kindbuf, sizeof(kindbuf), "worker group %d", n->group); + else + strlcpy(kindbuf, "worker", sizeof(kindbuf)); + } + const char *kind = kindbuf; + +#define ADD(k, v) do { props[pc].kw = (k); strlcpy(props[pc].val, (v), sizeof(props[0].val)); pc++; } while (0) +#define ADDF(k) do { props[pc].kw = (k); props[pc].val[0] = '\0'; pc++; } while (0) + if (n->launchDeferred) ADDF("launch deferred"); + if (n->async) ADDF("async"); + if (n->noMonitor) ADDF("no-monitor"); + if (n->listen) ADDF("listen"); + if (n->candidatePriority != 50) + { snprintf(numbuf, sizeof(numbuf), "%d", n->candidatePriority); ADD("candidate-priority", numbuf); } + if (!n->replicationQuorum) ADD("replication-quorum", "false"); + if (n->citusSecondary) ADDF("citus-secondary"); + if (n->citusClusterName[0]) ADD("citus-cluster-name", n->citusClusterName); + if (n->pgPort != 0) + { snprintf(numbuf, sizeof(numbuf), "%d", n->pgPort); ADD("port", numbuf); } + if (n->ssl[0]) ADD("ssl", n->ssl); + if (n->auth[0]) ADD("auth", n->auth); + if (n->debianCluster[0]) ADD("debian-cluster", n->debianCluster); + /* volumes are always multi-line; handled separately below */ + +#undef ADD + + /* compute inline representation */ + char inline_props[512] = ""; + for (int i = 0; i < pc; i++) + { + strncat(inline_props, " ", sizeof(inline_props)-strlen(inline_props)-1); + strncat(inline_props, props[i].kw, sizeof(inline_props)-strlen(inline_props)-1); + if (props[i].val[0]) + { + strncat(inline_props, " ", sizeof(inline_props)-strlen(inline_props)-1); + strncat(inline_props, props[i].val, sizeof(inline_props)-strlen(inline_props)-1); + } + } + + int nameLen = strlen(n->name); + int kindLen = kind[0] ? (int)strlen(kind) + 1 : 0; + int lineLen = baseIndent + nameLen + kindLen + strlen(inline_props); + + if ((lineLen <= 72 || pc == 0) && n->volumeCount == 0) + { + /* fits on one line — flat syntax, no "node" keyword needed */ + fprintf(out, "%*s%s", baseIndent, "", n->name); + if (kind[0]) fprintf(out, " %s", kind); + fprintf(out, "%s\n", inline_props); + return; + } + + /* multi-line — use block syntax: node { \n kind\n opt\n opt\n } */ + int innerIndent = baseIndent + 4; + fprintf(out, "%*snode %s {\n", baseIndent, "", n->name); + if (kind[0]) fprintf(out, "%*s%s\n", innerIndent, "", kind); + + for (int i = 0; i < pc; i++) + { + fprintf(out, "%*s%s", innerIndent, "", props[i].kw); + if (props[i].val[0]) + fprintf(out, " %s", props[i].val); + fprintf(out, "\n"); + } + for (int vi = 0; vi < n->volumeCount; vi++) + fprintf(out, "%*svolume %s \"%s\"\n", + innerIndent, "", + n->volumes[vi].name, n->volumes[vi].path); + fprintf(out, "%*s}\n", baseIndent, ""); +} + + +static void +print_cluster(FILE *out, const TestSpec *spec) +{ + const TestCluster *cl = &spec->cluster; + + fprintf(out, "cluster {\n"); + + if (cl->withMonitor) + fprintf(out, " monitor\n"); + + if (cl->secondMonitorName[0]) + fprintf(out, " monitor %s initially stopped\n", cl->secondMonitorName); + + if (cl->image[0]) + fprintf(out, " image \"%s\"\n", cl->image); + if (cl->ssl[0] && strcmp(cl->ssl, "self-signed") != 0) + fprintf(out, " ssl %s\n", cl->ssl); + if (cl->auth[0] && strcmp(cl->auth, "trust") != 0) + fprintf(out, " auth %s\n", cl->auth); + if (cl->extensionVersion[0]) + fprintf(out, " extension-version %s\n", cl->extensionVersion); + + for (int fi = 0; fi < cl->formationCount; fi++) + { + const TestFormation *f = &cl->formations[fi]; + + if (strcmp(f->name, "default") == 0) + fprintf(out, " formation {\n"); + else + fprintf(out, " formation %s {\n", f->name); + + for (int ni = 0; ni < f->nodeCount; ni++) + print_node(out, &f->nodes[ni], 8); + + fprintf(out, " }\n"); + } + + fprintf(out, "}\n"); +} + + +/* ----------------------------------------------------------------------- + * Step / command printing + * ----------------------------------------------------------------------- */ + +/* + * normalize_sql — collapse all whitespace runs (including embedded newlines + * from a multi-line block in the source file) to single spaces and trim + * leading/trailing whitespace. This makes `pgaftest indent` idempotent: a + * file that has already been indented produces the same output when indented + * again. + */ +static void +normalize_sql(const char *in, char *out, int outlen) +{ + const char *p = in; + char *q = out; + char *lim = out + outlen - 1; + bool ws = true; /* suppress leading whitespace */ + + while (*p && q < lim) + { + bool isws = (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r'); + if (isws) + { + if (!ws) { *q++ = ' '; } + ws = true; + } + else + { + *q++ = *p; + ws = false; + } + p++; + } + /* trim trailing space */ + if (q > out && q[-1] == ' ') q--; + *q = '\0'; +} + + +/* + * SQL_CLAUSE_KEYWORDS — clause-level keywords that force a new output line. + * Two-word keywords (ORDER BY, GROUP BY) must appear before any single-word + * prefix (BY, ORDER, GROUP) to prevent partial matches. + */ +static const char * const SQL_CLAUSE_KEYWORDS[] = { + "ORDER BY", + "GROUP BY", + "FROM", + "WHERE", + "HAVING", + "LIMIT", + "OFFSET", + NULL +}; + +/* + * match_clause_keyword — if a SQL clause keyword starts at p (case- + * insensitive, followed by space, semicolon, or end-of-string), return its + * length; otherwise return 0. + */ +static int +match_clause_keyword(const char *p) +{ + for (int i = 0; SQL_CLAUSE_KEYWORDS[i]; i++) + { + const char *kw = SQL_CLAUSE_KEYWORDS[i]; + int len = (int) strlen(kw); + if (strncasecmp(p, kw, len) == 0) + { + char next = p[len]; + if (next == ' ' || next == '\0' || next == ';') + return len; + } + } + return 0; +} + + +/* + * emit_segment — word-wrap a single normalized segment (no embedded newlines, + * no leading/trailing spaces) onto one or more lines, each prefixed with + * bodyIndent spaces and at most 79 characters wide total. + */ +static void +emit_segment(FILE *out, const char *seg, int bodyIndent) +{ + int avail = 79 - bodyIndent; + if (avail < 20) avail = 20; + + const char *p = seg; + + while (*p) + { + if ((int) strlen(p) <= avail) + { + fprintf(out, "%*s%s\n", bodyIndent, "", p); + break; + } + + /* Find the last space within avail columns. */ + const char *last_spc = NULL; + for (int i = 0; i < avail && p[i]; i++) + if (p[i] == ' ') last_spc = p + i; + + if (last_spc) + { + fprintf(out, "%*s%.*s\n", + bodyIndent, "", (int)(last_spc - p), p); + p = last_spc + 1; /* skip the space */ + } + else + { + /* No space — hard break (avoids infinite loop on long tokens). */ + fprintf(out, "%*s%.*s\n", bodyIndent, "", avail, p); + p += avail; + } + } +} + + +/* + * print_sql_body — emit normalized SQL with clause-keyword-aware line + * splitting inside a sql { … } block. + * + * Algorithm: + * 1. Normalize whitespace (fixes idempotency when the input was already + * a multi-line block from a previous indent pass). + * 2. If the whole thing fits in avail columns, emit it on one line. + * 3. Otherwise, scan for clause keywords (FROM, WHERE, ORDER BY, …). + * Each keyword starts a new output line; within each segment, apply + * word-wrap at 79 columns. + */ +static void +print_sql_body(FILE *out, const char *raw_sql, int bodyIndent) +{ + char norm[8192]; + normalize_sql(raw_sql, norm, sizeof(norm)); + + int avail = 79 - bodyIndent; + if (avail < 20) avail = 20; + + /* Short enough to fit on one line? */ + if ((int) strlen(norm) <= avail) + { + fprintf(out, "%*s%s\n", bodyIndent, "", norm); + return; + } + + /* + * Scan for clause-keyword split points. A keyword is a split point when + * it is preceded by a space (word boundary in the normalized string). + * We accumulate characters into a segment and flush when we hit a keyword. + */ + const char *p = norm; + const char *seg_start = norm; + + while (*p) + { + if (p > norm && p[-1] == ' ') + { + int kwlen = match_clause_keyword(p); + if (kwlen) + { + /* Flush the segment up to (but not including) the space + * that preceded this keyword. */ + int seglen = (int)((p - 1) - seg_start); + if (seglen > 0) + { + char seg[8192]; + memcpy(seg, seg_start, (size_t) seglen); + seg[seglen] = '\0'; + emit_segment(out, seg, bodyIndent); + } + seg_start = p; /* keyword begins the next segment */ + } + } + p++; + } + + /* Flush the final segment. */ + if (*seg_start) + emit_segment(out, seg_start, bodyIndent); +} + + +static void +print_step(FILE *out, const TestStep *step, bool named) +{ + (void) named; + for (const TestCmd *cmd = step->commands; cmd; cmd = cmd->next) + print_cmd(out, cmd, 4); +} + + +static void +print_cmd(FILE *out, const TestCmd *cmd, int indent) +{ + switch (cmd->kind) + { + case CMD_EXEC: + fprintf(out, "%*sexec %s %s\n", indent, "", cmd->service, cmd->args); + break; + case CMD_EXEC_FAILS: + fprintf(out, "%*sexec-fails %s %s\n", indent, "", + cmd->service, cmd->args); + break; + case CMD_WAIT_STATE: + case CMD_ASSERT_STATE: + case CMD_ASSERT_ASSIGNED: + case CMD_WAIT_MULTI: + print_cmd_wait(out, cmd, indent); + break; + case CMD_WAIT_STATES: + { + /* wait until s1, s2 [in group N] timeout Ns */ + fprintf(out, "%*swait until", indent, ""); + for (int i = 0; i < cmd->waitStateCount; i++) + { + if (i > 0) fprintf(out, ","); + fprintf(out, " %s", cmd->waitStates[i]); + } + if (cmd->waitGroupCount > 0) + { + for (int g = 0; g < cmd->waitGroupCount; g++) + fprintf(out, " in group %d", cmd->waitGroups[g]); + } + fprintf(out, " timeout %ds\n", cmd->timeoutSeconds); + break; + } + case CMD_WAIT_STOPPED: + fprintf(out, "%*swait until %s stopped timeout %ds\n", + indent, "", cmd->service, cmd->timeoutSeconds); + break; + case CMD_PROMOTE: + { + fprintf(out, "%*spromote", indent, ""); + for (int i = 0; i < cmd->promoteCount; i++) + { + if (i > 0) fprintf(out, ","); + fprintf(out, " %s", cmd->promoteNodes[i]); + } + fprintf(out, "\n"); + break; + } + case CMD_SQL: + { + /* + * Normalise the SQL first (collapses embedded newlines from a + * previous multi-line block), then check if the whole thing fits + * on one line: " sql { }". + * If not, open a block and emit clause-keyword-split SQL. + */ + char norm[8192]; + normalize_sql(cmd->args, norm, sizeof(norm)); + + int oneliner_len = indent + + 4 /* "sql " */ + + (int) strlen(cmd->service) + + 3 /* " { " */ + + (int) strlen(norm) + + 2; /* " }" */ + + if (oneliner_len <= 79) + { + fprintf(out, "%*ssql %s { %s }\n", + indent, "", cmd->service, norm); + } + else + { + fprintf(out, "%*ssql %s {\n", indent, "", cmd->service); + print_sql_body(out, norm, indent + 4); + fprintf(out, "%*s}\n", indent, ""); + } + break; + } + case CMD_EXPECT: + { + /* If the stored value has newlines it was converted from + * { r1 } { r2 } tuple syntax by expand_tuple_expect — reverse it. */ + if (strchr(cmd->expected, '\n')) + { + fprintf(out, "%*sexpect {", indent, ""); + const char *p = cmd->expected; + while (*p) + { + const char *nl = strchr(p, '\n'); + int len = nl ? (int)(nl - p) : (int)strlen(p); + fprintf(out, " { %.*s }", len, p); + p += len; + if (*p == '\n') p++; + } + fprintf(out, " }\n"); + } + else + fprintf(out, "%*sexpect { %s }\n", indent, "", cmd->expected); + break; + } + case CMD_EXPECT_ERROR: + fprintf(out, "%*sexpect error %s\n", indent, "", cmd->state); + break; + case CMD_NETWORK_OFF: + fprintf(out, "%*snetwork disconnect %s\n", indent, "", cmd->service); + break; + case CMD_NETWORK_ON: + fprintf(out, "%*snetwork connect %s\n", indent, "", cmd->service); + break; + case CMD_SLEEP: + fprintf(out, "%*ssleep %ds\n", indent, "", cmd->timeoutSeconds); + break; + case CMD_COMPOSE_DOWN: + fprintf(out, "%*scompose down\n", indent, ""); + break; + case CMD_COMPOSE_START: + fprintf(out, "%*scompose start %s\n", indent, "", cmd->service); + break; + case CMD_COMPOSE_STOP: + fprintf(out, "%*scompose stop %s\n", indent, "", cmd->service); + break; + case CMD_COMPOSE_KILL: + fprintf(out, "%*scompose kill %s\n", indent, "", cmd->service); + break; + case CMD_PG_AUTOCTL: + fprintf(out, "%*spg_autoctl %s\n", indent, "", cmd->args); + break; + case CMD_STOP_POSTGRES: + fprintf(out, "%*sstop postgres %s\n", indent, "", cmd->service); + break; + case CMD_START_POSTGRES: + fprintf(out, "%*sstart postgres %s\n", indent, "", cmd->service); + break; + case CMD_STAYS_WHILE: + fprintf(out, "%*sassert %s stays %s while {\n", + indent, "", cmd->service, cmd->state); + for (const TestCmd *bc = cmd->body; bc; bc = bc->next) + print_cmd(out, bc, indent + 4); + fprintf(out, "%*s}\n", indent, ""); + break; + case CMD_COMPOSE_INJECT: + fprintf(out, "%*scompose inject %s %s %s:%s\n", + indent, "", + cmd->expected, /* image */ + cmd->args, /* src path */ + cmd->service, /* dst service */ + cmd->state); /* dst path */ + break; + case CMD_SET_MONITOR: + fprintf(out, "%*sset monitor %s\n", indent, "", cmd->service); + break; + case CMD_LOGS_CHECK: + { + /* + * logs [not] contains|matches "" + * The logsNegate flag adds "not " and allowError picks the verb. + */ + const char *verb = cmd->allowError ? "matches" : "contains"; + fprintf(out, "%*slogs %s %s%s \"%s\"\n", + indent, "", + cmd->service, + cmd->logsNegate ? "not " : "", + verb, + cmd->args); + break; + } + default: + fprintf(out, "%*s(unknown cmd %d)\n", indent, "", cmd->kind); + break; + } +} + + +/* + * print_cmd_wait handles the various wait/assert forms, emitting multi-line + * output for CMD_WAIT_MULTI and for single-node waits with pass-through. + */ +static void +print_cmd_wait(FILE *out, const TestCmd *cmd, int indent) +{ + if (cmd->kind == CMD_WAIT_MULTI) + { + /* first condition on same line, subsequent "and" lines indented */ + fprintf(out, "%*swait until %s state is %s\n", + indent, "", cmd->waitNodes[0], cmd->waitStates[0]); + for (int i = 1; i < cmd->waitStateCount; i++) + fprintf(out, "%*sand %s state is %s\n", + indent + 4, "", + cmd->waitNodes[i], cmd->waitStates[i]); + fprintf(out, "%*s timeout %ds\n", indent, "", cmd->timeoutSeconds); + return; + } + + /* + * CMD_ASSERT_ASSIGNED: grammar uses `=` not `is`. + * Distinguish wait-form (has timeout) from assert-form (no timeout). + */ + if (cmd->kind == CMD_ASSERT_ASSIGNED) + { + if (cmd->timeoutSeconds > 0) + fprintf(out, "%*swait until %s assigned-state = %s timeout %ds\n", + indent, "", cmd->service, cmd->state, cmd->timeoutSeconds); + else + fprintf(out, "%*sassert %s assigned-state = %s\n", + indent, "", cmd->service, cmd->state); + return; + } + + /* CMD_ASSERT_STATE with no timeout: instant check → canonical assert form */ + if (cmd->kind == CMD_ASSERT_STATE && cmd->timeoutSeconds == 0) + { + fprintf(out, "%*sassert %s state = %s\n", + indent, "", cmd->service, cmd->state); + return; + } + + /* CMD_ASSERT_STATE with timeout, and CMD_WAIT_STATE: polling wait */ + const char *op = "wait until"; + + if (cmd->passThroughCount > 0) + { + /* multi-line: target state, then "passing through" line */ + fprintf(out, "%*s%s %s state is %s\n", + indent, "", op, cmd->service, cmd->state); + fprintf(out, "%*s passing through", indent, ""); + for (int i = 0; i < cmd->passThroughCount; i++) + { + if (i > 0) fprintf(out, ","); + fprintf(out, " %s", cmd->passThroughStates[i]); + } + fprintf(out, "\n"); + fprintf(out, "%*s timeout %ds\n", indent, "", cmd->timeoutSeconds); + return; + } + + /* simple single-line */ + if (cmd->timeoutSeconds > 0) + fprintf(out, "%*s%s %s state is %s timeout %ds\n", + indent, "", op, cmd->service, cmd->state, cmd->timeoutSeconds); + else + fprintf(out, "%*s%s %s state is %s\n", + indent, "", op, cmd->service, cmd->state); +} diff --git a/src/bin/pgaftest/cli_indent.h b/src/bin/pgaftest/cli_indent.h new file mode 100644 index 000000000..a625eead8 --- /dev/null +++ b/src/bin/pgaftest/cli_indent.h @@ -0,0 +1,15 @@ +/* + * src/bin/pgaftest/cli_indent.h + * pgaftest indent — parse a .pgaf file and rewrite it with canonical + * indentation. + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the PostgreSQL License. + */ + +#ifndef CLI_INDENT_H +#define CLI_INDENT_H + +void cli_indent(int argc, char **argv); + +#endif /* CLI_INDENT_H */ diff --git a/src/bin/pgaftest/cli_root.c b/src/bin/pgaftest/cli_root.c index 8e147902d..1b6304335 100644 --- a/src/bin/pgaftest/cli_root.c +++ b/src/bin/pgaftest/cli_root.c @@ -18,6 +18,7 @@ #include "test_spec.h" #include "test_runner.h" #include "cli_demo.h" +#include "cli_indent.h" /* ----------------------------------------------------------------------- * Shared option parsing @@ -31,6 +32,7 @@ typedef struct PgaftestOpts char schedule[1024]; char expected[1024]; bool withTmux; + bool noCleanup; /* --no-cleanup: skip compose down after run */ int verbose; } PgaftestOpts; @@ -72,12 +74,14 @@ derive_work_dir(const char *specPath, char *buf, int buflen) } static struct option long_options[] = { - { "work-dir", required_argument, NULL, 'w' }, - { "schedule", required_argument, NULL, 'S' }, - { "expected", required_argument, NULL, 'E' }, - { "tmux", no_argument, NULL, 't' }, - { "verbose", no_argument, NULL, 'v' }, - { "help", no_argument, NULL, 'h' }, + { "work-dir", required_argument, NULL, 'w' }, + { "schedule", required_argument, NULL, 'S' }, + { "expected", required_argument, NULL, 'E' }, + { "tmux", no_argument, NULL, 't' }, + { "no-cleanup", no_argument, NULL, 'n' }, + { "verbose", no_argument, NULL, 'v' }, + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; @@ -86,7 +90,7 @@ pgaftest_getopts(int argc, char **argv) { int c, option_index = 0; - while ((c = getopt_long(argc, argv, "w:S:E:tvh", + while ((c = getopt_long(argc, argv, "w:S:E:tnvdh", long_options, &option_index)) != -1) { switch (c) @@ -106,10 +110,17 @@ pgaftest_getopts(int argc, char **argv) case 't': pgaftestOpts.withTmux = true; break; + case 'n': + pgaftestOpts.noCleanup = true; + break; case 'v': pgaftestOpts.verbose++; log_set_level(LOG_DEBUG); break; + case 'd': + pgaftestOpts.verbose += 2; + log_set_level(LOG_TRACE); + break; case 'h': commandline_help(stderr); exit(EXIT_CODE_QUIT); @@ -127,7 +138,11 @@ pgaftest_getopts(int argc, char **argv) static void cli_run(int argc, char **argv) { - int optind = pgaftest_getopts(argc, argv); + /* + * The subcommand library already called pgaftest_getopts() and stripped + * all options from argv before calling us. argv[0] is the spec file + * (if provided), argc is the number of remaining positional arguments. + */ /* Handle --schedule file */ if (pgaftestOpts.schedule[0] != '\0') @@ -186,7 +201,7 @@ cli_run(int argc, char **argv) if (!spec) { failed++; total++; continue; } total++; - if (!runner_run(spec, workDir)) + if (!runner_run(spec, workDir, pgaftestOpts.noCleanup)) failed++; } fclose(f); @@ -197,13 +212,13 @@ cli_run(int argc, char **argv) } /* Single spec file */ - if (optind > argc) + if (argc < 1 || argv[0] == NULL) { log_error("Usage: pgaftest run [--schedule ] []"); exit(1); } - strncpy(pgaftestOpts.specFile, argv[optind - 1], + strncpy(pgaftestOpts.specFile, argv[0], sizeof(pgaftestOpts.specFile)-1); if (pgaftestOpts.workDir[0] == '\0') @@ -213,7 +228,7 @@ cli_run(int argc, char **argv) TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); if (!spec) exit(1); - bool ok = runner_run(spec, pgaftestOpts.workDir); + bool ok = runner_run(spec, pgaftestOpts.workDir, pgaftestOpts.noCleanup); exit(ok ? 0 : 1); } @@ -224,15 +239,13 @@ cli_run(int argc, char **argv) static void cli_setup(int argc, char **argv) { - int optind = pgaftest_getopts(argc, argv); - - if (optind > argc) + if (argc < 1 || argv[0] == NULL) { log_error("Usage: pgaftest setup [--tmux] [--work-dir ]"); exit(1); } - strncpy(pgaftestOpts.specFile, argv[optind - 1], + strncpy(pgaftestOpts.specFile, argv[0], sizeof(pgaftestOpts.specFile)-1); if (pgaftestOpts.workDir[0] == '\0') @@ -254,16 +267,14 @@ cli_setup(int argc, char **argv) static void cli_step(int argc, char **argv) { - int optind = pgaftest_getopts(argc, argv); - - if (optind > argc) + if (argc < 1 || argv[0] == NULL) { log_error("Usage: pgaftest step [--work-dir ]"); exit(1); } /* step name is positional */ - strncpy(pgaftestOpts.stepName, argv[optind - 1], + strncpy(pgaftestOpts.stepName, argv[0], sizeof(pgaftestOpts.stepName)-1); /* We need the spec file too — look for it in workDir */ @@ -272,8 +283,8 @@ cli_step(int argc, char **argv) pgaftestOpts.workDir); /* If there's a second positional arg, treat it as the spec path */ - if (optind + 1 < argc) - strncpy(specPath, argv[optind+1], sizeof(specPath)-1); + if (argc >= 2 && argv[1] != NULL) + strncpy(specPath, argv[1], sizeof(specPath)-1); /* derive work dir from spec path when not given explicitly */ if (pgaftestOpts.workDir[0] == '\0') @@ -288,6 +299,34 @@ cli_step(int argc, char **argv) exit(ok ? 0 : 1); } +/* ----------------------------------------------------------------------- + * pgaftest prepare [] + * + * Writes docker-compose.yml, *.ini files, and a Makefile to the output + * directory. Prints the docker compose command to stdout. + * ----------------------------------------------------------------------- */ + +static void +cli_prepare(int argc, char **argv) +{ + if (argc < 1 || argv[0] == NULL) + { + log_error("Usage: pgaftest prepare []"); + exit(1); + } + + strncpy(pgaftestOpts.specFile, argv[0], sizeof(pgaftestOpts.specFile)-1); + + const char *outDir = (argc >= 2 && argv[1] && argv[1][0] != '-') + ? argv[1] : NULL; + + TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); + if (!spec) exit(1); + + bool ok = runner_prepare(spec, outDir); + exit(ok ? 0 : 1); +} + /* ----------------------------------------------------------------------- * pgaftest show * ----------------------------------------------------------------------- */ @@ -295,15 +334,13 @@ cli_step(int argc, char **argv) static void cli_show(int argc, char **argv) { - int optind = pgaftest_getopts(argc, argv); - - if (optind > argc) + if (argc < 1 || argv[0] == NULL) { log_error("Usage: pgaftest show "); exit(1); } - strncpy(pgaftestOpts.specFile, argv[optind - 1], + strncpy(pgaftestOpts.specFile, argv[0], sizeof(pgaftestOpts.specFile)-1); TestSpec *spec = parse_test_spec(pgaftestOpts.specFile); @@ -320,12 +357,10 @@ cli_show(int argc, char **argv) static void cli_down(int argc, char **argv) { - int optind = pgaftest_getopts(argc, argv); - /* optional positional: spec file to derive work dir from */ - if (optind <= argc && argv[optind - 1] && argv[optind - 1][0] != '-') + if (argc >= 1 && argv[0] && argv[0][0] != '-') { - strncpy(pgaftestOpts.specFile, argv[optind - 1], + strncpy(pgaftestOpts.specFile, argv[0], sizeof(pgaftestOpts.specFile)-1); } @@ -368,7 +403,11 @@ static CommandLine run_command = " --expected Directory of expected output files\n" " --work-dir Working directory\n" " (default: $TMPDIR/pgaftest/)\n" - " --verbose Increase log verbosity\n", + " --no-cleanup Leave the compose stack running after the\n" + " run (pass or fail) for post-mortem inspection.\n" + " Use `pgaftest down ` to clean up.\n" + " --verbose Enable DEBUG log level\n" + " --debug Enable TRACE log level\n", pgaftest_getopts, cli_run); static CommandLine setup_command = @@ -378,7 +417,8 @@ static CommandLine setup_command = " --tmux Launch a tmux session after setup\n" " --work-dir Working directory\n" " (default: $TMPDIR/pgaftest/)\n" - " --verbose Increase log verbosity\n", + " --verbose Enable DEBUG log level\n" + " --debug Enable TRACE log level\n", pgaftest_getopts, cli_setup); static CommandLine step_command = @@ -395,6 +435,14 @@ static CommandLine show_command = "", pgaftest_getopts, cli_show); +static CommandLine prepare_command = + make_command("prepare", + "Write compose files and Makefile to a directory for manual use", + " []", + " Path to the spec file\n" + " Output directory (default: -compose/)\n", + pgaftest_getopts, cli_prepare); + static CommandLine down_command = make_command("down", "Run teardown block and stop the compose stack", @@ -402,12 +450,23 @@ static CommandLine down_command = " --work-dir Working directory (default: /tmp/pgaftest)\n", pgaftest_getopts, cli_down); +extern void cli_indent(int argc, char **argv); + +static CommandLine indent_command = + make_command("indent", + "Parse a .pgaf spec and rewrite it with canonical indentation", + "", + "", + pgaftest_getopts, cli_indent); + static CommandLine *root_subcommands[] = { &run_command, &setup_command, &step_command, &show_command, + &prepare_command, &down_command, + &indent_command, &pgaftest_demo_command, NULL }; @@ -416,10 +475,12 @@ CommandLine pgaftest_root = make_command_set("pgaftest", "pg_auto_failover test runner", "[command] [options]", - " run Run a .pgaf spec (CI mode)\n" - " setup Bring up a cluster interactively\n" - " step Run one named step\n" - " show Print generated docker-compose.yml\n" - " down Tear down the cluster\n" - " demo Demo application\n", + " run Run a .pgaf spec (CI mode)\n" + " setup Bring up a cluster interactively\n" + " step Run one named step\n" + " show Print generated docker-compose.yml\n" + " prepare Write compose files + Makefile to a directory\n" + " down Tear down the cluster\n" + " indent Rewrite a spec with canonical indentation\n" + " demo Demo application\n", NULL, root_subcommands); diff --git a/src/bin/pgaftest/compose_gen.c b/src/bin/pgaftest/compose_gen.c index 3e78a4756..62b6496ec 100644 --- a/src/bin/pgaftest/compose_gen.c +++ b/src/bin/pgaftest/compose_gen.c @@ -30,6 +30,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include "compose_gen.h" #include "pgsetup.h" @@ -50,25 +56,293 @@ /* Fixed PGDATA location inside every container */ #define NODE_PGDATA "/var/lib/postgres/pgaf" +/* Debian-style PGDATA prefix: /var/lib/postgresql// */ +#define DEBIAN_PGDATA_PREFIX "/var/lib/postgresql" + +static const char * +debian_pg_version(void) +{ + const char *v = getenv("PGVERSION"); + return (v && v[0]) ? v : "17"; +} + +/* SSL cert directory inside every container when ssl needs CA-signed certs */ +#define SSL_DIR_IN_CONTAINER "/etc/pgaf/ssl" + +/* + * Shell snippet prepended to the container start command when CA-signed certs + * are in use. + * + * - Server cert/key copied to /var/lib/postgres/ (volume root, writable) so + * PostgreSQL can open the key file as the container user. + * - Client cert/key copied to ~/.postgresql/ so libpq uses them automatically + * for all outbound connections (cert auth to monitor and peers). + * - CA cert copied to ~/.postgresql/root.crt so libpq trusts server certs. + */ +#define SSL_COPY_CERTS_CMD \ + "cp " SSL_DIR_IN_CONTAINER "/server/server.crt /var/lib/postgres/server.crt" \ + " && cp " SSL_DIR_IN_CONTAINER "/server/server.key /var/lib/postgres/server.key" \ + " && chmod 0600 /var/lib/postgres/server.key" \ + " && mkdir -p /var/lib/postgres/.postgresql" \ + " && cp " SSL_DIR_IN_CONTAINER "/client/postgresql.crt /var/lib/postgres/.postgresql/postgresql.crt" \ + " && cp " SSL_DIR_IN_CONTAINER "/client/postgresql.key /var/lib/postgres/.postgresql/postgresql.key" \ + " && chmod 0600 /var/lib/postgres/.postgresql/postgresql.key" \ + " && cp " SSL_DIR_IN_CONTAINER "/ca.crt /var/lib/postgres/.postgresql/root.crt" \ + " &&" + + +/* + * ssl_needs_certs returns true when the ssl mode requires CA-signed server + * certificates to be generated on the host: verify-ca and verify-full. + */ +static bool +ssl_needs_certs(const char *ssl) +{ + return strcmp(ssl, "verify-ca") == 0 || strcmp(ssl, "verify-full") == 0; +} + + +/* + * run_openssl runs a single openssl command (argv-style) and returns true on + * success. The last element of argv[] must be NULL. + */ +static bool +run_openssl(const char *const *argv) +{ + char cmd[4096] = "openssl"; + int pos = strlen(cmd); + + for (int i = 1; argv[i]; i++) + { + pos += snprintf(cmd + pos, sizeof(cmd) - pos, " %s", argv[i]); + if (pos >= (int) sizeof(cmd) - 1) + { + log_error("openssl command too long"); + return false; + } + } + + log_debug("Running: %s", cmd); + int rc = system(cmd); + if (rc != 0) + { + log_error("Command failed (exit %d): %s", rc, cmd); + return false; + } + return true; +} + + +/* + * compose_gen_write_ssl_certs generates the CA and per-service server + * certificates in /ssl/ using openssl. Called from + * runner_compose_generate() before compose_gen_write() so the volume paths + * already exist when the compose file is written. + * + * Layout on the host: + * ssl/ca.crt — shared CA certificate + * ssl/ca.key — CA private key (stays on host) + * ssl//server.crt — server certificate for service + * ssl//server.key — server private key for service + * + * The CA cert and the per-service dir are bind-mounted into each container so + * pg_autoctl can find them at the paths recorded in the ini [ssl] section. + */ +bool +compose_gen_write_ssl_certs(const TestCluster *cluster, const char *workDir) +{ + if (!ssl_needs_certs(cluster->ssl)) + return true; + + char sslDir[MAXPGPATH]; + sformat(sslDir, sizeof(sslDir), "%s/ssl", workDir); + + /* Create ssl/ directory */ + if (mkdir(sslDir, 0755) != 0 && errno != EEXIST) + { + log_error("Failed to create %s: %m", sslDir); + return false; + } + + char caKey[MAXPGPATH], caCrt[MAXPGPATH]; + sformat(caKey, sizeof(caKey), "%s/ca.key", sslDir); + sformat(caCrt, sizeof(caCrt), "%s/ca.crt", sslDir); + + /* Generate CA key + self-signed cert with basicConstraints=CA:TRUE */ + bool caRegenerated = false; + if (access(caCrt, F_OK) != 0) + { + const char *genCA[] = { + "openssl", "req", "-new", "-x509", "-nodes", "-text", + "-days", "3650", + "-keyout", caKey, + "-out", caCrt, + "-subj", "/CN=root.pgautofailover.ca", + "-addext", "basicConstraints=critical,CA:TRUE", + "-addext", "keyUsage=critical,keyCertSign,cRLSign", + NULL + }; + if (!run_openssl(genCA)) + return false; + + chmod(caKey, 0600); + log_info("Generated CA certificate at %s", caCrt); + caRegenerated = true; + } + + /* + * Generate server cert for each service: monitor + all nodes. + * We build a flat list of service names to iterate. + */ + const char *services[PGAF_MAX_NODES + 1]; /* +1 for monitor */ + int svcCount = 0; + + if (cluster->withMonitor) + services[svcCount++] = "monitor"; + + if (cluster->secondMonitorName[0]) + services[svcCount++] = cluster->secondMonitorName; + + for (int fi = 0; fi < cluster->formationCount; fi++) + { + const TestFormation *form = &cluster->formations[fi]; + for (int ni = 0; ni < form->nodeCount; ni++) + services[svcCount++] = form->nodes[ni].name; + } + + char serialFile[MAXPGPATH]; + sformat(serialFile, sizeof(serialFile), "%s/ca.srl", sslDir); + + for (int i = 0; i < svcCount; i++) + { + const char *svc = services[i]; + char svcDir[MAXPGPATH]; + sformat(svcDir, sizeof(svcDir), "%s/%s", sslDir, svc); + + if (mkdir(svcDir, 0755) != 0 && errno != EEXIST) + { + log_error("Failed to create %s: %m", svcDir); + return false; + } + + char srvKey[MAXPGPATH], srvCrt[MAXPGPATH], srvCsr[MAXPGPATH]; + sformat(srvKey, sizeof(srvKey), "%s/server.key", svcDir); + sformat(srvCrt, sizeof(srvCrt), "%s/server.crt", svcDir); + sformat(srvCsr, sizeof(srvCsr), "%s/server.csr", svcDir); + + if (access(srvCrt, F_OK) == 0 && !caRegenerated) + continue; /* already generated and CA hasn't changed */ + + char cn[128]; + sformat(cn, sizeof(cn), "/CN=%s.pgautofailover.ca", svc); + + const char *genReq[] = { + "openssl", "req", "-new", "-nodes", "-text", + "-out", srvCsr, "-keyout", srvKey, + "-subj", cn, + NULL + }; + if (!run_openssl(genReq)) + return false; + + chmod(srvKey, 0600); + + const char *signSrv[] = { + "openssl", "x509", "-req", "-in", srvCsr, + "-text", "-days", "365", + "-CA", caCrt, "-CAkey", caKey, "-CAcreateserial", + "-out", srvCrt, + NULL + }; + if (!run_openssl(signSrv)) + return false; + + log_info("Generated server certificate for %s at %s", svc, srvCrt); + } + + /* + * Generate client certificate with CN=autoctl_node, used by pg_autoctl + * processes to authenticate to PostgreSQL when ssl.auth = cert. + * Placed in ssl/client/ and mounted read-only into each container; + * the container start command copies it to ~/.postgresql/ with correct + * ownership so libpq can use it for all outbound connections. + */ + char clientDir[MAXPGPATH], clientCrt[MAXPGPATH], + clientKey[MAXPGPATH], clientCsr[MAXPGPATH]; + sformat(clientDir, sizeof(clientDir), "%s/client", sslDir); + sformat(clientCrt, sizeof(clientCrt), "%s/postgresql.crt", clientDir); + sformat(clientKey, sizeof(clientKey), "%s/postgresql.key", clientDir); + sformat(clientCsr, sizeof(clientCsr), "%s/postgresql.csr", clientDir); + + if (mkdir(clientDir, 0755) != 0 && errno != EEXIST) + { + log_error("Failed to create %s: %m", clientDir); + return false; + } + + if (access(clientCrt, F_OK) != 0 || caRegenerated) + { + const char *genReq[] = { + "openssl", "req", "-new", "-nodes", "-text", + "-out", clientCsr, "-keyout", clientKey, + "-subj", "/CN=autoctl_node", + NULL + }; + if (!run_openssl(genReq)) + return false; + + chmod(clientKey, 0600); + + const char *signClient[] = { + "openssl", "x509", "-req", "-in", clientCsr, + "-text", "-days", "365", + "-CA", caCrt, "-CAkey", caKey, "-CAcreateserial", + "-out", clientCrt, + NULL + }; + if (!run_openssl(signClient)) + return false; + + log_info("Generated client certificate at %s", clientCrt); + } + + return true; +} + /* * image_stanza writes either `image:` (when PGAF_IMAGE is set or the cluster * spec provides an image) or a `build:` stanza. */ static void -write_image_stanza(FILE *f, const TestCluster *cluster, const char *contextDir) +write_image_stanza_target(FILE *f, const TestCluster *cluster, + const char *contextDir, const char *target) { + /* + * The cluster image (from `image "..."` in the spec) is for data services + * only. The pgaftest service always builds from --target pgaftest so that + * the test runner binary is present regardless of which cluster image is + * used. + */ + bool isTestRunner = (strcmp(target, "pgaftest") == 0); + /* cluster-level image overrides PGAF_IMAGE env var */ const char *img = cluster->image[0] ? cluster->image : getenv("PGAF_IMAGE"); - if (img && *img) + if (img && *img && !isTestRunner) fprintf(f, " image: \"%s\"\n", img); else fprintf(f, " build:\n" " context: \"%s\"\n" - " target: run\n", - contextDir); + " target: %s\n", + contextDir, target); +} + +static void +write_image_stanza(FILE *f, const TestCluster *cluster, const char *contextDir) +{ + write_image_stanza_target(f, cluster, contextDir, "run"); } @@ -84,12 +358,69 @@ write_image_stanza(FILE *f, const TestCluster *cluster, const char *contextDir) * * The per-node ini file is bind-mounted from the workdir. */ +/* + * Pick a random free TCP port in the range [32768, 60999]. + * Tries up to 64 candidates; exits with a log_fatal if none found. + * + * Ports already handed out in this process are remembered in a static array + * so that consecutive calls never return the same port even though the OS + * releases the probe socket between calls. + */ +static int +pick_free_port(void) +{ + static int reserved[64]; + static int reserved_count = 0; + + srand((unsigned) time(NULL) ^ (unsigned) getpid()); + for (int attempt = 0; attempt < 64; attempt++) + { + int port = 32768 + rand() % (60999 - 32768 + 1); + + /* skip ports already given out this process */ + bool already_used = false; + for (int i = 0; i < reserved_count; i++) + { + if (reserved[i] == port) + { + already_used = true; + break; + } + } + if (already_used) + continue; + + int fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) continue; + + int opt = 1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons((uint16_t) port), + .sin_addr = { .s_addr = htonl(INADDR_LOOPBACK) }, + }; + int rc = bind(fd, (struct sockaddr *) &addr, sizeof(addr)); + close(fd); + + if (rc == 0) + { + if (reserved_count < 64) + reserved[reserved_count++] = port; + return port; + } + } + log_fatal("Could not find a free TCP port for monitor exposure"); + exit(1); +} + bool -compose_gen_write(const TestCluster *cluster, +compose_gen_write(TestCluster *cluster, const char *path, const char *projectName, - int monitorHostPort, - const char *contextDir) + const char *contextDir, + const char *specFile) { FILE *f = fopen(path, "w"); if (!f) @@ -105,29 +436,108 @@ compose_gen_write(const TestCluster *cluster, /* ---- monitor (optional) ---- */ if (cluster->withMonitor) { + /* allocate a random free host port for the monitor's postgres */ + if (cluster->monitorHostPort == 0) + cluster->monitorHostPort = pick_free_port(); + fprintf(f, " monitor:\n"); - write_image_stanza(f, cluster, contextDir); + if (cluster->monitorDebianCluster[0]) + write_image_stanza_target(f, cluster, contextDir, "debian"); + else if (cluster->monitorImageTarget[0]) + write_image_stanza_target(f, cluster, contextDir, + cluster->monitorImageTarget); + else + write_image_stanza(f, cluster, contextDir); + + char monitor_pgdata[MAXPGPATH]; + if (cluster->monitorDebianCluster[0]) + snprintf(monitor_pgdata, sizeof(monitor_pgdata), + DEBIAN_PGDATA_PREFIX "/%s/%s", + debian_pg_version(), cluster->monitorDebianCluster); + else + strlcpy(monitor_pgdata, NODE_PGDATA, sizeof(monitor_pgdata)); + fprintf(f, " hostname: monitor\n" " volumes:\n" " - monitor_data:/var/lib/postgres:rw\n" - " - ./monitor.ini:" NODE_INI_PATH ":ro\n" + " - ./monitor.ini:" NODE_INI_PATH ":ro\n"); + if (ssl_needs_certs(cluster->ssl)) + fprintf(f, + " - ./ssl/ca.crt:" SSL_DIR_IN_CONTAINER "/ca.crt:ro\n" + " - ./ssl/monitor:" SSL_DIR_IN_CONTAINER "/server:ro\n" + " - ./ssl/client:" SSL_DIR_IN_CONTAINER "/client:ro\n"); + if (cluster->bindSource) + fprintf(f, + " - %s:/usr/src/pg_auto_failover:rw\n", contextDir); + fprintf(f, + " environment:\n" + " PGDATA: %s\n", + monitor_pgdata); + if (cluster->extensionVersion[0]) + fprintf(f, + " PG_AUTOCTL_EXTENSION_VERSION: \"%s\"\n", + cluster->extensionVersion); + fprintf(f, + " ports:\n" + " - \"%d:5432\"\n", + cluster->monitorHostPort); + + fprintf(f, + " command: [\"/bin/sh\", \"-c\"," + " \"%s rm -f /tmp/pg_autoctl%s/pg_autoctl.pid" + " && exec pg_autoctl node run " NODE_INI_PATH "\"]\n" + " stop_grace_period: 60s\n\n", + ssl_needs_certs(cluster->ssl) ? SSL_COPY_CERTS_CMD : "", + monitor_pgdata); + } + + /* ---- second monitor (initially stopped, for replace-monitor tests) ---- */ + if (cluster->secondMonitorName[0]) + { + if (cluster->secondMonitorHostPort == 0) + cluster->secondMonitorHostPort = pick_free_port(); + + const char *svc = cluster->secondMonitorName; + fprintf(f, " %s:\n", svc); + write_image_stanza(f, cluster, contextDir); + fprintf(f, + " hostname: %s\n" + " volumes:\n" + " - %s_data:/var/lib/postgres:rw\n" + " - ./%s.ini:" NODE_INI_PATH ":ro\n", + svc, svc, svc); + if (ssl_needs_certs(cluster->ssl)) + fprintf(f, + " - ./ssl/ca.crt:" SSL_DIR_IN_CONTAINER "/ca.crt:ro\n" + " - ./ssl/%s:" SSL_DIR_IN_CONTAINER "/server:ro\n" + " - ./ssl/client:" SSL_DIR_IN_CONTAINER "/client:ro\n", + svc); + if (cluster->bindSource) + fprintf(f, + " - %s:/usr/src/pg_auto_failover:rw\n", contextDir); + fprintf(f, " environment:\n" - " PGDATA: " NODE_PGDATA "\n" + " PGDATA: " NODE_PGDATA "\n"); + fprintf(f, " ports:\n" - " - \"127.0.0.1:%d:5432\"\n" - " healthcheck:\n" - " test: [\"CMD-SHELL\"," - " \"pg_isready -d pg_auto_failover -U autoctl_node\"]\n" - " interval: 5s\n" - " timeout: 5s\n" - " retries: 20\n" - " start_period: 30s\n" - " command: [\"pg_autoctl\", \"node\", \"run\", \"" NODE_INI_PATH "\"]\n\n", - monitorHostPort); + " - \"%d:5432\"\n", + cluster->secondMonitorHostPort); + fprintf(f, + " command: [\"/bin/sh\", \"-c\"," + " \"%s rm -f /tmp/pg_autoctl" NODE_PGDATA "/pg_autoctl.pid" + " && exec pg_autoctl node run " NODE_INI_PATH "\"]\n" + " stop_grace_period: 60s\n\n", + ssl_needs_certs(cluster->ssl) ? SSL_COPY_CERTS_CMD : ""); } /* ---- data nodes — iterate all formations ---- */ + /* + * Non-default formations are listed in [formation ] sections of the + * monitor.ini. pg_autoctl node run reads them and creates each one after + * the monitor is initialized, before starting the supervisor. + * Data nodes retry registration until their formation exists. + */ const TestNode *firstNode = NULL; for (int fi = 0; fi < cluster->formationCount; fi++) @@ -137,61 +547,179 @@ compose_gen_write(const TestCluster *cluster, for (int ni = 0; ni < form->nodeCount; ni++) { const TestNode *n = &form->nodes[ni]; - char ini_filename[128]; + fprintf(f, " %s:\n", n->name); + if (n->debianCluster[0]) + write_image_stanza_target(f, cluster, contextDir, "debian"); + else + write_image_stanza(f, cluster, contextDir); - sformat(ini_filename, sizeof(ini_filename), "%s.ini", n->name); + /* debian PGDATA: /var/lib/postgresql// */ + char node_pgdata[MAXPGPATH]; + if (n->debianCluster[0]) + snprintf(node_pgdata, sizeof(node_pgdata), + DEBIAN_PGDATA_PREFIX "/%s/%s", + debian_pg_version(), n->debianCluster); + else + strlcpy(node_pgdata, NODE_PGDATA, sizeof(node_pgdata)); - fprintf(f, " %s:\n", n->name); - write_image_stanza(f, cluster, contextDir); fprintf(f, " hostname: %s\n" " volumes:\n" " - %s_data:/var/lib/postgres:rw\n" - " - ./%s:" NODE_INI_PATH ":ro\n" + " - ./%s.ini:" NODE_INI_PATH ":%s\n", + n->name, + n->name, + n->name, + n->launchDeferred ? "rw" : "ro"); + if (ssl_needs_certs(cluster->ssl)) + fprintf(f, + " - ./ssl/ca.crt:" SSL_DIR_IN_CONTAINER "/ca.crt:ro\n" + " - ./ssl/%s:" SSL_DIR_IN_CONTAINER "/server:ro\n" + " - ./ssl/client:" SSL_DIR_IN_CONTAINER "/client:ro\n", + n->name); + for (int vi = 0; vi < n->volumeCount; vi++) + fprintf(f, " - %s_%s:%s:rw\n", + n->volumes[vi].name, n->name, n->volumes[vi].path); + fprintf(f, " environment:\n" - " PGDATA: " NODE_PGDATA "\n" + " PGDATA: %s\n" " PGUSER: demo\n" " PGDATABASE: demo\n" + " PG_AUTOCTL_TEST_DELAY: \"1\"\n" " expose:\n" " - 5432\n", - n->name, - n->name, ini_filename); - if (cluster->withMonitor) + node_pgdata); + /* + * No depends_on: keeper retry loops handle monitor not yet ready, + * and the formation wait in keeper_register_and_init handles the + * case where the formation hasn't been created yet. + */ + + /* per-node ssl override may differ from cluster default */ + const char *node_ssl = n->ssl[0] ? n->ssl : cluster->ssl; + fprintf(f, + " command: [\"/bin/sh\", \"-c\"," + " \"%s rm -f /tmp/pg_autoctl%s/pg_autoctl.pid" + " && exec pg_autoctl node run " NODE_INI_PATH "\"]\n" + " stop_grace_period: 60s\n", + ssl_needs_certs(node_ssl) ? SSL_COPY_CERTS_CMD : "", + node_pgdata); + + /* + * The first data node gets a healthcheck so that subsequent nodes + * can use service_healthy depends_on. This ensures node1 has + * registered with the monitor (and become the initial primary) before + * any other node starts, making the initial election deterministic. + * + * pg_autoctl status exits 0 only after the keeper process is running + * and has established its state with the monitor. + */ + if (!firstNode) fprintf(f, - " depends_on:\n" - " monitor:\n" - " condition: service_healthy\n"); + " healthcheck:\n" + " test: [\"CMD\", \"pg_autoctl\", \"status\"," + " \"--pgdata\", \"%s\"]\n" + " interval: 2s\n" + " timeout: 5s\n" + " retries: 30\n" + " start_period: 5s\n", + node_pgdata); /* - * Ensure node registration order is deterministic: the first - * node in the first formation always registers before subsequent - * nodes, so node IDs are predictable in tests. + * Non-first data nodes wait for the first node to be healthy before + * starting, giving node1 a guaranteed head start on the monitor + * registration race. */ - if (firstNode && firstNode != n) + if (firstNode) fprintf(f, + " depends_on:\n" " %s:\n" - " condition: service_started\n", + " condition: service_healthy\n", firstNode->name); - - if (n->noAutostart) - fprintf(f, - " command: [\"sleep\", \"infinity\"]\n\n"); - else - fprintf(f, - " command: [\"pg_autoctl\", \"node\", \"run\"," - " \"" NODE_INI_PATH "\"]\n\n"); + fprintf(f, "\n"); if (!firstNode) firstNode = n; } } + /* + * ---- pgaftest service ---- + * + * When specFile is provided, include a pgaftest service that runs the + * spec from inside the compose network. Benefits: + * - direct TCP to monitor/nodes — LISTEN/NOTIFY works, no pg_hba issue + * - pg_autoctl commands run locally (just need --monitor ) + * - compose stop/start and network disconnect/connect via docker socket + * + * CI usage: docker compose up --exit-code-from pgaftest + */ + if (specFile) + { + /* Determine which service pgaftest must wait for before starting. */ + /* It needs the cluster fully ready: monitor healthy + all nodes started. */ + fprintf(f, " pgaftest:\n"); + write_image_stanza_target(f, cluster, contextDir, "pgaftest"); + /* Build monitor pguri for PG_AUTOCTL_MONITOR */ + char monitorPguri[512]; + if (cluster->monitorPassword[0]) + sformat(monitorPguri, sizeof(monitorPguri), + "postgres://autoctl_node:%s@monitor/pg_auto_failover", + cluster->monitorPassword); + else + sformat(monitorPguri, sizeof(monitorPguri), + "postgres://autoctl_node@monitor/pg_auto_failover"); + + /* + * pgaftest has its own ping loop that waits for the monitor before + * starting, so no depends_on is needed. + */ + /* Derive work dir (directory containing the compose file). */ + char workDir[MAXPGPATH]; + strlcpy(workDir, path, sizeof(workDir)); + char *slash = strrchr(workDir, '/'); + if (slash) *slash = '\0'; else strlcpy(workDir, ".", sizeof(workDir)); + + fprintf(f, + " user: root\n" + " volumes:\n" + " - %s:/spec.pgaf:ro\n" + " - /var/run/docker.sock:/var/run/docker.sock\n" + " - %s:%s:ro\n", + specFile, workDir, workDir); + if (ssl_needs_certs(cluster->ssl)) + fprintf(f, + " - %s/ssl/ca.crt:/root/.postgresql/root.crt:ro\n" + " - %s/ssl/client/postgresql.crt:/root/.postgresql/postgresql.crt:ro\n" + " - %s/ssl/client/postgresql.key:/root/.postgresql/postgresql.key:ro\n", + workDir, workDir, workDir); + fprintf(f, + " environment:\n" + " PGAFTEST_COMPOSE_SERVICE: \"1\"\n" + " PGAFTEST_HOST_WORK_DIR: \"%s\"\n" + " COMPOSE_PROJECT_NAME: \"%s\"\n", + workDir, projectName); + if (cluster->withMonitor) + fprintf(f, " PG_AUTOCTL_MONITOR: \"%s\"\n", monitorPguri); + fprintf(f, " command: [\"pgaftest\", \"run\", \"/spec.pgaf\"]\n\n"); + } + /* ---- volumes ---- */ fprintf(f, "volumes:\n"); if (cluster->withMonitor) fprintf(f, " monitor_data:\n"); + if (cluster->secondMonitorName[0]) + fprintf(f, " %s_data:\n", cluster->secondMonitorName); for (int fi = 0; fi < cluster->formationCount; fi++) - for (int ni = 0; ni < cluster->formations[fi].nodeCount; ni++) - fprintf(f, " %s_data:\n", cluster->formations[fi].nodes[ni].name); + { + const TestFormation *form = &cluster->formations[fi]; + for (int ni = 0; ni < form->nodeCount; ni++) + { + const TestNode *n = &form->nodes[ni]; + fprintf(f, " %s_data:\n", n->name); + for (int vi = 0; vi < n->volumeCount; vi++) + fprintf(f, " %s_%s:\n", n->volumes[vi].name, n->name); + } + } fclose(f); log_info("Wrote docker-compose.yml to \"%s\"", path); @@ -206,6 +734,9 @@ compose_gen_write(const TestCluster *cluster, bool compose_gen_write_monitor_ini(const TestCluster *cluster, const char *dir) { + if (!cluster->withMonitor) + return true; + char path[1024]; sformat(path, sizeof(path), "%s/monitor.ini", dir); @@ -216,6 +747,14 @@ compose_gen_write_monitor_ini(const TestCluster *cluster, const char *dir) return false; } + char mon_pgdata[MAXPGPATH]; + if (cluster->monitorDebianCluster[0]) + snprintf(mon_pgdata, sizeof(mon_pgdata), + DEBIAN_PGDATA_PREFIX "/%s/%s", + debian_pg_version(), cluster->monitorDebianCluster); + else + strlcpy(mon_pgdata, NODE_PGDATA, sizeof(mon_pgdata)); + fprintf(f, "# Generated by pgaftest — do not edit manually\n" "# Monitor node configuration\n" @@ -226,21 +765,114 @@ compose_gen_write_monitor_ini(const TestCluster *cluster, const char *dir) "port = 5432\n" "\n" "[postgresql]\n" - "pgdata = " NODE_PGDATA "\n" + "pgdata = %s\n" "\n" "[options]\n" "ssl = %s\n" "auth = %s\n" "pg_hba_lan = false\n", + mon_pgdata, cluster->ssl, cluster->auth); + if (ssl_needs_certs(cluster->ssl)) + fprintf(f, + "\n" + "[ssl]\n" + "ca_file = " SSL_DIR_IN_CONTAINER "/ca.crt\n" + /* + * The server cert/key are copied from the read-only bind-mount to + * /var/lib/postgres/ (the volume root, writable by the container + * user) in the start command so the key is owned by the container + * user and PostgreSQL can open it. + */ + "cert_file = /var/lib/postgres/server.crt\n" + "key_file = /var/lib/postgres/server.key\n"); + + if (cluster->monitorPassword[0]) + fprintf(f, + "\n" + "[pg_auto_failover]\n" + "autoctl_node_password = %s\n", + cluster->monitorPassword); + + /* emit [formation ] for every non-default formation */ + for (int fi = 0; fi < cluster->formationCount; fi++) + { + const TestFormation *form = &cluster->formations[fi]; + if (strcmp(form->name, "default") == 0) + continue; + /* kind defaults to "ha" — the monitor uses that default when absent */ + fprintf(f, "\n[formation %s]\n", form->name); + } + fclose(f); log_info("Wrote monitor.ini to \"%s\"", path); return true; } +/* ----------------------------------------------------------------------- + * compose_gen_write_second_monitor_ini + * ----------------------------------------------------------------------- */ + +bool +compose_gen_write_second_monitor_ini(const TestCluster *cluster, const char *dir) +{ + if (!cluster->secondMonitorName[0]) + return true; + + const char *name = cluster->secondMonitorName; + char path[1024]; + sformat(path, sizeof(path), "%s/%s.ini", dir, name); + + FILE *f = fopen(path, "w"); + if (!f) + { + log_error("Failed to open \"%s\" for writing: %m", path); + return false; + } + + fprintf(f, + "# Generated by pgaftest — do not edit manually\n" + "# Second monitor (replacement): %s\n" + "\n" + "[node]\n" + "kind = monitor\n" + "hostname = %s\n" + "port = 5432\n" + "\n" + "[postgresql]\n" + "pgdata = " NODE_PGDATA "\n" + "\n" + "[options]\n" + "ssl = %s\n" + "auth = %s\n" + "pg_hba_lan = false\n", + name, name, + cluster->ssl, + cluster->auth); + + if (ssl_needs_certs(cluster->ssl)) + fprintf(f, + "\n" + "[ssl]\n" + "ca_file = " SSL_DIR_IN_CONTAINER "/ca.crt\n" + /* + * The server cert/key are copied from the read-only bind-mount to + * /var/lib/postgres/ (the volume root, writable by the container + * user) in the start command so the key is owned by the container + * user and PostgreSQL can open it. + */ + "cert_file = /var/lib/postgres/server.crt\n" + "key_file = /var/lib/postgres/server.key\n"); + + fclose(f); + log_info("Wrote %s.ini to \"%s\"", name, path); + return true; +} + + /* ----------------------------------------------------------------------- * compose_gen_write_node_ini * ----------------------------------------------------------------------- */ @@ -249,6 +881,7 @@ bool compose_gen_write_node_ini(const TestCluster *cluster, const TestFormation *formation, const TestNode *node, + int nodeId, const char *dir) { char path[1024]; @@ -281,23 +914,46 @@ compose_gen_write_node_ini(const TestCluster *cluster, "\n" "[node]\n" "kind = %s\n" + "name = %s\n" "hostname = %s\n" "port = %d\n", node->name, formation->name, kindStr, node->name, + node->name, pg_port); if (node->debianCluster[0]) fprintf(f, "debian_cluster = %s\n", node->debianCluster); - fprintf(f, - "\n" - "[postgresql]\n" - "pgdata = " NODE_PGDATA "\n" - "\n"); + if (node->debianCluster[0]) + fprintf(f, + "\n" + "[postgresql]\n" + "pgdata = " DEBIAN_PGDATA_PREFIX "/%s/%s\n" + "\n", + debian_pg_version(), node->debianCluster); + else + fprintf(f, + "\n" + "[postgresql]\n" + "pgdata = " NODE_PGDATA "\n" + "\n"); - if (!node->noMonitor) + if (node->noMonitor) + { + fprintf(f, "[monitor]\nno_monitor = true\n"); + if (nodeId > 0) + fprintf(f, "node_id = %d\n", nodeId); + fprintf(f, "\n"); + } + else if (cluster->monitorPassword[0]) + fprintf(f, + "[monitor]\n" + "pguri = postgresql://autoctl_node:%s@monitor/pg_auto_failover\n" + "\n", + cluster->monitorPassword); + else fprintf(f, "[monitor]\n" "pguri = " MONITOR_PGURI "\n" @@ -316,10 +972,15 @@ compose_gen_write_node_ini(const TestCluster *cluster, node->candidatePriority, node->replicationQuorum ? "true" : "false"); - if (node->citusSecondary) - fprintf(f, "citus_secondary = true\n"); - if (node->citusClusterName[0]) - fprintf(f, "citus_cluster_name = %s\n", node->citusClusterName); + /* Citus role/cluster settings live in their own [citus] section */ + if (node->citusSecondary || node->citusClusterName[0]) + { + fprintf(f, "\n[citus]\n"); + if (node->citusSecondary) + fprintf(f, "role = secondary\n"); + if (node->citusClusterName[0]) + fprintf(f, "cluster_name = %s\n", node->citusClusterName); + } fprintf(f, "\n" @@ -331,8 +992,62 @@ compose_gen_write_node_ini(const TestCluster *cluster, eff_auth, node->noMonitor ? "false" : "true"); + if (ssl_needs_certs(eff_ssl)) + fprintf(f, + "\n" + "[ssl]\n" + "ca_file = " SSL_DIR_IN_CONTAINER "/ca.crt\n" + /* + * The server cert/key are copied from the read-only bind-mount to + * /var/lib/postgres/ (the volume root, writable by the container + * user) in the start command so the key is owned by the container + * user and PostgreSQL can open it. + */ + "cert_file = /var/lib/postgres/server.crt\n" + "key_file = /var/lib/postgres/server.key\n"); + if (node->listen) fprintf(f, "listen = 0.0.0.0\n"); + if (node->launchDeferred) + fprintf(f, "\n[launch]\nmode = deferred\n"); + + /* + * Write pg_auto_failover role passwords when configured. The + * replication.password key already exists in the [replication] section; + * monitor_password and the cluster-level autoctl_node_password go into a + * dedicated [pg_auto_failover] section so that pg_autoctl picks them up + * via the new OPTION_AUTOCTL_NODE_PASSWORD / OPTION_AUTOCTL_MONITOR_PASSWORD + * ini options. + */ + { + const char *eff_monitor_pw = + node->monitorPassword[0] ? node->monitorPassword : ""; + const char *eff_replication_pw = + node->replicationPassword[0] ? node->replicationPassword : ""; + + /* + * cluster->monitorPassword is the autoctl_node password on the monitor. + * It is already embedded in the monitor URI above; it does not belong + * in the node's own [pg_auto_failover] section. + * + * node->monitorPassword is the pgautofailover_monitor health-check role + * password on this data node — set by the monitor when it connects to + * run health checks. + */ + if (eff_replication_pw[0]) + fprintf(f, + "\n" + "[replication]\n" + "password = %s\n", + eff_replication_pw); + + if (eff_monitor_pw[0]) + fprintf(f, + "\n" + "[pg_auto_failover]\n" + "monitor_password = %s\n", + eff_monitor_pw); + } fclose(f); log_info("Wrote %s.ini to \"%s\"", node->name, path); diff --git a/src/bin/pgaftest/compose_gen.h b/src/bin/pgaftest/compose_gen.h index a0612da52..e73774fc4 100644 --- a/src/bin/pgaftest/compose_gen.h +++ b/src/bin/pgaftest/compose_gen.h @@ -12,17 +12,32 @@ #include #include "test_spec.h" +/* + * Generate CA and per-service server certificates in /ssl/ using + * openssl. Only called when cluster->ssl is "verify-ca" or "verify-full". + */ +bool compose_gen_write_ssl_certs(const TestCluster *cluster, + const char *workDir); + /* * Write a docker-compose.yml to `path` for the given cluster spec. - * The monitor's port 5432 is exposed on `monitorHostPort` so the - * test runner can query it directly with libpq. * Returns true on success. */ -bool compose_gen_write(const TestCluster *cluster, +/* cluster is non-const: monitorHostPort is filled in if zero. + * specFile is the absolute path to the .pgaf spec file; it is bind-mounted + * into the pgaftest service at /spec.pgaf. Pass NULL to omit the service. */ +bool compose_gen_write(TestCluster *cluster, const char *path, const char *projectName, - int monitorHostPort, - const char *contextDir); + const char *contextDir, + const char *specFile); + +/* + * Write a pg_autoctl_node.ini for the second (replacement) monitor into `dir`. + * Only called when cluster->secondMonitorName is set. + */ +bool compose_gen_write_second_monitor_ini(const TestCluster *cluster, + const char *dir); /* * Write a pg_autoctl_node.ini file for the monitor node into `dir`. @@ -40,6 +55,7 @@ bool compose_gen_write_monitor_ini(const TestCluster *cluster, bool compose_gen_write_node_ini(const TestCluster *cluster, const TestFormation *formation, const TestNode *node, + int nodeId, const char *dir); /* Return the docker network name for a project */ diff --git a/src/bin/pgaftest/pgaftest b/src/bin/pgaftest/pgaftest index b0d7ee0b8f7fadb07b1122300d9158f38691f965..c21c3397bb53bdef2b01eb547556bcf9963457b3 100755 GIT binary patch literal 870648 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 G$5o1z74sqt`) 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