1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
<?php
/**
* 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, $callback, $args = NULL)
{
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");
return;
}
$data = array(
'task' => $task,
'callback' => $callback,
);
if (Property::getCurrentSchemaVersion() >= 9) {
if (is_null($args))
$data['args'] = '';
else
$data['args'] = serialize($args);
Database::exec("INSERT INTO callback (taskid, dateline, cbfunction, args) VALUES (:task, UNIX_TIMESTAMP(), :callback, :args)", $data);
} else {
Database::exec("INSERT INTO callback (taskid, dateline, cbfunction) VALUES (:task, UNIX_TIMESTAMP(), :callback)", $data);
}
Property::setNeedsCallback(1);
}
/**
* Get all pending callbacks from the callback table.
*
* @return array list of array(taskid => list of callbacks)
*/
public static function getPendingCallbacks()
{
if (Property::getCurrentSchemaVersion() < 9)
return array();
$retval = array();
$res = Database::simpleQuery("SELECT taskid, cbfunction, args FROM callback");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$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($callback, $status = NULL)
{
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)) {
$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);
else
call_user_func($func, $status, unserialize($callback['args']));
}
}
}
// ####################################################################
/**
* Result of trying to (re)launch ldadp.
*/
public static function ldadpStartup($task)
{
if (Taskmanager::isFailed($task))
EventLog::warning("Could not start/stop LDAP-AD-Proxy instances", $task['data']['messages']);
}
/**
* Result of restoring the server configuration
*/
public static function dbRestored($task)
{
if (!Taskmanager::isFailed($task)) {
EventLog::info('Configuration backup restored.');
}
}
public static function adConfigCreate($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($task, $args)
{
if (Taskmanager::isFailed($task)) {
ConfigModule::generateFailed($task, $args);
} else {
ConfigModule::generateSucceeded($args);
}
}
}
|