diff options
Diffstat (limited to 'inc/trigger.inc.php')
-rw-r--r-- | inc/trigger.inc.php | 110 |
1 files changed, 39 insertions, 71 deletions
diff --git a/inc/trigger.inc.php b/inc/trigger.inc.php index 988b31c6..d0d5d365 100644 --- a/inc/trigger.inc.php +++ b/inc/trigger.inc.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + /** * This is one giant class containing various functions that will generate * required config files, daemon instances and more, mostly through the Taskmanager. @@ -14,20 +16,21 @@ class Trigger /** * Compile iPXE pxelinux menu. Needs to be done whenever the server's IP * address changes. - * - * @param boolean $force force recompilation even if it seems up to date - * @return boolean|string false if launching task failed, task-id otherwise + * + * @return ?string null if launching task failed, task-id otherwise */ - public static function ipxe() + public static function ipxe(string $taskId = null): ?string { + static $lastResult = null; + if ($lastResult !== null) + return $lastResult; $hooks = Hook::load('ipxe-update'); - static $taskId = false; foreach ($hooks as $hook) { $ret = function($taskId) use ($hook) { $ret = include_once($hook->file); if (is_string($ret)) return $ret; - return isset($taskId) ? $taskId : false; + return $taskId; }; $ret = $ret($taskId); if (is_string($ret)) { @@ -36,7 +39,7 @@ class Trigger $taskId = $ret['id']; } } - Property::set('ipxe-task-id', $taskId, 15); + $lastResult = $taskId; return $taskId; } @@ -48,7 +51,7 @@ class Trigger * @return boolean true if current configured IP address is still valid, or if a new address could * successfully be determined, false otherwise */ - public static function autoUpdateServerIp() + public static function autoUpdateServerIp(): bool { for ($i = 0; $i < 5; ++$i) { $task = Taskmanager::submit('LocalAddressesList'); @@ -59,7 +62,7 @@ class Trigger if ($task === false) return false; $task = Taskmanager::waitComplete($task, 10000); - if (!isset($task['data']['addresses']) || empty($task['data']['addresses'])) + if (empty($task['data']['addresses'])) return false; $serverIp = Property::getServerIp(); @@ -94,54 +97,20 @@ class Trigger } /** - * Launch all ldadp instances that need to be running. - * - * @param int $exclude if not NULL, id of config module NOT to start - * @param string $parent if not NULL, this will be the parent task of the launch-task - * @return boolean|string false on error, id of task otherwise - */ - public static function ldadp($exclude = NULL, $parent = NULL) - { - // TODO: Fetch list from ConfigModule_AdAuth (call loadDb first) - $res = Database::simpleQuery("SELECT DISTINCT moduleid FROM configtgz_module" - . " INNER JOIN configtgz_x_module USING (moduleid)" - . " INNER JOIN configtgz USING (configid)" - . " INNER JOIN configtgz_location USING (configid)" - . " WHERE moduletype IN ('AdAuth', 'LdapAuth')"); - $id = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if (!is_null($exclude) && (int)$row['moduleid'] === (int)$exclude) - continue; - $id[] = (int)$row['moduleid']; - } - $task = Taskmanager::submit('LdadpLauncher', array( - 'ids' => $id, - 'parentTask' => $parent, - 'failOnParentFail' => false - )); - if (!isset($task['id'])) - return false; - return $task['id']; - } - - /** * Mount the VM store into the server. * - * @param array $vmstore VM Store configuration to use. If false, read from properties - * @return array|false task status of mount procedure, or false on error + * @param array|false $vmstore VM Store configuration to use. If false, read from properties + * @param bool $ifLocalOnly Only execute task if the storage type is local (used for DNBD3) + * @return ?string task id of mount procedure, or false on error */ - public static function mount($vmstore = false) + public static function mount($vmstore = false, bool $ifLocalOnly = false): ?string { if ($vmstore === false) { $vmstore = Property::getVmStoreConfig(); } if (!is_array($vmstore)) - return false; - if (isset($vmstore['storetype'])) { - $storetype = $vmstore['storetype']; - } else { - $storetype = 'unknown'; - } + return null; + $storetype = $vmstore['storetype'] ?? 'unknown'; if ($storetype === 'nfs') { $addr = $vmstore['nfsaddr']; $opts = 'nfsopts'; @@ -152,18 +121,24 @@ class Trigger $opts = null; $addr = 'null'; } - if (isset($vmstore[$opts])) { - $opts = $vmstore[$opts]; - }else { - $opts = null; - } - return Taskmanager::submit('MountVmStore', array( + // Bail out if storage is not local, and we only want to run it in that case + if ($ifLocalOnly && $addr !== 'null') + return null; + $opts = $vmstore[$opts] ?? null; + $status = Taskmanager::submit('MountVmStore', array( 'address' => $addr, 'type' => 'images', 'opts' => $opts, + 'localNfs' => !Module::isAvailable('dnbd3') || !Dnbd3::isEnabled() || Dnbd3::hasNfsFallback(), 'username' => $vmstore['cifsuser'], 'password' => $vmstore['cifspasswd'] )); + if (!Taskmanager::isFailed($status)) { + // In case we have a concurrent active task, this should be enough + // for the taskmanager to give us the existing id + $status = Taskmanager::waitComplete($status, 100); + } + return $status['data']['existingTask'] ?? $status['id'] ?? null; } /** @@ -171,7 +146,7 @@ class Trigger * * @return boolean Whether there are still callbacks pending */ - public static function checkCallbacks() + public static function checkCallbacks(): bool { $tasksLeft = false; $callbackList = TaskmanagerCallback::getPendingCallbacks(); @@ -182,15 +157,16 @@ class Trigger foreach ($callbacks as $callback) { TaskmanagerCallback::handleCallback($callback, $status); } - if (Taskmanager::isFailed($status) || Taskmanager::isFinished($status)) + if (Taskmanager::isFailed($status) || Taskmanager::isFinished($status)) { Taskmanager::release($status); - else + } else { $tasksLeft = true; + } } return $tasksLeft; } - private static function triggerDaemons($action, $parent, &$taskids) + private static function triggerDaemons(string $action, ?string $parent, array &$taskids): ?string { $task = Taskmanager::submit('Systemctl', array( 'operation' => $action, @@ -215,7 +191,10 @@ class Trigger return $parent; } - public static function stopDaemons($parent, &$taskids) + /** + * Stop any daemons that might be sitting on the VMstore, or database. + */ + public static function stopDaemons(?string $parent, array &$taskids): ?string { $parent = self::triggerDaemons('stop', $parent, $taskids); $task = Taskmanager::submit('LdadpLauncher', array( @@ -230,15 +209,4 @@ class Trigger return $parent; } - public static function startDaemons($parent, &$taskids) - { - $parent = self::triggerDaemons('start', $parent, $taskids); - $taskid = self::ldadp($parent); - if ($taskid !== false) { - $taskids['ldadpid'] = $taskid; - $parent = $taskid; - } - return $parent; - } - } |