Several improvement and refactoring, especially in status.php.
authorNozomi Anzai <anzai@sraoss.co.jp>
Mon, 13 May 2013 06:05:24 +0000 (15:05 +0900)
committerNozomi Anzai <anzai@sraoss.co.jp>
Mon, 13 May 2013 06:05:24 +0000 (15:05 +0900)
Now in status.php we can add a new backend, remove a backend, stop/reload start PostgreSQL, and know each watchdog statuses.

33 files changed:
command.php
common.php
innerLog.php
innerNodeServerStatus.php
innerSystemCatalog.php
innerWatchdog.php [new file with mode: 0644]
lang/en.lang.php
lang/ja.lang.php
login.php
nodeServerStatus.php
nodeStatus.php
pgconfig.php
screen.css
status.php
templates/elements/pgconfig_new_backend.tpl [new file with mode: 0644]
templates/elements/status_js.tpl [new file with mode: 0644]
templates/elements/status_nodeinfo.tpl [new file with mode: 0644]
templates/elements/status_options.tpl [new file with mode: 0644]
templates/elements/status_pgsql_buttons.tpl [new file with mode: 0644]
templates/elements/status_pgsql_options.tpl [new file with mode: 0644]
templates/elements/status_start_option.tpl [new file with mode: 0644]
templates/elements/status_stop_option.tpl [new file with mode: 0644]
templates/innerLog.tpl
templates/innerNodeServerStatus.tpl
templates/innerSummary.tpl
templates/innerSystemCatalog.tpl
templates/innerWatchdog.tpl [new file with mode: 0644]
templates/menu.tpl
templates/nodeServerStatus.tpl
templates/nodeStatus.tpl
templates/pgconfig.tpl
templates/procInfo.tpl
templates/status.tpl

index ce64a80f7004049e5abcbbea4c0d6f697dcdced9..bde8f10a95ce3d54e42f35b797bb27d408171c4e 100644 (file)
  * is" without express or implied warranty.
  *
  * @author     Ryuma Ando <ando@ecomas.co.jp>
- * @copyright  2003-2009 PgPool Global Development Group
+ * @copyright  2003-2013 PgPool Global Development Group
  * @version    CVS: $Id$
  */
 
 require_once('common.php');
 
-// timeout seconds
-// (The parameter "pcp_timeout" existed till V3.0.)
-define('PCP_TIMEOUT', 10);
-
 /**
  * Execute pcp command
  *
@@ -170,4 +166,46 @@ function readPcpInfo()
     $params = readConfigParams(array('pcp_port'));
     return $params;
 }
+
+/** Get node count */
+function getNodeCount()
+{
+    global $tpl;
+
+    $result = execPcp('PCP_NODE_COUNT');
+
+    if (!array_key_exists('SUCCESS', $result)) {
+        $errorCode = 'e1002';
+        $tpl->assign('errorCode', $errorCode);
+        $tpl->display('innerError.tpl');
+        exit();
+    }
+
+    return $result['SUCCESS'];
+}
+
+/** Get info of the specified node */
+function getNodeInfo($i)
+{
+    global $tpl;
+
+    // execute "pcp_node_info" command
+    // ex) host1 5432 1 1073741823.500000
+    $result = execPcp('PCP_NODE_INFO', $i);
+
+    if (!array_key_exists('SUCCESS', $result)) {
+        $errorCode = 'e1003';
+        $tpl->assign('errorCode', $errorCode);
+        $tpl->display('innerError.tpl');
+        exit();
+    }
+
+    $arr = explode(" ", $result['SUCCESS']);
+    $rtn['hostname'] = $arr[0];
+    $rtn['port']     = $arr[1];
+    $rtn['status']   = $arr[2];
+    $rtn['weight']   = sprintf('%.3f', $arr[3]);
+
+    return $rtn;
+}
 ?>
index 302fb30e061eaa180ddc856a8f0df097c9f26be1..1cddd7bc5bf8d8b2da2ab62daae425ecb75acb09 100644 (file)
 
 require_once('version.php');
 require_once('libs/Smarty.class.php');
+require_once('bootstrap.php');
 error_reporting(E_ALL);
 
-define('SESSION_LOGIN_USER',          'loginUser');
-define('SESSION_LOGIN_USER_PASSWORD', 'md5pass');
-define('SESSION_LANG',                'lang');
-define('SESSION_MESSAGE',             'message');
-
 function versions()
 {
     return array('3.2', '3.1', '3.0',
@@ -40,12 +36,6 @@ function versions()
 
 session_start();
 
-/**
- * Smarty Parameter
- */
-define('SMARTY_TEMPLATE_DIR', dirname(__FILE__) . '/templates' );
-define('SMARTY_COMPILE_DIR', dirname(__FILE__) . '/templates_c' );
-
 /**
  * Initialize Smartry
  */
@@ -269,13 +259,13 @@ function NodeStandby($num)
         return -1;
     }
 
-    $res = pg_query($conn, 'SELECT pg_is_in_recovery()');
-    if (!pg_result_status($res) == PGSQL_TUPLES_OK) {
+    $result = pg_query($conn, 'SELECT pg_is_in_recovery()');
+    if (!pg_result_status($result) == PGSQL_TUPLES_OK) {
         @pg_close($conn);
         return -1;
     }
 
-    $rr = pg_fetch_array($res);
+    $rr = pg_fetch_array($result);
 
     if ($rr[0][0] == 't') {
         $r = 1;
@@ -283,7 +273,7 @@ function NodeStandby($num)
         $r = 0;
     }
 
-    @pg_free_result($res);
+    @pg_free_result($result);
     @pg_close($conn);
     return $r;
 }
@@ -308,13 +298,13 @@ function conStr($num, $mode = NULL)
                     $params['health_check_password'] : NULL;
     }
 
-    // backkend info
+    // backend info
     $params = readConfigParams(array('backend_hostname',
                                      'backend_port',
                                      'backend_weight'));
     $conStr = array();
     if ($params['backend_hostname'][$num] != '') {
-        $conStr[] = "host={$params['backend_hostname'][$num]} ";
+        $conStr[] = "host='{$params['backend_hostname'][$num]}'";
     }
     $conStr[] = "port='{$params['backend_port'][$num]}'";
     $conStr[] = "dbname='template1'";
@@ -657,4 +647,53 @@ function paramExists($param)
     }
     return FALSE;
 }
-?>
+
+/* Get if loginUser is super user */
+function isSuperUser($user_name)
+{
+    if (DoesPgpoolPidExist() && isset($_SESSION[SESSION_IS_SUPER_USER])) {
+        return $_SESSION[SESSION_IS_SUPER_USER];
+    }
+    $conn = @pg_connect(conStrPgpool());
+
+    if ($conn == FALSE) {
+        @pg_close($conn);
+        return NULL;
+    }
+
+    $result = pg_query($conn, "SELECT usesuper FROM pg_user WHERE usename = '{$user_name}'");
+
+   if (!pg_result_status($result) == PGSQL_TUPLES_OK) {
+        @pg_close($conn);
+        return NULL;
+    }
+
+    $rr = pg_fetch_array($result);
+    $rtn = (isset($rr['usesuper']) && $rr['usesuper'] == 't');
+
+    @pg_free_result($result);
+    @pg_close($conn);
+
+     $_SESSION[SESSION_IS_SUPER_USER] = $rtn;
+    return $rtn;
+}
+
+function conStrPgpool()
+{
+    $params = readConfigParams(array('port'));
+    $conStr[] = "port='{$params['port']}'";
+    $conStr[] = "dbname='template1'";
+    $conStr[] = "user='{$_SESSION[SESSION_LOGIN_USER]}'";
+    $conStr[] = "password='{$_SESSION[SESSION_LOGIN_USER_PASSWORD]}'";
+
+    $conStr = implode($conStr, ' ');
+    return $conStr;
+}
+
+/* for debug */
+function pr($array)
+{
+    echo '<pre>';
+    print_r($array);
+    echo '</pre>';
+}
index 54ed27b2dd333b9aaad336bebc3b80e410c1d22b..9bac2fe5134e3f41a26900b9a57a37dd0c609763 100644 (file)
@@ -60,6 +60,7 @@ for ($i = 0; $i < count($logFile); $i++) {
     $logFile[$i]['message'] = trim($logFile[$i]['message']);
 }
 
+$tpl->assign('refreshTimeLog', REFRESH_LOG_SECONDS);
 $tpl->assign('logFile', $logFile);
 $tpl->display('innerLog.tpl');
 ?>
index 12b6c98e4adf71459b119fcebab57ad13a8eae79..f42db35eb3f02c98717a4d96dfd27571618eae3f 100644 (file)
  * is" without express or implied warranty.
  *
  * @author     Ryuma Ando <ando@ecomas.co.jp>
- * @copyright  2003-2012 PgPool Global Development Group
+ * @copyright  2003-2013 PgPool Global Development Group
  * @version    CVS: $Id$
  */
 
 require_once('common.php');
+require_once('command.php');
 
+/* --------------------------------------------------------------------- */
+/* InnerNodeServerStatus.php                                             */
+/* --------------------------------------------------------------------- */
+
+// Check login status
 if (!isset($_SESSION[SESSION_LOGIN_USER])) {
     exit();
 }
 
-$params = readConfigParams('backend_hostname');
+// Get backend info
+$params = readConfigParams(array('backend_hostname', 'backend_port'));
 if (isset($params['backend_hostname'])) {
     $backendHostName = $params['backend_hostname'];
     $backendPort     = $params['backend_port'];
 
 } else {
     $backendHostName = array();
+    $backendHostPort = array();
 }
 
-$result = array();
+$is_pgpool_active = DoesPgpoolPidExist();
+$nodeInfo = array();
 foreach($backendHostName as $num => $hostname) {
-    $result[$num]['hostname'] = $backendHostName[$num];
-    $result[$num]['port']     = $backendPort[$num];
+    $nodeInfo[$num]['hostname'] = $backendHostName[$num];
+    $nodeInfo[$num]['port']     = $backendPort[$num];
+    $nodeInfo[$num]['is_active'] = NodeActive($num);
 
-    if (NodeActive($num)) {
-        $result[$num]['status'] = TRUE;
-    } else {
-        $result[$num]['status'] = FALSE;
+    if ($is_pgpool_active) {
+        $result = getNodeInfo($num);
+        $nodeInfo[$num]['status'] = $result['status'];
     }
 }
 
-$tpl->assign('nodeServerStatus', $result);
-$tpl->assign('nodeCount', count($result));
-$tpl->display('innerNodeServerStatus.tpl');
+// Get node num
+$nodeNum = (isset($_GET['num'])) ? $_GET['num'] : NULL;
 
-?>
+// Set vars
+$tpl->assign('pgpoolIsActive',   $is_pgpool_active);
+$tpl->assign('nodeServerStatus', $nodeInfo);
+$tpl->assign('nodeCount',        count($nodeInfo));
+$tpl->assign('nodeNum',          $nodeNum);
+$tpl->assign('refreshTime',      (0 <= _PGPOOL2_STATUS_REFRESH_TIME) ?
+                                 _PGPOOL2_STATUS_REFRESH_TIME * 1000 : 5000);
+
+// Display
+$tpl->display('innerNodeServerStatus.tpl');
index 0a679467b15d4cbc370040b5bff6183b2e013abb..f1b3f723c3349edb8f923317232de830e6456e60 100644 (file)
  * is" without express or implied warranty.
  *
  * @author     Ryuma Ando <ando@ecomas.co.jp>
- * @copyright  2003-2008 PgPool Global Development Group
+ * @copyright  2003-2013 PgPool Global Development Group
  * @version    CVS: $Id$
  */
 
 require_once('common.php');
 
+/* --------------------------------------------------------------------- */
+/* InnerSystemCatalog.php                                                */
+/* --------------------------------------------------------------------- */
+
+// Check login status
 if (!isset($_SESSION[SESSION_LOGIN_USER])) {
     exit();
 }
 
+// Get node num
 $pgCatalog = pg_escape_string($_GET['catalog']);
 $nodeNum = $_GET['num'];
 
@@ -37,10 +43,7 @@ if ($pgCatalog == '') {
 }
 
 // Set Parameters
-$params = readConfigParams();
-
-$tpl->assign('hostname', $params['backend_hostname'][$nodeNum]);
-$tpl->assign('port',     $params['backend_port'][$nodeNum]);
+$params = readConfigParams(array('backend_hostname', 'backend_port'));
 
 // Get Data From Database
 $conn = @pg_connect(conStr($nodeNum));
@@ -68,8 +71,11 @@ $results = pg_fetch_all($rs);
 
 closeDBConnection($conn);
 
-// Show
+// Set vars
+$tpl->assign('hostname', $params['backend_hostname'][$nodeNum]);
+$tpl->assign('port',     $params['backend_port'][$nodeNum]);
 $tpl->assign('results', $results);
-$tpl->display('innerSystemCatalog.tpl');
+$tpl->assign('nodeNum', $nodeNum);
 
-?>
+// Display
+$tpl->display('innerSystemCatalog.tpl');
diff --git a/innerWatchdog.php b/innerWatchdog.php
new file mode 100644 (file)
index 0000000..cec0e2c
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Infomation of the pgpool summary
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear in all
+ * copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of the
+ * author not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The author makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * @author     Ryuma Ando <ando@ecomas.co.jp>
+ * @copyright  2003-2011 PgPool Global Development Group
+ * @version    CVS: $Id$
+ */
+
+require_once('common.php');
+
+if (!isset($_SESSION[SESSION_LOGIN_USER])) {
+    exit();
+}
+
+$params = readConfigParams(array('port', 'wd_hostname', 'wd_port', 'delegate_IP',
+                                 'other_pgpool_hostname', 'other_pgpool_port', 'other_wd_port',
+                                 'wd_interval', 'wd_life_point', 'wd_lifecheck_query'));
+
+$tpl->assign('params', $params);
+$tpl->display('innerWatchdog.tpl');
+
+?>
index eb7d05b222a55f4bfa5fa86afb6a6e0fbc59a83e..a4be4bfb67550f57be8a1066561f1b0e5f34729f 100644 (file)
@@ -124,7 +124,8 @@ $message = array(
     'descReplication_mode' => 'Set this to true if you are going to use replication functionality',
     'descReplication_stop_on_mismatch' => 'Stop replication mode on data mismatch between master and secondary',
     'descReplicate_select' => 'If true, replicate SELECT queries. If false, send only to master',
-    'descReplication_timeout' => 'In non strict replication mode, there will be a risk of deadlock. Timeout in second for monitoring the deadlock',
+    'descReplication_timeout' => 'In non strict replication mode, there will be a risk of deadlock. '.
+                                 'Timeout in second for monitoring the deadlock',
     'descReset_query_list' => 'Semicolon separated SQL commands to be issued at the end of session',
     'descSsl' => 'The frontend connection',
     'descSsl_ca_cert' => 'Path to the SSL private key file',
@@ -169,7 +170,10 @@ $message = array(
     'errShouldBeZeroOrMore' => 'This should be 0 or more',
     'errSingleQuotation' => 'Please enclose the array element with a single quotation.',
 
+    'msgAddBackend' => 'Do you really add this node as a new backend?',
+    'msgAddBackendNg' => 'Invalid.',
     'msgDeleteConfirm' => 'Do you really want to delete it?',
+    'msgHasNotLoadedNode' => 'You have to reload pgpool to use the new backend node.',
     'msgMasterDbConnectionError' => 'Master DB connection failed',
     'msgPgpoolConfNotFound' => 'pgpool.conf not found',
     'msgPleaseSetup' => 'No found configuration file. Please execute the setup.',
@@ -178,15 +182,20 @@ $message = array(
     'msgRestartPgpool' => 'Do you really want to restart pgpool?',
     'msgSameAsPasswordFile' => 'The value is the same as item Password File',
     'msgSameAsPgpoolFile' => 'The value is the same as item pgpool.conf File',
+    'msgStartPgpool' => 'Do you really start pgpool?',
     'msgStopPgpool' => 'Do you really want to stop pgpool?',
     'msgUpdateComplete' => 'Update complete',
+    'msgUpdateCompleteInfo' => 'You have to reload or restart pgpool to use new configuration.',
     'msgUpdateFailed' => 'Update failed',
     'msgDetachConfirm' => 'Do you really detach this node?',
     'msgReturnConfirm' => 'Do you really make this node return?',
     'msgRecoveryConfirm' => 'Do you really recover this node?',
+    'msgRemoveBackend' => 'Do you really remove this backend node?',
     'msgRPromoteConfirm' => 'Do you really make this node primary?',
 
     'strAdd' => 'Add',
+    'strAddBackend' => 'Add a new backend node',
+    'strAddBackendNow' => 'Reload pgpool right after adding',
     'strAdminPassword' => 'Password',
     'strBack' => 'Back',
     'strBackendPid' => 'Backend Pid',
@@ -284,11 +293,15 @@ $message = array(
     'strQueryCache' => 'Query Cache',
     'strQueryStr' => 'Query',
     'strReloadPgpool' => 'Reload',
+    'strReloadPgsql' => 'Reload',
     'strReplicationMode' => 'Replication Mode',
     'strReset' => 'Reset',
     'strRestart' => 'Restart',
     'strRestartOption' => 'pgpool Restart Option',
     'strRestartPgpool' => 'Restart pgpool',
+    'strRestartPgsql' => 'Restart',
+    'strRestartPgsqlOption' => 'Restart PostgreSQL Option',
+    'strRemoveBackend' => 'Remove',
     'strReturn' => 'Return',
     'strRecovery' => 'Recovery',
     'strSchemaName' => 'Schema Name',
@@ -300,12 +313,17 @@ $message = array(
     'strStandbyRunning' => 'Running as standby server',
     'strStartOption' => 'Start Option',
     'strStartPgpool' => 'Start pgpool',
+    'strStartPgsql' => 'Start',
     'strStatus' => 'Status',
     'strStopOption' => 'pgpool Stop Option',
     'strStopPgpool' => 'Stop pgpool',
+    'strStopPgsql' => 'Stop',
+    'strStopPgsqlOption' => 'Stop PostgreSQL Option',
+    'strStoppingNow' => 'Not active',
     'strStreamingRepMode' => 'Streaming Replication mode',
     'strSummary' => 'Summary',
     'strSystemDb' => 'Partitioning Rule',
+    'strSystemCatalog' => 'System catalog',
     'strTable' => 'Table',
     'strTypeList' => 'Type List of Column',
     'strUp' => 'Up',
index 7be46d95c13de617ee42a966fcb35a90b1c5a307..9791fd3c6e1c806635106c1f815c4780a9eb878f 100644 (file)
@@ -161,7 +161,10 @@ $message = array(
     'errShouldBeZeroOrMore' => '0以上である必要があります',
     'errSingleQuotation' => '配列要素をシングルクォーテーションで囲んでください。',
 
+    'msgAddBackend' => 'バックエンドノードとして追加してよろしいですか?',
+    'msgAddBackendNg' => 'バックエンドノード情報に不備があります。',
     'msgDeleteConfirm' => '本当に削除してよいですか?',
+    'msgHasNotLoadedNode' => '新しいノード情報を読み込むには pgpool の設定をリロードする必要があります。',
     'msgMasterDbConnectionError' => 'マスターDBに接続できません',
     'msgPgpoolConfNotFound' => 'pgpool.confが見つかりません',
     'msgPleaseSetup' => '設定ファイルが見つかりません。セットアップを実行してください。',
@@ -170,15 +173,20 @@ $message = array(
     'msgRestartPgpool' => 'pgpoolを再起動してよろしいですか?',
     'msgSameAsPasswordFile' => '値はパスワードファイルの設定値となります',
     'msgSameAsPgpoolFile' => '値はpgpool.confファイルの設定値となります',
-    'msgStopPgpool' => 'pgpoolを停止してよいですか?',
-    'msgUpdateComplete' => '更新は正常に終了しました',
-    'msgUpdateFailed' => '更新に失敗しました',
-    'msgDetachConfirm' => 'このノードを切断してよいですか?',
-    'msgReturnConfirm' => 'このノードを復帰させてよいですか?',
+    'msgStartPgpool' => 'pgpoolを起動しますか?',
+    'msgStopPgpool' => 'pgpoolを停止してよろしいですか?',
+    'msgUpdateComplete' => '更新は正常に終了しました。',
+    'msgUpdateCompleteInfo' => '設定を反映するには、pgpoolの設定リロードか再起動をする必要があります。',
+    'msgUpdateFailed' => '更新に失敗しました。',
+    'msgDetachConfirm' => 'このノードを pgpool-II の管理から切断してよいですか?',
+    'msgReturnConfirm' => 'このノードを pgpool-II の管理下に復帰させてよいですか?',
     'msgRecoveryConfirm' => 'このノードをリカバリしますか?',
+    'msgRemoveBackend' => 'このバックエンドノードを削除してよろしいですか?',
     'msgRPromoteConfirm' => 'このノードをマスタに昇格しますか?',
 
     'strAdd' => '追加',
+    'strAddBackend' => '新しいバックエンドを登録',
+    'strAddBackendNow' => '即座に追加する(pgpool の設定をリロードします)',
     'strAdminPassword' => '管理者パスワード',
     'strBack' => '戻る',
     'strBackendPid' => 'バックエンドプロセスID',
@@ -277,27 +285,36 @@ $message = array(
     'strQueryStr' => 'クエリ文字列',
     'strReloadPgpool' => '設定リロード',
     'strReplicationMode' => 'レプリケーションモード',
+    'strReloadPgsql' => '設定リロード',
     'strReset' => 'リセット',
     'strRestart' => '再起動',
     'strRestartOption' => 'pgpool再起動オプション',
     'strRestartPgpool' => 'pgpool再起動',
+    'strRestartPgsql' => '再起動',
+    'strRestartPgsqlOption' => 'PostgreSQL再起動オプション',
+    'strRemoveBackend' => '登録削除',
     'strReturn' => '復帰',
     'strRecovery' => 'リカバリ',
     'strSchemaName' => 'スキーマ名',
     'strSearch' => '検索',
     'strSecondaryServer' => 'セカンダリサーバ',
-    'strSetting' => '管理ツール設定',
+    'strSetting' => 'pgpoolAdmin設定',
     'strSetup' => 'セットアップ',
     'strSlonyMode' => 'Slony-Iモード',
     'strStandbyRunning' => 'スタンバイとして稼働中',
     'strStartOption' => '起動オプション',
     'strStartPgpool' => 'pgpool起動',
+    'strStartPgsql' => '起動',
     'strStatus' => 'ステータス',
     'strStopOption' => 'pgpool停止オプション',
     'strStopPgpool' => 'pgpool停止',
+    'strStopPgsql' => '停止',
+    'strStopPgsqlOption' => 'PostgreSQL停止オプション',
+    'strStoppingNow' => '停止中',
     'strStreamingRepMode' => 'Streaming Replicationモード',
     'strSummary' => '概要',
     'strSystemDb' => '分散ルール',
+    'strSystemCatalog' => 'システムカタログ情報',
     'strTable' => 'テーブル名',
     'strTypeList' => '列データ型リスト',
     'strUp' => 'アップ',
index aae1e81faba2534d95cdc125f14355275eb97742..60b316420bf5c3f4993c51b2f9037059a38329f1 100644 (file)
--- a/login.php
+++ b/login.php
  * is" without express or implied warranty.
  *
  * @author     Ryuma Ando <ando@ecomas.co.jp>
- * @copyright  2003-2012 PgPool Global Development Group
+ * @copyright  2003-2013 PgPool Global Development Group
  * @version    CVS: $Id$
  */
 
 require_once('common.php');
 require_once('command.php');
 
-$success = FALSE;
+/* --------------------------------------------------------------------- */
+/* login.php                                                             */
+/* --------------------------------------------------------------------- */
 
+// Check loginstatus
+$success = FALSE;
 if (isset($_SESSION[SESSION_LOGIN_USER])) {
     $success = TRUE;
 }
@@ -77,35 +81,6 @@ if ($success == FALSE) {
     }
 }
 
-// If user has already logined, show nodeStatus page.
-$tpl->assign('isLogin', TRUE);
-$tpl->assign('viewPHP', 'nodeStatus.php');
-
-$refreshTime = 5000;
-if (_PGPOOL2_STATUS_REFRESH_TIME >= 0 ) {
-    $refreshTime = _PGPOOL2_STATUS_REFRESH_TIME * 1000;
-}
-if (DoesPgpoolPidExist()) {
-    $tpl->assign('pgpoolIsActive', TRUE);
-} else {
-    $tpl->assign('pgpoolIsActive', FALSE);
-}
-
-$tpl->assign('c', _PGPOOL2_CMD_OPTION_C);
-$tpl->assign('D', _PGPOOL2_CMD_OPTION_LARGE_D);
-$tpl->assign('d', _PGPOOL2_CMD_OPTION_D);
-$tpl->assign('m', _PGPOOL2_CMD_OPTION_M);
-$tpl->assign('n', _PGPOOL2_CMD_OPTION_N);
-$tpl->assign('C', _PGPOOL2_CMD_OPTION_LARGE_C);
-
-$tpl->assign('pgpoolStatus',  NULL);
-$tpl->assign('pgpoolMessage', NULL);
-$tpl->assign('pgpoolConf',    _PGPOOL2_CONFIG_FILE);
-$tpl->assign('pcpConf',       _PGPOOL2_PASSWORD_FILE);
-$tpl->assign('refreshTime',   $refreshTime);
-$tpl->assign('useSyslog',     useSyslog());
-$tpl->assign('msgStopPgpool', $message['msgStopPgpool']);
-$tpl->assign('help', 'status');
-$tpl->display('status.tpl');
-
-?>
+// If user has already logined, show status page.
+header("Location: status.php");
+exit();
index b3702450189c62d2e958cf779c0cb6a967d26888..0f411133c4f016f06132daf92e76513a77088c81 100644 (file)
  * is" without express or implied warranty.
  *
  * @author     Ryuma Ando <ando@ecomas.co.jp>
- * @copyright  2003-2008 PgPool Global Development Group
+ * @copyright  2003-2013 PgPool Global Development Group
  * @version    CVS: $Id$
  */
 
+/* --------------------------------------------------------------------- */
+/* nodeServerStatus.php                                                  */
+/* --------------------------------------------------------------------- */
+
 require_once('common.php');
-$tpl->assign('help', basename( __FILE__, '.php'));
 
+// Check login status
 if (!isset($_SESSION[SESSION_LOGIN_USER])) {
     header('Location: login.php');
     exit();
 }
 
-readConfigParams();
+// Set Vars
+$tpl->assign('help', basename( __FILE__, '.php'));
 
+// Display
+$is_pgpool_active = DoesPgpoolPidExist();
+$tpl->assign('pgpoolIsActive', $is_pgpool_active);
 $tpl->display('nodeServerStatus.tpl');
-?>
index 13580cd44430c529e225884e956ea748f4ead28b..c675f5e1343f18f611e5bc30e4c83c18468349d7 100644 (file)
  * is" without express or implied warranty.
  *
  * @author     Ryuma Ando <ando@ecomas.co.jp>
- * @copyright  2003-2011 PgPool Global Development Group
+ * @copyright  2003-2013 PgPool Global Development Group
  * @version    SVN: $Id$
  */
 
 require_once('common.php');
 require_once('command.php');
-$tpl->assign('help', basename( __FILE__, '.php'));
-
-$MAX_VALUE = PHP_INT_MAX;
 
-// node status in "pcp_node_info" result
-define('NODE_ACTIVE_NO_CONNECT', 1);
-define('NODE_ACTIVE_CONNECTED',  2);
-define('NODE_DOWN',              3);
+/* --------------------------------------------------------------------- */
+/* nodeStatus.php                                                        */
+/* --------------------------------------------------------------------- */
 
+// Check login status
 if (!isset($_SESSION[SESSION_LOGIN_USER])) {
     exit();
 }
 
-// cout nodes
-$ret = execPcp('PCP_NODE_COUNT');
-if (!array_key_exists('SUCCESS', $ret)) {
-    $errorCode = 'e1002';
-    $tpl->assign('errorCode', $errorCode);
-    $tpl->display('innerError.tpl');
-    exit();
-} else {
-    $nodeCount = $ret['SUCCESS'];
-}
-
-$tpl->assign('nodeCount', $nodeCount);
-
-$nodeInfo = array();
-$node_alive = FALSE;
-
-// get nodes' status
-for ($i = 0; $i < $nodeCount; $i++) {
-    // execute "pcp_node_info" command
-    // ex) host1 5432 1 1073741823.500000
-    $ret = execPcp('PCP_NODE_INFO', $i);
-
-    if (!array_key_exists('SUCCESS', $ret)) {
-        $errorCode = 'e1003';
-        $tpl->assign('errorCode', $errorCode);
-        $tpl->display('innerError.tpl');
-        exit();
-
-    } else {
-        $ret = $ret['SUCCESS'];
-    }
-
-    $nodeInfo[$i] = explode(" ", $ret);
-
-    // load balance weight: normalize format
-    $nodeInfo[$i][3] =  sprintf('%.3f', $nodeInfo[$i][3]);
-
-    // node is active?
-    if ($nodeInfo[$i][2] != NODE_DOWN) {
-        $node_alive = TRUE;
-    }
-}
-
 // select buttons to each nodes depending on their status
 $isParallelMode    = isParallelMode();
 $isReplicationMode = isReplicationMode();
 $isMasterSlaveMode = isMasterSlaveMode();
 
-for ($i = 0; $i < $nodeCount; $i++) {
-    if ($node_alive == FALSE) {
-        if (($isReplicationMode || $isMasterSlaveMode) && NodeActive($i)) {
-            array_push($nodeInfo[$i], 'return');
-        } else {
-            array_push($nodeInfo[$i], 'none');
-        }
+$configValue = readConfigParams(array('backend_hostname', 'backend_port'));
+if (!isset($configValue['backend_hostname'])) { return; }
+$backends_in_conf = $configValue['backend_hostname'];
 
-    } elseif ($isParallelMode ) {
-        array_push($nodeInfo[$i], 'none');
+// Get nodes' status
+$nodeCount = NULL;
+$is_pgpool_active = DoesPgpoolPidExist();
+if ($is_pgpool_active) {
+    $nodeCount = getNodeCount();
+}
+$has_not_loaded_node = FALSE;
 
-    } else {
-        switch($nodeInfo[$i][2]) {
+// Merge backends in pgpool.conf and them in pgpool
+// ex) when remove a backend but not reload yet
+if (count($backends_in_conf) < $nodeCount) {
+    for ($i = 0; $i < $nodeCount; $i++) {
+        $backends_in_conf[$i] = array();
+    }
+}
+
+$nodeInfo = array();
+foreach ($backends_in_conf as $i => $backend) {
+    // Set buttons
+    $nodeInfo[$i]['return']     = FALSE;
+    $nodeInfo[$i]['disconnect'] = FALSE;
+    $nodeInfo[$i]['promote']    = FALSE;
+    $nodeInfo[$i]['recovery']   = FALSE;
+
+    // The flag if postgres is active or sleeping
+    $nodeInfo[$i]['is_active'] = NodeActive($i);
+
+    // nodes recognized by pgpool
+    if ($nodeCount != NULL/* && $i < $nodeCount*/) {
+        // Get info by pcp_node_info
+        $nodeInfo[$i] += getNodeInfo($i);
+
+        // Get the result of "SELECT pg_is_in_recovery()" as integer(0, 1, -1)
+        // (If pgpool don't act in Master/Slave & SR mode, this value will be ignored.)
+        $nodeInfo[$i]['is_standby'] = NodeStandby($i);
+
+        switch($nodeInfo[$i]['status']) {
             case NODE_ACTIVE_NO_CONNECT:
             case NODE_ACTIVE_CONNECTED:
                 if ($isReplicationMode || $isMasterSlaveMode) {
-                    array_push($nodeInfo[$i], 'disconnect');
-                } else {
-                    array_push($nodeInfo[$i], 'none');
+                    if ($nodeInfo[$i]['is_active']) {
+                        $nodeInfo[$i]['disconnect'] = TRUE;
+                    }
                 }
+
                 // pcp_promote_node exists after V3.1
                 if (hasPcpPromote() && useStreaming()) {
-                    array_push($nodeInfo[$i], 'promote');
+                    $nodeInfo[$i]['promote'] = TRUE;
                 }
                 break;
 
             case NODE_DOWN:
                 if ($isReplicationMode || $isMasterSlaveMode) {
-                    if (NodeActive($i)) {
-                        array_push($nodeInfo[$i], 'return');
+                    if ($nodeInfo[$i]['is_active']) {
+                        $nodeInfo[$i]['return'] = TRUE;
                     } else {
-                        array_push($nodeInfo[$i], 'recovery');
+                        $nodeInfo[$i]['recovery'] = TRUE;
                     }
-                } else {
-                    array_push($nodeInfo[$i], 'none');
                 }
                 break;
         }
-    }
 
-    // result of "SELECT pg_is_in_recovery()" as integer(0, 1, -1)
-    // (If pgpool don't act in Master/Slave & SR mode, this value will be ignored.)
-    $nodeInfo[$i][6] = NodeStandby($i);
+    // nodes not working as backend (just written in pgpool.conf)
+    } else {
+        $has_not_loaded_node = TRUE;
+        $nodeInfo[$i]['hostname'] = $configValue['backend_hostname'][$i];
+        $nodeInfo[$i]['port'] = $configValue['backend_port'][$i];
+        $nodeInfo[$i]['weight'] = 0;
+        $nodeInfo[$i]['status'] =  NODE_NOT_LOADED;
+        $nodeInfo[$i]['is_standby'] = NULL;
+    }
 }
 
+// Set vars
+$tpl->assign('help', basename( __FILE__, '.php'));
+
 $tpl->assign('refreshTime',   _PGPOOL2_STATUS_REFRESH_TIME * 1000);
 $tpl->assign('nodeInfo',      $nodeInfo);
 $tpl->assign('parallelMode',  $isParallelMode);
 $tpl->assign('msgStopPgpool', $message['msgStopPgpool']);
-$tpl->display('nodeStatus.tpl');
+$tpl->assign('nodeCount',     $nodeCount);
+$tpl->assign('has_not_loaded_node', $has_not_loaded_node);
+$tpl->assign('pgpoolIsActive', $is_pgpool_active);
 
-?>
+// Set params
+$configValue = readConfigParams('recovery_1st_stage');
+$tpl->assign('params', $configValue);
+
+// Display
+$tpl->display('nodeStatus.tpl');
index 0d214685ef2d5faf6c64d65bfa1e8789512ddb76..6aed56af885cdd6063996043011188e37ea94080 100644 (file)
@@ -19,7 +19,7 @@
  * is" without express or implied warranty.
  *
  * @author     Ryuma Ando <ando@ecomas.co.jp>
- * @copyright  2003-2012 PgPool Global Development Group
+ * @copyright  2003-2013 PgPool Global Development Group
  * @version    CVS: $Id$
  */
 
@@ -67,32 +67,32 @@ switch ($action) {
         if (isset($_POST['backend_hostname'])) {
             $configValue['backend_hostname'] = $_POST['backend_hostname'];
         } else {
-            $configValue['backend_hostname'] = array();
+            $configValue['backend_hostname'][0] = NULL;
 
         }
         if (isset($_POST['backend_port'])) {
             $configValue['backend_port'] = $_POST['backend_port'];
         } else {
-            $configValue['backend_port'] = array();
+            $configValue['backend_port'][0] = NULL;
         }
 
         if (isset($_POST['backend_weight'])) {
             $configValue['backend_weight'] = $_POST['backend_weight'];
         } else {
-            $configValue['backend_weight'] = array();
+            $configValue['backend_weight'][0] = NULL;
         }
 
         if (isset($_POST['backend_data_directory'])) {
             $configValue['backend_data_directory'] = $_POST['backend_data_directory'];
         } else {
-             $configValue['backend_data_directory'] = array();
+             $configValue['backend_data_directory'][0] = NULL;
         }
 
         if (paramExists('backend_flag')) {
             if (isset($_POST['backend_flag'])) {
                 $configValue['backend_flag'] = $_POST['backend_flag'];
             } else {
-                $configValue['backend_flag'] = array();
+                $configValue['backend_flag'][0] = NULL;
             }
         }
 
@@ -100,20 +100,20 @@ switch ($action) {
         if (isset($_POST['other_pgpool_hostname'])) {
             $configValue['other_pgpool_hostname'] = $_POST['other_pgpool_hostname'];
         } else {
-            $configValue['other_pgpool_hostname'] = array();
+            $configValue['other_pgpool_hostname'][0] = NULL;
 
         }
 
         if (isset($_POST['other_pgpool_port'])) {
             $configValue['other_pgpool_port'] = $_POST['other_pgpool_port'];
         } else {
-            $configValue['other_pgpool_port'] = array();
+            $configValue['other_pgpool_port'][0] = NULL;
         }
 
         if (isset($_POST['other_wd_port'])) {
             $configValue['other_wd_port'] = $_POST['other_wd_port'];
         } else {
-            $configValue['other_wd_port'] = array();
+            $configValue['other_wd_port'][0] = NULL;
         }
 
         $tpl->assign('params', $configValue);
@@ -405,6 +405,20 @@ switch ($action) {
     default:
 }
 
+if (!isset($configValue['backend_hostname'])) {
+    $configValue['backend_hostname'][0] = NULL;
+    $configValue['backend_port'][0]     = NULL;
+    $configValue['backend_weight'][0]   = NULL;
+    $configValue['backend_data_directory'][0] = NULL;
+    $configValue['backend_flag'][0]     = NULL;
+}
+
+if (!isset($configValue['other_pgpool_hostname'])) {
+    $configValue['other_pgpool_hostname'][0] = NULL;
+    $configValue['other_pgpool_port'][0]     = NULL;
+    $configValue['other_wd_port'][0]         = NULL;
+}
+
 $tpl->assign('params', $configValue);
 $tpl->assign('error', $error);
 
@@ -646,7 +660,7 @@ function writeConfigFile($configValue, $pgpoolConfigParam)
 
     foreach ($pgpoolConfigParam as $key => $value) {
         $isWrite = FALSE;
-        for ($j = 0; $j<count($configFile); $j++) {
+        for ($j = 0; $j < count($configFile); $j++) {
             $line = $configFile[$j];
             $line = trim($line);
 
@@ -707,6 +721,8 @@ function writeConfigFile($configValue, $pgpoolConfigParam)
  */
 function deleteBackendHost($num, &$configValue)
 {
+    if (!isset($configValue['backend_hostname'])) { return; }
+
     unset($configValue['backend_hostname'][$num]);
     $configValue['backend_hostname'] = array_values($configValue['backend_hostname']);
 
@@ -730,6 +746,8 @@ function deleteBackendHost($num, &$configValue)
  */
 function deleteWdOther($num, &$configValue)
 {
+    if (!isset($configValue['other_pgpool_hostname'])) { return; }
+
     unset($configValue['other_pgpool_hostname'][$num]);
     $configValue['other_pgpool_hostname'] = array_values($configValue['other_pgpool_hostname']);
 
index 773e0a7acdba8b4d6985de4e93e0b02d65728951..a9658238f2a423bbbbf8a9c82ed58f000b62c9ec 100644 (file)
@@ -1,7 +1,12 @@
 body {
   margin: 0px;
-  font: x-small Verdana, Arial, Helvetica, sans-serif
+  font: x-small Verdana, Arial, Helvetica, sans-serif;
 }
+
+/* --------------------------------------------------------------------- */
+/* header                                                                */
+/* --------------------------------------------------------------------- */
+
 h1 {
   margin: 0px;
 }
@@ -17,9 +22,11 @@ h3 {
   border: 2px solid #8CD8E2;
   border-left: 10px solid #8CD8E2;
 }
-ul {
-  list-style: square;
-}
+
+/* --------------------------------------------------------------------- */
+/* table                                                                 */
+/* --------------------------------------------------------------------- */
+
 table {
   border-top: 1px solid lightsteelblue;
   border-collapse: collapse;
@@ -40,6 +47,22 @@ tbody th.category {
   color: #709CD1;
   font-size: small;
 }
+
+table#complete_msg
+{
+    margin-bottom: 20px;
+}
+
+td.pgconfig_msg img {
+  vertical-align: middle;
+  margin-right: 5px;
+  height: 12px;
+}
+
+/* --------------------------------------------------------------------- */
+/* link                                                                  */
+/* --------------------------------------------------------------------- */
+
 a:link {
   color: red;
   text-decoration: none;
@@ -55,9 +78,79 @@ a:link:hover, a:visited:hover {
 a img {
   border: none;
 }
+
+/* --------------------------------------------------------------------- */
+/* input                                                                 */
+/* --------------------------------------------------------------------- */
+
 input {
   font: x-small Verdana, Arial, Helvetica, sans-serif;
 }
+input[type=button], input[type=submit] {
+  border-radius: 3px;
+  padding: 2px 5px;
+
+  vertical-align: middle;
+
+  border-top: 1px solid #aaa;
+  border-right: 1px solid #666;
+  border-bottom: 1px solid #666;
+  border-left: 1px solid #aaa;
+
+  -webkit-border-radius: 3px;
+  -moz-border-radius:    3px;
+  border-radius:         3px;
+
+  background: #ffffff;
+  background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));
+  background: -moz-linear-gradient(top, #ffffff, #eeeeee);
+}
+
+input[type=button]:hover, input[type=submit]:hover, input[type=reset]:hover {
+  border-top: 1px solid #666;
+  border-right: 1px solid #aaa;
+  border-bottom: 1px solid #aaa;
+  border-left: 1px solid #666;
+
+  background: #f3f3f3;
+  background: -webkit-gradient(linear, left top, left bottom, from(#eeeeee), to(#ffffff));
+  background: -moz-linear-gradient(top, #eeeeee, #ffffff);
+  color: #5f5f5f;
+}
+input[type=button]:active, input[type=submit]:active, input[type=reset]:active {
+  border-top: 1px solid #666;
+  border-right: 1px solid #aaa;
+  border-bottom: 1px solid #aaa;
+  border-left: 1px solid #666;
+
+  background: #cccccc;
+  color: #000000;
+}
+input[type=button].command_active {
+  background: yellow;
+  background: -webkit-gradient(linear, left top, left bottom, from(yellow), to(#FCE114));
+  background: -moz-linear-gradient(top, yellow, #FCE114);
+  border-color: #BC4B00;
+}
+
+input[type=button][disabled], input[type=button][disabled]:hover {
+  border-top: 1px solid #aaa;
+  border-right: 1px solid #666;
+  border-bottom: 1px solid #666;
+  border-left: 1px solid #aaa;
+
+  background: #dedede;
+  color: #777777;
+  text-shadow: #eeeeee 0 1px 0;
+}
+input[type=button][disabled]:hover {
+  background: #f0f0f0;
+}
+
+/* --------------------------------------------------------------------- */
+/* text                                                                  */
+/* --------------------------------------------------------------------- */
+
 label {
   font-weight: bold;
 }
@@ -68,11 +161,21 @@ pre {
 p {
     margin: 5px;
 }
+ul {
+  list-style: square;
+}
+/* --------------------------------------------------------------------- */
+/* div                                                                   */
+/* --------------------------------------------------------------------- */
+
+/* header */
 #header {
   padding: 8px;
   border-bottom: 8px solid white;
   background: steelblue url("images/sea.jpg") no-repeat bottom right;
 }
+
+/* menu */
 #menu {
   padding-bottom: 40px;
   border-top: 1px solid lightsteelblue;
@@ -101,11 +204,15 @@ p {
 #menu a:hover {
   background: antiquewhite url("images/marker.gif") no-repeat 8px;
 }
+
+/* content */
 #content {
   padding: 8px 8px 40px 185px;
   border-top: 1px solid lightsteelblue;
   background: white url("images/background.gif") repeat-y left;
 }
+
+/* submenu */
 #submenu {
   border: 1px solid lightsteelblue;
   float: right;
@@ -127,6 +234,8 @@ p {
   border-top: 1px solid lightsteelblue;
   list-style: square inside;
 }
+
+/* footer */
 #footer {
   padding: 8px 8px 20px;
   clear: left;
@@ -144,6 +253,21 @@ p {
   color: white;
   font-weight: bold;
 }
+
+/* help */
+#help {
+  float: right;
+}
+
+/* commands */
+#div_commands {
+  margin-bottom: 20px;
+}
+
+/* --------------------------------------------------------------------- */
+/* other                                                                 */
+/* --------------------------------------------------------------------- */
+
 .hidden {
   display: none;
 }
@@ -155,7 +279,7 @@ p {
 .error {
   font-weight: normal;
   text-align: left;
-  background: red;
+  background: #FFB499;
 }
 .right_border {
   border-right: 1px solid lightsteelblue;
@@ -177,6 +301,20 @@ p {
     border-bottom: 1px dotted #cccccc;
 }
 
-#help {
+/* --------------------------------------------------------------------- */
+/* Refresh info                                                          */
+/* --------------------------------------------------------------------- */
+
+div.auto_reloading {
   float: right;
+  margin-bottom: 10px;
+}
+div.auto_reloading img {
+  vertical-align: middle;
+  height: 13px;
+}
+div.auto_reloading span {
+  padding: 2px 5px;
+  margin: 5px;
+  color: #2D1D00;
 }
index a8629057a3092dea2bf25b3169adde2924dce027..785c61298a138f6d31f1ac1f438b43b43184728e 100644 (file)
  * is" without express or implied warranty.
  *
  * @author     Ryuma Ando <ando@ecomas.co.jp>
- * @copyright  2003-2012 PgPool Global Development Group
+ * @copyright  2003-2013 PgPool Global Development Group
  * @version    SVN: $Id$
  */
 
 require_once('common.php');
 require_once('command.php');
-$tpl->assign('help', basename( __FILE__, '.php'));
-
-$viewPHP = 'nodeStatus.php';
-$refreshTime = 5000;
-if (isset($_POST['nodeNumber'])) {
-    $nodeNumber = $_POST['nodeNumber'];
-} else {
-    $nodeNumber = -1;
-}
 
+/* --------------------------------------------------------------------- */
+/* Status.php                                                            */
+/* --------------------------------------------------------------------- */
 
+// Check login status
 if (!isset($_SESSION[SESSION_LOGIN_USER])) {
     header('Location: login.php');
     exit();
 }
 
-if (isset($_POST['action'])) {
-    $action = $_POST['action'];
-} else {
-    $action = FALSE;
-}
-
-/**
- * Set pgpool command option
- */
+$is_pgpool_active = DoesPgpoolPidExist();
+
+// Do action
+$nodeNumber = (isset($_POST['nodeNumber'])) ? $_POST['nodeNumber'] : -1;
+$action     = (isset($_POST['action'])) ?  $_POST['action'] : FALSE;
+$viewPHP    = _doAction($action, $nodeNumber);
+
+// Set vars
+setNodeInfoFromConf();
+$tpl->assign('action',         $action);
+$tpl->assign('pgpoolIsActive', $is_pgpool_active);
+$tpl->assign('viewPHP',        $viewPHP);
+$tpl->assign('help',           basename( __FILE__, '.php'));
+$tpl->assign('pgpoolConf',     _PGPOOL2_CONFIG_FILE);
+$tpl->assign('pcpConf',        _PGPOOL2_PASSWORD_FILE);
+$tpl->assign('refreshTime',    (0 <= _PGPOOL2_STATUS_REFRESH_TIME) ?
+                               _PGPOOL2_STATUS_REFRESH_TIME * 1000 : 5000);
+$tpl->assign('refreshTimeLog', REFRESH_LOG_SECONDS);
+$tpl->assign('useSyslog',      useSyslog());
+$tpl->assign('pipe',           (isPipe(_PGPOOL2_LOG_FILE)) ? 1 : 0);
+$tpl->assign('msgStopPgpool',  $message['msgStopPgpool']);
+$tpl->assign('login_user',     $_SESSION[SESSION_LOGIN_USER]);
+$tpl->assign('is_superuser',   isSuperUser($_SESSION[SESSION_LOGIN_USER]));
+
+// Set params
+$configValue = readConfigParams('use_watchdog');
+$tpl->assign('params', $configValue);
+
+// Set pgpool command option
 $tpl->assign('c', _PGPOOL2_CMD_OPTION_C);
 $tpl->assign('D', _PGPOOL2_CMD_OPTION_LARGE_D);
 $tpl->assign('d', _PGPOOL2_CMD_OPTION_D);
@@ -57,269 +72,436 @@ $tpl->assign('m', _PGPOOL2_CMD_OPTION_M);
 $tpl->assign('n', _PGPOOL2_CMD_OPTION_N);
 $tpl->assign('C', _PGPOOL2_CMD_OPTION_LARGE_C);
 
-if (isPipe(_PGPOOL2_LOG_FILE)) {
-    $tpl->assign('pipe', 1);
-} else {
-    $tpl->assign('pipe', 0);
-}
+// Display
+$tpl->display('status.tpl');
 
-$tpl->assign('pgpoolStatus', NULL);
-$tpl->assign('pgpoolMessage', NULL);
+/* --------------------------------------------------------------------- */
+/* Functions                                                             */
+/* --------------------------------------------------------------------- */
 
-switch ($action) {
+/** Execute a command */
+function _doAction($action, $nodeNumber)
+{
+    global $tpl;
 
-    /* --------------------------------------------------------------------- */
-    /* start                                                                 */
-    /* --------------------------------------------------------------------- */
+    $viewPHP = 'nodeStatus.php';
+    $tpl->assign('pgpoolStatus',   NULL);
+    $tpl->assign('pgpoolMessage',  NULL);
 
-    case 'start':
-        $args = ' ';
+    switch ($action) {
+        /* --------------------------------------------------------------------- */
+        /* pgpool                                                                */
+        /* --------------------------------------------------------------------- */
 
-        if (isset($_POST['c'])) {
-            $args = $args . "-c ";
-        }
-        if (isset($_POST['D'])) {
-            $args = $args . "-D ";
-        }
-        if (isset($_POST['d'])) {
-            $args = $args . "-d ";
-        }
-        if (isset($_POST['C'])) {
-            $args = $args . "-C ";
-        }
-        if (isset($_POST['n'])) {
-            $pgpoolLog = _PGPOOL2_LOG_FILE;
-            if ($pgpoolLog == '') {
-                $logDir = readLogDir();
-                $pgpoolLog = "$logDir/pgpool.log";
-            }
-            if (isPipe($pgpoolLog)) {
-                $args = "$args -n 2>&1 $pgpoolLog ";
-            } else {
-                $args = "$args -n > $pgpoolLog ";
-            }
-        }
+        case 'startPgpool':
+            _startPgpool();
+            break;
 
-        $ret = execPcp('PCP_START_PGPOOL', $args);
-        if (!array_key_exists('SUCCESS', $ret)) {
-            $tpl->assign('pgpoolStatus', 'pgpool start failed.');
-            $tpl->assign('pgpoolMessage', $ret);
-        } else {
-            for ($i = 0; $i < 10; $i++) {
-                if (DoesPgpoolPidExist()) {
-                    break;
-                } else {
-                    sleep(1);
-                }
-            }
+        case 'stopPgpool':
+            _stopPgpool();
+            break;
 
-            if (DoesPgpoolPidExist()) {
-                $tpl->assign('pgpoolStatus', 'pgpool start succeed');
-            } else {
-                $tpl->assign('pgpoolStatus', 'pgpool start failed. pgpool.pid not found');
-            }
-            $tpl->assign('pgpoolMessage', $ret['SUCCESS']);
-        }
+        case 'restartPgpool':
+            _restartPgpool();
+            break;
 
-        break;
+        case 'reloadPgpool':
+            $args = ' ';
+            $result = execPcp('PCP_RELOAD_PGPOOL', $args);
+            break;
 
-    /* --------------------------------------------------------------------- */
-    /* stop                                                                  */
-    /* --------------------------------------------------------------------- */
+        /* --------------------------------------------------------------------- */
+        /* other command                                                         */
+        /* --------------------------------------------------------------------- */
 
-    case 'stop':
-        $m = $_POST['stop_mode'];
+        case 'return':
+            if (_execPcp('PCP_ATTACH_NODE', $nodeNumber, 'e1010') === FALSE) { exit(); }
+            break;
 
-        $ret = execPcp('PCP_STOP_PGPOOL', $m);
-        if (!array_key_exists('SUCCESS', $ret)) {
-            $errorCode = 'e1006';
-            $tpl->assign('errorCode', $errorCode);
-            $tpl->display('error.tpl');
-            exit();
+        case 'recovery':
+            if (_execPcp('PCP_RECOVERY_NODE', $nodeNumber, 'e1012') === FALSE) { exit(); }
+            break;
 
-        } else {
-            for ($i = 0; $i < 10; $i++) {
-                if (DoesPgpoolPidExist()) {
-                    sleep(1);
-                } else {
-                    break;
-                }
-            }
+        case 'detach':
+            if (_execPcp('PCP_DETACH_NODE', $nodeNumber, 'e1007') === FALSE) { exit(); }
+            break;
 
-            if (DoesPgpoolPidExist()) {
-                $tpl->assign('pgpoolStatus', 'pgpool stop failed. pgpool.pid exists.');
-            } else {
-                $tpl->assign('pgpoolStatus', 'pgpool stop succeed');
-            }
-        }
+        case 'promote':
+            if (_execPcp('PCP_PROMOTE_NODE', $nodeNumber, 'e1007') === FALSE) { exit(); }
+            break;
 
-        break;
+        /* --------------------------------------------------------------------- */
+        /* PostgreSQL                                                            */
+        /* --------------------------------------------------------------------- */
 
-    /* --------------------------------------------------------------------- */
-    /* restart                                                               */
-    /* --------------------------------------------------------------------- */
+        case 'startPgsql':
+            // ...
+            break;
 
-    case 'restart':
-        /**
-         * Stop pgpool
-         */
-        $m = $_POST['restart_mode'];
+        case 'stopPgsql':
+            _doPgCtl($nodeNumber, 'stop');
+            break;
 
-        $ret = execPcp('PCP_STOP_PGPOOL', $m);
-        if (!array_key_exists('SUCCESS', $ret)) {
-            $errorCode = 'e1006';
-            $tpl->assign('errorCode', $errorCode);
-            $tpl->display('error.tpl');
-            exit();
+        case 'restartPgsql':
+            _doPgCtl($nodeNumber, 'restart');
+            break;
 
-        } else {
-            for ($i = 0; $i < 10; $i++) {
-                if (DoesPgpoolPidExist()) {
-                    sleep(1);
-                } else {
-                    break;
-                }
-            }
-        }
+        case 'reloadPgsql':
+            $result = _doPgCtl($nodeNumber, 'reload');
+            $tpl->assign('status', ($result) ? 'success' : 'fail');
+            break;
 
-        if (DoesPgpoolPidExist()) {
-            $tpl->assign('pgpoolStatus', 'pgpool restart failed. pgpool.pid exists.');
+        case 'addBackend':
+            $result = _addNewBackend();
+            $tpl->assign('status', ($result) ? 'success' : 'fail');
             break;
-        }
 
-        /**
-         * Start pgpool
-         */
-        $args = ' ';
+        case 'removeBackend':
+            $result = _removeBackend();
+            $tpl->assign('status', ($result) ? 'success' : 'fail');
+            break;
 
-        if (isset($_POST['c'])) {
-            $args = $args . "-c ";
-        }
-        if (isset($_POST['D'])) {
-            $args = $args . "-D ";
-        }
-        if (isset($_POST['d'])) {
-            $args = $args . "-d ";
-        }
-        if (isset($_POST['n'])) {
-            $pgpoolLog = _PGPOOL2_LOG_FILE;
-            if ($pgpoolLog == '') {
-                $logDir = readLogDir();
-                $pgpoolLog = "$logDir/pgpool.log";
-            }
-            if (isPipe($pgpoolLog)) {
-                $args = "$args -n 2>&1 $pgpoolLog ";
-            } else {
-                $args = "$args -n > $pgpoolLog ";
+        /* --------------------------------------------------------------------- */
+        /* other                                                                 */
+        /* --------------------------------------------------------------------- */
+
+        case 'summary':
+            $viewPHP = 'innerSummary.php';
+            break;
+
+        case 'proc':
+            $viewPHP = 'procInfo.php';
+            break;
+
+        case 'watchdog':
+            $viewPHP = 'innerWatchdog.php';
+            break;
+
+        case 'node':
+            $viewPHP = 'nodeStatus.php';
+            break;
+
+        case 'log':
+            $viewPHP = 'innerLog.php';
+            break;
+    }
+
+    return $viewPHP;
+}
+
+/** Set node info from pgpool.conf when pgpool isn't active */
+function setNodeInfoFromConf()
+{
+    global $tpl;
+    global $is_pgpool_active;
+
+    if (!$is_pgpool_active) {
+        $nodeInfo = array();
+
+        $configValue = readConfigParams(array('backend_hostname', 'backend_port'));
+        if (isset($configValue['backend_hostname'])) {
+            foreach ($configValue['backend_hostname'] as $i => $backend_hostname) {
+                $nodeInfo[$i]['backend_hostname'] = $backend_hostname;
+                $nodeInfo[$i]['backend_port']     = $configValue['backend_port'][$i];
+                $nodeInfo[$i]['is_active']        = NodeActive($i);
             }
         }
-        if (isset($_POST['C'])) {
-            $args = $args . "-C ";
+        $tpl->assign('nodeInfo', $nodeInfo);
+    }
+
+    $configValue = readConfigParams('backend_hostname');
+    $tpl->assign('next_node_num', (isset($configValue['backend_hostname'])) ?
+                                  max(array_keys($configValue['backend_hostname'])) + 1 : 0);
+}
+
+/** Modify start options */
+function _setStartArgs()
+{
+    $args = ' ';
+
+    if (isset($_POST['c'])) {
+        $args = $args . "-c ";
+    }
+    if (isset($_POST['D'])) {
+        $args = $args . "-D ";
+    }
+    if (isset($_POST['d'])) {
+        $args = $args . "-d ";
+    }
+    if (isset($_POST['n'])) {
+        $pgpoolLog = _PGPOOL2_LOG_FILE;
+        if ($pgpoolLog == '') {
+            $logDir = readLogDir();
+            $pgpoolLog = "$logDir/pgpool.log";
         }
+        if (isPipe($pgpoolLog)) {
+            $args = "$args -n 2>&1 $pgpoolLog ";
+        } else {
+            $args = "$args -n > $pgpoolLog ";
+        }
+    }
+    if (isset($_POST['C'])) {
+        $args = $args . "-C ";
+    }
 
-        $ret = execPcp('PCP_START_PGPOOL', $args);
-        if (!array_key_exists('SUCCESS', $ret)) {
-            $tpl->assign('pgpoolStatus', 'pgpool restart failed.');
-            $tpl->assign('pgpoolMessage', $ret);
+    return $args;
+}
 
+/** Wait to find pgpool.pid */
+function _waitForPidFile()
+{
+    for ($i = 0; $i < PGPOOL_WAIT_SECONDS; $i++) {
+        if (DoesPgpoolPidExist()) {
+            return TRUE;
         } else {
-            for ($i = 0; $i < 10; $i++) {
-                if (DoesPgpoolPidExist()) {
-                    $tpl->assign('pgpoolStatus', 'pgpool restart succeed');
-                    break;
-                } else {
-                    sleep(1);
-                }
-            }
-            if (!DoesPgpoolPidExist()) {
-                $tpl->assign('pgpoolStatus', 'pgpool restart failed. pgpool.pid not found');
-            }
-            $tpl->assign('pgpoolMessage', $ret['SUCCESS']);
+            sleep(1);
         }
-        break;
-
-    /* --------------------------------------------------------------------- */
-    /* other                                                                 */
-    /* --------------------------------------------------------------------- */
-
-    case 'reload':
-        $args = ' ';
-        $ret = execPcp('PCP_RELOAD_PGPOOL', $args);
-        break;
-
-    case 'return':
-        $ret = execPcp('PCP_ATTACH_NODE', $nodeNumber);
-        if (!array_key_exists('SUCCESS', $ret)) {
-            $errorCode = 'e1010';
-            $tpl->assign('errorCode', $errorCode);
-            $tpl->display('error.tpl');
-            exit();
+    }
+    return FALSE;
+}
+
+/** Wait that pgpool.pid disappears */
+function _waitForNoPidFile()
+{
+    for ($i = 0; $i < PGPOOL_WAIT_SECONDS; $i++) {
+        if (DoesPgpoolPidExist()) {
+            sleep(1);
+        } else {
+            return TRUE;
         }
-        break;
-
-    case 'recovery':
-        $ret = execPcp('PCP_RECOVERY_NODE', $nodeNumber);
-        if (!array_key_exists('SUCCESS', $ret)) {
-            $errorCode = 'e1012';
-            $tpl->assign('errorCode', $errorCode);
-            $tpl->display('error.tpl');
-            exit();
+    }
+    return FALSE;
+}
+
+/** Start pgpool */
+function _startPgpool()
+{
+    global $tpl;
+
+    $args = _setStartArgs();
+    $result = execPcp('PCP_START_PGPOOL', $args);
+    if (!array_key_exists('SUCCESS', $result)) {
+        $pgpoolStatus = 'pgpool start failed.';
+        $pgpoolMessage = $result;
+
+    } else {
+        if (_waitForPidFile()) {
+            $pgpoolStatus = 'pgpool start succeed';
+        } else {
+            $pgpoolStatus = 'pgpool start failed. pgpool.pid not found';
         }
-        break;
-
-    case 'detach':
-        $ret = execPcp('PCP_DETACH_NODE', $nodeNumber);
-        if (!array_key_exists('SUCCESS', $ret)) {
-            $errorCode = 'e1007';
-            $tpl->assign('errorCode', $errorCode);
-            $tpl->display('error.tpl');
-            exit();
+        $pgpoolMessage = $result['SUCCESS'];
+    }
+
+    $tpl->assign('pgpoolStatus', $pgpoolStatus);
+    $tpl->assign('pgpoolMessage', $pgpoolMessage);
+}
+
+/** Stop pgpool */
+function _stopPgpool()
+{
+    global $_POST;
+    global $tpl;
+
+    $m = $_POST['stop_mode'];
+
+    $result = execPcp('PCP_STOP_PGPOOL', $m);
+    if (!array_key_exists('SUCCESS', $result)) {
+        $errorCode = 'e1006';
+        $tpl->assign('errorCode', $errorCode);
+        $tpl->display('error.tpl');
+        exit();
+
+    } else {
+        if (_waitForNoPidFile()) {
+            $pgpoolStatus = 'pgpool stop succeed';
+        } else {
+            $pgpoolStatus = 'pgpool stop failed. pgpool.pid exists.';
         }
-        break;
-
-    case 'promote':
-        $ret = execPcp('PCP_PROMOTE_NODE', $nodeNumber);
-        if (!array_key_exists('SUCCESS', $ret)) {
-            $errorCode = 'e1007';
-            $tpl->assign('errorCode', $errorCode);
-            $tpl->display('error.tpl');
-            exit();
+        $tpl->assign('pgpoolStatus', $pgpoolStatus);
+    }
+}
+
+/** Restart pgpool */
+function _restartPgpool()
+{
+    global $_POST;
+    global $tpl;
+
+    // Stop pgpool
+    $m = $_POST['stop_mode'];
+
+    $result = execPcp('PCP_STOP_PGPOOL', $m);
+    if (!array_key_exists('SUCCESS', $result)) {
+        $errorCode = 'e1006';
+        $tpl->assign('errorCode', $errorCode);
+        $tpl->display('error.tpl');
+        exit();
+    }
+
+    if (_waitForNoPidFile()) {
+        // Start pgpool
+        $args = _setStartArgs();
+        $result = execPcp('PCP_START_PGPOOL', $args);
+        if (!array_key_exists('SUCCESS', $result)) {
+            $pgpoolStatus = 'pgpool restart failed.';
+            $pgpoolMessage = $result;
+
+        } else {
+            if (_waitForPidFile()) {
+                $pgpoolStatus = 'pgpool restart succeed';
+            } else {
+                $pgpoolStatus = 'pgpool restart failed. pgpool.pid not found';
+            }
+            $pgpoolMessage = $result['SUCCESS'];
         }
-        break;
 
-    case 'summary':
-        $viewPHP = 'innerSummary.php';
-        break;
+    } else {
+        $pgpoolStatus = 'pgpool restart failed. pgpool.pid exists.';
+    }
+
+    $tpl->assign('pgpoolStatus', $pgpoolStatus);
+    $tpl->assign('pgpoolMessage', $pgpoolMessage);
+}
+
+/** Execute PCP command with node number */
+function _execPcp($pcp_command, $nodeNumber, $errorCode)
+{
+    global $tpl;
 
-    case 'proc':
-        $viewPHP = 'procInfo.php';
-        break;
+    $result = execPcp($pcp_command, $nodeNumber);
 
-    case 'node':
-        $viewPHP = 'nodeStatus.php';
-        break;
+    if (!array_key_exists('SUCCESS', $result)) {
+        $tpl->assign('errorCode', $errorCode);
+        $tpl->display('error.tpl');
+        return FALSE;
+    }
 
-    case 'log':
-        $viewPHP = 'innerLog.php';
-        break;
+    return TRUE;
 }
 
-if (DoesPgpoolPidExist()) {
-    $tpl->assign('pgpoolIsActive', TRUE);
-} else {
-    $tpl->assign('pgpoolIsActive', FALSE);
+/** Add a new backend and reload conf */
+function _addNewBackend()
+{
+    global $is_pgpool_active;
+    global $_POST;
+
+    // Check
+    if ($_POST['backend_hostname'][0] == NULL || $_POST['backend_port'][0] == NULL ||
+        $_POST['backend_weight'][0] == NULL)
+    {
+        return FALSE;
+    }
+
+    // Get next nodeNumber
+    $configValue = readConfigParams('backend_hostname');
+    $i = (isset($configValue['backend_hostname'])) ?
+         max(array_keys($configValue['backend_hostname'])) + 1 : 0;
+
+    // add
+    $lines[] = "backend_hostname{$i} = '{$_POST['backend_hostname'][0]}'\n";
+    $lines[] = "backend_port{$i} = {$_POST['backend_port'][0]}\n";
+    $lines[] = "backend_weight{$i} = {$_POST['backend_weight'][0]}\n";
+    $lines[] = "backend_data_directory{$i} = '{$_POST['backend_data_directory'][0]}'\n";
+    if (paramExists('backend_flag')) {
+        $lines[] = "backend_flag{$i}= '{$_POST['backend_flag'][0]}'\n";
+    }
+
+    // Write pgpool.conf
+    $outfp = fopen(_PGPOOL2_CONFIG_FILE, 'a');
+    if (!$outfp) { return FALSE; }
+    foreach ($lines as $line) {
+        if (fputs($outfp, $line) === FALSE) {
+            return FALSE;
+        }
+    }
+    fclose($outfp);
+
+    // Reload pgpool
+    $result = TRUE;
+    if (isset($_POST['reload_ok']) && $is_pgpool_active) {
+        $result = execPcp('PCP_RELOAD_PGPOOL', NO_ARGS);
+    }
+
+    return $result;
 }
 
-if (_PGPOOL2_STATUS_REFRESH_TIME >= 0 ) {
-    $refreshTime = _PGPOOL2_STATUS_REFRESH_TIME * 1000;
+/** Remove a backend and reload conf */
+function _removeBackend()
+{
+    global $is_pgpool_active;
+    global $_POST;
+
+    if (!isset($_POST['nodeNumber'])) { return FALSE; }
+    $nodeNumber = $_POST['nodeNumber'];
+
+    // Read execept backend info of node $nodeNumber
+    $lines_to_write = array();
+    $fd = fopen(_PGPOOL2_CONFIG_FILE, 'r');
+    if (!$fd) { return FALSE; }
+    while (!feof($fd)) {
+        $line = fgets($fd);
+
+        if (strpos($line, "backend_hostname") !== FALSE ||
+            strpos($line, "backend_port") !== FALSE ||
+            strpos($line, "backend_weight") !== FALSE ||
+            strpos($line, "backend_data_directory") !== FALSE ||
+            strpos($line, "backend_flag") !== FALSE)
+        {
+            continue;
+        }
+        $lines_to_write[] = $line;
+    }
+    fclose($fd);
+
+
+    // Get all the current backends' info
+    $params = readConfigParams(array('backend_hostname', 'backend_port', 'backend_weight',
+                                     'backend_data_directory', 'backend_flag'));
+    $i = 0;
+    foreach ($params['backend_hostname'] as $old_i => $arr) {
+        if ($old_i == $nodeNumber) { continue; }
+
+        $lines_to_write[] = "backend_hostname{$i} = '{$params['backend_hostname'][$old_i]}'\n";
+        $lines_to_write[] = "backend_port{$i} = {$params['backend_port'][$old_i]}\n";
+        $lines_to_write[] = "backend_weight{$i} = {$params['backend_weight'][$old_i]}\n";
+        $lines_to_write[] = "backend_data_directory{$i} = '{$params['backend_data_directory'][$old_i]}'\n";
+        if (paramExists('backend_flag')) {
+            $lines_to_write[] = "backend_flag{$i} = '{$params['backend_flag'][$old_i]}'\n";
+        }
+        $i++;
+    }
+
+    // Write editted lines
+    $fd = fopen(_PGPOOL2_CONFIG_FILE, 'w');
+    if (!$fd) { return FALSE; }
+    foreach ($lines_to_write as $line) {
+        if (fputs($fd, $line) === FALSE) {
+            return FALSE;
+        }
+    }
+    fclose($fd);
+
+    // Reload pgpool
+    $result = TRUE;
+    if ($is_pgpool_active) {
+        $result = execPcp('PCP_RELOAD_PGPOOL', NO_ARGS);
+    }
+    return $result;
 }
 
-$tpl->assign('viewPHP',       $viewPHP);
-$tpl->assign('pgpoolConf',    _PGPOOL2_CONFIG_FILE);
-$tpl->assign('pcpConf',       _PGPOOL2_PASSWORD_FILE);
-$tpl->assign('refreshTime',   $refreshTime);
-$tpl->assign('useSyslog',     useSyslog());
-$tpl->assign('msgStopPgpool', $message['msgStopPgpool']);
-$tpl->display('status.tpl');
+/** Execute pg_ctl through pgpool_pgctl() */
+function _doPgCtl($nodeNumber, $pg_ctl_action)
+{
+    global $_POST;
 
-?>
+    if (isSuperUser($_SESSION[SESSION_LOGIN_USER]) == FALSE) { return FALSE; }
+
+    $conn = @pg_connect(conStr($nodeNumber));
+    $query = sprintf("SELECT pgpool_pgctl('%s', '%s')",
+                     $pg_ctl_action,
+                     (isset($_POST['stop_mode'])) ? $_POST['stop_mode'] : NULL);
+    $result = execQuery($conn, $query);
+
+    return $result;
+}
diff --git a/templates/elements/pgconfig_new_backend.tpl b/templates/elements/pgconfig_new_backend.tpl
new file mode 100644 (file)
index 0000000..a58a289
--- /dev/null
@@ -0,0 +1,37 @@
+<tr>
+<th><label>{$message.descBackend_hostname|escape}</label>
+<br />backend_hostname{$smarty.section.num.index} (string)</th>
+<td><input type="text" id="backend_hostname" name="backend_hostname[]" value="" /></td>
+<td rowspan="{if paramExists('backend_flag')}5{else}4{/if}">
+</tr>
+
+</tr>
+<tr>
+<th><label>{$message.descBackend_port|escape}</label>
+<br />backend_port{$smarty.section.num.index|escape} (integer)</th>
+<td><input type="text" id="backend_port" name="backend_port[]" value="" /></td>
+</tr>
+
+<tr>
+<th><label>{$message.descBackend_weight|escape}</label>
+<br />backend_weight{$smarty.section.num.index|escape} (float)</th>
+<td><input type="text" id="backend_weight" name="backend_weight[]" value="" /></td>
+</tr>
+
+<tr>
+<th><label>{$message.descBackend_data_directory|escape}</label>
+<br />backend_data_directory{$smarty.section.num.index|escape} (string)</th>
+<td><input type="text" name="backend_data_directory[]" value="" /></td>
+</tr>
+
+{if paramExists('backend_flag')}
+<tr>
+<th><label>{$message.descBackend_flag|escape}</label>
+    <br />backend_flag{$smarty.section.num.index|escape} *</th>
+<td><select name="backend_flag[]" id="backend_flag[]">
+    <option value="ALLOW_TO_FAILOVER" selected>ALLOW_TO_FAILOVER</option>
+    <option value="DISALLOW_TO_FAILOVER">DISALLOW_TO_FAILOVER</option>
+    </select>
+</td>
+</tr>
+{/if}
diff --git a/templates/elements/status_js.tpl b/templates/elements/status_js.tpl
new file mode 100644 (file)
index 0000000..f53be72
--- /dev/null
@@ -0,0 +1,203 @@
+<script type="text/javascript">
+<!--
+var refreshTime  = "{$refreshTime|escape}";
+var refreshTimeLog  = "{$refreshTimeLog|escape}";
+var view         = "{$viewPHP|escape}";
+var msgStartPgpool   = "{$message.msgStartPgpool|escape}";
+var msgStopPgpool    = "{$message.msgStopPgpool|escape}";
+var msgRestartPgpool = "{$message.msgRestartPgpool|escape}";
+var msgAddBackend    = "{$message.msgAddBackend|escape}";
+var msgAddBackendNg  = "{$message.msgAddBackendNg|escape}";
+
+{literal}
+
+/* --------------------------------------------------------------------- */
+/* page reloading                                                        */
+/* --------------------------------------------------------------------- */
+
+function load()
+{
+    var xmlhttp = false;
+    if (typeof XMLHttpRequest!='undefined') {
+        xmlhttp = new XMLHttpRequest();
+    } else {
+        xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
+    }
+
+    if (!xmlhttp) {
+        alert('Sorry, cannot use XMLHttpRequest');
+        return;
+    }
+
+    xmlhttp.onreadystatechange = function()
+    {
+        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
+            var content = document.getElementById('div_status');
+            var ret = xmlhttp.responseText;
+            if (content == null) { return; }
+
+            content.innerHTML  = ret;
+            if (view != "innerLog.php") {
+                setTimeout("load()", refreshTimeLog);
+            } else if (refreshTime > 0) {
+                setTimeout("load()", refreshTime);
+            }
+        }
+    }
+    xmlhttp.open('GET', view, true);
+    xmlhttp.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
+    xmlhttp.send("");
+}
+
+function sendCommand(command, nodeNumber, message)
+{
+    if (window.confirm(message)) {
+        document.commandForm.action.value= command;
+        document.commandForm.nodeNumber.value= nodeNumber;
+        document.commandForm.submit();
+    }
+}
+
+/* --------------------------------------------------------------------- */
+/* When a button clicked                                                 */
+/* --------------------------------------------------------------------- */
+
+function _setVisible(id, visible)
+{
+    var button = document.getElementById(id);
+
+    if (visible) {
+        button.style.visibility = "visible";
+        button.style.position   = "";
+        button.style.height     = "";
+
+    } else {
+        button.style.visibility = "hidden";
+        button.style.position   = "absolute";
+        button.style.height     = "0";
+    }
+}
+
+function stopPgpoolButtonHandler()
+{
+    _setVisible('stopPgpoolOptionDiv', true);
+    _setVisible('commandButtonsDiv',   false);
+    document.stopPgpoolForm.action.value = 'stopPgpool';
+}
+
+function restartPgpoolButtonHandler()
+{
+    _setVisible('stopPgpoolOptionDiv',    false);
+    _setVisible('restartPgpoolOptionDiv', true);
+    _setVisible('commandButtonsDiv',      false);
+    document.restartPgpoolForm.action.value = 'restartPgpool';
+}
+
+function cancelPgpoolButtonHandler()
+{
+    _setVisible('stopPgpoolOptionDiv',    false);
+    _setVisible('restartPgpoolOptionDiv', false);
+    _setVisible('commandButtonsDiv',      true);
+}
+
+function execStartPgpool()   { execute('startPgpool',   msgStartPgpool,   null); }
+function execStopPgpool()    { execute('stopPgpool',    msgStopPgpool,    null); }
+function execReloadPgpool()  { execute('reloadPgpool',  msgReloadPgpool,  null); }
+function execRestartPgpool() { execute('restartPgpool', msgRestartPgpool, null); }
+
+/* --------------------------------------------------------------------- */
+/* execute PostgreSQL's command                                          */
+/* --------------------------------------------------------------------- */
+
+function stopPgsqlButtonHandler(nodeNumber)
+{
+    _setVisible('stopPgsqlDiv', true);
+    _setVisible('restartPgsqlDiv', false);
+    document.stopPgsqlForm.action.value = 'stopPgsql';
+    document.stopPgsqlForm.nodeNumber.value = nodeNumber;
+}
+
+function restartPgsqlHandler(nodeNumber)
+{
+    _setVisible('stopPgsqlDiv', false);
+    _setVisible('restartPgsqlDiv', true);
+    document.stopPgsqlForm.action.value = 'restartPgsql';
+    document.restartPgsqlForm.nodeNumber.value = nodeNumber;
+}
+
+//function execStartPgsql()   { execute('startPgsql',   null); }
+function execRestartPgsql() { execute('restartPgsql', msgRestartPgsql); }
+function execStopPgsql()    { execute('stopPgsql',    msgStopPgsql); }
+function execReloadPgsql(nodeNumber)  { execute('reloadPgsql', msgReloadPgsql, nodeNumber); }
+
+/* --------------------------------------------------------------------- */
+/* Add/remove backend node                                               */
+/* --------------------------------------------------------------------- */
+
+function addBackendButtonHandler()
+{
+    _setVisible('addBackendDiv', true);
+}
+
+function cancelButtonHandler(div_name)
+{
+    _setVisible(div_name, false);
+}
+
+function checkAddForm()
+{
+    // Check if not empty
+    msg = "";
+    if (document.getElementById('backend_hostname').value == '') {
+        msg += "- backend_hostname\n";
+    }
+
+    port = document.getElementById('backend_port').value;
+    if (port == '' || !isInteger(port)) {
+        msg += "- backend_port\n";
+    }
+
+    weight = document.getElementById('backend_weight').value;
+    if (weight == '' || !isFloat(weight)) {
+        msg += "- backend_weight\n";
+    }
+    if (msg != "") {
+        alert(msgAddBackendNg + "\n" + msg);
+        return false;
+    }
+
+    return confirm(msgAddBackend);
+}
+
+function isInteger(num) { return num.match(/^[0-9]+$/); }
+function isFloat(num) { return num.match(/^[0-9]+\.?[0-9]?$/); }
+
+function execRemoveBackend(node_num)
+{
+    execute('removeBackend', msgRemoveBackend, node_num);
+}
+
+/* --------------------------------------------------------------------- */
+/* execute pgpool's commands                                             */
+/* --------------------------------------------------------------------- */
+
+function execute(action, confirm_text, node_num)
+{
+    elements = document.getElementsByName(action + 'Form');
+    if (elements.length != 1) { alert('Unknown error.'); return; }
+    target_form = elements[0];
+
+    if (confirm_text == null || window.confirm(confirm_text)) {
+        target_form.action.value = action;
+        if (node_num != null) {
+            target_form.nodeNumber.value = node_num;
+        }
+        target_form.submit();
+    }
+}
+
+function changeView(chView)  { execute(chView, null, null); }
+
+// -->
+</script>
+{/literal}
diff --git a/templates/elements/status_nodeinfo.tpl b/templates/elements/status_nodeinfo.tpl
new file mode 100644 (file)
index 0000000..2161343
--- /dev/null
@@ -0,0 +1,174 @@
+<h3>{$message.strNodeInfo|escape}</h3>
+
+{if $smarty.const._PGPOOL2_STATUS_REFRESH_TIME > 0}
+    <div class="auto_reloading">
+    <span><img src="images/refresh.png">
+          Refresh info: {$smarty.const._PGPOOL2_STATUS_REFRESH_TIME} seconds
+    </span>
+    </div>
+    <br clear="all">
+{/if}
+
+{if $nodeCount > 0}
+    {if $has_not_loaded_node}<p>*) {$message.msgHasNotLoadedNode}</p>{/if}
+
+    <table>
+      <thead>
+      <tr>
+        <th></th>
+        <th><label>{$message.strIPaddress|escape}</label></th>
+        <th><label>{$message.strPort|escape}</label></th>
+        <th colspan="2"><label>{$message.strStatus|escape}</label></th>
+        {if $parallelMode == false}
+        <th><label>{$message.strWeight|escape}</label></th>
+        {/if}
+        <th></th>
+        <th></th>
+      </tr>
+      </thead>
+
+    <tbody>
+    {$i = 0}
+    {foreach from=$nodeInfo key=node_num item=v}
+        {$i = $i + 1}
+        <tr class="{if $i % 2 == 0}even{else}odd{/if}">
+
+        {* ---------------------------------------------------------------------- *}
+        {* node info (IP address, port)                                           *}
+        {* ---------------------------------------------------------------------- *}
+
+        <td>node {$node_num}</td>
+        <td>{$nodeInfo.$node_num.hostname|escape}</td>
+        <td>{$nodeInfo.$node_num.port|escape}</td>
+
+        {* ---------------------------------------------------------------------- *}
+        {* status                                                                 *}
+        {* ---------------------------------------------------------------------- *}
+
+        {if $nodeInfo.$node_num.status != $smarty.const.NODE_NOT_LOADED}
+            <td>
+            {if $nodeInfo.$node_num.status == $smarty.const.NODE_ACTIVE_NO_CONNECT}
+                {$message.strNodeStatus1|escape}
+            {elseif $nodeInfo.$node_num.status == $smarty.const.NODE_ACTIVE_CONNECTED}
+                {$message.strNodeStatus2|escape}
+            {elseif $nodeInfo.$node_num.status == $smarty.const.NODE_DOWN}
+                {$message.strNodeStatus3|escape}
+            {/if}
+
+            {if $nodeInfo.$node_num.is_standby == 1}
+                {$message.strStandbyRunning|escape}
+            {elseif $nodeInfo.$node_num.is_standby === 0}
+                {$message.strPrimaryRunning|escape}
+            {/if}
+            </td>
+        {else}
+            <td align="center">-</td>
+        {/if}
+
+        <td>postgres:
+            {if $nodeInfo.$node_num.is_active}{$message.strUp|escape}
+            {else}{$message.strDown|escape}
+            {/if}
+        </td>
+
+        {* ---------------------------------------------------------------------- *}
+        {* weight                                                                 *}
+        {* ---------------------------------------------------------------------- *}
+
+        {if $parallelMode == false}
+            {if $nodeInfo.$node_num.status != $smarty.const.NODE_NOT_LOADED}
+                <td>{$nodeInfo.$node_num.weight|escape}</td>
+            {else}
+                <td align="center">-</td>
+            {/if}
+        {/if}
+
+        {* ---------------------------------------------------------------------- *}
+        {* buttons (attch, recovery, etc.)                                        *}
+        {* ---------------------------------------------------------------------- *}
+
+        <td nowrap>
+        {if $nodeInfo.$node_num.disconnect}
+          <input type="button" name="command"
+                 onclick="sendCommand('detach', {$node_num|escape},
+                                      '{$message.msgDetachConfirm|escape}')"
+                  value="{$message.strDisconnect|escape}" />
+
+        {elseif $nodeInfo.$node_num.return}
+          <input type="button" name="command"
+                 onclick="sendCommand('return', {$node_num|escape},
+                                      '{$message.msgReturnConfirm|escape}')"
+                 value="{$message.strReturn|escape}" />
+
+        {elseif $nodeInfo.$node_num.recovery}
+          {if $params.recovery_1st_stage_command != NULL}
+              <input type="button" name="command"
+                     onclick="sendCommand('recovery', {$node_num|escape},
+                                          '{$message.msgRecoveryConfirm|escape}')"
+                     value="{$message.strRecovery|escape}" />
+          {else}
+              <input type="button" name="command"
+                     title="Please set recovery_1st_stage_command." disabled
+                     value="{$message.strRecovery|escape}" />
+          {/if}
+        {/if}
+
+        {if $nodeInfo.$node_num.promote && $nodeInfo.$node_num.is_standby == 1}
+          <input type="button" name="command"
+                 onclick="sendCommand('promote', {$node_num|escape},
+                                      '{$message.msgRPromoteConfirm|escape}')"
+                 value="{$message.strPromote|escape}" />
+        {/if}
+        </td>
+
+        {* ---------------------------------------------------------------------- *}
+        {* buttons (start, stop, etc.)                                            *}
+        {* ---------------------------------------------------------------------- *}
+
+        <td nowrap>{include file="elements/status_pgsql_buttons.tpl"}</td>
+        </tr>
+    {/foreach}
+    </tbody>
+
+      <tfoot>
+      <tr><th colspan="8" align="right">
+          <input type="button" id="button_add_backend" onClick="addBackendButtonHandler()"
+                 value="{$message.strAddBackend|escape}" />
+          </th>
+      </tr>
+      </tfoot>
+
+    </table>
+
+{else}
+    {$message.strNoNode|escape}
+{/if}
+
+
+<p>[ mode ]
+{if $params.replication_mode == 'on'}
+    {$message.strReplicationMode|escape}
+{elseif $params.master_slave_mode == 'on'}
+    {$message.strMasterSlaveMode|escape}
+{/if}
+{if $params.load_balance_mode == 'on'} / {$message.strLoadBalanceMode|escape}{/if}
+{if $params.memory_cache_enabled == 'on'} / {$message.strQueryCache|escape} {$message.strOn|escape}{/if}
+{if $params.use_watchdog == 'on'} / Watchdog {$message.strOn|escape}{/if}
+</p>
+<p>
+[ healthcheck ]
+every {$params.health_check_period} seconds /
+retry upto {$params.health_check_max_retries} counts
+</p>
+
+
+{* ---------------------------------------------------------------------- *}
+{* Command form to execute a command without any option                   *}
+{* ---------------------------------------------------------------------- *}
+
+<div id="commandDiv">
+<form action="status.php" name="commandForm" method="post" />
+  <input type="hidden" name="action" />
+  <input type="hidden" name="nodeNumber" />
+</form>
+</div>
diff --git a/templates/elements/status_options.tpl b/templates/elements/status_options.tpl
new file mode 100644 (file)
index 0000000..79e8446
--- /dev/null
@@ -0,0 +1,109 @@
+{* --------------------------------------------------------------------- *}
+{* Start Options                                                         *}
+{* --------------------------------------------------------------------- *}
+
+{if $pgpoolIsActive == false}
+    <h3>{$message.strStartOption|escape}</h3>
+
+    <form action="status.php" name="startPgpoolForm" method="post">
+    <input type="hidden" name="action" value="startPgpool" />
+    <input type="hidden" name="nodeNumber" value="" />
+
+    <table>
+    <thead><tr><th colspan="2">{$message.strStartOption|escape}</th></tr></thead>
+    <tbody>
+    {include file="elements/status_start_option.tpl"}
+    </tbody>
+    <tfoot><tr>
+      <td colspan="2">
+      <input type="button" name="command" onclick="execStartPgpool()"
+             value="{$message.strStartPgpool|escape}" />
+      </td>
+    </tr></tfoot>
+    </table>
+    </form>
+
+{else}
+    {* --------------------------------------------------------------------- *}
+    {* Command Buttons                                                       *}
+    {* --------------------------------------------------------------------- *}
+
+    <div id="commandButtonsDiv" style="visibility: visible">
+    <input type="button" name="command" onclick="stopPgpoolButtonHandler()"
+           value="{$message.strStopPgpool|escape}" />
+    <input type="button" name="command" onclick="restartPgpoolButtonHandler()"
+           value="{$message.strRestartPgpool|escape}" />
+    <input type="button" name="command" onclick="execReloadPgpool()"
+           value="{$message.strReloadPgpool|escape}" />
+    </div>
+
+    {* --------------------------------------------------------------------- *}
+    {* Stop Options                                                          *}
+    {* --------------------------------------------------------------------- *}
+    <div id="stopPgpoolOptionDiv" style="visibility: hidden; position: absolute">
+    <h3>{$message.strStopOption|escape}</h3>
+
+    <form action="status.php" name="stopPgpoolForm" method="post">
+    <input type="hidden" name="action" value="stopPgpool" />
+    <input type="hidden" name="nodeNumber" value="" />
+    <table>
+    <thead><tr><th colspan="2">{$message.strStopOption|escape}</th></tr></thead>
+    <tfoot><tr>
+      <td colspan="2">
+      <input type="button" name="command" onclick="execStopPgpool()"
+             value="{$message.strExecute|escape}" />
+      <input type="button" name="command" onclick="cancelPgpoolButtonHandler()"
+             value="{$message.strCancel|escape}" />
+      </td>
+    </tr></tfoot>
+    <tbody>
+    {include file="elements/status_stop_option.tpl"}
+    </tbody>
+    </table>
+    </form>
+    </div>
+
+    {* --------------------------------------------------------------------- *}
+    {* Restart Options                                                       *}
+    {* --------------------------------------------------------------------- *}
+    <div id="restartPgpoolOptionDiv" style="visibility: hidden; position: absolute">
+    <h3>{$message.strRestartOption|escape}</h3>
+
+    <form action="status.php" name="restartPgpoolForm" method="post">
+    <input type="hidden" name="action" value="restartPgpool" />
+    <input type="hidden" name="nodeNumber" value="" />
+    <table>
+    <thead><tr><th colspan="2">{$message.strRestartOption|escape}</th></tr></thead>
+    <tfoot><tr>
+      <td colspan="2">
+      <input type="button" name="command" onclick="execRestartPgpool()"
+             value="{$message.strExecute|escape}" />
+      <input type="button" name="command" onclick="cancelPgpoolButtonHandler()"
+             value="{$message.strCancel|escape}" />
+      </td>
+    </tr></tfoot>
+    <tbody>
+    {include file="elements/status_stop_option.tpl"}
+    {include file="elements/status_start_option.tpl"}
+    </tbody>
+    </table>
+    </form>
+    </div>
+
+{/if}
+
+{* --------------------------------------------------------------------- *}
+{* Start/Stop/Restart messages                                           */
+{* --------------------------------------------------------------------- *}
+
+{if isset($pgpoolStatus)}
+    <div class="message">
+    <h3>Messages</h3>
+        <p>{$pgpoolStatus|escape}</p>
+        <p>
+        {foreach from=$pgpoolMessage item=lines}
+        {$lines|escape}<br />
+        {/foreach}
+        </p>
+    </div>
+{/if}
diff --git a/templates/elements/status_pgsql_buttons.tpl b/templates/elements/status_pgsql_buttons.tpl
new file mode 100644 (file)
index 0000000..431e7bf
--- /dev/null
@@ -0,0 +1,15 @@
+<input type="button" onClick="stopPgsqlButtonHandler({$node_num})"
+       {if $nodeInfo.$node_num.is_active == false}disabled{/if}
+       value="{$message.strStopPgsql|escape}">
+
+<input type="button" onClick="restartPgsqlHandler({$node_num})"
+       {if $nodeInfo.$node_num.is_active == false}disabled{/if}
+       value="{$message.strRestartPgsql|escape}">
+
+<input type="button" onClick="sendCommand('reloadPgsql', {$node_num}, '{$message.msgReloadPgpool|escape}')"
+       {if $nodeInfo.$node_num.is_active == false}disabled{/if}
+       value="{$message.strReloadPgsql|escape}">
+|
+<input type="button" onClick="sendCommand('removeBackend', {$node_num}, '{$message.msgRemoveBackend|escape}')"
+       {if $pgpoolIsActive && $nodeInfo.$node_num.is_active}disabled{/if}
+       value="{$message.strRemoveBackend|escape}">
diff --git a/templates/elements/status_pgsql_options.tpl b/templates/elements/status_pgsql_options.tpl
new file mode 100644 (file)
index 0000000..ca4532a
--- /dev/null
@@ -0,0 +1,47 @@
+{* stop option *}
+<div id="stopPgsqlDiv" style="visibility: hidden; position: absolute;">
+<h3>{$message.strStopPgsqlOption|escape}</h3>
+<form action="status.php" name="stopPgsqlForm" method="post"
+      onSubmit="return execStopPgsql()" />
+<table>
+<thead>
+    <tr><th colspan="2">{$message.strCmdM|escape}(-m)</th></tr>
+</thead>
+<tbody>
+    {include file="elements/status_stop_option.tpl"}
+</tbody>
+<tfoot>
+    <tr><td colspan="2">
+    <input type="submit"
+           value="{$message.strStopPgsql|escape}" />
+    <input type="button" name="command" onclick="cancelButtonHandler('stopPgsqlDiv')"
+           value="{$message.strCancel|escape}" />
+    </td></tr>
+</tfoot>
+</table>
+</form>
+</div>
+
+{* restart option *}
+<div id="restartPgsqlDiv" style="visibility: hidden; position: absolute;">
+<h3>{$message.strRestartPgsqlOption|escape}</h3>
+<form action="status.php" name="restartPgsqlForm" method="post"
+      onSubmit="return execRestartPgsql()" />
+<table>
+<thead>
+    <tr><th colspan="2">{$message.strCmdM|escape}(-m)</th></tr>
+</thead>
+<tbody>
+    {include file="elements/status_stop_option.tpl"}
+</tbody>
+<tfoot>
+    <tr><td colspan="2">
+    <input type="submit"
+           value="{$message.strRestartPgsql|escape}" />
+    <input type="button" name="command" onclick="cancelButtonHandler('restartPgsqlDiv')"
+           value="{$message.strCancel|escape}" />
+    </td></tr>
+</tfoot>
+</table>
+</form>
+</div>
diff --git a/templates/elements/status_start_option.tpl b/templates/elements/status_start_option.tpl
new file mode 100644 (file)
index 0000000..5c2ebaf
--- /dev/null
@@ -0,0 +1,51 @@
+{if hasMemqCache() == false}
+    <tr><td>{$message.strCmdC|escape} (-c)</td>
+      {if $c == 1}
+      <td><input type="checkbox" name="c" checked="checked" /></td>
+      {else}
+      <td><input type="checkbox" name="c" /></td>
+      {/if}
+    </tr>
+{/if}
+
+<tr><td>{$message.strCmdLargeD|escape} (-D)</td>
+  {if $D == 1}
+  <td><input type="checkbox" name="D" checked="checked" /></td>
+  {else}
+  <td><input type="checkbox" name="D" /></td>
+  {/if}
+</tr>
+
+<tr><td>{$message.strCmdN|escape} (-n)</td>
+  {if $n == 1}
+  <td><input type="checkbox" name="n" checked="checked" /></td>
+  {else}
+  <td><input type="checkbox" name="n" /></td>
+  {/if}
+</tr>
+
+{if hasMemqCache()}
+<tr><td>{$message.strCmdLargeC|escape} (-C)</td>
+  {if $C == 1}
+  <td><input type="checkbox" name="C" checked="checked" /></td>
+  {else}
+  <td><input type="checkbox" name="C" /></td>
+  {/if}
+</tr>
+{/if}
+
+<tr><td>{$message.strCmdD|escape} (-d)</td>
+  {if $d == 1}
+  <td><input type="checkbox" name="d" checked="checked" /></td>
+  {else}
+  <td><input type="checkbox" name="d" /></td>
+  {/if}
+</tr>
+
+<tr><td>{$message.strCmdPgpoolFile|escape} (-f)</td>
+    <td>{$pgpoolConf|escape}</td>
+</tr>
+
+<tr><td>{$message.strCmdPcpFile|escape} (-F)</td>
+    <td>{$pcpConf|escape}</td>
+</tr>
diff --git a/templates/elements/status_stop_option.tpl b/templates/elements/status_stop_option.tpl
new file mode 100644 (file)
index 0000000..513f56b
--- /dev/null
@@ -0,0 +1,25 @@
+<tr><td>{$message.strCmdM|escape}(-m)</td><td>
+  <select name="stop_mode">
+  {if $m == 's'}
+       <option value="s" selected="selected">smart</option>
+       <option value="f">fast</option>
+       <option value="i">immediate</option>
+  {elseif $m == 'f'}
+       <option value="s">smart</option>
+       <option value="f" selected="selected">fast</option>
+       <option value="i">immediate</option>
+  {elseif $m == 'i'}
+       <option value="s">smart</option>
+       <option value="f">fast</option>
+       <option value="i" selected="selected">immediate</option>
+  {else}
+       <option value="s">smart</option>
+       <option value="f">fast</option>
+       <option value="i">immediate</option>
+  {/if}
+  </select>
+
+  <input type="hidden" name="action" />
+  <input type="hidden" name="nodeNumber" />
+  </td>
+</tr>
index 9f071bf6980a282cd4ebf9b748b107bbd677b5b1..ea7cf04abf0c8150f44ef24c7a2312ebb8f77f97 100644 (file)
@@ -6,14 +6,26 @@
 <link href="screen.css" rel="stylesheet" type="text/css" />
 </head>
 <body>
+
+<h3>{$message.strLog|escape}</h3>
+
+{if $smarty.const._PGPOOL2_STATUS_REFRESH_TIME > 0}
+    <div class="auto_reloading">
+    <span><img src="images/refresh.png">
+          Refresh info: {$refreshTimeLog} seconds
+    </span>
+    </div>
+    <br clear="all">
+{/if}
+
 <table>
   <thead>
   </thead>
   <tbody>
   {section name=num loop=$logFile}
-    {if $logFile[num][2] == 'ERROR:' }
+    {if $logFile[num]['level'] == 'ERROR:' }
     <tr class="error">
-    {elseif  ($smarty.section.num.index+1) % 2 == 0}
+    {elseif  ($smarty.section.num.index + 1) % 2 == 0}
     <tr class="even">
     {else}
     <tr class="odd">
index 4750d15999fdd98d197561a80a26d61be86e8441..4834b837bd0005676f58fbfc66a80606393febff 100644 (file)
 <table>
   <thead>
   <tr>
+    <th></th>
     <th><label>{$message.strIPaddress|escape}</label></th>
     <th><label>{$message.strPort|escape}</label></th>
-    <th><label>{$message.strStatus|escape}</label></th>
+    <th colspan="2"><label>{$message.strStatus|escape}</label></th>
     <th></th>
   </thead>
   <tbody>
-  {section name=num loop=$nodeServerStatus}
-    {if ($smarty.section.num.index+1) % 2 == 0}
-    <tr class="even">
-    {else}
-    <tr class="odd">
+  {$i = 0}
+  {foreach from=$nodeServerStatus key=node_num item=v}
+    {$i = $i + 1}
+    <tr class="{if $i % 2 == 0}even{else}odd{/if}">
+    <td class="input">node {$node_num}</td>
+    <td class="input">{$nodeServerStatus.$node_num.hostname|escape}</td>
+    <td class="input">{$nodeServerStatus.$node_num.port|escape}</td>
+    <td>
+    {if $pgpoolIsActive}
+        {if $nodeServerStatus.$node_num.status == $smarty.const.NODE_ACTIVE_NO_CONNECT}
+          {$message.strNodeStatus1|escape}
+        {elseif $nodeServerStatus.$node_num.status == $smarty.const.NODE_ACTIVE_CONNECTED}
+          {$message.strNodeStatus2|escape}
+        {elseif $nodeServerStatus.$node_num.status == $smarty.const.NODE_DOWN}
+          {$message.strNodeStatus3|escape}
+        {/if}
     {/if}
-    <td class="input">{$nodeServerStatus[num].hostname|escape}</td>
-    <td class="input">{$nodeServerStatus[num].port|escape}</td>
-    <td class="input">
-    {if $nodeServerStatus[num].status == true}
-    {$message.strUp|escape}
     </td>
-    <td><input type="button" name="detail" value="{$message.strDetail}" onclick="showDetail({$smarty.section.num.index})" /></td>
+    {if $nodeServerStatus.$node_num.is_active}
+        <td class="input">
+        postgres: {$message.strUp|escape}
+        </td>
+        <td>
+        <input type="button" name="detail" value="{$message.strSystemCatalog|escape}"
+               {if $smarty.section.num.index == $nodeNum}class="active_command"{/if}
+               onclick="showDetail({$node_num})" /></td>
     {else}
-    {$message.strDown|escape}
-    </td>
-    <td></td>
+        <td class="input">
+        postgres: {$message.strDown|escape}
+        </td>
+        <td>
+        <input type="button" name="detail" value="{$message.strSystemCatalog|escape}" disabled /></td>
+        </td>
     {/if}
-  {/section}
+  {/foreach}
   </tbody>
 </table>
 {else}
-{$message.strNoNode|escape}
+    {$message.strNoNode|escape}
 {/if}
 </body>
 </html>
index dcc8b8804c4f557ef2d092530ed4fd92f198950c..57411c125f8d5e21d2c3435c9933933a3636bc87 100644 (file)
@@ -15,6 +15,16 @@ td > img {
 
 <body>
 <h3>{$message.strPgpoolSummary|escape}</h3>
+
+{if $smarty.const._PGPOOL2_STATUS_REFRESH_TIME > 0}
+    <div class="auto_reloading">
+    <span><img src="images/refresh.png">
+          Refresh info: {$smarty.const._PGPOOL2_STATUS_REFRESH_TIME} seconds
+    </span>
+    </div>
+    <br clear="all">
+{/if}
+
 <table>
   <tbody>
     <tr><td>{$message.strReplicationMode|escape}</td>
index 35f1bbe08874c8e4a5d9a4fe759232e061c5835d..03b68e682242db64fdf3f164690a6ae31cd985c1 100644 (file)
@@ -6,7 +6,7 @@
 <link href="screen.css" rel="stylesheet" type="text/css" />
 </head>
 <body>
-<h2>{$message.strDetailInfo|escape}</h2>
+<h2>{$message.strSystemCatalog|escape} (node {$nodeNum})</h2>
 <table>
   <thead>
   <tr>
 <table>
   <thead>
   <tr>
-  {foreach from=$results[0] key=column item=value} 
+  {foreach from=$results[0] key=column item=value}
     <th><label>{$column|escape}</label></th>
     {/foreach}
   </tr>
   </thead>
   <tbody>
     {section name=num loop=$results}
-    {if ($smarty.section.num.index+1) % 2 == 0}
+    {if ($smarty.section.num.index + 1) % 2 == 0}
     <tr class="even">
     {else}
     <tr class="odd">
diff --git a/templates/innerWatchdog.tpl b/templates/innerWatchdog.tpl
new file mode 100644 (file)
index 0000000..ae69a85
--- /dev/null
@@ -0,0 +1,51 @@
+<h3>Watchdog
+{if $params.delegate_IP != NULL}(VIP: {$params.delegate_IP}){/if}</h3>
+
+{if $smarty.const._PGPOOL2_STATUS_REFRESH_TIME > 0}
+    <div class="auto_reloading">
+    <span><img src="images/refresh.png">
+          Refresh info: {$smarty.const._PGPOOL2_STATUS_REFRESH_TIME} seconds
+    </span>
+    </div>
+    <br clear="all">
+{/if}
+
+<div id="watchdog">
+<table>
+<thead>
+<tr>
+    <th></th>
+    <th><label>{$message.strIPaddress|escape}</label></th>
+    <th><label>{$message.strPort|escape}(pgpool-II)</label></th>
+    <th><label>{$message.strPort|escape}(Watchdog)</label></th>
+    <th><label>{$message.strStatus|escape}</label></th>
+</tr>
+</thead>
+<tbody>
+<tr>
+    <td>local</td>
+    <td>{$params.wd_hostname}</td>
+    <td>{$params.port}</td>
+    <td>{$params.wd_port}</td>
+    <td> ( XXX: no way exists to get status )</td>
+</tr>
+{section name=num loop=$params.other_pgpool_hostname}
+{if ($smarty.section.num.index) % 2 == 0}<tr class="even">{else}<tr class="odd">{/if}
+    <td>other {$smarty.section.num.index}</td>
+    <td>{$params.other_pgpool_hostname[num]}</td>
+    <td>{$params.other_pgpool_port[num]}</td>
+    <td>{$params.other_wd_port[num]}</td>
+    <td></td>
+</tr>
+{/section}
+</tbody>
+<tfoot>
+<tr><th colspan="5"></th></tr>
+</tfoot>
+</table>
+
+<p>[ lifecheck ]
+    every{$params.wd_interval} seconds /
+    retry upto {$params.wd_life_point} counts /
+    by "{$params.wd_lifecheck_query}"</p>
+</div>
index e07b3078acf67d065f6cb7a5c5355c10f97834c5..4b6b6592bee6e9331614c67ee66325f07268759e 100644 (file)
@@ -5,7 +5,9 @@
     {if hasMemqCache() == false}
     <li><a href="queryCache.php">{$message.strQueryCache|escape}</a></li>
     {/if}
+    {if isParallelMode()}
     <li><a href="systemDb.php">{$message.strSystemDb|escape}</a></li>
+    {/if}
     <li><a href="pgconfig.php">{$message.strPgConfSetting|escape}</a></li>
     <li><a href="config.php">{$message.strSetting|escape}</a></li>
     <li><a href="changePassword.php">{$message.strChangePassword|escape}</a></li>
index 49ff4bf76ff91b9db073ea1c0c9f649dc91ae3fe..e20643df2cba3e707cb89eb4a42ad7b1872f65c9 100644 (file)
@@ -7,20 +7,23 @@
 <script type="text/javascript">
 <!--
 {literal}
-function load() {
+function load()
+{
     var xmlhttp = false;
 
-    if (typeof XMLHttpRequest!='undefined')
+    if (typeof XMLHttpRequest!='undefined') {
         xmlhttp = new XMLHttpRequest();
-    else
+    } else {
         xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
+    }
 
     if (!xmlhttp) {
         alert('Sorry, cannot use XMLHttpRequest');
         return;
     }
 
-    xmlhttp.onreadystatechange = function() {
+    xmlhttp.onreadystatechange = function()
+    {
         if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
             var content = document.getElementById('status');
             var ret = xmlhttp.responseText;
@@ -33,7 +36,8 @@ function load() {
     xmlhttp.send("");
 }
 
-function showDetail(num) {
+function showDetail(num)
+{
     var catalog = "pg_settings";
     var xmlhttp = false;
     var url = "";
@@ -48,7 +52,8 @@ function showDetail(num) {
         return;
     }
 
-    xmlhttp.onreadystatechange = function() {
+    xmlhttp.onreadystatechange = function()
+    {
         if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
             var content = document.getElementById('detailInfo');
             var ret = xmlhttp.responseText;
@@ -79,7 +84,9 @@ function showDetail(num) {
 <div id="content">
 <div id="help"><a href="help.php?help={$help|escape}"><img src="images/question.gif" alt="help"/>{$message.strHelp|escape}</a></div>
 
-<h2>{$message.strNodeStatus|escape}</h2>
+<h2>{$message.strNodeStatus|escape}
+{if $pgpoolIsActive == false}[{$message.strStoppingNow}]{/if}
+</h2>
   <div id="status">{$message.strPleaseWait|escape}</div>
 <p>
   <div id="detailInfo"></div>
index d5e07ab4ed3046ad049b157cac0734633b9c5633..7ea1b6122e02d8f5472509f971475712dce910a0 100644 (file)
@@ -7,85 +7,6 @@
 </head>
 
 <body>
-<h3>{$message.strNodeInfo|escape}</h3>
-
-{if $nodeCount > 0}
-<table>
-  <thead>
-  <tr>
-    <th><label>{$message.strIPaddress|escape}</label></th>
-    <th><label>{$message.strPort|escape}</label></th>
-    <th><label>{$message.strStatus|escape}</label></th>
-    {if $parallelMode == false}
-    <th><label>{$message.strWeight|escape}</label></th>
-    {/if}
-    <th></th>
-  </tr>
-  </thead>
-
-  {section name=num loop=$nodeInfo}
-    {if ($smarty.section.num.index+1) % 2 == 0}
-    <tr class="even">
-    {else}
-    <tr class="odd">
-    {/if}
-    <td>{$nodeInfo[num][0]|escape}</td>
-    <td>{$nodeInfo[num][1]|escape}</td>
-
-    <td>
-    {if $nodeInfo[num][2] == $smarty.const.NODE_ACTIVE_NO_CONNECT}
-      {$message.strNodeStatus1|escape}
-    {elseif $nodeInfo[num][2] == $smarty.const.NODE_ACTIVE_CONNECTED}
-      {$message.strNodeStatus2|escape}
-    {elseif $nodeInfo[num][2] == $smarty.const.NODE_DOWN}
-      {$message.strNodeStatus3|escape}
-    {/if}
-    {if $nodeInfo[num][6] == 1}
-      {$message.strStandbyRunning|escape}
-    {elseif $nodeInfo[num][6] == 0}
-      {$message.strPrimaryRunning|escape}
-    {/if}
-    </td>
-
-    {if $parallelMode == false}
-    <td>{$nodeInfo[num][3]|escape}</td>
-    {/if}
-
-    <td>
-    {if $nodeInfo[num][4] == 'disconnect'}
-      <input type="button" name="command"
-       onclick="sendCommand('detach', {$smarty.section.num.index|escape}, '{$message.msgDetachConfirm|escape}')"
-       value="{$message.strDisconnect|escape}" />
-    {elseif $nodeInfo[num][4] == 'return'}
-      <input type="button" name="command"
-       onclick="sendCommand('return', {$smarty.section.num.index|escape}, '{$message.msgReturnConfirm|escape}')"
-       value="{$message.strReturn|escape}" />
-    {elseif $nodeInfo[num][4] == 'recovery'}
-      <input type="button" name="command"
-       onclick="sendCommand('recovery', {$smarty.section.num.index|escape}, '{$message.msgRecoveryConfirm|escape}')"
-       value="{$message.strRecovery|escape}" />
-    {/if}
-    {if isset($nodeInfo[num][5]) && $nodeInfo[num][5] == 'promote' && $nodeInfo[num][6] == 1}
-      <input type="button" name="command"
-       onclick="sendCommand('promote', {$smarty.section.num.index|escape}, '{$message.msgRPromoteConfirm|escape}')"
-       value="{$message.strPromote|escape}" />
-    {/if}
-    </td>
-
-    </tr>
-  {/section}
-
-  <tfoot>
-  <tr><th></th><th></th><th></th><th></th><th></th></tr>
-  </tfoot>
-
-</table>
-
-{else}
-{$message.strNoNode|escape}
-{/if}
-
-[*] The status is reloaded in every {$smarty.const._PGPOOL2_STATUS_REFRESH_TIME} seconds.
-
+{include file="elements/status_nodeinfo.tpl"}
 </body>
 </html>
index 50ffc6fd139f778ad965b522990b0f75bc977c61..c49c59b42520ce08ca2acb87f30cd81c569ffce5 100644 (file)
@@ -78,13 +78,16 @@ function delOtherWatchdog(num){
     {if $status == 'success'}
     <table>
       <tr>
-      <td>{$message.msgUpdateComplete|escape}</td>
+      <td class="pgconfig_msg">
+      <p>{$message.msgUpdateComplete|escape}</p>
+      <p><img src="images/warning.png"> {$message.msgUpdateCompleteInfo|escape}</p>
+      </td>
       </tr>
     </table>
     {elseif $status == 'fail'}
     <table>
       <tr>
-      <td>{$message.msgUpdateFailed|escape}</td>
+      <td class="pgconfig_msg"><p><img src="images/error.png"> {$message.msgUpdateFailed|escape}</p></td>
       </tr>
     </table>
     {/if}
@@ -350,6 +353,7 @@ function delOtherWatchdog(num){
     <table>
       <thead>
         <tr>
+          <th></th>
           <th>{$message.strParameter|escape}</th>
           <th>{$message.strValue|escape}</th>
           <td></td>
@@ -359,70 +363,72 @@ function delOtherWatchdog(num){
       {if isset($isAdd) && $isAdd == true}
           <tfoot>
             <tr>
-               <td colspan="3">
+               <td colspan="4">
                <input type="button" name="cancel" value="{$message.strCancel|escape}" onclick="cancelNode()" /></td>
             </tr>
           </tfoot>
       {else}
           <tfoot>
             <tr>
-              <td colspan="3">
+              <td colspan="4">
               <input type="button" name="add" value="{$message.strAdd|escape}" onclick="addNode()" /></td>
             </tr>
           </tfoot>
       {/if}
           <tbody>
 
-          {section name=num loop=$params.backend_hostname}
+          {foreach from=$params.backend_hostname key=node_num item=v}
           <tr>
-          <th{if isset($error.backend_hostname[num])} class="error"{/if}>
+          <td rowspan="{if paramExists('backend_flag')}5{else}4{/if}">node {$node_num}</td>
+          <th{if isset($error.backend_hostname.$node_num)} class="error"{/if}>
           <label>{$message.descBackend_hostname|escape}</label>
-          <br />backend_hostname{$smarty.section.num.index} (string)</th>
-          <td><input type="text" name="backend_hostname[]" value="{$params.backend_hostname[num]|escape}" /></td>
+          <br />backend_hostname{$node_num} (string)</th>
+          <td><input type="text" name="backend_hostname[]" value="{$params.backend_hostname.$node_num|escape}" /></td>
           <td rowspan="{if paramExists('backend_flag')}5{else}4{/if}">
           <input type="button" name="delete" value="{$message.strDelete|escape}"
-          onclick="del({$smarty.section.num.index})" /></td>
+                 onclick="del({$node_num})" /></td>
           </tr>
 
           <tr>
-          <th{if isset($error.backend_port[num])} class="error"{/if}>
+          <th{if isset($error.backend_port.$node_num)} class="error"{/if}>
           <label>{$message.descBackend_port|escape}</label>
-          <br />backend_port{$smarty.section.num.index|escape} (integer)</th>
-          <td><input type="text" name="backend_port[]" value="{$params.backend_port[num]|escape}" /></td>
+          <br />backend_port{$node_num|escape} (integer)</th>
+          <td><input type="text" name="backend_port[]" value="{$params.backend_port.$node_num|escape}" /></td>
           </tr>
 
           <tr>
-          <th{if isset($error.backend_weight[num])} class="error"{/if}>
+          <th{if isset($error.backend_weight.$node_num)} class="error"{/if}>
           <label>{$message.descBackend_weight|escape}</label>
-          <br />backend_weight{$smarty.section.num.index|escape} (float)</th>
-          <td><input type="text" name="backend_weight[]" value="{$params.backend_weight[num]|escape}" /></td>
+          <br />backend_weight{$node_num|escape} (float)</th>
+          <td><input type="text" name="backend_weight[]" value="{$params.backend_weight.$node_num|escape}" /></td>
           </tr>
 
           <tr>
-          <th{if isset($error.backend_data_directory[num])} class="error"{/if}>
+          <th{if isset($error.backend_data_directory.$node_num)} class="error"{/if}>
           <label>{$message.descBackend_data_directory|escape}</label>
-          <br />backend_data_directory{$smarty.section.num.index|escape} (string)</th>
+          <br />backend_data_directory{$node_num|escape} (string)</th>
           <td><input type="text" name="backend_data_directory[]"
-               value="{$params.backend_data_directory[num]|escape}" /></td>
+               value="{$params.backend_data_directory.$node_num|escape}" /></td>
           </tr>
 
           {if paramExists('backend_flag')}
               <tr>
-              <th{if isset($error.backend_flag[num])} class="error"{/if}>
+              <th{if isset($error.backend_flag.$node_num)} class="error"{/if}>
               <label>{$message.descBackend_flag|escape}</label>
-              <br />backend_flag{$smarty.section.num.index|escape} (string) *</th>
+              <br />backend_flag{$node_num|escape} (string) *</th>
               <td><select name="backend_flag[]" id="backend_flag[]">
                   <option value="ALLOW_TO_FAILOVER"
-                  {if $params.backend_flag[num] == 'ALLOW_TO_FAILOVER'}selected{/if}>ALLOW_TO_FAILOVER</option>
+                  {if $params.backend_flag.$node_num == 'ALLOW_TO_FAILOVER'}selected{/if}>ALLOW_TO_FAILOVER</option>
                   <option value="DISALLOW_TO_FAILOVER"
-                  {if $params.backend_flag[num] == 'DISALLOW_TO_FAILOVER'}selected{/if}>DISALLOW_TO_FAILOVER</option>
+                  {if $params.backend_flag.$node_num == 'DISALLOW_TO_FAILOVER'}selected{/if}>DISALLOW_TO_FAILOVER</option>
                   </select></td>
               </tr>
           {/if}
-          {/section}
+          {/foreach}
 
           {if isset($isAdd) && $isAdd == true}
               <tr>
+              <td rowspan="{if paramExists('backend_flag')}5{else}4{/if}">node [new]</td>
               <th><label>{$message.descBackend_hostname|escape}</label>
               <br />backend_hostname{$smarty.section.num.index} (string)</th>
               <td><input type="text" name="backend_hostname[]" value="" /></td>
@@ -1333,31 +1339,32 @@ function delOtherWatchdog(num){
 
         <tr><th class="category" colspan="3">Servers to monitor</th></tr>
 
-          {section name=num loop=$params.other_pgpool_hostname}
+          {foreach from=$params.other_pgpool_hostname key=host_num item=v}
           <tr>
           <th{if isset($error.other_pgpool_hostname[num])} class="error"{/if}>
           <label>{$message.descOther_pgpool_hostname|escape}</label>
-          <br />other_pgpool_hostname{$smarty.section.num.index} (string)</th>
-          <td><input type="text" name="other_pgpool_hostname[]" value="{$params.other_pgpool_hostname[num]|escape}" /></td>
+          <br />other_pgpool_hostname{$host_num} (string)</th>
+          <td><input type="text" name="other_pgpool_hostname[]"
+                     value="{$params.other_pgpool_hostname.$host_num|escape}" /></td>
           <td rowspan="3">
           <input type="button" name="delete" value="{$message.strDelete|escape}"
-          onclick="delOtherWatchdog({$smarty.section.num.index})" /></td>
+                 onclick="delOtherWatchdog({$host_num})" /></td>
           </tr>
 
           <tr>
           <th{if isset($error.other_pgpool_port[num])} class="error"{/if}>
           <label>{$message.descOther_pgpool_port|escape}</label>
-          <br />other_pgpool_port{$smarty.section.num.index|escape} (integer)</th>
-          <td><input type="text" name="other_pgpool_port[]" value="{$params.other_pgpool_port[num]|escape}" /></td>
+          <br />other_pgpool_port{$host_num|escape} (integer)</th>
+          <td><input type="text" name="other_pgpool_port[]" value="{$params.other_pgpool_port.$host_num|escape}" /></td>
           </tr>
 
           <tr>
           <th{if isset($error.other_wd_port[num])} class="error"{/if}>
           <label>{$message.descOther_wd_port|escape}</label>
-          <br />other_wd_port{$smarty.section.num.index|escape} (integer)</th>
-          <td><input type="text" name="other_wd_port[]" value="{$params.other_wd_port[num]|escape}" /></td>
+          <br />other_wd_port{$host_num|escape} (integer)</th>
+          <td><input type="text" name="other_wd_port[]" value="{$params.other_wd_port.$host_num|escape}" /></td>
           </tr>
-          {/section}
+          {/foreach}
 
           {if isset($isAddWd) && $isAddWd == true}
               <tr>
index 8bb802ae5ea53a7a2bb736c5b74611fa4db91765..86c7661a89e28c4d03651490f183301ee752aebc 100644 (file)
@@ -7,6 +7,16 @@
 </head>
 <body>
 <h3>{$message.strProcInfo|escape}</h3>
+
+{if $smarty.const._PGPOOL2_STATUS_REFRESH_TIME > 0}
+    <div class="auto_reloading">
+    <span><img src="images/refresh.png">
+          Refresh info: {$smarty.const._PGPOOL2_STATUS_REFRESH_TIME} seconds
+    </span>
+    </div>
+    <br clear="all">
+{/if}
+
 <table>
   <thead>
   <tr>
@@ -48,7 +58,7 @@
         <td>{$data.9|escape}</td>
         <td>{$data.10|escape}</td>
       </tr>
-    {/if}    
+    {/if}
   {/foreach}
 {/foreach}
 </table>
index 1cd7bbe49fc3b19f59285e8d8acf116b75392597..f4f4ebc4db565391d0a9997f7907c0a52b7d4e04 100644 (file)
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>{$message.strPgpoolStatus|escape}</title>
 <link href="screen.css" rel="stylesheet" type="text/css" />
-<script type="text/javascript">
-<!--
-
-var strConnError = "{$message.strConnectionError|escape}";
-var strUp        = "{$message.strUp|escape}";
-var strDown      = "{$message.strDown|escape}";
-var strDataError = "{$message.strDataError|escape}";
-var refreshTime  = "{$refreshTime|escape}";
-var view         = "{$viewPHP|escape}";
-var msgStopPgpool    = "{$message.msgStopPgpool|escape}";
-var msgRestartPgpool = "{$message.msgRestartPgpool|escape}";
-var msgReloadPgpool  = "{$message.msgReloadPgpool|escape}";
-
-{literal}
-
-function load() {
-    var xmlhttp = false;
-
-    if (typeof XMLHttpRequest!='undefined') {
-        xmlhttp = new XMLHttpRequest();
-    } else {
-        xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
-    }
-
-    if (!xmlhttp) {
-        alert('Sorry, cannot use XMLHttpRequest');
-        return;
-    }
-
-    xmlhttp.onreadystatechange = function() {
-        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
-            var content = document.getElementById('status');
-            var ret = xmlhttp.responseText;
-
-            content.innerHTML  = ret;
-            if(view != "innerLog.php")
-                timer(2000);
-        }
-    }
-    xmlhttp.open('GET', view, true);
-    xmlhttp.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
-    xmlhttp.send("");
-}
-
-/* --------------------------------------------------------------------- */
-
-function reload() {
-    var xmlhttp = false;
-    if (typeof XMLHttpRequest!='undefined') {
-        xmlhttp = new XMLHttpRequest();
-    } else {
-        xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
-    }
-
-    if (!xmlhttp) {
-        alert('Sorry, cannot use XMLHttpRequest');
-        return;
-    }
-
-    xmlhttp.onreadystatechange = function() {
-        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
-            var content = document.getElementById('status');
-            var ret = xmlhttp.responseText;
-
-            content.innerHTML  = ret;
-            if(refreshTime > 0)
-                timer(refreshTime);
-        }
-    }
-    xmlhttp.open('GET', view, true);
-    xmlhttp.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
-    xmlhttp.send("");
-}
-
-/* --------------------------------------------------------------------- */
-
-function timer(interval) {
-    setTimeout("reload()",interval);
-}
-
-function sendCommand(command, nodeNumber, message){
-    if (window.confirm(message)) {
-        document.Command.action.value= command;
-        document.Command.nodeNumber.value= nodeNumber;
-        document.Command.submit();
-    }
-}
-
-/* --------------------------------------------------------------------- */
-/* buttons                                                               */
-/* --------------------------------------------------------------------- */
-
-function startPgpool() {
-    document.Command.action.value= "start";
-    document.Command.submit();
-}
-
-function stopPgpool() {
-    var stopOption = document.getElementById('stopOption');
-    stopOption.style.visibility = "visible";
-    stopOption.style.position = "";
-    stopOption.style.height = "";
-
-    var cmdBtn = document.getElementById('cmdBtn');
-    cmdBtn.style.visibility = "hidden";
-    cmdBtn.style.position = "absolute";
-    cmdBtn.style.height = "0";
-}
-
-function restartPgpool() {
-    var stopOption = document.getElementById('stopOption');
-    stopOption.style.visibility = "hidden";
-    stopOption.style.position = "absolute";
-    stopOption.style.height = "0";
-
-    var restartOption = document.getElementById('restartOption');
-    restartOption.style.visibility = "visible";
-    restartOption.style.position = "";
-    restartOption.style.height = "";
-
-    var cmdBtn = document.getElementById('cmdBtn');
-    cmdBtn.style.visibility = "hidden";
-    cmdBtn.style.position = "absolute";
-    cmdBtn.style.height = "0";
-}
-
-function cancelCmd() {
-    var stopOption = document.getElementById('stopOption');
-    stopOption.style.visibility = "hidden";
-    stopOption.style.position = "absolute";
-    stopOption.style.height = "0";
-
-    var restartOption = document.getElementById('restartOption');
-    restartOption.style.visibility = "hidden";
-    restartOption.style.position = "absolute";
-    restartOption.style.height = "0";
-
-    var cmdBtn = document.getElementById('cmdBtn');
-    cmdBtn.style.visibility = "visible";
-    cmdBtn.style.position = "";
-    cmdBtn.style.height = "";
-}
-
-/* --------------------------------------------------------------------- */
-/* execute                                                               */
-/* --------------------------------------------------------------------- */
-
-function execRestartPgpool() {
-   if (window.confirm(msgRestartPgpool)){
-    document.Command.action.value= "restart";
-    document.Command.submit();
-   }
-}
-
-function execReloadPgpool() {
-   if (window.confirm(msgReloadPgpool)){
-    document.Command.action.value= "reload";
-    document.Command.submit();
-   }
-}
-
-function execStopPgpool() {
-   if (window.confirm(msgStopPgpool)){
-    document.Command.action.value= "stop";
-    document.Command.submit();
-   }
-}
-
-function changeView(chView){
-    document.Command.action.value= chView;
-    document.Command.submit();
-}
-
-// -->
-</script>
-{/literal}
+{include file="elements/status_js.tpl"}
 </head>
 
-<body onload="load()">
+<body onLoad="load()">
 <div id="header">
   <h1><img src="images/logo.gif" alt="pgpoolAdmin" /></h1>
 </div>
@@ -190,281 +15,173 @@ function changeView(chView){
 <div id="menu">
 {include file="menu.tpl"}
 </div>
-<div id="content">
-<div id="help"><a href="help.php?help={$help|escape}"><img src="images/question.gif" alt="help"/>{$message.strHelp|escape}</a></div>
 
-<form action="status.php" name="Command" method="post">
-  <input type="hidden" name="action" value="" />
-  <input type="hidden" name="nodeNumber" value="" />
+<div id="content">
+    <div id="help">
+    <a href="help.php?help={$help|escape}"><img src="images/question.gif" alt="help"/>{$message.strHelp|escape}</a>
+    </div>
 
-<h2>pgpool-II Version</h2>
-{$smarty.const._PGPOOL2_VERSION}
+    {* --------------------------------------------------------------------- *}
+    {* pgpool's version                                                      *}
+    {* --------------------------------------------------------------------- *}
 
-{* --------------------------------------------------------------------- *}
-{* Status Info Buttons                                                   *}
-{* --------------------------------------------------------------------- *}
+    <h2>pgpool-II Version</h2>
+    {$smarty.const._PGPOOL2_VERSION}
 
-<h2>{$message.strPgpoolStatus|escape}</h2>
+    <p>login user: {$login_user}</p>
+    <p>is_superuser: {if $is_superuser}yes{else}no{/if}</p>
 
-{if $pgpoolIsActive == true}
-<p>
-    <input type="button" name="command" onclick="changeView('summary')" value="{$message.strPgpoolSummary|escape}" />
-    <input type="button" name="command" onclick="changeView('proc')" value="{$message.strProcInfo|escape}" />
-    <input type="button" name="command" onclick="changeView('node')" value="{$message.strNodeInfo|escape}" />
-    {if $useSyslog == FALSE && $n == 1 && $pipe == 0}
-    <input type="button" name="command" onclick="changeView('log')" value="{$message.strLog|escape}" />
-    {/if}
-</p>
-  <div id="status"></div>
-<p>
-    <input type="button" name="command" onclick="changeView('summary')" value="{$message.strPgpoolSummary|escape}" />
-    <input type="button" name="command" onclick="changeView('proc')" value="{$message.strProcInfo|escape}" />
-    <input type="button" name="command" onclick="changeView('node')" value="{$message.strNodeInfo|escape}" />
-    {if $useSyslog == FALSE && $n == 1 && $pipe == 0}
-    <input type="button" name="command" onclick="changeView('log')" value="{$message.strLog|escape}" />
-    {/if}
-</p>
-{else}
-{$message.strStopPgpool|escape}
-{/if}
+    {* --------------------------------------------------------------------- *}
+    {* Status Info Buttons                                                   *}
+    {* --------------------------------------------------------------------- *}
 
-{* --------------------------------------------------------------------- *}
+    <h2>Backend info (PostgreSQL)</h2>
 
-<h2>{$message.strPgpool|escape}</h2>
+    {if isset($complete_msg)}{$complete_msg}{/if}
 
     {* --------------------------------------------------------------------- *}
-    {* Start Options                                                         *}
+    {* Succeeed / Failed                                                     *}
     {* --------------------------------------------------------------------- *}
 
-    {if $pgpoolIsActive == false}
-    <table>
-    <thead><tr><th colspan="2">{$message.strStartOption|escape}</th></tr></thead>
-    <tfoot><tr>
-      <td colspan="2">
-      <input type="button" name="command" onclick="startPgpool()"
-       value="{$message.strStartPgpool|escape}" />
-      </td>
-    </tr></tfoot>
-    <tbody>
-
-        {if hasMemqCache() == false}
-        <tr><td>{$message.strCmdC|escape} (-c)</td>
-          {if $c == 1}
-          <td><input type="checkbox" name="c" checked="checked" /></td>
-          {else}
-          <td><input type="checkbox" name="c" /></td>
-          {/if}
+    {if isset($status)}
+      {if $status == 'success'}
+      <table id="complete_msg">
+        <tr>
+        <td class="pgconfig_msg"><p>{$message.msgUpdateComplete|escape}</p></td>
         </tr>
-        {/if}
-
-        <tr><td>{$message.strCmdLargeD|escape} (-D)</td>
-          {if $D == 1}
-          <td><input type="checkbox" name="D" checked="checked" /></td>
-          {else}
-          <td><input type="checkbox" name="D" /></td>
-          {/if}
+      </table>
+      {elseif $status == 'fail'}
+      <table id="command">
+        <tr>
+        <td class="pgconfig_msg"><p><img src="images/error.png"> {$message.msgUpdateFailed|escape}</p></td>
         </tr>
+      </table>
+      {/if}
+    {/if}
 
-        <tr><td>{$message.strCmdN|escape} (-n)</td>
-          {if $n == 1}
-          <td><input type="checkbox" name="n" checked="checked" /></td>
-          {else}
-          <td><input type="checkbox" name="n" /></td>
-          {/if}
-        </tr>
+    {if $pgpoolIsActive == true}
+        <p>
+        <input type="button" name="command" onClick="changeView('summary')"
+               {if $action == 'summary'}class="command_active"{/if}
+               value="{$message.strPgpoolSummary|escape}" />
 
-        {if hasMemqCache()}
-        <tr><td>{$message.strCmdLargeC|escape} (-C)</td>
-          {if $C == 1}
-          <td><input type="checkbox" name="C" checked="checked" /></td>
-          {else}
-          <td><input type="checkbox" name="C" /></td>
-          {/if}
-        </tr>
+        <input type="button" name="command" onClick="changeView('proc')"
+               {if $action == 'proc'}class="command_active"{/if}
+               value="{$message.strProcInfo|escape}" />
+
+        {if $params.use_watchdog == 'on'}
+        <input type="button" name="command" onClick="changeView('watchdog')"
+               {if $action == 'watchdog'}class="command_active"{/if}
+               value="Watchdog" />
         {/if}
 
-        <tr><td>{$message.strCmdD|escape} (-d)</td>
-          {if $d == 1}
-          <td><input type="checkbox" name="d" checked="checked" /></td>
-          {else}
-          <td><input type="checkbox" name="d" /></td>
-          {/if}
-        </tr>
+        <input type="button" name="command" onClick="changeView('node')"
+               {if $action == NULL || $action == 'node'}class="command_active"{/if}
+               value="{$message.strNodeInfo|escape}" />
 
-        <tr><td>{$message.strCmdPgpoolFile|escape} (-f)</td>
-          <td>{$pgpoolConf|escape}</td>
-        </tr>
+        {if $useSyslog == FALSE && $n == 1 && $pipe == 0}
+        <input type="button" name="command" onClick="changeView('log')"
+               {if $action == 'log'}class="command_active"{/if}
+               value="{$message.strLog|escape}" />
+        {/if}
+        </p>
 
-        <tr><td>{$message.strCmdPcpFile|escape} (-F)</td>
-          <td>{$pcpConf|escape}</td>
-        </tr>
+        <div id="div_status"></div>{* show elements/status_nodeinfo.tpl *}
 
-    </tbody>
-    </table>
     {else}
+        <table>
+          <thead>
+          <tr>
+            <th></th>
+            <th><label>{$message.strIPaddress|escape}</label></th>
+            <th><label>{$message.strPort|escape}</label></th>
+            <th><label>{$message.strStatus|escape}</label></th>
+            <th></th>
+          </tr>
+          </thead>
+
+          <tbody>
+          {if isset($params.backend_hostname)}
+              {$i = 0}
+              {foreach from=$params.backend_hostname key=node_num item=v}
+                  {$i = $i + 1}
+                  <tr class="{if $i % 2 == 0}even{else}odd{/if}">
+                  <td>node {$node_num}</td>
+                  <td class="input">{$params.backend_hostname.$node_num|escape}</td>
+                  <td class="input">{$params.backend_port.$node_num|escape}</td>
+                  <td>postgres:
+                      {if $nodeInfo.$node_num.is_active}{$message.strUp|escape}
+                      {else}{$message.strDown|escape}
+                      {/if}
+                  </td>
+                  <td>{include file="elements/status_pgsql_buttons.tpl"}</td>
+                  </tr>
+              {/foreach}
 
-    {* --------------------------------------------------------------------- *}
-    {* Command Buttons                                                       *}
-    {* --------------------------------------------------------------------- *}
+          {else}
+            <tr><td colspan="5">{$message.strNoNode|escape}</td></tr>
+          {/if}
+          </tbody>
+
+          <tfoot>
+          <tr><th colspan="5" align="right">
+              <input type="button" onClick="addBackendButtonHandler()"
+                     value="{$message.strAddBackend|escape}">
+              </th></tr>
+          </tfoot>
+        </table>
+    {/if}
 
-    <div id="cmdBtn" style="visibility: visible">
-    <input type="button" name="command" onclick="stopPgpool()" value="{$message.strStopPgpool|escape}" />
-    <input type="button" name="command" onclick="restartPgpool()" value="{$message.strRestartPgpool|escape}" />
-    <input type="button" name="command" onclick="execReloadPgpool()" value="{$message.strReloadPgpool|escape}" />
-    </div>
+    {* ---------------------------------------------------------------------- *}
+    {* Form to add a new backend                                              *}
+    {* ---------------------------------------------------------------------- *}
 
-    {* --------------------------------------------------------------------- *}
-    {* Stop Options                                                          *}
-    {* --------------------------------------------------------------------- *}
-    <div id="stopOption" style="visibility: hidden; position: absolute">
+    <div id="addBackendDiv" style="visibility: hidden; position: absolute;">
+    <h3>{$message.strAddBackend|escape}  (node {$next_node_num})</h3>
+    <form action="status.php" name="addBackendForm" method="post"
+          onSubmit="return checkAddForm()" />
+    <input type="hidden" name="action" value="addBackend" />
 
     <table>
-    <thead><tr><th colspan="2">{$message.strStopOption|escape}</th></tr></thead>
-    <tfoot><tr>
-      <td colspan="2">
-      <input type="button" name="command" onclick="execStopPgpool()" value="{$message.strExecute|escape}" />
-      <input type="button" name="command" onclick="cancelCmd()" value="{$message.strCancel|escape}" />
-      </td>
-    </tr></tfoot>
+    <thead>
+        <tr><th colspan="2">new backend</th></tr>
+    </thead>
     <tbody>
-          <tr><td>{$message.strCmdM|escape}(-m)</td>
-          <td><select name="stop_mode">
-          {if $m == 's'}
-               <option value="s" selected="selected">smart</option>
-               <option value="f">fast</option>
-               <option value="i">immediate</option>
-          {elseif $m == 'f'}
-               <option value="s">smart</option>
-               <option value="f" selected="selected">fast</option>
-               <option value="i">immediate</option>
-          {elseif $m == 'i'}
-               <option value="s">smart</option>
-               <option value="f">fast</option>
-               <option value="i" selected="selected">immediate</option>
-          {else}
-               <option value="s">smart</option>
-               <option value="f">fast</option>
-               <option value="i">immediate</option>
-          {/if}
-          </select>
-          </td></tr>
+        {include file="elements/pgconfig_new_backend.tpl"}
+        <tr>
+        <th>{$message.strAddBackendNow|escape}</th>
+        <td><input type="checkbox" name="reload_ok" id="reload_ok" checked></td>
+        </tr>
     </tbody>
+    <tfoot>
+        <tr><td colspan="2">
+        <input type="submit"
+               value="{$message.strAdd|escape}" />
+        <input type="button" name="command" onclick="cancelButtonHandler('addBackendDiv')"
+               value="{$message.strCancel|escape}" />
+        </td></tr>
+    </tfoot>
     </table>
+
+    </form>
     </div>
 
     {* --------------------------------------------------------------------- *}
-    {* Restart Options                                                       *}
+    {* Form of options to stop/restart PostgreSQL                            *}
     {* --------------------------------------------------------------------- *}
-    <div id="restartOption" style="visibility: hidden; position: absolute">
 
-    <table>
-    <thead><tr><th colspan="2">{$message.strRestartOption|escape}</th></tr></thead>
-    <tfoot><tr>
-      <td colspan="2">
-      <input type="button" name="command" onclick="execRestartPgpool()" value="{$message.strExecute|escape}" />
-      <input type="button" name="command" onclick="cancelCmd()" value="{$message.strCancel|escape}" />
-      </td>
-    </tr></tfoot>
-    <tbody>
+    {include file="elements/status_pgsql_options.tpl"}
 
-        {if hasMemqCache() == false}
-        <tr><td>{$message.strCmdC|escape}(-c)</td>
-          {if $c == 1}
-          <td><input type="checkbox" name="c" checked="checked" /></td>
-          {else}
-          <td><input type="checkbox" name="c" /></td>
-          {/if}
-        </tr>
-        {/if}
-
-        <tr><td>{$message.strCmdLargeD|escape}(-D)</td>
-          {if $D == 1}
-          <td><input type="checkbox" name="D" checked="checked" /></td>
-          {else}
-          <td><input type="checkbox" name="D" /></td>
-          {/if}
-        </tr>
-
-        <tr><td>{$message.strCmdN|escape}(-n)</td>
-          {if $n == 1}
-          <td><input type="checkbox" name="n" checked="checked" /></td>
-          {else}
-          <td><input type="checkbox" name="n" /></td>
-          {/if}
-        </tr>
-
-        {if hasMemqCache()}
-        <tr><td>{$message.strCmdLargeC|escape} (-C)</td>
-          {if $C == 1}
-          <td><input type="checkbox" name="C" checked="checked" /></td>
-          {else}
-          <td><input type="checkbox" name="C" /></td>
-          {/if}
-        </tr>
-        {/if}
-
-        <tr><td>{$message.strCmdD|escape}(-d)</td>
-          {if $d == 1}
-          <td><input type="checkbox" name="d" checked="checked" /></td>
-          {else}
-          <td><input type="checkbox" name="d" /></td>
-          {/if}
-        </tr>
-
-        <tr><td>{$message.strCmdM|escape}(-m)</td><td>
-          <select name="restart_mode">
-          {if $m == 's'}
-               <option value="s" selected="selected">smart</option>
-               <option value="f">fast</option>
-               <option value="i">immediate</option>
-          {elseif $m == 'f'}
-               <option value="s">smart</option>
-               <option value="f" selected="selected">fast</option>
-               <option value="i">immediate</option>
-          {elseif $m == 'i'}
-               <option value="s">smart</option>
-               <option value="f">fast</option>
-               <option value="i" selected="selected">immediate</option>
-          {else}
-               <option value="s">smart</option>
-               <option value="f">fast</option>
-               <option value="i">immediate</option>
-          {/if}
-          </select>
-          </td>
-        </tr>
-
-        <tr><td>{$message.strCmdPgpoolFile|escape}(-f)</td>
-          <td>{$pgpoolConf|escape}</td>
-        </tr>
-
-        <tr><td>{$message.strCmdPcpFile|escape}(-F)</td>
-          <td>{$pcpConf|escape}</td>
-        </tr>
-
-    </tbody>
-    </table>
-    </div>
-    {/if}
-
-{* --------------------------------------------------------------------- *}
-{* Start/Stop/Restart messages                                           */
-{* --------------------------------------------------------------------- *}
+    {* --------------------------------------------------------------------- *}
+    {* start / stop / reload                                                 *}
+    {* --------------------------------------------------------------------- *}
 
-{if isset($pgpoolStatus)}
-<div class="message">
-<h3>Messages</h3>
-    <p>{$pgpoolStatus|escape}</p>
-    <p>
-    {foreach from=$pgpoolMessage item=lines}
-    {$lines|escape}<br />
-    {/foreach}
-    </p>
-</div>
-{/if}
+    <h2>{$message.strPgpool|escape}
+    {if !$pgpoolIsActive}[ {$message.strStoppingNow|escape} ]{/if}
+    </h2>
+    {include file="elements/status_options.tpl"}
 
-</form>
-</div>
+</div>{* end div#content *}
 
 <div id="footer">
 {include file='footer.tpl'}