Fix PXE interface detection, add br-pxe bridge to test VM, network upload import
- Playbook: detect interface already configured with 10.9.100.1 before falling back to non-default-gateway heuristic (fixes dnsmasq binding to wrong NIC when multiple interfaces exist) - test-vm.sh: auto-attach br-pxe bridge NIC if available on host - Webapp: add network upload import via SMB share with shared driver deduplication and symlinks Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,81 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
|
||||
<!-- Network Upload Import -->
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="bi bi-cloud-upload me-2"></i> Import from Network Upload
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if upload_sources %}
|
||||
<form method="POST" id="uploadImportForm">
|
||||
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
||||
<div class="mb-3">
|
||||
<label for="uploadSource" class="form-label fw-semibold">Source</label>
|
||||
<select class="form-select" name="source" id="uploadSource" required>
|
||||
<option value="">-- Select upload source --</option>
|
||||
{% for src in upload_sources %}
|
||||
<option value="{{ src }}">{{ src }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="form-text">
|
||||
Files uploaded via SMB to <code>\\10.9.100.1\image-upload</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="uploadTarget" class="form-label fw-semibold">Target Image Type</label>
|
||||
<select class="form-select" name="target" id="uploadTarget" 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. Shared resources
|
||||
(Out-of-box Drivers) are stored once and linked across all image types.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info d-flex align-items-start" role="alert">
|
||||
<i class="bi bi-info-circle-fill me-2 mt-1"></i>
|
||||
<div>
|
||||
<strong>Shared Drivers:</strong> Out-of-box Drivers are automatically pooled
|
||||
into a shared directory and symlinked for each image type to save disk space.
|
||||
</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="uploadImportBtn">
|
||||
<i class="bi bi-download me-1"></i> Start Import
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-cloud-slash display-4 text-muted"></i>
|
||||
<h5 class="mt-3 text-muted">No Upload Content Found</h5>
|
||||
<p class="text-muted mb-0">
|
||||
Map <code>\\10.9.100.1\image-upload</code> on your Windows PC and copy
|
||||
the Deploy directory contents there.
|
||||
</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>
|
||||
|
||||
<!-- USB Import -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="bi bi-usb-drive me-2"></i> Import from USB Drive
|
||||
@@ -54,7 +129,7 @@
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="text-center py-5">
|
||||
<div class="text-center py-4">
|
||||
<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">
|
||||
@@ -107,14 +182,16 @@
|
||||
{% 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...';
|
||||
});
|
||||
}
|
||||
['importForm', 'uploadImportForm'].forEach(function(formId) {
|
||||
var form = document.getElementById(formId);
|
||||
if (form) {
|
||||
form.addEventListener('submit', function() {
|
||||
var btn = form.querySelector('button[type="submit"]');
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span> Importing...';
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user