mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
The instance lists, the VM page header and the power tab knew three libvirt states: running, paused and shut off. A VM that was blocked, shutting down, crashed, suspended by its guest or without a state got an empty status cell and no actions, so a crashed VM could not even be forced off from the list. The lists also offered actions users could not use: Suspend and Resume (views for superusers) to everyone, and power actions to users who see every VM through the read-only view_instances permission. instances/states.py holds the rules in one place: the label and color of each state, the actions each state allows, and which of them a user may use (superusers all; a VM's owners all but suspend and resume, and nothing on a VM an administrator suspended, as the VM page already showed; nobody else any). Blocked is a running VM; shutting down, crashed and suspended by the guest get Force Off, after which the VM can be started. A shut-off template offers Clone to whoever has the clone permission, as the clone view allows. The templates read them through two tags (vm_states): the lists and the VM page header show the state, instance_actions.html has one slot per button, each enabled or disabled from the allowed actions. The power tab offers Force Off in the states that need it. The new tests check the rules directly and render every state in the lists and on the VM page for a superuser, an owner and a view_instances user; they fail on the previous code.
70 lines
3.5 KiB
HTML
70 lines
3.5 KiB
HTML
{% load i18n %}
|
|
{% load bootstrap_icons %}
|
|
{% load vm_states %}
|
|
{% vm_actions instance as actions %}
|
|
{% if actions %}
|
|
<div class="btn-group" role="group" aria-label="Instance actions">
|
|
{% if "clone" in actions %}
|
|
<a href="{% url 'instances:instance' instance.id %}#clone" class="btn btn-sm btn-secondary" title="{% trans "Clone" %}">
|
|
{% bs_icon 'copy' %}
|
|
</a>
|
|
{% elif "poweron" in actions %}
|
|
<form action="{% url 'instances:poweron' instance.id %}" method="post" style="display:inline;" onsubmit="showPleaseWaitDialog()">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-sm btn-secondary" title="{% trans "Power On" %}">{% bs_icon 'play-fill' %}</button>
|
|
</form>
|
|
{% elif "resume" in actions %}
|
|
<form action="{% url 'instances:resume' instance.id %}" method="post" style="display:inline;">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-sm btn-secondary" title="{% trans "Resume" %}">{% bs_icon 'play-fill' %}</button>
|
|
</form>
|
|
{% else %}
|
|
<button class="btn btn-sm btn-secondary disabled" title="{% trans "Power On" %}" disabled>{% bs_icon 'play-fill' %}</button>
|
|
{% endif %}
|
|
|
|
{% if "suspend" in actions %}
|
|
<form action="{% url 'instances:suspend' instance.id %}" method="post" style="display:inline;">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-sm btn-secondary" title="{% trans "Suspend" %}">{% bs_icon 'pause-fill' %}</button>
|
|
</form>
|
|
{% else %}
|
|
<button class="btn btn-sm btn-secondary disabled" title="{% trans "Suspend" %}" disabled>{% bs_icon 'pause-fill' %}</button>
|
|
{% endif %}
|
|
|
|
{% if "poweroff" in actions %}
|
|
<form action="{% url 'instances:poweroff' instance.id %}" method="post" style="display:inline;">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-sm btn-secondary" title="{% trans "Power Off" %}">{% bs_icon 'power' %}</button>
|
|
</form>
|
|
{% elif "force_off" in actions %}
|
|
<form action="{% url 'instances:force_off' instance.id %}" method="post" style="display:inline;">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-sm btn-secondary" title="{% trans "Force Off" %}">{% bs_icon 'power' %}</button>
|
|
</form>
|
|
{% else %}
|
|
<button class="btn btn-sm btn-secondary disabled" title="{% trans "Power Off" %}" disabled>{% bs_icon 'power' %}</button>
|
|
{% endif %}
|
|
|
|
{% if "powercycle" in actions %}
|
|
<form action="{% url 'instances:powercycle' instance.id %}" method="post" style="display:inline;">
|
|
{% csrf_token %}
|
|
<button type="submit" class="btn btn-sm btn-secondary" title="{% trans "Power Cycle" %}">{% bs_icon 'repeat' %}</button>
|
|
</form>
|
|
{% else %}
|
|
<button class="btn btn-sm btn-secondary disabled" title="{% trans "Power Cycle" %}" disabled>{% bs_icon 'repeat' %}</button>
|
|
{% endif %}
|
|
|
|
{% if "console" in actions %}
|
|
<button class="btn btn-sm btn-secondary" type="button" onclick='open_console("{{ instance.compute.id }}-{{ instance.get_uuid }}")'
|
|
title="{% trans "Console" %}">{% bs_icon 'eye-fill' %}</button>
|
|
{% else %}
|
|
<button class="btn btn-sm btn-secondary disabled" title="{% trans "VNC Console" %}" disabled>{% bs_icon 'eye-fill' %}</button>
|
|
{% endif %}
|
|
</div>
|
|
<script>
|
|
function open_console(uuid) {
|
|
url = '{% url 'console' %}?token=' + uuid + '';
|
|
window.open(url, '', 'width=850,height=650')
|
|
}
|
|
</script>
|
|
{% endif %}
|