Заметки · 03.01.2025

Карусель из дисков в web

Продолжаю тему загрузочного PXE-сервера и iVentoy.

В прошлом посте я рассказывал, как запустить iVentoy с помощью скрипта и обновить перечень дисков с помощью команды ln. Сегодня я шагну чуть дальше и покажу как можно сделать всё то же самое, но не прибегая к помощи терминала или ssh-сессии. Речь про отдельную веб-страничку, с помощью которой можно было бы запускать скрипт getiventoy.sh.

После получаса развлечений со старым добрым набором из php, html и css получилась вот такая красота:

Функционал странички, думаю, понятен. Интерфейс состоит из двух кнопок для запуска скриптов, панели вывода ответа от скриптов и сопутствующих ссылок.

Чтобы всё это заработало, на вашем сервере обязательно должны быть установлены apache2 и php. Я проводил испытания на виртуальном сервере с Ubuntu Server 22.04. В случае с Ubuntu спайку apache2 и php можно установить этой командой:

sudo apt install apache2 php libapache2-mod-php

После установки apache2, вероятно, может потребоваться его включение:

sudo systemctl enable --now apache2

Теперь приведу код php-скрипта для создания веб-странички:

<?php
$output = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') 
{
    if (isset($_POST['run_script'])) 
    {
        $output = shell_exec('sudo /scripts/getiventoy.sh 2>&1');
    } 
    elseif (isset($_POST['create_symlink']))
    {
        $output = shell_exec('sudo /scripts/isoupdate.sh 2>&1');
    }
    $output = htmlspecialchars($output);
}
?>

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Запустить iVentoy</title>
    <style>
        body 
        {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            margin: 0;
            padding: 40px;
        }
        .container 
        {
            display: flex;
            flex-direction: column;
            align-items: center;
            background: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            max-width: 600px;
            margin: auto;
        }
        h1 
        {
            text-align: center;
            color: #333;
        }
        button 
        {
            padding: 10px 20px;
            font-size: 16px;
            color: #fff;
            background-color: #007bff;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            margin-top: 20px;
            margin-bottom: 10px;
        }
        button:hover 
        {
            background-color: #0056b3;
        }
        .author 
        {
            margin-top: 20px;
            text-align: center;
            color: #555;
            font-size: 12px;
        }
        .output 
        {
            margin-top: 30px;
            background: #e9ecef;
            padding: 15px;
            border-radius: 5px;
            width: 100%;
            overflow: auto;
            white-space: pre-wrap;
            font-family: monospace;
            color: #333;
        }
        .link_block 
        {
            margin: 10px 0;
            text-align: center;
        }
        .link_block a 
        {
            color: #007bff;
            text-decoration: none;
        }
        .link_block a:hover 
        {
            text-decoration: underline;
        }
        a 
        {
            color: #007bff;
            text-decoration: none;
            transition: color 0.3s;
        }
        a:hover 
        {
            color: #0056b3;
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Запуск iVentoy</h1>
        <form method="POST">
            <button type="submit" name="run_script">Запустить iVentoy</button>
            <button type="submit" name="create_symlink">Сканировать образы</button>
        </form>
        
        <div class="link_block">
            <a href="http://192.168.1.100:26000/" target="_blank" title="Открыть iVentoy">Открыть iVentoy</a>
        </div>
        
        <div class="output">
            <?php if ($output): ?>
                <h3>Вывод:</h3>
                <pre><?php echo $output; ?></pre>
            <?php endif; ?>
        </div>
        
        <div class="author">
            <a href="https://ngdream.ru" target="_blank" title="СерЁжкин код">ngdream.ru</a>
        </div>
    </div>
</body>
</html>

В условиях своего сервера не забудьте откорректировать адрес ссылки в этой строке:

<a href="http://192.168.1.100:26000/" target="_blank" title="Открыть iVentoy">Открыть iVentoy</a>

Ну, или можете поиграть с глобальными переменными php (я про конструкцию $_SERVER[‘SERVER_ADDR’]) и сделать скрипт более универсальным. Если вдруг сервер сменит IP-адрес ссылка будет живая.

Для того, чтобы кнопки выполняли свой функционал потребуется повысить уровень привилегий пользователю, от имени которого запущен веб-сервер. В Ubuntu этим пользователем является некто с причудливым именем — www-data.

Открываем для редактирования файл /etc/sudoers:

sudo visudo

И дописываем в файл вот эти строчки:

www-data ALL=(ALL) NOPASSWD: /scripts/getiventoy.sh
www-data ALL=(ALL) NOPASSWD: /scripts/isoupdate.sh

Ну, с getiventoy.sh всё понятно, — скажете Вы. — А вот что за зверь такой isoupdate.sh? А это тот самый сценарий для обновления набора ваших образов. Код скрипта isoupdate.sh:

#!/bin/bash

result=$(ln -sf /iso/* /ventoy/iventoy-1.0.20/iso/ 2>&1)
if [ $? -eq 0 ]; then
    echo "Команда выполнена успешно."
else
    echo "Произошла ошибка при выполнении команды."
    echo "$result"
fi

Не забудьте убедиться, что путь /ventoy/iventoy-1.0.20/iso/ является действующим в рамках установленной Вами версии iVentoy.

А для общего спокойствия я бы порекомендовал запретить изменения скриптов getiventoy.sh и isoupdate.sh. Например, с помощью этого метода.