#!/bin/bash
#
# TODO
# * Backup configuration file (at update, too) to some remote site for pgxc_ctl HA feature too.
# * Write output of *_ctl, intdb and intgtm result to log files
# * Write every operation to the log.  Log file can be specified with --l file or --log file
# * Configure log level
# * Switch log		log file
# * Log option to the configuration file so that this can be failed over.
# * Log to a remote server?
# * Multiple log?
#
# Configuration file.   Configuration file can be specified as -c option of
# the command like, or PGXCCONFIG environment variable.  If both are
# not specified, the following configuration file will be used.
#
# Change in the cluster status due to failover will be added to the configuration file so that
# new master can be invoked as the master when restarted.
#
# All such addition will be tagged with proper comment and date/time info.   If you'd like to
# cancel such changes, you can remove or comment-out such additional lines.
#
#
#==========================================================================================================================
#
# Configuration Section
#
#		This section should be in the file $configFile for
#		user's configuration.
#
# Several assumptons:
# 1) configuration file will be set to data directory.
#    configuration file name is fixed to postgresql.conf
# 2) pg_hba.conf will be set to data directory.  File name is
#    fixed to pg_hba.conf
#
#================================================================
# MEMO
#
# max_connections, min_pool_size, max_pool_size --> should be configurable!
# They're not cluster specific.  So we may give a chance to include
# these specific options to be included from external files.
# They should not change by failover so they just have to be
# configured at first time only.
#===============================================================
#
#
#---- Home dir of pgxc_ctl
pgxc_ctl_home=$HOME/.pgxc_ctl
#---- Configuration File
pgxcInstallDir=$HOME/pgxc
configFile=$pgxcInstallDir/pgxcConf
#---- OVERALL -----------------------------------------------------------------------------------------------------------
#
pgxcOwner=pgxc			# owner of the Postgres-XC database cluster.  Here, we use this
						# both as linus user and database user.  This must be
						# the super user of each coordinator and datanode.
pgxcUser=$pgxcOwner		# OS user of Postgres-XC owner

tmpDir=/tmp					# temporary dir used in XC servers
localTmpDir=$tmpDir			# temporary dir used here locally

logOpt=y						# If you want log
logDir=$pgxc_ctl_home/pgxc_ctl_log	# Directory to write pgxc_ctl logs

configBackup=y					# If you want config file backup
configBackupHost=pgxc-linker	# host to backup config file
configBackupDir=$pgxcInstallDir
configBackupFile=`basename $configFile`	# Backup file name --> Need to synchronize when original changed.

#---- GTM --------------------------------------------------------------------------------------------------------------

# GTM is mandatory.  You must have at least (and only) one GTM master in your Postgres-XC cluster.
# If GTM crashes and you need to reconfigure it, you can do it by pgxc_update_gtm command to update
# GTM master with others.   Of course, we provide pgxc_remove_gtm command to remove it.  This command
# will not stop the current GTM.  It is up to the operator.

#---- Overall -------
gtmName=gtm

#---- GTM Master -----------------------------------------------

#---- Overall ----
gtmMasterServer=node13
gtmMasterPort=20001
gtmMasterDir=$HOME/pgxc/nodes/gtm

#---- Configuration ---
gtmExtraConfig=none			# Will be added gtm.conf for both Master and Slave (done at initilization only)
gtmMasterSpecificExtraConfig=none	# Will be added to Master's gtm.conf (done at initialization only)

#---- GTM Slave -----------------------------------------------

# Because GTM is a key component to maintain database consistency, you may want to configure GTM slave
# for backup.

#---- Overall ------
gtmSlave=y					# Specify y if you configure GTM Slave.   Otherwise, GTM slave will not be configured and
							# all the following variables will be reset.
gtmSlaveServer=node12		# value none means GTM slave is not available.  Give none if you don't configure GTM Slave.
gtmSlavePort=20001			# Not used if you don't configure GTM slave.
gtmSlaveDir=$HOME/pgxc/nodes/gtm	# Not used if you don't configure GTM slave.
# Please note that when you have GTM failover, then there will be no slave available until you configure the slave
# again. (pgxc_add_gtm_slave function will handle it)

#---- Configuration ----
gtmSlaveSpecificExtraConfig=none # Will be added to Slave's gtm.conf (done at initialization only)

#---- GTM Proxy -------------------------------------------------------------------------------------------------------
# GTM proxy will be selected based upon which server each component runs on.
# When fails over to the slave, the slave inherits its master's gtm proxy.  It should be
# reconfigured based upon the new location.
#
# To do so, slave should be restarted.   So pg_ctl promote -> (edit postgresql.conf and recovery.conf) -> pg_ctl restart
#
# You don't have to configure GTM Proxy if you dont' configure GTM slave or you are happy if every component connects
# to GTM Master directly.  If you configure GTL slave, you must configure GTM proxy too.

#---- Shortcuts ------
gtmProxyDir=$HOME/pgxc/nodes/gtm_pxy

#---- Overall -------
gtmProxy=y				# Specify y if you conifugre at least one GTM proxy.   You may not configure gtm proxies
						# only when you dont' configure GTM slaves.
						# If you specify this value not to y, the following parameters will be set to default empty values.
						# If we find there're no valid Proxy server names (means, every servers are specified
						# as none), then gtmProxy value will be set to "n" and all the entries will be set to
						# empty values.
gtmProxyNames=(gtm_pxy1 gtm_pxy2 gtm_pxy3 gtm_pxy4)	# No used if it is not configured
gtmProxyServers=(node06 node07 node08 node09)			# Specify none if you dont' configure it.
gtmProxyPorts=(20001 20001 20001 20001)				# Not used if it is not configured.
gtmProxyDirs=($gtmProxyDir $gtmProxyDir $gtmProxyDir $gtmProxyDir)	# Not used if it is not configured.

#---- Configuration ----
gtmPxyExtraConfig=none		# Extra configuration parameter for gtm_proxy
gtmPxySpecificExtraConfig=(none none none none)

#---- Coordinators ----------------------------------------------------------------------------------------------------

#---- shortcuts ----------
coordMasterDir=$HOME/pgxc/nodes/coord
coordSlaveDir=$HOME/pgxc/nodes/coord_slave
coordArchLogDir=$HOME/pgxc/nodes/coord_archlog

#---- Overall ------------
coordNames=(coord1 coord2 coord3 coord4)		# Master and slave use the same name
coordPorts=(20004 20005 20004 20005)			# Master and slave use the same port
poolerPorts=(20010 20011 20010 20011)			# Master and slave use the same pooler port
coordPgHbaEntries=(192.168.1.0/24)				# Assumes that all the coordinator (master/slave) accepts
												# the same connection
												# This entry allows only $pgxcOwner to connect.
												# If you'd like to setup another connection, you should
												# supply these entries through files specified below.
# Note: The above parameter is extracted as "host all all 0.0.0.0/0 trust".   If you don't want
# such setups, specify the value () to this variable and suplly what you want using coordExtraPgHba
# and/or coordSpecificExtraPgHba variables.

#---- Master -------------
coordMasterServers=(node06 node07 node08 node09)		# none means this master is not available
coordMasterDirs=($coordMasterDir $coordMasterDir $coordMasterDir $coordMasterDir)
coordMaxWALsernder=5	# max_wal_senders: needed to configure slave. If zero value is specified,
						# it is expected to supply this parameter explicitly by external files
						# specified in the following.	If you don't configure slaves, leave this value to zero.
coordMaxWALSenders=($coordMaxWALsernder $coordMaxWALsernder $coordMaxWALsernder $coordMaxWALsernder)
						# max_wal_senders configuration for each coordinator.

#---- Slave -------------
coordSlave=y			# Specify y if you configure at least one coordiantor slave.  Otherwise, the following
						# configuration parameters will be set to empty values.
						# If no effective server names are found (that is, every servers are specified as none),
						# then coordSlave value will be set to n and all the following values will be set to
						# empty values.
coordSlaveSync=y		# Specify to connect with synchronized mode.
coordSlaveServers=(node07 node08 node09 node06)			# none means this slave is not available
coordSlaveDirs=($coordSlaveDir $coordSlaveDir $coordSlaveDir $coordSlaveDir)
coordArchLogDirs=($coordArchLogDir $coordArchLogDir $coordArchLogDir $coordArchLogDir)

#---- Configuration files---
# Need these when you'd like setup specific non-default configuration 
# These files will go to corresponding files for the master.
# You may supply your bash script to setup extra config lines and extra pg_hba.conf entries 
# Or you may supply these files manually.
coordExtraConfig=none	# Extra configuration file for coordinators.  This file will be added to all the coordinators'
						# postgresql.conf
coordSpecificExraConfig=(none none none none)
coordExtraPgHba=none	# Extra entry for pg_hba.conf.  This file will be added to all the coordinators' pg_hba.conf
coordSpecificExtraPgHba=(none none none none)

#----- Additional Slaves -----
coordAdditionalSlaves=n		# Additional slave can be specified as follows: where you
coordAdditionalSlaveSet=(cad1)		# Each specifies set of slaves.   This case, two set of slaves are
											# configured
cad1_Sync=n		  		# All the slaves at "cad1" are connected with asynchronous mode.
							# If not, specify "y"
							# The following lines specifies detailed configuration for each
							# slave tag, cad1.  You can define cad2 similarly.
cad1_Servers=(node08 node09 node06 node07)	# Hosts
cad1_dir=$HOME/pgxc/nodes/coord_slave_cad1
cad1_Dirs=($cad1_dir $cad1_dir $cad1_dir $cad1_dir)
cad1_ArchLogDir=$HOME/pgxc/nodes/coord_archlog_cad1
cad1_ArchLogDirs=($cad1_ArchLogDir $cad1_ArchLogDir $cad1_ArchLogDir $cad1_ArchLogDir)


#---- Datanodes -------------------------------------------------------------------------------------------------------

#---- Shortcuts --------------
datanodeMasterDir=$HOME/pgxc/nodes/dn_master
datanodeSlaveDir=$HOME/pgxc/nodes/dn_slave
datanodeArchLogDir=$HOME/pgxc/nodes/datanode_archlog

#---- Overall ---------------
#primaryDatanode=datanode1				# Primary Node.
# At present, xc has a priblem to issue ALTER NODE against the primay node.  Until it is fixed, the test will be done
# without this feature.
primaryDatanode=datanode1				# Primary Node.
datanodeNames=(datanode1 datanode2 datanode3 datanode4)
datanodePorts=(20008 20009 20008 20009)	# Master and slave use the same port!
datanodePgHbaEntries=(192.168.1.0/24)	# Assumes that all the coordinator (master/slave) accepts
										# the same connection
										# This list sets up pg_hba.conf for $pgxcOwner user.
										# If you'd like to setup other entries, supply them
										# through extra configuration files specified below.
# Note: The above parameter is extracted as "host all all 0.0.0.0/0 trust".   If you don't want
# such setups, specify the value () to this variable and suplly what you want using datanodeExtraPgHba
# and/or datanodeSpecificExtraPgHba variables.

#---- Master ----------------
datanodeMasterServers=(node06 node07 node08 node09)	# none means this master is not available.
													# This means that there should be the master but is down.
													# The cluster is not operational until the master is
													# recovered and ready to run.	
datanodeMasterDirs=($datanodeMasterDir $datanodeMasterDir $datanodeMasterDir $datanodeMasterDir)
datanodeMaxWalSender=5								# max_wal_senders: needed to configure slave. If zero value is 
													# specified, it is expected this parameter is explicitly supplied
													# by external configuration files.
													# If you don't configure slaves, leave this value zero.
datanodeMaxWalSenders=($datanodeMaxWalSender $datanodeMaxWalSender $datanodeMaxWalSender $datanodeMaxWalSender)
						# max_wal_senders configuration for each datanode

#---- Slave -----------------
datanodeSlave=y			# Specify y if you configure at least one coordiantor slave.  Otherwise, the following
						# configuration parameters will be set to empty values.
						# If no effective server names are found (that is, every servers are specified as none),
						# then datanodeSlave value will be set to n and all the following values will be set to
						# empty values.
datanodeSlaveServers=(node07 node08 node09 node06)	# value none means this slave is not available
datanodeSlaveDirs=($datanodeSlaveDir $datanodeSlaveDir $datanodeSlaveDir $datanodeSlaveDir)
datanodeArchLogDirs=( $datanodeArchLogDir $datanodeArchLogDir $datanodeArchLogDir $datanodeArchLogDir )

# ---- Configuration files ---
# You may supply your bash script to setup extra config lines and extra pg_hba.conf entries here.
# These files will go to corresponding files for the master.
# Or you may supply these files manually.
datanodeExtraConfig=none	# Extra configuration file for datanodes.  This file will be added to all the 
							# datanodes' postgresql.conf
datanodeSpecificExtraConfig=(none none none none)
datanodeExtraPgHba=none		# Extra entry for pg_hba.conf.  This file will be added to all the datanodes' postgresql.conf
datanodeSpecificExtraPgHba=(none none none none)

#----- Additional Slaves -----
datanodeAdditionalSlaves=n	# Additional slave can be specified as follows: where you
# datanodeAdditionalSlaveSet=(dad1 dad2)		# Each specifies set of slaves.   This case, two set of slaves are
											# configured
# dad1_Sync=n		  		# All the slaves at "cad1" are connected with asynchronous mode.
							# If not, specify "y"
							# The following lines specifies detailed configuration for each
							# slave tag, cad1.  You can define cad2 similarly.
# dad1_Servers=(node08 node09 node06 node07)	# Hosts
# dad1_dir=$HOME/pgxc/nodes/coord_slave_cad1
# dad1_Dirs=($cad1_dir $cad1_dir $cad1_dir $cad1_dir)
# dad1_ArchLogDir=$HOME/pgxc/nodes/coord_archlog_cad1
# dad1_ArchLogDirs=($cad1_ArchLogDir $cad1_ArchLogDir $cad1_ArchLogDir $cad1_ArchLogDir)

#---- WAL archives -------------------------------------------------------------------------------------------------
walArchive=n	# If you'd like to configure WAL archive, edit this section.
				# Pgxc_ctl assumes that if you configure WAL archive, you configure it
				# for all the coordinators and datanodes.
				# Default is "no".   Please specify "y" here to turn it on.
# You can setup more than one backup set for various purposes, such as disaster recovery.
walArchiveSet=(war1 war2)
war1_source=(master)	# you can specify master, slave or ano other additional slaves as a source of WAL archive.
					# Default is the master
wal1_source=(slave)
wal1_source=(additiona_coordinator_slave_set additional_datanode_slave_set)
war1_host=node10	# All the nodes are backed up at the same host for a given archive set
war1_backupdir=$HOME/pgxc/backup_war1
wal2_source=(master)
war2_host=node11
war2_backupdir=$HOME/pgxc/backup_war2
#
#		End of Configuration Section
#
#==========================================================================================================================

# Common variables ######################################################################
xc_prompt='PGXC$ '
interactive=n
verbose=n
progname=$0
bin=pgxc_ctl		# Just in case.  Never touch this
logfile=none

# Create config file template
#
# If you change the structure of configuration file section, you must reflect the change in the part below.
#
function create_config_file_template
{
	cat > $configFile <<EOF
#!/bin/bash
#
# TODO
# * Backup configuration file (at update, too) to some remote site for pgxc_ctl HA feature too.
# * Write output of *_ctl, intdb and intgtm result to log files
# * Write every operation to the log.  Log file can be specified with --l file or --log file
# * Configure log level
# * Switch log		log file
# * Log option to the configuration file so that this can be failed over.
# * Log to a remote server?
# * Multiple log?
#
# Configuration file.   Configuration file can be specified as -c option of
# the command like, or PGXCCONFIG environment variable.  If both are
# not specified, the following configuration file will be used.
#
# Change in the cluster status due to failover will be added to the configuration file so that
# new master can be invoked as the master when restarted.
#
# All such addition will be tagged with proper comment and date/time info.   If you'd like to
# cancel such changes, you can remove or comment-out such additional lines.
#
#
#==========================================================================================================================
#
# Configuration Section
#
#		This section should be in the file $configFile for
#		user's configuration.
#
# Several assumptons:
# 1) configuration file will be set to data directory.
#    configuration file name is fixed to postgresql.conf
# 2) pg_hba.conf will be set to data directory.  File name is
#    fixed to pg_hba.conf
#
#================================================================
# MEMO
#
# max_connections, min_pool_size, max_pool_size --> should be configurable!
# They're not cluster specific.  So we may give a chance to include
# these specific options to be included from external files.
# They should not change by failover so they just have to be
# configured at first time only.
#===============================================================
#
#
#---- Home dir of pgxc_ctl
pgxc_ctl_home=$HOME/.pgxc_ctl
#---- Configuration File
pgxcInstallDir=$HOME/pgxc
configFile=$pgxcInstallDir/pgxcConf
#---- OVERALL -----------------------------------------------------------------------------------------------------------
#
pgxcOwner=pgxc			# owner of the Postgres-XC database cluster.  Here, we use this
						# both as linus user and database user.  This must be
						# the super user of each coordinator and datanode.
pgxcUser=$pgxcOwner		# OS user of Postgres-XC owner

tmpDir=/tmp					# temporary dir used in XC servers
localTmpDir=$tmpDir			# temporary dir used here locally

logOpt=y						# If you want log
logDir=$pgxc_ctl_home/pgxc_ctl_log	# Directory to write pgxc_ctl logs

configBackup=y					# If you want config file backup
configBackupHost=pgxc-linker	# host to backup config file
configBackupDir=$pgxcInstallDir
configBackupFile=`basename $configFile`	# Backup file name --> Need to synchronize when original changed.

#---- GTM --------------------------------------------------------------------------------------------------------------

# GTM is mandatory.  You must have at least (and only) one GTM master in your Postgres-XC cluster.
# If GTM crashes and you need to reconfigure it, you can do it by pgxc_update_gtm command to update
# GTM master with others.   Of course, we provide pgxc_remove_gtm command to remove it.  This command
# will not stop the current GTM.  It is up to the operator.

#---- Overall -------
gtmName=gtm

#---- GTM Master -----------------------------------------------

#---- Overall ----
gtmMasterServer=node13
gtmMasterPort=20001
gtmMasterDir=$HOME/pgxc/nodes/gtm

#---- Configuration ---
gtmExtraConfig=none			# Will be added gtm.conf for both Master and Slave (done at initilization only)
gtmMasterSpecificExtraConfig=none	# Will be added to Master's gtm.conf (done at initialization only)

#---- GTM Slave -----------------------------------------------

# Because GTM is a key component to maintain database consistency, you may want to configure GTM slave
# for backup.

#---- Overall ------
gtmSlave=y					# Specify y if you configure GTM Slave.   Otherwise, GTM slave will not be configured and
							# all the following variables will be reset.
gtmSlaveServer=node12		# value none means GTM slave is not available.  Give none if you don't configure GTM Slave.
gtmSlavePort=20001			# Not used if you don't configure GTM slave.
gtmSlaveDir=$HOME/pgxc/nodes/gtm	# Not used if you don't configure GTM slave.
# Please note that when you have GTM failover, then there will be no slave available until you configure the slave
# again. (pgxc_add_gtm_slave function will handle it)

#---- Configuration ----
gtmSlaveSpecificExtraConfig=none # Will be added to Slave's gtm.conf (done at initialization only)

#---- GTM Proxy -------------------------------------------------------------------------------------------------------
# GTM proxy will be selected based upon which server each component runs on.
# When fails over to the slave, the slave inherits its master's gtm proxy.  It should be
# reconfigured based upon the new location.
#
# To do so, slave should be restarted.   So pg_ctl promote -> (edit postgresql.conf and recovery.conf) -> pg_ctl restart
#
# You don't have to configure GTM Proxy if you dont' configure GTM slave or you are happy if every component connects
# to GTM Master directly.  If you configure GTL slave, you must configure GTM proxy too.

#---- Shortcuts ------
gtmProxyDir=$HOME/pgxc/nodes/gtm_pxy

#---- Overall -------
gtmProxy=y				# Specify y if you conifugre at least one GTM proxy.   You may not configure gtm proxies
						# only when you dont' configure GTM slaves.
						# If you specify this value not to y, the following parameters will be set to default empty values.
						# If we find there're no valid Proxy server names (means, every servers are specified
						# as none), then gtmProxy value will be set to "n" and all the entries will be set to
						# empty values.
gtmProxyNames=(gtm_pxy1 gtm_pxy2 gtm_pxy3 gtm_pxy4)	# No used if it is not configured
gtmProxyServers=(node06 node07 node08 node09)			# Specify none if you dont' configure it.
gtmProxyPorts=(20001 20001 20001 20001)				# Not used if it is not configured.
gtmProxyDirs=($gtmProxyDir $gtmProxyDir $gtmProxyDir $gtmProxyDir)	# Not used if it is not configured.

#---- Configuration ----
gtmPxyExtraConfig=none		# Extra configuration parameter for gtm_proxy
gtmPxySpecificExtraConfig=(none none none none)

#---- Coordinators ----------------------------------------------------------------------------------------------------

#---- shortcuts ----------
coordMasterDir=$HOME/pgxc/nodes/coord
coordSlaveDir=$HOME/pgxc/nodes/coord_slave
coordArchLogDir=$HOME/pgxc/nodes/coord_archlog

#---- Overall ------------
coordNames=(coord1 coord2 coord3 coord4)		# Master and slave use the same name
coordPorts=(20004 20005 20004 20005)			# Master and slave use the same port
poolerPorts=(20010 20011 20010 20011)			# Master and slave use the same pooler port
coordPgHbaEntries=(192.168.1.0/24)				# Assumes that all the coordinator (master/slave) accepts
												# the same connection
												# This entry allows only $pgxcOwner to connect.
												# If you'd like to setup another connection, you should
												# supply these entries through files specified below.
# Note: The above parameter is extracted as "host all all 0.0.0.0/0 trust".   If you don't want
# such setups, specify the value () to this variable and suplly what you want using coordExtraPgHba
# and/or coordSpecificExtraPgHba variables.

#---- Master -------------
coordMasterServers=(node06 node07 node08 node09)		# none means this master is not available
coordMasterDirs=($coordMasterDir $coordMasterDir $coordMasterDir $coordMasterDir)
coordMaxWALsernder=5	# max_wal_senders: needed to configure slave. If zero value is specified,
						# it is expected to supply this parameter explicitly by external files
						# specified in the following.	If you don't configure slaves, leave this value to zero.
coordMaxWALSenders=($coordMaxWALsernder $coordMaxWALsernder $coordMaxWALsernder $coordMaxWALsernder)
						# max_wal_senders configuration for each coordinator.

#---- Slave -------------
coordSlave=y			# Specify y if you configure at least one coordiantor slave.  Otherwise, the following
						# configuration parameters will be set to empty values.
						# If no effective server names are found (that is, every servers are specified as none),
						# then coordSlave value will be set to n and all the following values will be set to
						# empty values.
coordSlaveSync=y		# Specify to connect with synchronized mode.
coordSlaveServers=(node07 node08 node09 node06)			# none means this slave is not available
coordSlaveDirs=($coordSlaveDir $coordSlaveDir $coordSlaveDir $coordSlaveDir)
coordArchLogDirs=($coordArchLogDir $coordArchLogDir $coordArchLogDir $coordArchLogDir)

#---- Configuration files---
# Need these when you'd like setup specific non-default configuration 
# These files will go to corresponding files for the master.
# You may supply your bash script to setup extra config lines and extra pg_hba.conf entries 
# Or you may supply these files manually.
coordExtraConfig=none	# Extra configuration file for coordinators.  This file will be added to all the coordinators'
						# postgresql.conf
coordSpecificExraConfig=(none none none none)
coordExtraPgHba=none	# Extra entry for pg_hba.conf.  This file will be added to all the coordinators' pg_hba.conf
coordSpecificExtraPgHba=(none none none none)

#----- Additional Slaves -----
coordAdditionalSlaveSet=n	# Additional slave can be specified as follows: where you
# coordAdditionalSlaveSet=(cad1 cad2)		# Each specifies set of slaves.   This case, two set of slaves are
											# configured
# cad1_Sync=n		  		# All the slaves at "cad1" are connected with asynchronous mode.
							# If not, specify "y"
							# The following lines specifies detailed configuration for each
							# slave tag, cad1.  You can define cad2 similarly.
# cad1_Servers=(node08 node09 node06 node07)	# Hosts
# cad1_dir=$HOME/pgxc/nodes/coord_slave_cad1
# cad1_Dirs=($cad1_dir $cad1_dir $cad1_dir $cad1_dir)
# cad1_ArchLogDir=$HOME/pgxc/nodes/coord_archlog_cad1
# cad1_ArchLogDirs=($cad1_ArchLogDir $cad1_ArchLogDir $cad1_ArchLogDir $cad1_ArchLogDir)


#---- Datanodes -------------------------------------------------------------------------------------------------------

#---- Shortcuts --------------
datanodeMasterDir=$HOME/pgxc/nodes/dn_master
datanodeSlaveDir=$HOME/pgxc/nodes/dn_slave
datanodeArchLogDir=$HOME/pgxc/nodes/datanode_archlog

#---- Overall ---------------
#primaryDatanode=datanode1				# Primary Node.
# At present, xc has a priblem to issue ALTER NODE against the primay node.  Until it is fixed, the test will be done
# without this feature.
primaryDatanode=datanode1				# Primary Node.
datanodeNames=(datanode1 datanode2 datanode3 datanode4)
datanodePorts=(20008 20009 20008 20009)	# Master and slave use the same port!
datanodePgHbaEntries=(192.168.1.0/24)	# Assumes that all the coordinator (master/slave) accepts
										# the same connection
										# This list sets up pg_hba.conf for $pgxcOwner user.
										# If you'd like to setup other entries, supply them
										# through extra configuration files specified below.
# Note: The above parameter is extracted as "host all all 0.0.0.0/0 trust".   If you don't want
# such setups, specify the value () to this variable and suplly what you want using datanodeExtraPgHba
# and/or datanodeSpecificExtraPgHba variables.

#---- Master ----------------
datanodeMasterServers=(node06 node07 node08 node09)	# none means this master is not available.
													# This means that there should be the master but is down.
													# The cluster is not operational until the master is
													# recovered and ready to run.	
datanodeMasterDirs=($datanodeMasterDir $datanodeMasterDir $datanodeMasterDir $datanodeMasterDir)
datanodeMaxWalSender=5								# max_wal_senders: needed to configure slave. If zero value is 
													# specified, it is expected this parameter is explicitly supplied
													# by external configuration files.
													# If you don't configure slaves, leave this value zero.
datanodeMaxWalSenders=($datanodeMaxWalSender $datanodeMaxWalSender $datanodeMaxWalSender $datanodeMaxWalSender)
						# max_wal_senders configuration for each datanode

#---- Slave -----------------
datanodeSlave=y			# Specify y if you configure at least one coordiantor slave.  Otherwise, the following
						# configuration parameters will be set to empty values.
						# If no effective server names are found (that is, every servers are specified as none),
						# then datanodeSlave value will be set to n and all the following values will be set to
						# empty values.
datanodeSlaveServers=(node07 node08 node09 node06)	# value none means this slave is not available
datanodeSlaveDirs=($datanodeSlaveDir $datanodeSlaveDir $datanodeSlaveDir $datanodeSlaveDir)
datanodeArchLogDirs=( $datanodeArchLogDir $datanodeArchLogDir $datanodeArchLogDir $datanodeArchLogDir )

# ---- Configuration files ---
# You may supply your bash script to setup extra config lines and extra pg_hba.conf entries here.
# These files will go to corresponding files for the master.
# Or you may supply these files manually.
datanodeExtraConfig=none	# Extra configuration file for datanodes.  This file will be added to all the 
							# datanodes' postgresql.conf
datanodeSpecificExtraConfig=(none none none none)
datanodeExtraPgHba=none		# Extra entry for pg_hba.conf.  This file will be added to all the datanodes' postgresql.conf
datanodeSpecificExtraPgHba=(none none none none)

#----- Additional Slaves -----
datanodeAdditionalSlaveSet=n	# Additional slave can be specified as follows: where you
# datanodeAdditionalSlaveSet=(dad1 dad2)		# Each specifies set of slaves.   This case, two set of slaves are
											# configured
# dad1_Sync=n		  		# All the slaves at "cad1" are connected with asynchronous mode.
							# If not, specify "y"
							# The following lines specifies detailed configuration for each
							# slave tag, cad1.  You can define cad2 similarly.
# dad1_Servers=(node08 node09 node06 node07)	# Hosts
# dad1_dir=$HOME/pgxc/nodes/coord_slave_cad1
# dad1_Dirs=($cad1_dir $cad1_dir $cad1_dir $cad1_dir)
# dad1_ArchLogDir=$HOME/pgxc/nodes/coord_archlog_cad1
# dad1_ArchLogDirs=($cad1_ArchLogDir $cad1_ArchLogDir $cad1_ArchLogDir $cad1_ArchLogDir)

#---- WAL archives -------------------------------------------------------------------------------------------------
walArchive=n	# If you'd like to configure WAL archive, edit this section.
				# Pgxc_ctl assumes that if you configure WAL archive, you configure it
				# for all the coordinators and datanodes.
				# Default is "no".   Please specify "y" here to turn it on.
# You can setup more than one backup set for various purposes, such as disaster recovery.
walArchiveSet=(war1 war2)
war1_source=master	# you can specify master, slave or ano other additional slaves as a source of WAL archive.
					# Default is the master
wal1_source=slave
wal1_source=(additiona_coordinator_slave_set additional_datanode_slave_set)
war1_host=node10	# All the nodes are backed up at the same host for a given archive set
war1_backupdir=$HOME/pgxc/backup_war1
wal2_source=master
war2_host=node11
war2_backupdir=$HOME/pgxc/backup_war2
#
#		End of Configuration Section
#
#==========================================================================================================================
EOF
	chmod +x $configFile
}


#===========================================================
#
# Extract parsed configuration values
#
#===========================================================

# $1 is variable name of the array to print
function print_array
{
	echo -n $1 " "
	eval echo '$'{$1[@]}
}


function print_values
{
	local i
	declare -i i
	local el

	# Home
	echo pgxc_ctl_home $pgxc_ctl_home
	echo pgxcInstallDir $pgxcInstallDir
	echo configFile $configFile

	# Overall
	echo pgxcOwner $pgxcOwner
	echo pgxcUser $pgxcUser
	echo tmpDir $tmpDir
	echo localTmpDir $localTmpDir
	echo logOpt $logOpt
	echo logDir $logDir
	echo configBackup $configBackup
	echo configBackupHost $configBackupHost
	echo configBackupDir $configBackupDir
	echo configBackupFile $configBackupFile

	# GTM overall
	echo gtmName $gtmName

	# GTM master
	echo gtmMasterServer $gtmMasterServer
	echo gtmMasterPort $gtmMasterPort
	echo gtmMasterDir $gtmMasterDir
	echo gtmExtraConfig $gtmExtraConfig
	echo gtmMasterSpecificExtraConfig $gtmMasterSpecificExtraConfig

	# GTM slave
	echo gtmSlave $gtmSlave
	echo gtmSlaveServer $gtmSlaveServer
	echo gtmSlavePort $gtmSlavePort
	echo gtmSlaveDir $gtmSlaveDir
	echo gtmSlaveSpecificExtraConfig $gtmSlaveSpecificExtraConfig

	# GTM Proxy
	echo gtmProxy $gtmProxy
	print_array gtmProxyNames
	print_array gtmProxyServers
	print_array gtmProxyPorts
	print_array gtmProxyDirs
	echo gtmPxyExtraConfig $gtmPxyExtraConfig
	print_array gtmPxySpecificExtraConfig

	# Coordinators overall
	print_array coordNames
	print_array coordPorts
	print_array poolerPorts
	print_array coordPgHbaEntries

	# Coordinators master
	print_array coordMasterServers
	print_array coordMasterDirs
	print_array coordMaxWALSenders

	# Coordinators slave
	echo coordSlave $coordSlave
	echo coordSlaveSync $coordSlaveSync
	print_array coordSlaveDirs
	print_array coordArchLogDirs

	# Coordinator Configuration files
	echo coordExtraConfig $coordExtraConfig
	print_array coordSpecificExraConfig
	echo coordExtraPgHba $coordExtraPgHba
	print_array coordSpecificExtraPgHba

	# Coordinator Additional Slaves
	echo coordAdditionalSlaves $coordAdditionalSlaves
	if [ $coordAdditionalSlaves == "y" ]; then
		print_array coordAdditionalSlaveSet
		for ((i=0; i<${#coordAdditionalSlaveSet[@]}; i++)); do
			el=${coordAdditionalSlaveSet[$i]}
			echo -n ${el}_Sync " "
			eval echo '$'"$el"_Sync
			print_array ${el}_Servers
			print_array ${el}_Dirs
			print_array ${el}_ArchLogDirs
		done
	fi

	# Datanodes overall
	echo primaryDatanode $primaryDatanode
	print_array datanodeNames
	print_array datanodePorts
	print_array datanodePgHbaEntries
	
	# Datanodes masters
	print_array datanodeMasterServers
	print_array datanodeMasterDirs
	print_array datanodeMaxWalSenders
	
	# Datanodes slaves
	echo datanodeSlave $datanodeSlave
	print_array datanodeSlaveServers
	print_array datanodeSlaveDirs
	print_array datanodeArchLogDirs

	# Datanode configuration files
	echo datanodeExtraConfig $datanodeExtraConfig
	print_array datanodeSpecificExtraConfig
	echo datanodeExtraPgHba $datanodeExtraPgHba
	print_array datanodeSpecificExtraPgHba

	# Datanodes additional slaves
	echo datanodeAdditionalSlaves $datanodeAdditionalSlaves
	if [ $datanodeAdditionalSlaves == "y" ]; then
		print_array datanodeAdditionalSlaveSet
		for ((i=0; i<${#datanodeAdditionalSlaveSet[@]}; i++)); do
			el=${datanodeAdditionalSlaveSet[$i]}
			echo -n ${el}_Sync " "
			eval echo '$'"$el"_Sync
			print_array ${el}_Servers
			print_array ${el}_Dirs
			print_array ${el}_ArchLogDirs
		done
	fi
	
	# WAL Archives
	echo walArchive $walArchive
	print_array walArchiveSet
	if [ $walArchive == "y" ]; then
		for ((i=0; i<${#walArchvieSet[@]}; i++)); do
			print_array ${el}_source
			echo -n ${el}_host
			eval echo '$'"$el"_host
			echo -n ${el}_backupdir
			eval echo '$'"$el"_backupdir
		done
	fi

	# Other options
	echo xc_prompt $xc_prompt
	echo verbose $verbose
	echo bin $bin
}



#============================================================
#
# Common functions
#
#============================================================

# Optionally $1 will be $PGXC_CTL_HOME settings.
function set_home
{
	if [ $# > 1 ]; then
		echo "Invalid set_home function call"
		return 1
	fi
	if [ $# == 1 ]; then
		if [ -d $1 ]; then
			pgxc_ctl_home=$1
		else
			eecho "set_home: $1 is not a directory."
			return 1
		fi
	elif [ $PGXC_CTL_HOME != "" ]; then
		if [ -d $PGXC_CTL_HOME ]; then
			pgxc_ctl_home=$PGXC_CTL_HOME
		else
			eecho "set_home: env PGXC_CTL_HOME($PGXC_CTL_HOME) is not a directory."
			return 1;
		fi
	fi
	cd $pgxc_ctl_home;
}

###############################################################################
#
#   EXECUTING SECTION
#
###############################################################################

#=======================================================
# Things to be done at first
#=======================================================

# Handle options
progname=$0
moretodo=y
cmd_with_log=null
#set_home
if [ -f $pgxc_ctl_home/.pgxc_ctl_rc ]; then
	source $pgxc_ctl_home/.pgxc_ctl_rc
fi

while [ $moretodo == y ]; do
	if [ $# -gt 0 ]; then
		case $1 in
			-v )
				shift;
				verbose=y;
				continue;;
			--verbose )
				shift;
				verbose=y;
				continue;;
			--silent )
				verbose=n;
				continue;;
			-d ) # debug option
				shift;
				DEBUG=y;
				continue;;
			--debug )
				shift;
				DEBUG=y;
				continue;;
			-c ) # Configuraton file
				shift;
				if [ $# -le 0 ]; then
					echo ERROR: no -c option value found
					exit 1
				else
					configFile=$1
					shift
				fi;
				continue;;
			--configuration ) # Configuraion file
				shift;
				if [ $# -le 0 ]; then
					echo ERROR: no --configuration option value found
					exit 1
				else
					configFile=$1
					shift
				fi;
				continue;;
			--home ) # PGXC_CTL_HOME
				shift;
				if [ $# -le 0 ]; then
					echo ERROR: no pgxc_ctl_home specified
					exit 1
				else
					pgxc_ctl_home=$1
					cd $pgxc_ctl_home
					shift
				fi;
				continue;;
			* )
				moretodo=n
				continue;;
		esac
	else
		moretodo=n
	fi
done

# Read configuration file --> Should be activated only when debug option is off
if [ -f $configFile ]; then
	source $configFile
fi
# Log option can be overriden by command-line option

print_values

