Location: PHPKode > projects > GForge > gforge-as-571-src/install-gforge-2-db.php
#!/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();

?>
Return current item: GForge