mirror of
https://github.com/retspen/webvirtcloud
synced 2024-12-24 15:15: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 %}
|
||||
{% 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>
|
||||
</a>
|
||||
|
||||
|
|
|
@ -526,8 +526,8 @@
|
|||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active">
|
||||
<a href="#media" aria-controls="media" role="tab" data-toggle="tab">
|
||||
{% trans "Media" %}
|
||||
<a href="#boot_opt" aria-controls="boot" role="tab" data-toggle="tab">
|
||||
{% trans "Boot" %}
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
|
@ -535,13 +535,6 @@
|
|||
{% trans "Disk" %}
|
||||
</a>
|
||||
</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 %}
|
||||
<li role="presentation">
|
||||
|
@ -593,78 +586,152 @@
|
|||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="media">
|
||||
{% if request.user.is_superuser and status == 5 %}
|
||||
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<button type="submit" name="add_cdrom" type="button" class="btn btn-success pull-right">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% for cd in media %}
|
||||
{% 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">
|
||||
<a class="col-sm-2 control-label"
|
||||
name="details"
|
||||
title="{% trans "Details" %}"
|
||||
tabindex="0"
|
||||
data-trigger="focus"
|
||||
data-toggle="popover"
|
||||
data-html="true"
|
||||
data-content="<strong>Bus:</strong> {{ cd.bus }} <br/> <strong>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>
|
||||
{% if status == 5 %}
|
||||
<button type="submit" class="btn btn-sm btn-danger pull-left" name="detach_cdrom" value="{{ cd.dev }}" style="margin-top: 2px;"><i class="glyphicon glyphicon-remove-circle"></i></button>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<button class="btn btn-sm btn-success pull-left disabled" style="margin-top: 2px;">{% trans "Mount" %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<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 %}
|
||||
<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 %}
|
||||
<input type="submit" class="btn btn-danger" name="unset_autostart" value="{% trans "Disable" %}">
|
||||
{% endifequal %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endfor %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="disks">
|
||||
<p style="font-weight:bold;">
|
||||
{% trans "Instance Volumes" %}
|
||||
{% include 'add_instance_volume.html' %}
|
||||
</p>
|
||||
|
||||
<div class="col-xs-12 col-sm-12">
|
||||
<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>
|
||||
</button>
|
||||
</p>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% 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>
|
||||
{% if status == 5 %}
|
||||
<button type="submit" class="btn btn-sm btn-danger pull-left" name="detach_cdrom" value="{{ cd.dev }}" style="margin-top: 2px;"><i class="glyphicon glyphicon-remove-circle"></i></button>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<button class="btn btn-sm btn-success pull-left disabled" style="margin-top: 2px;">{% trans "Mount" %}</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>
|
||||
{% endfor %}
|
||||
|
||||
<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>
|
||||
|
@ -726,21 +793,167 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="clearfix"></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 role="tabpanel" class="tab-pane tab-pane-bordered" id="autostart">
|
||||
<p>{% trans "Autostart your instance when host server is power on" %}</p>
|
||||
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
||||
{% ifequal autostart 0 %}
|
||||
<input type="submit" class="btn btn-lg btn-success pull-right" name="set_autostart" value="{% trans "Enable" %}">
|
||||
<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>
|
||||
<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 %}
|
||||
<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 %}
|
||||
</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 userinstance.is_vnc %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="vncsettings">
|
||||
|
@ -857,65 +1070,6 @@
|
|||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% 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 %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="clone">
|
||||
<p style="font-weight:bold;">{% trans "Create a clone" %}</p>
|
||||
|
@ -923,25 +1077,25 @@
|
|||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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 %}
|
||||
|
@ -1006,84 +1160,6 @@
|
|||
</form>
|
||||
<div class="clearfix"></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">
|
||||
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
||||
<div class="form-group">
|
||||
|
@ -1113,36 +1189,6 @@
|
|||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% 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>
|
||||
|
@ -1217,7 +1263,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody class="searchable">
|
||||
<tr><td colspan="3"><i>None ...</i></td></tr>
|
||||
<tr><td colspan="3"><i>{% trans 'None' %}...</i></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -1271,8 +1317,6 @@
|
|||
<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();
|
||||
|
@ -1281,8 +1325,7 @@
|
|||
$.each(data['vols'], function(i, item) {
|
||||
$("#vols").append('<option value=' + item +'>' + item + '</option>');
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
var sto_drop = document.getElementById('select_storage');
|
||||
|
@ -1292,7 +1335,6 @@
|
|||
var sto_input = document.getElementById('selected_storage');
|
||||
sto_input.value = pool;
|
||||
sto_input.innerHTML = pool;
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -1415,7 +1457,6 @@
|
|||
});
|
||||
$(document).ready(function () {
|
||||
// set vdi url
|
||||
|
||||
$.get("{% url 'vdi_url' vname %}", function(data) {
|
||||
$("#vdi_url_input").attr("value", data);
|
||||
$("#vdi_url").attr("href", data);
|
||||
|
@ -1444,6 +1485,72 @@ $(document).ready(function(){
|
|||
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 () {
|
||||
|
@ -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');
|
||||
$(btnsect).each(function () {
|
||||
if ($(this).attr('href') === '#settings') {
|
||||
|
|
|
@ -255,6 +255,8 @@ def instance(request, compute_id, vname):
|
|||
compute_nwfilters = conn.get_nwfilters()
|
||||
status = conn.get_status()
|
||||
autostart = conn.get_autostart()
|
||||
bootmenu = conn.get_bootmenu()
|
||||
boot_order = conn.get_bootorder()
|
||||
vcpu = conn.get_vcpu()
|
||||
cur_vcpu = conn.get_cur_vcpu()
|
||||
uuid = conn.get_uuid()
|
||||
|
@ -525,7 +527,7 @@ def instance(request, compute_id, vname):
|
|||
conn.attach_disk("", target, device='cdrom', cache='none', targetbus=bus)
|
||||
msg = _('Add CD-Rom: ' + target)
|
||||
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:
|
||||
dev = request.POST.get('detach_cdrom', '')
|
||||
|
@ -533,7 +535,7 @@ def instance(request, compute_id, vname):
|
|||
conn.detach_disk(dev)
|
||||
msg = _('Detach CD-Rom: ' + dev)
|
||||
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:
|
||||
image = request.POST.get('path', '')
|
||||
|
@ -541,7 +543,7 @@ def instance(request, compute_id, vname):
|
|||
conn.umount_iso(dev, image)
|
||||
msg = _("Mount media: " + dev)
|
||||
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:
|
||||
image = request.POST.get('media', '')
|
||||
|
@ -549,7 +551,7 @@ def instance(request, compute_id, vname):
|
|||
conn.mount_iso(dev, image)
|
||||
msg = _("Umount media: " + dev)
|
||||
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:
|
||||
name = request.POST.get('name', '')
|
||||
|
@ -591,13 +593,37 @@ def instance(request, compute_id, vname):
|
|||
conn.set_autostart(1)
|
||||
msg = _("Set autostart")
|
||||
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:
|
||||
conn.set_autostart(0)
|
||||
msg = _("Unset autostart")
|
||||
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:
|
||||
exit_xml = request.POST.get('inst_xml', '')
|
||||
|
|
|
@ -133,3 +133,21 @@ p {
|
|||
display: inline;
|
||||
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):
|
||||
result = []
|
||||
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'):
|
||||
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]
|
||||
try:
|
||||
disk_format = disk.xpath('driver/@type')[0]
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
disk_cache = disk.xpath('driver/@cache')[0]
|
||||
except:
|
||||
pass
|
||||
|
@ -310,6 +313,121 @@ class wvmInstance(wvmConnect):
|
|||
|
||||
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 attach_iso(dev, disk, vol):
|
||||
if disk.get('device') == 'cdrom':
|
||||
|
|
Loading…
Reference in a new issue