mirror of
https://github.com/retspen/webvirtcloud
synced 2024-12-25 07:35:22 +00:00
Add boot menu/order functionality. Minor improvements. Some bug fixes
This commit is contained in:
parent
6b06ed25ff
commit
96efde814a
5 changed files with 553 additions and 284 deletions
|
@ -1,6 +1,6 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% if request.user.is_superuser %}
|
{% if request.user.is_superuser %}
|
||||||
<a href="#addvol" type="button" class="btn btn-success pull-right" data-toggle="modal">
|
<a href="#addvol" type="button" class="btn btn-success pull-right" data-toggle="modal" title="Add Volume">
|
||||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
|
@ -526,8 +526,8 @@
|
||||||
<!-- Nav tabs -->
|
<!-- Nav tabs -->
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
<li role="presentation" class="active">
|
<li role="presentation" class="active">
|
||||||
<a href="#media" aria-controls="media" role="tab" data-toggle="tab">
|
<a href="#boot_opt" aria-controls="boot" role="tab" data-toggle="tab">
|
||||||
{% trans "Media" %}
|
{% trans "Boot" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li role="presentation">
|
<li role="presentation">
|
||||||
|
@ -535,13 +535,6 @@
|
||||||
{% trans "Disk" %}
|
{% trans "Disk" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% if request.user.is_superuser %}
|
|
||||||
<li role="presentation">
|
|
||||||
<a href="#autostart" aria-controls="autostart" role="tab" data-toggle="tab">
|
|
||||||
{% trans "Autostart" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if request.user.is_superuser or userinstance.is_vnc %}
|
{% if request.user.is_superuser or userinstance.is_vnc %}
|
||||||
<li role="presentation">
|
<li role="presentation">
|
||||||
|
@ -593,29 +586,105 @@
|
||||||
</ul>
|
</ul>
|
||||||
<!-- Tab panes -->
|
<!-- Tab panes -->
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="media">
|
{% if request.user.is_superuser %}
|
||||||
{% if request.user.is_superuser and status == 5 %}
|
<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 %}
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12 col-sm-offset-2">
|
||||||
<button type="submit" name="add_cdrom" type="button" class="btn btn-success pull-right">
|
<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" value="{% trans "Enable" %}">
|
||||||
|
{% else %}
|
||||||
|
<input type="submit" class="btn btn-danger" name="unset_bootmenu" value="{% trans "Disable" %}">
|
||||||
|
{% endifequal %}
|
||||||
|
{% else %}
|
||||||
|
<p>{% trans "**** Please shutdown instance to modify boot menu ****" %}
|
||||||
|
{% endifequal %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% 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="multiselect">
|
||||||
|
{% 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"></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"></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">
|
||||||
|
{% if status == 5 %}
|
||||||
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
||||||
|
<p style="font-weight:bold;">
|
||||||
|
{% trans "Instance Media" %}
|
||||||
|
<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>
|
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</p>
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for cd in media %}
|
{% for cd in media %}
|
||||||
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<a class="col-sm-2 control-label"
|
<a class="col-sm-3 control-label"
|
||||||
name="details"
|
name="details"
|
||||||
title="{% trans "Details" %}"
|
title="{% trans "Details" %}"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
data-trigger="focus"
|
data-trigger="focus"
|
||||||
data-toggle="popover"
|
data-toggle="popover"
|
||||||
data-html="true"
|
data-html="true"
|
||||||
data-content="<strong>Bus:</strong> {{ cd.bus }} <br/> <strong>Dev:</strong> {{ cd.dev }}">
|
data-content="<strong>{% trans 'Bus' %}:</strong> {{ cd.bus }} <br/>
|
||||||
|
<strong>{% trans 'Dev' %}:</strong> {{ cd.dev }}">
|
||||||
{% trans "CDROM" %} {{ forloop.counter }}
|
{% trans "CDROM" %} {{ forloop.counter }}
|
||||||
</a>
|
</a>
|
||||||
{% if not cd.image %}
|
{% if not cd.image %}
|
||||||
|
@ -656,11 +725,9 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div class="clearfix"></div>
|
|
||||||
</div>
|
|
||||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="disks">
|
|
||||||
<p style="font-weight:bold;">
|
<p style="font-weight:bold;">
|
||||||
{% trans "Instance Volumes" %}
|
{% trans "Instance Volume" %}
|
||||||
{% include 'add_instance_volume.html' %}
|
{% include 'add_instance_volume.html' %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -728,19 +795,165 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="network">
|
||||||
|
<p>
|
||||||
|
{% trans "Assign network device to bridge" %}
|
||||||
|
{% include 'add_instance_network_block.html' %}
|
||||||
|
</p>
|
||||||
|
<p style="font-weight:bold;">{% trans "Network devices" %}</p>
|
||||||
|
<div class="col-xs-12 col-sm-12">
|
||||||
|
<form method="post" role="form">{% csrf_token %}
|
||||||
|
{% for network in networks %}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<label>eth{{ forloop.counter0 }}({{ network.target|default:"no target" }})</label>
|
||||||
|
</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 %}>Network {{ c_net }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
{% for c_iface in compute_interfaces %}
|
||||||
|
<option value="iface:{{ c_iface }}" {% ifequal c_iface network.nic %} selected {% endifequal %}>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>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if request.user.is_superuser %}
|
<div class="panel-footer">
|
||||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="autostart">
|
<button class="btn btn-sm btn-primary" name="change_network" title="{% trans "Change" %}">{% trans "Change" %}</button>
|
||||||
<p>{% trans "Autostart your instance when host server is power on" %}</p>
|
<button class="btn btn-sm pull-right btn-danger" value="{{ network.mac }}" name="delete_network" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">{% trans "Delete" %}</button>
|
||||||
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
</div>
|
||||||
{% ifequal autostart 0 %}
|
</div>
|
||||||
<input type="submit" class="btn btn-lg btn-success pull-right" name="set_autostart" value="{% trans "Enable" %}">
|
{% 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 %}
|
{% else %}
|
||||||
<input type="submit" class="btn btn-lg btn-success pull-right" name="unset_autostart" value="{% trans "Disable" %}">
|
<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 %}
|
{% endifequal %}
|
||||||
</form>
|
</form>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</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 %}
|
{% endif %}
|
||||||
{% if request.user.is_superuser or userinstance.is_vnc %}
|
{% if request.user.is_superuser or userinstance.is_vnc %}
|
||||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="vncsettings">
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="vncsettings">
|
||||||
|
@ -857,65 +1070,6 @@
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if request.user.is_superuser %}
|
|
||||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="network">
|
|
||||||
<p>
|
|
||||||
{% trans "Assign network device to bridge" %}
|
|
||||||
{% include 'add_instance_network_block.html' %}
|
|
||||||
</p>
|
|
||||||
<p style="font-weight:bold;">{% trans "Network devices" %}</p>
|
|
||||||
<div class="col-xs-12 col-sm-12">
|
|
||||||
<form method="post" role="form">{% csrf_token %}
|
|
||||||
{% for network in networks %}
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<label>eth{{ forloop.counter0 }}({{ network.target|default:"no target" }})</label>
|
|
||||||
</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 %}>Network {{ c_net }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
{% for c_iface in compute_interfaces %}
|
|
||||||
<option value="iface:{{ c_iface }}" {% ifequal c_iface network.nic %} selected {% endifequal %}>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>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel-footer">
|
|
||||||
<button class="btn btn-sm btn-primary" name="change_network" title="{% trans "Change" %}">{% trans "Change" %}</button>
|
|
||||||
<button class="btn btn-sm pull-right btn-danger" value="{{ network.mac }}" name="delete_network" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">{% trans "Delete" %}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="clearfix"></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if request.user.is_superuser or request.user.userattributes.can_clone_instances %}
|
{% if request.user.is_superuser or request.user.userattributes.can_clone_instances %}
|
||||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="clone">
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="clone">
|
||||||
<p style="font-weight:bold;">{% trans "Create a clone" %}</p>
|
<p style="font-weight:bold;">{% trans "Create a clone" %}</p>
|
||||||
|
@ -1006,84 +1160,6 @@
|
||||||
</form>
|
</form>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
{% if request.user.is_superuser %}
|
|
||||||
<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>
|
|
||||||
{% endif %}
|
|
||||||
{% if request.user.is_superuser or request.user.userattributes.can_clone_instances %}
|
|
||||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="options">
|
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="options">
|
||||||
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -1113,36 +1189,6 @@
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if request.user.is_superuser %}
|
|
||||||
<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 %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1217,7 +1263,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="searchable">
|
<tbody class="searchable">
|
||||||
<tr><td colspan="3"><i>None ...</i></td></tr>
|
<tr><td colspan="3"><i>{% trans 'None' %}...</i></td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1271,8 +1317,6 @@
|
||||||
<script src="{% static "js/ace.js" %}" type="text/javascript" charset="utf-8"></script>
|
<script src="{% static "js/ace.js" %}" type="text/javascript" charset="utf-8"></script>
|
||||||
<script>
|
<script>
|
||||||
function get_volumes(compute_id, pool) {
|
function get_volumes(compute_id, pool) {
|
||||||
|
|
||||||
|
|
||||||
get_vol_url = "/computes/" + compute_id + "/storage/" + pool + "/volumes";
|
get_vol_url = "/computes/" + compute_id + "/storage/" + pool + "/volumes";
|
||||||
$.getJSON(get_vol_url, function (data) {
|
$.getJSON(get_vol_url, function (data) {
|
||||||
$("#vols").find('option').remove();
|
$("#vols").find('option').remove();
|
||||||
|
@ -1281,8 +1325,7 @@
|
||||||
$.each(data['vols'], function(i, item) {
|
$.each(data['vols'], function(i, item) {
|
||||||
$("#vols").append('<option value=' + item +'>' + item + '</option>');
|
$("#vols").append('<option value=' + item +'>' + item + '</option>');
|
||||||
|
|
||||||
});
|
})
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var sto_drop = document.getElementById('select_storage');
|
var sto_drop = document.getElementById('select_storage');
|
||||||
|
@ -1292,7 +1335,6 @@
|
||||||
var sto_input = document.getElementById('selected_storage');
|
var sto_input = document.getElementById('selected_storage');
|
||||||
sto_input.value = pool;
|
sto_input.value = pool;
|
||||||
sto_input.innerHTML = pool;
|
sto_input.innerHTML = pool;
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1415,7 +1457,6 @@
|
||||||
});
|
});
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
// set vdi url
|
// set vdi url
|
||||||
|
|
||||||
$.get("{% url 'vdi_url' vname %}", function(data) {
|
$.get("{% url 'vdi_url' vname %}", function(data) {
|
||||||
$("#vdi_url_input").attr("value", data);
|
$("#vdi_url_input").attr("value", data);
|
||||||
$("#vdi_url").attr("href", data);
|
$("#vdi_url").attr("href", data);
|
||||||
|
@ -1444,6 +1485,72 @@ $(document).ready(function(){
|
||||||
placement : 'top'
|
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>
|
||||||
<script>
|
<script>
|
||||||
$(function () {
|
$(function () {
|
||||||
|
@ -1619,7 +1726,7 @@ $(document).ready(function(){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (~$.inArray(hash, ['#media', "#disks", '#network', '#clone', '#autostart', '#xmledit', '#vncsettings', '#migrate', '#options', '#users'])) {
|
if (~$.inArray(hash, ['#boot_opt', "#disks", '#network', '#clone', '#xmledit', '#vncsettings', '#migrate', '#options', '#users'])) {
|
||||||
var btnsect = $('#navbtn>li>a');
|
var btnsect = $('#navbtn>li>a');
|
||||||
$(btnsect).each(function () {
|
$(btnsect).each(function () {
|
||||||
if ($(this).attr('href') === '#settings') {
|
if ($(this).attr('href') === '#settings') {
|
||||||
|
|
|
@ -255,6 +255,8 @@ def instance(request, compute_id, vname):
|
||||||
compute_nwfilters = conn.get_nwfilters()
|
compute_nwfilters = conn.get_nwfilters()
|
||||||
status = conn.get_status()
|
status = conn.get_status()
|
||||||
autostart = conn.get_autostart()
|
autostart = conn.get_autostart()
|
||||||
|
bootmenu = conn.get_bootmenu()
|
||||||
|
boot_order = conn.get_bootorder()
|
||||||
vcpu = conn.get_vcpu()
|
vcpu = conn.get_vcpu()
|
||||||
cur_vcpu = conn.get_cur_vcpu()
|
cur_vcpu = conn.get_cur_vcpu()
|
||||||
uuid = conn.get_uuid()
|
uuid = conn.get_uuid()
|
||||||
|
@ -525,7 +527,7 @@ def instance(request, compute_id, vname):
|
||||||
conn.attach_disk("", target, device='cdrom', cache='none', targetbus=bus)
|
conn.attach_disk("", target, device='cdrom', cache='none', targetbus=bus)
|
||||||
msg = _('Add CD-Rom: ' + target)
|
msg = _('Add CD-Rom: ' + target)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#media')
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
||||||
|
|
||||||
if 'detach_cdrom' in request.POST and allow_admin_or_not_template:
|
if 'detach_cdrom' in request.POST and allow_admin_or_not_template:
|
||||||
dev = request.POST.get('detach_cdrom', '')
|
dev = request.POST.get('detach_cdrom', '')
|
||||||
|
@ -533,7 +535,7 @@ def instance(request, compute_id, vname):
|
||||||
conn.detach_disk(dev)
|
conn.detach_disk(dev)
|
||||||
msg = _('Detach CD-Rom: ' + dev)
|
msg = _('Detach CD-Rom: ' + dev)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#media')
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
||||||
|
|
||||||
if 'umount_iso' in request.POST and allow_admin_or_not_template:
|
if 'umount_iso' in request.POST and allow_admin_or_not_template:
|
||||||
image = request.POST.get('path', '')
|
image = request.POST.get('path', '')
|
||||||
|
@ -541,7 +543,7 @@ def instance(request, compute_id, vname):
|
||||||
conn.umount_iso(dev, image)
|
conn.umount_iso(dev, image)
|
||||||
msg = _("Mount media: " + dev)
|
msg = _("Mount media: " + dev)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#media')
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
||||||
|
|
||||||
if 'mount_iso' in request.POST and allow_admin_or_not_template:
|
if 'mount_iso' in request.POST and allow_admin_or_not_template:
|
||||||
image = request.POST.get('media', '')
|
image = request.POST.get('media', '')
|
||||||
|
@ -549,7 +551,7 @@ def instance(request, compute_id, vname):
|
||||||
conn.mount_iso(dev, image)
|
conn.mount_iso(dev, image)
|
||||||
msg = _("Umount media: " + dev)
|
msg = _("Umount media: " + dev)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#media')
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
||||||
|
|
||||||
if 'snapshot' in request.POST and allow_admin_or_not_template:
|
if 'snapshot' in request.POST and allow_admin_or_not_template:
|
||||||
name = request.POST.get('name', '')
|
name = request.POST.get('name', '')
|
||||||
|
@ -591,13 +593,37 @@ def instance(request, compute_id, vname):
|
||||||
conn.set_autostart(1)
|
conn.set_autostart(1)
|
||||||
msg = _("Set autostart")
|
msg = _("Set autostart")
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#autostart')
|
return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
|
||||||
|
|
||||||
if 'unset_autostart' in request.POST:
|
if 'unset_autostart' in request.POST:
|
||||||
conn.set_autostart(0)
|
conn.set_autostart(0)
|
||||||
msg = _("Unset autostart")
|
msg = _("Unset autostart")
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#autostart')
|
return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
|
||||||
|
|
||||||
|
if 'set_bootmenu' in request.POST:
|
||||||
|
conn.set_bootmenu(1)
|
||||||
|
msg = _("Enable boot menu")
|
||||||
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
|
return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
|
||||||
|
|
||||||
|
if 'unset_bootmenu' in request.POST:
|
||||||
|
conn.set_bootmenu(0)
|
||||||
|
msg = _("Disable boot menu")
|
||||||
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
|
return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
|
||||||
|
|
||||||
|
if 'set_bootorder' in request.POST:
|
||||||
|
bootorder = request.POST.get('bootorder', '')
|
||||||
|
if bootorder:
|
||||||
|
order_list = {}
|
||||||
|
for idx, val in enumerate(bootorder.split(',')):
|
||||||
|
type, dev = val.split(':', 1)
|
||||||
|
order_list[idx] = {"type": type, "dev": dev}
|
||||||
|
conn.set_bootorder(order_list)
|
||||||
|
msg = _("Set boot order")
|
||||||
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
|
return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
|
||||||
|
|
||||||
if 'change_xml' in request.POST:
|
if 'change_xml' in request.POST:
|
||||||
exit_xml = request.POST.get('inst_xml', '')
|
exit_xml = request.POST.get('inst_xml', '')
|
||||||
|
|
|
@ -133,3 +133,21 @@ p {
|
||||||
display: inline;
|
display: inline;
|
||||||
min-width: 250px;
|
min-width: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.multiselect {
|
||||||
|
width:27em;
|
||||||
|
height:10em;
|
||||||
|
border:solid 2px #c0c0c0;
|
||||||
|
overflow:auto;
|
||||||
|
padding: 0 1em;
|
||||||
|
margin: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiselect label {
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiselect-on {
|
||||||
|
color:#ffffff;
|
||||||
|
background-color:#000099;
|
||||||
|
}
|
|
@ -248,7 +248,7 @@ class wvmInstance(wvmConnect):
|
||||||
def disks(doc):
|
def disks(doc):
|
||||||
result = []
|
result = []
|
||||||
dev = volume = storage = src_file = None
|
dev = volume = storage = src_file = None
|
||||||
disk_format = used_size = disk_size = None
|
disk_format = used_size = disk_size = disk_cache = None
|
||||||
|
|
||||||
for disk in doc.xpath('/domain/devices/disk'):
|
for disk in doc.xpath('/domain/devices/disk'):
|
||||||
device = disk.xpath('@device')[0]
|
device = disk.xpath('@device')[0]
|
||||||
|
@ -259,6 +259,9 @@ class wvmInstance(wvmConnect):
|
||||||
src_file = disk.xpath('source/@file|source/@dev|source/@name|source/@volume')[0]
|
src_file = disk.xpath('source/@file|source/@dev|source/@name|source/@volume')[0]
|
||||||
try:
|
try:
|
||||||
disk_format = disk.xpath('driver/@type')[0]
|
disk_format = disk.xpath('driver/@type')[0]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
disk_cache = disk.xpath('driver/@cache')[0]
|
disk_cache = disk.xpath('driver/@cache')[0]
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
@ -310,6 +313,121 @@ class wvmInstance(wvmConnect):
|
||||||
|
|
||||||
return util.get_xml_path(self._XMLDesc(0), func=disks)
|
return util.get_xml_path(self._XMLDesc(0), func=disks)
|
||||||
|
|
||||||
|
def get_bootmenu(self):
|
||||||
|
menu = util.get_xml_path(self._XMLDesc(0), "/domain/os/bootmenu/@enable")
|
||||||
|
return True if menu == 'yes' else False
|
||||||
|
|
||||||
|
def set_bootmenu(self, flag):
|
||||||
|
tree = ElementTree.fromstring(self._XMLDesc(0))
|
||||||
|
os = tree.find('os')
|
||||||
|
menu = os.find("bootmenu")
|
||||||
|
|
||||||
|
if menu == None:
|
||||||
|
bootmenu = ElementTree.fromstring("<bootmenu enable='yes'/>")
|
||||||
|
os.append(bootmenu)
|
||||||
|
menu = os.find("bootmenu")
|
||||||
|
|
||||||
|
if flag == 0: # Disable
|
||||||
|
menu.attrib['enable'] = 'no'
|
||||||
|
elif flag == 1: # Enable
|
||||||
|
menu.attrib['enable'] = 'yes'
|
||||||
|
elif flag == -1: # Remove
|
||||||
|
os.remove(menu)
|
||||||
|
else:
|
||||||
|
raise Exception('Unknown boot menu option, please choose one of 0:disable, 1:enable, -1:remove')
|
||||||
|
|
||||||
|
xmldom = ElementTree.tostring(tree)
|
||||||
|
self._defineXML(xmldom)
|
||||||
|
|
||||||
|
def get_bootorder(self):
|
||||||
|
boot_order = {}
|
||||||
|
tree = ElementTree.fromstring(self._XMLDesc(0))
|
||||||
|
os = tree.find('os')
|
||||||
|
boot = os.findall('boot')
|
||||||
|
|
||||||
|
for idx, b in enumerate(boot):
|
||||||
|
dev = b.get('dev')
|
||||||
|
if dev == 'hd':
|
||||||
|
target = "disk"
|
||||||
|
type = "file"
|
||||||
|
elif dev == 'fd':
|
||||||
|
target = "floppy"
|
||||||
|
type = "file"
|
||||||
|
elif dev == 'cdrom':
|
||||||
|
target = "cdrom"
|
||||||
|
type = "file"
|
||||||
|
elif dev == 'network':
|
||||||
|
target = "network"
|
||||||
|
type = "network"
|
||||||
|
boot_order[idx] = {"type": type, "dev": dev, "target": target}
|
||||||
|
|
||||||
|
devices = tree.find('devices')
|
||||||
|
for dev in devices:
|
||||||
|
dev_target = dev_type = dev_device = dev_alias = None
|
||||||
|
boot_dev = dev.find('boot')
|
||||||
|
if boot_dev != None:
|
||||||
|
idx = boot_dev.get('order')
|
||||||
|
dev_type = dev.get('type')
|
||||||
|
dev_device = dev.get('device')
|
||||||
|
|
||||||
|
if dev_type == 'file':
|
||||||
|
dev_target = dev.find('target').get('dev')
|
||||||
|
|
||||||
|
elif dev_type == 'network':
|
||||||
|
dev_mac = dev.find('mac').get('address')
|
||||||
|
dev_device = "network"
|
||||||
|
dev_target = "nic-{}".format(dev_mac[9:])
|
||||||
|
elif dev_type == 'usb':
|
||||||
|
pass
|
||||||
|
|
||||||
|
boot_order[int(idx)-1] = {"type": dev_type, "dev": dev_device, "target": dev_target}
|
||||||
|
|
||||||
|
return boot_order
|
||||||
|
|
||||||
|
def set_bootorder(self, devorder):
|
||||||
|
if not devorder:
|
||||||
|
return
|
||||||
|
|
||||||
|
def remove_bootorder():
|
||||||
|
tree = ElementTree.fromstring(self._XMLDesc(0))
|
||||||
|
os = tree.find('os')
|
||||||
|
boot = os.findall('boot')
|
||||||
|
# Remove old style boot order
|
||||||
|
for b in boot:
|
||||||
|
os.remove(b)
|
||||||
|
# Remove rest of them
|
||||||
|
for dev in tree.find('devices'):
|
||||||
|
boot_dev = dev.find('boot')
|
||||||
|
if boot_dev != None:
|
||||||
|
dev.remove(boot_dev)
|
||||||
|
return tree
|
||||||
|
|
||||||
|
tree = remove_bootorder()
|
||||||
|
|
||||||
|
for idx, dev in devorder.items():
|
||||||
|
order = ElementTree.fromstring("<boot order='{}'/>".format(idx + 1))
|
||||||
|
if dev['type'] == 'disk':
|
||||||
|
devices = tree.findall("./devices/disk[@device='disk']")
|
||||||
|
for d in devices:
|
||||||
|
device = d.find("./target[@dev='{}']".format(dev['dev']))
|
||||||
|
if device != None:
|
||||||
|
d.append(order)
|
||||||
|
elif dev['type'] == 'cdrom':
|
||||||
|
devices = tree.findall("./devices/disk[@device='cdrom']")
|
||||||
|
for d in devices:
|
||||||
|
device = d.find("./target[@dev='{}']".format(dev['dev']))
|
||||||
|
if device != None:
|
||||||
|
d.append(order)
|
||||||
|
elif dev['type'] == 'network':
|
||||||
|
devices = tree.findall("./devices/interface[@type='network']")
|
||||||
|
for d in devices:
|
||||||
|
device = d.find("mac[@address='{}']".format(dev['dev']))
|
||||||
|
if device != None:
|
||||||
|
d.append(order)
|
||||||
|
else:
|
||||||
|
raise Exception('Invalid Device Type for boot order')
|
||||||
|
self._defineXML(ElementTree.tostring(tree))
|
||||||
|
|
||||||
def mount_iso(self, dev, image):
|
def mount_iso(self, dev, image):
|
||||||
def attach_iso(dev, disk, vol):
|
def attach_iso(dev, disk, vol):
|
||||||
if disk.get('device') == 'cdrom':
|
if disk.get('device') == 'cdrom':
|
||||||
|
|
Loading…
Reference in a new issue