mirror of
https://github.com/retspen/webvirtcloud
synced 2024-12-25 15:45:23 +00:00
1932 lines
142 KiB
HTML
1932 lines
142 KiB
HTML
{% extends "base.html" %}
|
|
{% load staticfiles %}
|
|
{% load i18n %}
|
|
{% block title %}{% trans "Instance" %} - {{ vname }}{% endblock %}
|
|
{% block content %}
|
|
{% include 'pleasewaitdialog.html' %}
|
|
<!-- Page Heading -->
|
|
<div class="row">
|
|
<div>
|
|
<h3>
|
|
{{ vname }}{% if title %} ({{ title }}){% endif %}
|
|
</h3>
|
|
</div>
|
|
<div>
|
|
<div>
|
|
{% ifequal status 5 %}
|
|
<span class="label label-danger">{% trans "Off" %}</span>
|
|
{% endifequal %}
|
|
{% ifequal status 1 %}
|
|
<span class="label label-success">{% trans "Active" %}</span>
|
|
{% endifequal %}
|
|
{% ifequal status 3 %}
|
|
<span class="label label-warning">{% trans "Suspend" %}</span>
|
|
{% endifequal %}
|
|
|
|
|
{% if cur_vcpu %}
|
|
{{ cur_vcpu }} {% trans "Vcpu" %}
|
|
{% else %}
|
|
{{ vcpu }} {% trans "Vcpu" %}
|
|
{% endif %}
|
|
|
|
|
{{ cur_memory }} {% trans "MB" %} {% trans "Ram" %}
|
|
|
|
|
{% for disk in disks %}
|
|
{{ disk.size|filesizeformat }} {% trans "Disk" %} |
|
|
{% endfor %}
|
|
<a href="{% url 'instance' compute.id vname %}" type="button" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-refresh"></span></a>
|
|
<em>on</em>
|
|
<a href="{% url 'overview' compute.id %}"><span class="label label-primary">{{ compute.name }}{% if compute.name != compute.hostname %} - {{ compute.hostname }}{% endif %} </span></a>
|
|
</div>
|
|
</div>
|
|
{% if user_quota_msg %}
|
|
<span class="label label-warning">{{ user_quota_msg|capfirst }} {% trans "quota reached" %}.</span>
|
|
{% endif %}
|
|
<hr>
|
|
</div>
|
|
|
|
{% include 'errors_block.html' %}
|
|
{% include 'messages_block.html' %}
|
|
|
|
|
|
<div class="row" id="max-width-page">
|
|
<div class="col-lg-12">
|
|
<div role="tabpanel">
|
|
<!-- Nav tabs -->
|
|
<ul class="nav nav-pills" role="tablist" id="navbtn">
|
|
<li role="presentation" class="active">
|
|
<a href="#power" class="action-button" aria-controls="power" role="tab" data-toggle="tab">
|
|
<span id="action-block" class="glyphicon glyphicon-off" aria-hidden="true"></span>
|
|
{% trans "Power" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#access" class="action-button" aria-controls="access" role="tab" data-toggle="tab">
|
|
<span id="action-block" class="glyphicon glyphicon-lock" aria-hidden="true"></span>
|
|
{% trans "Access" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#resize" class="action-button" aria-controls="resize" role="tab" data-toggle="tab">
|
|
<span id="action-block" class="glyphicon glyphicon-resize-full" aria-hidden="true"></span>
|
|
{% trans "Resize" %}
|
|
</a>
|
|
</li>
|
|
{% if allow_admin_or_not_template %}
|
|
<li role="presentation">
|
|
<a href="#snapshots" class="action-button" aria-controls="snapshots" role="tab" data-toggle="tab">
|
|
<span id="action-block" class="glyphicon glyphicon-camera" aria-hidden="true"></span>
|
|
{% trans "Snapshots" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
<li role="presentation">
|
|
<a href="#settings" class="action-button" aria-controls="settings" role="tab" data-toggle="tab">
|
|
<span id="action-block" class="glyphicon glyphicon-cog" aria-hidden="true"></span>
|
|
{% trans "Settings" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#graphics" id="chartgraphs" class="action-button" aria-controls="graphics" role="tab" data-toggle="tab">
|
|
<span id="action-block" class="glyphicon glyphicon-stats" aria-hidden="true"></span>
|
|
{% trans "Stats" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#undefine" class="action-button" aria-controls="undefine" role="tab" data-toggle="tab">
|
|
<span id="action-block" class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
|
{% trans "Destroy" %}
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<!-- Tab panes -->
|
|
<div class="tab-content">
|
|
<div role="tabpanel" class="tab-pane active" id="power">
|
|
<div role="tabpanel">
|
|
<!-- Nav tabs -->
|
|
<ul class="nav nav-tabs" role="tablist">
|
|
{% ifequal status 1 %}
|
|
<li role="presentation" class="active">
|
|
<a href="#poweroff" aria-controls="poweroff" role="tab" data-toggle="tab">
|
|
{% trans "Power Off" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#powercycle" aria-controls="powercycle" role="tab" data-toggle="tab">
|
|
{% trans "Power Cycle" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#powerforce" aria-controls="powerforce" role="tab" data-toggle="tab">
|
|
{% trans "Force Off" %}
|
|
</a>
|
|
</li>
|
|
{% if request.user.is_superuser %}
|
|
<li role="presentation">
|
|
<a href="#suspend" aria-controls="suspend" role="tab" data-toggle="tab">
|
|
{% trans "Suspend" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% endifequal %}
|
|
{% ifequal status 3 %}
|
|
{% if request.user.is_superuser %}
|
|
<li role="presentation" class="active">
|
|
<a href="#resume" aria-controls="resume" role="tab" data-toggle="tab">
|
|
{% trans "Resume" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#powerforce" aria-controls="powerforce" role="tab" data-toggle="tab">
|
|
{% trans "Force Off" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% endifequal %}
|
|
{% ifequal status 5 %}
|
|
<li role="presentation" class="active">
|
|
<a href="#boot" aria-controls="boot" role="tab" data-toggle="tab">
|
|
{% trans "Power On" %}
|
|
</a>
|
|
</li>
|
|
{% endifequal %}
|
|
</ul>
|
|
<!-- Tab panes -->
|
|
<div class="tab-content">
|
|
{% ifequal status 1 %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="poweroff">
|
|
<p>{% trans "This action sends an ACPI shutdown signal to the instance." %}</p>
|
|
<form action="" method="post" role="form">{% csrf_token %}
|
|
<input type="submit" name="poweroff" class="btn btn-lg btn-success pull-right" value="{% trans "Power Off" %}">
|
|
<div class="clearfix"></div>
|
|
</form>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="powercycle">
|
|
<p>{% trans "This action forcibly powers off and start the instance and may cause data corruption." %}</p>
|
|
<form action="" method="post" role="form">{% csrf_token %}
|
|
<input type="submit" name="powercycle" class="btn btn-lg btn-success pull-right" value="{% trans "Power Cycle" %}">
|
|
<div class="clearfix"></div>
|
|
</form>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="powerforce">
|
|
<p>{% trans "This action forcibly powers off the instance and may cause data corruption." %}</p>
|
|
<form action="" method="post" role="form">{% csrf_token %}
|
|
<input type="submit" name="powerforce" class="btn btn-lg btn-success pull-right" value="{% trans "Force Off" %}">
|
|
<div class="clearfix"></div>
|
|
</form>
|
|
</div>
|
|
{% if request.user.is_superuser %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="suspend">
|
|
<p>{% trans "This action suspends the instance." %}</p>
|
|
<form action="" method="post" role="form">{% csrf_token %}
|
|
<input type="submit" name="suspend" class="btn btn-lg btn-success pull-right" value="{% trans "Suspend" %}">
|
|
<div class="clearfix"></div>
|
|
</form>
|
|
</div>
|
|
{% endif %}
|
|
{% endifequal %}
|
|
{% ifequal status 3 %}
|
|
{% if request.user.is_superuser %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resume">
|
|
<p>{% trans "This action restore the instance after suspend." %}</p>
|
|
<form action="" method="post" role="form">{% csrf_token %}
|
|
<input type="submit" name="resume" class="btn btn-lg btn-success pull-right" value="{% trans "Resume" %}">
|
|
<div class="clearfix"></div>
|
|
</form>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="powerforce">
|
|
<p>{% trans "This action forcibly powers off the instance and may cause data corruption." %}</p>
|
|
<form action="" method="post" role="form">{% csrf_token %}
|
|
<input type="submit" name="powerforce" class="btn btn-lg btn-success pull-right" value="{% trans "Force Off" %}">
|
|
<div class="clearfix"></div>
|
|
</form>
|
|
</div>
|
|
{% else %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resume">
|
|
<p>{% trans "Administrator blocked your instance." %}</p>
|
|
<form action="" method="post" role="form">{% csrf_token %}
|
|
<button class="btn btn-lg btn-success disabled pull-right">{% trans "Resume" %}</button>
|
|
<div class="clearfix"></div>
|
|
</form>
|
|
</div>
|
|
{% endif %}
|
|
{% endifequal %}
|
|
{% ifequal status 5 %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="boot">
|
|
<p>{% trans "Click on Boot button to start this instance." %}</p>
|
|
<form action="" method="post" role="form">{% csrf_token %}
|
|
{% if instance.is_template %}
|
|
<p>{% trans "Template instance cannot be started." %}</p>
|
|
<input type="submit" name="poweron" class="btn btn-lg btn-success pull-right disabled" value="{% trans "Power On" %}">
|
|
{% else %}
|
|
<input type="submit" name="poweron" class="btn btn-lg btn-success pull-right" value="{% trans "Power On" %}">
|
|
{% endif %}
|
|
<div class="clearfix"></div>
|
|
</form>
|
|
</div>
|
|
{% endifequal %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane" id="access">
|
|
<div role="tabpanel">
|
|
<!-- Nav tabs -->
|
|
<ul class="nav nav-tabs" role="tablist">
|
|
<li role="presentation" class="active">
|
|
<a href="#vnconsole" aria-controls="vnconsole" role="tab" data-toggle="tab">
|
|
{% trans "Console" %}
|
|
</a>
|
|
</li>
|
|
{% if show_access_root_password %}
|
|
<li role="presentation">
|
|
<a href="#rootpasswd" aria-controls="rootpasswd" role="tab" data-toggle="tab">
|
|
{% trans "Root Password" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if show_access_ssh_keys %}
|
|
<li role="presentation">
|
|
<a href="#sshkeys" aria-controls="sshkeys" role="tab" data-toggle="tab">
|
|
{% trans "SSH Keys" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% ifequal status 1 %}
|
|
<li role="presentation">
|
|
<a href="#vdiconsole" aria-controls="vdiconsole" role="tab" data-toggle="tab">
|
|
{% trans "VDI" %}
|
|
</a>
|
|
</li>
|
|
{% endifequal %}
|
|
</ul>
|
|
<!-- Tab panes -->
|
|
<div class="tab-content">
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="vnconsole">
|
|
<p>{% trans "This action opens a new window with a VNC connection to the console of the instance." %}</p>
|
|
{% ifequal status 1 %}
|
|
<!-- Split button -->
|
|
<div class="btn-group pull-right">
|
|
<button type="button" class="btn btn-lg btn-success " onclick="open_console('lite')">Console</button>
|
|
<button type="button" class="btn btn-lg btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<span class="caret"></span>
|
|
<span class="sr-only">{% trans 'Toggle Dropdown' %}</span>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a href="#" title="Console port: {{ console_port }}" onclick="open_console('lite')">{% trans "Console - Lite" %}</a></li>
|
|
<li><a href="#" title="Console port: {{ console_port }}" onclick="open_console('full')">{% trans "Console - Full" %}</a></li>
|
|
</ul>
|
|
</div>
|
|
{% else %}
|
|
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Console" %}</button>
|
|
{% endifequal %}
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
{% if show_access_root_password %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="rootpasswd">
|
|
<p>{% trans "You need shut down your instance and enter a new root password." %}</p>
|
|
<form class="form-inline" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<input type="text" class="form-control input-lg" name="passwd" placeholder="{% trans "Enter Password" %}" maxlength="24">
|
|
</div>
|
|
</div>
|
|
{% ifequal status 5 %}
|
|
<input type="submit" class="btn btn-lg btn-success pull-right" name="rootpasswd" value="{% trans "Reset Root Password" %}">
|
|
{% else %}
|
|
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Reset Root Password" %}</button>
|
|
{% endifequal %}
|
|
</form>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
{% endif %}
|
|
{% if show_access_ssh_keys %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="sshkeys">
|
|
<p>{% trans "You need shut down your instance and choose your public key." %}</p>
|
|
<form class="form-inline" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<select name="sshkeyid" class="form-control keyselect">
|
|
{% if publickeys %}
|
|
{% for key in publickeys %}
|
|
<option value="{{ key.id }}">{{ key.keyname }}</option>
|
|
{% endfor %}
|
|
{% else %}
|
|
<option value="None">{% trans "None" %}</option>
|
|
{% endif %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
{% ifequal status 5 %}
|
|
<input type="submit" class="btn btn-lg btn-success pull-right" name="addpublickey" value="{% trans "Add Public Key" %}">
|
|
{% else %}
|
|
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Add Public Key" %}</button>
|
|
{% endifequal %}
|
|
</form>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
{% endif %}
|
|
{% ifequal status 1 %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="vdiconsole">
|
|
<p>{% trans "This action opens a remote viewer with a connection to the console of the instance." %}</p>
|
|
<div class="input-group">
|
|
<input type="text" class="input-lg disabled form-control" disabled id="vdi_url_input"/>
|
|
<span class="input-group-btn">
|
|
<a href="#" class="btn btn-lg btn-success" id="vdi_url" >{% trans "VDI" %}</a>
|
|
</span>
|
|
</div>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
{% endifequal %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane" id="resize">
|
|
<div role="tabpanel">
|
|
<!-- Nav tabs -->
|
|
<ul class="nav nav-tabs" role="tablist">
|
|
<li role="presentation" class="active">
|
|
<a href="#resizevm" aria-controls="resizevm" role="tab" data-toggle="tab">
|
|
{% trans "Resize Instance" %}
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<!-- Tab panes -->
|
|
<div class="tab-content">
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resizevm">
|
|
{% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %}
|
|
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
|
|
<p style="font-weight:bold;">{% trans "Logical host CPUs" %} : {{ vcpu_host }}</p>
|
|
<div class="form-group">
|
|
<label class="col-sm-4 control-label" style="font-weight:normal;"> {% trans "Current allocation" %}</label>
|
|
<div class="col-sm-4">
|
|
<select name="cur_vcpu" class="form-control">
|
|
{% for cpu in vcpu_range %}
|
|
{% if cur_vcpu %}
|
|
<option value="{{ cpu }}" {% if cpu == cur_vcpu %}selected{% endif %}>{{ cpu }}</option>
|
|
{% else %}
|
|
<option value="{{ cpu }}" {% if cpu == vcpu %}selected{% endif %}>{{ cpu }}</option>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-4 control-label" style="font-weight:normal;">{% trans "Maximum allocation" %}</label>
|
|
<div class="col-sm-4">
|
|
<select name="vcpu" class="form-control">
|
|
{% for cpu in vcpu_range %}
|
|
<option value="{{ cpu }}" {% if cpu == vcpu %}selected{% endif %}>{{ cpu }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<p style="font-weight:bold;">{% trans "Total host memory:" %} {{ memory_host|filesizeformat }}</p>
|
|
<div class="form-group">
|
|
<label class="col-sm-4 control-label" style="font-weight:normal;">{% trans "Current allocation" %} ({% trans "MB" %})</label>
|
|
<div class="col-sm-4 js-custom__container">
|
|
<select name="cur_memory" class="form-control js-custom__toggle">
|
|
{% for mem in memory_range %}
|
|
<option value="{{ mem }}" {% if mem == cur_memory %}selected{% endif %}>{{ mem }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<input type="text" name="cur_memory_custom" class="form-control js-custom__toggle" style="display: none" />
|
|
<small><input type="checkbox" class="js-custom__checkbox" /> {% trans "Custom value" %}</small>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-4 control-label"
|
|
style="font-weight:normal;">{% trans "Maximum allocation" %} ({% trans "MB" %})</label>
|
|
<div class="col-sm-4 js-custom__container">
|
|
<select name="memory" class="form-control js-custom__toggle">
|
|
{% for mem in memory_range %}
|
|
<option value="{{ mem }}"
|
|
{% if mem == memory %}selected{% endif %}>{{ mem }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<input type="text" name="memory_custom" class="form-control js-custom__toggle" style="display: none" />
|
|
<small><input type="checkbox" class="js-custom__checkbox" /> {% trans "Custom value" %}</small>
|
|
</div>
|
|
</div>
|
|
<p style="font-weight:bold;">{% trans "Disk allocation (B):" %}</p>
|
|
{% for disk in disks %}
|
|
<div class="form-group">
|
|
<label class="col-sm-4 control-label" style="font-weight:normal;">{% trans "Current allocation" %} ({{ disk.dev }})</label>
|
|
<div class="col-sm-4 js-custom__container">
|
|
<input type="text" name="disk_size_{{ disk.dev }}" class="form-control" value="{{ disk.size|filesizeformat }}" />
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
{% ifequal status 5 %}
|
|
<button type="submit" class="btn btn-lg btn-success pull-right" name="resize">{% trans "Resize" %}</button>
|
|
{% else %}
|
|
<button class="btn btn-lg btn-success pull-right disabled" name="resize">{% trans "Resize" %}</button>
|
|
{% endifequal %}
|
|
</form>
|
|
{% else %}
|
|
{% trans "You don't have permission for resizing instance" %}
|
|
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Resize" %}</button>
|
|
{% endif %}
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane" id="snapshots">
|
|
<div role="tabpanel">
|
|
<!-- Nav tabs -->
|
|
<ul class="nav nav-tabs" role="tablist">
|
|
<li role="presentation" class="active">
|
|
<a href="#takesnapshot" aria-controls="takesnapshot" role="tab" data-toggle="tab">
|
|
{% trans "Take Snapshot" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#managesnapshot" aria-controls="managesnapshot" role="tab" data-toggle="tab">
|
|
{% trans "Manage Snapshots" %}
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<!-- Tab panes -->
|
|
<div class="tab-content">
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="takesnapshot">
|
|
{% ifequal status 5 %}
|
|
<p>{% trans "This may take more than an hour, depending on how much content is on your droplet and how large the disk is." %}</p>
|
|
<form class="form-inline" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<div class="col-sm-12">
|
|
<input type="text" class="form-control input-lg" name="name" placeholder="{% trans "Enter Snapshot Name" %}" maxlength="14">
|
|
</div>
|
|
</div>
|
|
{% ifequal status 5 %}
|
|
<input type="submit" class="btn btn-lg btn-success pull-right" name="snapshot" value="{% trans "Take Snapshot" %}">
|
|
{% else %}
|
|
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Take Snapshot" %}</button>
|
|
{% endifequal %}
|
|
</form>
|
|
<div class="clearfix"></div>
|
|
{% else %}
|
|
<p>{% trans "To take a snapshot please Power Off the instance." %}</p>
|
|
{% endifequal %}
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="managesnapshot">
|
|
{% ifequal status 5 %}
|
|
{% if snapshots %}
|
|
<p>{% trans "Choose a snapshot for restore/delete" %}</p>
|
|
<div class="table-responsive">
|
|
<table class="table">
|
|
<thead>
|
|
<th>{% trans "Name" %}</th>
|
|
<th>{% trans "Date" %}</th>
|
|
<th colspan="2">{% trans "Action" %}</th>
|
|
</thead>
|
|
<tbody>
|
|
{% for snap in snapshots %}
|
|
<tr>
|
|
<td><strong>{{ snap.name }}</strong></td>
|
|
<td>{{ snap.date|date:"M d H:i:s" }}</td>
|
|
<td style="width:30px;">
|
|
<form action="" method="post" style="height:10px" role="form">{% csrf_token %}
|
|
<input type="hidden" name="name" value="{{ snap.name }}">
|
|
{% ifequal status 5 %}
|
|
<button type="submit" class="btn btn-sm btn-default" name="revert_snapshot" title="Revert to this Snapshot" onclick="return confirm('Are you sure?')">
|
|
<span class="glyphicon glyphicon-save"></span>
|
|
</button>
|
|
{% else %}
|
|
<button type="button" class="btn btn-sm btn-default disabled">
|
|
<span class="glyphicon glyphicon-save"></span>
|
|
</button>
|
|
{% endifequal %}
|
|
</form>
|
|
</td>
|
|
<td style="width:30px;">
|
|
<form action="" method="post" role="form">{% csrf_token %}
|
|
<input type="hidden" name="name" value="{{ snap.name }}">
|
|
<button type="submit" class="btn btn-sm btn-default" name="delete_snapshot" title="Delete Snapshot" onclick="return confirm('{% trans "Are you sure?" %}')">
|
|
<span class="glyphicon glyphicon-trash"></span>
|
|
</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<p>{% trans "You do not have any snapshots" %}</p>
|
|
{% endif %}
|
|
{% else %}
|
|
<p>{% trans "To restore snapshots you need Power Off the instance." %}</p>
|
|
{% endifequal %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane" id="settings">
|
|
<div role="tabpanel">
|
|
<!-- Nav tabs -->
|
|
<ul class="nav nav-tabs" role="tablist">
|
|
{% if request.user.is_superuser %}
|
|
<li role="presentation" class="active">
|
|
<a href="#boot_opt" aria-controls="boot" role="tab" data-toggle="tab">
|
|
{% trans "Boot" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#disks" aria-controls="disks" role="tab" data-toggle="tab">
|
|
{% trans "Disk" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if request.user.is_superuser or request.user.is_staff or userinstance.is_vnc %}
|
|
<li role="presentation">
|
|
<a href="#vncsettings" aria-controls="vncsettings" role="tab" data-toggle="tab">
|
|
{% trans "Console" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if request.user.is_superuser %}
|
|
<li role="presentation">
|
|
<a href="#network" aria-controls="network" role="tab" data-toggle="tab">
|
|
{% trans "Network" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if request.user.is_superuser or request.user.userattributes.can_clone_instances %}
|
|
<li role="presentation">
|
|
<a href="#clone" aria-controls="clone" role="tab" data-toggle="tab">
|
|
{% trans "Clone" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if request.user.is_superuser %}
|
|
<li role="presentation">
|
|
<a href="#migrate" aria-controls="migrate" role="tab" data-toggle="tab">
|
|
{% trans "Migrate" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#xmledit" aria-controls="xmledit" role="tab" data-toggle="tab">
|
|
{% trans "XML" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if request.user.is_superuser or request.user.userattributes.can_clone_instances %}
|
|
<li role="presentation">
|
|
<a href="#options" aria-controls="options" role="tab" data-toggle="tab">
|
|
{% trans "Options" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
{% if request.user.is_superuser %}
|
|
<li role="presentation">
|
|
<a href="#users" aria-controls="users" role="tab" data-toggle="tab">
|
|
{% trans "Users" %}
|
|
</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
<!-- Tab panes -->
|
|
<div class="tab-content">
|
|
{% if request.user.is_superuser %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="boot_opt">
|
|
<p style="font-weight:bold;">{% trans 'Autostart' %}</p>
|
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<div class="col-sm-12 col-sm-offset-2">
|
|
<p>{% trans "Autostart your instance when host server is power on " %}
|
|
{% ifequal autostart 0 %}
|
|
<input type="submit" class="btn btn-success" name="set_autostart" value="{% trans "Enable" %}">
|
|
{% else %}
|
|
<input type="submit" class="btn btn-danger" name="unset_autostart" value="{% trans "Disable" %}">
|
|
{% endifequal %}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<p style="font-weight:bold;">{% trans 'Boot Order' %}</p>
|
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<div class="col-sm-12 col-sm-offset-2">
|
|
{% ifequal status 5 %}
|
|
<p>{% trans "Enable Boot Menu for your instance when it starts up " %}
|
|
{% ifequal bootmenu 0 %}
|
|
<input type="submit" class="btn btn-success" name="set_bootmenu" title="Show boot menu" value="{% trans "Enable" %}">
|
|
{% else %}
|
|
<input type="submit" class="btn btn-danger" name="unset_bootmenu" title="Hide boot menu" value="{% trans "Disable" %}">
|
|
{% endifequal %}
|
|
{% else %}
|
|
{% ifequal bootmenu 0 %}
|
|
<p>{% trans "**** Please shutdown instance to modify boot menu ****" %}</p>
|
|
{% endifequal %}
|
|
{% endifequal %}
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</p>
|
|
{% ifequal bootmenu 1 %}
|
|
<div class="col-sm-6 col-sm-offset-2">
|
|
<div class="well">
|
|
{% for idx, val in boot_order.items %}
|
|
<label>{{ idx|add:1 }}:{{ val.target }}, </label>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
|
<input id="bootorder" name="bootorder" hidden>
|
|
<div class="form-group">
|
|
<div class="col-sm-6 col-sm-offset-2">
|
|
<div id="b_order" class="multipleselect">
|
|
{% for disk in disks %}
|
|
<label><input type="checkbox" name="disk:{{ disk.dev }}" value="disk:{{ disk.dev }}" onclick="set_orderlist($('#bootorder'))" />{{ disk.dev }} - {{ disk.image }}</label>
|
|
{% endfor %}
|
|
{% for cd in media %}
|
|
<label><input type="checkbox" name="cdrom:{{ cd.dev }}" value="cdrom:{{ cd.dev }}" onclick="set_orderlist($('#bootorder'))"/>{{ cd.dev }} - {{ cd.image }}</label>
|
|
{% endfor %}
|
|
{% for net in networks %}
|
|
<label><input type="checkbox" name="network:{{ net.mac }}" value="network:{{ net.mac }}" onclick="set_orderlist($('#bootorder'))"/>NIC - {{ net.mac|slice:"9:" }}</label>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-3">
|
|
<div class="row" style="margin-top: 2em;">
|
|
<a href="#" id="boot_order_up" class="btn btn-default"><span class="glyphicon glyphicon-arrow-up" title="up: move selected devices"></span></a>
|
|
</div>
|
|
<div class="row" style="margin-top: 1em;">
|
|
<a href="#" id="boot_order_down" class="btn btn-default"><span class="glyphicon glyphicon-arrow-down" title="down: move selected devices"></span></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-sm-offset-2">
|
|
<input type="submit" class="btn btn-success btn-block" name="set_bootorder" value="{% trans "Apply" %}">
|
|
</div>
|
|
</form>
|
|
{% endifequal %}
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="disks">
|
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
|
<p style="font-weight:bold;">
|
|
{% trans "Instance Media" %}
|
|
{% if status == 5 %}
|
|
<button type="submit" name="add_cdrom" type="button" class="btn btn-success pull-right" title="Add CD-ROM">
|
|
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
|
</button>
|
|
{% else %}
|
|
<button type="submit" type="button" class="btn btn-success disabled pull-right" title="Add CD-ROM" disabled>
|
|
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
|
</button>
|
|
{% endif %}
|
|
</p>
|
|
</form>
|
|
{% for cd in media %}
|
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<a class="col-sm-3 control-label"
|
|
name="details"
|
|
title="{% trans "Details" %}"
|
|
tabindex="0"
|
|
data-trigger="focus"
|
|
data-toggle="popover"
|
|
data-html="true"
|
|
data-content="<strong>{% trans 'Bus' %}:</strong> {{ cd.bus }} <br/>
|
|
<strong>{% trans 'Dev' %}:</strong> {{ cd.dev }}">
|
|
{% trans "CDROM" %} {{ forloop.counter }}
|
|
</a>
|
|
{% if not cd.image %}
|
|
<div class="col-sm-6">
|
|
<select name="media" class="form-control">
|
|
{% if media_iso %}
|
|
{% for iso in media_iso %}
|
|
<option value="{{ iso }}">{{ iso }}</option>
|
|
{% endfor %}
|
|
{% else %}
|
|
<option value="none">{% trans "None" %}</option>
|
|
{% endif %}
|
|
</select>
|
|
</div>
|
|
<div class="col-sm-2">
|
|
{% if media_iso and allow_admin_or_not_template %}
|
|
<button type="submit" class="btn btn-sm btn-success pull-left" name="mount_iso" value="{{ cd.dev }}" style="margin-top: 2px;">{% trans "Mount" %}</button>
|
|
{% else %}
|
|
<button class="btn btn-sm btn-success pull-left disabled" style="margin-top: 2px;">{% trans "Mount" %}</button>
|
|
{% endif %}
|
|
{% if status == 5 and allow_admin_or_not_template %}
|
|
<button type="submit" class="btn btn-sm btn-danger pull-left" title="Detach CD-Rom (remove device)" name="detach_cdrom" value="{{ cd.dev }}" style="margin-top: 2px;"><i class="glyphicon glyphicon-remove-circle"></i></button>
|
|
{% endif %}
|
|
</div>
|
|
{% else %}
|
|
<div class="col-sm-6">
|
|
<input class="form-control" value="{{ cd.image }}" disabled/>
|
|
</div>
|
|
<div class="col-sm-2">
|
|
<input type="hidden" name="path" value="{{ cd.path }}">
|
|
{% if allow_admin_or_not_template %}
|
|
<button type="submit" class="btn btn-sm btn-success pull-left" value="{{ cd.dev }}" name="umount_iso" style="margin-top: 2px;">{% trans "Umount" %}</button>
|
|
{% else %}
|
|
<button class="btn btn-sm btn-success pull-left disabled" value="{{ cd.dev }}" name="umount_iso" style="margin-top: 2px;">{% trans "Umount" %}</button>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</form>
|
|
{% empty %}
|
|
<div class="col-sm-offset-3 col-sm-6">
|
|
<div class="well well-sm">{% trans 'There is not any CD-ROM device.' %}</div>
|
|
</div>
|
|
{% endfor %}
|
|
<div class="clearfix"></div>
|
|
<p style="font-weight:bold;">
|
|
{% trans "Instance Volume" %}
|
|
{% include 'add_instance_volume.html' %}
|
|
</p>
|
|
|
|
<div class="col-xs-12 col-sm-12">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<th>{% trans "Device" %}</th>
|
|
<th>{% trans "Used" %}</th>
|
|
<th>{% trans "Capacity" %}</th>
|
|
<th>{% trans "Storage" %}</th>
|
|
<th>{% trans "Source" %}</th>
|
|
<th style="width:100px;">{% trans "Action" %}</th>
|
|
</thead>
|
|
<tbody>
|
|
{% for disk in disks %}
|
|
<tr>
|
|
<td>
|
|
<button type="submit" class="btn btn-sm btn-default"
|
|
name="details"
|
|
title="{% trans "Details" %}"
|
|
tabindex="0"
|
|
data-trigger="focus"
|
|
data-toggle="popover"
|
|
data-html="true"
|
|
data-content="<strong>Bus:</strong> {{ disk.bus }} <br/>
|
|
<strong>Format:</strong> {{ disk.format }} <br/>
|
|
<strong>Cache:</strong> {{ disk.cache }}">
|
|
<i class="fa fa-info"></i>
|
|
</button>
|
|
{{ disk.dev }}
|
|
<br>
|
|
{{ disk.target }}
|
|
</td>
|
|
<td>{{ disk.used | filesizeformat}}</td>
|
|
<td>{{ disk.size | filesizeformat }}</td>
|
|
<td>{{ disk.storage }}</td>
|
|
<td>{{ disk.path }}</td>
|
|
<td>
|
|
<form action="" method="post" style="height:10px" role="form">{% csrf_token %}
|
|
<input type="hidden" name="path" value="{{ disk.path }}">
|
|
<input type="hidden" name="dev" value="{{ disk.dev }}">
|
|
<input type="hidden" name="storage" value="{{ disk.storage }}">
|
|
<input type="hidden" name="name" value="{{ disk.image }}">
|
|
{% ifequal status 5 %}
|
|
<button type="submit" class="btn btn-sm btn-default" name="detach_vol" value="{{ disk.dev }}" title="{% trans "Detach" %}" onclick="return confirm('{% trans "Are you sure to detach volume?" %}')">
|
|
<i class="fa fa-eject"></i>
|
|
</button>
|
|
<button type="submit" class="btn btn-sm btn-default" name="delete_vol" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure to delete volume?" %}')">
|
|
<i class="fa fa-trash"></i>
|
|
</button>
|
|
{% else %}
|
|
<button class="btn btn-sm btn-default disabled" name="detach_vol" value="{{ disk.dev }}" title="{% trans "Detach" %}" onclick="return confirm('{% trans "Are you sure to detach volume after shutdown?" %}')">
|
|
<i class="fa fa-eject"></i>
|
|
</button>
|
|
<button class="btn btn-sm btn-default disabled" name="delete_vol" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure to delete after shutdown?" %}')">
|
|
<i class="fa fa-trash"></i>
|
|
</button>
|
|
{% endifequal %}
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="network">
|
|
<p>
|
|
{% trans "Add a network device" %}
|
|
{% include 'add_instance_network_block.html' %}
|
|
</p>
|
|
|
|
<div class="col-xs-12 col-sm-12">
|
|
<form method="post" role="form">{% csrf_token %}
|
|
{% for network in networks %}
|
|
{% if forloop.first %}
|
|
<p><strong>{% trans "Network Devices" %}</strong></p>
|
|
{% endif %}
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<label>eth{{ forloop.counter0 }}({{ network.target|default:"no target" }})</label>
|
|
<button class="btn btn-sm pull-right btn-danger" value="{{ network.mac }}" name="delete_network" title="{% trans "Delete Device" %}" onclick="return confirm('{% trans "Are you sure?" %}')">{% trans "Delete" %}</button>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="form-group form-inline">
|
|
<label class="col-sm-2 col-sm-offset-1 control-label">{% trans "MAC" %} </label>
|
|
<input class="form-control" type="text" value="{{ network.mac }}" readonly/>
|
|
<label class="control-label"><em>to</em></label>
|
|
<input class="form-control" type="text" name="net-mac-{{ forloop.counter0 }}" value="{{ network.mac }}"/>
|
|
</div>
|
|
<div class="form-group form-inline">
|
|
<label class="col-sm-2 col-sm-offset-1 control-label">{% trans "NIC" %} </label>
|
|
<input class="form-control" type="text" value="{{ network.nic }}" readonly/>
|
|
<label class="control-label"><em>to</em></label>
|
|
<select class="form-control" name="net-source-{{ forloop.counter0 }}">
|
|
{% for c_net in compute_networks %}
|
|
<option value="net:{{ c_net }}" {% ifequal c_net network.nic %} selected {% endifequal %}>{% trans 'Network' %} {{ c_net }}</option>
|
|
{% endfor %}
|
|
{% for c_iface in compute_interfaces %}
|
|
<option value="iface:{{ c_iface }}" {% ifequal c_iface network.nic %} selected {% endifequal %}>{% trans 'Interface' %} {{ c_iface }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="form-group form-inline">
|
|
<label class="col-sm-2 col-sm-offset-1">{% trans "Filter" %} </label>
|
|
<input class="form-control" type="text" value="{{ network.filterref }}" readonly/>
|
|
<label class="control-label"><em>to</em></label>
|
|
<select class="form-control" name="net-nwfilter-{{ forloop.counter0 }}">
|
|
<option value="">{% trans "None" %}</option>
|
|
{% for c_filters in compute_nwfilters %}
|
|
<option value="{{ c_filters }}" {% ifequal c_filters network.filterref %} selected {% endifequal %}>{{ c_filters }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<button class="btn btn-sm btn-primary btn-block" name="change_network" title="{% trans "Apply Network Changes" %}">{% trans "Apply" %}</button>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</form>
|
|
</div>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="migrate">
|
|
<p>{% trans "For migration both host servers must have equal settings and OS type" %}</p>
|
|
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Original host" %}</label>
|
|
<div class="col-sm-6">
|
|
<p style="margin: 10px -10px 0 0;">{{ compute.name }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Host migration" %}</label>
|
|
<div class="col-sm-6">
|
|
<select name="compute_id" class="form-control">
|
|
{% if computes_count != 1 %}
|
|
{% for comp in computes %}
|
|
{% if comp.id != compute.id %}
|
|
<option value="{{ comp.id }}">{{ comp.name }}</option>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Live migration" %}</label>
|
|
<div class="col-sm-6">
|
|
<input type="checkbox" name="live_migrate" value="true" id="vm_live_migrate" {% ifequal status 1 %}checked{% endifequal %}>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Unsafe migration" %}</label>
|
|
<div class="col-sm-6">
|
|
<input type="checkbox" name="unsafe_migrate" value="true" id="vm_unsafe_migrate">
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Delete original" %}</label>
|
|
<div class="col-sm-6">
|
|
<input type="checkbox" name="xml_delete" value="true" id="xml_delete" checked>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Offline migration" %}</label>
|
|
<div class="col-sm-6">
|
|
<input type="checkbox" name="offline_migrate" value="true" id="offline_migrate" {% ifequal status 5 %}checked{% endifequal %}>
|
|
</div>
|
|
</div>
|
|
{% if computes_count != 1 %}
|
|
<button type="submit" class="btn btn-lg btn-success pull-right" name="migrate" onclick="showPleaseWaitDialog();">{% trans "Migrate" %}</button>
|
|
{% else %}
|
|
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Migrate" %}</button>
|
|
{% endif %}
|
|
</form>
|
|
<div class="clearfix"></div></p>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="xmledit">
|
|
<p>{% trans "If you need to edit xml please Power Off the instance" %}</p>
|
|
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
|
|
<div class="col-sm-12" id="xmlheight">
|
|
<textarea id="editor">{{ inst_xml }}</textarea>
|
|
</div>
|
|
{% ifequal status 5 %}
|
|
<input type="hidden" name="inst_xml">
|
|
<button type="submit" class="btn btn-lg btn-success pull-right" name="change_xml">
|
|
{% trans "Change" %}
|
|
</button>
|
|
{% else %}
|
|
<button class="btn btn-lg btn-success pull-right disabled">
|
|
{% trans "Change" %}
|
|
</button>
|
|
{% endifequal %}
|
|
</form>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="users">
|
|
<div>
|
|
<p style="font-weight:bold;">
|
|
{% trans "Instance owners" %}
|
|
{% include 'add_instance_owner_block.html' %}
|
|
</p>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table table-striped sortable-theme-bootstrap" data-sortable>
|
|
<tbody class="searchable">
|
|
{% for userinstance in userinstances %}
|
|
<tr>
|
|
<td><a href="{% url 'account' userinstance.user.id %}">{{ userinstance.user }}</a></td>
|
|
<td style="width:30px;">
|
|
<form action="" method="post" style="height:10px" role="form">{% csrf_token %}
|
|
<input type="hidden" name="userinstance" value="{{ userinstance.pk }}">
|
|
<button type="submit" class="btn btn-sm btn-default" name="del_owner" title="{% trans "Delete" %}">
|
|
<i class="fa fa-trash"></i>
|
|
</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
{% endif %}
|
|
{% if request.user.is_superuser or request.user.is_staff or userinstance.is_vnc %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="vncsettings">
|
|
<p>{% trans "To set console's type, shutdown the instance." %}</p>
|
|
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group" id="console_type_selection">
|
|
<label for="console_select_type" class="col-sm-2 control-label">{% trans "Type" %}</label>
|
|
<div class="col-sm-6">
|
|
<select id="console_select_type" class="form-control" name="console_type">
|
|
<option value="" style="font-weight: bold">{% trans "please choose" %}</option>
|
|
{% for ctype in console_types %}
|
|
<option value="{{ ctype }}">{{ ctype }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-sm-3">
|
|
{% ifequal status 5 %}
|
|
<button type="submit" class="btn btn-success " name="set_console_type">{% trans "Set" %}</button>
|
|
{% else %}
|
|
<button class="btn btn-success disabled" name="set_console_type">{% trans "Set" %}</button>
|
|
{% endifequal %}
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<p>{% trans "To set console listen address, shutdown the instance." %}</p>
|
|
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group" id="console_listen_address_selection">
|
|
<label for="console_select_listen_address" class="col-sm-2 control-label">{% trans "Listen on" %}</label>
|
|
<div class="col-sm-6">
|
|
<select id="console_select_listen_address" class="form-control" name="console_listen_address">
|
|
<option value="" style="font-weight: bold">{% trans "please choose" %}</option>
|
|
{% for address, label in console_listen_addresses %}
|
|
<option value="{{ address }}">{{ label }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-sm-3">
|
|
{% ifequal status 5 %}
|
|
<button type="submit" class="btn btn-success " name="set_console_listen_address">{% trans "Set" %}</button>
|
|
{% else %}
|
|
<button class="btn btn-success disabled" name="set_console_listen_address">{% trans "Set" %}</button>
|
|
{% endifequal %}
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<p>{% trans "To create console password, shutdown the instance." %}</p>
|
|
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<div class="col-sm-offset-2 col-sm-10">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" name="auto_pass" value="true" id="console_passwd_gen">{% trans "Generate" %}
|
|
</label>
|
|
</div>
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" name="clear_pass" value="true" id="console_passwd_clear">{% trans "Clear" %}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="inputPassword1" class="col-sm-2 control-label">{% trans "Password" %}</label>
|
|
<div class="col-sm-6" id="console_passwd_manual">
|
|
<input id="console_show_pass" type="password" class="form-control" name="console_passwd"
|
|
{% if console_passwd %}
|
|
value="{{ console_passwd }}"
|
|
{% else %}
|
|
placeholder="{% trans "Password" %}"
|
|
{% endif %} maxlength="14">
|
|
</div>
|
|
<div class="col-sm-3">
|
|
{% if console_passwd %}
|
|
<a href="#" name="console_show" class="btn btn-primary btn-md" onclick="show_console()">{% trans "Show" %}</a>
|
|
{% endif %}
|
|
{% ifequal status 5 %}
|
|
<button type="submit" class="btn btn-success" name="set_console_passwd">{% trans "Set" %}</button>
|
|
{% else %}
|
|
<button class="btn btn-success disabled" name="set_console_passwd">{% trans "Set" %}</button>
|
|
{% endifequal %}
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<p>{% trans "To set console's keymap, shutdown the instance." %}</p>
|
|
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<div class="col-sm-offset-2 col-sm-10">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" name="clear_keymap" value="true" id="console_keymap_clear">{% trans "Clear" %}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group" id="console_keymap_selection">
|
|
<label for="console_select_keymap" class="col-sm-2 control-label">{% trans "Keymap" %}</label>
|
|
<div class="col-sm-6">
|
|
<select id="console_select_keymap" class="form-control" name="console_keymap">
|
|
<option value="" style="font-weight: bold">{% trans "please choose" %}</option>
|
|
{% for keymap in keymaps %}
|
|
<option value="{{ keymap }}">{{ keymap }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-sm-3">
|
|
{% ifequal status 5 %}
|
|
<button type="submit" class="btn btn-success" name="set_console_keymap">{% trans "Set" %}</button>
|
|
{% else %}
|
|
<button class="btn btn-success disabled" name="set_console_keymap">{% trans "Set" %}</button>
|
|
{% endifequal %}
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
{% endif %}
|
|
{% if request.user.is_superuser or request.user.userattributes.can_clone_instances %}
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="clone">
|
|
<p style="font-weight:bold;">{% trans "Create a clone" %}</p>
|
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label" style="font-weight:normal;">{% trans "Clone Name" %}</label>
|
|
{% if request.user.is_superuser %}
|
|
<div class="col-sm-4">
|
|
<input id="clone_name" type="text" class="form-control" name="name" value="{{ vname }}-clone"/>
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<button type="button" class="btn btn-sm btn-success pull-left" name="guess-clone-name"
|
|
onclick="guess_clone_name()" style="margin-top: 2px;">{% trans "Guess" %}</button>
|
|
</div>
|
|
{% elif clone_instance_auto_name %}
|
|
<div class="col-sm-4">
|
|
<input id="clone_instance_auto_name" type="text" class="form-control" name="auto_name" value="Automatic" disabled/>
|
|
</div>
|
|
{% else %}
|
|
<div class="col-sm-4">
|
|
<select id="select_clone_name" class="form-control" name="name" size="1"/>
|
|
{% for name in clone_free_names %}
|
|
<option value="{{ name }}">{{ name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% if request.user.is_superuser %}
|
|
<p style="font-weight:bold;">{% trans "Network devices" %}</p>
|
|
{% for network in networks %}
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label" style="font-weight:normal;">eth{{ forloop.counter0 }} ({{ network.nic }})</label>
|
|
<div class="col-sm-4">
|
|
<input type="text" class="form-control" name="clone-net-mac-{{ forloop.counter0 }}" value="{{ network.mac }}"/>
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<button type="button" class="btn btn-sm btn-success pull-left" name="random-mac-{{ forloop.counter0 }}"
|
|
onclick="random_mac('clone-net-mac-{{ forloop.counter0 }}')" style="margin-top: 2px;">{% trans "Random" %}</button>
|
|
<button type="button" class="btn btn-sm btn-success pull-left" name="guess-mac-{{ forloop.counter0 }}"
|
|
onclick="guess_mac_address('#clone_name', {{ forloop.counter0 }})" style="margin-top: 2px;">{% trans "Guess" %}</button>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
{% else %}
|
|
{% for network in networks %}
|
|
<input type="hidden" class="form-control" name="clone-net-mac-{{ forloop.counter0 }}" value="{{ network.mac }}"/>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% if request.user.is_superuser %}
|
|
<p style="font-weight:bold;">{% trans "Storage devices" %}</p>
|
|
{% for disk in disks %}
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label" style="font-weight:normal;">{{ disk.dev }} ({{ disk.storage }})</label>
|
|
<div class="col-sm-4">
|
|
<input id="disk_name-{{ disk.dev }}" type="text" class="form-control" name="disk-{{ disk.dev }}" value="{{ disk.image }}"/>
|
|
</div>
|
|
{% ifequal disk.format 'qcow2' %}
|
|
<label class="col-sm-2 control-label" style="font-weight:normal;margin-left:-35px;">{% trans 'Metadata' %}</label>
|
|
<div class="col-sm-1">
|
|
<input type="checkbox" name="meta-{{ disk.dev }}" value="true" style="margin-top: 10px;">
|
|
</div>
|
|
{% endifequal %}
|
|
</div>
|
|
{% endfor %}
|
|
{% else %}
|
|
{% for disk in disks %}
|
|
<input id="disk_name-{{ disk.dev }}" type="hidden" class="form-control" name="disk-{{ disk.dev }}" value="{{ disk.image }}"/>
|
|
{% endfor %}
|
|
{% endif %}
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Title" %}</label>
|
|
<div class="col-sm-6">
|
|
<input type="text" name="clone-title" class="form-control">
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Description" %}</label>
|
|
<div class="col-sm-6">
|
|
<textarea name="clone-description" class="form-control"></textarea>
|
|
</div>
|
|
</div>
|
|
{% ifequal status 5 %}
|
|
<button type="submit" class="btn btn-lg btn-success pull-right" name="clone" onclick="showPleaseWaitDialog();">{% trans "Clone" %}</button>
|
|
{% else %}
|
|
<button class="btn btn-lg btn-success pull-right disabled" name="clone">{% trans "Clone" %}</button>
|
|
{% endifequal %}
|
|
</form>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="options">
|
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Title" %}</label>
|
|
<div class="col-sm-6">
|
|
<input type="text" name="title" class="form-control" value="{{ title }}">
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Description" %}</label>
|
|
<div class="col-sm-6">
|
|
<textarea name="description" class="form-control">{{ description }}</textarea>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="col-sm-3 control-label">{% trans "Is template" %}</label>
|
|
<div class="col-sm-6">
|
|
<input type="checkbox" name="is_template" value="True" id="is_template" {% if instance.is_template %}checked{% endif %} {% if not request.user.is_superuser %}disabled{% endif %}>
|
|
</div>
|
|
</div>
|
|
{% ifequal status 5 %}
|
|
<button type="submit" class="btn btn-lg btn-success pull-right" name="change_options">{% trans "Change" %}</button>
|
|
{% else %}
|
|
<button class="btn btn-lg btn-success pull-right disabled" name="change_options">{% trans "Change" %}</button>
|
|
{% endifequal %}
|
|
</form>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane" id="graphics">
|
|
<div role="tabpanel">
|
|
<!-- Nav tabs -->
|
|
<ul class="nav nav-tabs" role="tablist">
|
|
<li role="presentation" class="active">
|
|
<a href="#graphs" aria-controls="graphs" role="tab" data-toggle="tab">
|
|
{% trans "Real Time" %}
|
|
</a>
|
|
</li>
|
|
<li role="presentation">
|
|
<a href="#logs" aria-controls="logs" role="tab" data-toggle="tab" onclick='update_logs_table("{{ vname }}");'>
|
|
{% trans "Logs" %}
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<!-- Tab panes -->
|
|
<div class="tab-content">
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="graphs">
|
|
<div class="panel panel-success">
|
|
<div class="panel-heading">
|
|
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "CPU Usage" %}</h3>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="flot-chart">
|
|
<div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
|
|
<canvas id="cpuChart" width="735" height="160"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "Memory Usage" %}</h3>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="flot-chart">
|
|
<div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
|
|
<canvas id="memChart" width="735" height="160"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% for net in networks %}
|
|
<div class="panel panel-info">
|
|
<div class="panel-heading">
|
|
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "Bandwidth Device" %}: eth{{ forloop.counter0 }}</h3>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="flot-chart">
|
|
<div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
|
|
<canvas id="netEth{{ forloop.counter0 }}Chart" width="735" height="160"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
{% for disk in disks %}
|
|
<div class="panel panel-warning">
|
|
<div class="panel-heading">
|
|
<h3 class="panel-title"><i class="fa fa-long-arrow-right"></i> {% trans "Disk I/O device" %}: {{ disk.dev }}</h3>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="flot-chart">
|
|
<div class="flot-chart-content" id="flot-moving-line-chart" style="padding: 0px; position: relative;">
|
|
<canvas id="blk{{ disk.dev }}Chart" width="735" height="160"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="logs">
|
|
<div class="table-responsive">
|
|
<table class="table table-striped sortable-theme-bootstrap" id="logs_table" data-sortable>
|
|
<thead>
|
|
<tr>
|
|
<th>{% trans "Date" %}</th>
|
|
<th>{% trans "User" %}</th>
|
|
<th>{% trans "Message" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="searchable">
|
|
<tr><td colspan="3"><i>{% trans 'None' %}...</i></td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div role="tabpanel" class="tab-pane" id="undefine">
|
|
<div role="tabpanel">
|
|
<!-- Nav tabs -->
|
|
<ul class="nav nav-tabs" role="tablist">
|
|
<li role="presentation" class="active">
|
|
<a href="#destroy" aria-controls="destroy" role="tab" data-toggle="tab">
|
|
{% trans "Destroy Instance" %}
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<!-- Tab panes -->
|
|
<div class="tab-content">
|
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="destroy">
|
|
<p>{% trans "Delete storage for instance?" %}</p>
|
|
{% if request.user.is_superuser or userinstance.is_delete %}
|
|
{% ifequal status 3 %}
|
|
<button class="btn btn-lg btn-success disabled pull-right" name="delete">{% trans "Destroy" %}</button>
|
|
{% else %}
|
|
<form class="form-group" method="post" role="form">{% csrf_token %}
|
|
<div class="checkbox" style="margin-left: 8px;">
|
|
<label>
|
|
<input type="checkbox" name="delete_disk" value="true" checked>
|
|
<strong>{% trans "Remove Instance's data" %}</strong>
|
|
</label>
|
|
</div>
|
|
<button type="submit" class="btn btn-lg btn-success pull-right" name="delete">{% trans "Destroy" %}</button>
|
|
</form>
|
|
{% endifequal %}
|
|
{% else %}
|
|
<button class="btn btn-lg btn-success disabled pull-right" name="delete">{% trans "Destroy" %}</button>
|
|
{% endif %}
|
|
<div class="clearfix"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
{% block script %}
|
|
<script src="{% static "js/ace.js" %}" type="text/javascript" charset="utf-8"></script>
|
|
<script>
|
|
function get_volumes(compute_id, pool) {
|
|
get_vol_url = "/computes/" + compute_id + "/storage/" + pool + "/volumes";
|
|
$.getJSON(get_vol_url, function (data) {
|
|
$("#vols").find('option').remove();
|
|
$("#vols").removeAttr("disabled");
|
|
|
|
$.each(data['vols'], function(i, item) {
|
|
$("#vols").append('<option value=' + item +'>' + item + '</option>');
|
|
})
|
|
});
|
|
|
|
var sto_drop = document.getElementById('select_storage');
|
|
sto_drop.value = pool;
|
|
sto_drop.innerHTML = pool + "<span class=\"caret\"></span>";
|
|
|
|
var sto_input = document.getElementById('selected_storage');
|
|
sto_input.value = pool;
|
|
sto_input.innerHTML = pool;
|
|
}
|
|
</script>
|
|
|
|
<script>
|
|
var editor = ace.edit("editor");
|
|
editor.getSession().setMode("ace/mode/xml");
|
|
|
|
var input = $('input[name="inst_xml"]');
|
|
editor.getSession().on("change", function () {
|
|
input.val(editor.getSession().getValue());
|
|
});
|
|
</script>
|
|
<script>
|
|
function open_console(view_style) {
|
|
window.open('{% url 'console' %}?token={{ compute_id }}-{{ uuid }}&view=' + view_style +'', '', 'width=850,height=600')
|
|
}
|
|
</script>
|
|
<script>
|
|
function random_mac(net) {
|
|
$.getJSON('{% url 'random_mac_address' %}', function (data) {
|
|
$('input[name="' + net + '"]').val(data['mac']);
|
|
});
|
|
};
|
|
</script>
|
|
<script>
|
|
function show_console() {
|
|
if ($('#console_show_pass').attr('type') == 'password') {
|
|
$('#console_show_pass').attr('type', 'text');
|
|
} else {
|
|
$('#console_show_pass').attr('type', 'password');
|
|
}
|
|
}
|
|
</script>
|
|
<script>
|
|
function guess_mac_address(src_elem, net) {
|
|
new_vname = $(src_elem).val();
|
|
guess_mac_address_url = "{% url 'guess_mac_address' 1 %}".replace(1, new_vname);
|
|
$.getJSON(guess_mac_address_url, function(data) {
|
|
$('input[name="clone-net-mac-'+net+'"]').val(data['mac']);
|
|
});
|
|
}
|
|
</script>
|
|
<script>
|
|
function guess_clone_name() {
|
|
$.getJSON('{% url 'guess_clone_name' %}', function(data) {
|
|
guessed_name = data['name'].split(".")[0];
|
|
$('#clone_name').val(guessed_name);
|
|
update_clone_disk_name(guessed_name);
|
|
guess_mac_address('#clone_name', 0);
|
|
});
|
|
}
|
|
</script>
|
|
<script>
|
|
function update_clone_disk_name(new_vname) {
|
|
vname = '{{ vname }}';
|
|
{% for disk in disks %}
|
|
disk_name = '{{ disk.image }}';
|
|
disk_dot = disk_name.split('.')
|
|
disk_dot_suffix = disk_dot[disk_dot.length-1];
|
|
if (disk_name.startsWith(vname)) {
|
|
image = disk_name.replace(vname, new_vname);
|
|
} else if (disk_name.lastIndexOf('.') > -1 && disk_dot_suffix.length <= 7) {
|
|
disk_dot.pop();
|
|
disk_name_only = disk_dot.join('-')
|
|
image = new_vname + "-" + disk_name_only + "." + disk_dot_suffix
|
|
} else if (new_vname != disk_name) {
|
|
image = new_vname
|
|
} else {
|
|
image = new_vname + '-clone';
|
|
}
|
|
$('#disk_name-{{ disk.dev }}').val(image);
|
|
{% endfor %}
|
|
}
|
|
</script>
|
|
<script>
|
|
$(document).on('change', '#console_passwd_gen', function () {
|
|
if ($(this).prop('checked')) {
|
|
$('#console_passwd_manual').hide();
|
|
$('#console_passwd_clear').prop('checked', false);
|
|
} else {
|
|
$('#console_passwd_manual').show();
|
|
}
|
|
});
|
|
$(document).on('change', '#console_passwd_clear', function () {
|
|
if ($(this).prop('checked')) {
|
|
$('#console_passwd_manual').hide();
|
|
$('#console_passwd_gen').prop('checked', false);
|
|
} else {
|
|
$('#console_passwd_manual').show();
|
|
}
|
|
});
|
|
$(document).on('change', '#console_keymap_clear', function () {
|
|
if ($(this).prop('checked')) {
|
|
$('#console_keymap_selection').hide();
|
|
} else {
|
|
$('#console_keymap_selection').show();
|
|
}
|
|
});
|
|
$('#clone_name').on('input', function () {
|
|
update_clone_disk_name($(this).val());
|
|
});
|
|
$(document).ready(function () {
|
|
// set current console keymap or fall back to default
|
|
var keymap = "{{ console_keymap }}"
|
|
if (keymap != '') {
|
|
$("#console_select_keymap option[value='" + keymap + "']").prop('selected', true);
|
|
}
|
|
});
|
|
$(document).ready(function () {
|
|
// set current console type or fall back to default
|
|
var console_type = "{{ console_type }}"
|
|
if (console_type != '') {
|
|
$("#console_select_type option[value='" + console_type + "']").prop('selected', true);
|
|
}
|
|
});
|
|
$(document).ready(function () {
|
|
// set current console listen address or fall back to default
|
|
var console_listen_address = "{{ console_listen_address }}"
|
|
if (console_listen_address != '') {
|
|
$("#console_select_listen_address option[value='" + console_listen_address + "']").prop('selected', true);
|
|
}
|
|
});
|
|
$(document).ready(function () {
|
|
// set vdi url
|
|
$.get("{% url 'vdi_url' vname %}", function(data) {
|
|
$("#vdi_url_input").attr("value", data);
|
|
$("#vdi_url").attr("href", data);
|
|
});
|
|
});
|
|
{% if request.user.is_superuser %}
|
|
$(document).ready(function () {
|
|
random_mac('clone-net-mac-0');
|
|
random_mac('add-net-mac');
|
|
update_clone_disk_name($('#clone_name').val());
|
|
});
|
|
{% else %}
|
|
$('#select_clone_name').on('change', function () {
|
|
update_clone_disk_name($(this).val());
|
|
guess_mac_address('#select_clone_name', 0);
|
|
});
|
|
$(document).ready(function () {
|
|
update_clone_disk_name($('#select_clone_name').val());
|
|
guess_mac_address('#select_clone_name', 0);
|
|
});
|
|
{% endif %}
|
|
</script>
|
|
<script>
|
|
$(document).ready(function(){
|
|
$('[data-toggle="popover"]').popover({
|
|
placement : 'top'
|
|
});
|
|
});
|
|
</script>
|
|
<script>
|
|
function set_orderlist(obj){
|
|
var result = '';
|
|
$('#b_order label input:checked').each(function () {
|
|
if (result != '') result += ',';
|
|
result += $(this).val();
|
|
});
|
|
obj.val(result);
|
|
}
|
|
$(document).ready(function () {
|
|
{# Boot Order Arragements #}
|
|
jQuery.fn.multiselect = function() {
|
|
$(this).each(function() {
|
|
var checkboxes = $(this).find("input:checkbox");
|
|
checkboxes.each(function() {
|
|
var checkbox = $(this);
|
|
// Highlight pre-selected checkboxes
|
|
if (checkbox.prop("checked"))
|
|
checkbox.parent().addClass("multiselect-on");
|
|
// Highlight checkboxes that the user selects
|
|
checkbox.click(function() {
|
|
if (checkbox.prop("checked"))
|
|
checkbox.parent().addClass("multiselect-on");
|
|
else
|
|
checkbox.parent().removeClass("multiselect-on");
|
|
});
|
|
});
|
|
});
|
|
};
|
|
$(function() {
|
|
$(".multiselect").multiselect();
|
|
});
|
|
|
|
$('#boot_order_up').bind('click', function() {
|
|
$('#b_order label input:checked').each( function() {
|
|
var label = $(this).parent();
|
|
var newPos = label.index() - 1;
|
|
if (newPos > -1) {
|
|
$('#b_order label').eq(newPos).before("<label><input type='checkbox' value='"+$(this).val()+"' name='"+$(this).val()+"' checked>"+$(this).parent().text()+"</label>");
|
|
label.remove();
|
|
}
|
|
$(".multiselect").multiselect();
|
|
});
|
|
set_orderlist($("#bootorder"));
|
|
});
|
|
|
|
$('#boot_order_down').bind('click', function() {
|
|
var countOptions = $('#b_order label').size();
|
|
var countSelected = $('#b_order label input:checked').size();
|
|
$('#b_order label input:checked').each( function() {
|
|
var label = $(this).parent();
|
|
var newPos = label.index() + countSelected;
|
|
if (newPos < countOptions) {
|
|
$('#b_order label').eq(newPos).after("<label><input type='checkbox' value='"+$(this).val()+"' name='"+$(this).val()+"' checked>"+$(this).parent().text()+"</label>");
|
|
label.remove();
|
|
}
|
|
$(".multiselect").multiselect();
|
|
});
|
|
set_orderlist($("#bootorder"));
|
|
});
|
|
|
|
});
|
|
</script>
|
|
<script>
|
|
$(function () {
|
|
$('.js-custom__checkbox').change(function () {
|
|
var container = $(this).closest('.js-custom__container');
|
|
var toggles = container.find('.js-custom__toggle');
|
|
toggles.toggle();
|
|
});
|
|
});
|
|
</script>
|
|
<script src="{% static "js/Chart.bundle.min.js" %}"></script>
|
|
<script>
|
|
$('#chartgraphs').on('shown.bs.tab', function (event) {
|
|
|
|
var cpu_ctx = $("#cpuChart").get(0).getContext("2d");
|
|
var cpuChart = new Chart(cpu_ctx, {
|
|
type: 'line',
|
|
data: {
|
|
datasets : [{
|
|
backgroundColor: "rgba(44,127,184,0.5)",
|
|
label: "Usage"
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
legend: {
|
|
display: false
|
|
},
|
|
scales: {
|
|
xAxes:[{
|
|
offset: false,
|
|
ticks: {
|
|
beginAtZero: false,
|
|
autoSkip: true,
|
|
maxTicksLimit: 10,
|
|
maxRotation: 0,
|
|
minRotation: 0,
|
|
stepSize: 10,
|
|
},
|
|
}],
|
|
yAxes: [{
|
|
ticks: {
|
|
suggestedMax: 100,
|
|
suggestedMin: 0,
|
|
stepSize: 20,
|
|
callback: function(value, index, values) {
|
|
return value + ' %';
|
|
}
|
|
},
|
|
}],
|
|
},
|
|
tooltips: {
|
|
callbacks: {
|
|
label: function (tooltipItem, chart) {
|
|
var label = chart.datasets[tooltipItem.datasetIndex].label || '';
|
|
if (label) {
|
|
label += ': ';
|
|
}
|
|
return label += tooltipItem.yLabel + ' %';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
var mem_ctx = $("#memChart").get(0).getContext("2d");
|
|
var memChart = new Chart(mem_ctx, {
|
|
type: 'line',
|
|
data: {
|
|
datasets : [{
|
|
label: "Usage"
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
legend: {
|
|
display: false
|
|
},
|
|
scales: {
|
|
xAxes:[{
|
|
offset: false,
|
|
ticks: {
|
|
beginAtZero: false,
|
|
autoSkip: true,
|
|
maxTicksLimit: 10,
|
|
maxRotation: 0,
|
|
minRotation: 0,
|
|
stepSize: 10,
|
|
},
|
|
}],
|
|
yAxes: [{
|
|
ticks: {
|
|
suggestedMax: 100,
|
|
suggestedMin: 0,
|
|
stepSize: 20,
|
|
callback: function(value, index, values) {
|
|
return value + ' MB';
|
|
}
|
|
},
|
|
}],
|
|
},
|
|
tooltips: {
|
|
callbacks: {
|
|
label: function (tooltipItem, chart) {
|
|
var label = chart.datasets[tooltipItem.datasetIndex].label || '';
|
|
if (label) {
|
|
label += '(RSS): ';
|
|
}
|
|
return label += tooltipItem.yLabel + ' MB';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
var diskChart = {};
|
|
{% for disk in disks %}
|
|
var disk_ctx_{{ disk.dev }} = $("#blk{{ disk.dev }}Chart").get(0).getContext("2d");
|
|
diskChart['{{ disk.dev }}'] = new Chart(disk_ctx_{{ disk.dev }}, {
|
|
type: 'line',
|
|
data: {
|
|
datasets : [{
|
|
backgroundColor: "rgba(127,205,187,0.5)",
|
|
label: "Read"
|
|
},
|
|
{
|
|
backgroundColor: "rgba(44,127,184,0.5)",
|
|
label: "Write"
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
legend: {
|
|
display: false
|
|
},
|
|
scales: {
|
|
xAxes:[{
|
|
offset: false,
|
|
ticks: {
|
|
beginAtZero: false,
|
|
autoSkip: true,
|
|
maxTicksLimit: 10,
|
|
maxRotation: 0,
|
|
minRotation: 0,
|
|
stepSize: 10,
|
|
},
|
|
}],
|
|
yAxes: [{
|
|
ticks: {
|
|
suggestedmax: 100,
|
|
suggestedMin: 0,
|
|
callback: function(value, index, values) {
|
|
return value + ' Mb/s';
|
|
}
|
|
},
|
|
}],
|
|
},
|
|
tooltips: {
|
|
callbacks: {
|
|
label: function (tooltipItem, chart) {
|
|
var label = chart.datasets[tooltipItem.datasetIndex].label || '';
|
|
if (label) {
|
|
label += ': ';
|
|
}
|
|
return label += tooltipItem.yLabel + ' Mb/s';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
{% endfor %}
|
|
|
|
var netChart = {};
|
|
{% for net in networks %}
|
|
var net_ctx_{{ forloop.counter0 }} = $("#netEth{{ forloop.counter0 }}Chart").get(0).getContext("2d");
|
|
netChart['{{ forloop.counter0 }}'] = new Chart(net_ctx_{{ forloop.counter0 }}, {
|
|
type: 'line',
|
|
data: {
|
|
datasets : [
|
|
{
|
|
backgroundColor: "rgba(127,205,187,0.5)",
|
|
label: "Inbound"
|
|
},
|
|
{
|
|
backgroundColor: "rgba(44,127,184,0.5)",
|
|
label: "Outbound"
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
legend: {
|
|
display: false
|
|
},
|
|
scales: {
|
|
xAxes:[{
|
|
offset: false,
|
|
ticks: {
|
|
beginAtZero: false,
|
|
autoSkip: true,
|
|
maxTicksLimit: 10,
|
|
maxRotation: 0,
|
|
minRotation: 0,
|
|
stepSize: 10,
|
|
},
|
|
}],
|
|
yAxes: [{
|
|
ticks: {
|
|
suggestedMax: 100,
|
|
suggestedMin: 0,
|
|
callback: function(value, index, values) {
|
|
return value + ' Mbps';
|
|
}
|
|
},
|
|
}],
|
|
},
|
|
tooltips: {
|
|
callbacks: {
|
|
label: function (tooltipItem, chart) {
|
|
var label = chart.datasets[tooltipItem.datasetIndex].label || '';
|
|
if (label) {
|
|
label += ': ';
|
|
}
|
|
return label += tooltipItem.yLabel + ' Mbps';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
{% endfor %}
|
|
|
|
window.setInterval(function graph_usage() {
|
|
$.getJSON('{% url 'inst_graph' compute_id vname %}', function (data) {
|
|
|
|
cpuChart.data.labels.push(data.timeline);
|
|
|
|
cpuChart.data.datasets[0].data.push(data.cpudata);
|
|
if (cpuChart.data.datasets[0].data.length > 10){
|
|
cpuChart.data.labels.shift();
|
|
cpuChart.data.datasets[0].data.shift();
|
|
}
|
|
cpuChart.update();
|
|
|
|
memChart.data.labels.push(data.timeline);
|
|
|
|
|
|
memChart.options.scales.yAxes[0].ticks.max = parseInt(data.memdata.total / 1024);
|
|
memChart.options.scales.yAxes[0].ticks.stepSize = parseInt(data.memdata.total / (1024 * 5));
|
|
memChart.data.datasets[0].data.push(data.memdata.used / 1024);
|
|
if (memChart.data.datasets[0].data.length > 10){
|
|
memChart.data.labels.shift();
|
|
memChart.data.datasets[0].data.shift();
|
|
}
|
|
memChart.update();
|
|
|
|
|
|
for (let j = 0; j < data.blkdata.length; j++) {
|
|
diskChart[data.blkdata[j].dev].data.labels.push(data.timeline);
|
|
|
|
diskChart[data.blkdata[j].dev].data.datasets[0].data.push(data.blkdata[0].data[0]);
|
|
diskChart[data.blkdata[j].dev].data.datasets[1].data.push(data.blkdata[0].data[1]);
|
|
if (diskChart[data.blkdata[j].dev].data.datasets[0].data.length > 10){
|
|
diskChart[data.blkdata[j].dev].data.labels.shift();
|
|
diskChart[data.blkdata[j].dev].data.datasets[0].data.shift();
|
|
diskChart[data.blkdata[j].dev].data.datasets[1].data.shift();
|
|
}
|
|
diskChart[data.blkdata[j].dev].update();
|
|
}
|
|
|
|
for (let j = 0; j < data.netdata.length; j++) {
|
|
netChart[data.netdata[j].dev].data.labels.push(data.timeline);
|
|
|
|
netChart[data.netdata[j].dev].data.datasets[0].data.push(data.netdata[0].data[0]);
|
|
netChart[data.netdata[j].dev].data.datasets[1].data.push(data.netdata[0].data[1]);
|
|
if (netChart[data.netdata[j].dev].data.datasets[0].data.length > 10){
|
|
netChart[data.netdata[j].dev].data.labels.shift();
|
|
netChart[data.netdata[j].dev].data.datasets[0].data.shift();
|
|
netChart[data.netdata[j].dev].data.datasets[1].data.shift();
|
|
}
|
|
netChart[data.netdata[j].dev].update();
|
|
}
|
|
});
|
|
}, 10000);
|
|
});
|
|
</script>
|
|
<script>
|
|
backgroundJobRunning = false;
|
|
window.setInterval(function get_status() {
|
|
var status = {{ status }};
|
|
$.getJSON('{% url 'inst_status' compute_id vname %}', function (data) {
|
|
if (data['status'] != status && !backgroundJobRunning) {
|
|
window.location.reload()
|
|
}
|
|
});
|
|
}, 5000);
|
|
</script>
|
|
<script>
|
|
var hash = location.hash;
|
|
if (~$.inArray(hash, ['#poweron', '#poweroff', '#powercycle', '#suspend', '#resume'])) {
|
|
var btnsect = $('#navbtn>li>a');
|
|
$(btnsect).each(function () {
|
|
if ($(this).attr('href') === '#power') {
|
|
$(this).trigger('click');
|
|
}
|
|
});
|
|
}
|
|
if (~$.inArray(hash, ['#resize'])) {
|
|
var btnsect = $('#navbtn>li>a');
|
|
$(btnsect).each(function () {
|
|
if ($(this).attr('href') === '#resize') {
|
|
$(this).trigger('click');
|
|
}
|
|
});
|
|
}
|
|
if (~$.inArray(hash, ['#boot_opt', "#disks", '#network', '#clone', '#xmledit', '#vncsettings', '#migrate', '#options', '#users'])) {
|
|
var btnsect = $('#navbtn>li>a');
|
|
$(btnsect).each(function () {
|
|
if ($(this).attr('href') === '#settings') {
|
|
$(this).trigger('click');
|
|
}
|
|
});
|
|
|
|
var btn = $('#settings>div>ul>li>a');
|
|
$(btn).each(function () {
|
|
if ($(this).attr('href') === hash) {
|
|
$(this).trigger('click');
|
|
}
|
|
});
|
|
}
|
|
if (~$.inArray(hash, ['#takesnapshot', '#managesnapshot'])) {
|
|
var btnsect = $('#navbtn>li>a');
|
|
$(btnsect).each(function () {
|
|
if ($(this).attr('href') === '#snapshots') {
|
|
$(this).trigger('click');
|
|
}
|
|
});
|
|
|
|
var btn = $('#snapshots>div>ul>li>a');
|
|
$(btn).each(function () {
|
|
if ($(this).attr('href') === hash) {
|
|
$(this).trigger('click');
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
<script>
|
|
function update_logs_table(vname) {
|
|
logurl = "{% url 'vm_logs' 1 %}".replace(1, vname);
|
|
$.getJSON(logurl, function(data) {
|
|
var logs = "";
|
|
$.each(data, function(id) {
|
|
row = data[id];
|
|
console.log(row);
|
|
logs += '<tr><td style="width:150px">'+row['date']+'</td>';
|
|
logs += '<td>'+row['user']+'</td>';
|
|
logs += '<td>'+row['message']+'</td></tr>';
|
|
});
|
|
$("#logs_table > tbody").html(logs);
|
|
});
|
|
}
|
|
</script>
|
|
{% endblock %}
|