#!/usr/bin/php
<?php
/**
* Copyright (c) 2005-2008 GForge, LLC
*
* @version $Id: $
*
* See LICENSE for details. This file is part of GForge AS and may not be
* redistributed without written permission of GForge, LLC
*
*/
define ('GREEN', "\033[01;32m" );
define ('NORMAL', "\033[00m" );
define ('RED', "\033[01;31m" );
show("\n-=# Welcome to GForge DB-Installer v5.0 #=-");
if (!run("php check-deps.php", true)) {
echo RED.'Not all the necessary dependencies were found. aborting.'.NORMAL."\n";
exit(1);
}
// Find the Postgresql service script
$possible_pgservice_paths = array(
'/etc/init.d/postgresql',
'/etc/init.d/postgresql-7.4',
'/etc/init.d/postgresql-8.2',
'/etc/init.d/postgresql-8.3',
'/etc/init.d/cswpostgres',
);
$pgservice = '';
foreach ($possible_pgservice_paths as $possible_pgservice_path) {
if (is_file($possible_pgservice_path)) {
$pgservice = $possible_pgservice_path;
break;
}
}
if (!$pgservice) {
die("ERROR: Could not find Postgresql init script\n");
}
// Might fail if it's already running, so we'll ingnore the result
run("$pgservice start", true);
// Find the Postgresql configuration file
$possible_pghba_paths = array(
'/var/lib/pgsql/data/pg_hba.conf',
'/etc/postgresql/7.4/main/pg_hba.conf',
'/etc/postgresql/8.2/main/pg_hba.conf',
'/etc/postgresql/8.3/main/pg_hba.conf',
'/opt/csw/var/pgdata/pg_hba.conf',
);
$PGHBA = '';
foreach ($possible_pghba_paths as $possible_pghba_path) {
if (is_file($possible_pghba_path)) {
$PGHBA = $possible_pghba_path;
break;
}
}
if (!$PGHBA) {
die("ERROR: Could not find pg_hba.conf file\n");
}
// Find the tsearch2 script
$possible_tsearch2_paths = array(
'/usr/share/pgsql/contrib/tsearch2.sql',
'/usr/share/postgresql/contrib/tsearch2.sql',
'/usr/share/postgresql/7.4/contrib/tsearch2.sql',
'/usr/share/postgresql/8.2/contrib/tsearch2.sql',
'/usr/share/postgresql/8.3/contrib/tsearch2.sql',
'/opt/csw/postgresql/share/contrib/tsearch2.sql',
);
$tsearch2_sql = '';
foreach ($possible_tsearch2_paths as $possible_tsearch2_path) {
if (is_file($possible_tsearch2_path)) {
$tsearch2_sql = $possible_tsearch2_path;
break;
}
}
if (!$tsearch2_sql) {
die("ERROR: Could not find tsearch2.sql file\n");
}
// Where the PHP code will live
$gforge_lib_dir = '/opt/gforge5';
if (!is_dir($gforge_lib_dir)) {
show("Error: GForge5 folder doesn't exist. Run install-gforge-1-deps.php first.");
die();
}
// Where the configuration files will live
$gforge_etc_dir = getenv('GFORGE_ETC_DIR');
if (empty($gforge_etc_dir)) {
$gforge_etc_dir = '/etc/gforge';
}
function install() {
global $PGHBA, $gforge_lib_dir, $gforge_etc_dir, $tsearch2_sql, $pgservice;
show("\n * Enter the Database Name (gforge5): ");
$gforge_db = trim(fgets(STDIN));
if (strlen($gforge_db) == 0) {
$gforge_db = 'gforge5';
show(" ...using '$gforge_db'");
}
show(' * Enter the Database Username (gforge): ');
$gforge_user = trim(fgets(STDIN));
if (strlen($gforge_user) == 0) {
$gforge_user = 'gforge';
show(" ...using '$gforge_user'");
}
show(" * Modifying DB Access Permissions...");
if (!file_exists("$PGHBA.gforge.backup")) {
run("cp $PGHBA $PGHBA.gforge.backup", true);
}
run("echo \"# GFORGE5\nlocal all all trust\" > $PGHBA");
// Check if the database exists (just executes an empty query against the DB)
$exists = run("su - postgres -c \"psql $gforge_db -c \\\"\\\" &> /dev/null \"", true);
if ($exists) {
show(RED."The database $gforge_db already exists. If you want to update your installation, please run\nthe upgrade.php script.".NORMAL."\n");
die(1);
}
show(' * Restarting PostgreSQL...');
run("$pgservice stop", true);
run("$pgservice start");
show(" * Creating '$gforge_user' Group...");
run("/usr/sbin/groupadd $gforge_user", true);
show(" * Creating '$gforge_user' User...");
run("/usr/sbin/useradd -g $gforge_user $gforge_user", true);
show(" * Creating Database User '$gforge_user'...");
run("su - postgres -c \"createuser -A -d -E $gforge_user\"", true);
show(' * Creating Language...');
run("su - postgres -c \"createlang plpgsql template1\"", true);
if (!is_dir("/home/$gforge_user")) {
$susufix = '';
} else {
$susufix = '-';
}
show(" * Creating '$gforge_db' Database...");
run("su $susufix $gforge_user -c \"createdb $gforge_db\"", true);
show(" * Dumping tsearch2 Database Into '$gforge_db' DB");
run("su - postgres -c \"psql $gforge_db < $tsearch2_sql\"");
// The names for the tsearch2 tables have changed in Postgresql 8.3. If it's Postgresql >= 8.3, use the new table names
$postgres_version = trim(`psql -V | awk '{ print \$3 }' | head -n1`);
$is_postgres_8_3 = version_compare($postgres_version, '8.3', '>=');
if ($is_postgres_8_3) {
$tables = array('pg_ts_config', 'pg_ts_config_map', 'pg_ts_dict', 'pg_ts_parser');
} else {
$tables = array('pg_ts_cfg', 'pg_ts_cfgmap', 'pg_ts_dict', 'pg_ts_parser');
}
foreach ($tables as $table) {
run('su - postgres -c "psql '.$gforge_db.' -c \\"GRANT ALL on '.$table.' TO '.$gforge_user.';\\""');
}
// Postgresql 8.3 changed the way the casts are created. We need to create an explicit cast for comparing
// between int and text
if ($is_postgres_8_3) {
run('su - postgres -c "psql '.$gforge_db.' -c \\"CREATE FUNCTION int_to_text(INT4) RETURNS TEXT AS \'SELECT textin(int4out(\\\\\\$1));\' LANGUAGE SQL STRICT IMMUTABLE;\\""'); // Yes, it needs SIX backslashes
run('su - postgres -c "psql '.$gforge_db.' -c \\"CREATE CAST (INT4 AS TEXT) WITH FUNCTION int_to_text(INT4) AS IMPLICIT;\\""');
}
show(' * Dumping GForge DB');
run("su $susufix $gforge_user -c \"psql $gforge_db < $gforge_lib_dir/db/pgsql/gforge5-complete.sql\" > /tmp/gforge-import.log");
show(' * Dumping GForge FTI DB');
if ($is_postgres_8_3) {
run("su $susufix $gforge_user -c \"psql $gforge_db < $gforge_lib_dir/db/pgsql/FTI-gforge5-postgres8.3.sql\" >> /tmp/gforge-import.log");
} else {
run("su $susufix $gforge_user -c \"psql $gforge_db < $gforge_lib_dir/db/pgsql/FTI-gforge5.sql\" >> /tmp/gforge-import.log");
}
show(" * Enter the Admin Username (gforgeadmin): ");
$admin_user = trim(fgets(STDIN));
if (strlen($admin_user) == 0) {
$admin_user = 'gforgeadmin';
show(" ...using '$admin_user'");
}
$retries = 0;
$bad_pwd = true;
$pwd1 = '';
$pwd2 = '';
$error = '';
while ($bad_pwd && $retries < 5) {
if ($bad_pwd && $retries > 0) {
show(' * ' . $error);
}
$pwd1 = readMasked(" * Enter the Site Admin Password:");
$error = validatePassword($pwd1);
if ($error != '') {
$bad_pwd = true;
} else {
$pwd2 = readMasked(" * Please enter it again: \n");
if ($pwd1 == $pwd2) {
$bad_pwd = false;
} else {
$error = 'Passwords don\'t match. Please try again.';
}
}
$retries++;
}
if ($bad_pwd) {
show('Passwords didn\'t match! Aborting.');
die();
} else {
$pw_md5 = md5($pwd1);
$pw_crypt = crypt($pwd1);
$pw_crypt = str_replace('$', '\\\\\\$', $pw_crypt);
run('su - postgres -c "psql '.$gforge_db.' -c \\"UPDATE \\\\\"user\\\\\" SET unix_name=\''.$admin_user.'\', password_md5=\''.$pw_md5.'\', password_crypt=\''.$pw_crypt.'\' WHERE user_id=101;\\""');
}
if (!is_dir($gforge_etc_dir)) {
mkdir($gforge_etc_dir);
}
show(' * Setting up Config File for GForge');
$gforge5_db_conf = array("'hostspec'"=> "'hostspec' => '',",
"'database'"=> "'database' => '$gforge_db',",
"'username'"=> "'username' => '$gforge_user',",
"'password'"=> "'password' => '',");
exec('/bin/cp conf/gforge5-db-conf.php.example '.$gforge_etc_dir.'/gforge5-db-conf.php');
foreach($gforge5_db_conf as $key => $val) {
$key = str_replace("'", "\\'", $key);
$val = str_replace("'", "\\'", $val);
run("perl -pi -e \"s/$key.*/$val/gi\" $gforge_etc_dir/gforge5-db-conf.php");
}
finish();
}
/*
function uninstall() {
global $PGHBA, $gforge_lib_dir, $gforge_var_dir, $gforge_etc_dir, $gforge_db, $gforge_user, $tsearch2_sql;
show(" * Removing DATABASE \n";
system("su - $gforge_user -c \"dropdb $gforge_db\"", $ret );
show(" done . ($ret)\n";
show(" * Removing Language \n";
system("su - postgres -c \"droplang plpgsql template1\"", $ret );
show(" done. ($ret)\n";
show(" * Removing GForge DATABASE User: \n";
system("su - postgres -c \"dropuser $gforge_user\"", $ret );
show(" done.($ret)");
show(" * Removing GForge User: \n";
system("userdel $gforge_user");
show(" done.");
show(" * Restoring $PGHBA file: ... ";
system("cp $PGHBA.gforge.backup $PGHBA");
show(" done.");
show(" * Restarting PostgreSQL: ...\n";
system("/etc/init.d/postgresql restart");
show(" done.");
}
*/
function validatePassword($password) {
if (strlen($password)<6) {
return 'Password is too short. Please try again.';
}
if (!preg_match('/[[:alnum:]]*/', $password)) {
return 'Password contains invalid characters. Please try again.';
}
return '';
}
function readMasked($prompt) {
if (strtolower(php_uname('s')) == 'sunos') {
show($prompt);
$text_entered = fgets(STDIN);
} else {
$options="-er -s -p";
//$returned=popen("read $options \"".GREEN.$prompt.NORMAL."\n\"; echo \$REPLY", 'r');
$cmd = 'bash -c "read '.$options.' \"'.GREEN.$prompt.NORMAL."\n".'\"; echo \$REPLY"';
$returned=popen($cmd, 'r');
$text_entered=fgets($returned, 100);
pclose($returned);
$text_entered=substr($text_entered, 0, strlen($text_entered));
@ob_flush();
flush();
}
return trim($text_entered);
}
function finish() {
show(NORMAL."Done.\nYou are ready to run install-gforge-3.php");
}
function show($text, $newLine = true) {
if ($newLine) {
$text = GREEN.$text .NORMAL."\n";
}
fwrite(STDOUT, $text);
}
function run($command, $ignore = false) {
system($command, $ret);
if ($ignore) {
if ($ret != 0) {
return false;
} else {
return true;
}
} else {
if ($ret != 0) {
echo RED.'An error ocurred running the last command... aborting.'.NORMAL."\n";
die();
}
}
}
install();
?>