Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_list.html @ bcb81dc8

History | View | Annotate | Download (19.4 kB)

1
<!--
2
Copyright 2011 GRNET S.A. All rights reserved.
3

4
Redistribution and use in source and binary forms, with or
5
without modification, are permitted provided that the following
6
conditions are met:
7

8
  1. Redistributions of source code must retain the above
9
     copyright notice, this list of conditions and the following
10
     disclaimer.
11

12
  2. Redistributions in binary form must reproduce the above
13
     copyright notice, this list of conditions and the following
14
     disclaimer in the documentation and/or other materials
15
     provided with the distribution.
16

17
THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
POSSIBILITY OF SUCH DAMAGE.
29

30
The views and conclusions contained in the software and
31
documentation are those of the authors and should not be
32
interpreted as representing official policies, either expressed
33
or implied, of GRNET S.A.
34
-->
35

    
36
{% load i18n %}
37

    
38
<div id="machinesview-list" class="list">
39
    <div class="large-spinner"></div>
40
    <div id="machinesview_content">
41
        <div class="actions">
42
            <a id="action-start">{% trans "Start" %}</a>
43
            <a id="action-reboot">{% trans "Reboot" %}</a>
44
            <a id="action-shutdown">{% trans "Shutdown" %}</a>
45
            <br />
46
            <a id="action-destroy">{% trans "Destroy" %}</a>
47
            <br />
48
            <a id="action-details">{% trans "Show Details" %}</a>
49
            {% comment %}<a id="action-group">{% trans "Add to group" %}</a>{% endcomment %}
50
            <br />
51
            <a id="action-console">{% trans "Console" %}</a>
52
            <a id="action-connect">{% trans "Connect" %}</a>
53
            <br />
54
            {% comment %}
55
            <a id="action-attach">{% trans "Attach disk" %}</a>
56
            <a id="action-detach">{% trans "Detach disk" %}</a>
57
            <br />
58
            <a id="action-network-connect">{% trans "Connect to network" %}</a>
59
            <a id="action-network-disconnect">{% trans "Disconnect from net" %}</a>
60
            {% endcomment %}
61
        </div>
62
        <table class="list-machines" style="display: none">
63
            <thead>
64
                <tr>
65
                    <th class="selection select-running">
66
                        <input type="checkbox"/>
67
                        <!-- Drop down selector is commented out for v0.5
68
                        <div class="expand-icon"></div>
69
                        -->
70
                    </th>
71
                    <th class="vmos">{% trans "OS" %}</th>
72
                    <th class="vmname">{% trans "Name" %}</th>
73
                    <th class="vmflavor">{% trans "Flavor" %}</th>
74
                    <th class="vmgroup">{% trans "Group" %}</th>
75
                    <th class="vmstatus">{% trans "Status" %}</th>
76
                </tr>
77
            </thead>
78
            <tbody class="machines"></tbody>
79
        </table>
80
        <!-- Drop down selector is commented out for v0.5
81
        <ul class="dropdown-selector" style="display: none">
82
            <li class="select-all" ><a href="#">{% trans "all" %}</a></li>
83
            <li class="select-none"><a href="#">{% trans "none" %}</a></li>
84
            <li class="select-group"><a href="#">{% trans "group" %}</a></li>
85
        </ul>
86
        -->
87
    </div>
88
</div>
89

    
90
<script>
91

92
// select/deselect all from checkbox widget of table headers
93
$("#machinesview .list table thead tr th.selection :checkbox").live('change', function() {
94
    if ( $(this).is(":checked") ) {
95
        $(":checkbox").attr("checked", true);
96
    }
97
    else {
98
        $(":checkbox").attr("checked", false);
99
    }
100
    update_listview_actions();
101
    return false;
102
});
103

104
/* Drop down selector is commented out for v0.5
105
// select all from drop down menu
106
$("#machinesview .list ul.dropdown-selector li.select-all a").live('click', function() {
107
    $(":checkbox").attr("checked", true);
108
    $(".dropdown-selector").slideToggle('medium');
109
    update_listview_actions();
110
    return false;
111
});
112

113
// select none from drop down menu
114
$("#machinesview .list ul.dropdown-selector li.select-none a").live('click', function() {
115
    $(":checkbox").attr("checked", false);
116
    $(".dropdown-selector").slideToggle('medium');
117
    update_listview_actions();
118
    return false;
119
});
120

121
// select group from drop down menu
122
$("#machinesview .list ul.dropdown-selector li.select-group a").live('click', function() {
123
    $(":checkbox").attr("checked", true);
124
    $(".dropdown-selector").slideToggle('medium');
125
    update_listview_actions();
126
    return false;
127
});
128

129
// menu toggle, running menu
130
$("#machinesview .list table.list-machines thead tr th.selection .expand-icon").click( function (obj) {
131
    $(".dropdown-selector").slideToggle('medium');
132
    return false;
133
});
134

135
*/
136

137
// TODO: This should be populated with more rules for all available states
138
//a key represents an action, while values are lists with permitted states to which the action can be applied
139
var actions = { 'reboot':        ['UNKOWN', 'ACTIVE', 'REBOOT', 'multiple'],
140
                'shutdown':      ['UNKOWN', 'ACTIVE', 'REBOOT', 'multiple'],
141
                'connect':       ['UNKOWN', 'ACTIVE'],
142
                //'network-connect':       ['UNKOWN', 'ACTIVE'],
143
                //'network-disconnect':    ['UNKOWN', 'ACTIVE', 'network'],
144
                'console':       ['UNKOWN', 'ACTIVE', 'multiple'],
145
                'details':       ['UNKOWN', 'ACTIVE', 'REBOOT', 'STOPPED'],
146
                'start':         ['UNKOWN', 'STOPPED', 'multiple'],
147
                'destroy':       ['UNKOWN', 'ACTIVE', 'STOPPED', 'REBOOT', 'ERROR', 'BUILD', 'multiple']
148
                //'group':         ['UNKOWN', 'ACTIVE', 'STOPPED', 'REBOOT','multiple'],
149
               };
150

151
// on checkbox click, update the actions
152
$("#machinesview .list tbody input[type='checkbox']").live('change', function() {
153
    update_listview_actions();
154
    pending_actions = [];
155
    $(".selected").removeClass('selected');
156
    return false;
157
});
158

159
// destroy action
160
$("#machinesview .list a.enabled#action-destroy").live('click', function() {
161
    var checked = $("#machinesview .list table.list-machines tbody input[type='checkbox']:checked");
162
    $("#machinesview .list .selected").removeClass('selected');
163
    $(this).addClass('selected');
164
    pending_actions = []; // reset pending actions
165
    checked.each(function(i,c) {
166
        serverID=c.id;
167
        serverName = $('#machinesview .list #'+serverID+' span.name').text();
168
        pending_actions.push([destroy, serverID]);
169
    });
170
    update_confirmations();
171
    return false;
172
});
173

174
$("#machinesview .list a.enabled#action-reboot").live('click', function() {
175
    var checked = $("#machinesview .list table.list-machines tbody input[type='checkbox']:checked");
176
    $("#machinesview .list .selected").removeClass('selected');
177
    $(this).addClass('selected');
178
    pending_actions = []; // reset pending actions
179
    checked.each(function(i,c) {
180
        serverID=c.id;
181
        serverName = $('#machinesview .list #'+serverID+' span.name').text();
182
        pending_actions.push([reboot, serverID]);
183
    });
184
    update_confirmations();
185
    return false;
186
});
187

188
$("#machinesview .list a.enabled#action-start").live('click', function() {
189
    var checked = $("#machinesview .list table.list-machines tbody input[type='checkbox']:checked");
190
    $("#machinesview .list .selected").removeClass('selected');
191
    $(this).addClass('selected');
192
    pending_actions = []; // reset pending actions
193
    checked.each(function(i,c) {
194
        serverID=c.id;
195
        serverName = $('#machinesview .list #'+serverID+' span.name').text();
196
        pending_actions.push([start, serverID]);
197
    });
198
    update_confirmations();
199
    return false;
200
});
201

202
$("#machinesview .list a.enabled#action-shutdown").live('click', function() {
203
    var checked = $("#machinesview .list table.list-machines tbody input[type='checkbox']:checked");
204
    $("#machinesview .list .selected").removeClass('selected');
205
    $(this).addClass('selected');
206
    pending_actions = []; // reset pending actions
207
    checked.each(function(i,c) {
208
        serverID=c.id;
209
        serverName = $('#machinesview .list #'+serverID+' span.name').text();
210
        pending_actions.push([shutdown, serverID]);
211
    });
212
    update_confirmations();
213
    return false;
214
});
215

216
$("#machinesview .list a.enabled#action-console").live('click', function() {
217
    var checked = $("#machinesview .list table.list-machines tbody input[type='checkbox']:checked");
218
    $("#machinesview .list .selected").removeClass('selected');
219
    $(this).addClass('selected');
220
    pending_actions = []; // reset pending actions
221
    checked.each(function(i,c) {
222
        serverID=c.id;
223
        serverName = $('#machinesview .list #'+serverID+' span.name').text();
224
        pending_actions.push([open_console, serverID]);
225
    });
226
    update_confirmations();
227
    return false;
228
});
229

230
$("#machinesview .list a.enabled#action-details").live('click', function() {
231
    var checked = $("#machinesview .list table.list-machines tbody input[type='checkbox']:checked");
232
    $("#machinesview .list .selected").removeClass('selected');
233
    $(this).addClass('selected');
234
    pending_actions = []; // reset pending actions
235
    checked.each(function(i,c) {
236
        serverID=c.id;
237
    });
238
    $.cookie('server', serverID);
239
    $('a#single').click();
240
    return false;
241
});
242

243

244
function update_machines_view(data){
245
    /*
246
    Go through the servers in the input data. Update existing entries, add
247
    new ones to the list
248
    */
249
    tableData = vmTable.fnGetData();
250

251
    $.each(data.servers.values, function(i,server){
252
        current = -1;
253
        // check server status to select the appropriate OS icon, defaults to on state
254
        osTag = os_icon(server.metadata);
255
        var osIcon = osTag + "-on.png", imgStr, imgSrc;
256
        // check if the server already exists in the datatable
257
        if (tableData.length > 0) {
258
            tableData.forEach(function(row,index){
259
                if (row[0].split(' ')[2].replace('id=','') == server.id){
260
                    current = index;
261
                }
262
            });
263
        }
264
        if (current != -1) { // if it's there, update the values
265
            // get current status description, including non api states
266
            var server_row = $('#machinesview .list #' + server.id).parent().parent();
267
            var status_desc = server_row.find('span.status').text();
268
            // firebug console logging
269
            try {
270
                console.info(server.name + ' from ' + status_desc + ' to ' + STATUSES[server.status]);
271
            } catch(err) {}
272
            // when server is in deleted status it must be removed from the list
273
            if (server.status == "DELETED") {
274
                vmTable.fnDeleteRow(current);
275
            } else { // when server is not deleted, it should be updated
276
                if (['BUILD','ACTIVE','REBOOT'].indexOf(server.status) >= 0 &&
277
                    [STATUSES['STOPPED'], STATUSES['ERROR'], STATUSES['UNKNOWN'],
278
                     TRANSITIONS['Starting']].indexOf(server_row.find('span.status').text()) >= 0) {
279
                    // from stopped, on error or starting to building, active or rebooting
280
                    // starting is not an api state, it means the server is stopped or on error
281
                    tableData[current][0] = "<input class="+server.status+" id="+server.id+" type=checkbox>";
282
                    imgSrc = "static/icons/indicators/small/wave.gif";
283
                    imgStr = "<img class=list-logo src=" + imgSrc + " title=" + osTag + "></img>";
284
                    tableData[current][1] = "<span class=imagetag>" + osTag + "</span>" + imgStr;
285
                    tableData[current][2] = "<a class=name><span class=name>" + server.name.substring(0,60) + "</span></a>";
286
                    //tableData[current][4] = "group"; //TODO
287
                    tableData[current][5] = "<span class=status>" + STATUSES[server.status] + "</span>";
288
                    vmTable.fnUpdate(tableData[current],current);
289
                    setTimeout("$('#machinesview .list #"+server.id+"').parent().parent().find('.list-logo').attr('src','static/icons/machines/small/" + osIcon + "')", 1600);
290
                } else if (['STOPPED','ERROR', 'UNKNOWN'].indexOf(server.status) >= 0 &&
291
                           [STATUSES['ACTIVE'], STATUSES['BUILD'], STATUSES['REBOOT'],
292
                            TRANSITIONS['Shutting down']].indexOf(server_row.find('span.status').text()) >= 0) {
293
                    tableData[current][0] = "<input class="+server.status+" id="+server.id+" type=checkbox>";
294
                    imgSrc = "static/icons/indicators/small/wave.gif";
295
                    imgStr = "<img class=list-logo src=" + imgSrc + " title=" + osTag + "></img>";
296
                    tableData[current][1] = "<span class=imagetag>" + osTag + "</span>" + imgStr;
297
                    tableData[current][2] = "<a class=name><span class=name>" + server.name.substring(0,60) + "</span></a>";
298
                    //tableData[current][4] = "group"; //TODO
299
                    tableData[current][5] = "<span class=status>" + STATUSES[server.status] + "</span>";
300
                    vmTable.fnUpdate(tableData[current],current);
301
                    setTimeout("$('#machinesview .list #"+server.id+"').parent().parent().find('.list-logo').attr('src','static/icons/machines/small/" + osTag + "-off.png')", 1600);
302
                } else if ( STATUSES[server.status] == server_row.find('span.status').text()) {
303

304
                } else if (server.status == 'ACTIVE' &&
305
                           [STATUSES['BUILD'],TRANSITIONS['Rebooting']].indexOf(server_row.find('span.status').text()) >= 0) {
306
                    tableData[current][0] = "<input class="+server.status+" id="+server.id+" type=checkbox>";
307
                    imgSrc = "static/icons/indicators/small/wave.gif";
308
                    imgStr = "<img class=list-logo src=" + imgSrc + " title=" + osTag + "></img>";
309
                    tableData[current][1] = "<span class=imagetag>" + osTag + "</span>" + imgStr;
310
                    tableData[current][2] = "<a class=name><span class=name>" + server.name.substring(0,60) + "</span></a>";
311
                    //tableData[current][4] = "group"; //TODO
312
                    tableData[current][5] = "<span class=status>" + STATUSES[server.status] + "</span>";
313
                    vmTable.fnUpdate(tableData[current],current);
314
                    setTimeout("$('#machinesview .list #"+server.id+"').parent().parent().find('.list-logo').attr('src','static/icons/machines/small/" + osIcon + "')", 1600);
315
                }
316
            }
317
            update_listview_actions();
318
        } else if (server.status != "DELETED") { // does not exist, we should create it
319
            // check server status to select the appropriate OS icon
320
            if (['ERROR', 'STOPPED', 'UNKNOWN'].indexOf(server.status) >= 0) {
321
                osIcon = "static/icons/machines/small/" + osTag + "-off.png";
322
            } else if ( server.status == 'BUILD') {
323
                osIcon = "static/icons/indicators/small/progress.gif";
324
            } else {
325
                osIcon = "static/icons/machines/small/" + osTag + "-on.png";
326
            }
327
            // find flavor parameters
328
            var flavorLabel;
329
            if ( flavors.length > 0 ) {
330
                var current_flavor = '';
331
                for (i=0; i<flavors.length; i++) {
332
                    if (flavors[i]['id'] == server.flavorRef) {
333
                        current_flavor = flavors[i];
334
                    }
335
                }
336
                var flavor_label = '';
337
                if (current_flavor['cpu'] == '1') {
338
                    flavorLabel = '1 CPU, ';
339
                } else {
340
                    flavorLabel = current_flavor['cpu'] + ' CPUs, ';
341
                }
342
                flavorLabel = flavorLabel + current_flavor['ram'] + 'MB, ' + current_flavor['disk'] + 'GB';
343
            } else {
344
                flavorLabel = 'No flavor data';
345
            }
346

347
            // add new row to the table
348
            vmTable.fnAddData([
349
                "<input class=" + server.status + " id=" + server.id + " type=checkbox>",
350
                "<span class=imagetag>" + osTag + "</span><img class=list-logo src=" + osIcon +
351
                    " title=" + osTag + ">",
352
                "<a class=name><span class=name>" + server.name.substring(0,60) + "</span></a>",
353
                "<a class=flavor><span>"+ flavorLabel + "</span></a>",
354
                "group",
355
                "<span class=status>" + STATUSES[server.status] + "</span>"
356
            ]);
357
        }
358
    });
359
    update_listview_actions();
360
    $("#machinesview .list > div.large-spinner").hide();
361
    // in case there are no data, leave the page empty
362
    if ($("#machinesview .list table.list-machines tbody").length > 0) {
363
        $("#machinesview .list div.dataTables_filter").show();
364
        $("#machinesview .list div.dataTables_filter input").show();
365
        $("#machinesview .list table.list-machines").show();
366
        $("#machinesview .list div.actions").show();
367
    }
368

369
    // show message in case user has no servers!
370
    if ($("#machinesview .list tbody.machines .dataTables_empty").length > 0) {
371
        standard_view();
372
    } else {
373
        hideWelcome();
374
        $("#machinesview_content").fadeIn("fast");
375
    }
376

377
    // set confirm box position
378
    if (window.innerHeight - 200 < $('#machinesview').height())
379
        $('.confirm_multiple').addClass('fixed');
380
    else
381
        $('.confirm_multiple').removeClass('fixed');
382

383
    $('#machinesview .list .dataTables_scrollHeadInner table').attr('style','');
384
    $('#machinesview .list .dataTables_scrollHeadInner th').attr('style','');
385
}
386

387
function display_success(serverID) {
388
    // do nothing
389
}
390

391
// indicate that the requested action was not completed
392
function display_failure(status, serverID, action, responseText) {
393
    osIcon = $('#machinesview .list #'+serverID).parent().parent().find('.list-logo');
394
    osIcon.attr('src',osIcon.attr('os'));
395
    ajax_error(status, serverID, action, responseText);
396
}
397

398
var vmTable = $("div.list table.list-machines").dataTable({
399
    "bInfo": false,
400
    "bRetrieve": true,
401
    "bPaginate": false,
402
    "bAutoWidth": false,
403
    "bSort": true,
404
    "bStateSave": true,
405
    "sScrollXInner": "500px",
406
    "aoColumnDefs": [
407
        { "bSortable": false, "aTargets": [ 0 ] }
408
    ]
409
});
410

411
// basic functions executed on page load
412
if ( flavors.length == 0 && images.length == 0 ) {
413
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
414
    update_flavors();
415
    // populate image list
416
    update_images();
417
} else if ( flavors.length == 0 && images.length != 0 ) {
418
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
419
    update_flavors();
420
} else if ( flavors.length != 0 && images.length == 0 ) {
421
    // populate image list
422
    update_images();
423
    update_vms(UPDATE_INTERVAL);
424
} else {
425
    // start updating vm list
426
    update_vms(UPDATE_INTERVAL);
427
}
428

429
// reposition multiple confirmation box on window resize
430
$(window).resize(function(){
431
    if (this.innerHeight - 200 < $('#machinesview').height())
432
        $('.confirm_multiple').addClass('fixed');
433
    else
434
        $('.confirm_multiple').removeClass('fixed');
435
});
436

437
// set the label of the multiple buttons
438
$('.confirm_multiple button.yes').text(VARIOUS["CONFIRM"]);
439
$('.confirm_multiple button.no').text(VARIOUS["CANCEL"]);
440
</script>