feat: Major VTL System Upgrade (Auth, Monitoring, CLI, Installer)

- Web UI:
  - Added secure Authentication system (Login, 2 Roles: Admin/Viewer)
  - Added System Monitoring Dashboard (Health, Services, Power Mgmt)
  - Added User Management Interface (Create, Delete, Enable/Disable)
  - Added Device Mapping view in iSCSI tab (lsscsi output)
- Backend:
  - Implemented secure session management (auth.php)
  - Added power management APIs (restart/shutdown appliance)
  - Added device mapping API
- CLI:
  - Created global 'vtl' management tool
  - Added scripts for reliable startup (vtllibrary fix)
- Installer:
  - Updated install.sh with new dependencies (tgt, sudoers, permissions)
  - Included all new components in build-installer.sh
- Docs:
  - Consolidated documentation into docs/ folder
This commit is contained in:
2025-12-09 18:15:36 +00:00
parent 8a0523a265
commit 01080498af
53 changed files with 13399 additions and 425 deletions

View File

@@ -1,11 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>mhvtl Configuration Manager - Adastra VTL</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<nav class="navbar">
<div class="container">
@@ -14,17 +16,62 @@
<span class="subtitle">Virtual Tape Library Configuration</span>
</div>
<div class="nav-links">
<a href="#system" class="nav-link">System</a>
<a href="#library" class="nav-link active">Library</a>
<a href="#drives" class="nav-link">Drives</a>
<a href="#tapes" class="nav-link">Tapes</a>
<a href="#manage-tapes" class="nav-link">Manage Tapes</a>
<a href="#iscsi" class="nav-link">iSCSI</a>
<a href="#users" class="nav-link" id="users-tab">Users</a>
<a href="#export" class="nav-link">Export</a>
</div>
</div>
</nav>
<main class="container">
<section id="system" class="section">
<div class="section-header">
<h2>🖥️ System Monitoring & Management</h2>
<p>Monitor system health and manage appliance power</p>
</div>
<div class="card">
<div class="card-header">
<h3>💚 System Health Dashboard</h3>
<button class="btn btn-primary" onclick="refreshSystemHealth()">
<span>🔄</span> Refresh
</button>
</div>
<div class="card-body">
<div id="health-loading" style="display: none; text-align: center; padding: 2rem;">
<strong></strong> Loading system health...
</div>
<div id="health-dashboard">
<!-- Health dashboard will be populated here -->
</div>
</div>
</div>
<div class="card" style="margin-top: 1rem;">
<div class="card-header">
<h3>⚡ Power Management</h3>
</div>
<div class="card-body">
<p><strong>⚠️ Warning:</strong> These actions will affect the entire appliance.</p>
<div style="margin-top: 1rem;">
<button class="btn btn-warning" onclick="restartAppliance()" style="margin-right: 1rem;">
<span>🔄</span> Restart Appliance
</button>
<button class="btn btn-danger" onclick="shutdownAppliance()">
<span></span> Shutdown Appliance
</button>
</div>
<div id="power-result" class="alert" style="display: none; margin-top: 1rem;"></div>
</div>
</div>
</section>
<section id="library" class="section active">
<div class="section-header">
<h2>📚 Library Configuration</h2>
@@ -148,7 +195,8 @@
</div>
</div>
<div class="alert alert-info">
<strong> Info:</strong> Generate mktape commands for creating virtual tapes. Run these commands on the server after installation.
<strong> Info:</strong> Generate mktape commands for creating virtual tapes. Run these
commands on the server after installation.
</div>
</div>
</div>
@@ -228,13 +276,14 @@
</div>
<div id="tape-list-error" class="alert alert-danger" style="display: none;"></div>
<div id="tape-list-empty" class="alert alert-info" style="display: none;">
<strong></strong> No tape files found. Create tapes using the commands from the "Tapes" section.
<strong></strong> No tape files found. Create tapes using the commands from the "Tapes"
section.
</div>
<div id="tape-list-container" style="display: none;">
<div style="margin-bottom: 1rem;">
<input type="text" id="tape-search" placeholder="🔍 Search tapes..."
style="width: 100%; padding: 0.5rem; border: 1px solid #ddd; border-radius: 4px;"
onkeyup="filterTapes()">
style="width: 100%; padding: 0.5rem; border: 1px solid #ddd; border-radius: 4px;"
onkeyup="filterTapes()">
</div>
<table class="tape-table" id="tape-table">
<thead>
@@ -280,6 +329,24 @@
</div>
<div class="card">
<div class="card-header">
<h3>💾 Device Mapping</h3>
<button class="btn btn-primary" onclick="loadDeviceMapping()">
<span>🔄</span> Refresh
</button>
</div>
<div class="card-body">
<p>Current SCSI devices available for iSCSI export:</p>
<div id="device-mapping-loading" style="display: none; text-align: center; padding: 2rem;">
<strong></strong> Loading device mapping...
</div>
<div id="device-mapping">
<!-- Device mapping will be populated here -->
</div>
</div>
</div>
<div class="card" style="margin-top: 1rem;">
<div class="card-header">
<h3>🎯 iSCSI Targets</h3>
<button class="btn btn-primary" onclick="loadTargets()">
@@ -388,6 +455,90 @@
</div>
</section>
<section id="users" class="section">
<div class="section-header">
<h2>👥 User Management</h2>
<p>Manage user accounts and permissions (Admin Only)</p>
</div>
<div class="card">
<div class="card-header">
<h3>📋 User List</h3>
<button class="btn btn-primary" onclick="loadUsers()">
<span>🔄</span> Refresh
</button>
</div>
<div class="card-body">
<div id="users-loading" style="display: none; text-align: center; padding: 2rem;">
<strong></strong> Loading users...
</div>
<div id="users-list">
<!-- Users will be populated here -->
</div>
</div>
</div>
<div class="card" style="margin-top: 1rem;">
<div class="card-header">
<h3> Create New User</h3>
</div>
<div class="card-body">
<div class="form-grid">
<div class="form-group">
<label for="new-username">Username</label>
<input type="text" id="new-username" placeholder="Enter username" required>
</div>
<div class="form-group">
<label for="new-password">Password</label>
<input type="password" id="new-password" placeholder="Enter password" required>
</div>
<div class="form-group">
<label for="new-role">Role</label>
<select id="new-role">
<option value="viewer">Viewer (Read-Only)</option>
<option value="admin">Admin (Full Access)</option>
</select>
</div>
</div>
<div style="margin-top: 1rem;">
<button class="btn btn-success" onclick="createNewUser()">
<span></span> Create User
</button>
</div>
<div id="create-user-result" class="alert" style="display: none; margin-top: 1rem;"></div>
</div>
</div>
<div class="card" style="margin-top: 1rem;">
<div class="card-header">
<h3>🔑 Change Password</h3>
</div>
<div class="card-body">
<p>Change your own password</p>
<div class="form-grid">
<div class="form-group">
<label for="current-password">Current Password</label>
<input type="password" id="current-password" required>
</div>
<div class="form-group">
<label for="new-user-password">New Password</label>
<input type="password" id="new-user-password" required>
</div>
<div class="form-group">
<label for="confirm-password">Confirm New Password</label>
<input type="password" id="confirm-password" required>
</div>
</div>
<div style="margin-top: 1rem;">
<button class="btn btn-warning" onclick="changeUserPassword()">
<span>🔑</span> Change Password
</button>
</div>
<div id="change-password-result" class="alert" style="display: none; margin-top: 1rem;"></div>
</div>
</div>
</section>
<section id="export" class="section">
<div class="section-header">
<h2>📤 Export Configuration</h2>
@@ -455,4 +606,5 @@
<script src="script.js"></script>
</body>
</html>
</html>