Improvements to CLI and backup & restore.
This commit is contained in:
@@ -68,6 +68,10 @@ EOT
|
|||||||
);
|
);
|
||||||
CLI::taskArg('backup-file', false);
|
CLI::taskArg('backup-file', false);
|
||||||
CLI::taskArg('workspace', true);
|
CLI::taskArg('workspace', true);
|
||||||
|
CLI::taskOpt("overwrite", "If a workspace already exists, overwrite it.", "o", "overwrite");
|
||||||
|
CLI::taskOpt("info", "Only shows information about a backup archive.", "i");
|
||||||
|
CLI::taskOpt("workspace", "Select which workspace to restore if multiple workspaces are present in the archive.",
|
||||||
|
"w", "workspace");
|
||||||
CLI::taskRun(run_workspace_restore);
|
CLI::taskRun(run_workspace_restore);
|
||||||
|
|
||||||
CLI::taskName('cacheview-repair');
|
CLI::taskName('cacheview-repair');
|
||||||
@@ -357,19 +361,53 @@ function run_workspace_backup($args, $opts) {
|
|||||||
$workspaces[] = new workspaceTools($arg);
|
$workspaces[] = new workspaceTools($arg);
|
||||||
}
|
}
|
||||||
} else if (sizeof($args) > 0) {
|
} else if (sizeof($args) > 0) {
|
||||||
$workspaces[] = new workspaceTools($args[0]);
|
$workspace = new workspaceTools($args[0]);
|
||||||
|
$workspaces[] = $workspace;
|
||||||
if (sizeof($args) == 2)
|
if (sizeof($args) == 2)
|
||||||
$filename = $args[1];
|
$filename = $args[1];
|
||||||
else
|
else
|
||||||
$filename = $workspace->name . ".tar.gz";
|
$filename = "{$workspace->name}.tar";
|
||||||
|
} else {
|
||||||
|
throw new Exception("No workspace specified for backup");
|
||||||
}
|
}
|
||||||
foreach ($workspaces as $workspace)
|
foreach ($workspaces as $workspace)
|
||||||
$workspace->backup($filename);
|
if (!$workspace->workspaceExists())
|
||||||
|
throw new Exception("Workspace '{$workspace->name}' not found");
|
||||||
|
//If this is a relative path, put the file in the backups directory
|
||||||
|
if (strpos($filename, "/") === false && strpos($filename, '\\') === false)
|
||||||
|
$filename = PATH_DATA . "backups/$filename";
|
||||||
|
CLI::logging("Backing up to $filename\n");
|
||||||
|
$backup = workspaceTools::createBackup($filename);
|
||||||
|
|
||||||
|
foreach ($workspaces as $workspace)
|
||||||
|
$workspace->backup($backup);
|
||||||
|
|
||||||
|
CLI::logging("\n");
|
||||||
|
workspaceTools::printSysInfo();
|
||||||
|
foreach ($workspaces as $workspace) {
|
||||||
|
CLI::logging("\n");
|
||||||
|
$workspace->printMetadata(false);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_workspace_restore($args, $opts) {
|
function run_workspace_restore($args, $opts) {
|
||||||
//$workspace = new workspaceTools($args[0]);
|
$filename = $args[0];
|
||||||
workspaceTools::restore($args[0], $args[1]);
|
if (strpos($filename, "/") === false && strpos($filename, '\\') === false) {
|
||||||
|
$filename = PATH_DATA . "backups/$filename";
|
||||||
|
if (substr_compare($filename, ".tar", -4, 4, true) != 0)
|
||||||
|
$filename .= ".tar";
|
||||||
|
}
|
||||||
|
$info = array_key_exists("info", $opts);
|
||||||
|
if ($info) {
|
||||||
|
workspaceTools::getBackupInfo($filename);
|
||||||
|
} else {
|
||||||
|
CLI::logging("Restoring from $filename\n");
|
||||||
|
$workspace = array_key_exists("workspace", $opts) ? $opts['workspace'] : NULL;
|
||||||
|
$overwrite = array_key_exists("overwrite", $opts);
|
||||||
|
$dstWorkspace = $args[1];
|
||||||
|
workspaceTools::restore($filename, $workspace, $dstWorkspace, $overwrite);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class CLI {
|
|||||||
'description' => NULL,
|
'description' => NULL,
|
||||||
'args' => array(),
|
'args' => array(),
|
||||||
'function' => NULL,
|
'function' => NULL,
|
||||||
'opt' => array('short' => '', 'long' => array())
|
'opt' => array('short' => '', 'long' => array(), 'descriptions' => array())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,9 +83,16 @@ class CLI {
|
|||||||
* @param string $short short options
|
* @param string $short short options
|
||||||
* @param array $long long options
|
* @param array $long long options
|
||||||
*/
|
*/
|
||||||
public static function taskOpt($short, $long = array()) {
|
public static function taskOpt($name, $description, $short, $long = NULL) {
|
||||||
assert(self::$currentTask !== NULL);
|
assert(self::$currentTask !== NULL);
|
||||||
self::$tasks[self::$currentTask]["opt"] = array('short' => $short, 'long' => $long);
|
$opts = self::$tasks[self::$currentTask]["opt"];
|
||||||
|
if ($short)
|
||||||
|
$opts['short'] .= $short;
|
||||||
|
if ($long)
|
||||||
|
$opts['long'][] = $long;
|
||||||
|
$opts['descriptions'][$name] = array('short' => $short, 'long' => $long,
|
||||||
|
'description' => $description);
|
||||||
|
self::$tasks[self::$currentTask]["opt"] = $opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,10 +111,13 @@ class CLI {
|
|||||||
* @param array $args if defined, the task name should be argument 0
|
* @param array $args if defined, the task name should be argument 0
|
||||||
* @param array $opts options as returned by getopt
|
* @param array $opts options as returned by getopt
|
||||||
*/
|
*/
|
||||||
public static function help($args, $opts) {
|
public static function help($args, $opts = NULL) {
|
||||||
global $argv;
|
global $argv;
|
||||||
$scriptName = $argv[0];
|
$scriptName = $argv[0];
|
||||||
$taskName = $args[0];
|
if (is_array($args))
|
||||||
|
$taskName = $args[0];
|
||||||
|
else
|
||||||
|
$taskName = $args;
|
||||||
|
|
||||||
if (!$taskName) {
|
if (!$taskName) {
|
||||||
echo "usage: $scriptName <task> [options] [args]\n";
|
echo "usage: $scriptName <task> [options] [args]\n";
|
||||||
@@ -142,9 +152,21 @@ Usage: $scriptName $taskName $valid_args
|
|||||||
$description
|
$description
|
||||||
|
|
||||||
EOT;
|
EOT;
|
||||||
|
$valid_options = array();
|
||||||
|
foreach(self::$tasks[$taskName]['opt']['descriptions'] as $opt => $data) {
|
||||||
|
$optString = array();
|
||||||
|
if ($data['short'])
|
||||||
|
$optString[] = "-{$data['short']}";
|
||||||
|
if ($data['long'])
|
||||||
|
$optString[] = "--{$data['long']}";
|
||||||
|
$valid_options[] = " " . join(", ", $optString) . "\n\t" . wordwrap($data['description'], 70, "\n\t");
|
||||||
|
}
|
||||||
|
$valid_options = join("\n", $valid_options);
|
||||||
if ($valid_options) {
|
if ($valid_options) {
|
||||||
$message .= <<< EOT
|
$message .= <<< EOT
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
|
||||||
$valid_options
|
$valid_options
|
||||||
|
|
||||||
EOT;
|
EOT;
|
||||||
@@ -185,9 +207,40 @@ EOT;
|
|||||||
G::LoadThirdParty('pear/Console', 'Getopt');
|
G::LoadThirdParty('pear/Console', 'Getopt');
|
||||||
$short = "h" . $taskData['opt']['short'];
|
$short = "h" . $taskData['opt']['short'];
|
||||||
$long = array_merge(array("help"), $taskData['opt']['long']);
|
$long = array_merge(array("help"), $taskData['opt']['long']);
|
||||||
list($options, $arguments) = Console_GetOpt::getopt2($args, $short, $long);
|
$getopt = Console_GetOpt::getopt2($args, $short, $long);
|
||||||
|
if (!is_array($getopt)) {
|
||||||
|
echo self::error("Invalid options (" . $getopt->getMessage() . ")") . "\n\n";
|
||||||
|
self::help($taskName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
list($options, $arguments) = $getopt;
|
||||||
|
foreach ($taskData['opt']['descriptions'] as $optName => $optDescription) {
|
||||||
|
$validOpts[$optDescription['short']] = $optName;
|
||||||
|
$validOpts[$optDescription['long']] = $optName;
|
||||||
|
}
|
||||||
|
$taskOpts = array();
|
||||||
try {
|
try {
|
||||||
call_user_func($taskData['function'], $arguments, $options);
|
foreach ($options as $opt) {
|
||||||
|
list($optName, $optArg) = $opt;
|
||||||
|
if ($optName === "h" || $optName === "--help") {
|
||||||
|
self::help($taskName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (strpos($optName, '--') === 0)
|
||||||
|
$optName = substr($optName, 2);
|
||||||
|
if (!array_key_exists($optName, $validOpts))
|
||||||
|
throw new Exception("Invalid option: $optName");
|
||||||
|
if (array_key_exists($validOpts[$optName], $taskOpts))
|
||||||
|
throw new Exception("'$optName' specified more then once");
|
||||||
|
$taskOpts[$validOpts[$optName]] = $optArg;
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo self::error("Invalid options: " . $e->getMessage()) . "\n\n";
|
||||||
|
self::help($taskName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
call_user_func($taskData['function'], $arguments, $taskOpts);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
echo self::error("\n Error executing '$taskName':\n\n {$e->getMessage()}\n") . "\n";
|
echo self::error("\n Error executing '$taskName':\n\n {$e->getMessage()}\n") . "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,9 +115,12 @@ class workspaceTools {
|
|||||||
/* Change the database name to the new workspace, following the standard
|
/* Change the database name to the new workspace, following the standard
|
||||||
* of prefix (either wf_, rp_, rb_) and the workspace name.
|
* of prefix (either wf_, rp_, rb_) and the workspace name.
|
||||||
*/
|
*/
|
||||||
$this->resetDBDiff[$value] = $dbPrefix[$key] . $this->name;
|
$dbName = $dbPrefix[$key] . $this->name;
|
||||||
$value = $dbPrefix[$key] . $this->name;
|
} else {
|
||||||
|
$dbName = $value;
|
||||||
}
|
}
|
||||||
|
$this->resetDBDiff[$value] = $dbName;
|
||||||
|
$value = $dbName;
|
||||||
}
|
}
|
||||||
return $matches[1].$value.$matches[4];
|
return $matches[1].$value.$matches[4];
|
||||||
}
|
}
|
||||||
@@ -126,11 +129,14 @@ class workspaceTools {
|
|||||||
* Reset the database information to that of a newly created workspace.
|
* Reset the database information to that of a newly created workspace.
|
||||||
*
|
*
|
||||||
* This assumes this workspace already has a db.php file, which will be changed
|
* This assumes this workspace already has a db.php file, which will be changed
|
||||||
* to contain the new information
|
* to contain the new information.
|
||||||
|
* This function will reset the database hostname to the system database.
|
||||||
|
* If reseting database names, it will also use the the prefixes rp_,
|
||||||
|
* rb_ and wf_, with the workspace name as database names.
|
||||||
*
|
*
|
||||||
* @param string $newHost the new hostname for the database
|
* @param string $newHost the new hostname for the database
|
||||||
* @param bool $resetDBNames if true, also reset all database names
|
* @param bool $resetDBNames if true, also reset all database names
|
||||||
* @return bool true on success
|
* @return array contains the new database names as values
|
||||||
*/
|
*/
|
||||||
public function resetDBInfo($newHost, $resetDBNames = true) {
|
public function resetDBInfo($newHost, $resetDBNames = true) {
|
||||||
if (count(explode(":", $newHost)) < 2)
|
if (count(explode(":", $newHost)) < 2)
|
||||||
@@ -141,8 +147,10 @@ class workspaceTools {
|
|||||||
|
|
||||||
CLI::logging("Resetting db info\n");
|
CLI::logging("Resetting db info\n");
|
||||||
if (!$this->workspaceExists())
|
if (!$this->workspaceExists())
|
||||||
throw new Exception("Could not find db.php in the restore");
|
throw new Exception("Could not find db.php in the workspace");
|
||||||
$sDbFile = file_get_contents($this->dbPath);
|
$sDbFile = file_get_contents($this->dbPath);
|
||||||
|
if ($sDbFile === false)
|
||||||
|
throw new Exception("Could not read database information from db.php");
|
||||||
/* Match all defines in the config file. Check updateDBCallback to know what
|
/* Match all defines in the config file. Check updateDBCallback to know what
|
||||||
* keys are changed and what groups are matched.
|
* keys are changed and what groups are matched.
|
||||||
* This regular expression will match any "define ('<key>', '<value>');"
|
* This regular expression will match any "define ('<key>', '<value>');"
|
||||||
@@ -151,8 +159,14 @@ class workspaceTools {
|
|||||||
$sNewDbFile = preg_replace_callback("/( *define *\( *'(?P<key>.*?)' *, *\n* *')(?P<value>.*?)(' *\) *;.*)/",
|
$sNewDbFile = preg_replace_callback("/( *define *\( *'(?P<key>.*?)' *, *\n* *')(?P<value>.*?)(' *\) *;.*)/",
|
||||||
array(&$this, 'resetDBInfoCallback'),
|
array(&$this, 'resetDBInfoCallback'),
|
||||||
$sDbFile);
|
$sDbFile);
|
||||||
file_put_contents($this->dbPath, $sNewDbFile);
|
if (file_put_contents($this->dbPath, $sNewDbFile) === false)
|
||||||
return $this->resetDBDiff;
|
throw new Exception("Could not write database information to db.php");
|
||||||
|
$newDBNames = $this->resetDBDiff;
|
||||||
|
unset($this->resetDBDiff);
|
||||||
|
unset($this->resetDBNames);
|
||||||
|
//Clear the cached information about db.php
|
||||||
|
unset($this->dbInfo);
|
||||||
|
return $newDBNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -618,26 +632,14 @@ class workspaceTools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function printInfo($fields) {
|
||||||
* Print workspace information
|
|
||||||
*
|
|
||||||
* @param bool $printSysInfo include sys info as well or not
|
|
||||||
*/
|
|
||||||
public function printMetadata($printSysInfo = true) {
|
|
||||||
$fields = $this->getMetadata();
|
|
||||||
|
|
||||||
if ($printSysInfo) {
|
|
||||||
workspaceTools::printSysInfo ();
|
|
||||||
CLI::logging("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
$wfDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_USER'] . ':' . $fields['DB_PASS'] . '@' . $fields['DB_HOST'] . '/' . $fields['DB_NAME'];
|
$wfDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_USER'] . ':' . $fields['DB_PASS'] . '@' . $fields['DB_HOST'] . '/' . $fields['DB_NAME'];
|
||||||
$rbDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_RBAC_USER'] . ':' . $fields['DB_RBAC_PASS'] . '@' . $fields['DB_RBAC_HOST'] . '/' . $fields['DB_RBAC_NAME'];
|
$rbDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_RBAC_USER'] . ':' . $fields['DB_RBAC_PASS'] . '@' . $fields['DB_RBAC_HOST'] . '/' . $fields['DB_RBAC_NAME'];
|
||||||
$rpDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_REPORT_USER'] . ':' . $fields['DB_REPORT_PASS'] . '@' . $fields['DB_REPORT_HOST'] . '/' . $fields['DB_REPORT_NAME'];
|
$rpDsn = $fields['DB_ADAPTER'] . '://' . $fields['DB_REPORT_USER'] . ':' . $fields['DB_REPORT_PASS'] . '@' . $fields['DB_REPORT_HOST'] . '/' . $fields['DB_REPORT_NAME'];
|
||||||
|
|
||||||
$info = array(
|
$info = array(
|
||||||
'Workspace Name' => $fields['WORKSPACE_NAME'],
|
'Workspace Name' => $fields['WORKSPACE_NAME'],
|
||||||
'Available Databases' => $fields['AVAILABLE_DB'],
|
//'Available Databases' => $fields['AVAILABLE_DB'],
|
||||||
'Workflow Database' => sprintf("%s://%s:%s@%s/%s", $fields['DB_ADAPTER'] , $fields['DB_USER'], $fields['DB_PASS'], $fields['DB_HOST'], $fields['DB_NAME']),
|
'Workflow Database' => sprintf("%s://%s:%s@%s/%s", $fields['DB_ADAPTER'] , $fields['DB_USER'], $fields['DB_PASS'], $fields['DB_HOST'], $fields['DB_NAME']),
|
||||||
'RBAC Database' => sprintf("%s://%s:%s@%s/%s", $fields['DB_ADAPTER'] , $fields['DB_RBAC_USER'], $fields['DB_RBAC_PASS'], $fields['DB_RBAC_HOST'], $fields['DB_RBAC_NAME']),
|
'RBAC Database' => sprintf("%s://%s:%s@%s/%s", $fields['DB_ADAPTER'] , $fields['DB_RBAC_USER'], $fields['DB_RBAC_PASS'], $fields['DB_RBAC_HOST'], $fields['DB_RBAC_NAME']),
|
||||||
'Report Database' => sprintf("%s://%s:%s@%s/%s", $fields['DB_ADAPTER'] , $fields['DB_REPORT_USER'], $fields['DB_REPORT_PASS'], $fields['DB_REPORT_HOST'], $fields['DB_REPORT_NAME']),
|
'Report Database' => sprintf("%s://%s:%s@%s/%s", $fields['DB_ADAPTER'] , $fields['DB_REPORT_USER'], $fields['DB_REPORT_PASS'], $fields['DB_REPORT_HOST'], $fields['DB_REPORT_NAME']),
|
||||||
@@ -650,6 +652,20 @@ class workspaceTools {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print workspace information
|
||||||
|
*
|
||||||
|
* @param bool $printSysInfo include sys info as well or not
|
||||||
|
*/
|
||||||
|
public function printMetadata($printSysInfo = true, $fields = NULL) {
|
||||||
|
if ($printSysInfo) {
|
||||||
|
workspaceTools::printInfo ();
|
||||||
|
CLI::logging("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
workspaceTools::printMetadata($this->getMetadata());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* exports this workspace database to the specified path
|
* exports this workspace database to the specified path
|
||||||
*
|
*
|
||||||
@@ -697,6 +713,8 @@ class workspaceTools {
|
|||||||
*/
|
*/
|
||||||
static public function createBackup($filename, $compress = true) {
|
static public function createBackup($filename, $compress = true) {
|
||||||
G::LoadThirdParty('pear/Archive', 'Tar');
|
G::LoadThirdParty('pear/Archive', 'Tar');
|
||||||
|
if (!file_exists(dirname($filename)))
|
||||||
|
mkdir(dirname($filename));
|
||||||
if (file_exists($filename))
|
if (file_exists($filename))
|
||||||
unlink ($filename);
|
unlink ($filename);
|
||||||
$backup = new Archive_Tar($filename);
|
$backup = new Archive_Tar($filename);
|
||||||
@@ -710,23 +728,27 @@ class workspaceTools {
|
|||||||
* workspace can later be restored.
|
* workspace can later be restored.
|
||||||
*
|
*
|
||||||
* @param string|archive $filename archive filename to use as backup or
|
* @param string|archive $filename archive filename to use as backup or
|
||||||
* archive object create from createBackup
|
* archive object created by createBackup
|
||||||
* @param bool $compress specifies wheter the backup is compressed or not
|
* @param bool $compress specifies wheter the backup is compressed or not
|
||||||
*/
|
*/
|
||||||
public function backup($filename, $compress = true) {
|
public function backup($backupFile, $compress = true) {
|
||||||
/* $filename can be a string, in which case it's used as the filename of
|
/* $filename can be a string, in which case it's used as the filename of
|
||||||
* the backup, or it can be a previously created tar, which allows for
|
* the backup, or it can be a previously created tar, which allows for
|
||||||
* multiple workspaces in one backup.
|
* multiple workspaces in one backup.
|
||||||
*/
|
*/
|
||||||
if (is_string($filename))
|
if (!$this->workspaceExists()) {
|
||||||
$backup = $this->createBackup($filename);
|
throw new Exception("Workspace '{$this->name}' not found");
|
||||||
else
|
}
|
||||||
$backup = $filename;
|
if (is_string($backupFile)) {
|
||||||
//Get a temporary directory for database backup
|
$backup = $this->createBackup($backupFile);
|
||||||
$tempDirectory = tempnam(__FILE__, '');
|
$filename = $backupFile;
|
||||||
//tempnam gives us a file, so remove it and create a directory instead.
|
} else {
|
||||||
if (file_exists($tempDirectory))
|
$backup = $backupFile;
|
||||||
unlink($tempDirectory);
|
$filename = $backup->_tarname;
|
||||||
|
}
|
||||||
|
if (!file_exists(PATH_DATA . "upgrade/"))
|
||||||
|
mkdir(PATH_DATA . "upgrade/");
|
||||||
|
$tempDirectory = PATH_DATA . "upgrade/" . basename(tempnam(__FILE__, ''));
|
||||||
mkdir($tempDirectory);
|
mkdir($tempDirectory);
|
||||||
$metadata = $this->getMetadata();
|
$metadata = $this->getMetadata();
|
||||||
CLI::logging("Backing up database...\n");
|
CLI::logging("Backing up database...\n");
|
||||||
@@ -737,9 +759,11 @@ class workspaceTools {
|
|||||||
/* Write metadata to file, but make it prettier before. The metadata is just
|
/* Write metadata to file, but make it prettier before. The metadata is just
|
||||||
* a JSON codified array.
|
* a JSON codified array.
|
||||||
*/
|
*/
|
||||||
file_put_contents($metaFilename,
|
if (!file_put_contents($metaFilename,
|
||||||
str_replace(array(",", "{", "}"), array(",\n ", "{\n ", "\n}\n"),
|
str_replace(array(",", "{", "}"), array(",\n ", "{\n ", "\n}\n"),
|
||||||
G::json_encode($metadata)));
|
G::json_encode($metadata)))) {
|
||||||
|
throw new Exception("Could not create backup metadata");
|
||||||
|
}
|
||||||
CLI::logging("Copying database to backup...\n");
|
CLI::logging("Copying database to backup...\n");
|
||||||
$this->addToBackup($backup, $tempDirectory, $tempDirectory);
|
$this->addToBackup($backup, $tempDirectory, $tempDirectory);
|
||||||
CLI::logging("Copying files to backup...\n");
|
CLI::logging("Copying files to backup...\n");
|
||||||
@@ -747,8 +771,6 @@ class workspaceTools {
|
|||||||
$this->addToBackup($backup, $this->path, $this->path, "{$this->name}.files");
|
$this->addToBackup($backup, $this->path, $this->path, "{$this->name}.files");
|
||||||
//Remove leftovers.
|
//Remove leftovers.
|
||||||
G::rm_dir($tempDirectory);
|
G::rm_dir($tempDirectory);
|
||||||
|
|
||||||
$this->printMetadata();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Move to class.dbMaintenance.php
|
//TODO: Move to class.dbMaintenance.php
|
||||||
@@ -757,6 +779,7 @@ class workspaceTools {
|
|||||||
*
|
*
|
||||||
* Create a user specified by the parameters and grant all priviledges for
|
* Create a user specified by the parameters and grant all priviledges for
|
||||||
* the database specified, when the user connects from the hostname.
|
* the database specified, when the user connects from the hostname.
|
||||||
|
* Drops the user if it already exists.
|
||||||
* This function only supports MySQL.
|
* This function only supports MySQL.
|
||||||
*
|
*
|
||||||
* @param string $username username
|
* @param string $username username
|
||||||
@@ -780,10 +803,10 @@ class workspaceTools {
|
|||||||
CLI::logging("Creating user $username for $hostname\n");
|
CLI::logging("Creating user $username for $hostname\n");
|
||||||
$result = mysql_query("CREATE USER '$username'@'$hostname' IDENTIFIED BY '$password'");
|
$result = mysql_query("CREATE USER '$username'@'$hostname' IDENTIFIED BY '$password'");
|
||||||
if ($result === false)
|
if ($result === false)
|
||||||
throw new Exception("Unable to create user: " . mysql_error ());
|
throw new Exception("Unable to create user $username: " . mysql_error ());
|
||||||
$result = mysql_query("GRANT ALL ON $database.* TO '$username'@'$hostname'");
|
$result = mysql_query("GRANT ALL ON $database.* TO '$username'@'$hostname'");
|
||||||
if ($result === false)
|
if ($result === false)
|
||||||
throw new Exception("Unable to grant priviledges: " . mysql_error ());
|
throw new Exception("Unable to grant priviledges to user $username: " . mysql_error ());
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Move to class.dbMaintenance.php
|
//TODO: Move to class.dbMaintenance.php
|
||||||
@@ -828,7 +851,34 @@ class workspaceTools {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static public function restoreLegacy($directory) {
|
static public function restoreLegacy($directory) {
|
||||||
throw new Exception("Legacy restore not implemented");
|
throw new Exception("Use gulliver to restore backups from old versions");
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function getBackupInfo($filename) {
|
||||||
|
G::LoadThirdParty('pear/Archive', 'Tar');
|
||||||
|
$backup = new Archive_Tar($filename);
|
||||||
|
//Get a temporary directory in the upgrade directory
|
||||||
|
$tempDirectory = PATH_DATA . "upgrade/" . basename(tempnam(__FILE__, ''));
|
||||||
|
mkdir($tempDirectory);
|
||||||
|
$metafiles = array();
|
||||||
|
foreach ($backup->listContent() as $backupFile) {
|
||||||
|
$filename = $backupFile["filename"];
|
||||||
|
if (strpos($filename, "/") === false && substr_compare($filename, ".meta", -5, 5, true) === 0) {
|
||||||
|
if (!$backup->extractList(array($filename), $tempDirectory))
|
||||||
|
throw new Exception("Could not extract backup");
|
||||||
|
$metafiles[] = "$tempDirectory/$filename";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CLI::logging("Found " . count($metafiles) . " workspace(s) in backup\n");
|
||||||
|
|
||||||
|
foreach ($metafiles as $metafile) {
|
||||||
|
$data = file_get_contents($metafile);
|
||||||
|
$workspaceData = G::json_decode($data);
|
||||||
|
CLI::logging("\n");
|
||||||
|
workspaceTools::printInfo((array)$workspaceData);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -841,38 +891,55 @@ class workspaceTools {
|
|||||||
* @param string $newWorkspaceName if defined, supplies the name for the
|
* @param string $newWorkspaceName if defined, supplies the name for the
|
||||||
* workspace to restore to
|
* workspace to restore to
|
||||||
*/
|
*/
|
||||||
static public function restore($filename, $newWorkspaceName = NULL) {
|
static public function restore($filename, $srcWorkspace, $dstWorkspace = NULL, $overwrite = true) {
|
||||||
G::LoadThirdParty('pear/Archive', 'Tar');
|
G::LoadThirdParty('pear/Archive', 'Tar');
|
||||||
$backup = new Archive_Tar($filename);
|
$backup = new Archive_Tar($filename);
|
||||||
//Get a temporary directory in the upgrade directory
|
//Get a temporary directory in the upgrade directory
|
||||||
$tempDirectory = PATH_DATA . "upgrade/" . basename(tempnam(__FILE__, ''));
|
$tempDirectory = PATH_DATA . "upgrade/" . basename(tempnam(__FILE__, ''));
|
||||||
mkdir($tempDirectory);
|
mkdir($tempDirectory);
|
||||||
//Extract all backup file, including database scripts and workspace files
|
//Extract all backup files, including database scripts and workspace files
|
||||||
$backup->extract($tempDirectory);
|
if (!$backup->extract($tempDirectory))
|
||||||
|
throw new Exception("Could not extract backup");
|
||||||
//Search for metafiles in the new standard (the old standard would contain
|
//Search for metafiles in the new standard (the old standard would contain
|
||||||
//txt files.
|
//txt files).
|
||||||
$metaFiles = glob($tempDirectory . "/*.meta");
|
$metaFiles = glob($tempDirectory . "/*.meta");
|
||||||
print_r($metaFiles);
|
print_r($metaFiles);
|
||||||
if (empty($metaFiles)) {
|
if (empty($metaFiles)) {
|
||||||
return workspaceTools::restoreLegacy($tempDirectory);
|
$metaFiles = glob($tempDirectory . "/*.txt");
|
||||||
|
if (!empty($metaFiles))
|
||||||
|
return workspaceTools::restoreLegacy($tempDirectory);
|
||||||
|
else
|
||||||
|
throw new Exception("No metadata found in backup");
|
||||||
}
|
}
|
||||||
|
if (isset($srcWorkspace) && count($metaFiles) > 0)
|
||||||
|
throw new Exception("Multiple workspaces in backup but no workspace specified to restore");
|
||||||
|
if (isset($srcWorkspace) && !in_array("$srcWorkspace.meta", $metaFiles))
|
||||||
|
throw new Exception("Workspace $srcWorkspace not found in backup");
|
||||||
foreach ($metaFiles as $metaFile) {
|
foreach ($metaFiles as $metaFile) {
|
||||||
$metadata = G::json_decode(file_get_contents($metaFile));
|
$metadata = G::json_decode(file_get_contents($metaFile));
|
||||||
print_r($metadata);
|
print_r($metadata);
|
||||||
if ($metadata->version != 1)
|
if ($metadata->version != 1)
|
||||||
throw new Exception("Backup version {$metadata->version} not supported");
|
throw new Exception("Backup version {$metadata->version} not supported");
|
||||||
$backupWorkspace = $metadata->WORKSPACE_NAME;
|
$backupWorkspace = $metadata->WORKSPACE_NAME;
|
||||||
if (isset($newWorkspaceName)) {
|
if (isset($srcWorkspace)) {
|
||||||
$workspaceName = $newWorkspaceName;
|
$workspaceName = $srcWorkspace;
|
||||||
$createWorkspace = true;
|
$createWorkspace = true;
|
||||||
} else {
|
} else {
|
||||||
$workspaceName = $metadata->WORKSPACE_NAME;
|
$workspaceName = $metadata->WORKSPACE_NAME;
|
||||||
$createWorkspace = false;
|
$createWorkspace = false;
|
||||||
}
|
}
|
||||||
|
if (isset($srcWorkspace) && strcmp($metadata->WORKSPACE_NAME, $srcWorkspace) != 0) {
|
||||||
|
CLI::logging("Workspace $backupWorkspace found, but not restoring.\n");
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
CLI::logging("Restoring $backupWorkspace to $workspaceName\n");
|
||||||
|
}
|
||||||
$workspace = new workspaceTools($workspaceName);
|
$workspace = new workspaceTools($workspaceName);
|
||||||
if ($workspace->workspaceExists())
|
if ($workspace->workspaceExists())
|
||||||
// throw new Exception("Workspace exists");
|
if ($overwrite)
|
||||||
CLI::logging("Workspace $workspaceName already exists, overwriting!\n");
|
CLI::logging("Workspace $workspaceName already exists, overwriting!\n");
|
||||||
|
else
|
||||||
|
throw new Exception("Destination workspace already exists and not overwriting");
|
||||||
|
|
||||||
if (file_exists($workspace->path))
|
if (file_exists($workspace->path))
|
||||||
G::rm_dir($workspace->path);
|
G::rm_dir($workspace->path);
|
||||||
@@ -881,12 +948,16 @@ class workspaceTools {
|
|||||||
CLI::logging("Restoring directory '$dir'\n");
|
CLI::logging("Restoring directory '$dir'\n");
|
||||||
|
|
||||||
if (!rename("$tempDirectory/$dir", $workspace->path)) {
|
if (!rename("$tempDirectory/$dir", $workspace->path)) {
|
||||||
throw new Exception("There was an error copying the backup files ($tempDirectory/$dir) to the workspace directory {$workspace->path}.\n");
|
throw new Exception("There was an error copying the backup files ($tempDirectory/$dir) to the workspace directory {$workspace->path}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list($dbHost, $dbUser, $dbPass) = @explode(SYSTEM_HASH, G::decrypt(HASH_INSTALLATION, SYSTEM_HASH));
|
list($dbHost, $dbUser, $dbPass) = @explode(SYSTEM_HASH, G::decrypt(HASH_INSTALLATION, SYSTEM_HASH));
|
||||||
mysql_connect($dbHost, $dbUser, $dbPass);
|
|
||||||
|
CLI::logging("Connecting to system database in $dbHost\n");
|
||||||
|
$link = mysql_connect($dbHost, $dbUser, $dbPass);
|
||||||
|
if (!$link)
|
||||||
|
throw new Exception('Could not connect to system database: ' . mysql_error());
|
||||||
|
|
||||||
$newDBNames = $workspace->resetDBInfo($dbHost, $createWorkspace);
|
$newDBNames = $workspace->resetDBInfo($dbHost, $createWorkspace);
|
||||||
|
|
||||||
@@ -898,6 +969,8 @@ class workspaceTools {
|
|||||||
$workspace->createDBUser($dbName, $db->pass, "%", $dbName);
|
$workspace->createDBUser($dbName, $db->pass, "%", $dbName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql_close($link);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
G::rm_dir($tempDirectory);
|
G::rm_dir($tempDirectory);
|
||||||
|
|||||||
Reference in New Issue
Block a user