1 {% extends
"menu_base.html" %}
4 {% block title %} {% trans
"Virtual Machine" %} {{ instance.hostname }}{% endblock %}
6 <link href=
"{{STATIC_URL}}/css/jquery-ui.css" rel=
"stylesheet" type=
"text/css"/>
7 <script src=
"{{STATIC_URL}}/js/jquery-ui.min.js"></script>
8 <script src=
"{{STATIC_URL}}/js/jquery.progressbar.js"></script>
9 <script type=
"text/javascript" src=
"{{STATIC_URL}}/js/jquery.form.js"></script>
10 <script type=
"text/javascript" src=
"{{STATIC_URL}}/js/jquery.ajax.delete.js"></script>
11 <script type=
"text/javascript">
15 $(document
).ready(function() {
19 select: function(event
, ui
) {
20 window
.location
.hash
= ui
.tab
.hash
;
25 {% ifnotequal instance
.info
.status
"running" %}
26 $('#tabs .ui-tabs-nav a[title=console]').parent()
27 .addClass('ui-state-disabled');
31 // confirmation dialogs for start, reinstall
32 $("#actions a.power").live("click", function(event
) {
33 event
.preventDefault();
34 if(!$(this).hasClass('disabled')) {
35 if(!confirm('Are you sure you want to '+ this.title
+ ' this VM?')) {
38 $.post(this.href
, action_response
);
42 // disable buttons that are actually links to other pages
43 $("#actions .edit").live("click", function(event
) {
44 return !$(this).hasClass('disabled');
47 $(".migrate").click(function(event
){
48 event
.preventDefault();
50 if(!$this.hasClass('disabled')) {
51 $('.qtip').qtip('destroy');
56 title
: {text
:"Migrate", button
:"close"}
58 position
: { corner
:{target
:'center', tooltip
:'center'}},
63 background
:'#eeeeee'},
64 show
: {when
:false, ready
:true},
65 hide
: {fixed
: true, when
:false},
66 api
:{onShow:function(){
67 $(".ajax_form input[type!=hidden], .ajax_form select")
74 $(".vm_migrate_form").live("submit", function(event
){
75 event
.preventDefault();
77 $(this).ajaxSubmit({success
: vm_form_response
});
80 $(".replace_disks").click(function(event
){
81 event
.preventDefault();
83 if(!$this.hasClass('disabled')) {
84 $('.qtip').qtip('destroy');
89 title
: {text
:"Replace Disks", button
:"close"}
91 position
: { corner
:{target
:'center', tooltip
:'center'}},
96 background
:'#eeeeee'},
97 show
: {when
:false, ready
:true},
98 hide
: {fixed
: true, when
:false},
99 api
:{onShow:function(){
100 $(".ajax_form input[type!=hidden], .ajax_form select")
107 $(".vm_replace_disks_form").live("submit", function(event
){
108 event
.preventDefault();
109 $("#errors").empty();
110 $(this).ajaxSubmit({success
: vm_form_response
});
113 job_poller
= new JobPoller();
115 var job_status_url
= "{% url instance-job-status instance.id %}";
116 var cluster_detail_url
= "{% url cluster-detail cluster.slug %}";
117 job_poller
.init(job_status_url
, cluster_detail_url
, job_complete
);
118 {% if instance
.last_job_id
%}
119 job_poller
.get_jobs();
122 {% if instance
.error
%}
123 display_ganeti_error("{{instance.error}}");
128 function job_complete() {
129 window
.location
.reload();
132 function action_response(result
) {
133 if(result
.ops
== undefined) {
134 display_ganeti_error(result
['__all__'][0]);
135 $('#actions a').removeClass('disabled');
137 job_poller
.render_job(result
);
138 job_poller
.poll(job_poller
.FAST
);
142 function vm_form_response(responseText
, statusText
, xhr
, $form
) {
143 if(responseText
["opstatus"] == undefined) {
144 // no opstatus, must be an error
146 for (var key
in responseText
) {
147 $("#errors").append("<li>"+ responseText
[key
] +"</li>");
150 $('.qtip').qtip("hide");
151 poll_job_status("{% url cluster-detail cluster.slug %}",
152 responseText
['id'], job_complete
);
153 display_job("{% url cluster-detail cluster.slug %}",
158 /* XXX: temporarily (maybe permanently) using this for reporting
159 when a quota limit has been encountered on startup */
160 function display_ganeti_error(msg
) {
161 $("#messages").empty();
162 var html
= "<li class='error'>Error:<p>" + msg
+ "</p></li>";
163 $("#messages").append(html
);
167 <script type=
"text/javascript" src=
"{{STATIC_URL}}/js/job_status.js"></script>
172 <h1 class=
"breadcrumb">
173 {% if view_cluster %}
174 <a href=
"{% url cluster-detail cluster.slug %}#virtual_machines">{{cluster.hostname|abbreviate_fqdn}}
</a>
176 <span>{{cluster.hostname|abbreviate_fqdn}}
</span>
178 : {{ instance.hostname }}
181 <ul id=
"messages"></ul>
185 <li><a href=
"#overview">{% trans
"Overview" %}
</a></li>
189 href=
"{% url vm-users cluster.slug instance.hostname %}">
195 href=
"{% url vm-object_log cluster.slug instance.hostname %}">
200 {% if admin or power %}
203 href=
"{% url instance-vnc cluster.slug instance.hostname %}">
204 {% trans
"Console" %}
209 <div id=
"overview" class=
"tab_content">
210 {% if instance.cluster.username %}
211 {% with instance.cluster.username as username %}
213 {# Start, Shutdown, Reboot #}
214 {% if admin or power %}
215 {% ifequal instance.info.status
"running" %}
217 <a class=
"button shutdown power" title=
"shut down" href=
"{% url instance-shutdown cluster.slug instance.hostname %}">
218 {% trans
"Shutdown" %}
221 {% if has_immediate_shutdown %}
223 <a class=
"button shutdown power"
224 title=
"Immediate Shutdown"
225 href=
"{% url instance-shutdown-now cluster.slug instance.hostname %}">
226 {% trans
"Immediate Shutdown" %}
231 <a class=
"button reboot power" title=
"reboot" href=
"{% url instance-reboot cluster.slug instance.hostname %}">
237 <a class=
"button startup power" title=
"start" href=
"{% url instance-startup cluster.slug instance.hostname %}">
246 <a class=
"button reinstall" title=
"reinstall" href=
"{% url instance-reinstall cluster.slug instance.hostname %}">
247 {% trans
"Reinstall" %}
254 <a class=
"button edit" href=
"{% url instance-modify cluster.slug instance.hostname %}">
260 {% if cluster_admin %}
262 <a class=
"button edit" href=
"{% url instance-reparent cluster.slug instance.hostname %}">
263 {% trans
"Change Owner" %}
270 <a class=
"button edit" href=
"{% url instance-rename cluster.slug instance.hostname %}">
275 {# Replace Disks and Migrate #}
276 {% if cluster_admin and instance|is_drbd %}
277 {% if replace_disks %}
279 <a class=
"button replace_disks" title=
"replace disks" href=
"{% url instance-replace-disks cluster.slug instance.hostname %}">
280 {% trans
"Replace Disks" %}
286 {% if instance|is_drbd or instance|is_shared %}
288 <a class=
"button migrate" title=
"migrate" href=
"{% url instance-migrate cluster.slug instance.hostname %}">
289 {% trans
"Migrate" %}
294 {# Create Template #}
295 {% if cluster_admin %}
297 <a class=
"button add" href=
"{% url template-create-from-instance cluster.slug instance.hostname %}">
298 {% trans
"Create Template" %}
305 <a class=
"button delete" title=
"Delete" href=
"{% url instance-delete cluster.slug instance.hostname %}">
314 {% with instance.info as info %}
316 <table class=
"overview horizontal">
317 <tr><th>{% trans
"Owner" %}
</th><td>{{ instance.owner.name }}
</td></tr>
318 <tr><th>{% trans
"Created on" %}
</th><td>{{ instance.ctime|date }}
</td></tr>
319 <tr><th>{% trans
"Last modified" %}
</th><td>{{ instance.mtime|date }}
</td></tr>
321 <th>{% trans
"Status" %}
</th>
322 <td>{{ info.oper_state|yesno:
"Running,Stopped" }}
</td>
324 <tr><th>{% trans
"Primary node" %}
</th><td>
325 {% if cluster_admin %}
326 <a href=
"{% url node-detail cluster.slug info.pnode %}">
333 <tr><th>{% trans
"Secondary node" %}
</th><td>
334 {% if cluster_admin %}
335 {% for host in info.snodes %}
336 <a href=
"{% url node-detail cluster.slug host %}">
339 {% if not forloop.last %}, {% endif %}
342 {{ info.snodes|join:
", " }}
346 <th>{% trans
"Operating System" %}
</th>
347 <td>{{ instance.operating_system|render_os }}
</td>
350 <th>{% trans
"Autostart" %}
</th>
351 <td>{{ info.admin_state|checkmark }}
</td>
355 <td>{{ info.pnode }}::{{ info.network_port }}
</td>
360 <table class=
"horizontal">
361 <tr><th>{% trans
"VCPUs" %}
</th><td>{{ instance.virtual_cpus }}
</td></tr>
362 <tr><th>{% trans
"Memory (Min/Max)" %}
</th><td>{{ instance.minram|render_storage }} / {{ instance.ram|render_storage }}
</td></tr>
363 <tr><th>{% trans
"NIC type" %}
</th><td>{{ info.hvparams.nic_type }}
</td></tr>
366 <h3>{% trans
"Disks" %}
</h3>
367 <table class=
"horizontal">
368 <tr><th>{% trans
"Disk Template" %}
</th><td>{{ info.disk_template }}
</td></tr>
369 <tr><th>{% trans
"Disk type" %}
</th><td>{{ info.hvparams.disk_type }}
</td></tr>
373 <th>{% trans
"Disk" %}
</th>
374 <th>{% trans
"Size" %}
</th>
376 {% for size in info|index:
"disk.sizes" %}
378 <td>disk/{{ forloop.counter0 }}
</td>
379 {#
<td>{{ info.hvparams.disk_type }}
</td> #}
380 <td>{{ size|render_storage }}
</td>
385 <h3>{% trans
"Network Devices" %}
</h3>
394 {% for mac in info|index:'nic.macs' %}
396 <td>nic/{{ forloop.counter0 }}
</td>
398 <td>{{ info|index:'nic.ips'|index:forloop.counter0 }}
</td>
400 {{ info|index:'nic.modes'|index:forloop.counter0 }}
403 {{ info|index:'nic.links'|index:forloop.counter0 }}
410 <table class=
"horizontal">
411 <tr><th>ACPI
</th><td>{{ info.hvparams.acpi|checkmark }}
</td></tr>
412 <tr><th>{% trans
"Boot Order" %}
</th><td>{{ info.hvparams.boot_order }}
</td></tr>
414 <th>{% trans
"CDROM Image Path" %}
</th>
415 <td>{{ info.hvparams.cdrom_image_path }}
</td>
418 <th>{% trans
"CDROM 2 Image Path" %}
</th>
419 <td>{{ info.hvparams.cdrom2_image_path }}
</td>
421 <tr><th>Disk Cache
</th><td>{{ info.hvparams.disk_cache }}
</td></tr>
423 <th>initrd Path
</th><td>{{ info.hvparams.initrd_path }}
</td>
426 <th>Kernel Args
</th><td>{{ info.hvparams.kernel_args }}
</td>
429 <th>Kernel Path
</th><td>{{ info.hvparams.kernel_path }}
</td>
431 <tr><th>KVM Flag
</th><td>{{ info.hvparams.kvm_flag }}
</td></tr>
432 <tr><th>Mem Path
</th><td>{{ info.hvparams.mem_path }}
</td></tr>
434 <th>Migration Downtime
</th>
435 <td>{{ info.hvparams.migration_downtime }}
</td>
437 <tr><th>Nic Type
</th><td>{{ info.hvparams.nic_type }}
</td></tr>
438 <tr><th>Network Port
</th><td>{{ info.network_port }}
</td></tr>
439 <tr><th>Root Path
</th><td>{{ info.hvparams.root_path }}
</td></tr>
441 <th>Security Domain
</th>
442 <td>{{ info.hvparams.security_domain }}
</td>
445 <th>Security Model
</th>
446 <td>{{ info.hvparams.security_model }}
</td>
449 <th>Serial Console
</th>
450 <td>{{ info.hvparams.serial_console|checkmark }}
</td>
452 <tr><th>USB Mouse
</th><td>{{ info.hvparams.usb_mouse }}
</td></tr>
455 <td>{{ info.hvparams.use_chroot|checkmark }}
</td>
458 <th>Use Localtime
</th>
459 <td>{{ info.hvparams.use_localtime|checkmark }}
</td>
462 <th>VNC Bind Address
</th>
463 <td>{{ info.hvparams.vnc_bind_address }}
</td>
466 <th>VNC Password File
</th>
467 <td>{{ info.hvparams.vnc_password_file }}
</td>
471 <td>{{ info.hvparams.vnc_tls|checkmark }}
</td>
474 <th>VNC x509 Path
</th>
475 <td>{{ info.hvparams.vnc_x509_path }}
</td>
478 <th>VNC x509 Verify
</th>
479 <td>{{ info.hvparams.vnc_x509_verify|checkmark }}
</td>