1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00
webvirtcloud/instances/templates/create_instance_w1.html
catborise 9c6e07a467 fix(instances): a refused XML definition comes back in its editor
On the machine step, "Or define it from XML" lost the definition when it
was refused: a taken name re-rendered the page with an empty, collapsed
editor; malformed XML went on to libvirt, and libvirt's refusal sent the
browser back to an empty page with the reason at the top.

All three refusals now render the page with the section open, the
submitted XML in the editor (and in the field it posts, so it can be sent
again unchanged), and the reason above the editor, which takes the focus.

Fixes #174

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 11:24:44 +03:00

115 lines
5.5 KiB
HTML

{% extends "base.html" %}
{% load i18n %}
{% load static %}
{% load bootstrap_icons %}
{% block title %}{% trans "Create new instance" %} - {% trans "Machine" %}{% endblock %}
{% block style %}
<style>.create-vm { max-width: 56rem; }</style>
{% endblock %}
{% block page_heading%}
{% blocktrans with host=compute.name %}New instance on {{ host }} {% endblocktrans %}
{% endblock page_heading %}
{% block content %}
{% include 'pleasewaitdialog.html' %}
<div class="create-vm mx-auto">
{% include "create_steps.html" with step=2 %}
<section class="card mb-3" aria-labelledby="machine-heading">
<div class="card-body">
<h2 class="h5 card-title" id="machine-heading">{% trans "Machine" %}</h2>
<div class="row g-3">
<div class="col-md-6">
<label class="form-label" for="select_archs">{% trans "Architecture" %}</label>
<select class="form-select" id="select_archs" name="archs">
{% for hpv in hypervisors %}
<option value="{{ hpv }}"{% if hpv == default_arch %} selected{% endif %}>{{ hpv }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-6">
<label class="form-label" for="select_chipset">{% trans "Machine type" %}</label>
<select class="form-select" id="select_chipset" name="chipset" aria-describedby="chipset_help"></select>
<div id="chipset_help" class="form-text">{% trans "The host's machine types for this architecture." %}</div>
</div>
</div>
</div>
</section>
<div class="d-flex flex-wrap gap-2 justify-content-end mb-4">
<a class="btn btn-link" href="{% url 'instances' compute.id %}">{% trans "Cancel" %}</a>
<button class="btn btn-primary" type="button" id="next" disabled>{% trans "Next" %}</button>
</div>
<section class="card mb-3" aria-labelledby="xml-heading">
<div class="card-body">
<h2 class="h5 card-title mb-0" id="xml-heading">
<button class="btn p-0 border-0 text-body fw-medium w-100 text-start focus-ring disclosure" type="button" data-bs-toggle="collapse" data-bs-target="#from-xml"
aria-expanded="{% if xml_error %}true{% else %}false{% endif %}" aria-controls="from-xml">
{% bs_icon 'chevron-down' %} {% trans "Or define it from XML" %}
</button>
</h2>
<div class="collapse{% if xml_error %} show{% endif %}" id="from-xml">
<form method="post" class="pt-3" aria-label="{% trans "Create instance from XML" %}">{% csrf_token %}
{% if xml_error %}<div class="alert alert-danger form-errors" role="alert">{{ xml_error }}</div>{% endif %}
<input type="hidden" name="dom_xml" value="{{ xml }}">
<div class="xmlheight mb-3"><textarea id="editor" aria-label="{% trans "Domain XML" %}">{{ xml }}</textarea></div>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-primary" name="create_xml" onclick="showPleaseWaitDialog()">
{% trans "Create VM" %}
</button>
</div>
</form>
</div>
</div>
</section>
</div>
{% endblock %}
{% block script %}
<script>
// the machine types of the chosen architecture, the default one selected
function load_machines(arch) {
const next = document.querySelector("#next");
next.disabled = true;
$.getJSON("/computes/{{ compute_id }}/archs/" + encodeURIComponent(arch) + "/machines", function (data) {
document.querySelector("#select_chipset").replaceChildren(...data['machines'].map(
item => new Option(item, item, false, item === "{{ default_machine|escapejs }}")));
next.disabled = !data['machines'].length;
});
}
// placeholders, not "x86_64"/"pc": an architecture such as ppc64 contains "pc"
function create_url(arch, machine) {
return "{% url 'instances:create_instance' compute.id '__arch__' '__machine__' %}"
.replace("__arch__", encodeURIComponent(arch)).replace("__machine__", encodeURIComponent(machine));
}
function goto_create() {
window.location.href = create_url(document.querySelector("#select_archs").value,
document.querySelector("#select_chipset").value);
}
$(document).ready(function () {
const archs = document.querySelector("#select_archs");
archs.addEventListener("change", () => load_machines(archs.value));
document.querySelector("#next").addEventListener("click", goto_create);
load_machines(archs.value);
});
</script>
<script src="{% static "js/ace/ace.js" %}"></script>
<script>
var editor = ace.edit("editor");
editor.getSession().setMode("ace/mode/xml");
var input = $('input[name="dom_xml"]');
editor.getSession().on("change",function () {
input.val(editor.getSession().getValue());
})
// the editor measures itself when its section is shown
document.querySelector("#from-xml").addEventListener("shown.bs.collapse", () => editor.resize());
</script>
{% endblock %}