Files
pxe-server/webapp/templates/import.html
cproudlock cee4ecd18d Add web management UI, offline packages, WinPE consolidation, and docs
- webapp/: Flask web management app with:
  - Dashboard showing image types and service status
  - USB import page for WinPE deployment content
  - Unattend.xml visual editor (driver paths, specialize commands,
    OOBE settings, first logon commands, raw XML view)
  - API endpoints for services and image management
- SETUP.md: Complete setup documentation for streamlined process
- build-usb.sh: Now copies webapp and optional WinPE images to USB
- playbook: Added webapp deployment (systemd service, Apache reverse
  proxy), offline package verification, WinPE auto-import from USB

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 15:57:34 -05:00

120 lines
4.2 KiB
HTML

{% extends "base.html" %}
{% block title %}Image Import - PXE Server Manager{% endblock %}
{% block content %}
<h2 class="mb-4">Image Import</h2>
<div class="row">
<div class="col-lg-8">
<div class="card">
<div class="card-header">
<i class="bi bi-usb-drive me-2"></i> Import from USB Drive
</div>
<div class="card-body">
{% if usb_mounts %}
<form method="POST" id="importForm">
<div class="mb-3">
<label for="source" class="form-label fw-semibold">Source (USB Mount Point)</label>
<select class="form-select" name="source" id="source" required>
<option value="">-- Select a mounted USB drive --</option>
{% for mount in usb_mounts %}
<option value="{{ mount }}">{{ mount }}</option>
{% endfor %}
</select>
<div class="form-text">
Select the mounted USB drive containing the WinPE deployment content.
</div>
</div>
<div class="mb-3">
<label for="target" class="form-label fw-semibold">Target Image Type</label>
<select class="form-select" name="target" id="target" required>
<option value="">-- Select target image --</option>
{% for it in image_types %}
<option value="{{ it }}">{{ friendly_names[it] }} ({{ it }})</option>
{% endfor %}
</select>
<div class="form-text">
Content will be copied into the Deploy directory for this image type.
</div>
</div>
<div class="alert alert-warning d-flex align-items-start" role="alert">
<i class="bi bi-exclamation-triangle-fill me-2 mt-1"></i>
<div>
<strong>Warning:</strong> Existing files in the target Deploy directory with the
same names will be overwritten. This operation may take several minutes for large
images.
</div>
</div>
<button type="submit" class="btn btn-primary" id="importBtn">
<i class="bi bi-download me-1"></i> Start Import
</button>
</form>
{% else %}
<div class="text-center py-5">
<i class="bi bi-usb-plug display-4 text-muted"></i>
<h5 class="mt-3 text-muted">No USB Drives Detected</h5>
<p class="text-muted mb-0">
No mounted USB drives were found under <code>/mnt/</code> or <code>/media/</code>.<br>
Mount a USB drive and refresh this page.
</p>
<button class="btn btn-outline-secondary btn-sm mt-3" onclick="location.reload()">
<i class="bi bi-arrow-clockwise"></i> Refresh
</button>
</div>
{% endif %}
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card">
<div class="card-header">
<i class="bi bi-info-circle me-2"></i> Current Image Status
</div>
<div class="card-body p-0">
<table class="table table-sm mb-0">
<thead class="table-light">
<tr>
<th>Image</th>
<th>Content</th>
</tr>
</thead>
<tbody>
{% for img in images %}
<tr>
<td class="small">{{ img.friendly_name }}</td>
<td>
{% if img.has_content %}
<span class="badge bg-success">Present</span>
{% else %}
<span class="badge bg-secondary">Empty</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_scripts %}
<script>
document.addEventListener('DOMContentLoaded', function() {
var form = document.getElementById('importForm');
if (form) {
form.addEventListener('submit', function() {
var btn = document.getElementById('importBtn');
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span> Importing...';
});
}
});
</script>
{% endblock %}