diff options
Diffstat (limited to 'modules-available')
-rw-r--r-- | modules-available/dnbd3/inc/dnbd3.inc.php | 8 | ||||
-rw-r--r-- | modules-available/vmstore/inc/vmstorebenchmark.inc.php | 16 | ||||
-rw-r--r-- | modules-available/vmstore/page.inc.php | 41 | ||||
-rw-r--r-- | modules-available/vmstore/templates/benchmark-imgselect.html | 58 | ||||
-rw-r--r-- | modules-available/vmstore/templates/benchmark-result.html | 24 |
5 files changed, 114 insertions, 33 deletions
diff --git a/modules-available/dnbd3/inc/dnbd3.inc.php b/modules-available/dnbd3/inc/dnbd3.inc.php index 7f873f23..6d0f7ceb 100644 --- a/modules-available/dnbd3/inc/dnbd3.inc.php +++ b/modules-available/dnbd3/inc/dnbd3.inc.php @@ -39,4 +39,12 @@ class Dnbd3 { return $lookup; } + public static function getServer(string $serverId) + { + return Database::queryFirst('SELECT s.serverid, IFNULL(s.fixedip, m.clientip) AS clientip + FROM dnbd3_server s + LEFT JOIN machine m ON (s.machineuuid = m.machineuuid) + WHERE s.serverid = :id', ['id' => $serverId]); + } + } diff --git a/modules-available/vmstore/inc/vmstorebenchmark.inc.php b/modules-available/vmstore/inc/vmstorebenchmark.inc.php index 10c55431..3a696d04 100644 --- a/modules-available/vmstore/inc/vmstorebenchmark.inc.php +++ b/modules-available/vmstore/inc/vmstorebenchmark.inc.php @@ -25,12 +25,12 @@ class VmStoreBenchmark /** * @param array $machineUuids - * @param string $image - * @param bool $nfs + * @param string $image relative path/name of image + * @param string $serverOrMode IP address of DNBD3 server, OR 'auto' for all servers known to client, or 'nfs' for NFS * @param int $start timestamp when the clients should start * @return ?string taskId, or null on error */ - public static function start(string $id, array $machineUuids, string $image, bool $nfs, int &$start) + public static function start(string $id, array $machineUuids, string $image, string $serverOrMode, int &$start) { Module::isAvailable('rebootcontrol'); $clients = Database::queryAll('SELECT machineuuid, clientip FROM machine WHERE machineuuid IN (:uuids)', @@ -41,7 +41,13 @@ class VmStoreBenchmark // The more clients we have, the longer it takes to SSH into all of them. // As of 2022, RemoteExec processes 4 clients in parallel $start = ceil(count($clients) / 4 + 5 + time()); - $nfsOpt = $nfs ? '--nfs' : ''; + if ($serverOrMode === 'nfs') { + $modeOption = '--nfs'; + } elseif ($serverOrMode === 'auto') { + $modeOption = ''; + } else { + $modeOption = "--servers '$serverOrMode'"; + } // We fork off the benchmark into the background, and collect the results with another RemoteExec job // when we're done. This is because RemoteExec only does four concurrent SSH connections, so if we wanted to // do this the easy, synchronous way, we never could run more than four tests at the same time. @@ -49,7 +55,7 @@ class VmStoreBenchmark ( exec &> /dev/null < /dev/null setsid -image_speedcheck --start $start --console $nfsOpt --file "$image" > "/tmp/speedcheck-$id" +image_speedcheck --start $start --console $modeOption --file "$image" > "/tmp/speedcheck-$id" ) & COMMAND; $task = RebootControl::runScript($clients, $command); diff --git a/modules-available/vmstore/page.inc.php b/modules-available/vmstore/page.inc.php index 8813cde0..b490e749 100644 --- a/modules-available/vmstore/page.inc.php +++ b/modules-available/vmstore/page.inc.php @@ -91,6 +91,7 @@ class Page_VmStore extends Page if (!Module::isAvailable('rebootcontrol')) { ErrorHandler::traceError('rebootcontrol module not enabled'); } + Render::setTitle(Dictionary::translate('page-title-benchmark', true)); if (Request::post('action') === 'start') { $this->benchmarkActionStart(); } @@ -134,13 +135,23 @@ class Page_VmStore extends Page } Util::redirect('?do=vmstore&show=benchmark&action=result&id=' . $id); } - $nfs = !Dnbd3::isEnabled(); + $selectedServer = Request::post('server', 'auto', 'string'); + if ($selectedServer !== 'nfs' && !Dnbd3::isEnabled()) { + $selectedServer = 'nfs'; + } elseif ($selectedServer !== 'auto') { + $ip = Dnbd3::getServer($selectedServer); + if ($ip === false) { + Message::addError('invalid-dnbd3-server-id', $selectedServer); + return; + } + $selectedServer = $ip['clientip']; + } $data['image'] = Request::post('image', Request::REQUIRED, 'string'); // Save once first to minimize race window $data['task'] = 'inprogress'; Property::updateListEntry(VmStoreBenchmark::PROP_LIST_KEY, $id, json_encode($data), 30); $start = 0; - $data['task'] = VmStoreBenchmark::start($id, $data['machines'], $data['image'], $nfs, $start); + $data['task'] = VmStoreBenchmark::start($id, $data['machines'], $data['image'], $selectedServer, $start); if ($data['task'] === null) { $data['task'] = 'failed'; } else { @@ -176,7 +187,8 @@ class Page_VmStore extends Page if (!isset($images[$name])) { $images[$name] = [ 'users' => 0, - 'size' => Util::readableFileSize($img['size'], 1), + 'size' => $img['size'], + 'size_s' => Util::readableFileSize($img['size'], 1), 'name' => $name, 'id' => count($images) ]; @@ -184,8 +196,25 @@ class Page_VmStore extends Page $images[$name]['users'] += $img['users']; } } + $servers = []; + if (Dnbd3::isEnabled()) { + $servers[] = ['idx' => 'auto', + 'server' => Dictionary::translate('dnbd3-all-loadbalance', true)]; + foreach ($lookup as $ip => $idx) { + $servers[] = ['idx' => $idx, 'server' => $ip]; + } + } + if (!Dnbd3::isEnabled() || Dnbd3::hasNfsFallback()) { + $servers[] = ['idx' => 'nfs', 'server' => 'NFS']; + } + $servers[0]['checked'] = 'checked'; ArrayUtil::sortByColumn($images, 'users', SORT_NUMERIC | SORT_DESC); - Render::addTemplate('benchmark-imgselect', ['id' => $id, 'list' => array_values($images)]); + Module::isAvailable('js_stupidtable'); + Render::addTemplate('benchmark-imgselect', [ + 'id' => $id, + 'list' => array_values($images), + 'servers' => $servers, + ]); } private function benchmarkShowResult() @@ -265,6 +294,10 @@ EOF; 'values' => VmStoreBenchmark::parseBenchLine($mode[3]), ]; } + } else { + $client['stderr'] = substr($out['stderr'], 0, 4000) + . "\nStatus: {$out['state']}, ExitCode: {$out['exitCode']}'"; + $client['stdout'] = substr($out['stdout'], 0, 4000); } $m = Database::queryFirst('SELECT clientip, hostname FROM machine WHERE machineuuid = :uuid', ['uuid' => $uuid]); diff --git a/modules-available/vmstore/templates/benchmark-imgselect.html b/modules-available/vmstore/templates/benchmark-imgselect.html index 26ac898e..2ef61644 100644 --- a/modules-available/vmstore/templates/benchmark-imgselect.html +++ b/modules-available/vmstore/templates/benchmark-imgselect.html @@ -7,29 +7,45 @@ <input type="hidden" name="show" value="benchmark"> <input type="hidden" name="id" value="{{id}}"> - <table class="table"> - <thead> - <tr> - <th>{{lang_image}}</th> - <th class="slx-smallcol">{{lang_users}}</th> - <th class="slx-smallcol">{{lang_size}}</th> - </tr> - </thead> - <tbody> - {{#list}} + <div style="max-height:1000px;max-height:80vh;overflow:auto"> + <table class="table table-condensed stupidtable"> + <thead> <tr> - <td> - <div class="radio radio-inline"> - <input type="radio" id="r-{{id}}" name="image" value="{{name}}"> - <label for="r-{{id}}">{{name}}</label> - </div> - </td> - <td class="text-right">{{users}}</td> - <td class="text-right">{{size}}</td> + <th data-sort="string">{{lang_image}}</th> + <th class="slx-smallcol" data-sort="int" data-sort-default="desc">{{lang_users}}</th> + <th class="slx-smallcol" data-sort="int" data-sort-default="desc">{{lang_size}}</th> </tr> - {{/list}} - </tbody> - </table> + </thead> + <tbody> + {{#list}} + <tr> + <td> + <div class="radio radio-inline"> + <input type="radio" id="r-{{id}}" name="image" value="{{name}}"> + <label for="r-{{id}}">{{name}}</label> + </div> + </td> + <td class="text-right">{{users}}</td> + <td class="text-right" data-sort-value="{{size}}">{{size_s}}</td> + </tr> + {{/list}} + </tbody> + </table> + </div> + + <div class="slx-space"></div> + + <div class="slx-bold"> + {{lang_selectServerOrNfs}} + </div> + {{#servers}} + <div class="radio"> + <input type="radio" id="s-{{idx}}" name="server" value="{{idx}}" {{checked}}> + <label for="s-{{idx}}">{{server}}</label> + </div> + {{/servers}} + + <div class="slx-space"></div> <div class="buttonbar text-right"> <button type="submit" name="action" value="start" class="btn btn-primary"> diff --git a/modules-available/vmstore/templates/benchmark-result.html b/modules-available/vmstore/templates/benchmark-result.html index edf4a4f5..28f31f12 100644 --- a/modules-available/vmstore/templates/benchmark-result.html +++ b/modules-available/vmstore/templates/benchmark-result.html @@ -10,16 +10,18 @@ <div id="graphs"></div> +<div id="errors"></div> + <script> document.addEventListener('DOMContentLoaded', function() { var result = {{{result}}}; var clients = {{{wanted}}}; var graphs = {}; function formatBytes(val) { - return Math.floor(val / 1024 / 1024) + "MB/s"; + return Math.floor(val / 1024 / 1024) + "\u2009MiB/s"; } function renderX(val, index) { - return Math.floor(val / 1000) + 's'; + return Math.floor(val / 1000) + '\u2009s'; } function makeGraph(typeKey, resourceKey, caption) { var uuid; @@ -95,7 +97,23 @@ graphs[typeKey].data.datasets = ds; graphs[typeKey].update(); } - console.log(graphs[typeKey].data); + } + + var $err = $('#errors'); + for (var uuid in result) { + if (result[uuid].stdout || result[uuid].stderr) { + var $frame = $('<div class="panel panel-body">'); + $frame.append($('<h5>').text(result[uuid].name)); + if (result[uuid].stdout) { + $frame.append($('<label>').text('stdout')); + $frame.append($('<pre>').text(result[uuid].stdout)); + } + if (result[uuid].stderr) { + $frame.append($('<label>').text('stderr')); + $frame.append($('<pre>').text(result[uuid].stderr)); + } + $err.append($frame); + } } makeGraph('SEQ', 'net', 'Sequential Reads'); |