function cos_upgrade_to($version) { common::echoMessage("Will now pull source, and checkout latest tag", 'y'); $command = "git fetch --tags && git checkout master && git pull && git checkout {$version}"; $ret = common::execCommand($command); if ($ret) { common::abort('Aborting upgrade'); } common::echoMessage("Will upgrade vendor with composer according to version", 'y'); $command = "composer update"; $ret = common::systemCommand($command); if ($ret) { common::abort('Composer update failed.'); } common::echoMessage("Will upgrade all modules and templates the versions in the profile", 'y'); // Upgrade all modules and templates $profile = conf::getModuleIni('system_profile'); if (!$profile) { $profile = 'default'; } upgrade_from_profile(array('clone_only' => 1, 'profile' => $profile)); // reload any changes common::echoMessage("Reloading all configuration files", 'y'); $p = new profile(); $p->reloadProfile($profile); common::echoMessage("Load modules changes into database", 'y'); cos_config_reload(); }
/** * build source package with more simple form of install. * @param array $options */ function cos_build_simple($options = null) { $dir = getcwd(); $name = basename($dir); if (file_exists("./build/{$name}")) { common::execCommand("sudo rm -rf ./build/{$name}*"); } common::execCommand("mkdir ./build/{$name}"); $htdocs = "cp -rf htdocs/* ./build/{$name}"; common::execCommand($htdocs); $domain = conf::getMainIni('domain'); if (!$domain) { $domain = 'default'; } $files_rm = "sudo rm -rf ./build/{$name}/files/{$domain}/*"; common::execCommand($files_rm); $config = "mkdir ./build/{$name}/config"; common::execCommand($config); $tmp_dir = "mkdir ./build/{$name}/tmp"; common::execCommand($tmp_dir); $profiles = "cp -rf profiles ./build/{$name}"; common::execCommand($profiles); $sql_scripts = "cp -rf scripts ./build/{$name}"; common::execCommand($sql_scripts); $cli = "cp -rf coscli.sh ./build/{$name}"; common::execCommand($cli); $composer = "cp -rf composer.json ./build/{$name}"; common::execCommand($composer); // reset database password $ary = conf::getIniFileArray("./config/config.ini"); $profile = new profile(); $ary = $profile->iniArrayPrepare($ary); // clean ini settings for secrets $ini_settings = conf::arrayToIniFile($ary); // add ini dist file file_put_contents("./build/{$name}/config/config.ini-dist", $ini_settings); $index = "cp -rf htdocs/index.php ./build/{$name}/index.php"; common::execCommand($index); $phar_cli = "cp -rf phar-cli.php ./build/{$name}/"; common::execCommand($phar_cli); $phar_web = "cp -rf phar-web.php ./build/{$name}/"; common::execCommand($phar_web); $module_dir = conf::pathModules(); $modules = "cp -rf {$module_dir} ./build/{$name}"; common::execCommand($modules); $vendor = "cp -rf vendor ./build/{$name}"; common::execCommand($vendor); $rm_git = "rm `find ./build/{$name} -name '.git'` -rf"; common::execCommand($rm_git); $rm_ignore = "rm `find ./build/{$name} -name '.gitignore'` -rf"; common::execCommand($rm_ignore); $rm_doc = "rm -rf ./build/vendor/doc"; common::execCommand($rm_doc); $output = array(); exec('git tag -l', $output); $version = array_pop($output); $command = "cd ./build && tar -Pczf {$name}-{$version}.tar.gz {$name} "; common::execCommand($command); }
/** * function for purgeing a template * * @param array options */ function purge_template($options) { //uninstall_module($options); if (strlen($options['template']) == 0) { common::echoMessage("No such template: {$options['template']}"); common::abort(); } $template_path = conf::pathBase() . '/htdocs/templates/' . $options['template']; if (!file_exists($template_path)) { common::echoMessage("Template already purged: No such template path: {$template_path}"); common::abort(); } $command = "rm -rf {$template_path}"; common::execCommand($command); }
/** * wrapper function for creating documention with phpdoc * hi! I'am created with this function :) * * @return int value from cos_system command */ function create_docs() { // check if command exists $command = "whereis phpdoc"; $ret = common::execCommand($command); if ($ret) { common::echoMessage("Could not find command phpdoc on your system"); common::echoMessage("If the command phpdoc is not on your system we will not be able to create documentation."); common::echoMessage("One way to do this is to: pear install PhpDocumentor"); exit(127); } $command = "phpdoc run "; $command .= "-d coslib "; $command .= "--template abstract -t " . conf::pathBase() . "/htdocs/phpdocs "; common::systemCommand($command); }
function db_to_sqlite($options = array()) { $check = "which sequel"; if (common::execCommand($check)) { common::echoMessage('You need sequel. Install it like this, e.g.:'); common::echoMessage('sudo aptitude install ruby-sequel libsqlite3-ruby libmysql-ruby'); common::abort(); } else { common::echoStatus('OK', 'g', 'Sequel is installed'); } $ok = false; $info = admin::getDbInfo(); if (!$info) { return db_no_url(); } if ($info['scheme'] == 'mysql') { $ok = true; } if ($info['scheme'] == 'mysqli') { $ok = true; } if (!$ok) { common::echoStatus('ERROR', 'r', 'Driver needs to be mysql or mysqli'); } $fs = new Filesystem(); $fs->remove('sqlite/database.sql'); $username = conf::getMainIni('username'); $password = conf::getMainIni('password'); $command = "sequel "; $command .= "{$info['scheme']}://{$username}:{$password}@{$info['host']}/{$info['dbname']} "; $command .= "-C "; $command .= "sqlite://sqlite/database.sql"; $ret = common::systemCommand($command); $base = conf::pathBase(); if (!$ret) { $fs->chmod('sqlite/database.sql', 0777, 00, true); common::echoMessage('Sqlite database created. Edit config.ini and add:'); common::echoMessage("sqlite:/{$base}/sqlite/database.sql"); } }
/** * function for creating a skeleton for a module. We are just * using shell command touch for creating the files. * * @param array e.g: <code>array('module' => 'test')</code> This will create * the following folder /modules/test containing base files * used when writing a module * @return int result from shell operation 0 is success */ function create_module_skeleton($args) { $module_name = $args['module']; $ary = explode('/', $module_name); $module_path = conf::pathModules() . '/' . $module_name; common::execCommand('mkdir ' . $module_path); if (count($ary) == 1) { // create dirs for sql. Only need in a base module $mysql_dir = $module_path . "/mysql"; common::execCommand('mkdir ' . $mysql_dir); $mysql_up = $mysql_dir . "/up"; common::execCommand('mkdir ' . $mysql_up); $mysql_down = $mysql_dir . "/down"; common::execCommand('mkdir ' . $mysql_down); // create dirs for language. Only need in base module $lang_dir = $module_path . "/lang"; common::execCommand('mkdir ' . $lang_dir); $lang_dir_en = $module_path . "/lang/en_GB"; common::execCommand('mkdir ' . $lang_dir_en); $files = $module_path . "/menu.inc "; $files .= $module_path . "/views.php "; $files .= $module_path . "/README.md "; $files .= $module_path . "/install.inc "; $files .= $module_path . "/{$module_name}.ini "; $files .= $module_path . "/{$module_name}.ini-dist "; $files .= $module_path . "/module.php "; $files .= $lang_dir_en . "/system.inc "; $files .= $lang_dir_en . "/language.inc "; } common::echoMessage('Creating files: '); $res = common::execCommand('touch ' . $files); if (!$res) { // add a version $str = "<?php\n\n\$_INSTALL['VERSION'] = 1.71; \n"; $res = file_put_contents($module_path . "/install.inc", $str); $res; } }
/** * Try to set a public clone URL in a module array * @param array $val module info * @return array $val module info with a public clone URL. If a public clone URL exists */ public static function getCloneUrl($module_name) { $module_path = conf::pathModules() . "/{$module_name}"; if (!file_exists($module_path)) { common::echoStatus('NOTICE', 'y', "module {$module_name} has no module source"); return false; } $command = "cd {$module_path} && git config --get remote.origin.url"; $ret = common::execCommand($command, array('silence' => 1), 0); if ($ret == 0) { $git_url = shell_exec($command); return trim($git_url); } return false; }
/** * function for loading a database file into db specified in config.ini * * @param array options. You can specifiy a file to load in options. * e.g. <code>$options = array('File' => 'backup/sql/latest.sql')</code> * @return int the executed commands shell status 0 on success. */ function cos_db_load_table($options) { if (!isset($options['table'])) { common::abort('Specify a table to load with a backup'); } $dump_dir = "backup/sql/{$options['table']}"; if (!file_exists($dump_dir)) { common::abort('Yet no backups'); } $search = conf::pathBase() . "/backup/sql/{$options['table']}"; $latest = get_latest_db_dump($search); if ($latest == 0) { common::abort('Yet no database dumps'); } $latest = "backup/sql/{$options['table']}/" . $latest . ".sql"; $db = admin::getDbInfo(); if (!$db) { return db_no_url(); } $command = "mysql --default-character-set=utf8 -u" . conf::$vars['coscms_main']['username'] . " -p" . conf::$vars['coscms_main']['password'] . " {$db['dbname']} < {$latest}"; return $ret = common::execCommand($command); }
/** * function for loading a database file into db specified in config.ini * * @param array options. You can specifiy a file to load in options. * e.g. <code>$options = array('File' => 'backup/sql/latest.sql')</code> * @return int the executed commands shell status 0 on success. */ function load_db_file($options) { if (!isset($options['File'])) { common::echoMessage('You did not specify file to load. We use latest!'); $latest = get_latest_db_dump(); if ($latest == 0) { common::abort('Yet no database dumps'); } $latest = "backup/sql/" . $latest . ".sql"; $file = $latest; } else { $file = $options['File']; if (!file_exists($file)) { common::abort("No such file: {$file}"); } } $db = admin::getDbInfo(conf::getMainIni('url')); if (!$db) { return db_no_url(); } $command = "mysql --default-character-set=utf8 -u" . conf::$vars['coscms_main']['username'] . " -p" . conf::$vars['coscms_main']['password'] . " -h{$db['host']} {$db['dbname']} < {$file}"; return $ret = common::execCommand($command); }
/** * Method that disable an apache2 site * * @param array $options only options is $options[sitename] */ public static function disableSite($options) { common::needRoot(); $hostname = trim($options['hostname']); $apache2_conf_file = "/etc/apache2/sites-available/{$hostname}"; $ret = common::execCommand("a2dissite {$hostname}"); if ($ret) { return false; } $version = self::getVersion(); $version = version::getSemanticAry($version); if ($version['minor'] >= 4) { $apache2_conf_file .= ".conf"; } $ret = common::execCommand("rm -f {$apache2_conf_file}"); // create new hosts file and reload server $host_file_str = ''; $hosts_file_str = file("/etc/hosts"); $host_search = "127.0.0.1\t{$hostname}\n"; $str = ""; foreach ($hosts_file_str as $key => $val) { if (strstr($val, $host_search)) { continue; } else { $host_file_str .= $val; } } file_put_contents("tmp/hosts", $host_file_str); common::execCommand("cp -f tmp/hosts /etc/hosts"); common::execCommand("/etc/init.d/apache2 reload"); }
/** * Get a clone URL from git path * @param string $path * @return string|false string if we get a clone URL, selse false */ public static function getCloneUrlFromPath($path) { $command = "cd {$path} && git config --get remote.origin.url"; $ret = common::execCommand($command, array('silence' => 1), 0); if ($ret == 0) { $git_url = shell_exec($command); return trim($git_url); } return false; }
/** * function for removing all files in htdocs/files/*, htdocs/logo/* * when doing an install * * @return int value from exec command */ function cos_create_files() { $files_path = conf::pathBase() . '/logs/coscms.log'; if (!file_exists($files_path)) { $command = "touch {$files_path}"; common::execCommand($command); } $files_path = conf::pathBase() . '/logs/cron.log'; if (!file_exists($files_path)) { $command = "touch {$files_path}"; common::execCommand($command); } $files_path = conf::pathFiles(); if (!file_exists($files_path)) { $command = "mkdir -p {$files_path}"; common::execCommand($command); } }
function cos_phar_web_create() { // move sources to build dir. // e.g. build/coscms cos_build_simple(); // some base values $dir = getcwd(); $base = basename($dir); // dir we build phar from $build_from_dir = "{$dir}/build/{$base}"; // when creating a web phar we add // config.ini // this is done so that on first exectution of the // phar archive we will create this file and a .sqlite database. $build_phar_dir = "build/phar"; if (!file_exists($build_phar_dir)) { common::execCommand("mkdir {$build_phar_dir}"); } // hidden .config file // cos_exec("cp -f config/config.ini $build_from_dir/tmp/.config.ini"); // reset database password $ary = conf::getIniFileArray("./config/config.ini"); $profile = new profile(); // rm secrets $ary = $profile->iniArrayPrepare($ary); // add sqlite database to build phar dir if (conf::getMainIni('phar_sqlite')) { db_to_sqlite(); // mv sqlite database into hidden file common::execCommand("cp -R sqlite/database.sql {$build_from_dir}/tmp/.database.sql"); common::execCommand("chmod 777 {$build_from_dir}/tmp/.database.sql"); common::execCommand("mkdir {$build_from_dir}/sqlite"); unset($ary['db_init']); $ary['url'] = 'sqlite:.database.sql'; } // no caching of assets. Place css and js in file $ary['cached_assets'] = 0; $ary['cashed_assets_reload'] = 0; $ary['cached_assets_minify'] = 0; $ary['cached_assets_compress'] = 0; $ary['cached_assets_inline'] = 1; if (conf::getMainIni('phar_files')) { common::execCommand("cp -rf htdocs/files {$build_from_dir}"); common::execCommand("sudo chown -R 777 {$build_from_dir}/files"); } $ini_settings = conf::arrayToIniFile($ary); file_put_contents("{$build_from_dir}/tmp/.config.ini", $ini_settings); chdir($build_phar_dir); $output = "{$base}-web.phar"; $phar = new Phar($output); $phar->buildFromDirectory($build_from_dir); $stub = $phar->createDefaultStub('phar-web.php', 'phar-web.php'); $phar->setStub($stub); $phar->stopBuffering(); echo "Web phar executable file created from current source ({$output})\n"; echo "Serve it e.g. with the built-in server. Like this:\n"; echo "cd {$build_phar_dir}\n"; echo "php -S localhost:8080 {$base}-web.phar\n"; exit(0); }
/** * CLI command. Function for restoring tar archive * All file settings are restored (if user is the owner of all files) * * @param array options to parser, e.g. * <code>array('File' => '/backup/full/latest.tar')</code> This will restore * the tar achive /backup/full/latest.tar * * Leave options empty if you * want to restore latest archive with highest timestamp, .e.g * backup/full/1264168904.tar * @return int the executed commands shell status 0 on success. */ function backup_files_restore($options) { // in order to easily preserve ownership we use need to run as root if (!isset($options['File'])) { $latest = backup_get_latest_backup('files'); if ($latest == 0) { die("Yet no backups\n"); } $backup_file = $latest = "backup/files/" . $latest . ".tar.gz"; } else { $backup_file = $options['File']; } common::needRoot("In order to restore: {$backup_file}. We need root"); $command = "tar -Pxzf {$backup_file} -v ./htdocs/files "; $ret = common::execCommand($command); }
/** * function for removing all files in htdocs/files/*, htdocs/logo/* * when doing an install * * @return int value from exec command */ function cos_create_files() { $files_path = conf::pathBase() . '/logs/coscms.log'; if (!file_exists($files_path)) { $command = "touch {$files_path}"; common::execCommand($command); } $files_path = conf::pathBase() . '/htdocs/files'; if (!file_exists($files_path)) { $command = "mkdir {$files_path}"; common::execCommand($command); } $domain = conf::getDomain(); $files_path = conf::pathBase() . "/htdocs/files/{$domain}"; if (!file_exists($files_path)) { $command = "mkdir {$files_path}"; common::execCommand($command); } }
/** * function for purging a module (compleate removal) * * @param array options */ function purge_module($options) { // check if module is set if (strlen($options['module']) == 0) { common::echoMessage("No such module: {$options['module']}"); common::abort(); } // check if module exists $module_path = conf::pathModules() . '/' . $options['module']; if (!file_exists($module_path)) { common::echoMessage("module already purged: No such module path: {$module_path}"); common::abort(); } // it exists. Uninstall uninstall_module($options); // remove $command = "rm -rf {$module_path}"; common::execCommand($command); }
/** * function for doing a prompt install from shell mode * is a wrapper around other shell functions. */ function prompt_install() { common::echoMessage('Pick a version to install:', 'y'); $tags = git::getTagsInstallLatest() . PHP_EOL; $tags .= "master"; common::echoMessage($tags); $tag = common::readSingleline("Enter tag (version) to use:"); common::execCommand("git checkout {$tag}"); // Which profile to install $profiles = file::getFileList('profiles', array('dir_only' => true)); if (count($profiles) == 1) { $profile = array_pop($profiles); } else { common::echoMessage("List of profiles: "); foreach ($profiles as $val) { common::echoMessage("\t" . $val); } // select profile and load it $profile = common::readSingleline('Enter profile, and hit return: '); } common::echoMessage("Loading the profile '{$profile}'", 'y'); load_profile(array('profile' => $profile, 'config_only' => true)); common::echoMessage("Main configuration (placed in config/config.ini) for '{$profile}' is loaded", 'y'); // Keep base path. Ortherwise we will lose it when loading profile $base_path = conf::pathBase(); // Load the default config.ini settings as a skeleton conf::$vars['coscms_main'] = conf::getIniFileArray($base_path . '/config/config.ini', true); // Reset base path conf::setMainIni('base_path', $base_path); conf::defineCommon(); common::echoMessage("Enter MySQL credentials", 'y'); // Get configuration info $host = common::readSingleline('Enter your MySQL host: '); $database = common::readSingleline('Enter database name: '); $username = common::readSingleline('Enter database user: '******'Enter database users password: '******'Enter server host name: '); common::echoMessage("Writing database connection info to main configuration"); // Assemble configuration info conf::$vars['coscms_main']['url'] = "mysql:dbname={$database};host={$host};charset=utf8"; conf::$vars['coscms_main']['username'] = $username; conf::$vars['coscms_main']['password'] = $password; conf::$vars['coscms_main']['server_name'] = $server_name; // Write it to ini file $content = conf::arrayToIniFile(conf::$vars['coscms_main'], false); $path = conf::pathBase() . "/config/config.ini"; file_put_contents($path, $content); common::echoMessage("Your can also always change the config/config.ini file manually"); $options = array(); $options['profile'] = $profile; if ($tag == 'master') { $options['master'] = true; } common::echoMessage("Will now clone and install all modules", 'y'); cos_install($options); common::echoMessage("Create a super user", 'y'); useradd_add(); $login = "******"; common::echoMessage("If there was no errors you will be able to login at {$login}"); common::echoMessage("Remember to change file permissions. This will require super user"); common::echoMessage("E.g. like this:"); common::echoMessage("sudo ./coscli.sh file --chmod-files"); }
/** * function for upgrading a module, template or profile according to latest tag * or master * * @param array with module options * @param string tag with wersion or 'master' * @param string module, templatee or profile. */ function cos_git_upgrade($val, $tag = 'master', $type = 'module') { if (!isset($val['module_name'])) { $val['module_name'] = git::getModulenameFromRepo($val['repo']); } $repo_path = cos_get_repo_path($val['module_name'], $type); if (!cos_git_is_repo($repo_path)) { common::echoMessage("{$repo_path} is not a git repo - will not upgrade"); return; } $git_command = "cd {$repo_path} && "; $git_command .= "git checkout master && "; $git_command .= "git pull && git fetch --tags && "; $git_command .= "git checkout {$tag}"; common::execCommand($git_command); if ($type == 'module') { // It is called with a different name in the upgrade_module // function ... $val['module'] = $val['module_name']; // upgrade to latest set in $_INSTALL['VERSION'] $val['version'] = null; upgrade_module($val); } // templates have no registry - they are tag based only in version }
/** * prompt install command */ function heroku_prompt_install() { $res = common::execCommand("which heroku"); if ($res) { die('You wll need the heroku command. Download the heroku toolbelt'); } echo "Enabling addons ... wait\n"; heroku_enable_addons(); common::execCommand("cp misc/htaccess .htaccess"); common::execCommand("mkdir -p files/default"); common::execCommand("chmod -R 777 files"); common::execCommand("touch files/default/dummy.txt"); load_db_default(); common::echoMessage('Installing all modules. This may take a few minutes. Be patient'); install_from_profile(array('profile' => 'default')); useradd_add(); }
/** * creates a database from config params (url, password, username) * @param array $options * @return int $res result from exec operation */ public static function createDB($options = array()) { $db = admin::getDbInfo(); if (!$db) { return db_no_url(); } $command = "mysqladmin -u" . conf::$vars['coscms_main']['username'] . " -p" . conf::$vars['coscms_main']['password'] . " -h{$db['host']} "; $command .= "--default-character-set=utf8 "; $command .= "CREATE {$db['dbname']}"; return $ret = common::execCommand($command, $options); }