summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2020-02-26 18:05:14 +0100
committerSimon Rettberg2020-02-26 18:05:14 +0100
commit2903a586a5f19e546ed12841e0c7a170320fd82b (patch)
tree7c088143b64b1481ae7c99946c14bf59538144f6
parent[backup/systemstatus] Show up/downloads in backup page (diff)
downloadslx-admin-2903a586a5f19e546ed12841e0c7a170320fd82b.tar.gz
slx-admin-2903a586a5f19e546ed12841e0c7a170320fd82b.tar.xz
slx-admin-2903a586a5f19e546ed12841e0c7a170320fd82b.zip
[minilinux] Show warning if stage4 cannot be replicated
-rw-r--r--modules-available/minilinux/inc/minilinux.inc.php75
-rw-r--r--modules-available/minilinux/page.inc.php3
-rw-r--r--modules-available/minilinux/templates/filelist.html3
3 files changed, 81 insertions, 0 deletions
diff --git a/modules-available/minilinux/inc/minilinux.inc.php b/modules-available/minilinux/inc/minilinux.inc.php
index 7fe2035a..e79884f9 100644
--- a/modules-available/minilinux/inc/minilinux.inc.php
+++ b/modules-available/minilinux/inc/minilinux.inc.php
@@ -243,7 +243,9 @@ class MiniLinux
if ($task !== false) {
// Callback for db column
TaskmanagerCallback::addCallback($task, 'mlGotLinux', $versionid);
+ self::checkStage4($data);
}
+ // Race - someone else wrote a taskid to DB, just call self again to get that one
if ($aff === 0)
return self::downloadVersion($versionid);
return $task;
@@ -377,4 +379,77 @@ class MiniLinux
}
}
+ /**
+ * Check whether an optionally required stage4 is available.
+ * Return true if there is no stage4, otherwise check filesystem,
+ * or try to request from local dnbd3-server.
+ * @param array $data decoded data column from minilinux_version
+ * @param string[] $errors in array of error messages if not available
+ * @return bool true if stage4 is available or none required
+ */
+ public static function checkStage4($data, &$errors = false)
+ {
+ $errors = [];
+ $image = false;
+ $rid = 0;
+ foreach (['agnostic', 'efi', 'bios'] as $type) {
+ if (!isset($data[$type]) || !isset($data[$type]['commandLine']))
+ continue;
+ if (!preg_match('/\bslx\.stage4\.path=(\S+)/', $data[$type]['commandLine'], $out))
+ continue;
+ $image = $out[1];
+ if (preg_match('/\bslx\.stage4\.rid=(\d+)/', $data[$type]['commandLine'], $out)) {
+ $rid = $out[1];
+ }
+ break;
+ }
+ if ($image === false)
+ return true; // No stage4
+ if (file_exists(CONFIG_VMSTORE_DIR . '/' . $image))
+ return true; // Already exists locally
+ // Not found locally -- try to replicate
+ $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+ if ($sock === false) {
+ $errors[] = 'Error creatring socket to connect to dnbd3-server';
+ return false;
+ }
+ socket_set_option($sock, SOL_SOCKET, SO_SNDTIMEO, array('sec' => 1, 'usec' => 0));
+ socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 5, 'usec' => 0));
+ if (@socket_connect($sock, '127.0.0.1', 5003) === false) {
+ $errors[] = 'Could not connect to local dnbd3-server';
+ socket_close($sock);
+ return false;
+ }
+ // proto-version(16), image name\0, rid(16), flags(8)
+ $payload = pack('vA*xvC', 3, $image, $rid, 0);
+ // magic(16), cmd(16), payload-len(32), offset(64), handle(64)
+ $packet = pack('A*vVPP', 'sr', 2, strlen($payload), 0, 1234) . $payload;
+ if (!socket_send($sock, $packet, strlen($packet), 0)) {
+ $errors[] = 'Cannot send request to dnbd3-server';
+ socket_close($sock);
+ return false;
+ }
+ $len = socket_recv($sock, $reply, 16, MSG_WAITALL);
+ if ($len === 0) {
+ $errors[] = 'Local dnbd3-server cannot replicate required stage4 from master-server';
+ socket_close($sock);
+ return false;
+ }
+ if ($len !== 16) {
+ $errors[] = 'Incomplete reply received from local dnbd3-server. Stage4 might not replicate!';
+ socket_close($sock);
+ return false;
+ }
+ socket_close($sock);
+ // Try to decode header
+ $reply = unpack('A2magic/vcmd/Vsize/Phandle', $reply);
+ if ($reply['magic'] !== 'sr') {
+ $errors[] = 'Reply has wrong magic';
+ }
+ if ($reply['cmd'] !== 2) {
+ $errors[] = 'Reply is not CMD_IMAGE_REPLY';
+ }
+ return empty($errors);
+ }
+
} \ No newline at end of file
diff --git a/modules-available/minilinux/page.inc.php b/modules-available/minilinux/page.inc.php
index 76bcb95f..faea7599 100644
--- a/modules-available/minilinux/page.inc.php
+++ b/modules-available/minilinux/page.inc.php
@@ -163,6 +163,9 @@ class Page_MiniLinux extends Page
MiniLinux::setInstalledState($versionid, true);
}
}
+ if ($data['dltask'] !== false || $ver['installed']) {
+ MiniLinux::checkStage4($data, $data['s4_errors']);
+ }
echo Render::parse('filelist', $data);
}
diff --git a/modules-available/minilinux/templates/filelist.html b/modules-available/minilinux/templates/filelist.html
index b006fd1e..fdbef4ad 100644
--- a/modules-available/minilinux/templates/filelist.html
+++ b/modules-available/minilinux/templates/filelist.html
@@ -41,6 +41,9 @@
</tr>
{{/files}}
</table>
+{{#s4_errors}}
+<div class="alert alert-warning">{{lang_maybeMissingStage4}}: {{.}}</div>
+{{/s4_errors}}
{{#dltask}}
<div class="hidden" data-tm-id="{{dltask}}" data-tm-callback="dlTmCb"></div>
<pre class="collapse" id="error-{{dltask}}"></pre>