From 037212badb221b0d93f30fc1466a545ea3f99c20 Mon Sep 17 00:00:00 2001 From: denise Date: Mon, 14 Jan 2013 11:45:51 -0500 Subject: [PATCH] Upgrade Scripts --- .../airtime-2.3.0/ConfFileUpgrade.php | 16 + .../upgrades/airtime-2.3.0/DbUpgrade.php | 24 ++ .../airtime-2.3.0/airtime-upgrade.php | 11 + .../airtime-2.3.0/common/UpgradeCommon.php | 322 ++++++++++++++++++ .../upgrades/airtime-2.3.0/data/upgrade.sql | 3 + .../airtime-2.3.0/etc/airtime.conf.230 | 32 ++ .../airtime-2.3.0/etc/api_client.cfg.230 | 128 +++++++ .../airtime-2.3.0/etc/media-monitor.cfg.230 | 31 ++ .../upgrades/airtime-2.3.0/etc/pypo.cfg.230 | 85 +++++ 9 files changed, 652 insertions(+) create mode 100644 install_minimal/upgrades/airtime-2.3.0/ConfFileUpgrade.php create mode 100644 install_minimal/upgrades/airtime-2.3.0/DbUpgrade.php create mode 100644 install_minimal/upgrades/airtime-2.3.0/airtime-upgrade.php create mode 100644 install_minimal/upgrades/airtime-2.3.0/common/UpgradeCommon.php create mode 100644 install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql create mode 100644 install_minimal/upgrades/airtime-2.3.0/etc/airtime.conf.230 create mode 100644 install_minimal/upgrades/airtime-2.3.0/etc/api_client.cfg.230 create mode 100644 install_minimal/upgrades/airtime-2.3.0/etc/media-monitor.cfg.230 create mode 100644 install_minimal/upgrades/airtime-2.3.0/etc/pypo.cfg.230 diff --git a/install_minimal/upgrades/airtime-2.3.0/ConfFileUpgrade.php b/install_minimal/upgrades/airtime-2.3.0/ConfFileUpgrade.php new file mode 100644 index 000000000..8aab3191d --- /dev/null +++ b/install_minimal/upgrades/airtime-2.3.0/ConfFileUpgrade.php @@ -0,0 +1,16 @@ +&1 | grep -v \"will create implicit index\""); + } +} diff --git a/install_minimal/upgrades/airtime-2.3.0/airtime-upgrade.php b/install_minimal/upgrades/airtime-2.3.0/airtime-upgrade.php new file mode 100644 index 000000000..924babbdb --- /dev/null +++ b/install_minimal/upgrades/airtime-2.3.0/airtime-upgrade.php @@ -0,0 +1,11 @@ +fetchColumn(); + + date_default_timezone_set($timezone); + } + + public static function connectToDatabase($p_exitOnError = true) + { + try { + $con = Propel::getConnection(); + } catch (Exception $e) { + echo $e->getMessage().PHP_EOL; + echo "Database connection problem.".PHP_EOL; + echo "Check if database exists with corresponding permissions.".PHP_EOL; + if ($p_exitOnError) { + exit(1); + } + return false; + } + return true; + } + + + 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; + } + + private static function GetAirtimeSrcDir() + { + return __DIR__."/../../../../airtime_mvc"; + } + + public static function MigrateTablesToVersion($dir, $version) + { + echo "Upgrading database, may take several minutes, please wait".PHP_EOL; + + $appDir = self::GetAirtimeSrcDir(); + $command = "php --php-ini $dir/../../airtime-php.ini ". + "$appDir/library/doctrine/migrations/doctrine-migrations.phar ". + "--configuration=$dir/common/migrations.xml ". + "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". + "--no-interaction migrations:migrate $version"; + system($command); + } + + public static function BypassMigrations($dir, $version) + { + $appDir = self::GetAirtimeSrcDir(); + $command = "php --php-ini $dir/../../airtime-php.ini ". + "$appDir/library/doctrine/migrations/doctrine-migrations.phar ". + "--configuration=$dir/common/migrations.xml ". + "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". + "--no-interaction --add migrations:version $version"; + system($command); + } + + public static function upgradeConfigFiles(){ + + $configFiles = array(UpgradeCommon::CONF_FILE_AIRTIME, + UpgradeCommon::CONF_FILE_PYPO, + //this is not necessary because liquidsoap configs + //are automatically generated + //UpgradeCommon::CONF_FILE_LIQUIDSOAP, + UpgradeCommon::CONF_FILE_MEDIAMONITOR, + UpgradeCommon::CONF_FILE_API_CLIENT); + + // Backup the config files + $suffix = date("Ymdhis")."-".UpgradeCommon::VERSION_NUMBER; + foreach ($configFiles as $conf) { + // do not back up monit cfg -- ok?? not being done anyway + if (file_exists($conf)) { + echo "Backing up $conf to $conf$suffix.bak".PHP_EOL; + //copy($conf, $conf.$suffix.".bak"); + exec("cp -p $conf $conf$suffix.bak"); //use cli version to preserve file attributes + } + } + + self::CreateIniFiles(UpgradeCommon::CONF_BACKUP_SUFFIX); + self::MergeConfigFiles($configFiles, $suffix); + + //HACK: This will fix a last minute bug we discovered with our upgrade scripts. + //Will be fixed properly in 2.3.0 + $old = "list_all_db_files = 'list-all-files/format/json/api_key/%%api_key%%/dir_id/%%dir_id%%'"; + $new = "list_all_db_files = 'list-all-files/format/json/api_key/%%api_key%%/dir_id/%%dir_id%%/all/%%all%%'"; + exec("sed -i \"s#$old#$new#g\" /etc/airtime/api_client.cfg"); + + $old = "update_start_playing_url = 'notify-media-item-start-play/api_key/%%api_key%%/media_id/%%media_id%%/schedule_id/%%schedule_id%%'"; + $new = "update_start_playing_url = 'notify-media-item-start-play/api_key/%%api_key%%/media_id/%%media_id%%/'"; + exec("sed -i \"s#$old#$new#g\" /etc/airtime/api_client.cfg"); + } + + /** + * This function creates the /etc/airtime configuration folder + * and copies the default config files to it. + */ + public static function CreateIniFiles($suffix) + { + if (!file_exists("/etc/airtime/")){ + if (!mkdir("/etc/airtime/", 0755, true)){ + echo "Could not create /etc/airtime/ directory. Exiting."; + exit(1); + } + } + + $config_copy = array( + "../etc/airtime.conf" => self::CONF_FILE_AIRTIME, + "../etc/pypo.cfg" => self::CONF_FILE_PYPO, + "../etc/media-monitor.cfg" => self::CONF_FILE_MEDIAMONITOR, + "../etc/api_client.cfg" => self::CONF_FILE_API_CLIENT + ); + + echo "Copying configs:\n"; + foreach ($config_copy as $path_part => $destination) { + $full_path = OsPath::normpath(OsPath::join(__DIR__, + "$path_part.$suffix")); + echo "'$full_path' --> '$destination'\n"; + if(!copy($full_path, $destination)) { + echo "Failed on the copying operation above\n"; + exit(1); + } + } + } + + private static function MergeConfigFiles(array $configFiles, $suffix) { + foreach ($configFiles as $conf) { + if (file_exists("$conf$suffix.bak")) { + + if($conf === self::CONF_FILE_AIRTIME) { + // Parse with sections + $newSettings = parse_ini_file($conf, true); + $oldSettings = parse_ini_file("$conf$suffix.bak", true); + } + else { + $newSettings = self::ReadPythonConfig($conf); + $oldSettings = self::ReadPythonConfig("$conf$suffix.bak"); + } + + $settings = array_keys($newSettings); + + foreach($settings as $section) { + if(isset($oldSettings[$section])) { + if(is_array($oldSettings[$section])) { + $sectionKeys = array_keys($newSettings[$section]); + foreach($sectionKeys as $sectionKey) { + + if(isset($oldSettings[$section][$sectionKey])) { + self::UpdateIniValue($conf, $sectionKey, + $oldSettings[$section][$sectionKey]); + } + } + } else { + self::UpdateIniValue($conf, $section, + $oldSettings[$section]); + } + } + } + } + } + } + + private static function ReadPythonConfig($p_filename) + { + $values = array(); + + $fh = fopen($p_filename, 'r'); + + while(!feof($fh)){ + $line = fgets($fh); + if(substr(trim($line), 0, 1) == '#' || trim($line) == ""){ + continue; + }else{ + $info = explode('=', $line, 2); + $values[trim($info[0])] = trim($info[1]); + } + } + + return $values; + } + + /** + * This function updates an INI style config file. + * + * A property and the value the property should be changed to are + * supplied. If the property is not found, then no changes are made. + * + * @param string $p_filename + * The path the to the file. + * @param string $p_property + * The property to look for in order to change its value. + * @param string $p_value + * The value the property should be changed to. + * + */ + private static function UpdateIniValue($p_filename, $p_property, $p_value) + { + $lines = file($p_filename); + $n = count($lines); + foreach ($lines as &$line) { + if ($line[0] != "#"){ + $key_value = explode("=", $line); + $key = trim($key_value[0]); + + if ($key == $p_property){ + $line = "$p_property = $p_value".PHP_EOL; + } + } + } + + $fp=fopen($p_filename, 'w'); + for($i=0; $i<$n; $i++){ + fwrite($fp, $lines[$i]); + } + fclose($fp); + } + + public static function queryDb($p_sql){ + $con = Propel::getConnection(); + + try { + $result = $con->query($p_sql); + } catch (Exception $e) { + echo "Error executing $p_sql. Exiting."; + exit(1); + } + + return $result; + } +} + +class OsPath { + // this function is from http://stackoverflow.com/questions/2670299/is-there-a-php-equivalent-function-to-the-python-os-path-normpath + public static function normpath($path) + { + if (empty($path)) + return '.'; + + if (strpos($path, '/') === 0) + $initial_slashes = true; + else + $initial_slashes = false; + if ( + ($initial_slashes) && + (strpos($path, '//') === 0) && + (strpos($path, '///') === false) + ) + $initial_slashes = 2; + $initial_slashes = (int) $initial_slashes; + + $comps = explode('/', $path); + $new_comps = array(); + foreach ($comps as $comp) + { + if (in_array($comp, array('', '.'))) + continue; + if ( + ($comp != '..') || + (!$initial_slashes && !$new_comps) || + ($new_comps && (end($new_comps) == '..')) + ) + array_push($new_comps, $comp); + elseif ($new_comps) + array_pop($new_comps); + } + $comps = $new_comps; + $path = implode('/', $comps); + if ($initial_slashes) + $path = str_repeat('/', $initial_slashes) . $path; + if ($path) + return $path; + else + return '.'; + } + + /* Similar to the os.path.join python method + * http://stackoverflow.com/a/1782990/276949 */ + public static function join() { + $args = func_get_args(); + $paths = array(); + + foreach($args as $arg) { + $paths = array_merge($paths, (array)$arg); + } + + foreach($paths as &$path) { + $path = trim($path, DIRECTORY_SEPARATOR); + } + + if (substr($args[0], 0, 1) == DIRECTORY_SEPARATOR) { + $paths[0] = DIRECTORY_SEPARATOR . $paths[0]; + } + + return join(DIRECTORY_SEPARATOR, $paths); + } +} diff --git a/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql b/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql new file mode 100644 index 000000000..4461717c4 --- /dev/null +++ b/install_minimal/upgrades/airtime-2.3.0/data/upgrade.sql @@ -0,0 +1,3 @@ +DELETE FROM cc_pref WHERE keystr = 'system_version'; +INSERT INTO cc_pref (keystr, valstr) VALUES ('system_version', '2.3.0'); + diff --git a/install_minimal/upgrades/airtime-2.3.0/etc/airtime.conf.230 b/install_minimal/upgrades/airtime-2.3.0/etc/airtime.conf.230 new file mode 100644 index 000000000..1a22289c0 --- /dev/null +++ b/install_minimal/upgrades/airtime-2.3.0/etc/airtime.conf.230 @@ -0,0 +1,32 @@ +[database] +host = localhost +dbname = airtime +dbuser = airtime +dbpass = airtime + +[rabbitmq] +host = 127.0.0.1 +port = 5672 +user = guest +password = guest +vhost = / + +[general] +api_key = AAA +web_server_user = www-data +airtime_dir = x +base_url = localhost +base_port = 80 +base_dir = '' + +;How many hours ahead of time should Airtime playout engine (PYPO) +;cache scheduled media files. +cache_ahead_hours = 1 + +[monit] +monit_user = guest +monit_password = airtime + +[soundcloud] +connection_retries = 3 +time_between_retries = 60 diff --git a/install_minimal/upgrades/airtime-2.3.0/etc/api_client.cfg.230 b/install_minimal/upgrades/airtime-2.3.0/etc/api_client.cfg.230 new file mode 100644 index 000000000..369f74eb8 --- /dev/null +++ b/install_minimal/upgrades/airtime-2.3.0/etc/api_client.cfg.230 @@ -0,0 +1,128 @@ +bin_dir = "/usr/lib/airtime/api_clients" + +############################# +## Common +############################# + +# Value needed to access the API +api_key = 'AAA' + +# Path to the base of the API +api_base = 'api' + +# URL to get the version number of the server API +version_url = 'version/api_key/%%api_key%%' + +#URL to register a components IP Address with the central web server +register_component = 'register-component/format/json/api_key/%%api_key%%/component/%%component%%' + +# Hostname +host = 'localhost' +base_port = 80 +base_dir = '' + +############################# +## Config for Media Monitor +############################# + +# URL to setup the media monitor +media_setup_url = 'media-monitor-setup/format/json/api_key/%%api_key%%' + +# Tell Airtime the file id associated with a show instance. +upload_recorded = 'upload-recorded/format/json/api_key/%%api_key%%/fileid/%%fileid%%/showinstanceid/%%showinstanceid%%' + +# URL to tell Airtime to update file's meta data +update_media_url = 'reload-metadata/format/json/api_key/%%api_key%%/mode/%%mode%%' + +# URL to tell Airtime we want a listing of all files it knows about +list_all_db_files = 'list-all-files/format/json/api_key/%%api_key%%/dir_id/%%dir_id%%/all/%%all%%' + +# URL to tell Airtime we want a listing of all dirs its watching (including the stor dir) +list_all_watched_dirs = 'list-all-watched-dirs/format/json/api_key/%%api_key%%' + +# URL to tell Airtime we want to add watched directory +add_watched_dir = 'add-watched-dir/format/json/api_key/%%api_key%%/path/%%path%%' + +# URL to tell Airtime we want to add watched directory +remove_watched_dir = 'remove-watched-dir/format/json/api_key/%%api_key%%/path/%%path%%' + +# URL to tell Airtime we want to add watched directory +set_storage_dir = 'set-storage-dir/format/json/api_key/%%api_key%%/path/%%path%%' + +# URL to tell Airtime about file system mount change +update_fs_mount = 'update-file-system-mount/format/json/api_key/%%api_key%%' + +# URL to commit multiple updates from media monitor at the same time + +reload_metadata_group = 'reload-metadata-group/format/json/api_key/%%api_key%%' + +# URL to tell Airtime about file system mount change +handle_watched_dir_missing = 'handle-watched-dir-missing/format/json/api_key/%%api_key%%/dir/%%dir%%' + +############################# +## Config for Recorder +############################# + +# URL to get the schedule of shows set to record +show_schedule_url = 'recorded-shows/format/json/api_key/%%api_key%%' + +# URL to upload the recorded show's file to Airtime +upload_file_url = 'upload-file/format/json/api_key/%%api_key%%' + +# URL to commit multiple updates from media monitor at the same time + +#number of retries to upload file if connection problem +upload_retries = 3 + +#time to wait between attempts to upload file if connection problem (in seconds) +upload_wait = 60 + +################################################################################ +# Uncomment *one of the sets* of values from the API clients below, and comment +# out all the others. +################################################################################ + +############################# +## Config for Pypo +############################# + +# Schedule export path. +# %%from%% - starting date/time in the form YYYY-MM-DD-hh-mm +# %%to%% - starting date/time in the form YYYY-MM-DD-hh-mm +export_url = 'schedule/api_key/%%api_key%%' + +get_media_url = 'get-media/file/%%file%%/api_key/%%api_key%%' + +# Update whether a schedule group has begun playing. +update_item_url = 'notify-schedule-group-play/api_key/%%api_key%%/schedule_id/%%schedule_id%%' + +# Update whether an audio clip is currently playing. +update_start_playing_url = 'notify-media-item-start-play/api_key/%%api_key%%/media_id/%%media_id%%/' + +# URL to tell Airtime we want to get stream setting +get_stream_setting = 'get-stream-setting/format/json/api_key/%%api_key%%/' + +#URL to update liquidsoap status +update_liquidsoap_status = 'update-liquidsoap-status/format/json/api_key/%%api_key%%/msg/%%msg%%/stream_id/%%stream_id%%/boot_time/%%boot_time%%' + +#URL to check live stream auth +check_live_stream_auth = 'check-live-stream-auth/format/json/api_key/%%api_key%%/username/%%username%%/password/%%password%%/djtype/%%djtype%%' + +#URL to update source status +update_source_status = 'update-source-status/format/json/api_key/%%api_key%%/sourcename/%%sourcename%%/status/%%status%%' + +get_bootstrap_info = 'get-bootstrap-info/format/json/api_key/%%api_key%%' + +get_files_without_replay_gain = 'get-files-without-replay-gain/api_key/%%api_key%%/dir_id/%%dir_id%%' + +update_replay_gain_value = 'update-replay-gain-value/api_key/%%api_key%%' + +notify_webstream_data = 'notify-webstream-data/api_key/%%api_key%%/media_id/%%media_id%%/format/json' + +notify_liquidsoap_started = 'rabbitmq-do-push/api_key/%%api_key%%/format/json' + +get_stream_parameters = 'get-stream-parameters/api_key/%%api_key%%/format/json' + +push_stream_stats = 'push-stream-stats/api_key/%%api_key%%/format/json' + +update_stream_setting_table = 'update-stream-setting-table/api_key/%%api_key%%/format/json' diff --git a/install_minimal/upgrades/airtime-2.3.0/etc/media-monitor.cfg.230 b/install_minimal/upgrades/airtime-2.3.0/etc/media-monitor.cfg.230 new file mode 100644 index 000000000..b1167f56b --- /dev/null +++ b/install_minimal/upgrades/airtime-2.3.0/etc/media-monitor.cfg.230 @@ -0,0 +1,31 @@ +api_client = "airtime" + +# where the binary files live +bin_dir = '/usr/lib/airtime/media-monitor' + +# where the logging files live +log_dir = '/var/log/airtime/media-monitor' + + +############################################ +# RabbitMQ settings # +############################################ +rabbitmq_host = 'localhost' +rabbitmq_user = 'guest' +rabbitmq_password = 'guest' +rabbitmq_vhost = '/' + +############################################ +# Media-Monitor preferences # +############################################ +check_filesystem_events = 5 #how long to queue up events performed on the files themselves. +check_airtime_events = 30 #how long to queue metadata input from airtime. + +# MM2 only: +touch_interval = 5 +chunking_number = 450 +request_max_wait = 3.0 +rmq_event_wait = 0.1 +logpath = '/var/log/airtime/media-monitor/media-monitor.log' +index_path = '/var/tmp/airtime/media-monitor/last_index' + diff --git a/install_minimal/upgrades/airtime-2.3.0/etc/pypo.cfg.230 b/install_minimal/upgrades/airtime-2.3.0/etc/pypo.cfg.230 new file mode 100644 index 000000000..9ffc390e4 --- /dev/null +++ b/install_minimal/upgrades/airtime-2.3.0/etc/pypo.cfg.230 @@ -0,0 +1,85 @@ +############################################ +# pypo - configuration # +############################################ + +# Set the type of client you are using. +# Currently supported types: +# 1) "obp" = Open Broadcast Platform +# 2) "airtime" +# +api_client = "airtime" + +############################################ +# Cache Directories # +# *include* trailing slash !! # +############################################ +cache_dir = '/var/tmp/airtime/pypo/cache/' +file_dir = '/var/tmp/airtime/pypo/files/' +tmp_dir = '/var/tmp/airtime/pypo/tmp/' + +############################################ +# Setup Directories # +# Do *not* include trailing slash !! # +############################################ +cache_base_dir = '/var/tmp/airtime/pypo' +bin_dir = '/usr/lib/airtime/pypo' +log_base_dir = '/var/log/airtime' +pypo_log_dir = '/var/log/airtime/pypo' +liquidsoap_log_dir = '/var/log/airtime/pypo-liquidsoap' + +############################################ +# Liquidsoap settings # +############################################ +ls_host = '127.0.0.1' +ls_port = '1234' + +############################################ +# RabbitMQ settings # +############################################ +rabbitmq_host = 'localhost' +rabbitmq_user = 'guest' +rabbitmq_password = 'guest' +rabbitmq_vhost = '/' + +############################################ +# pypo preferences # +############################################ + +# Poll interval in seconds. +# +# This will rarely need to be changed because any schedule changes are +# automatically sent to pypo immediately. +# +# This is how often the poll script downloads new schedules and files from the +# server in the event that no changes are made to the schedule. +# +poll_interval = 3600 # in seconds. + + +# Push interval in seconds. +# +# This is how often the push script checks whether it has something new to +# push to liquidsoap. +# +# It's hard to imagine a situation where this should be more than 1 second. +# +push_interval = 1 # in seconds + +# 'pre' or 'otf'. 'pre' cues while playlist preparation +# while 'otf' (on the fly) cues while loading into ls +# (needs the post_processor patch) +cue_style = 'pre' + +############################################ +# Recorded Audio settings # +############################################ +record_bitrate = 256 +record_samplerate = 44100 +record_channels = 2 +record_sample_size = 16 + +#can be either ogg|mp3, mp3 recording requires installation of the package "lame" +record_file_type = 'ogg' + +# base path to store recordered shows at +base_recorded_files = '/var/tmp/airtime/show-recorder/'