summaryrefslogtreecommitdiffstats
path: root/admin/WebConsole/rest/remotepc.php
diff options
context:
space:
mode:
authorRamón M. Gómez <ramongomez@us.es>2020-09-11 11:05:33 +0200
committerRamón M. Gómez <ramongomez@us.es>2020-09-11 11:05:33 +0200
commitee80b183d90b6e05e3730813eb76386ff6377e3c (patch)
tree4589a73c3e5b484cbc760b6541dd650400c53b9e /admin/WebConsole/rest/remotepc.php
parent3cffc27097143b880b7aaf3e208f364217b57fa9 (diff)
#992: New REST route `/ous/:ouid/labs/:labid/clients/:clntid/init`
New route to boot up a computer and init session on the operating systems where the image was restored. UDS will request this route when it detects that a reserved computer is turned off.
Diffstat (limited to 'admin/WebConsole/rest/remotepc.php')
-rw-r--r--admin/WebConsole/rest/remotepc.php198
1 files changed, 172 insertions, 26 deletions
diff --git a/admin/WebConsole/rest/remotepc.php b/admin/WebConsole/rest/remotepc.php
index e11f8870..428d5252 100644
--- a/admin/WebConsole/rest/remotepc.php
+++ b/admin/WebConsole/rest/remotepc.php
@@ -39,13 +39,13 @@ $app->post('/ous/:ouid/images/:imageid/reserve(/)', 'validateApiKey',
global $ACCION_SINRESULTADO;
global $ACCION_FALLIDA;
global $userid;
- $response = Array();
- $ogagent = Array();
- $repo = Array();
+ $response = [];
+ $ogagent = [];
+ $repo = [];
if ($app->settings['debug'])
writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
- // Checking parameters.
+ // Checking parameters.
try {
if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
@@ -120,35 +120,35 @@ EOD;
$repoip = $rs->campos["repoip"];
$repokey = $rs->campos["repokey"];
// Check client's status.
- $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/status";
+ $ogagent = [['url' => "https://$clntip:8000/opengnsys/status"]];
if ($app->settings['debug'])
- writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent status, url=".$ogagent[$clntip]['url'].".");
+ writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent status, url=".$ogagent[0]['url'].".");
$result = multiRequest($ogagent);
- if (empty($result[$clntip]['data'])) {
+ if (empty($result[0]['data'])) {
// Client is off, send WOL command to ogAdmServer.
// TODO: if client is busy?????
if ($app->settings['debug'])
writeRemotepcLog($app->request()->getResourceUri(). ": Send boot command through ogAdmServer: iph=$clntip,mac=$clntmac.");
wol(1, [$clntmac], [$clntip], [$clntnetmask]);
// Send WOL command to client repository.
- $repo[$repoip]['url'] = "https://$repoip/opengnsys/rest/repository/poweron";
- $repo[$repoip]['header'] = Array("Authorization: ".$repokey);
- $repo[$repoip]['post'] = '{"macs": ["'.$clntmac.'"], "ips": ["'.$clntip.'"]}';
+ $repo = [['url' => "https://$repoip/opengnsys/rest/repository/poweron",
+ 'header' => ["Authorization: $repokey"],
+ 'post' => '{"macs": ["'.$clntmac.'"], "ips": ["'.$clntip.'"]}']];
if ($app->settings['debug'])
- writeRemotepcLog($app->request()->getResourceUri(). ": Send Boot command through repo: repo=$repoip, ip=$clntip,mac=$clntmac.");
+ writeRemotepcLog($app->request()->getResourceUri(). ": Send Boot command through repo: repo=$repoip,ip=$clntip,mac=$clntmac.");
$result = multiRequest($repo);
// ... (check response)
- //if ($result[$repoip]['code'] != 200) {
+ //if ($result[0]['code'] != 200) {
// ...
} else {
- // Client is on, send a rieboot command to its OGAgent.
- $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/reboot";
- $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey);
+ // Client is on, send a reboot command to its OGAgent.
+ $ogagent = [['url' => "https://$clntip:8000/opengnsys/reboot",
+ 'header' => ["Authorization: ".$agentkey]]];
if ($app->settings['debug'])
- writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent reboot, url=".$ogagent[$clntip]['url'].".");
+ writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent reboot, url=".$ogagent[0]['url'].".");
$result = multiRequest($ogagent);
// ... (check response)
- //if ($result[$clntip]['code'] != 200) {
+ //if ($result[0]['code'] != 200) {
// ...
}
// DB Transaction: mark choosed client as reserved and
@@ -265,7 +265,7 @@ $app->post('/ous/:ouid/labs/:labid/clients/:clntid/events', 'validateApiKey',
if ($app->settings['debug'])
writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
- // Checking parameters.
+ // Checking parameters.
try {
if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
@@ -359,7 +359,7 @@ $app->post('/ous/:ouid/labs/:labid/clients/:clntid/session', 'validateApiKey',
if ($app->settings['debug'])
writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
- // Checking parameters.
+ // Checking parameters.
try {
if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
@@ -463,12 +463,12 @@ $app->delete('/ous/:ouid/labs/:labid/clients/:clntid/unreserve', 'validateApiKey
global $cmd;
global $userid;
global $ACCION_INICIADA;
- $response = Array();
- $ogagent = Array();
+ $response = [];
+ $ogagent = [];
if ($app->settings['debug'])
writeRemotepcLog($app->request()->getResourceUri(). ": Init.");
- // Checking parameters.
+ // Checking parameters.
try {
if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
@@ -537,13 +537,13 @@ EOD;
$cmd->texto = "COMMIT;";
$cmd->Ejecutar();
// Send a poweroff command to client's OGAgent.
- $ogagent[$clntip]['url'] = "https://$clntip:8000/opengnsys/poweroff";
- $ogagent[$clntip]['header'] = Array("Authorization: ".$agentkey);
+ $ogagent = [['url' => "https://$clntip:8000/opengnsys/poweroff",
+ 'header' => ["Authorization: ".$agentkey]]];
if ($app->settings['debug'])
- writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent poweroff, url=".$ogagent[$clntip]['url'].".");
+ writeRemotepcLog($app->request()->getResourceUri(). ": OGAgent poweroff, url=".$ogagent[0]['url'].".");
$result = multiRequest($ogagent);
// ... (check response)
- //if ($result[$clntip]['code'] != 200) {
+ //if ($result[0]['code'] != 200) {
// ...
// Confirm operation.
$response = "";
@@ -562,3 +562,149 @@ EOD;
}
);
+
+/*
+ * @brief Send an init operation to a client with an image installed.
+ * @note Route: /ous/:ouid/labs/:labid/clients/:clntid/init, Method: POST
+ * @param int image Image id.
+ */
+$app->post('/ous/:ouid/labs/:labid/clients/:clntid/init', 'validateApiKey',
+ function($ouid, $labid, $clntid) use ($app) {
+ global $cmd;
+ global $userid;
+
+ if ($app->settings['debug'])
+ writeRemotepcLog("{$app->request()->getResourceUri()}: Init.");
+ // Checking parameters.
+ try {
+ if (empty(preg_match('/^python-requests\//', $_SERVER['HTTP_USER_AGENT']))) {
+ throw new Exception("Bad agent: sender=".$_SERVER['REMOTE_ADDR'].", agent=".$_SERVER['HTTP_USER_AGENT']);
+ }
+ if (!checkIds($ouid, $labid, $clntid)) {
+ throw new Exception("Ids. must be positive integers");
+ }
+ // Reading POST parameters in JSON format.
+ $input = json_decode($app->request()->getBody());
+ $imageid = $input->image ?? 0;
+ if (filter_var($imageid, FILTER_VALIDATE_INT, $opts) === false) {
+ throw new Exception("Image id. must be positive integer");
+ }
+ } catch (Exception $e) {
+ // Communication error.
+ $response["message"] = $e->getMessage();
+ if ($app->settings['debug'])
+ writeRemotepcLog("{$app->request()->getResourceUri()}: ERROR: {$response["message"]}.");
+ jsonResponse(400, $response);
+ $app->stop();
+ }
+
+ // Select data to init a session.
+ $cmd->texto = <<<EOD
+SELECT adm.idusuario, ordenadores.ip, ordenadores.mac, ordenadores.mascara, ordenadores.agentkey,
+ par.numdisk, par.numpar, repo.ip AS repoip, repo.apikey AS repokey
+ FROM ordenadores
+ JOIN aulas USING(idaula)
+ RIGHT JOIN administradores_centros AS adm USING(idcentro)
+ RIGHT JOIN usuarios USING(idusuario)
+ RIGHT JOIN ordenadores_particiones AS par USING(idordenador)
+ RIGHT JOIN imagenes USING(idimagen)
+ RIGHT JOIN repositorios AS repo ON repo.idrepositorio = ordenadores.idrepositorio
+ LEFT JOIN remotepc ON remotepc.id=ordenadores.idordenador
+ WHERE adm.idusuario = '$userid'
+ AND aulas.idcentro = '$ouid' AND aulas.idaula LIKE '$labid'
+ AND ordenadores.idordenador = '$clntid' AND ordenadores.maintenance = 0
+ AND imagenes.idimagen = '$imageid'
+ LIMIT 1;
+EOD;
+ $rs=new Recordset;
+ $rs->Comando=&$cmd;
+ if (!$rs->Abrir()) return(false); // Error opening recordset.
+ // Check if user is admin and client exists.
+ $rs->Primero();
+ if (checkAdmin($rs->campos["idusuario"]) and checkParameter($rs->campos["idordenador"])) {
+ // Read query data.
+ $clntip = $rs->campos["ip"];
+ $clntmac = $rs->campos["mac"];
+ $clntnetmask = $rs->campos["mascara"];
+ $agentkey = $rs->campos["agentkey"];
+ $disk = $rs->campos["numdisk"];
+ $part = $rs->campos["numpar"];
+ $repoip = $rs->campos["repoip"];
+ $repokey = $rs->campos["repokey"];
+ // Check client's status.
+ $ogagent = [['url' => "https://$clntip:8000/opengnsys/status"]];
+ if ($app->settings['debug'])
+ writeRemotepcLog("{$app->request()->getResourceUri()}: OGAgent status, url={$ogagent[0]['url']}.");
+ $result = multiRequest($ogagent);
+ if (empty($result[0]['data'])) {
+ // Client is off, send WOL command to ogAdmServer.
+ // TODO: if client is busy?????
+ if ($app->settings['debug'])
+ writeRemotepcLog("{$app->request()->getResourceUri()}: Send boot command through ogAdmServer: iph=$clntip,mac=$clntmac.");
+ wol(1, [$clntmac], [$clntip], [$clntnetmask]);
+ // Send WOL command to client repository.
+ $repo = [['url' => "https://$repoip/opengnsys/rest/repository/poweron",
+ 'header' => ["Authorization: $repokey"],
+ 'post' => '{"macs": ["'.$clntmac.'"], "ips": ["'.$clntip.'"]}']];
+ if ($app->settings['debug'])
+ writeRemotepcLog("{$app->request()->getResourceUri()}: Send Boot command through repo: repo=$repoip,ip=$clntip,mac=$clntmac.");
+ $result = multiRequest($repo);
+ }
+ // Create an init session on opertions queue.
+ $cmd->texto = <<<EOD
+INSERT INTO acciones
+ SET tipoaccion=$EJECUCION_COMANDO,
+ idtipoaccion=9,
+ idcomando=9,
+ parametros='nfn=IniciarSesion\rdsk=$disk\rpar=$part',
+ descriaccion='RemotePC Session',
+ idordenador=$clntid,
+ ip='$clntip',
+ sesion=$timestamp,
+ fechahorareg=NOW(),
+ estado=$ACCION_INICIADA,
+ resultado=$ACCION_SINRESULTADO,
+ ambito=$AMBITO_ORDENADORES,
+ idambito=$clntid,
+ restrambito='$clntip',
+ idcentro=$ouid;
+EOD;
+ $cmd->Ejecutar();
+ // Create event to remove the operation on timeout (15 min.).
+ $timeout = "15 MINUTE";
+ $cmd->texto = <<<EOD
+CREATE EVENT IF NOT EXISTS e_timeout_$clntid
+ ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL $timeout DO
+ BEGIN
+ SET @action_id = NULL;
+ UPDATE acciones
+ SET estado = $ACCION_FINALIZADA, resultado = $ACCION_FALLIDA,
+ descrinotificacion = 'Timeout'
+ WHERE descriaccion = 'RemotePC Session' AND estado = $ACCION_INICIADA
+ AND idordenador = '$clntid'
+ AND (SELECT @action_id := idaccion);
+ IF @action_id IS NOT NULL THEN
+ DELETE FROM acciones
+ WHERE idaccion = @action_id;
+ END IF;
+ END
+EOD;
+ $cmd->Ejecutar();
+ if ($app->settings['debug'])
+ writeRemotepcLog("{$app->request()->getResourceUri()}: DB tables and events updated, clntid=$clntid.");
+ // Send init session command if client is booted on ogLive.
+ if ($app->settings['debug'])
+ writeRemotepcLog("{$app->request()->getResourceUri()}: Send Init Session command to ogAdmClient, ido=$clntid,iph=$clntip,dsk=$disk,par=$part.");
+ session($clntip, "$disk\r$part");
+ // Confirm operation.
+ $response = [];
+ jsonResponse(200, $response);
+ } else {
+ // Error message.
+ $response["message"] = "Client with this image not found";
+ jsonResponse(404, $response);
+ }
+ $rs->Cerrar();
+ }
+);
+