source: admin/WebConsole/rest/remotepc.php @ 8b1c92b

918-git-images-111dconfigfileconfigure-oglivegit-imageslgromero-new-oglivemainmaint-cronmount-efivarfsmultivmmultivm-ogboot-installerogClonningEngineogboot-installer-jenkinsoglive-ipv6test-python-scriptsticket-301ticket-50ticket-50-oldticket-577ticket-585ticket-611ticket-612ticket-693ticket-700ubu24tplunification2use-local-agent-oglivevarios-instalacion
Last change on this file since 8b1c92b was 0f21492, checked in by Ramón M. Gómez <ramongomez@…>, 6 years ago

#839: Reservation (power-on) operation is also sent to client repository (as in e57b608 commit).

  • Property mode set to 100644
File size: 20.7 KB
RevLine 
[e0b6a5e]1<?php
2/**
3 * @file    remotepc.php
4 * @brief   OpenGnsys Server REST API consumed by UDS Server for Remote PC implementation.
5 * @warning All input and output messages are formatted in JSON.
6 * @note    Some ideas are based on article "How to create REST API for Android app using PHP, Slim and MySQL" by Ravi Tamada, thanx.
7 * @license GNU GPLv3+
8 * @author  Ramón M. Gómez, ETSII Univ. Sevilla
9 * @version 1.1.0 - First version
10 * @date    2017-02-01
11 */
12
[4073d14]13// OGAgent sessions log file.
14define('REMOTEPC_LOGFILE', '/opt/opengnsys/log/remotepc.log');
15
16// Function to write a line into log file.
17function writeRemotepcLog($message = "") {
18        file_put_contents(REMOTEPC_LOGFILE, date(DATE_ISO8601).": $message\n", FILE_APPEND);
19}
20
[e0b6a5e]21
22// REST routes.
23
24/**
[63e439a]25 * @brief    Reserve a client with an installed image and the older reservation time, then send a boot/reboot operation depending on its status.
[9ed6a67]26 * @warning  If "lab" parameter is specified, then choose a client from this lab.
[63e439a]27 * @note     Route: /ous/:ouid/images/:imageid/reserve, Method: POST
[9a39c75]28 * @param    integer ouid      OU identificator
29 * @param    integer imageid   image identificator
[63e439a]30 * @note     Input JSON message: {"labid":int_labid,"maxtime":int_hours}
[e0b6a5e]31 */
[d8b6c70]32$app->post('/ous/:ouid/images/:imageid/reserve(/)', 'validateApiKey',
[e0b6a5e]33    function($ouid, $imageid) use ($app) {
34        global $cmd;
35        global $AMBITO_ORDENADORES;
36        global $EJECUCION_COMANDO;
37        global $ACCION_INICIADA;
[232d1da]38        global $ACCION_FINALIZADA;
[e0b6a5e]39        global $ACCION_SINRESULTADO;
[232d1da]40        global $ACCION_FALLIDA;
[e0b6a5e]41        global $userid;
[6f17d76]42        $response = Array();
43        $ogagent = Array();
[0f21492]44        $repo = Array();
[e0b6a5e]45
[4073d14]46        if ($app->settings['debug'])
47                writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
[e0b6a5e]48        // Checking parameters.
[d8b6c70]49        try {
[4073d14]50                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
51                        throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
52                }
[2f11053]53                if (!checkIds($ouid, $imageid)) {
[d8b6c70]54                        throw new Exception("Ids. must be positive integers");
55                }
56                // Reading POST parameters in JSON format.
57                $input = json_decode($app->request()->getBody());
[2f11053]58                // Default: no lab. filter.
59                if (isset($input->labid)) {
60                        $labid = $input->labid != "0" ? $input->labid : '%';
61                } else {
62                        $labid = '%';
63                }
[d8b6c70]64                $maxtime = isset($input->maxtime) ? $input->maxtime : 24;       // Default: 24 h.
[2f11053]65                $opts = Array('options' => Array('min_range' => 1));    // Check for int>0
[4705afe]66                if (filter_var($labid, FILTER_VALIDATE_INT, $opts) === false and $labid !== '%') {
[d8b6c70]67                        throw new Exception("Lab id. must be positive integer");
68                }
[4705afe]69                if (filter_var($maxtime, FILTER_VALIDATE_INT, $opts) === false) {
[d8b6c70]70                        throw new Exception("Time must be positive integer (in hours)");
71                }
72        } catch (Exception $e) {
73                // Communication error.
74                $response["message"] = $e->getMessage();
[4073d14]75                if ($app->settings['debug'])
76                        writeRemotepcLog($app->request()->getResourceUri(). ": ERROR: ".$response["message"].".");
[d8b6c70]77                jsonResponse(400, $response);
78                $app->stop();
79        }
[4073d14]80
81        if ($app->settings['debug'])
82                writeRemotepcLog($app->request()->getResourceUri(). ": Parameters: labid=$labid, maxtime=$maxtime");
[63e439a]83        // Choose older not-reserved client with image installed and get ogAdmServer data.
[e0b6a5e]84        $cmd->texto = <<<EOD
[9199fc7]85SELECT adm.idusuario, entornos.ipserveradm, entornos.portserveradm,
[d8b6c70]86       ordenadores.idordenador, ordenadores.nombreordenador, ordenadores.ip,
[0f21492]87       ordenadores.mac, ordenadores.agentkey, par.numdisk, par.numpar,
88       aulas.idaula, aulas.idcentro, repo.ip AS repoip, repo.apikey AS repokey
[e0b6a5e]89  FROM entornos, ordenadores
90  JOIN aulas USING(idaula)
[e7d47882]91 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[e0b6a5e]92 RIGHT JOIN usuarios USING(idusuario)
[0f21492]93 RIGHT JOIN ordenadores_particiones AS par USING(idordenador)
[e0b6a5e]94 RIGHT JOIN imagenes USING(idimagen)
[0f21492]95 RIGHT JOIN repositorios AS repo ON repo.idrepositorio = ordenadores.idrepositorio
[6f17d76]96  LEFT JOIN remotepc ON remotepc.id=ordenadores.idordenador
[9199fc7]97 WHERE adm.idusuario = '$userid'
[9a39c75]98   AND aulas.idcentro = '$ouid' AND aulas.idaula LIKE '$labid' AND aulas.inremotepc = 1
99   AND imagenes.idimagen = '$imageid' AND imagenes.inremotepc = 1
[35a63b6]100   AND (remotepc.reserved < NOW() OR ISNULL(reserved))
[63e439a]101 ORDER BY remotepc.reserved ASC LIMIT 1;
[e0b6a5e]102EOD;
103        $rs=new Recordset;
104        $rs->Comando=&$cmd;
105        if (!$rs->Abrir()) return(false);       // Error opening recordset.
[e7d47882]106        // Check if user is admin and client exists.
[e0b6a5e]107        $rs->Primero();
[9199fc7]108        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) {
[2f11053]109                // Read query data.
110                $serverip = $rs->campos["ipserveradm"];
111                $serverport = $rs->campos["portserveradm"];
112                $clntid = $rs->campos["idordenador"];
113                $clntname = $rs->campos["nombreordenador"];
114                $clntip = $rs->campos["ip"];
115                $clntmac = $rs->campos["mac"];
116                $agentkey = $rs->campos["agentkey"];
117                $disk = $rs->campos["numdisk"];
118                $part = $rs->campos["numpar"];
119                $labid = $rs->campos["idaula"];
120                $ouid = $rs->campos["idcentro"];
[0f21492]121                $repoip = $rs->campos["repoip"];
122                $repokey = $rs->campos["repokey"];
[2f11053]123                // Check client's status.
124                $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/status";
[4073d14]125                if ($app->settings['debug'])
126                        writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent status, url=".$ogagent[$clntip]['url'].".");
[2f11053]127                $result = multiRequest($ogagent);
128                if (empty($result[$clntip]['data'])) {
129                        // Client is off, send a boot command to ogAdmServer.
130                        // TODO: if client is busy?????
131                        $reqframe = "nfn=Arrancar\r".
132                                    "ido=$clntid\r".
133                                    "iph=$clntip\r".
134                                    "mac=$clntmac\r".
135                                    "mar=1\r";
[4073d14]136                        if ($app->settings['debug'])
137                                writeRemotepcLog($app->request()->getResourceUri(). "Send Boot command to ogAdmClient, ido=$clntid,iph=$clntip,mac=$clntmac.");
[2f11053]138                        sendCommand($serverip, $serverport, $reqframe, $values);
[0f21492]139                        // Send WOL command to client repository.
140                        $repo[$repoip]['url'] = "https://$repoip/opengnsys/rest/repository/poweron";
141                        $repo[$repoip]['header'] = Array("Authorization: ".$repokey);
142                        $repo[$repoip]['post'] = '{"macs": ["'.$clntmac.'"], "ips": ["'.$clntip.'"]}';
143                        if ($app->settings['debug'])
144                                writeRemotepcLog($app->request()->getResourceUri(). "Send Boot command to repo: repo=$repoip, ip=$clntip,mac=$clntmac.");
145                        $result = multiRequest($repo);
146                        // ... (check response)
147                        //if ($result[$repoip]['code'] != 200) {
148                        // ...
[2f11053]149                } else {
[4073d14]150                        // Client is on, send a rieboot command to its OGAgent.
[2f11053]151                        $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/reboot";
152                        $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey);
[4073d14]153                        if ($app->settings['debug'])
154                                writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent reboot, url=".$ogagent[$clntip]['url'].".");
[6f17d76]155                        $result = multiRequest($ogagent);
[2f11053]156                        // ... (check response)
157                        //if ($result[$clntip]['code'] != 200) {
158                        // ...
159                }
160                // DB Transaction: mark choosed client as reserved and
161                // create an init session command into client's actions queue.
162                $cmd->texto = "START TRANSACTION;";
163                $cmd->Ejecutar();
164                $timestamp = time();
165                $cmd->texto = <<<EOD
[e0b6a5e]166INSERT INTO remotepc
[d8b6c70]167   SET id='$clntid', reserved=NOW() + INTERVAL $maxtime HOUR, urllogin=NULL, urllogout=NULL
[6f17d76]168    ON DUPLICATE KEY UPDATE
[e0b6a5e]169       id=VALUES(id), reserved=VALUES(reserved),
[6f17d76]170       urllogin=VALUES(urllogin), urllogout=VALUES(urllogout);
171EOD;
[2f11053]172                $t1 = $cmd->Ejecutar();
173                $cmd->texto = <<<EOD
[e0b6a5e]174INSERT INTO acciones
175   SET tipoaccion=$EJECUCION_COMANDO,
176       idtipoaccion=9,
177       idcomando=9,
[6f17d76]178       parametros='nfn=IniciarSesion\rdsk=$disk\rpar=$part',
[e0b6a5e]179       descriaccion='RemotePC Session',
[6f17d76]180       idordenador=$clntid,
181       ip='$clntip',
182       sesion=$timestamp,
[e0b6a5e]183       fechahorareg=NOW(),
184       estado=$ACCION_INICIADA,
185       resultado=$ACCION_SINRESULTADO,
186       ambito=$AMBITO_ORDENADORES,
[6f17d76]187       idambito=$clntid,
188       restrambito='$clntip',
[e0b6a5e]189       idcentro=$ouid;
[9a39c75]190EOD;
[2f11053]191                $t2 = $cmd->Ejecutar();
[232d1da]192                // Create event to remove reservation on timeout (15 min.).
[0c9d25a]193                $timeout = "15 MINUTE";
194                $cmd->texto = <<<EOD
195CREATE EVENT e_timeout_$clntid
196       ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL $timeout DO
197       BEGIN
[232d1da]198            SET @clntid = NULL;
[0c9d25a]199            UPDATE acciones
200               SET estado = $ACCION_FINALIZADA, resultado = $ACCION_FALLIDA,
201                   descrinotificacion = 'Timeout'
[232d1da]202             WHERE descriaccion = 'RemotePC Session' AND estado = $ACCION_INICIADA
203               AND idordenador = (SELECT @clntid := '$clntid');
[0c9d25a]204            IF @clntid IS NOT NULL THEN
205               UPDATE remotepc
206                  SET reserved=NOW() - INTERVAL 1 SECOND, urllogin=NULL, urllogout=NULL
207                WHERE id = @clntid;
[232d1da]208               DELETE FROM acciones
209                WHERE idordenador = @clntid
210                  AND descriaccion = 'RemotePC Session'
211                  AND descrinotificacion = 'Timeout';
212            END IF;
[0c9d25a]213       END
214EOD;
215                $t3 = $cmd->Ejecutar();
[232d1da]216                if ($t1 and $t2 and $t3) {
[2f11053]217                        // Commit transaction on success.
218                        $cmd->texto = "COMMIT;";
219                        $cmd->Ejecutar();
[4073d14]220                        if ($app->settings['debug'])
221                                writeRemotepcLog($app->request()->getResourceUri(). ": DB tables and events updated, clntid=$clntid.");
[2f11053]222                        // Send init session command if client is booted on ogLive.
223                        $reqframe = "nfn=IniciarSesion\r".
224                                    "ido=$clntid\r".
225                                    "iph=$clntip\r".
226                                    "dsk=$disk\r".
227                                    "par=$part\r";
[4073d14]228                        if ($app->settings['debug'])
229                                writeRemotepcLog($app->request()->getResourceUri(). ": Send Init Session command to ogAdmClient, ido=$clntid,iph=$clntip,dsk=$disk,par=$part.");
[2f11053]230                        sendCommand($serverip, $serverport, $reqframe, $values);
231                        // Compose JSON response.
[ffaf580]232                        $response['id'] = (int)$clntid;
[2f11053]233                        $response['name'] = $clntname;
234                        $response['ip'] = $clntip;
235                        $response['mac'] = $clntmac;
236                        $response['lab']['id'] = $labid;
[ffaf580]237                        $response['ou']['id'] = (int)$ouid;
[4073d14]238                        if ($app->settings['debug'])
239                                writeRemotepcLog($app->request()->getResourceUri(). ": Response, ".var_export($response,true).".");
[2f11053]240                        jsonResponse(200, $response);
[232d1da]241                } else {
[2f11053]242                        // Roll-back transaction on DB error.
243                        $cmd->texto = "ROLLBACK;";
244                        $cmd->Ejecutar();
[9a39c75]245                        // Error message.
[4073d14]246                        $response["message"] = "Database error: $t1, $t2, $t3";
247                        if ($app->settings['debug'])
248                                writeRemotepcLog($app->request()->getResourceUri(). ": ERROR: ".$response["message"].".");
[9a39c75]249                        jsonResponse(400, $response);
250                }
[4073d14]251        } else {
252                if ($app->settings['debug'])
253                        writeRemotepcLog($app->request()->getResourceUri(). ": UNASSIGNED");
[9ed6a67]254        }
[e0b6a5e]255        $rs->Cerrar();
[a38cb26]256        $app->stop();
[e0b6a5e]257    }
258);
259
260
261/**
262 * @brief    Store UDS server URLs to resend some events recieved from OGAgent.
263 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/events, Method: POST
264 * @param    string urlLogin   URL to redirect login notification.
265 * @param    string urlLogout  URL to redirect logout notification.
266 * @warning  Events parameters will be stored in a new "remotepc" table.
267 */
268$app->post('/ous/:ouid/labs/:labid/clients/:clntid/events', 'validateApiKey',
269    function($ouid, $labid, $clntid) use ($app) {
270        global $cmd;
271        global $userid;
[6f17d76]272        $response = Array();
[e0b6a5e]273
[4073d14]274        if ($app->settings['debug'])
275                writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
[d8b6c70]276        // Checking parameters.
[e0b6a5e]277        try {
[4073d14]278                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
279                        throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
280                }
[2f11053]281                if (!checkIds($ouid, $labid, $clntid)) {
[d8b6c70]282                        throw new Exception("Ids. must be positive integers");
283                }
284                // Reading JSON parameters.
[e0b6a5e]285                $input = json_decode($app->request()->getBody());
286                $urlLogin = htmlspecialchars($input->urlLogin);
287                $urlLogout = htmlspecialchars($input->urlLogout);
[4705afe]288                if (filter_var($urlLogin, FILTER_VALIDATE_URL) === false) {
[d8b6c70]289                        throw new Exception("Must be a valid URL for login notification");
290                }
[4705afe]291                if (filter_var($urlLogout, FILTER_VALIDATE_URL) === false) {
[d8b6c70]292                        throw new Exception("Must be a valid URL for logout notification");
293                }
[e0b6a5e]294        } catch (Exception $e) {
295                // Error message.
296                $response["message"] = $e->getMessage();
[4073d14]297                if ($app->settings['debug'])
298                        writeRemotepcLog($app->request()->getResourceUri(). ": ERROR: ".$response["message"].".");
[e0b6a5e]299                jsonResponse(400, $response);
300                $app->stop();
301        }
302
[4073d14]303        if ($app->settings['debug'])
304                writeRemotepcLog($app->request()->getResourceUri(). ": Parameters: urlLogin=$urlLogin, urlLogout=$urlLogout");
[e0b6a5e]305        // Select client data for UDS compatibility.
306        $cmd->texto = <<<EOD
[9199fc7]307SELECT adm.idusuario, ordenadores.idordenador, remotepc.*
[e0b6a5e]308  FROM remotepc
309 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
310  JOIN aulas USING(idaula)
[e7d47882]311 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[e0b6a5e]312 RIGHT JOIN usuarios USING(idusuario)
[9199fc7]313 WHERE adm.idusuario = '$userid'
[e0b6a5e]314   AND idcentro = '$ouid' AND aulas.idaula ='$labid'
315   AND ordenadores.idordenador = '$clntid';
316EOD;
317        $rs=new Recordset;
318        $rs->Comando=&$cmd;
319        if (!$rs->Abrir()) return(false);       // Error opening recordset.
[e7d47882]320        // Check if user is admin and client exists.
[e0b6a5e]321        $rs->Primero();
[9199fc7]322        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) {
[e0b6a5e]323                // Check if client is reserved.
[d8b6c70]324                if (! is_null($rs->campos["reserved"])) {
[9a39c75]325                        // Updating DB if client is reserved.
[d7352ab]326                        $cmd->CreaParametro("@urllogin", $urlLogin, 0);
327                        $cmd->CreaParametro("@urllogout", $urlLogout, 0);
[e0b6a5e]328                        $cmd->texto = <<<EOD
[63e439a]329UPDATE remotepc
330   SET urllogin=@urllogin, urllogout=@urllogout
331 WHERE id='$clntid';
[9a39c75]332EOD;
[d7352ab]333                        if ($cmd->Ejecutar()) {
334                                // Confirm operation.
[ffaf580]335                                $response = "";
336                                jsonResponse(200, $response);
[d7352ab]337                        } else {
338                                // Error message.
339                                $response["message"] = "Database error";
340                                jsonResponse(400, $response);
341                        }
[e0b6a5e]342                } else {
343                        // Error message.
[9a39c75]344                        $response["message"] = "Client is not reserved";
[e0b6a5e]345                        jsonResponse(400, $response);
346                }
347        }
348        $rs->Cerrar();
[a38cb26]349        $app->stop();
[e0b6a5e]350    }
351);
352
353
[4073d14]354/*
355 * @brief    Store session time (in sec).
356 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/session, Method: POST
[61e5ebd]357 * @param    int    deadLine   maximum session time, in seconds (0 for unlimited)
[4073d14]358 * @warning  Parameters will be stored in a new "remotepc" table.
359 */
[e0b6a5e]360$app->post('/ous/:ouid/labs/:labid/clients/:clntid/session', 'validateApiKey',
[4073d14]361    function($ouid, $labid, $clntid) use ($app) {
362        global $cmd;
363        global $userid;
364        $response = Array();
365
366        if ($app->settings['debug'])
367                writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
368        // Checking parameters.
369        try {
370                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
371                        throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
372                }
373                if (!checkIds($ouid, $labid, $clntid)) {
374                        throw new Exception("Ids. must be positive integers");
375                }
376                // Reading JSON parameters.
377                $input = json_decode($app->request()->getBody());
378                $deadLine = $input->deadLine;
[4705afe]379                if (filter_var($deadLine, FILTER_VALIDATE_INT) === false) {
[4073d14]380                        throw new Exception("Deadline must be integer");
381                }
[61e5ebd]382                if ($deadLine < 0) {
[23b08a8]383                        throw new Exception("Resource unavailable");
384                }
[4073d14]385        } catch (Exception $e) {
386                // Error message.
387                $response["message"] = $e->getMessage();
388                if ($app->settings['debug'])
389                        writeRemotepcLog($app->request()->getResourceUri(). ": ERROR: ".$response["message"].".");
390                jsonResponse(400, $response);
391                $app->stop();
392        }
393
394        if ($app->settings['debug'])
395                writeRemotepcLog($app->request()->getResourceUri(). ": Parameters: deadLine=$deadLine");
[a38cb26]396        // Get client's data.
397        $cmd->texto = <<<EOD
[9199fc7]398SELECT adm.idusuario, ordenadores.idordenador, remotepc.*
[a38cb26]399  FROM remotepc
400 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
401  JOIN aulas USING(idaula)
402 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[9199fc7]403 WHERE adm.idusuario = '$userid'
[a38cb26]404   AND aulas.idcentro = '$ouid' AND aulas.idaula = '$labid'
405   AND ordenadores.idordenador = '$clntid';
406EOD;
407        $rs=new Recordset;
408        $rs->Comando=&$cmd;
409        if (!$rs->Abrir()) return(false);       // Error opening recordset.
410        // Check if user is admin and client exists.
411        $rs->Primero();
[9199fc7]412        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) {
[a38cb26]413                // Check if client is reserved.
[6c2501e]414                if (! is_null($rs->campos["urllogin"])) {
[a38cb26]415                        // Read query data.
416                        $clntid = $rs->campos["idordenador"];
417                        # Removing previous commands from OGAgent operations queue.
418                        if ($app->settings['debug'])
419                                writeRemotepcLog($app->request()->getResourceUri(). ": Updating database.");
420                        $cmd->texto = <<<EOD
421DELETE FROM ogagent_queue
[9240a63]422 WHERE clientid = '$clntid' AND operation IN ('popup-10', 'popup-5', 'poweroff');
[a38cb26]423EOD;
424                        $cmd->Ejecutar();
425                        # Add new commands to OGAgent operations queue.
[399af4d]426                        $cmd->texto = "INSERT INTO ogagent_queue (clientid, exectime, operation) VALUES";
[a38cb26]427                        if ($deadLine > 600) {
428                                # Add reminder 10 min. before deadline.
429                                $cmd->texto .= " ($clntid, NOW() + INTERVAL $deadLine SECOND - INTERVAL 10 MINUTE, 'popup-10'),";
430                        }
431                        if ($deadLine > 300) {
432                                # Add reminder 5 min. before deadline.
433                                $cmd->texto .= " ($clntid, NOW() + INTERVAL $deadLine SECOND - INTERVAL 5 MINUTE, 'popup-5'),";
434                        }
[23b08a8]435                        # Add power off command at deadline time.
436                        $cmd->texto .= " ($clntid, NOW() + INTERVAL $deadLine SECOND, 'poweroff');";
[61e5ebd]437                        if ($deadLine == 0 or $cmd->Ejecutar()) {
[23b08a8]438                                // Confirm operation.
[61e5ebd]439                                $cmd->texto = "";
[ffaf580]440                                $response = "";
441                                jsonResponse(200, $response);
[61e5ebd]442                        } else {
[23b08a8]443                                // Error message.
444                                $response["message"] = "Database error";
445                                jsonResponse(400, $response);
[a38cb26]446                        }
447                } else {
448                        // Error message.
449                        $response["message"] = "Client is not reserved";
450                        jsonResponse(400, $response);
451                }
[61e5ebd]452        } else {
[a38cb26]453                // Error message.
454                $response["message"] = "Client does not exist";
455                jsonResponse(404, $response);
456        }
457        $rs->Cerrar();
[e0b6a5e]458    }
459);
460
461
[4073d14]462/**
463 * @brief    Store UDS server URLs to resend some events recieved from OGAgent.
464 * @brief    Unreserve a client and send a poweroff operation.
465 * @note     Route: /ous/:ouid/labs/:labid/clients/:clntid/unreserve, Method: DELETE
466 */
[9a39c75]467$app->delete('/ous/:ouid/labs/:labid/clients/:clntid/unreserve', 'validateApiKey',
[4073d14]468    function($ouid, $labid, $clntid) use ($app) {
[e0b6a5e]469        global $cmd;
470        global $userid;
[d7352ab]471        global $ACCION_INICIADA;
[9ed6a67]472        $response = Array();
473        $ogagent = Array();
[e0b6a5e]474
[4073d14]475        if ($app->settings['debug'])
476                writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
[9ed6a67]477        // Checking parameters.
[d8b6c70]478        try {
[a237bd1]479                if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
480                        throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
481                }
[4073d14]482                if (!checkIds($ouid, $labid, $clntid)) {
483                        throw new Exception("Ids. must be positive integers");
484                }
[d8b6c70]485        } catch (Exception $e) {
486                // Error message.
487                $response["message"] = $e->getMessage();
[4073d14]488                if ($app->settings['debug'])
489                        writeRemotepcLog($app->request()->getResourceUri(). ": ERROR: ".$response["message"].".");
[d8b6c70]490                jsonResponse(400, $response);
491                $app->stop();
492        }
493
[9ed6a67]494        // Select client data for UDS compatibility.
495        $cmd->texto = <<<EOD
[9199fc7]496SELECT adm.idusuario, ordenadores.idordenador, ordenadores.ip, ordenadores.agentkey, remotepc.reserved
[9ed6a67]497  FROM remotepc
498 RIGHT JOIN ordenadores ON remotepc.id=ordenadores.idordenador
499  JOIN aulas USING(idaula)
[e7d47882]500 RIGHT JOIN administradores_centros AS adm USING(idcentro)
[9ed6a67]501 RIGHT JOIN usuarios USING(idusuario)
[9199fc7]502 WHERE adm.idusuario = '$userid'
[9ed6a67]503   AND idcentro = '$ouid' AND aulas.idaula ='$labid'
504   AND ordenadores.idordenador = '$clntid';
505EOD;
506        $rs=new Recordset;
507        $rs->Comando=&$cmd;
508        if (!$rs->Abrir()) return(false);       // Error opening recordset.
[e7d47882]509        // Check if user is admin and client exists.
[9ed6a67]510        $rs->Primero();
[9199fc7]511        if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) {
[9ed6a67]512                // Check if client is reserved.
[d8b6c70]513                if (! is_null($rs->campos["reserved"])) {
[9ed6a67]514                        // Read query data.
[40db2a3]515                        $clntip = $rs->campos["ip"];
[9ed6a67]516                        $agentkey = $rs->campos["agentkey"];
[63e439a]517                        // DB Transaction: set reservation time to the past and
[8182ab14]518                        // remove pending boot commands from client's and agent's queues.
[1d76269]519                        if ($app->settings['debug'])
520                                writeRemotepcLog($app->request()->getResourceUri(). ": Updating database.");
[9ed6a67]521                        $cmd->texto = "START TRANSACTION;";
522                        $cmd->Ejecutar();
523                        $cmd->texto = <<<EOD
524UPDATE remotepc
[63e439a]525   SET reserved=NOW() - INTERVAL 1 SECOND, urllogin=NULL, urllogout=NULL
[9ed6a67]526 WHERE id='$clntid';
527EOD;
528                        $cmd->Ejecutar();
529                        $cmd->texto = <<<EOD
530DELETE FROM acciones
531 WHERE idordenador = '$clntid'
[35a63b6]532   AND descriaccion = 'RemotePC Session';
[9ed6a67]533EOD;
534                        $cmd->Ejecutar();
[8182ab14]535                        $cmd->texto = <<<EOD
536DELETE FROM ogagent_queue
537 WHERE clientid = '$clntid' AND command IN ('popup-10', 'popup-5', 'poweroff');
[1b7c102]538EOD;
[8182ab14]539                        $cmd->Ejecutar();
[9ed6a67]540                        $cmd->texto = "COMMIT;";
541                        $cmd->Ejecutar();
542                        // Send a poweroff command to client's OGAgent.
543                        $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/poweroff";
544                        $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey);
[23b08a8]545                        if ($app->settings['debug'])
546                                writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent poweroff, url=".$ogagent[$clntip]['url'].".");
[9ed6a67]547                        $result = multiRequest($ogagent);
548                        // ... (check response)
[357352b]549                        //if ($result[$clntip]['code'] != 200) {
[9ed6a67]550                        // ...
551                        // Confirm operation.
[ffaf580]552                        $response = "";
553                        jsonResponse(200, $response);
[a38cb26]554                } else {
[9ed6a67]555                        // Error message.
556                        $response["message"] = "Client is not reserved";
557                        jsonResponse(400, $response);
558                }
[a38cb26]559        } else {
560                // Error message.
561                $response["message"] = "Client does not exist";
562                jsonResponse(404, $response);
563        }
[9ed6a67]564        $rs->Cerrar();
[e0b6a5e]565    }
566);
567
[b6ec162]568
Note: See TracBrowser for help on using the repository browser.