518 lines
18 KiB
PHP
518 lines
18 KiB
PHP
<?php
|
|
set_include_path(__DIR__.'/../../airtime_mvc/library' . PATH_SEPARATOR . get_include_path());
|
|
//Zend framework
|
|
if (file_exists('/usr/share/php/libzend-framework-php')){
|
|
set_include_path('/usr/share/php/libzend-framework-php' . PATH_SEPARATOR . get_include_path());
|
|
}
|
|
#require_once('Zend/Loader/Autoloader.php');
|
|
|
|
class AirtimeInstall
|
|
{
|
|
const CONF_DIR_BINARIES = "/usr/lib/airtime";
|
|
const CONF_DIR_WWW = "/usr/share/airtime";
|
|
const CONF_DIR_LOG = "/var/log/airtime";
|
|
|
|
public static $databaseTablesCreated = false;
|
|
|
|
public static function GetAirtimeSrcDir()
|
|
{
|
|
return __DIR__."/../../airtime_mvc";
|
|
}
|
|
|
|
public static function GetUtilsSrcDir()
|
|
{
|
|
return __DIR__."/../../utils";
|
|
}
|
|
|
|
/**
|
|
* Ensures that the user is running this PHP script with root
|
|
* permissions. If not running with root permissions, causes the
|
|
* script to exit.
|
|
*/
|
|
public static function ExitIfNotRoot()
|
|
{
|
|
// Need to check that we are superuser before running this.
|
|
if(posix_geteuid() != 0){
|
|
echo "Must be root user.\n";
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return the version of Airtime currently installed.
|
|
* If not installed, return null.
|
|
*
|
|
* @return NULL|string
|
|
*/
|
|
public static function GetVersionInstalled()
|
|
{
|
|
try {
|
|
$con = Propel::getConnection();
|
|
} catch (PropelException $e) {
|
|
return null;
|
|
}
|
|
|
|
if (file_exists('/etc/airtime/airtime.conf')) {
|
|
$values = parse_ini_file('/etc/airtime/airtime.conf', true);
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
|
|
$sql = "SELECT valstr FROM cc_pref WHERE keystr = 'system_version' LIMIT 1";
|
|
|
|
try {
|
|
$version = $con->query($sql)->fetchColumn(0);
|
|
} catch (PDOException $e){
|
|
// no pref table therefore Airtime is not installed.
|
|
//We only get here if airtime database exists, but the table doesn't
|
|
//This state sometimes happens if a previous Airtime uninstall couldn't remove
|
|
//the database because it was busy, so it just removed the tables instead.
|
|
return null;
|
|
}
|
|
|
|
//if version is empty string, then version is older than version 1.8.0
|
|
if ($version == '') {
|
|
try {
|
|
// If this table exists, then it's version 1.7.0
|
|
$sql = "SELECT * FROM cc_show_rebroadcast LIMIT 1";
|
|
$result = $con->query($sql)->fetchColumn(0);
|
|
$version = "1.7.0";
|
|
} catch (Exception $e) {
|
|
$version = null;
|
|
}
|
|
}
|
|
|
|
return $version;
|
|
}
|
|
|
|
public static function DbTableExists($p_name)
|
|
{
|
|
$con = Propel::getConnection();
|
|
try {
|
|
$sql = "SELECT * FROM ".$p_name." LIMIT 1";
|
|
$con->query($sql);
|
|
} catch (PDOException $e){
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static function InstallQuery($sql, $verbose = true)
|
|
{
|
|
$con = Propel::getConnection();
|
|
try {
|
|
$con->exec($sql);
|
|
if ($verbose) {
|
|
echo "done.\n";
|
|
}
|
|
} catch (Exception $e) {
|
|
echo "Error!\n".$e->getMessage()."\n";
|
|
echo " SQL statement was:\n";
|
|
echo " ".$sql."\n\n";
|
|
}
|
|
}
|
|
|
|
public static function DropSequence($p_sequenceName)
|
|
{
|
|
AirtimeInstall::InstallQuery("DROP SEQUENCE IF EXISTS $p_sequenceName");
|
|
}
|
|
|
|
/**
|
|
* Try to connect to the database. Return true on success, false on failure.
|
|
* @param boolean $p_exitOnError
|
|
* Exit the program on failure.
|
|
* @return boolean
|
|
*/
|
|
public static function DbConnect($p_exitOnError = true)
|
|
{
|
|
global $CC_CONFIG;
|
|
try {
|
|
$con = Propel::getConnection();
|
|
} catch (Exception $e) {
|
|
echo $e->getMessage().PHP_EOL;
|
|
echo "Database connection problem.".PHP_EOL;
|
|
echo "Check if database '{$CC_CONFIG['dsn']['database']}' exists".
|
|
" with corresponding permissions.".PHP_EOL;
|
|
if ($p_exitOnError) {
|
|
exit(1);
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
/* TODO: This function should be moved to the media-monitor
|
|
* install script. */
|
|
public static function InstallStorageDirectory()
|
|
{
|
|
global $CC_CONFIG;
|
|
echo "* Storage directory setup".PHP_EOL;
|
|
|
|
$ini = parse_ini_file(__DIR__."/airtime-install.ini");
|
|
$stor_dir = $ini["storage_dir"];
|
|
|
|
$dirs = array($stor_dir, $stor_dir."/organize");
|
|
|
|
foreach ($dirs as $dir){
|
|
if (!file_exists($dir)) {
|
|
if (mkdir($dir, 02775, true)){
|
|
$rp = realpath($dir);
|
|
echo "* Directory $rp created".PHP_EOL;
|
|
} else {
|
|
echo "* Failed creating {$dir}".PHP_EOL;
|
|
exit(1);
|
|
}
|
|
}
|
|
else if (is_writable($dir)) {
|
|
$rp = realpath($dir);
|
|
echo "* Skipping directory already exists: $rp".PHP_EOL;
|
|
}
|
|
else {
|
|
$rp = realpath($dir);
|
|
echo "* Error: Directory already exists, but is not writable: $rp".PHP_EOL;
|
|
exit(1);
|
|
}
|
|
|
|
echo "* Giving Apache permission to access $rp".PHP_EOL;
|
|
$success = chgrp($rp, $CC_CONFIG["webServerUser"]);
|
|
$success = chmod($rp, 02775);
|
|
}
|
|
}
|
|
|
|
public static function CreateDatabaseUser()
|
|
{
|
|
global $CC_CONFIG;
|
|
|
|
echo " * Creating Airtime database user".PHP_EOL;
|
|
|
|
$username = $CC_CONFIG['dsn']['username'];
|
|
$password = $CC_CONFIG['dsn']['password'];
|
|
$command = "echo \"CREATE USER $username ENCRYPTED PASSWORD '$password' LOGIN CREATEDB NOCREATEUSER;\" | su postgres -c psql 2>/dev/null";
|
|
|
|
@exec($command, $output, $results);
|
|
if ($results == 0) {
|
|
echo " * Database user '{$CC_CONFIG['dsn']['username']}' created.".PHP_EOL;
|
|
} else {
|
|
if (count($output) > 0) {
|
|
echo " * Could not create user '{$CC_CONFIG['dsn']['username']}': ".PHP_EOL;
|
|
echo implode(PHP_EOL, $output);
|
|
}
|
|
else {
|
|
echo " * Database user '{$CC_CONFIG['dsn']['username']}' already exists.".PHP_EOL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static function CreateDatabase()
|
|
{
|
|
global $CC_CONFIG;
|
|
|
|
echo " * Creating Airtime database".PHP_EOL;
|
|
|
|
$database = $CC_CONFIG['dsn']['database'];
|
|
$username = $CC_CONFIG['dsn']['username'];
|
|
#$command = "echo \"CREATE DATABASE $database OWNER $username\" | su postgres -c psql 2>/dev/null";
|
|
$command = "su postgres -c \"createdb $database --encoding UTF8 --owner $username\"";
|
|
|
|
@exec($command, $output, $results);
|
|
if ($results == 0) {
|
|
echo " * Database '{$CC_CONFIG['dsn']['database']}' created.".PHP_EOL;
|
|
} else {
|
|
if (count($output) > 0) {
|
|
echo " * Could not create database '{$CC_CONFIG['dsn']['database']}': ".PHP_EOL;
|
|
echo implode(PHP_EOL, $output);
|
|
}
|
|
else {
|
|
echo " * Database '{$CC_CONFIG['dsn']['database']}' already exists.".PHP_EOL;
|
|
}
|
|
}
|
|
|
|
$databaseExisted = ($results != 0);
|
|
|
|
return $databaseExisted;
|
|
}
|
|
|
|
public static function InstallPostgresScriptingLanguage()
|
|
{
|
|
$con = Propel::getConnection();
|
|
|
|
// Install postgres scripting language
|
|
$sql = 'SELECT COUNT(*) FROM pg_language WHERE lanname = \'plpgsql\'';
|
|
$langIsInstalled = $con->query($sql)->fetchColumn(0);
|
|
if ($langIsInstalled == '0') {
|
|
echo " * Installing Postgres scripting language".PHP_EOL;
|
|
$sql = "CREATE LANGUAGE 'plpgsql'";
|
|
AirtimeInstall::InstallQuery($sql, false);
|
|
} else {
|
|
echo " * Postgres scripting language already installed".PHP_EOL;
|
|
}
|
|
}
|
|
|
|
public static function CreateDatabaseTables($p_dbuser, $p_dbpasswd, $p_dbname, $p_dbhost)
|
|
{
|
|
echo " * Creating database tables".PHP_EOL;
|
|
|
|
// Put Propel sql files in Database
|
|
//$command = AirtimeInstall::CONF_DIR_WWW."/library/propel/generator/bin/propel-gen ".AirtimeInstall::CONF_DIR_WWW."/build/ insert-sql 2>/dev/null";
|
|
|
|
$dir = self::GetAirtimeSrcDir()."/build/sql/";
|
|
$files = array("schema.sql", "sequences.sql", "views.sql", "triggers.sql", "defaultdata.sql");
|
|
|
|
foreach ($files as $f){
|
|
$command = "export PGPASSWORD=$p_dbpasswd && psql --username $p_dbuser --dbname $p_dbname --host $p_dbhost --file $dir$f 2>/dev/null";
|
|
@exec($command, $output, $results);
|
|
}
|
|
|
|
AirtimeInstall::$databaseTablesCreated = true;
|
|
}
|
|
|
|
public static function BypassMigrations($dir, $version)
|
|
{
|
|
$appDir = AirtimeInstall::GetAirtimeSrcDir();
|
|
$command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ".
|
|
"--configuration=$dir/../../DoctrineMigrations/migrations.xml ".
|
|
"--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ".
|
|
"--no-interaction --add migrations:version $version";
|
|
system($command);
|
|
}
|
|
|
|
public static function MigrateTablesToVersion($dir, $version)
|
|
{
|
|
$appDir = AirtimeInstall::GetAirtimeSrcDir();
|
|
$command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ".
|
|
"--configuration=$dir/../../DoctrineMigrations/migrations.xml ".
|
|
"--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ".
|
|
"--no-interaction migrations:migrate $version";
|
|
system($command);
|
|
}
|
|
|
|
public static function SetAirtimeVersion($p_version)
|
|
{
|
|
$con = Propel::getConnection();
|
|
$sql = "DELETE FROM cc_pref WHERE keystr = 'system_version'";
|
|
$con->exec($sql);
|
|
|
|
$sql = "INSERT INTO cc_pref (keystr, valstr) VALUES ('system_version', '$p_version')";
|
|
$result = $con->exec($sql);
|
|
if ($result < 1) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static function SetUniqueId()
|
|
{
|
|
$con = Propel::getConnection();
|
|
$uniqueId = md5(uniqid("", true));
|
|
|
|
$sql = "INSERT INTO cc_pref (keystr, valstr) VALUES ('uniqueId', '$uniqueId')";
|
|
$result = $con->exec($sql);
|
|
if ($result < 1) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static function SetDefaultTimezone()
|
|
{
|
|
$con = Propel::getConnection();
|
|
// we need to run php as commandline because we want to get the timezone in cli php.ini file
|
|
$defaultTimezone = exec("php -r 'echo date_default_timezone_get().PHP_EOL;'");
|
|
$defaultTimezone = trim($defaultTimezone);
|
|
if((!in_array($defaultTimezone, DateTimeZone::listIdentifiers()))){
|
|
$defaultTimezone = "UTC";
|
|
}
|
|
$sql = "INSERT INTO cc_pref (keystr, valstr) VALUES ('timezone', '$defaultTimezone')";
|
|
$result = $con->exec($sql);
|
|
if ($result < 1) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static function SetImportTimestamp()
|
|
{
|
|
$con = Propel::getConnection();
|
|
$sql = "INSERT INTO cc_pref (keystr, valstr) VALUES ('import_timestamp', '0')";
|
|
$result = $con->exec($sql);
|
|
if ($result < 1) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
public static function GetAirtimeVersion()
|
|
{
|
|
$con = Propel::getConnection();
|
|
$sql = "SELECT valstr FROM cc_pref WHERE keystr = 'system_version' LIMIT 1";
|
|
$version = $con->query($sql)->fetchColumn(0);
|
|
return $version;
|
|
}
|
|
|
|
public static function DeleteFilesRecursive($p_path)
|
|
{
|
|
$command = "rm -rf \"$p_path\"";
|
|
exec($command);
|
|
}
|
|
|
|
public static function CreateSymlinksToUtils()
|
|
{
|
|
echo "* Creating /usr/bin symlinks".PHP_EOL;
|
|
AirtimeInstall::RemoveSymlinks();
|
|
|
|
echo "* Installing airtime-import".PHP_EOL;
|
|
$dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-import/airtime-import";
|
|
exec("ln -s $dir /usr/bin/airtime-import");
|
|
|
|
echo "* Installing airtime-update-db-settings".PHP_EOL;
|
|
$dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-update-db-settings";
|
|
exec("ln -s $dir /usr/bin/airtime-update-db-settings");
|
|
|
|
echo "* Installing airtime-check-system".PHP_EOL;
|
|
$dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-check-system";
|
|
exec("ln -s $dir /usr/bin/airtime-check-system");
|
|
|
|
echo "* Installing airtime-user".PHP_EOL;
|
|
$dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-user";
|
|
exec("ln -s $dir /usr/bin/airtime-user");
|
|
|
|
echo "* Installing airtime-log".PHP_EOL;
|
|
$dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-log";
|
|
exec("ln -s $dir /usr/bin/airtime-log");
|
|
}
|
|
|
|
public static function RemoveSymlinks()
|
|
{
|
|
exec("rm -f /usr/bin/airtime-import");
|
|
exec("rm -f /usr/bin/airtime-update-db-settings");
|
|
exec("rm -f /usr/bin/airtime-check-system");
|
|
exec("rm -f /usr/bin/airtime-user");
|
|
exec("rm -f /usr/bin/airtime-log");
|
|
exec("rm -f /usr/bin/airtime-clean-storage");
|
|
}
|
|
|
|
public static function InstallPhpCode()
|
|
{
|
|
global $CC_CONFIG;
|
|
echo "* Installing PHP code to ".AirtimeInstall::CONF_DIR_WWW.PHP_EOL;
|
|
exec("mkdir -p ".AirtimeInstall::CONF_DIR_WWW);
|
|
exec("cp -R ".AirtimeInstall::GetAirtimeSrcDir()."/* ".AirtimeInstall::CONF_DIR_WWW);
|
|
|
|
}
|
|
|
|
public static function UninstallPhpCode()
|
|
{
|
|
echo "* Removing PHP code from ".AirtimeInstall::CONF_DIR_WWW.PHP_EOL;
|
|
exec('rm -rf "'.AirtimeInstall::CONF_DIR_WWW.'"');
|
|
}
|
|
|
|
public static function InstallBinaries()
|
|
{
|
|
echo "* Installing binaries to ".AirtimeInstall::CONF_DIR_BINARIES.PHP_EOL;
|
|
exec("mkdir -p ".AirtimeInstall::CONF_DIR_BINARIES);
|
|
exec("cp -R ".AirtimeInstall::GetUtilsSrcDir()." ".AirtimeInstall::CONF_DIR_BINARIES);
|
|
}
|
|
|
|
public static function UninstallBinaries()
|
|
{
|
|
echo "* Removing Airtime binaries from ".AirtimeInstall::CONF_DIR_BINARIES.PHP_EOL;
|
|
exec('rm -rf "'.AirtimeInstall::CONF_DIR_BINARIES.'"');
|
|
}
|
|
|
|
public static function DirCheck()
|
|
{
|
|
echo "Legend: \"+\" means the dir/file exists, \"-\" means that it does not.".PHP_EOL;
|
|
$dirs = array(AirtimeInstall::CONF_DIR_BINARIES,
|
|
AirtimeInstall::CONF_DIR_WWW,
|
|
AirtimeIni::CONF_FILE_AIRTIME,
|
|
AirtimeIni::CONF_FILE_LIQUIDSOAP,
|
|
AirtimeIni::CONF_FILE_PYPO,
|
|
AirtimeIni::CONF_FILE_RECORDER,
|
|
"/usr/lib/airtime/pypo",
|
|
"/var/log/airtime",
|
|
"/var/log/airtime/pypo",
|
|
"/var/tmp/airtime/pypo");
|
|
foreach ($dirs as $f) {
|
|
if (file_exists($f)) {
|
|
echo "+ $f".PHP_EOL;
|
|
} else {
|
|
echo "- $f".PHP_EOL;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static function CreateZendPhpLogFile(){
|
|
global $CC_CONFIG;
|
|
|
|
$path = AirtimeInstall::CONF_DIR_LOG;
|
|
$file = $path.'/zendphp.log';
|
|
if (!file_exists($path)){
|
|
mkdir($path, 0755, true);
|
|
}
|
|
|
|
touch($file);
|
|
chmod($file, 0644);
|
|
chown($file, $CC_CONFIG['webServerUser']);
|
|
chgrp($file, $CC_CONFIG['webServerUser']);
|
|
}
|
|
|
|
public static function RemoveLogDirectories(){
|
|
$path = AirtimeInstall::CONF_DIR_LOG;
|
|
echo "* Removing logs directory ".$path.PHP_EOL;
|
|
|
|
exec("rm -rf \"$path\"");
|
|
}
|
|
|
|
public static function CreateCronFile(){
|
|
echo "* Creating Cron File".PHP_EOL;
|
|
// Create CRON task to run every day. Time of day is initialized to a random time.
|
|
$hour = rand(0,23);
|
|
$minute = rand(0,59);
|
|
|
|
$fp = fopen('/etc/cron.d/airtime-crons','w');
|
|
fwrite($fp, "$minute $hour * * * root /usr/lib/airtime/utils/phone_home_stat\n");
|
|
fclose($fp);
|
|
}
|
|
|
|
public static function removeVirtualEnvDistributeFile(){
|
|
echo "* Removing distribute-0.6.10.tar.gz".PHP_EOL;
|
|
if(file_exists('/usr/share/python-virtualenv/distribute-0.6.10.tar.gz')){
|
|
exec("rm -f /usr/share/python-virtualenv/distribute-0.6.10.tar.gz");
|
|
}
|
|
}
|
|
|
|
public static function printUsage($opts)
|
|
{
|
|
$msg = $opts->getUsageMessage();
|
|
echo PHP_EOL."Usage: airtime-install [options]";
|
|
echo substr($msg, strpos($msg, "\n")).PHP_EOL;
|
|
}
|
|
|
|
public static function getOpts()
|
|
{
|
|
try {
|
|
$autoloader = Zend_Loader_Autoloader::getInstance();
|
|
$opts = new Zend_Console_Getopt(
|
|
array(
|
|
'help|h' => 'Displays usage information.',
|
|
'overwrite|o' => 'Overwrite any existing config files.',
|
|
'preserve|p' => 'Keep any existing config files.',
|
|
'no-db|n' => 'Turn off database install.',
|
|
'reinstall|r' => 'Force a fresh install of this Airtime Version',
|
|
'webonly|w' => 'Install only web files'
|
|
)
|
|
);
|
|
$opts->parse();
|
|
} catch (Zend_Console_Getopt_Exception $e) {
|
|
print $e->getMessage() .PHP_EOL;
|
|
AirtimeInstall::printUsage($opts);
|
|
return NULL;
|
|
}
|
|
return $opts;
|
|
}
|
|
}
|