summaryrefslogtreecommitdiffstats
path: root/inc
diff options
context:
space:
mode:
authorSimon Rettberg2015-01-29 20:41:41 +0100
committerSimon Rettberg2015-01-29 20:41:41 +0100
commit06d9d5f70e8475e768b528b1f46e1005b8c2e1ee (patch)
treea2355836c9128cf4d5aa3939c48bad635ed768b8 /inc
parent[sysconfig] Add legend (diff)
downloadslx-admin-06d9d5f70e8475e768b528b1f46e1005b8c2e1ee.tar.gz
slx-admin-06d9d5f70e8475e768b528b1f46e1005b8c2e1ee.tar.xz
slx-admin-06d9d5f70e8475e768b528b1f46e1005b8c2e1ee.zip
Config.tgz improvements, automatic rebuilds etc.
Diffstat (limited to 'inc')
-rw-r--r--inc/configmodule.inc.php34
-rw-r--r--inc/configmodule/adauth.inc.php7
-rw-r--r--inc/configmodule/branding.inc.php5
-rw-r--r--inc/configmodule/customodule.inc.php6
-rw-r--r--inc/configtgz.inc.php143
-rw-r--r--inc/taskmanagercallback.inc.php15
-rw-r--r--inc/util.inc.php13
7 files changed, 205 insertions, 18 deletions
diff --git a/inc/configmodule.inc.php b/inc/configmodule.inc.php
index ae2201fc..31c19953 100644
--- a/inc/configmodule.inc.php
+++ b/inc/configmodule.inc.php
@@ -163,6 +163,14 @@ abstract class ConfigModule
* @return boolean true if data was successfully set, false otherwise (i.e. invalid data being set)
*/
public abstract function setData($key, $value);
+
+ /**
+ * Get module specific data
+ *
+ * @param string $key key, name or id of data to get
+ * @return mixed Module specific data
+ */
+ public abstract function getData($key);
/**
* Module specific version of generate.
@@ -260,6 +268,28 @@ abstract class ConfigModule
));
return true;
}
+
+ /**
+ * Update the given module in database. This will not regenerate
+ * the module's tgz.
+ *
+ * @return boolean true on success, false otherwise
+ */
+ public final function update()
+ {
+ if ($this->moduleId === 0)
+ Util::traceError('ConfigModule::update called when moduleId == 0');
+ if (!$this->validateConfig())
+ return false;
+ // Update
+ Database::exec("UPDATE configtgz_module SET contents = :contents, status = :status "
+ . " WHERE moduleid = :moduleid LIMIT 1", array(
+ 'moduleid' => $this->moduleId,
+ 'contents' => json_encode($this->moduleData),
+ 'status' => 'OUTDATED'
+ ));
+ return true;
+ }
/**
* Generate the module's tgz, don't wait for completion.
@@ -283,7 +313,7 @@ abstract class ConfigModule
if ($ret === true || (isset($ret['statusCode']) && $ret['statusCode'] === TASK_FINISHED)) {
// Already Finished
if (file_exists($this->moduleArchive) && !file_exists($tmpTgz))
- $tmpTgz = false;
+ $tmpTgz = false; // If generateInternal succeeded and there's no tmpTgz, it means the file didn't have to be updated
return $this->markUpdated($tmpTgz);
}
if (!is_array($ret) || !isset($ret['id']) || Taskmanager::isFailed($ret)) {
@@ -362,6 +392,7 @@ abstract class ConfigModule
// Update related config.tgzs
$configs = ConfigTgz::getAllForModule($this->moduleId);
foreach ($configs as $config) {
+ $config->markOutdated();
$config->generate();
}
return $retval;
@@ -406,7 +437,6 @@ abstract class ConfigModule
{
self::loadDb(); // Quick hack: Hard code AdAuth, should be a property of the config module class....
$list = self::getAll('AdAuth');
- error_log('Changed: Telling ' - count($list) . ' modules');
foreach ($list as $mod) {
$mod->event_serverIpChanged();
}
diff --git a/inc/configmodule/adauth.inc.php b/inc/configmodule/adauth.inc.php
index 828469c3..11087286 100644
--- a/inc/configmodule/adauth.inc.php
+++ b/inc/configmodule/adauth.inc.php
@@ -47,6 +47,13 @@ class ConfigModule_AdAuth extends ConfigModule
return true;
}
+ public function getData($key)
+ {
+ if (!is_array($this->moduleData) || !isset($this->moduleData[$key]))
+ return false;
+ return $this->moduleData[$key];
+ }
+
// ############## Callbacks #############################
/**
diff --git a/inc/configmodule/branding.inc.php b/inc/configmodule/branding.inc.php
index 6e452a93..b2f28c2f 100644
--- a/inc/configmodule/branding.inc.php
+++ b/inc/configmodule/branding.inc.php
@@ -47,4 +47,9 @@ class ConfigModule_Branding extends ConfigModule
$this->tmpFile = $value;
}
+ public function getData($key)
+ {
+ return false;
+ }
+
}
diff --git a/inc/configmodule/customodule.inc.php b/inc/configmodule/customodule.inc.php
index 195f738f..89f63549 100644
--- a/inc/configmodule/customodule.inc.php
+++ b/inc/configmodule/customodule.inc.php
@@ -48,4 +48,10 @@ class ConfigModule_CustomModule extends ConfigModule
return false;
$this->tmpFile = $value;
}
+
+ public function getData($key)
+ {
+ return false;
+ }
+
}
diff --git a/inc/configtgz.inc.php b/inc/configtgz.inc.php
index 783f8b80..2082155c 100644
--- a/inc/configtgz.inc.php
+++ b/inc/configtgz.inc.php
@@ -22,6 +22,21 @@ class ConfigTgz
{
return $this->configTitle;
}
+
+ public function areAllModulesUpToDate()
+ {
+ if (!$this->configId > 0)
+ Util::traceError('ConfigTgz::areAllModulesUpToDate called on un-inserted config.tgz!');
+ foreach ($this->modules as $module) {
+ if (!empty($module['filepath']) && file_exists($module['filepath'])) {
+ if ($module['status'] !== 'OK')
+ return false;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
public static function insert($title, $moduleIds)
{
@@ -104,21 +119,73 @@ class ConfigTgz
}
return $list;
}
+
+ /**
+ * Called when (re)generating a config tgz failed, so we can
+ * update the status in the DB and add a server log entry.
+ *
+ * @param array $task
+ * @param array $args contains 'configid' and optionally 'deleteOnError'
+ */
+ public static function generateFailed($task, $args)
+ {
+ if (!isset($args['configid']) || !is_numeric($args['configid'])) {
+ EventLog::warning('Ignoring generateFailed event as it has no configid assigned.');
+ return;
+ }
+ $config = self::get($args['configid']);
+ if ($config === false) {
+ EventLog::warning('generateFailed callback for config id ' . $args['configid'] . ', but no instance could be generated.');
+ return;
+ }
+ if (isset($task['data']['error']))
+ $error = $task['data']['error'];
+ elseif (isset($task['data']['messages']))
+ $error = $task['data']['messages'];
+ else
+ $error = '';
+ EventLog::failure("Generating config.tgz '" . $config->configTitle . "' failed.", $error);
+ if ($args['deleteOnError'])
+ $config->delete();
+ else
+ $config->markFailed();
+ }
+
+ /**
+ * (Re)generating a config tgz succeeded. Update db entry.
+ *
+ * @param array $args contains 'configid' and optionally 'deleteOnError'
+ */
+ public static function generateSucceeded($args)
+ {
+ if (!isset($args['configid']) || !is_numeric($args['configid'])) {
+ EventLog::warning('Ignoring generateSucceeded event as it has no configid assigned.');
+ return;
+ }
+ $config = self::get($args['configid']);
+ if ($config === false) {
+ EventLog::warning('generateSucceeded callback for config id ' . $args['configid'] . ', but no instance could be generated.');
+ return;
+ }
+ $config->markUpdated();
+ }
- public function generate()
+ /**
+ *
+ * @param type $deleteOnError
+ * @param type $timeoutMs
+ * @return string - OK (success)
+ * - OUTDATED (updating failed, but old version still exists)
+ * - MISSING (failed and no old version available)
+ */
+ public function generate($deleteOnError = false, $timeoutMs = 0)
{
if (!($this->configId > 0) || !is_array($this->modules) || $this->file === false)
Util::traceError ('configId <= 0 or modules not array in ConfigTgz::rebuild()');
$files = array();
- $successStatus = 'OK';
foreach ($this->modules as $module) {
- if (!empty($module['filepath']) && file_exists($module['filepath'])) {
+ if (!empty($module['filepath']) && file_exists($module['filepath']))
$files[] = $module['filepath'];
- if ($module['status'] !== 'OK')
- $successStatus = 'OUTDATED';
- } else {
- $successStatus = 'OUTDATED';
- }
}
// Hand over to tm
$task = Taskmanager::submit('RecompressArchive', array(
@@ -126,18 +193,28 @@ class ConfigTgz
'outputFile' => $this->file
));
// Wait for completion
- if (!Taskmanager::isFailed($task) && !Taskmanager::isFinished($task))
- $task = Taskmanager::waitComplete($task, 5000);
- // Failed...
- if (Taskmanager::isFailed($task)) {
+ if ($timeoutMs > 0 && !Taskmanager::isFailed($task) && !Taskmanager::isFinished($task))
+ $task = Taskmanager::waitComplete($task, $timeoutMs);
+ if ($task === true || (isset($task['statusCode']) && $task['statusCode'] === TASK_FINISHED)) {
+ // Success!
+ $this->markUpdated();
+ return true;
+ }
+ if (!is_array($task) || !isset($task['id']) || Taskmanager::isFailed($task)) {
+ // Failed...
Taskmanager::addErrorMessage($task);
- $successStatus = file_exists($this->file) ? 'OUTDATED' : 'MISSING';
+ if (!$deleteOnError)
+ $this->markFailed();
+ else
+ $this->delete();
+ return false;
}
- Database::exec("UPDATE configtgz SET status = :status WHERE configid = :configid LIMIT 1", array(
+ // Still running, add callback
+ TaskmanagerCallback::addCallback($task, 'cbConfTgzCreated', array(
'configid' => $this->configId,
- 'status' => $successStatus
+ 'deleteOnError' => $deleteOnError
));
- return $successStatus;
+ return $task['id'];
}
public function delete()
@@ -157,4 +234,38 @@ class ConfigTgz
return $ret;
}
+ public function markOutdated()
+ {
+ if ($this->configId === 0)
+ Util::traceError('ConfigTgz::markOutdated called with invalid config id!');
+ return $this->mark('OUTDATED');
+ }
+
+ private function markUpdated()
+ {
+ if ($this->configId === 0)
+ Util::traceError('ConfigTgz::markUpdated called with invalid config id!');
+ if ($this->areAllModulesUpToDate())
+ return $this->mark('OK');
+ return $this->mark('OUTDATED');
+ }
+
+ private function markFailed()
+ {
+ if ($this->configId === 0)
+ Util::traceError('ConfigTgz::markFailed called with invalid config id!');
+ if ($this->file === false || !file_exists($this->file))
+ return $this->mark('MISSING');
+ return $this->mark('OUTDATED');
+ }
+
+ private function mark($status)
+ {
+ Database::exec("UPDATE configtgz SET status = :status WHERE configid = :configid LIMIT 1", array(
+ 'configid' => $this->configId,
+ 'status' => $status
+ ));
+ return $status;
+ }
+
}
diff --git a/inc/taskmanagercallback.inc.php b/inc/taskmanagercallback.inc.php
index 8550d845..546fbbc9 100644
--- a/inc/taskmanagercallback.inc.php
+++ b/inc/taskmanagercallback.inc.php
@@ -130,5 +130,20 @@ class TaskmanagerCallback
ConfigModule::generateSucceeded($args);
}
}
+
+ /**
+ * Generating a config.tgz has finished.
+ *
+ * @param array $task task obj
+ * @param array $args has keys 'configid' and optionally 'deleteOnError'
+ */
+ public static function cbConfTgzCreated($task, $args)
+ {
+ if (Taskmanager::isFailed($task)) {
+ ConfigTgz::generateFailed($task, $args);
+ } else {
+ ConfigTgz::generateSucceeded($args);
+ }
+ }
}
diff --git a/inc/util.inc.php b/inc/util.inc.php
index d2ecba6f..4378a084 100644
--- a/inc/util.inc.php
+++ b/inc/util.inc.php
@@ -2,6 +2,7 @@
class Util
{
+ private static $redirectParams = array();
/**
* Displays an error message and stops script execution.
@@ -69,9 +70,21 @@ SADFACE;
$location .= '&' . $messages;
}
}
+ if (!empty(self::$redirectParams)) {
+ if (strpos($location, '?') === false) {
+ $location .= '?' . implode('&', self::$redirectParams);
+ } else {
+ $location .= '&' . implode('&', self::$redirectParams);
+ }
+ }
Header('Location: ' . $location);
exit(0);
}
+
+ public static function addRedirectParam($key, $value)
+ {
+ self::$redirectParams[] = $key .= '=' . urlencode($value);
+ }
/**
* Verify the user's token that protects agains CSRF.