ported CLI stuff to namespaces-layout
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
@@ -21,483 +21,11 @@ if (@php_sapi_name() !== 'cli') {
|
||||
die('This script will only work in the shell.');
|
||||
}
|
||||
|
||||
require dirname(dirname(__DIR__)) . '/lib/classes/output/class.CmdLineHandler.php';
|
||||
|
||||
class ConfigServicesCmd extends CmdLineHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* list of valid switches
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $switches = array(
|
||||
'h'
|
||||
);
|
||||
|
||||
/**
|
||||
* list of valid parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $params = array(
|
||||
'create',
|
||||
'apply',
|
||||
'import-settings',
|
||||
'daemon',
|
||||
'list-daemons',
|
||||
'froxlor-dir',
|
||||
'help'
|
||||
);
|
||||
|
||||
public static $action_class = 'Action';
|
||||
|
||||
public static function printHelp()
|
||||
{
|
||||
self::println("");
|
||||
self::println("Help / command line parameters:");
|
||||
self::println("");
|
||||
// commands
|
||||
self::println("--create\t\tlets you create a services list configuration for the 'apply' command");
|
||||
self::println("");
|
||||
self::println("--apply\t\t\tconfigure your services by given configuration file. To create one run the --create command");
|
||||
self::println("\t\t\tExample: --apply=/path/to/my-config.json or --apply=http://domain.tld/my-config.json");
|
||||
self::println("");
|
||||
self::println("--list-daemons\t\tOutput the services that are going to be configured using a given config file. No services will be configured.");
|
||||
self::println("\t\t\tExample: --apply=/path/to/my-config.json --list-daemons");
|
||||
self::println("");
|
||||
self::println("--daemon\t\tWhen running --apply you can specify a daemon. This will be the only service that gets configured");
|
||||
self::println("\t\t\tExample: --apply=/path/to/my-config.json --daemon=apache24");
|
||||
self::println("");
|
||||
self::println("--import-settings\tImport settings from another froxlor installation. This should be done prior to running --apply or alternatively in the same command together.");
|
||||
self::println("\t\t\tExample: --import-settings=/path/to/Froxlor_settings-[version]-[dbversion]-[date].json or --import-settings=http://domain.tld/Froxlor_settings-[version]-[dbversion]-[date].json");
|
||||
self::println("");
|
||||
self::println("--froxlor-dir\t\tpath to froxlor installation");
|
||||
self::println("\t\t\tExample: --froxlor-dir=/var/www/froxlor/");
|
||||
self::println("");
|
||||
self::println("--help\t\t\tshow help screen (this)");
|
||||
self::println("");
|
||||
// switches
|
||||
// self::println("-d\t\t\tenable debug output");
|
||||
self::println("-h\t\t\tsame as --help");
|
||||
self::println("");
|
||||
|
||||
die(); // end of execution
|
||||
}
|
||||
}
|
||||
|
||||
class Action
|
||||
{
|
||||
|
||||
private $_args = null;
|
||||
|
||||
private $_name = null;
|
||||
|
||||
private $_db = null;
|
||||
|
||||
public function __construct($args)
|
||||
{
|
||||
$this->_args = $args;
|
||||
$this->_validate();
|
||||
}
|
||||
|
||||
public function getActionName()
|
||||
{
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the parsed command line parameters
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private function _validate()
|
||||
{
|
||||
$this->_checkConfigParam(true);
|
||||
$this->_parseConfig();
|
||||
|
||||
require FROXLOR_INSTALL_DIR . '/lib/tables.inc.php';
|
||||
require FROXLOR_INSTALL_DIR . '/lib/functions.php';
|
||||
require FROXLOR_INSTALL_DIR . '/lib/classes/settings/class.Settings.php';
|
||||
require FROXLOR_INSTALL_DIR . '/lib/classes/settings/class.SImExporter.php';
|
||||
require FROXLOR_INSTALL_DIR . '/lib/classes/config/class.ConfigParser.php';
|
||||
require FROXLOR_INSTALL_DIR . '/lib/classes/config/class.ConfigService.php';
|
||||
require FROXLOR_INSTALL_DIR . '/lib/classes/config/class.ConfigDaemon.php';
|
||||
|
||||
if (array_key_exists("import-settings", $this->_args)) {
|
||||
$this->_importSettings();
|
||||
}
|
||||
|
||||
if (array_key_exists("create", $this->_args)) {
|
||||
$this->_createConfig();
|
||||
} elseif (array_key_exists("apply", $this->_args)) {
|
||||
$this->_applyConfig();
|
||||
} elseif (array_key_exists("list-daemons", $this->_args) || array_key_exists("daemon", $this->_args)) {
|
||||
CmdLineHandler::printwarn("--list-daemons and --daemon only work together with --apply");
|
||||
}
|
||||
}
|
||||
|
||||
private function _importSettings()
|
||||
{
|
||||
if (strtoupper(substr($this->_args["import-settings"], 0, 4)) == 'HTTP') {
|
||||
echo "Settings file seems to be an URL, trying to download" . PHP_EOL;
|
||||
$target = "/tmp/froxlor-import-settings-" . time() . ".json";
|
||||
if (@file_exists($target)) {
|
||||
@unlink($target);
|
||||
}
|
||||
$this->downloadFile($this->_args["import-settings"], $target);
|
||||
$this->_args["import-settings"] = $target;
|
||||
}
|
||||
if (! is_file($this->_args["import-settings"])) {
|
||||
throw new Exception("Given settings file is not a file");
|
||||
} elseif (! file_exists($this->_args["import-settings"])) {
|
||||
throw new Exception("Given settings file cannot be found ('" . $this->_args["import-settings"] . "')");
|
||||
} elseif (! is_readable($this->_args["import-settings"])) {
|
||||
throw new Exception("Given settings file cannot be read ('" . $this->_args["import-settings"] . "')");
|
||||
}
|
||||
$imp_content = file_get_contents($this->_args["import-settings"]);
|
||||
SImExporter::import($imp_content);
|
||||
CmdLineHandler::printsucc("Successfully imported settings from '" . $this->_args["import-settings"] . "'");
|
||||
}
|
||||
|
||||
private function _createConfig()
|
||||
{
|
||||
$_daemons_config = array(
|
||||
'distro' => ""
|
||||
);
|
||||
|
||||
$config_dir = FROXLOR_INSTALL_DIR . '/lib/configfiles/';
|
||||
// show list of available distro's
|
||||
$distros = glob($config_dir . '*.xml');
|
||||
// tmp array
|
||||
$distributions_select_data = array();
|
||||
// read in all the distros
|
||||
foreach ($distros as $_distribution) {
|
||||
// get configparser object
|
||||
$dist = new ConfigParser($_distribution);
|
||||
// get distro-info
|
||||
$dist_display = $this->getCompleteDistroName($dist);
|
||||
// store in tmp array
|
||||
$distributions_select_data[$dist_display] = str_replace(".xml", "", strtolower(basename($_distribution)));
|
||||
}
|
||||
|
||||
// sort by distribution name
|
||||
ksort($distributions_select_data);
|
||||
|
||||
// list all distributions
|
||||
$mask = "|%-50.50s |%-50.50s |\n";
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
printf($mask, 'dist', 'name');
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
foreach ($distributions_select_data as $name => $filename) {
|
||||
printf($mask, $filename, $name);
|
||||
}
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
echo PHP_EOL;
|
||||
|
||||
while (! in_array($_daemons_config['distro'], $distributions_select_data)) {
|
||||
$_daemons_config['distro'] = CmdLineHandler::getInput("choose distribution", "stretch");
|
||||
}
|
||||
|
||||
// go through all services and let user check whether to include it or not
|
||||
$configfiles = new ConfigParser($config_dir . '/' . $_daemons_config['distro'] . ".xml");
|
||||
$services = $configfiles->getServices();
|
||||
|
||||
foreach ($services as $si => $service) {
|
||||
echo PHP_EOL . "--- " . strtoupper($si) . " ---" . PHP_EOL . PHP_EOL;
|
||||
$_daemons_config[$si] = "";
|
||||
|
||||
$daemons = $service->getDaemons();
|
||||
$mask = "|%-50.50s |%-50.50s |\n";
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
printf($mask, 'value', 'name');
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
$default_daemon = "";
|
||||
foreach ($daemons as $di => $dd) {
|
||||
$title = $dd->title;
|
||||
if ($dd->default) {
|
||||
$default_daemon = $di;
|
||||
$title = $title . " (default)";
|
||||
}
|
||||
printf($mask, $di, $title);
|
||||
}
|
||||
printf($mask, "x", "No " . $si);
|
||||
$daemons['x'] = 'x';
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
echo PHP_EOL;
|
||||
if ($si == 'system') {
|
||||
$_daemons_config[$si] = array();
|
||||
// for the system/other services we need a multiple choice possibility
|
||||
CmdLineHandler::println("Select every service you need. Enter empty value when done");
|
||||
$sysservice = "";
|
||||
do {
|
||||
$sysservice = CmdLineHandler::getInput("choose service");
|
||||
if (! empty($sysservice)) {
|
||||
$_daemons_config[$si][] = $sysservice;
|
||||
}
|
||||
} while (! empty($sysservice));
|
||||
// add 'cron' as fixed part (doesn't hurt if it exists)
|
||||
if (! in_array('cron', $_daemons_config[$si])) {
|
||||
$_daemons_config[$si][] = 'cron';
|
||||
}
|
||||
} else {
|
||||
// for all others -> only one value
|
||||
while (! array_key_exists($_daemons_config[$si], $daemons)) {
|
||||
$_daemons_config[$si] = CmdLineHandler::getInput("choose service", $default_daemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo PHP_EOL . PHP_EOL;
|
||||
$daemons_config = json_encode($_daemons_config);
|
||||
$output = CmdLineHandler::getInput("choose output-filename", "/tmp/froxlor-config-" . date('Ymd') . ".json");
|
||||
file_put_contents($output, $daemons_config);
|
||||
CmdLineHandler::printsucc("Successfully generated service-configfile '" . $output . "'");
|
||||
echo PHP_EOL;
|
||||
CmdLineHandler::printsucc("You can now apply this config running:" . PHP_EOL . "php " . __FILE__ . " --froxlor-dir=" . dirname(dirname(__DIR__)) . " --apply=" . $output);
|
||||
echo PHP_EOL;
|
||||
$proceed = CmdLineHandler::getYesNo("Do you want to apply the config now? [y/N]", 0);
|
||||
if ($proceed) {
|
||||
passthru("php " . __FILE__ . " --froxlor-dir=" . dirname(dirname(__DIR__)) . " --apply=" . $output);
|
||||
}
|
||||
}
|
||||
|
||||
private function getCompleteDistroName($cparser)
|
||||
{
|
||||
// get distro-info
|
||||
$dist_display = $cparser->distributionName;
|
||||
if ($cparser->distributionCodename != '') {
|
||||
$dist_display .= " " . $cparser->distributionCodename;
|
||||
}
|
||||
if ($cparser->distributionVersion != '') {
|
||||
$dist_display .= " (" . $cparser->distributionVersion . ")";
|
||||
}
|
||||
if ($cparser->deprecated) {
|
||||
$dist_display .= " [deprecated]";
|
||||
}
|
||||
return $dist_display;
|
||||
}
|
||||
|
||||
private function _applyConfig()
|
||||
{
|
||||
if (strtoupper(substr($this->_args["apply"], 0, 4)) == 'HTTP') {
|
||||
echo "Config file seems to be an URL, trying to download" . PHP_EOL;
|
||||
$target = "/tmp/froxlor-config-" . time() . ".json";
|
||||
if (@file_exists($target)) {
|
||||
@unlink($target);
|
||||
}
|
||||
$this->downloadFile($this->_args["apply"], $target);
|
||||
$this->_args["apply"] = $target;
|
||||
}
|
||||
if (! is_file($this->_args["apply"])) {
|
||||
throw new Exception("Given config file is not a file");
|
||||
} elseif (! file_exists($this->_args["apply"])) {
|
||||
throw new Exception("Given config file cannot be found ('" . $this->_args["apply"] . "')");
|
||||
} elseif (! is_readable($this->_args["apply"])) {
|
||||
throw new Exception("Given config file cannot be read ('" . $this->_args["apply"] . "')");
|
||||
}
|
||||
|
||||
$config = file_get_contents($this->_args["apply"]);
|
||||
$decoded_config = json_decode($config, true);
|
||||
|
||||
if (array_key_exists("list-daemons", $this->_args)) {
|
||||
$mask = "|%-50.50s |%-50.50s |\n";
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
printf($mask, 'service', 'daemon');
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
foreach ($decoded_config as $service => $daemon) {
|
||||
if (is_array($daemon) && count($daemon) > 0) {
|
||||
foreach ($daemon as $sysdaemon) {
|
||||
printf($mask, $service, $sysdaemon);
|
||||
}
|
||||
} else {
|
||||
if ($daemon == 'x') {
|
||||
$daemon = '--- skipped ---';
|
||||
}
|
||||
printf($mask, $service, $daemon);
|
||||
}
|
||||
}
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
echo PHP_EOL;
|
||||
exit();
|
||||
}
|
||||
|
||||
$only_daemon = null;
|
||||
if (array_key_exists("daemon", $this->_args)) {
|
||||
$only_daemon = $this->_args['daemon'];
|
||||
}
|
||||
|
||||
if (! empty($decoded_config)) {
|
||||
$config_dir = FROXLOR_INSTALL_DIR . '/lib/configfiles/';
|
||||
$configfiles = new ConfigParser($config_dir . '/' . $decoded_config['distro'] . ".xml");
|
||||
$services = $configfiles->getServices();
|
||||
$replace_arr = $this->_getReplacerArray();
|
||||
|
||||
foreach ($services as $si => $service) {
|
||||
echo PHP_EOL . "--- Configuring: " . strtoupper($si) . " ---" . PHP_EOL . PHP_EOL;
|
||||
if (! isset($decoded_config[$si]) || $decoded_config[$si] == 'x') {
|
||||
CmdLineHandler::printwarn("Skipping " . strtoupper($si) . " configuration as desired");
|
||||
continue;
|
||||
}
|
||||
$daemons = $service->getDaemons();
|
||||
foreach ($daemons as $di => $dd) {
|
||||
// check for desired service
|
||||
if (($si != 'system' && $decoded_config[$si] != $di) || (is_array($decoded_config[$si]) && ! in_array($di, $decoded_config[$si]))) {
|
||||
continue;
|
||||
}
|
||||
CmdLineHandler::println("Configuring '" . $di . "'");
|
||||
|
||||
if (! empty($only_daemon) && $only_daemon != $di) {
|
||||
CmdLineHandler::printwarn("Skipping " . $di . " configuration as desired");
|
||||
continue;
|
||||
}
|
||||
// run all cmds
|
||||
$confarr = $dd->getConfig();
|
||||
foreach ($confarr as $action) {
|
||||
switch ($action['type']) {
|
||||
case "install":
|
||||
CmdLineHandler::println("Installing required packages");
|
||||
$result = null;
|
||||
passthru(strtr($action['content'], $replace_arr), $result);
|
||||
if (strlen($result) > 1) {
|
||||
echo $result;
|
||||
}
|
||||
break;
|
||||
case "command":
|
||||
exec(strtr($action['content'], $replace_arr));
|
||||
break;
|
||||
case "file":
|
||||
if (array_key_exists('content', $action)) {
|
||||
CmdLineHandler::printwarn("Creating file '" . $action['name'] . "'");
|
||||
file_put_contents($action['name'], trim(strtr($action['content'], $replace_arr)));
|
||||
} elseif (array_key_exists('subcommands', $action)) {
|
||||
foreach ($action['subcommands'] as $fileaction) {
|
||||
if (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "pre") {
|
||||
exec(strtr($fileaction['content'], $replace_arr));
|
||||
} elseif (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "post") {
|
||||
exec(strtr($fileaction['content'], $replace_arr));
|
||||
} elseif ($fileaction['type'] == 'file') {
|
||||
CmdLineHandler::printwarn("Creating file '" . $fileaction['name'] . "'");
|
||||
file_put_contents($fileaction['name'], trim(strtr($fileaction['content'], $replace_arr)));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// set is_configured flag
|
||||
Settings::Set('panel.is_configured', '1', true);
|
||||
// run cronjob at the end to ensure configs are all up to date
|
||||
exec('php ' . FROXLOR_INSTALL_DIR . '/scripts/froxlor_master_cronjob.php --force');
|
||||
// and done
|
||||
CmdLineHandler::printsucc("All services have been configured");
|
||||
} else {
|
||||
CmdLineHandler::printerr("Unable to decode given JSON file");
|
||||
}
|
||||
}
|
||||
|
||||
private function _getReplacerArray()
|
||||
{
|
||||
$customer_tmpdir = '/tmp/';
|
||||
if (Settings::Get('system.mod_fcgid') == '1' && Settings::Get('system.mod_fcgid_tmpdir') != '') {
|
||||
$customer_tmpdir = Settings::Get('system.mod_fcgid_tmpdir');
|
||||
} elseif (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.tmpdir') != '') {
|
||||
$customer_tmpdir = Settings::Get('phpfpm.tmpdir');
|
||||
}
|
||||
|
||||
// try to convert namserver hosts to ip's
|
||||
$ns_ips = "";
|
||||
if (Settings::Get('system.nameservers') != '') {
|
||||
$nameservers = explode(',', Settings::Get('system.nameservers'));
|
||||
foreach ($nameservers as $nameserver) {
|
||||
$nameserver = trim($nameserver);
|
||||
$nameserver_ips = gethostbynamel6($nameserver);
|
||||
if (is_array($nameserver_ips) && count($nameserver_ips) > 0) {
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Database::needSqlData();
|
||||
$sql = Database::getSqlData();
|
||||
|
||||
$replace_arr = array(
|
||||
'<SQL_UNPRIVILEGED_USER>' => $sql['user'],
|
||||
'<SQL_UNPRIVILEGED_PASSWORD>' => $sql['passwd'],
|
||||
'<SQL_DB>' => $sql['db'],
|
||||
'<SQL_HOST>' => $sql['host'],
|
||||
'<SQL_SOCKET>' => isset($sql['socket']) ? $sql['socket'] : null,
|
||||
'<SERVERNAME>' => Settings::Get('system.hostname'),
|
||||
'<SERVERIP>' => Settings::Get('system.ipaddress'),
|
||||
'<NAMESERVERS>' => Settings::Get('system.nameservers'),
|
||||
'<NAMESERVERS_IP>' => $ns_ips,
|
||||
'<AXFRSERVERS>' => Settings::Get('system.axfrservers'),
|
||||
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
|
||||
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
|
||||
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),
|
||||
'<SSLPROTOCOLS>' => (Settings::Get('system.use_ssl') == '1') ? 'imaps pop3s' : '',
|
||||
'<CUSTOMER_TMP>' => makeCorrectDir($customer_tmpdir),
|
||||
'<BASE_PATH>' => makeCorrectDir(FROXLOR_INSTALL_DIR),
|
||||
'<BIND_CONFIG_PATH>' => makeCorrectDir(Settings::Get('system.bindconf_directory')),
|
||||
'<WEBSERVER_RELOAD_CMD>' => Settings::Get('system.apachereload_command'),
|
||||
'<CUSTOMER_LOGS>' => makeCorrectDir(Settings::Get('system.logfiles_directory')),
|
||||
'<FPM_IPCDIR>' => makeCorrectDir(Settings::Get('phpfpm.fastcgi_ipcdir')),
|
||||
'<WEBSERVER_GROUP>' => Settings::Get('system.httpgroup')
|
||||
);
|
||||
return $replace_arr;
|
||||
}
|
||||
|
||||
private function _parseConfig()
|
||||
{
|
||||
define('FROXLOR_INSTALL_DIR', $this->_args['froxlor-dir']);
|
||||
if (! file_exists(FROXLOR_INSTALL_DIR . '/lib/classes/database/class.Database.php')) {
|
||||
throw new Exception("Could not find froxlor's Database class. Is froxlor really installed to '" . FROXLOR_INSTALL_DIR . "'?");
|
||||
}
|
||||
if (! file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
throw new Exception("Could not find froxlor's userdata.inc.php file. You should use this script only with a fully installed and setup froxlor system.");
|
||||
}
|
||||
require FROXLOR_INSTALL_DIR . '/lib/classes/database/class.Database.php';
|
||||
}
|
||||
|
||||
private function _checkConfigParam($needed = false)
|
||||
{
|
||||
if ($needed) {
|
||||
if (! isset($this->_args["froxlor-dir"])) {
|
||||
throw new Exception("No configuration given (missing --froxlor-dir parameter?)");
|
||||
} elseif (! is_dir($this->_args["froxlor-dir"])) {
|
||||
throw new Exception("Given --froxlor-dir parameter is not a directory");
|
||||
} elseif (! file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (! is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new Exception("Given froxlor direcotry cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function downloadFile($src, $dest)
|
||||
{
|
||||
set_time_limit(0);
|
||||
// This is the file where we save the information
|
||||
$fp = fopen($dest, 'w+');
|
||||
// Here is the file we are downloading, replace spaces with %20
|
||||
$ch = curl_init(str_replace(" ", "%20", $src));
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
// write curl response to file
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
// get curl response
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
require dirname(dirname(__DIR__)) . '/vendor/autoload.php';
|
||||
|
||||
// give control to command line handler
|
||||
try {
|
||||
ConfigServicesCmd::processParameters($argc, $argv);
|
||||
\Froxlor\Cli\ConfigServicesCmd::processParameters($argc, $argv);
|
||||
} catch (Exception $e) {
|
||||
ConfigServicesCmd::printerr($e->getMessage());
|
||||
\Froxlor\Cli\ConfigServicesCmd::printerr($e->getMessage());
|
||||
}
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the SysCP project.
|
||||
* Copyright (c) 2003-2007 the SysCP Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.syscp.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Martin Burchert <eremit@syscp.org>
|
||||
* @license GPLv2 http://files.syscp.org/misc/COPYING.txt
|
||||
* @package System
|
||||
*
|
||||
*/
|
||||
|
||||
// some configs
|
||||
$baseLanguage = 'english.lng.php';
|
||||
|
||||
// Check if we're in the CLI
|
||||
if(@php_sapi_name() !== 'cli') {
|
||||
die('This script will only work in the shell.');
|
||||
}
|
||||
|
||||
// Check argument count
|
||||
/*
|
||||
if (sizeof($argv) != 2) {
|
||||
print_help($argv);
|
||||
exit;
|
||||
}
|
||||
*/
|
||||
|
||||
// Load the contents of the given path
|
||||
$path = $argv[1];
|
||||
$_f = isset($argv[2]) ? $argv[2] : null;
|
||||
$files = array();
|
||||
|
||||
if ($dh = opendir($path)) {
|
||||
while (false !== ($file = readdir($dh))) {
|
||||
if ($file != "."
|
||||
&& $file != ".."
|
||||
&& !is_dir($file)
|
||||
&& preg_match('/(.+)\.lng\.php/i', $file)
|
||||
) {
|
||||
if (is_null($_f) || (!is_null($_f) && ($file == $_f || $file == $baseLanguage))) {
|
||||
$files[$file] = str_replace('//', '/', $path . '/' . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir($dh);
|
||||
} else {
|
||||
print "ERROR: The path you requested cannot be read! \n ";
|
||||
print "\n";
|
||||
print_help($argv);
|
||||
exit;
|
||||
}
|
||||
|
||||
// check if there is the default language defined
|
||||
if (!isset($files[$baseLanguage])) {
|
||||
print "ERROR: The baselanguage cannot be found! \n";
|
||||
print "\n";
|
||||
print_help($argv);
|
||||
exit;
|
||||
}
|
||||
|
||||
// import the baselanguage
|
||||
$base = import($files[$baseLanguage]);
|
||||
|
||||
// and unset it in the files, because we don't need to compare base to base
|
||||
unset($files[$baseLanguage]);
|
||||
|
||||
// compare each language with the baselanguage
|
||||
foreach ($files as $key => $file) {
|
||||
$comp = import($file);
|
||||
|
||||
print "\n\nComparing " . $baseLanguage . " to " . $key . "\n";
|
||||
$result = compare($base, $comp);
|
||||
|
||||
if (is_array($result)
|
||||
&& sizeof($result) > 0
|
||||
) {
|
||||
print " found missing strings: \n";
|
||||
foreach ($result as $value) {
|
||||
print " " . $value . "\n";
|
||||
}
|
||||
} else {
|
||||
print " no missing strings found! \n ";
|
||||
}
|
||||
|
||||
print "\nReverse Checking " . $key . " to " . $baseLanguage . "\n";
|
||||
$result = compare($comp, $base);
|
||||
|
||||
if (is_array($result)
|
||||
&& sizeof($result) > 0
|
||||
) {
|
||||
print " found strings not in basefile: \n";
|
||||
foreach ($result as $key => $value) {
|
||||
print " " . $value . "\n";
|
||||
}
|
||||
} else {
|
||||
print " There are no strings which are not in the basefile! \n ";
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// FUNCTIONS
|
||||
//-----------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* prints the help screen
|
||||
*
|
||||
* @param array $argv
|
||||
*/
|
||||
function print_help($argv) {
|
||||
print "Usage: php " . $argv[0] . " /PATH/TO/LNG \n";
|
||||
print " \n ";
|
||||
}
|
||||
|
||||
function import($file) {
|
||||
|
||||
$input = file($file);
|
||||
$return = array();
|
||||
|
||||
foreach ($input as $key => $value) {
|
||||
|
||||
if (!preg_match('/^\$/', $value)) {
|
||||
unset($input[$key]);
|
||||
} else {
|
||||
// generate the key
|
||||
$key = preg_replace('/^\$lng\[\'(.*)=(.*)$/U', '\\1', $value);
|
||||
$key = str_replace('[\'', '/', $key);
|
||||
$key = trim(str_replace('\']', '', $key));
|
||||
|
||||
//generate the value
|
||||
$value = trim($value);
|
||||
|
||||
// set the result
|
||||
$return[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
function compare($array1, $array2) {
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach ($array1 as $key => $value) {
|
||||
|
||||
if (!isset($array2[$key])) {
|
||||
$result[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@@ -21,253 +21,11 @@ if (@php_sapi_name() !== 'cli') {
|
||||
die('This script will only work in the shell.');
|
||||
}
|
||||
|
||||
require dirname(dirname(__DIR__)) . '/lib/classes/output/class.CmdLineHandler.php';
|
||||
|
||||
class SwitchServerIp extends CmdLineHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* list of valid switches
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $switches = array(
|
||||
'h'
|
||||
);
|
||||
|
||||
/**
|
||||
* list of valid parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $params = array(
|
||||
'switch',
|
||||
'list',
|
||||
'froxlor-dir',
|
||||
'help'
|
||||
);
|
||||
|
||||
public static $action_class = 'Action';
|
||||
|
||||
public static function printHelp()
|
||||
{
|
||||
self::println("");
|
||||
self::println("Help / command line parameters:");
|
||||
self::println("");
|
||||
// commands
|
||||
self::println("--switch\t\tlets you switch ip-address A with ip-address B");
|
||||
self::println("\t\t\tExample: --switch=A,B");
|
||||
self::println("\t\t\tExample: --switch=\"A1,B1 A2,B2 A3,B3 ...\"");
|
||||
self::println("");
|
||||
self::println("--list\t\t\tshow all currently used ip-addresses in froxlor");
|
||||
self::println("");
|
||||
self::println("--froxlor-dir\t\tpath to froxlor installation");
|
||||
self::println("\t\t\tExample: --froxlor-dir=/var/www/froxlor/");
|
||||
self::println("");
|
||||
self::println("--help\t\t\tshow help screen (this)");
|
||||
self::println("");
|
||||
// switches
|
||||
// self::println("-d\t\t\tenable debug output");
|
||||
self::println("-h\t\t\tsame as --help");
|
||||
self::println("");
|
||||
|
||||
die(); // end of execution
|
||||
}
|
||||
}
|
||||
|
||||
class Action
|
||||
{
|
||||
|
||||
private $_args = null;
|
||||
|
||||
private $_name = null;
|
||||
|
||||
private $_db = null;
|
||||
|
||||
public function __construct($args)
|
||||
{
|
||||
$this->_args = $args;
|
||||
$this->_validate();
|
||||
}
|
||||
|
||||
public function getActionName()
|
||||
{
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the parsed command line parameters
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private function _validate()
|
||||
{
|
||||
$need_config = false;
|
||||
if (array_key_exists("list", $this->_args) || array_key_exists("switch", $this->_args)) {
|
||||
$need_config = true;
|
||||
}
|
||||
|
||||
$this->_checkConfigParam($need_config);
|
||||
|
||||
$this->_parseConfig();
|
||||
|
||||
if (array_key_exists("list", $this->_args)) {
|
||||
$this->_listIPs();
|
||||
}
|
||||
if (array_key_exists("switch", $this->_args)) {
|
||||
$this->_switchIPs();
|
||||
}
|
||||
}
|
||||
|
||||
private function _listIPs()
|
||||
{
|
||||
$sel_stmt = Database::prepare("SELECT * FROM panel_ipsandports ORDER BY ip ASC, port ASC");
|
||||
Database::pexecute($sel_stmt);
|
||||
$ips = $sel_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$mask = "|%-10.10s |%-50.50s | %10.10s |\n";
|
||||
printf($mask, str_repeat("-", 10), str_repeat("-", 50), str_repeat("-", 10));
|
||||
printf($mask, 'id', 'IP address', 'port');
|
||||
printf($mask, str_repeat("-", 10), str_repeat("-", 50), str_repeat("-", 10));
|
||||
foreach ($ips as $ipdata) {
|
||||
printf($mask, $ipdata['id'], $ipdata['ip'], $ipdata['port']);
|
||||
}
|
||||
printf($mask, str_repeat("-", 10), str_repeat("-", 50), str_repeat("-", 10));
|
||||
echo PHP_EOL . PHP_EOL;
|
||||
}
|
||||
|
||||
private function _switchIPs()
|
||||
{
|
||||
$ip_list = $this->_args['switch'];
|
||||
|
||||
if (empty($ip_list) || is_bool($ip_list)) {
|
||||
throw new Exception("No paramters given for --switch action.");
|
||||
}
|
||||
|
||||
$ips_to_switch = array();
|
||||
$ip_list = explode(" ", $ip_list);
|
||||
foreach ($ip_list as $ips_combo) {
|
||||
$ip_pair = explode(",", $ips_combo);
|
||||
if (count($ip_pair) != 2) {
|
||||
throw new Exception("Invalid parameter given for --switch");
|
||||
} else {
|
||||
if (filter_var($ip_pair[0], FILTER_VALIDATE_IP) == false) {
|
||||
throw new Exception("Invalid source ip address: " . $ip_pair[0]);
|
||||
}
|
||||
if (filter_var($ip_pair[1], FILTER_VALIDATE_IP) == false) {
|
||||
throw new Exception("Invalid target ip address: " . $ip_pair[1]);
|
||||
}
|
||||
if ($ip_pair[0] == $ip_pair[1]) {
|
||||
throw new Exception("Source and target ip address are equal");
|
||||
}
|
||||
}
|
||||
$ips_to_switch[] = $ip_pair;
|
||||
}
|
||||
|
||||
if (count($ips_to_switch) > 0) {
|
||||
$check_stmt = Database::prepare("SELECT `id` FROM panel_ipsandports WHERE `ip` = :newip");
|
||||
$upd_stmt = Database::prepare("UPDATE panel_ipsandports SET `ip` = :newip WHERE `ip` = :oldip");
|
||||
|
||||
// system.ipaddress
|
||||
$check_sysip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'ipaddress'");
|
||||
$check_sysip = Database::pexecute_first($check_sysip_stmt);
|
||||
|
||||
// system.mysql_access_host
|
||||
$check_mysqlip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'mysql_access_host'");
|
||||
$check_mysqlip = Database::pexecute_first($check_mysqlip_stmt);
|
||||
|
||||
// system.axfrservers
|
||||
$check_axfrip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'axfrservers'");
|
||||
$check_axfrip = Database::pexecute_first($check_axfrip_stmt);
|
||||
|
||||
foreach ($ips_to_switch as $ip_pair) {
|
||||
echo "Switching IP \033[1m" . $ip_pair[0] . "\033[0m to IP \033[1m" . $ip_pair[1] . "\033[0m" . PHP_EOL;
|
||||
|
||||
$ip_check = Database::pexecute_first($check_stmt, array('newip' => $ip_pair[1]));
|
||||
if ($ip_check) {
|
||||
CmdLineHandler::printwarn("Note: " . $ip_pair[0] . " not updated to " . $ip_pair[1] . " - IP already exists in froxlor's database");
|
||||
continue;
|
||||
}
|
||||
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'newip' => $ip_pair[1],
|
||||
'oldip' => $ip_pair[0]
|
||||
));
|
||||
$rows_updated = $upd_stmt->rowCount();
|
||||
|
||||
if ($rows_updated == 0) {
|
||||
CmdLineHandler::printwarn("Note: " . $ip_pair[0] . " not updated to " . $ip_pair[1] . " (possibly no entry found in froxlor database. Use --list to see what IP addresses are added in froxlor");
|
||||
}
|
||||
|
||||
// check whether the system.ipaddress needs updating
|
||||
if ($check_sysip['value'] == $ip_pair[0]) {
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newip WHERE `settinggroup` = 'system' and `varname` = 'ipaddress'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newip' => $ip_pair[1]
|
||||
));
|
||||
CmdLineHandler::printsucc("Updated system-ipaddress from '" . $ip_pair[0] . "' to '" . $ip_pair[1] . "'");
|
||||
}
|
||||
|
||||
// check whether the system.mysql_access_host needs updating
|
||||
if (strstr($check_mysqlip['value'], $ip_pair[0]) !== false) {
|
||||
$new_mysqlip = str_replace($ip_pair[0], $ip_pair[1], $check_mysqlip['value']);
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newmysql WHERE `settinggroup` = 'system' and `varname` = 'mysql_access_host'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newmysql' => $new_mysqlip
|
||||
));
|
||||
CmdLineHandler::printsucc("Updated mysql_access_host from '" . $check_mysqlip['value'] . "' to '" . $new_mysqlip . "'");
|
||||
}
|
||||
|
||||
// check whether the system.axfrservers needs updating
|
||||
if (strstr($check_axfrip['value'], $ip_pair[0]) !== false) {
|
||||
$new_axfrip = str_replace($ip_pair[0], $ip_pair[1], $check_axfrip['value']);
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newaxfr WHERE `settinggroup` = 'system' and `varname` = 'axfrservers'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newaxfr' => $new_axfrip
|
||||
));
|
||||
CmdLineHandler::printsucc("Updated axfrservers from '" . $check_axfrip['value'] . "' to '" . $new_axfrip . "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
||||
CmdLineHandler::printwarn("*** ATTENTION *** Remember to replace IP addresses in configuration files if used anywhere.");
|
||||
CmdLineHandler::printsucc("IP addresses updated");
|
||||
}
|
||||
|
||||
private function _parseConfig()
|
||||
{
|
||||
define('FROXLOR_INSTALL_DIR', $this->_args['froxlor-dir']);
|
||||
if (! file_exists(FROXLOR_INSTALL_DIR . '/lib/classes/database/class.Database.php')) {
|
||||
throw new Exception("Could not find froxlor's Database class. Is froxlor really installed to '" . FROXLOR_INSTALL_DIR . "'?");
|
||||
}
|
||||
if (! file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
throw new Exception("Could not find froxlor's userdata.inc.php file. You should use this script only with a fully installed and setup froxlor system.");
|
||||
}
|
||||
require FROXLOR_INSTALL_DIR . '/lib/functions/filedir/function.makeSecurePath.php';
|
||||
require FROXLOR_INSTALL_DIR . '/lib/functions/filedir/function.makeCorrectDir.php';
|
||||
require FROXLOR_INSTALL_DIR . '/lib/functions/filedir/function.makeCorrectFile.php';
|
||||
require FROXLOR_INSTALL_DIR . '/lib/classes/database/class.Database.php';
|
||||
}
|
||||
|
||||
private function _checkConfigParam($needed = false)
|
||||
{
|
||||
if ($needed) {
|
||||
if (! isset($this->_args["froxlor-dir"])) {
|
||||
throw new Exception("No configuration given (missing --froxlor-dir parameter?)");
|
||||
} elseif (! is_dir($this->_args["froxlor-dir"])) {
|
||||
throw new Exception("Given --froxlor-dir parameter is not a directory");
|
||||
} elseif (! file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (! is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new Exception("Given froxlor direcotry cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
require dirname(dirname(__DIR__)) . '/vendor/autoload.php';
|
||||
|
||||
// give control to command line handler
|
||||
try {
|
||||
SwitchServerIp::processParameters($argc, $argv);
|
||||
\Froxlor\Cli\SwitchServerIpCmd::processParameters($argc, $argv);
|
||||
} catch (Exception $e) {
|
||||
SwitchServerIp::printerr($e->getMessage());
|
||||
\Froxlor\Cli\SwitchServerIpCmd::printerr($e->getMessage());
|
||||
}
|
||||
|
||||
18
lib/Froxlor/Cli/Action.php
Normal file
18
lib/Froxlor/Cli/Action.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
abstract class Action
|
||||
{
|
||||
|
||||
protected function __construct($args)
|
||||
{
|
||||
$this->_args = $args;
|
||||
}
|
||||
|
||||
public function getActionName()
|
||||
{
|
||||
return get_called_class();
|
||||
}
|
||||
|
||||
abstract public function run();
|
||||
}
|
||||
403
lib/Froxlor/Cli/Action/ConfigServicesAction.php
Normal file
403
lib/Froxlor/Cli/Action/ConfigServicesAction.php
Normal file
@@ -0,0 +1,403 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli\Action;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\SImExporter;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cli\ConfigServicesCmd;
|
||||
|
||||
class ConfigServicesAction extends \Froxlor\Cli\Action
|
||||
{
|
||||
|
||||
public function __construct($args)
|
||||
{
|
||||
parent::__construct($args);
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->_validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the parsed command line parameters
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function _validate()
|
||||
{
|
||||
$this->_checkConfigParam(true);
|
||||
$this->_parseConfig();
|
||||
|
||||
require FROXLOR_INSTALL_DIR . '/lib/tables.inc.php';
|
||||
require FROXLOR_INSTALL_DIR . '/lib/functions.php';
|
||||
|
||||
if (array_key_exists("import-settings", $this->_args)) {
|
||||
$this->_importSettings();
|
||||
}
|
||||
|
||||
if (array_key_exists("create", $this->_args)) {
|
||||
$this->_createConfig();
|
||||
} elseif (array_key_exists("apply", $this->_args)) {
|
||||
$this->_applyConfig();
|
||||
} elseif (array_key_exists("list-daemons", $this->_args) || array_key_exists("daemon", $this->_args)) {
|
||||
ConfigServicesCmd::printwarn("--list-daemons and --daemon only work together with --apply");
|
||||
}
|
||||
}
|
||||
|
||||
private function _importSettings()
|
||||
{
|
||||
if (strtoupper(substr($this->_args["import-settings"], 0, 4)) == 'HTTP') {
|
||||
echo "Settings file seems to be an URL, trying to download" . PHP_EOL;
|
||||
$target = "/tmp/froxlor-import-settings-" . time() . ".json";
|
||||
if (@file_exists($target)) {
|
||||
@unlink($target);
|
||||
}
|
||||
$this->downloadFile($this->_args["import-settings"], $target);
|
||||
$this->_args["import-settings"] = $target;
|
||||
}
|
||||
if (! is_file($this->_args["import-settings"])) {
|
||||
throw new \Exception("Given settings file is not a file");
|
||||
} elseif (! file_exists($this->_args["import-settings"])) {
|
||||
throw new \Exception("Given settings file cannot be found ('" . $this->_args["import-settings"] . "')");
|
||||
} elseif (! is_readable($this->_args["import-settings"])) {
|
||||
throw new \Exception("Given settings file cannot be read ('" . $this->_args["import-settings"] . "')");
|
||||
}
|
||||
$imp_content = file_get_contents($this->_args["import-settings"]);
|
||||
SImExporter::import($imp_content);
|
||||
ConfigServicesCmd::printsucc("Successfully imported settings from '" . $this->_args["import-settings"] . "'");
|
||||
}
|
||||
|
||||
private function _createConfig()
|
||||
{
|
||||
$_daemons_config = array(
|
||||
'distro' => ""
|
||||
);
|
||||
|
||||
$config_dir = FROXLOR_INSTALL_DIR . '/lib/configfiles/';
|
||||
// show list of available distro's
|
||||
$distros = glob($config_dir . '*.xml');
|
||||
// tmp array
|
||||
$distributions_select_data = array();
|
||||
// read in all the distros
|
||||
foreach ($distros as $_distribution) {
|
||||
// get configparser object
|
||||
$dist = new \Froxlor\Config\ConfigParser($_distribution);
|
||||
// get distro-info
|
||||
$dist_display = $this->getCompleteDistroName($dist);
|
||||
// store in tmp array
|
||||
$distributions_select_data[$dist_display] = str_replace(".xml", "", strtolower(basename($_distribution)));
|
||||
}
|
||||
|
||||
// sort by distribution name
|
||||
ksort($distributions_select_data);
|
||||
|
||||
// list all distributions
|
||||
$mask = "|%-50.50s |%-50.50s |\n";
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
printf($mask, 'dist', 'name');
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
foreach ($distributions_select_data as $name => $filename) {
|
||||
printf($mask, $filename, $name);
|
||||
}
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
echo PHP_EOL;
|
||||
|
||||
while (! in_array($_daemons_config['distro'], $distributions_select_data)) {
|
||||
$_daemons_config['distro'] = ConfigServicesCmd::getInput("choose distribution", "stretch");
|
||||
}
|
||||
|
||||
// go through all services and let user check whether to include it or not
|
||||
$configfiles = new \Froxlor\Config\ConfigParser($config_dir . '/' . $_daemons_config['distro'] . ".xml");
|
||||
$services = $configfiles->getServices();
|
||||
|
||||
foreach ($services as $si => $service) {
|
||||
echo PHP_EOL . "--- " . strtoupper($si) . " ---" . PHP_EOL . PHP_EOL;
|
||||
$_daemons_config[$si] = "";
|
||||
|
||||
$daemons = $service->getDaemons();
|
||||
$mask = "|%-50.50s |%-50.50s |\n";
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
printf($mask, 'value', 'name');
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
$default_daemon = "";
|
||||
foreach ($daemons as $di => $dd) {
|
||||
$title = $dd->title;
|
||||
if ($dd->default) {
|
||||
$default_daemon = $di;
|
||||
$title = $title . " (default)";
|
||||
}
|
||||
printf($mask, $di, $title);
|
||||
}
|
||||
printf($mask, "x", "No " . $si);
|
||||
$daemons['x'] = 'x';
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
echo PHP_EOL;
|
||||
if ($si == 'system') {
|
||||
$_daemons_config[$si] = array();
|
||||
// for the system/other services we need a multiple choice possibility
|
||||
ConfigServicesCmd::println("Select every service you need. Enter empty value when done");
|
||||
$sysservice = "";
|
||||
do {
|
||||
$sysservice = ConfigServicesCmd::getInput("choose service");
|
||||
if (! empty($sysservice)) {
|
||||
$_daemons_config[$si][] = $sysservice;
|
||||
}
|
||||
} while (! empty($sysservice));
|
||||
// add 'cron' as fixed part (doesn't hurt if it exists)
|
||||
if (! in_array('cron', $_daemons_config[$si])) {
|
||||
$_daemons_config[$si][] = 'cron';
|
||||
}
|
||||
} else {
|
||||
// for all others -> only one value
|
||||
while (! array_key_exists($_daemons_config[$si], $daemons)) {
|
||||
$_daemons_config[$si] = ConfigServicesCmd::getInput("choose service", $default_daemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo PHP_EOL . PHP_EOL;
|
||||
$daemons_config = json_encode($_daemons_config);
|
||||
$output = ConfigServicesCmd::getInput("choose output-filename", "/tmp/froxlor-config-" . date('Ymd') . ".json");
|
||||
file_put_contents($output, $daemons_config);
|
||||
ConfigServicesCmd::printsucc("Successfully generated service-configfile '" . $output . "'");
|
||||
echo PHP_EOL;
|
||||
ConfigServicesCmd::printsucc("You can now apply this config running:" . PHP_EOL . "php " . __FILE__ . " --froxlor-dir=" . dirname(dirname(__DIR__)) . " --apply=" . $output);
|
||||
echo PHP_EOL;
|
||||
$proceed = ConfigServicesCmd::getYesNo("Do you want to apply the config now? [y/N]", 0);
|
||||
if ($proceed) {
|
||||
passthru("php " . __FILE__ . " --froxlor-dir=" . dirname(dirname(__DIR__)) . " --apply=" . $output);
|
||||
}
|
||||
}
|
||||
|
||||
private function getCompleteDistroName($cparser)
|
||||
{
|
||||
// get distro-info
|
||||
$dist_display = $cparser->distributionName;
|
||||
if ($cparser->distributionCodename != '') {
|
||||
$dist_display .= " " . $cparser->distributionCodename;
|
||||
}
|
||||
if ($cparser->distributionVersion != '') {
|
||||
$dist_display .= " (" . $cparser->distributionVersion . ")";
|
||||
}
|
||||
if ($cparser->deprecated) {
|
||||
$dist_display .= " [deprecated]";
|
||||
}
|
||||
return $dist_display;
|
||||
}
|
||||
|
||||
private function _applyConfig()
|
||||
{
|
||||
if (strtoupper(substr($this->_args["apply"], 0, 4)) == 'HTTP') {
|
||||
echo "Config file seems to be an URL, trying to download" . PHP_EOL;
|
||||
$target = "/tmp/froxlor-config-" . time() . ".json";
|
||||
if (@file_exists($target)) {
|
||||
@unlink($target);
|
||||
}
|
||||
$this->downloadFile($this->_args["apply"], $target);
|
||||
$this->_args["apply"] = $target;
|
||||
}
|
||||
if (! is_file($this->_args["apply"])) {
|
||||
throw new \Exception("Given config file is not a file");
|
||||
} elseif (! file_exists($this->_args["apply"])) {
|
||||
throw new \Exception("Given config file cannot be found ('" . $this->_args["apply"] . "')");
|
||||
} elseif (! is_readable($this->_args["apply"])) {
|
||||
throw new \Exception("Given config file cannot be read ('" . $this->_args["apply"] . "')");
|
||||
}
|
||||
|
||||
$config = file_get_contents($this->_args["apply"]);
|
||||
$decoded_config = json_decode($config, true);
|
||||
|
||||
if (array_key_exists("list-daemons", $this->_args)) {
|
||||
$mask = "|%-50.50s |%-50.50s |\n";
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
printf($mask, 'service', 'daemon');
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
foreach ($decoded_config as $service => $daemon) {
|
||||
if (is_array($daemon) && count($daemon) > 0) {
|
||||
foreach ($daemon as $sysdaemon) {
|
||||
printf($mask, $service, $sysdaemon);
|
||||
}
|
||||
} else {
|
||||
if ($daemon == 'x') {
|
||||
$daemon = '--- skipped ---';
|
||||
}
|
||||
printf($mask, $service, $daemon);
|
||||
}
|
||||
}
|
||||
printf($mask, str_repeat("-", 50), str_repeat("-", 50));
|
||||
echo PHP_EOL;
|
||||
exit();
|
||||
}
|
||||
|
||||
$only_daemon = null;
|
||||
if (array_key_exists("daemon", $this->_args)) {
|
||||
$only_daemon = $this->_args['daemon'];
|
||||
}
|
||||
|
||||
if (! empty($decoded_config)) {
|
||||
$config_dir = FROXLOR_INSTALL_DIR . '/lib/configfiles/';
|
||||
$configfiles = new \Froxlor\Config\ConfigParser($config_dir . '/' . $decoded_config['distro'] . ".xml");
|
||||
$services = $configfiles->getServices();
|
||||
$replace_arr = $this->_getReplacerArray();
|
||||
|
||||
foreach ($services as $si => $service) {
|
||||
echo PHP_EOL . "--- Configuring: " . strtoupper($si) . " ---" . PHP_EOL . PHP_EOL;
|
||||
if (! isset($decoded_config[$si]) || $decoded_config[$si] == 'x') {
|
||||
ConfigServicesCmd::printwarn("Skipping " . strtoupper($si) . " configuration as desired");
|
||||
continue;
|
||||
}
|
||||
$daemons = $service->getDaemons();
|
||||
foreach ($daemons as $di => $dd) {
|
||||
// check for desired service
|
||||
if (($si != 'system' && $decoded_config[$si] != $di) || (is_array($decoded_config[$si]) && ! in_array($di, $decoded_config[$si]))) {
|
||||
continue;
|
||||
}
|
||||
ConfigServicesCmd::println("Configuring '" . $di . "'");
|
||||
|
||||
if (! empty($only_daemon) && $only_daemon != $di) {
|
||||
ConfigServicesCmd::printwarn("Skipping " . $di . " configuration as desired");
|
||||
continue;
|
||||
}
|
||||
// run all cmds
|
||||
$confarr = $dd->getConfig();
|
||||
foreach ($confarr as $action) {
|
||||
switch ($action['type']) {
|
||||
case "install":
|
||||
ConfigServicesCmd::println("Installing required packages");
|
||||
$result = null;
|
||||
passthru(strtr($action['content'], $replace_arr), $result);
|
||||
if (strlen($result) > 1) {
|
||||
echo $result;
|
||||
}
|
||||
break;
|
||||
case "command":
|
||||
exec(strtr($action['content'], $replace_arr));
|
||||
break;
|
||||
case "file":
|
||||
if (array_key_exists('content', $action)) {
|
||||
ConfigServicesCmd::printwarn("Creating file '" . $action['name'] . "'");
|
||||
file_put_contents($action['name'], trim(strtr($action['content'], $replace_arr)));
|
||||
} elseif (array_key_exists('subcommands', $action)) {
|
||||
foreach ($action['subcommands'] as $fileaction) {
|
||||
if (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "pre") {
|
||||
exec(strtr($fileaction['content'], $replace_arr));
|
||||
} elseif (array_key_exists('execute', $fileaction) && $fileaction['execute'] == "post") {
|
||||
exec(strtr($fileaction['content'], $replace_arr));
|
||||
} elseif ($fileaction['type'] == 'file') {
|
||||
ConfigServicesCmd::printwarn("Creating file '" . $fileaction['name'] . "'");
|
||||
file_put_contents($fileaction['name'], trim(strtr($fileaction['content'], $replace_arr)));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// set is_configured flag
|
||||
Settings::Set('panel.is_configured', '1', true);
|
||||
// run cronjob at the end to ensure configs are all up to date
|
||||
exec('php ' . FROXLOR_INSTALL_DIR . '/scripts/froxlor_master_cronjob.php --force');
|
||||
// and done
|
||||
ConfigServicesCmd::printsucc("All services have been configured");
|
||||
} else {
|
||||
ConfigServicesCmd::printerr("Unable to decode given JSON file");
|
||||
}
|
||||
}
|
||||
|
||||
private function _getReplacerArray()
|
||||
{
|
||||
$customer_tmpdir = '/tmp/';
|
||||
if (Settings::Get('system.mod_fcgid') == '1' && Settings::Get('system.mod_fcgid_tmpdir') != '') {
|
||||
$customer_tmpdir = Settings::Get('system.mod_fcgid_tmpdir');
|
||||
} elseif (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.tmpdir') != '') {
|
||||
$customer_tmpdir = Settings::Get('phpfpm.tmpdir');
|
||||
}
|
||||
|
||||
// try to convert namserver hosts to ip's
|
||||
$ns_ips = "";
|
||||
if (Settings::Get('system.nameservers') != '') {
|
||||
$nameservers = explode(',', Settings::Get('system.nameservers'));
|
||||
foreach ($nameservers as $nameserver) {
|
||||
$nameserver = trim($nameserver);
|
||||
$nameserver_ips = gethostbynamel6($nameserver);
|
||||
if (is_array($nameserver_ips) && count($nameserver_ips) > 0) {
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Database::needSqlData();
|
||||
$sql = Database::getSqlData();
|
||||
|
||||
$replace_arr = array(
|
||||
'<SQL_UNPRIVILEGED_USER>' => $sql['user'],
|
||||
'<SQL_UNPRIVILEGED_PASSWORD>' => $sql['passwd'],
|
||||
'<SQL_DB>' => $sql['db'],
|
||||
'<SQL_HOST>' => $sql['host'],
|
||||
'<SQL_SOCKET>' => isset($sql['socket']) ? $sql['socket'] : null,
|
||||
'<SERVERNAME>' => Settings::Get('system.hostname'),
|
||||
'<SERVERIP>' => Settings::Get('system.ipaddress'),
|
||||
'<NAMESERVERS>' => Settings::Get('system.nameservers'),
|
||||
'<NAMESERVERS_IP>' => $ns_ips,
|
||||
'<AXFRSERVERS>' => Settings::Get('system.axfrservers'),
|
||||
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
|
||||
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
|
||||
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),
|
||||
'<SSLPROTOCOLS>' => (Settings::Get('system.use_ssl') == '1') ? 'imaps pop3s' : '',
|
||||
'<CUSTOMER_TMP>' => makeCorrectDir($customer_tmpdir),
|
||||
'<BASE_PATH>' => makeCorrectDir(FROXLOR_INSTALL_DIR),
|
||||
'<BIND_CONFIG_PATH>' => makeCorrectDir(Settings::Get('system.bindconf_directory')),
|
||||
'<WEBSERVER_RELOAD_CMD>' => Settings::Get('system.apachereload_command'),
|
||||
'<CUSTOMER_LOGS>' => makeCorrectDir(Settings::Get('system.logfiles_directory')),
|
||||
'<FPM_IPCDIR>' => makeCorrectDir(Settings::Get('phpfpm.fastcgi_ipcdir')),
|
||||
'<WEBSERVER_GROUP>' => Settings::Get('system.httpgroup')
|
||||
);
|
||||
return $replace_arr;
|
||||
}
|
||||
|
||||
private function _parseConfig()
|
||||
{
|
||||
define('FROXLOR_INSTALL_DIR', $this->_args['froxlor-dir']);
|
||||
if (! file_exists(FROXLOR_INSTALL_DIR . '/lib/classes/database/class.Database.php')) {
|
||||
throw new \Exception("Could not find froxlor's Database class. Is froxlor really installed to '" . FROXLOR_INSTALL_DIR . "'?");
|
||||
}
|
||||
if (! file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
throw new \Exception("Could not find froxlor's userdata.inc.php file. You should use this script only with a fully installed and setup froxlor system.");
|
||||
}
|
||||
}
|
||||
|
||||
private function _checkConfigParam($needed = false)
|
||||
{
|
||||
if ($needed) {
|
||||
if (! isset($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("No configuration given (missing --froxlor-dir parameter?)");
|
||||
} elseif (! is_dir($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given --froxlor-dir parameter is not a directory");
|
||||
} elseif (! file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (! is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor direcotry cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function downloadFile($src, $dest)
|
||||
{
|
||||
set_time_limit(0);
|
||||
// This is the file where we save the information
|
||||
$fp = fopen($dest, 'w+');
|
||||
// Here is the file we are downloading, replace spaces with %20
|
||||
$ch = curl_init(str_replace(" ", "%20", $src));
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
// write curl response to file
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
// get curl response
|
||||
curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
186
lib/Froxlor/Cli/Action/SwitchServerIpAction.php
Normal file
186
lib/Froxlor/Cli/Action/SwitchServerIpAction.php
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli\Action;
|
||||
|
||||
use Froxlor\Database;
|
||||
use Froxlor\Cli\SwitchServerIpCmd;
|
||||
|
||||
class SwitchServerIpAction extends \Froxlor\Cli\Action
|
||||
{
|
||||
|
||||
public function __construct($args)
|
||||
{
|
||||
parent::__construct($args);
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->_validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the parsed command line parameters
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function _validate()
|
||||
{
|
||||
$need_config = false;
|
||||
if (array_key_exists("list", $this->_args) || array_key_exists("switch", $this->_args)) {
|
||||
$need_config = true;
|
||||
}
|
||||
|
||||
$this->_checkConfigParam($need_config);
|
||||
|
||||
$this->_parseConfig();
|
||||
|
||||
if (array_key_exists("list", $this->_args)) {
|
||||
$this->_listIPs();
|
||||
}
|
||||
if (array_key_exists("switch", $this->_args)) {
|
||||
$this->_switchIPs();
|
||||
}
|
||||
}
|
||||
|
||||
private function _listIPs()
|
||||
{
|
||||
$sel_stmt = Database::prepare("SELECT * FROM panel_ipsandports ORDER BY ip ASC, port ASC");
|
||||
Database::pexecute($sel_stmt);
|
||||
$ips = $sel_stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
$mask = "|%-10.10s |%-50.50s | %10.10s |\n";
|
||||
printf($mask, str_repeat("-", 10), str_repeat("-", 50), str_repeat("-", 10));
|
||||
printf($mask, 'id', 'IP address', 'port');
|
||||
printf($mask, str_repeat("-", 10), str_repeat("-", 50), str_repeat("-", 10));
|
||||
foreach ($ips as $ipdata) {
|
||||
printf($mask, $ipdata['id'], $ipdata['ip'], $ipdata['port']);
|
||||
}
|
||||
printf($mask, str_repeat("-", 10), str_repeat("-", 50), str_repeat("-", 10));
|
||||
echo PHP_EOL . PHP_EOL;
|
||||
}
|
||||
|
||||
private function _switchIPs()
|
||||
{
|
||||
$ip_list = $this->_args['switch'];
|
||||
|
||||
if (empty($ip_list) || is_bool($ip_list)) {
|
||||
throw new \Exception("No paramters given for --switch action.");
|
||||
}
|
||||
|
||||
$ips_to_switch = array();
|
||||
$ip_list = explode(" ", $ip_list);
|
||||
foreach ($ip_list as $ips_combo) {
|
||||
$ip_pair = explode(",", $ips_combo);
|
||||
if (count($ip_pair) != 2) {
|
||||
throw new \Exception("Invalid parameter given for --switch");
|
||||
} else {
|
||||
if (filter_var($ip_pair[0], FILTER_VALIDATE_IP) == false) {
|
||||
throw new \Exception("Invalid source ip address: " . $ip_pair[0]);
|
||||
}
|
||||
if (filter_var($ip_pair[1], FILTER_VALIDATE_IP) == false) {
|
||||
throw new \Exception("Invalid target ip address: " . $ip_pair[1]);
|
||||
}
|
||||
if ($ip_pair[0] == $ip_pair[1]) {
|
||||
throw new \Exception("Source and target ip address are equal");
|
||||
}
|
||||
}
|
||||
$ips_to_switch[] = $ip_pair;
|
||||
}
|
||||
|
||||
if (count($ips_to_switch) > 0) {
|
||||
$check_stmt = Database::prepare("SELECT `id` FROM panel_ipsandports WHERE `ip` = :newip");
|
||||
$upd_stmt = Database::prepare("UPDATE panel_ipsandports SET `ip` = :newip WHERE `ip` = :oldip");
|
||||
|
||||
// system.ipaddress
|
||||
$check_sysip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'ipaddress'");
|
||||
$check_sysip = Database::pexecute_first($check_sysip_stmt);
|
||||
|
||||
// system.mysql_access_host
|
||||
$check_mysqlip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'mysql_access_host'");
|
||||
$check_mysqlip = Database::pexecute_first($check_mysqlip_stmt);
|
||||
|
||||
// system.axfrservers
|
||||
$check_axfrip_stmt = Database::prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'system' and `varname` = 'axfrservers'");
|
||||
$check_axfrip = Database::pexecute_first($check_axfrip_stmt);
|
||||
|
||||
foreach ($ips_to_switch as $ip_pair) {
|
||||
echo "Switching IP \033[1m" . $ip_pair[0] . "\033[0m to IP \033[1m" . $ip_pair[1] . "\033[0m" . PHP_EOL;
|
||||
|
||||
$ip_check = Database::pexecute_first($check_stmt, array(
|
||||
'newip' => $ip_pair[1]
|
||||
));
|
||||
if ($ip_check) {
|
||||
SwitchServerIpCmd::printwarn("Note: " . $ip_pair[0] . " not updated to " . $ip_pair[1] . " - IP already exists in froxlor's database");
|
||||
continue;
|
||||
}
|
||||
|
||||
Database::pexecute($upd_stmt, array(
|
||||
'newip' => $ip_pair[1],
|
||||
'oldip' => $ip_pair[0]
|
||||
));
|
||||
$rows_updated = $upd_stmt->rowCount();
|
||||
|
||||
if ($rows_updated == 0) {
|
||||
SwitchServerIpCmd::printwarn("Note: " . $ip_pair[0] . " not updated to " . $ip_pair[1] . " (possibly no entry found in froxlor database. Use --list to see what IP addresses are added in froxlor");
|
||||
}
|
||||
|
||||
// check whether the system.ipaddress needs updating
|
||||
if ($check_sysip['value'] == $ip_pair[0]) {
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newip WHERE `settinggroup` = 'system' and `varname` = 'ipaddress'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newip' => $ip_pair[1]
|
||||
));
|
||||
SwitchServerIpCmd::printsucc("Updated system-ipaddress from '" . $ip_pair[0] . "' to '" . $ip_pair[1] . "'");
|
||||
}
|
||||
|
||||
// check whether the system.mysql_access_host needs updating
|
||||
if (strstr($check_mysqlip['value'], $ip_pair[0]) !== false) {
|
||||
$new_mysqlip = str_replace($ip_pair[0], $ip_pair[1], $check_mysqlip['value']);
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newmysql WHERE `settinggroup` = 'system' and `varname` = 'mysql_access_host'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newmysql' => $new_mysqlip
|
||||
));
|
||||
SwitchServerIpCmd::printsucc("Updated mysql_access_host from '" . $check_mysqlip['value'] . "' to '" . $new_mysqlip . "'");
|
||||
}
|
||||
|
||||
// check whether the system.axfrservers needs updating
|
||||
if (strstr($check_axfrip['value'], $ip_pair[0]) !== false) {
|
||||
$new_axfrip = str_replace($ip_pair[0], $ip_pair[1], $check_axfrip['value']);
|
||||
$upd2_stmt = Database::prepare("UPDATE `panel_settings` SET `value` = :newaxfr WHERE `settinggroup` = 'system' and `varname` = 'axfrservers'");
|
||||
Database::pexecute($upd2_stmt, array(
|
||||
'newaxfr' => $new_axfrip
|
||||
));
|
||||
SwitchServerIpCmd::printsucc("Updated axfrservers from '" . $check_axfrip['value'] . "' to '" . $new_axfrip . "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
||||
SwitchServerIpCmd::printwarn("*** ATTENTION *** Remember to replace IP addresses in configuration files if used anywhere.");
|
||||
SwitchServerIpCmd::printsucc("IP addresses updated");
|
||||
}
|
||||
|
||||
private function _parseConfig()
|
||||
{
|
||||
define('FROXLOR_INSTALL_DIR', $this->_args['froxlor-dir']);
|
||||
if (! file_exists(FROXLOR_INSTALL_DIR . '/lib/classes/database/class.Database.php')) {
|
||||
throw new \Exception("Could not find froxlor's Database class. Is froxlor really installed to '" . FROXLOR_INSTALL_DIR . "'?");
|
||||
}
|
||||
if (! file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
throw new \Exception("Could not find froxlor's userdata.inc.php file. You should use this script only with a fully installed and setup froxlor system.");
|
||||
}
|
||||
}
|
||||
|
||||
private function _checkConfigParam($needed = false)
|
||||
{
|
||||
if ($needed) {
|
||||
if (! isset($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("No configuration given (missing --froxlor-dir parameter?)");
|
||||
} elseif (! is_dir($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given --froxlor-dir parameter is not a directory");
|
||||
} elseif (! file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (! is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor direcotry cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -12,7 +13,7 @@
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*
|
||||
*/
|
||||
abstract class CmdLineHandler
|
||||
{
|
||||
@@ -27,7 +28,7 @@ abstract class CmdLineHandler
|
||||
/**
|
||||
* Action object read from commandline/config
|
||||
*
|
||||
* @var Action
|
||||
* @var \Froxlor\Cli\Action
|
||||
*/
|
||||
private $_action = null;
|
||||
|
||||
@@ -46,17 +47,6 @@ abstract class CmdLineHandler
|
||||
return new $me($argc, $argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the Action object generated in
|
||||
* the class constructor
|
||||
*
|
||||
* @return Action
|
||||
*/
|
||||
public function getAction()
|
||||
{
|
||||
return $this->_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* class constructor, validates the command line parameters
|
||||
* and sets the Action-object if valid
|
||||
@@ -65,12 +55,13 @@ abstract class CmdLineHandler
|
||||
* @param string[] $argv
|
||||
*
|
||||
* @return null
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function __construct($argc, $argv)
|
||||
{
|
||||
self::$args = $this->_parseArgs($argv);
|
||||
$this->_action = $this->_createAction();
|
||||
$this->_action->run();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,8 +118,8 @@ abstract class CmdLineHandler
|
||||
/**
|
||||
* Creates an Action-Object for the Action-Handler
|
||||
*
|
||||
* @return Action
|
||||
* @throws Exception
|
||||
* @return \Froxlor\Cli\Action
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function _createAction()
|
||||
{
|
||||
@@ -142,9 +133,9 @@ abstract class CmdLineHandler
|
||||
foreach (self::$args as $arg => $value) {
|
||||
|
||||
if (is_numeric($arg)) {
|
||||
throw new Exception("Unknown parameter '" . $value . "' in argument list");
|
||||
throw new \Exception("Unknown parameter '" . $value . "' in argument list");
|
||||
} elseif (! in_array($arg, static::$params) && ! in_array($arg, static::$switches)) {
|
||||
throw new Exception("Unknown parameter '" . $arg . "' in argument list");
|
||||
throw new \Exception("Unknown parameter '" . $arg . "' in argument list");
|
||||
}
|
||||
}
|
||||
|
||||
81
lib/Froxlor/Cli/ConfigServicesCmd.php
Executable file
81
lib/Froxlor/Cli/ConfigServicesCmd.php
Executable file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2018 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
class ConfigServicesCmd extends CmdLineHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* list of valid switches
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $switches = array(
|
||||
'h'
|
||||
);
|
||||
|
||||
/**
|
||||
* list of valid parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $params = array(
|
||||
'create',
|
||||
'apply',
|
||||
'import-settings',
|
||||
'daemon',
|
||||
'list-daemons',
|
||||
'froxlor-dir',
|
||||
'help'
|
||||
);
|
||||
|
||||
public static $action_class = 'ConfigServicesAction';
|
||||
|
||||
public static function printHelp()
|
||||
{
|
||||
self::println("");
|
||||
self::println("Help / command line parameters:");
|
||||
self::println("");
|
||||
// commands
|
||||
self::println("--create\t\tlets you create a services list configuration for the 'apply' command");
|
||||
self::println("");
|
||||
self::println("--apply\t\t\tconfigure your services by given configuration file. To create one run the --create command");
|
||||
self::println("\t\t\tExample: --apply=/path/to/my-config.json or --apply=http://domain.tld/my-config.json");
|
||||
self::println("");
|
||||
self::println("--list-daemons\t\tOutput the services that are going to be configured using a given config file. No services will be configured.");
|
||||
self::println("\t\t\tExample: --apply=/path/to/my-config.json --list-daemons");
|
||||
self::println("");
|
||||
self::println("--daemon\t\tWhen running --apply you can specify a daemon. This will be the only service that gets configured");
|
||||
self::println("\t\t\tExample: --apply=/path/to/my-config.json --daemon=apache24");
|
||||
self::println("");
|
||||
self::println("--import-settings\tImport settings from another froxlor installation. This should be done prior to running --apply or alternatively in the same command together.");
|
||||
self::println("\t\t\tExample: --import-settings=/path/to/Froxlor_settings-[version]-[dbversion]-[date].json or --import-settings=http://domain.tld/Froxlor_settings-[version]-[dbversion]-[date].json");
|
||||
self::println("");
|
||||
self::println("--froxlor-dir\t\tpath to froxlor installation");
|
||||
self::println("\t\t\tExample: --froxlor-dir=/var/www/froxlor/");
|
||||
self::println("");
|
||||
self::println("--help\t\t\tshow help screen (this)");
|
||||
self::println("");
|
||||
// switches
|
||||
// self::println("-d\t\t\tenable debug output");
|
||||
self::println("-h\t\t\tsame as --help");
|
||||
self::println("");
|
||||
|
||||
die(); // end of execution
|
||||
}
|
||||
}
|
||||
68
lib/Froxlor/Cli/SwitchServerIpCmd.php
Executable file
68
lib/Froxlor/Cli/SwitchServerIpCmd.php
Executable file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2018 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
class SwitchServerIpCmd extends CmdLineHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* list of valid switches
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $switches = array(
|
||||
'h'
|
||||
);
|
||||
|
||||
/**
|
||||
* list of valid parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $params = array(
|
||||
'switch',
|
||||
'list',
|
||||
'froxlor-dir',
|
||||
'help'
|
||||
);
|
||||
|
||||
public static $action_class = 'SwitchServerIpAction';
|
||||
|
||||
public static function printHelp()
|
||||
{
|
||||
self::println("");
|
||||
self::println("Help / command line parameters:");
|
||||
self::println("");
|
||||
// commands
|
||||
self::println("--switch\t\tlets you switch ip-address A with ip-address B");
|
||||
self::println("\t\t\tExample: --switch=A,B");
|
||||
self::println("\t\t\tExample: --switch=\"A1,B1 A2,B2 A3,B3 ...\"");
|
||||
self::println("");
|
||||
self::println("--list\t\t\tshow all currently used ip-addresses in froxlor");
|
||||
self::println("");
|
||||
self::println("--froxlor-dir\t\tpath to froxlor installation");
|
||||
self::println("\t\t\tExample: --froxlor-dir=/var/www/froxlor/");
|
||||
self::println("");
|
||||
self::println("--help\t\t\tshow help screen (this)");
|
||||
self::println("");
|
||||
// switches
|
||||
// self::println("-d\t\t\tenable debug output");
|
||||
self::println("-h\t\t\tsame as --help");
|
||||
self::println("");
|
||||
|
||||
die(); // end of execution
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
namespace Froxlor\Config;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,55 +9,61 @@
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*
|
||||
* @since 0.9.34
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*
|
||||
* @since 0.9.34
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Class ConfigDaemon
|
||||
*
|
||||
* Parses a distributions XML - file and gives access to the configuration
|
||||
* Not to be used directly
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*/
|
||||
class ConfigDaemon {
|
||||
class ConfigDaemon
|
||||
{
|
||||
|
||||
/**
|
||||
* Holding the commands for this daemon
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $orders = array();
|
||||
|
||||
/**
|
||||
* Store the parsed SimpleXMLElement for usage
|
||||
* @var SimpleXMLElement
|
||||
*
|
||||
* @var \SimpleXMLElement
|
||||
*/
|
||||
private $fullxml;
|
||||
|
||||
/**
|
||||
* Memorize if we already parsed the XML
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $isparsed = false;
|
||||
|
||||
/**
|
||||
* Sub - area of the full - XML only holding the daemon - data we are interessted in
|
||||
* @var SimpleXMLElement
|
||||
*
|
||||
* @var \SimpleXMLElement
|
||||
*/
|
||||
private $daemon;
|
||||
|
||||
/**
|
||||
* xpath leading to this daemon in the full XML
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $xpath;
|
||||
@@ -64,38 +71,43 @@ class ConfigDaemon {
|
||||
/**
|
||||
* cache of sql-data if used
|
||||
*/
|
||||
private $_sqldata_cache = null;
|
||||
private $_sqldata_cache = null;
|
||||
|
||||
/**
|
||||
* Human - readable title of this service
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $title;
|
||||
|
||||
/**
|
||||
* Whether this is the default daemon of the service-category
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $default;
|
||||
|
||||
public function __construct($xml, $xpath) {
|
||||
public function __construct($xml, $xpath)
|
||||
{
|
||||
$this->fullxml = $xml;
|
||||
$this->xpath = $xpath;
|
||||
$this->daemon = $this->fullxml->xpath($this->xpath);
|
||||
$attributes = $this->daemon[0]->attributes();
|
||||
if ($attributes['title'] != '') {
|
||||
$this->title = $this->_parseContent((string)$attributes['title']);
|
||||
$this->title = $this->_parseContent((string) $attributes['title']);
|
||||
}
|
||||
if (isset($attributes['default'])) {
|
||||
$this->default = ($attributes['default'] == true);
|
||||
$this->default = ($attributes['default'] == true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the XML and populate $this->orders
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function _parse() {
|
||||
private function _parse()
|
||||
{
|
||||
// We only want to parse the stuff one time
|
||||
if ($this->isparsed == true) {
|
||||
return true;
|
||||
@@ -104,18 +116,19 @@ class ConfigDaemon {
|
||||
$preparsed = array();
|
||||
// First: let's push everything into an array and expand all includes
|
||||
foreach ($this->daemon[0]->children() as $order) {
|
||||
switch((string)$order->getName()) {
|
||||
switch ((string) $order->getName()) {
|
||||
case "install":
|
||||
case "file":
|
||||
case "command":
|
||||
// Normal stuff, just add it to the preparsed - array
|
||||
$preparsed[] = $order; break;
|
||||
$preparsed[] = $order;
|
||||
break;
|
||||
case "include":
|
||||
// Includes, get the part we want via xpath
|
||||
$includes = $this->fullxml->xpath((string)$order);
|
||||
$includes = $this->fullxml->xpath((string) $order);
|
||||
foreach ($includes[0] as $include) {
|
||||
// The "include" is also a child, so just skip it, would make a mess later
|
||||
if ((string)$include->getName() == 'include') {
|
||||
if ((string) $include->getName() == 'include') {
|
||||
continue;
|
||||
}
|
||||
$preparsed[] = $include;
|
||||
@@ -127,22 +140,24 @@ class ConfigDaemon {
|
||||
case "installs":
|
||||
// Hold the results
|
||||
$visibility = 1;
|
||||
foreach($order->children() as $child) {
|
||||
switch((string)$child->getName()) {
|
||||
case "visibility": $visibility += $this->_checkVisibility($child); break;
|
||||
foreach ($order->children() as $child) {
|
||||
switch ((string) $child->getName()) {
|
||||
case "visibility":
|
||||
$visibility += $this->_checkVisibility($child);
|
||||
break;
|
||||
case "install":
|
||||
case "file":
|
||||
case "command":
|
||||
if ($visibility > 0) {
|
||||
$preparsed[] = $child;
|
||||
$preparsed[] = $child;
|
||||
}
|
||||
break;
|
||||
case "include":
|
||||
// Includes, get the part we want via xpath
|
||||
$includes = $this->fullxml->xpath((string)$child);
|
||||
$includes = $this->fullxml->xpath((string) $child);
|
||||
foreach ($includes[0] as $include) {
|
||||
// The "include" is also a child, so just skip it, would make a mess later
|
||||
if ((string)$include->getName() == 'include') {
|
||||
if ((string) $include->getName() == 'include') {
|
||||
continue;
|
||||
}
|
||||
$preparsed[] = $include;
|
||||
@@ -160,9 +175,9 @@ class ConfigDaemon {
|
||||
// We got an array (= valid order) and the array already has a type -> add to stack
|
||||
if (is_array($parsedorder) && array_key_exists('type', $parsedorder)) {
|
||||
$this->orders[] = $parsedorder;
|
||||
// We got an array, but no type, means we got multiple orders back, at them to the stack one at a time
|
||||
// We got an array, but no type, means we got multiple orders back, at them to the stack one at a time
|
||||
} elseif (is_array($parsedorder)) {
|
||||
foreach($parsedorder as $neworder) {
|
||||
foreach ($parsedorder as $neworder) {
|
||||
$this->orders[] = $neworder;
|
||||
}
|
||||
}
|
||||
@@ -183,7 +198,8 @@ class ConfigDaemon {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConfig() {
|
||||
public function getConfig()
|
||||
{
|
||||
$this->_parse();
|
||||
return $this->orders;
|
||||
}
|
||||
@@ -191,21 +207,30 @@ class ConfigDaemon {
|
||||
/**
|
||||
* Parse a single order and return it in a format for easier usage
|
||||
*
|
||||
* @param SimpleXMLElement object holding a single order from the distribution - XML
|
||||
* @param
|
||||
* SimpleXMLElement object holding a single order from the distribution - XML
|
||||
* @return array|string
|
||||
*/
|
||||
private function _parseOrder($order) {
|
||||
private function _parseOrder($order)
|
||||
{
|
||||
$attributes = array();
|
||||
foreach($order->attributes() as $key => $value) {
|
||||
$attributes[(string)$key] = (string)$value;
|
||||
foreach ($order->attributes() as $key => $value) {
|
||||
$attributes[(string) $key] = (string) $value;
|
||||
}
|
||||
|
||||
$parsedorder = '';
|
||||
switch((string)$order->getName()) {
|
||||
case "file": $parsedorder = $this->_parseFile($order, $attributes); break;
|
||||
case "command": $parsedorder = $this->_parseCommand($order, $attributes); break;
|
||||
case "install": $parsedorder = $this->_parseInstall($order, $attributes); break;
|
||||
default: throw new \Exception('Invalid order: ' . (string)$order->getName());
|
||||
switch ((string) $order->getName()) {
|
||||
case "file":
|
||||
$parsedorder = $this->_parseFile($order, $attributes);
|
||||
break;
|
||||
case "command":
|
||||
$parsedorder = $this->_parseCommand($order, $attributes);
|
||||
break;
|
||||
case "install":
|
||||
$parsedorder = $this->_parseInstall($order, $attributes);
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('Invalid order: ' . (string) $order->getName());
|
||||
}
|
||||
|
||||
return $parsedorder;
|
||||
@@ -214,27 +239,39 @@ class ConfigDaemon {
|
||||
/**
|
||||
* Parse a install - order and return it in a format for easier usage
|
||||
*
|
||||
* @param SimpleXMLElement object holding a single install from the distribution - XML
|
||||
* @param
|
||||
* SimpleXMLElement object holding a single install from the distribution - XML
|
||||
* @return array|string
|
||||
*/
|
||||
private function _parseInstall($order, $attributes) {
|
||||
private function _parseInstall($order, $attributes)
|
||||
{
|
||||
// No sub - elements, so the content can be returned directly
|
||||
if ($order->count() == 0) {
|
||||
return array('type' => 'install', 'content' => $this->_parseContent(trim((string)$order)));
|
||||
return array(
|
||||
'type' => 'install',
|
||||
'content' => $this->_parseContent(trim((string) $order))
|
||||
);
|
||||
}
|
||||
|
||||
// Hold the results
|
||||
$visibility = 1;
|
||||
$content = '';
|
||||
foreach($order->children() as $child) {
|
||||
switch((string)$child->getName()) {
|
||||
case "visibility": $visibility += $this->_checkVisibility($child); break;
|
||||
case "content": $content = trim((string)$child); break;
|
||||
foreach ($order->children() as $child) {
|
||||
switch ((string) $child->getName()) {
|
||||
case "visibility":
|
||||
$visibility += $this->_checkVisibility($child);
|
||||
break;
|
||||
case "content":
|
||||
$content = trim((string) $child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($visibility > 0) {
|
||||
return array('type' => 'install', 'content' => $this->_parseContent($content));
|
||||
return array(
|
||||
'type' => 'install',
|
||||
'content' => $this->_parseContent($content)
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -243,27 +280,39 @@ class ConfigDaemon {
|
||||
/**
|
||||
* Parse a command - order and return it in a format for easier usage
|
||||
*
|
||||
* @param SimpleXMLElement object holding a single command from the distribution - XML
|
||||
* @param
|
||||
* SimpleXMLElement object holding a single command from the distribution - XML
|
||||
* @return array|string
|
||||
*/
|
||||
private function _parseCommand($order, $attributes) {
|
||||
private function _parseCommand($order, $attributes)
|
||||
{
|
||||
// No sub - elements, so the content can be returned directly
|
||||
if ($order->count() == 0) {
|
||||
return array('type' => 'command', 'content' => $this->_parseContent(trim((string)$order)));
|
||||
return array(
|
||||
'type' => 'command',
|
||||
'content' => $this->_parseContent(trim((string) $order))
|
||||
);
|
||||
}
|
||||
|
||||
// Hold the results
|
||||
$visibility = 1;
|
||||
$content = '';
|
||||
foreach($order->children() as $child) {
|
||||
switch((string)$child->getName()) {
|
||||
case "visibility": $visibility += $this->_checkVisibility($child); break;
|
||||
case "content": $content = trim((string)$child); break;
|
||||
foreach ($order->children() as $child) {
|
||||
switch ((string) $child->getName()) {
|
||||
case "visibility":
|
||||
$visibility += $this->_checkVisibility($child);
|
||||
break;
|
||||
case "content":
|
||||
$content = trim((string) $child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($visibility > 0) {
|
||||
return array('type' => 'command', 'content' => $this->_parseContent($content));
|
||||
return array(
|
||||
'type' => 'command',
|
||||
'content' => $this->_parseContent($content)
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -272,20 +321,26 @@ class ConfigDaemon {
|
||||
/**
|
||||
* Parse a file - order and return it in a format for easier usage
|
||||
*
|
||||
* @param SimpleXMLElement object holding a single file from the distribution - XML
|
||||
* @param
|
||||
* SimpleXMLElement object holding a single file from the distribution - XML
|
||||
* @return array|string
|
||||
*/
|
||||
private function _parseFile($order, $attributes) {
|
||||
private function _parseFile($order, $attributes)
|
||||
{
|
||||
$visibility = 1;
|
||||
// No sub - elements, so the content can be returned directly
|
||||
if ($order->count() == 0) {
|
||||
$content = (string)$order;
|
||||
$content = (string) $order;
|
||||
} else {
|
||||
// Hold the results
|
||||
foreach($order->children() as $child) {
|
||||
switch((string)$child->getName()) {
|
||||
case "visibility": $visibility += $this->_checkVisibility($child); break;
|
||||
case "content": $content = (string)$child; break;
|
||||
foreach ($order->children() as $child) {
|
||||
switch ((string) $child->getName()) {
|
||||
case "visibility":
|
||||
$visibility += $this->_checkVisibility($child);
|
||||
break;
|
||||
case "content":
|
||||
$content = (string) $child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,34 +350,59 @@ class ConfigDaemon {
|
||||
// @TODO: Maybe have a backup - location somewhere central?
|
||||
// @TODO: Use IO - class
|
||||
if (array_key_exists('backup', $attributes)) {
|
||||
if (array_key_exists('mode', $attributes) && $attributes['mode'] == 'append') {
|
||||
$cmd = 'cp';
|
||||
} else {
|
||||
$cmd = 'mv';
|
||||
}
|
||||
$return[] = array('type' => 'command', 'content' => $cmd.' "' . $this->_parseContent($attributes['name']) . '" "' . $this->_parseContent($attributes['name']) . '.frx.bak"', 'execute' => "pre");
|
||||
if (array_key_exists('mode', $attributes) && $attributes['mode'] == 'append') {
|
||||
$cmd = 'cp';
|
||||
} else {
|
||||
$cmd = 'mv';
|
||||
}
|
||||
$return[] = array(
|
||||
'type' => 'command',
|
||||
'content' => $cmd . ' "' . $this->_parseContent($attributes['name']) . '" "' . $this->_parseContent($attributes['name']) . '.frx.bak"',
|
||||
'execute' => "pre"
|
||||
);
|
||||
}
|
||||
|
||||
// Now the content of the file can be written
|
||||
if (isset($attributes['mode'])) {
|
||||
$return[] = array('type' => 'file', 'content' => $this->_parseContent($content), 'name' => $this->_parseContent($attributes['name']), 'mode' => $this->_parseContent($attributes['mode']));
|
||||
$return[] = array(
|
||||
'type' => 'file',
|
||||
'content' => $this->_parseContent($content),
|
||||
'name' => $this->_parseContent($attributes['name']),
|
||||
'mode' => $this->_parseContent($attributes['mode'])
|
||||
);
|
||||
} else {
|
||||
$return[] = array('type' => 'file', 'content' => $this->_parseContent($content), 'name' => $this->_parseContent($attributes['name']));
|
||||
$return[] = array(
|
||||
'type' => 'file',
|
||||
'content' => $this->_parseContent($content),
|
||||
'name' => $this->_parseContent($attributes['name'])
|
||||
);
|
||||
}
|
||||
|
||||
// Let's check if the mode of the file should be changed
|
||||
if (array_key_exists('chmod', $attributes)) {
|
||||
$return[] = array('type' => 'command', 'content' => 'chmod ' . $attributes['chmod'] . ' "' . $this->_parseContent($attributes['name']) . '"', 'execute' => "post");
|
||||
$return[] = array(
|
||||
'type' => 'command',
|
||||
'content' => 'chmod ' . $attributes['chmod'] . ' "' . $this->_parseContent($attributes['name']) . '"',
|
||||
'execute' => "post"
|
||||
);
|
||||
}
|
||||
|
||||
// Let's check if the owner of the file should be changed
|
||||
if (array_key_exists('chown', $attributes)) {
|
||||
$return[] = array('type' => 'command', 'content' => 'chown ' . $attributes['chown'] . ' "' . $this->_parseContent($attributes['name']) . '"', 'execute' => "post");
|
||||
$return[] = array(
|
||||
'type' => 'command',
|
||||
'content' => 'chown ' . $attributes['chown'] . ' "' . $this->_parseContent($attributes['name']) . '"',
|
||||
'execute' => "post"
|
||||
);
|
||||
}
|
||||
|
||||
// If we have more than 1 element, we want to group this stuff for easier processing later
|
||||
if (count($return) > 1) {
|
||||
$return = array('type' => 'file', 'subcommands' => $return, 'name' => $this->_parseContent($attributes['name']));
|
||||
$return = array(
|
||||
'type' => 'file',
|
||||
'subcommands' => $return,
|
||||
'name' => $this->_parseContent($attributes['name'])
|
||||
);
|
||||
}
|
||||
|
||||
if ($visibility > 0) {
|
||||
@@ -334,13 +414,15 @@ class ConfigDaemon {
|
||||
|
||||
/**
|
||||
* Replace placeholders with content
|
||||
*
|
||||
* @param string $content
|
||||
* @return string $content w/o placeholder
|
||||
*/
|
||||
private function _parseContent($content) {
|
||||
private function _parseContent($content)
|
||||
{
|
||||
$content = preg_replace_callback('/\{\{(.*)\}\}/Ui', function ($matches) {
|
||||
if (preg_match('/^settings\.(.*)$/', $matches[1], $match)) {
|
||||
return Settings::Get($match[1]);
|
||||
return \Froxlor\Settings::Get($match[1]);
|
||||
} elseif (preg_match('/^lng\.(.*)(?:\.(.*)(?:\.(.*)))$/U', $matches[1], $match)) {
|
||||
global $lng;
|
||||
if (isset($match[1]) && $match[1] != '' && isset($match[2]) && $match[2] != '' && isset($match[3]) && $match[3] != '') {
|
||||
@@ -359,12 +441,12 @@ class ConfigDaemon {
|
||||
}
|
||||
} elseif (preg_match('/^sql\.(.*)$/', $matches[1], $match)) {
|
||||
if (is_null($this->_sqldata_cache)) {
|
||||
// read in sql-data (if exists)
|
||||
if (file_exists(\Froxlor\Froxlor::getInstallDir()."/lib/userdata.inc.php")) {
|
||||
require \Froxlor\Froxlor::getInstallDir()."/lib/userdata.inc.php";
|
||||
unset($sql_root);
|
||||
$this->_sqldata_cache = $sql;
|
||||
}
|
||||
// read in sql-data (if exists)
|
||||
if (file_exists(\Froxlor\Froxlor::getInstallDir() . "/lib/userdata.inc.php")) {
|
||||
require \Froxlor\Froxlor::getInstallDir() . "/lib/userdata.inc.php";
|
||||
unset($sql_root);
|
||||
$this->_sqldata_cache = $sql;
|
||||
}
|
||||
}
|
||||
return isset($this->_sqldata_cache[$match[1]]) ? $this->_sqldata_cache[$match[1]] : '';
|
||||
}
|
||||
@@ -374,35 +456,99 @@ class ConfigDaemon {
|
||||
|
||||
/**
|
||||
* Check if visibility should be changed
|
||||
* @param SimpleXMLElement $order
|
||||
*
|
||||
* @param \SimpleXMLElement $order
|
||||
* @return int 0|-1
|
||||
*/
|
||||
private function _checkVisibility($order) {
|
||||
private function _checkVisibility($order)
|
||||
{
|
||||
$attributes = array();
|
||||
foreach($order->attributes() as $key => $value) {
|
||||
$attributes[(string)$key] = $this->_parseContent(trim((string)$value));
|
||||
foreach ($order->attributes() as $key => $value) {
|
||||
$attributes[(string) $key] = $this->_parseContent(trim((string) $value));
|
||||
}
|
||||
|
||||
$order = $this->_parseContent(trim((string)$order));
|
||||
if (!array_key_exists('mode', $attributes)) {
|
||||
$order = $this->_parseContent(trim((string) $order));
|
||||
if (! array_key_exists('mode', $attributes)) {
|
||||
throw new \Exception('"<visibility>' . $order . '</visibility>" is missing mode');
|
||||
}
|
||||
|
||||
$return = 0;
|
||||
switch ($attributes['mode']) {
|
||||
case "isfile": if (!is_file($order)) { $return = -1; }; break;
|
||||
case "notisfile": if (is_file($order)) { $return = -1; }; break;
|
||||
case "isdir": if (!is_dir($order)) { $return = -1; }; break;
|
||||
case "notisdir": if (is_dir($order)) { $return = -1; }; break;
|
||||
case "false": if ($order == true) { $return = -1; }; break;
|
||||
case "true": if ($order == false) { $return = -1; }; break;
|
||||
case "notempty": if ($order == "") { $return = -1; }; break;
|
||||
case "userexists": if (posix_getpwuid($order) === false) { $return = -1; }; break;
|
||||
case "groupexists": if (posix_getgrgid($order) === false) { $return = -1; }; break;
|
||||
case "usernotexists": if (is_array(posix_getpwuid($order))) { $return = -1; }; break;
|
||||
case "groupnotexists": if (is_array(posix_getgrgid($order))) { $return = -1; }; break;
|
||||
case "usernamenotexists": if (is_array(posix_getpwnam($order))) { $return = -1; }; break;
|
||||
case "equals": $return = (isset($attributes['value']) && $attributes['value'] == $order ? 0 : -1); break;
|
||||
case "isfile":
|
||||
if (! is_file($order)) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "notisfile":
|
||||
if (is_file($order)) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "isdir":
|
||||
if (! is_dir($order)) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "notisdir":
|
||||
if (is_dir($order)) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "false":
|
||||
if ($order == true) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "true":
|
||||
if ($order == false) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "notempty":
|
||||
if ($order == "") {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "userexists":
|
||||
if (posix_getpwuid($order) === false) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "groupexists":
|
||||
if (posix_getgrgid($order) === false) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "usernotexists":
|
||||
if (is_array(posix_getpwuid($order))) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "groupnotexists":
|
||||
if (is_array(posix_getgrgid($order))) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "usernamenotexists":
|
||||
if (is_array(posix_getpwnam($order))) {
|
||||
$return = - 1;
|
||||
}
|
||||
;
|
||||
break;
|
||||
case "equals":
|
||||
$return = (isset($attributes['value']) && $attributes['value'] == $order ? 0 : - 1);
|
||||
break;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
namespace Froxlor\Config;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,13 +9,13 @@
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*
|
||||
* @since 0.9.34
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*
|
||||
* @since 0.9.34
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -22,107 +23,132 @@
|
||||
*
|
||||
* Parses a distributions XML - file and gives access to the configuration
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*/
|
||||
class ConfigParser {
|
||||
class ConfigParser
|
||||
{
|
||||
|
||||
/**
|
||||
* Holding the available services in the XML
|
||||
* @var array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $services = array();
|
||||
|
||||
/**
|
||||
* Store the parsed SimpleXMLElement for usage
|
||||
* @var SimpleXMLElement
|
||||
*
|
||||
* @var \SimpleXMLElement
|
||||
*/
|
||||
private $xml;
|
||||
|
||||
/**
|
||||
* Memorize if we already parsed the XML
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $isparsed = false;
|
||||
|
||||
/**
|
||||
* Name of the distribution this configuration is for
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $distributionName = '';
|
||||
|
||||
/**
|
||||
* Codename of the distribution this configuration is for
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $distributionCodename = '';
|
||||
|
||||
/**
|
||||
* Version of the distribution this configuration is for
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $distributionVersion = '';
|
||||
|
||||
/**
|
||||
* Recommended editor
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $distributionEditor = '/bin/nano';
|
||||
|
||||
/**
|
||||
* Show if this configuration is deprecated
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $deprecated = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*
|
||||
* Initialize the XML - ConfigParser
|
||||
* @param string $filename filename of the froxlor - configurationfile
|
||||
*
|
||||
* @param string $filename
|
||||
* filename of the froxlor - configurationfile
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($filename) {
|
||||
if (!is_readable($filename)) {
|
||||
throw new Exception('File not readable');
|
||||
public function __construct($filename)
|
||||
{
|
||||
if (! is_readable($filename)) {
|
||||
throw new \Exception('File not readable');
|
||||
}
|
||||
|
||||
$this->xml = simplexml_load_file($filename);
|
||||
if ($this->xml === false) {
|
||||
$error = '';
|
||||
foreach(libxml_get_errors() as $error) {
|
||||
foreach (libxml_get_errors() as $error) {
|
||||
$error .= "\t" . $error->message;
|
||||
}
|
||||
throw new \Exception($error);
|
||||
}
|
||||
|
||||
|
||||
// Let's see if we can find a <distribution> block in the XML
|
||||
$distribution = $this->xml->xpath('//distribution');
|
||||
|
||||
// No distribution found - can't use this file
|
||||
if (!is_array($distribution)) {
|
||||
if (! is_array($distribution)) {
|
||||
throw new \Exception('Invalid XML, no distribution found');
|
||||
}
|
||||
|
||||
// Search for attributes we understand
|
||||
foreach($distribution[0]->attributes() as $key => $value) {
|
||||
switch ((string)$key) {
|
||||
case "name": $this->distributionName = (string)$value; break;
|
||||
case "version": $this->distributionVersion = (string)$value; break;
|
||||
case "codename": $this->distributionCodename = (string)$value; break;
|
||||
case "defaulteditor": $this->distributionEditor = (string)$value; break;
|
||||
case "deprecated": (string)$value == 'true' ? $this->deprecated = true : $this->deprecated = false; break;
|
||||
foreach ($distribution[0]->attributes() as $key => $value) {
|
||||
switch ((string) $key) {
|
||||
case "name":
|
||||
$this->distributionName = (string) $value;
|
||||
break;
|
||||
case "version":
|
||||
$this->distributionVersion = (string) $value;
|
||||
break;
|
||||
case "codename":
|
||||
$this->distributionCodename = (string) $value;
|
||||
break;
|
||||
case "defaulteditor":
|
||||
$this->distributionEditor = (string) $value;
|
||||
break;
|
||||
case "deprecated":
|
||||
(string) $value == 'true' ? $this->deprecated = true : $this->deprecated = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the XML and populate $this->services
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function _parse() {
|
||||
private function _parse()
|
||||
{
|
||||
// We only want to parse the stuff one time
|
||||
if ($this->isparsed == true) {
|
||||
return true;
|
||||
@@ -138,7 +164,7 @@ class ConfigParser {
|
||||
// Search the attributes for "type"
|
||||
foreach ($service->attributes() as $key => $value) {
|
||||
if ($key == 'type') {
|
||||
$this->services[(string)$value] = new ConfigService($this->xml, '//services/service[@type="' . (string)$value . '"]');
|
||||
$this->services[(string) $value] = new ConfigService($this->xml, '//services/service[@type="' . (string) $value . '"]');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,11 +176,13 @@ class ConfigParser {
|
||||
|
||||
/**
|
||||
* Return all services defined by the XML
|
||||
*
|
||||
*
|
||||
* The array will hold ConfigService - Objects for further handling
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getServices() {
|
||||
public function getServices()
|
||||
{
|
||||
// Let's parse this shit(!)
|
||||
$this->_parse();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
namespace Froxlor\Config;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -8,74 +9,83 @@
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*
|
||||
* @since 0.9.34
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*
|
||||
* @since 0.9.34
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Class ConfigService
|
||||
*
|
||||
* Parses a distributions XML - file and gives access to the services within
|
||||
* Not to be used directly
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
* @copyright (c) the authors
|
||||
* @author Florian Aders <eleras@froxlor.org>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Classes
|
||||
*/
|
||||
class ConfigService {
|
||||
class ConfigService
|
||||
{
|
||||
|
||||
/**
|
||||
* Holding the available daemons in this service
|
||||
* @var array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $daemons = array();
|
||||
|
||||
/**
|
||||
* Store the parsed SimpleXMLElement for usage
|
||||
* @var SimpleXMLElement
|
||||
*
|
||||
* @var \SimpleXMLElement
|
||||
*/
|
||||
private $fullxml;
|
||||
|
||||
/**
|
||||
* Memorize if we already parsed the XML
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $isparsed = false;
|
||||
|
||||
/**
|
||||
* xpath leading to this service in the full XML
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $xpath;
|
||||
|
||||
/**
|
||||
* Human - readable title of this service
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $title;
|
||||
|
||||
public function __construct($xml, $xpath) {
|
||||
public function __construct($xml, $xpath)
|
||||
{
|
||||
$this->fullxml = $xml;
|
||||
$this->xpath = $xpath;
|
||||
$service = $this->fullxml->xpath($this->xpath);
|
||||
$attributes = $service[0]->attributes();
|
||||
if ($attributes['title'] != '') {
|
||||
$this->title = $this->_parseContent((string)$attributes['title']);
|
||||
$this->title = $this->_parseContent((string) $attributes['title']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the XML and populate $this->daemons
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function _parse() {
|
||||
private function _parse()
|
||||
{
|
||||
// We only want to parse the stuff one time
|
||||
if ($this->isparsed == true) {
|
||||
return true;
|
||||
@@ -89,12 +99,12 @@ class ConfigService {
|
||||
$name = '';
|
||||
$nametag = '';
|
||||
$versiontag = '';
|
||||
foreach($daemon->attributes() as $key => $value) {
|
||||
foreach ($daemon->attributes() as $key => $value) {
|
||||
if ($key == 'name' && $name == '') {
|
||||
$name = (string)$value;
|
||||
$name = (string) $value;
|
||||
$nametag = "[@name='" . $value . "']";
|
||||
} elseif ($key == 'name' && $name != '') {
|
||||
$name = (string)$value . '_' . $name;
|
||||
$name = (string) $value . '_' . $name;
|
||||
$nametag = "[@name='" . $value . "']";
|
||||
} elseif ($key == 'version' && $name == '') {
|
||||
$name = str_replace('.', '', $value);
|
||||
@@ -105,7 +115,7 @@ class ConfigService {
|
||||
}
|
||||
}
|
||||
if ($name == '') {
|
||||
throw new Exception ('No name attribute for daemon');
|
||||
throw new \Exception('No name attribute for daemon');
|
||||
}
|
||||
$this->daemons[$name] = new ConfigDaemon($this->fullxml, $this->xpath . "/daemon" . $nametag . $versiontag);
|
||||
}
|
||||
@@ -117,13 +127,15 @@ class ConfigService {
|
||||
|
||||
/**
|
||||
* Replace placeholders with content
|
||||
*
|
||||
* @param string $content
|
||||
* @return string $content w/o placeholder
|
||||
*/
|
||||
private function _parseContent($content) {
|
||||
private function _parseContent($content)
|
||||
{
|
||||
$content = preg_replace_callback('/\{\{(.*)\}\}/Ui', function ($matches) {
|
||||
if (preg_match('/^settings\.(.*)$/', $matches[1], $match)) {
|
||||
return Settings::Get($match[1]);
|
||||
return \Froxlor\Settings::Get($match[1]);
|
||||
} elseif (preg_match('/^lng\.(.*)(?:\.(.*)(?:\.(.*)))$/U', $matches[1], $match)) {
|
||||
global $lng;
|
||||
if (isset($match[1]) && $match[1] != '' && isset($match[2]) && $match[2] != '' && isset($match[3]) && $match[3] != '') {
|
||||
@@ -139,7 +151,8 @@ class ConfigService {
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function getDaemons() {
|
||||
public function getDaemons()
|
||||
{
|
||||
$this->_parse();
|
||||
return $this->daemons;
|
||||
}
|
||||
Reference in New Issue
Block a user