mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
The host pages' dialogs (new network, fixed address, DHCP range, bandwidth limit, new interface, new filter, filter rule, filter clone, new storage pool, new secret, a secret's value) and the VM page's XML review closed with a grey filled Cancel beside their action; the redone dialogs use an outlined Cancel, so the action is the one filled button.
168 lines
13 KiB
HTML
168 lines
13 KiB
HTML
{% load i18n %}
|
|
{% load static %}
|
|
{% load bootstrap_icons %}
|
|
{% load form_fields %}
|
|
{% if request.user.is_superuser %}
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#AddInterface">
|
|
<span aria-hidden="true">{% bs_icon 'plus-lg' %}</span> {% trans "New interface" %}
|
|
</button>
|
|
|
|
{# one form: a card per type, the fields of the chosen one (the others hidden and disabled, so not sent) #}
|
|
<div class="modal fade" id="AddInterface" tabindex="-1" aria-labelledby="AddInterfaceLabel" aria-hidden="true"
|
|
{% if form.errors %}data-open{% endif %}>
|
|
<div class="modal-dialog modal-lg modal-dialog-scrollable modal-fullscreen-sm-down">
|
|
<form method="post" class="modal-content" id="interface-form">{% csrf_token %}
|
|
<div class="modal-header">
|
|
<div>
|
|
<h5 class="modal-title" id="AddInterfaceLabel">{% trans "New interface" %}</h5>
|
|
<div class="small text-body-secondary">{% blocktrans with host=compute.name %}On {{ host }}{% endblocktrans %}</div>
|
|
</div>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans "Close" %}"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
{% include "instances/form_errors.html" %}
|
|
|
|
<fieldset class="mb-3">
|
|
<legend class="form-label fs-6">{% trans "Type" %}</legend>
|
|
<div class="row row-cols-1 row-cols-sm-2 g-2">
|
|
{% trans "Bridge" as title %}{% trans "A new bridge over a device of the host; VMs can join it." as help %}
|
|
{% include "radio_card.html" with name="itype" value="bridge" chosen=if_kind %}
|
|
{% trans "Ethernet" as title %}{% trans "A device of the host, configured and started by libvirt." as help %}
|
|
{% include "radio_card.html" with name="itype" value="ethernet" chosen=if_kind %}
|
|
</div>
|
|
</fieldset>
|
|
|
|
<fieldset data-kinds="bridge">
|
|
<legend class="visually-hidden">{% trans "Bridge" %}</legend>
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-sm-6">
|
|
<label for="iface_name" class="form-label">{% trans "Bridge name" %}</label>
|
|
<input id="iface_name" type="text" name="name" class="form-control font-monospace{% if if_kind == "bridge" %}{{ form.name|invalid }}{% endif %}"
|
|
value="{% if if_kind == "bridge" %}{{ form.name.value|default:"" }}{% endif %}" placeholder="br0" maxlength="15" required pattern="[A-Za-z0-9_.\-]+"
|
|
{% if if_kind == "bridge" %}{% error_attrs form.name "iface_name" %}{% endif %}>
|
|
{% if if_kind == "bridge" %}{% field_error form.name "iface_name" %}{% endif %}
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label for="iface_netdev" class="form-label">{% trans "Member device" %}</label>
|
|
<select id="iface_netdev" name="netdev" class="form-select{{ form.netdev|invalid }}" required {% error_attrs form.netdev "iface_netdev" "iface_netdev_help" %}>
|
|
{# a device taken meanwhile is chosen again, not swapped for the first one #}
|
|
{% if form.netdev.value and form.netdev.value not in members %}<option value="" selected>{% trans "Choose a device" %}</option>{% endif %}
|
|
{% for dev in members %}<option value="{{ dev }}"{% if dev == form.netdev.value %} selected{% endif %}>{{ dev }}</option>{% endfor %}
|
|
</select>
|
|
<div class="form-text" id="iface_netdev_help">{% trans "Devices in no bridge, bond or VLAN." %}</div>
|
|
{% field_error form.netdev "iface_netdev" %}
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label for="iface_stp" class="form-label">{% trans "Spanning tree (STP)" %}</label>
|
|
<select id="iface_stp" name="stp" class="form-select">
|
|
<option value="off"{% if form.stp.value == "off" %} selected{% endif %}>{% trans "Off" %}</option>
|
|
<option value="on"{% if form.stp.value == "on" %} selected{% endif %}>{% trans "On" %}</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label for="iface_delay" class="form-label">{% trans "Forward delay (s)" %}</label>
|
|
<input id="iface_delay" type="number" name="delay" min="0" class="form-control{{ form.delay|invalid }}" value="{{ form.delay.value|default:"0" }}" required
|
|
{% error_attrs form.delay "iface_delay" %}>
|
|
{% field_error form.delay "iface_delay" %}
|
|
</div>
|
|
</div>
|
|
<div class="alert alert-warning small">
|
|
{% bs_icon 'exclamation-triangle' %} {% trans "The device's own addresses go: the bridge takes the ones below, and connections through the device drop while it is rebuilt." %}
|
|
</div>
|
|
</fieldset>
|
|
|
|
<fieldset data-kinds="ethernet">
|
|
<legend class="visually-hidden">{% trans "Ethernet" %}</legend>
|
|
{% if ethernet_devices %}
|
|
<div class="mb-3">
|
|
<label for="iface_device" class="form-label">{% trans "Device" %}</label>
|
|
<select id="iface_device" name="name" class="form-select{% if if_kind == "ethernet" %}{{ form.name|invalid }}{% endif %}" required
|
|
{% if if_kind == "ethernet" %}{% error_attrs form.name "iface_device" %}{% endif %}>
|
|
{% if if_kind == "ethernet" and form.name.value and form.name.value not in ethernet_devices %}<option value="" selected>{% trans "Choose a device" %}</option>{% endif %}
|
|
{% for dev in ethernet_devices %}<option value="{{ dev }}"{% if dev == form.name.value %} selected{% endif %}>{{ dev }}</option>{% endfor %}
|
|
</select>
|
|
{% if if_kind == "ethernet" %}{% field_error form.name "iface_device" %}{% endif %}
|
|
</div>
|
|
{% else %}
|
|
<div class="alert alert-secondary small">{% trans "The host has every device defined already; a device's page shows it." %}</div>
|
|
{% endif %}
|
|
</fieldset>
|
|
|
|
<div class="mb-3">
|
|
<label for="iface_ipv4" class="form-label">IPv4</label>
|
|
<select id="iface_ipv4" name="ipv4_type" class="form-select" data-static="#iface_ipv4_static">
|
|
<option value="none"{% if form.ipv4_type.value == "none" %} selected{% endif %}>{% trans "None" %}</option>
|
|
<option value="dhcp"{% if form.ipv4_type.value == "dhcp" or not form.is_bound and "dhcp" == "dhcp" %} selected{% endif %}>DHCP</option>
|
|
<option value="static"{% if form.ipv4_type.value == "static" %} selected{% endif %}>{% trans "Static" %}</option>
|
|
</select>
|
|
</div>
|
|
<fieldset class="row g-3 mb-3" id="iface_ipv4_static">
|
|
<legend class="visually-hidden">IPv4</legend>
|
|
<div class="col-sm-6">
|
|
<label for="iface_ipv4_addr" class="form-label">{% trans "Address/prefix" %}</label>
|
|
<input id="iface_ipv4_addr" name="ipv4_addr" class="form-control font-monospace{{ form.ipv4_addr|invalid }}" value="{{ form.ipv4_addr.value|default:"" }}"
|
|
placeholder="192.0.2.10/24" required {% error_attrs form.ipv4_addr "iface_ipv4_addr" %}>
|
|
{% field_error form.ipv4_addr "iface_ipv4_addr" %}
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label for="iface_ipv4_gw" class="form-label">{% trans "Gateway" %}</label>
|
|
<input id="iface_ipv4_gw" name="ipv4_gw" class="form-control font-monospace{{ form.ipv4_gw|invalid }}" value="{{ form.ipv4_gw.value|default:"" }}"
|
|
placeholder="192.0.2.1" {% error_attrs form.ipv4_gw "iface_ipv4_gw" %}>
|
|
{% field_error form.ipv4_gw "iface_ipv4_gw" %}
|
|
</div>
|
|
</fieldset>
|
|
<div class="mb-3">
|
|
<label for="iface_ipv6" class="form-label">IPv6</label>
|
|
<select id="iface_ipv6" name="ipv6_type" class="form-select" data-static="#iface_ipv6_static">
|
|
<option value="none"{% if form.ipv6_type.value == "none" %} selected{% endif %}>{% trans "None" %}</option>
|
|
<option value="dhcp"{% if form.ipv6_type.value == "dhcp" or not form.is_bound and "none" == "dhcp" %} selected{% endif %}>DHCP</option>
|
|
<option value="static"{% if form.ipv6_type.value == "static" %} selected{% endif %}>{% trans "Static" %}</option>
|
|
</select>
|
|
</div>
|
|
<fieldset class="row g-3 mb-3" id="iface_ipv6_static">
|
|
<legend class="visually-hidden">IPv6</legend>
|
|
<div class="col-sm-6">
|
|
<label for="iface_ipv6_addr" class="form-label">{% trans "Address/prefix" %}</label>
|
|
<input id="iface_ipv6_addr" name="ipv6_addr" class="form-control font-monospace{{ form.ipv6_addr|invalid }}" value="{{ form.ipv6_addr.value|default:"" }}"
|
|
placeholder="2001:db8::10/64" required {% error_attrs form.ipv6_addr "iface_ipv6_addr" %}>
|
|
{% field_error form.ipv6_addr "iface_ipv6_addr" %}
|
|
</div>
|
|
<div class="col-sm-6">
|
|
<label for="iface_ipv6_gw" class="form-label">{% trans "Gateway" %}</label>
|
|
<input id="iface_ipv6_gw" name="ipv6_gw" class="form-control font-monospace{{ form.ipv6_gw|invalid }}" value="{{ form.ipv6_gw.value|default:"" }}"
|
|
placeholder="2001:db8::1" {% error_attrs form.ipv6_gw "iface_ipv6_gw" %}>
|
|
{% field_error form.ipv6_gw "iface_ipv6_gw" %}
|
|
</div>
|
|
</fieldset>
|
|
<div class="mb-3">
|
|
<label for="iface_start_mode" class="form-label">{% trans "Starts" %}</label>
|
|
<select id="iface_start_mode" name="start_mode" class="form-select">
|
|
<option value="onboot"{% if form.start_mode.value == "onboot" %} selected{% endif %}>{% trans "On boot" %}</option>
|
|
<option value="hotplug"{% if form.start_mode.value == "hotplug" %} selected{% endif %}>{% trans "When plugged in" %}</option>
|
|
<option value="none"{% if form.start_mode.value == "none" %} selected{% endif %}>{% trans "Only by hand" %}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">{% trans "Cancel" %}</button>
|
|
<button type="submit" class="btn btn-primary" name="create">{% trans "Create interface" %}</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<script src="{% static 'js/choice_dialog.js' %}"></script>
|
|
<script>
|
|
// a static address's fields show with its choice (after the page's
|
|
// scripts, Bootstrap's among them)
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
var form = document.getElementById('interface-form');
|
|
form.querySelectorAll('select[data-static]').forEach(function (method) {
|
|
var fields = form.querySelector(method.dataset.static);
|
|
function show() { fields.hidden = fields.disabled = method.value !== 'static'; }
|
|
method.addEventListener('change', show);
|
|
show();
|
|
});
|
|
choiceDialog(document.getElementById('AddInterface'), 'itype', function () {});
|
|
});
|
|
</script>
|
|
{% endif %}
|