summaryrefslogblamecommitdiffstats
path: root/inc/taskmanagercallback.inc.php
blob: 536c899e34f8b99af51ea1d0d7140c3b40270f72 (plain) (tree)
1
2
3
4
5
6
7
8
9

     

                        




                                                         
 






                                                                                                   
                                                                                       







                                                                                                      
                                                                                                                       

                               
                              
                                        
                                                
                  

                                           
                        
                                                         
                 



                                                                                                                  




                                                                                                                       


           



                                                                   
                                                           
         

                                                                                                             
                                       
                                  
                                        








                                                                             
                                                                                            
                                                                                                               
           
                                                                                          






                                                                                                                                                                                               
                                                                                                                                
                                       
                         

                                                       
                                                      



                                                                                                                       
                                                             
                                                                             

                                                                                                       






                                                                               

                                                
                                                        
         



                                                                
                                                                                                                     
                 

         


                                                       
                                                      
         
                                                    


                                                                         
        
                                                          










                                                                                                                       
                                                                         
         


                                                
                                         





                                                                   






                                                                                
                                                                         
         


                                                
                                         


                                                                
                                                                   

                 
        
                                                              







                                                          

                                                                                                





                                                                                                                           

                 
 
                                                            







                                                              
                                                             






                                                               
 
                                                               







                                                                     
                                                          







                                                           
                                                           







                                                            








                                                              
                                                                   




                                                   









                                                                     

         
 
<?php

declare(strict_types=1);

/**
 * Contains all callbacks for detached taskmanager tasks.
 */
class TaskmanagerCallback
{

	/**
	 * Add a callback for given task id. This is the only exception in this class,
	 * as this is not a callback, but a function to define one :)
	 *
	 * @param string|array $task Task or Task ID to define callback for
	 * @param string $callback name of callback function, must be a static method in this class
	 */
	public static function addCallback($task, string $callback, $args = NULL): void
	{
		if (!call_user_func_array('method_exists', array('TaskmanagerCallback', $callback))) {
			EventLog::warning("addCallback: Invalid callback function: $callback");
			return;
		}
		if (is_array($task) && isset($task['id']))
			$task = $task['id'];
		if (!is_string($task)) {
			EventLog::warning("addCallback: Not a valid task id: $task", print_r(debug_backtrace(), true));
			return;
		}
		$data = array(
			'task' => $task,
			'callback' => $callback,
		);
		if (is_null($args)) {
			$data['args'] = '';
		} else {
			$data['args'] = serialize($args);
		}
		if (Database::exec("INSERT INTO callback (taskid, dateline, cbfunction, args)"
				. " VALUES (:task, UNIX_TIMESTAMP(), :callback, :args)", $data, true) !== false) {
			return;
		}
		// Most likely the args column is missing - try to add it on-the-fly so the update routine can properly
		// use it (confmod updates - otherwise the status of modules is not updated properly)
		Database::exec("ALTER TABLE `callback` ADD `args` TEXT NOT NULL DEFAULT ''", array(), true);
		Database::exec("INSERT INTO callback (taskid, dateline, cbfunction, args)"
			. " VALUES (:task, UNIX_TIMESTAMP(), :callback, :args)", $data);
	}

	/**
	 * Get all pending callbacks from the callback table.
	 *
	 * @return array list of array(taskid => list of callbacks)
	 */
	public static function getPendingCallbacks(): array
	{
		$res = Database::simpleQuery("SELECT taskid, cbfunction, args FROM callback", array(), true);
		if ($res === false)
			return array();
		$retval = array();
		foreach ($res as $row) {
			$retval[$row['taskid']][] = $row;
		}
		return $retval;
	}

	/**
	 * Handle the given callback. Will delete the entry from the callback
	 * table if appropriate.
	 * 
	 * @param array $callback entry from the callback table (cbfunction + taskid + args)
	 * @param ?array $status status of the task as returned by the taskmanager. If NULL it will be queried.
	 */
	public static function handleCallback(array $callback, array $status = NULL): void
	{
		if (is_null($status))
			$status = Taskmanager::status($callback['taskid']);
		if ($status === false) // No reply from Taskmanager, retry later
			return;
		if (Taskmanager::isFailed($status) || Taskmanager::isFinished($status)) {
			$del = Database::exec("DELETE FROM callback WHERE taskid = :task AND cbfunction = :cb LIMIT 1", array('task' => $callback['taskid'], 'cb' => $callback['cbfunction']));
			if ($del === 0) { // No entry deleted, so someone else must have deleted it - race condition, do nothing
				return;
			}
		}
		if (Taskmanager::isFinished($status)) {
			Taskmanager::release($status);
			$func = array('TaskmanagerCallback', preg_replace('/\W/', '', $callback['cbfunction']));
			if (!call_user_func_array('method_exists', $func)) {
				Eventlog::warning("handleCallback: Callback {$callback['cbfunction']} doesn't exist.");
			} else {
				if (empty($callback['args']))
					call_user_func($func, $status, null);
				else
					call_user_func($func, $status, unserialize($callback['args']));
			}
		}
	}

	// ####################################################################

	/**
	 * Result of trying to (re)launch ldadp.
	 */
	public static function ldadpStartup(array $task)
	{
		if (Taskmanager::isFailed($task)) {
			if (!isset($task['data']['messages'])) {
				$task['data']['messages'] = '';
			}
			EventLog::warning("Could not start/stop LDAP-AD-Proxy instances", $task['data']['messages']);
		}
	}

	/**
	 * Result of restoring the server configuration
	 */
	public static function dbRestored(array $task)
	{
		if (!Taskmanager::isFailed($task)) {
			EventLog::info('Configuration backup restored.');
		}
	}
	
	public static function adConfigCreate(array $task)
	{
		if (Taskmanager::isFailed($task))
			EventLog::warning("Could not generate Active Directory configuration", $task['data']['error']);
	}
	
	/**
	 * Generating a config module has finished.
	 *
	 * @param array $task task obj
	 * @param array $args has keys 'moduleid' and optionally 'deleteOnError' and 'tmpTgz'
	 */
	public static function cbConfModCreated(array $task, array $args)
	{
		$mod = Module::get('sysconfig');
		if ($mod === false)
			return;
		$mod->activate(1, false);
		if (Taskmanager::isFailed($task)) {
			ConfigModule::generateFailed($task, $args);
		} else {
			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(array $task, array $args)
	{
		$mod = Module::get('sysconfig');
		if ($mod === false)
			return;
		$mod->activate(1, false);
		if (Taskmanager::isFailed($task)) {
			ConfigTgz::generateFailed($task, $args);
		} else {
			ConfigTgz::generateSucceeded($task, $args);
		}
	}
	
	public static function manualMount(array $task, $args)
	{
		if (!isset($task['data']['exitCode']))
			return;
		if ($task['data']['exitCode'] == 0) {
			// Success - store configuration
			Property::setVmStoreConfig($args);
			return;
		}
		// If code is 99 then the script failed to even unmount -- don't change anything
		if ($task['data']['exitCode'] != 99) {
			// Manual mount failed with non-taskmanager related error - reset storage type to reflect situation
			$data = Property::getVmStoreConfig();
			if (isset($data['storetype'])) {
				unset($data['storetype']);
				Property::setVmStoreConfig($data);
			}
		}
	}

	public static function mlGotList(array $task, $args)
	{
		$mod = Module::get('minilinux');
		if ($mod === false)
			return;
		$mod->activate(1, false);
		MiniLinux::listDownloadCallback($task, $args);
	}

	public static function mlGotLinux(array $task, $args)
	{
		$mod = Module::get('minilinux');
		if ($mod === false)
			return;
		$mod->activate(1, false);
		MiniLinux::linuxDownloadCallback($task, $args);
	}

	public static function rbcConnCheck(array $task, $args)
	{
		$mod = Module::get('rebootcontrol');
		if ($mod === false)
			return;
		$mod->activate(1, false);
		RebootControl::connectionCheckCallback($task, $args);
	}

	public static function ipxeVersionSet(array $task)
	{
		$mod = Module::get('serversetup');
		if ($mod === false)
			return;
		$mod->activate(1, false);
		IPxeBuilder::setIPxeVersionCallback($task);
	}

	public static function ipxeCompileDone(array $task)
	{
		$mod = Module::get('serversetup');
		if ($mod === false)
			return;
		$mod->activate(1, false);
		IPxeBuilder::compileCompleteCallback($task);
	}

	public static function ssUpgradable(array $task): void
	{
		$mod = Module::get('systemstatus');
		if ($mod === false)
			return;
		$mod->activate(1, false);
		SystemStatus::setUpgradableData($task);
	}

	public static function acmeErrors(array $task, $args): void
	{
		$mod = Module::get('webinterface');
		if ($mod === false)
			return;
		$mod->activate(1, false);
		Acme::callbackErrorCheck($task, $args);
	}

	public static function webifCert(array $task, $args): void
	{
		$mod = Module::get('webinterface');
		if ($mod === false)
			return;
		$mod->activate(1, false);
		WebInterface::certTaskFinishedCallback($task, $args);
	}

}