Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_icon.html @ a5bc3755

History | View | Annotate | Download (30.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
<!-- the standard view -->
39
<div id="machinesview-icon" class="standard">
40
    <div class="large-spinner"></div>
41
    <div class="machine-container" id="machine-container-template" style="display:none">
42
        <div class="machine" id="machine-template" \>
43
            <div class="actions">
44
                <a href="#" class="action-start">{% trans "Start" %}</a>
45
                <a href="#" class="action-reboot">{% trans "Reboot" %}</a>
46
                <a href="#" class="action-shutdown">{% trans "Shutdown" %}</a>
47
                <a href="#" class="action-console">{% trans "Console" %}</a>
48
                <a href="#" class="action-destroy">{% trans "Destroy" %}</a>
49
            </div>
50
            <div class="confirm_single">
51
                <button class="yes">{% trans "Confirm" %}</button>
52
                <button class="no">{% trans "Cancel" %}</button>
53
            </div>
54
            <div class="action_error" align="center">
55
                {% trans "<span class='orange'>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
56
                <span class="code"></span>
57
                <span class="message"></span>
58
                <button class="details">{% trans "Details" %}</button>
59
            </div>
60
            <div class="state">
61
                <div class="status">{% trans "Running" %}</div>
62
                <div class="indicator1"></div>
63
                <div class="indicator2"></div>
64
                <div class="indicator3"></div>
65
                <div class="indicator4"></div>
66
                <img class="spinner" style="display:none" src="static/icons/indicators/medium/progress.gif" />
67
                <img class="wave" style="display:none" src="static/icons/indicators/medium/wave.gif" />
68
            </div>
69
            <div class='connect-border'></div>
70
            <div class='connect-arrow'></div>
71
            <img class="logo" src="" />
72
            <div href="#" class="name">
73
                <h5 class="namecontainer editable">
74
                    <span class="name">node.name</span><span class="rename"></span>
75
                    <div class="editbuttons" style="display:none">
76
                        <div class="save"></div>
77
                        <div class="cancel"></div>
78
                    </div>
79
                </h5>
80
            </div>
81
            <a href="#" class="ip">
82
                <h5>{% trans "IP" %}: <span class="public">node.public_ip</span></h5>
83
            </a>
84
            <div class="info">
85
                <div class="info-header">
86
                    <span class="info-label">{% trans "info" %}</span>
87
                    <div class="toggler down"></div>
88
                </div>
89
                <div class="info-content">
90
                    <div class="metadata-separator"></div>
91
                    <div class="metadata-container">
92
                        <div class="vm-details metadata-column">
93
                            {% trans "CPUs" %}: <span class="cpu-data">1</span><br />
94
                            {% trans "RAM" %}: <span class="ram-data">2048</span> (MB)<br />
95
                            {% trans "System Disk" %}: <span class="disk-data">20</span> (GB) <br /><br />
96
                            {% trans "Image" %}: <span class="image-data">Debian</span><br />
97
                            {% trans "Image Size" %}: <span class="image-size-data">2.3</span> (GB)
98
                        </div>
99
                        <div class="vm-stats metadata-column">
100
                            {% trans "CPU" %} <img src="static/cpu-bar.png" class="metadata-bar" /><br />
101
                            {% trans "RAM" %} <img src="static/ram-bar.png" class="metadata-bar" /><br />
102
                            {% trans "S.Disk" %} <img src="static/cpu-bar.png" class="metadata-bar" /><br />
103
                            {% trans "Net" %} <img src="static/net-bar.png" class="metadata-bar" /><br /><br />
104
                            {% trans "details" %}
105
                        </div>
106
                        <div class="vm-metadata metadata-column">
107
                            <div class="metadata-left">
108
                                {% trans "Metadata" %}: <br />
109
                                (<span class="metadata-count">0</span>)
110
                            </div>
111
                            <div class="metadata-keys-container">
112
                                <div class="scrollable vertical">
113
                                    <div class="items">
114
                                    </div>
115
                                </div>
116
                                <div class="metadata-actions">
117
                                    <div class="prev"></div>
118
                                    <div class="next"></div>
119
                                </div>
120
                            </div>
121
                            <a href="#" class="manage-metadata">{% trans "Manage Tags" %}</a>
122
                        </div>
123
                    </div>
124
                    <div class="metadata-separator"></div>
125
                </div>
126
            </div>
127
        </div>
128
        <div class="separator"></div>
129
    </div>
130
    <div class="running"></div>
131
    <div class="terminated" style="display:none;"></div>
132
</div>
133

    
134
<script>
135
CONFIRMBOX_OFFSET = 200;
136
// actions on mahcine hover
137
$("#machinesview-icon.standard .machine").live('mouseover', function() {
138
    // show connect button
139
    $(this).find("div.connect-arrow").show();
140
    $(this).find("div.connect-border").show();
141
    // change color of info button
142
    $(this).find(".info-header").addClass('info-hover');
143
});
144

145
$("#machinesview-icon.standard .machine").live('mouseout', function() {
146
    // hide connect button
147
    $(this).find("div.connect-arrow").hide();
148
    $(this).find("div.connect-border").hide();
149
    // change color of info button
150
    $(this).find(".info-header").removeClass('info-hover');
151
});
152

153

154
//hide the all of the info contents
155
$("#machinesview-icon.standard .info-content").hide();
156
//toggle the component with class info-content
157
$("#machinesview-icon.standard div.info").live('click', function() {
158
    if ($(this).find('.toggler').hasClass('up')) {
159
        $(this).find('.toggler').removeClass('up');
160
        $(this).find('.toggler').addClass('down');
161
    } else {
162
        $(this).find('.toggler').removeClass('down');
163
        $(this).find('.toggler').addClass('up');
164
    }
165
    $(this).find(".info-content").slideToggle(600);
166
    return false;
167
});
168

169
// intercept manage metadata click
170
$("#machinesview-icon.standard a.manage-metadata").live('click', function() {
171
    // get server name and server ID
172
    var serverID = $(this).parent().parent().parent().parent().parent().attr("id");
173
    var serverName = $(this).parent().parent().parent().parent().parent().find("span.name").text();
174
    // set server name to all related metadata dialogs
175
    $("#metadata-wizard div.machine-name").text(serverName);
176
    if ($(this).parent().parent().parent().parent().parent().parent().hasClass('terminated')) {
177
        $("#metadata-wizard div#on-off").text('off');
178
    } else {
179
        $("#metadata-wizard div#on-off").text('on');
180
    }
181
    // set server id to all related metadata dialogs
182
    $("#metadata-wizard p").text(serverID);
183
    show_metadata_wizard();
184
    return false;
185
});
186

187
//initiate machine renaming
188
$("#machinesview-icon.standard .rename, #machinesview-icon.standard h5.editable span.name").live('click', function() {
189
    $(this).parent().find('.name').html("<input id=\"txtEdit\" type=\"text\" class=\"nametextbox\" value=\"" +
190
                                        $(this).parent().find('.name').text() +
191
                                        "\" / ><span class=\"oldValue\">" +
192
                                        $(this).parent().find('.name').text() + "</span>");
193
    $(this).parent().find('.rename').hide();
194
    $(this).parent().find(".editbuttons").fadeIn();
195
    $(this).parent().find(".nametextbox").focus().select();
196
    $(this).parent().removeClass('editable');
197

198
    //submit wizard by pressing enter on the name textbox
199
    $("#txtEdit").keydown(function (e) {
200
        if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
201
            $(this).parent().parent().find('div.editbuttons span.save').click();
202
            return false;
203
        } else if ((e.which && e.which == 27) || (e.keyCode && e.keyCode == 27)) {
204
            $(this).parent().parent().find('div.editbuttons span.cancel').click();
205
            return true;
206
        }
207
    });
208
    return false;
209
});
210

211
//rename machine
212
$("#machinesview-icon.standard .editbuttons .save").live('click', function() {
213
    serverID = $(this).closest('.machine-container').attr("id");
214
    serverName = $(this).parent().parent().find('.name').find('.nametextbox').val();
215
    if (serverName.trim() == ''){
216
        return false;
217
    }
218
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.nametextbox').val());
219
    $(this).parent().parent().find(".editbuttons").fadeOut("fast");
220
    $(this).parent().parent().find(".rename").fadeIn("slow");
221
    rename(serverID, serverName);
222
    return false;
223
});
224

225
//cancel renaming
226
$("#machinesview-icon.standard .editbuttons .cancel").live('click', function() {
227
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.oldValue').text());
228
    $(this).parent().parent().find(".editbuttons").hide();
229
    $(this).parent().parent().find(".rename").fadeIn();
230
    $(this).parent().parent().addClass('editable');
231
    return false;
232
});
233

234
// intercept reboot click
235
$("#machinesview-icon.standard div.actions a.action-reboot").live('click', function(){
236
    var serverID = $(this).parent().parent().parent().attr("id");
237
    var serverName = $(this).parent().prevAll("div.name").find("span.name").text();
238
    var found = false;
239

240
    $(this).parent().children('a').removeClass('selected');
241
    $(this).addClass('selected');
242
    $(this).parent().addClass('display');
243
    $(this).parent().parent().find('.action_error').hide();
244
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
245
        if (pending_actions[i][1]==serverID){
246
            pending_actions[i][0] = reboot;
247
            found = true
248
        }
249
    }
250
    if (!found) // no pending action for this server was found, so let's just add it to the list
251
        pending_actions.push([reboot, serverID, serverName])
252
    update_confirmations();
253
    return false;
254
});
255

256
// intercept shutdown click
257
$("#machinesview-icon.standard div.actions a.action-shutdown").live('click', function(){
258
    var serverID = $(this).parent().parent().parent().attr("id");
259
    var serverName = $(this).parent().prevAll("div.name").find("span.name").text();
260
    var found = false;
261
    $(this).parent().children('a').removeClass('selected');
262
    $(this).addClass('selected');
263
    $(this).parent().addClass('display')
264
    $(this).parent().parent().find('.action_error').hide();
265

266
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
267
        if (pending_actions[i][1]==serverID){
268
            pending_actions[i][0] = shutdown;
269
            found = true
270
        }
271
    }
272
    if (!found) // no pending action for this server was found, so let's just add it to the list
273
        pending_actions.push([shutdown, serverID, serverName])
274
    update_confirmations();
275
    return false;
276
});
277

278
// intercept start click
279
$("#machinesview-icon.standard div.actions a.action-start").live('click', function(){
280
    var serverID = $(this).parent().parent().parent().attr("id");
281
    var serverName = $(this).parent().prevAll("div.name").find("span.name").text();
282
    var found = false;
283
    $(this).parent().children('a').removeClass('selected');
284
    $(this).addClass('selected');
285
    $(this).parent().addClass('display')
286
    $(this).parent().parent().find('.action_error').hide();
287

288
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
289
        if (pending_actions[i][1]==serverID){
290
            pending_actions[i][0] = start;
291
            found = true
292
        }
293
    }
294
    if (!found) // no pending action for this server was found, so let's just add it to the list
295
        pending_actions.push([start, serverID, serverName])
296
    update_confirmations();
297
    return false;
298
});
299

300
// intercept console click
301
$("#machinesview-icon.standard div.actions a.action-console").live('click', function(){
302
    var serverID = $(this).parent().parent().parent().attr("id");
303
    var serverName = $(this).parent().prevAll("div.name").find("span.name").text();
304
    var found = false;
305
    $(this).parent().children('a').removeClass('selected');
306
    $(this).addClass('selected');
307
    $(this).parent().addClass('display')
308
    $(this).parent().parent().find('.action_error').hide();
309

310
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
311
        if (pending_actions[i][1]==serverID){
312
            pending_actions[i][0] = open_console;
313
            found = true
314
        }
315
    }
316
    if (!found) // no pending action for this server was found, so let's just add it to the list
317
        pending_actions.push([open_console, serverID, serverName])
318
    update_confirmations();
319
    return false;
320
});
321

322

323
// intercept destroy click
324
$("#machinesview-icon.standard div.actions a.action-destroy").live('click', function(){
325
    var serverID = $(this).parent().parent().parent().attr("id");
326
    var serverName = $(this).parent().prevAll("div.name").find("span.name").text();
327
    var found = false;
328
    $(this).parent().children('a').removeClass('selected');
329
    $(this).addClass('selected');
330
    $(this).parent().addClass('display')
331
    $(this).parent().parent().find('.action_error').hide();
332

333
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
334
        if (pending_actions[i][1]==serverID){
335
            pending_actions[i][0] = destroy;
336
            found = true
337
        }
338
    }
339
    if (!found) // no pending action for this server was found, so let's just add it to the list
340
        pending_actions.push([destroy, serverID, serverName])
341
    update_confirmations();
342
    return false;
343
});
344

345
$("#machinesview-icon.standard div.confirm_single .yes").live('click', function(){
346
    var serverID = $(this).parent().parent().parent().attr("id");
347
    for (i=0;i<pending_actions.length;i++){ // if there is a pending action for this server execute it
348
        if (pending_actions[i][1]==serverID){
349
            action = pending_actions.splice(i,1)[0]; // extract action
350
            // change the status text in cases where no api state exists
351
            if (action[0] == start) {
352
                $(this).parent().parent().find('.status').text(TRANSITIONS['Starting']);
353
                $(this).parent().parent().find('.state').removeClass().addClass('state starting-state');
354
                $(this).parent().parent().find('.spinner').show();
355
            } else if (action[0] == shutdown) {
356
                $(this).parent().parent().find('.status').text(TRANSITIONS['Shutting down']);
357
                $(this).parent().parent().find('.state').removeClass().addClass('state shutting-state');
358
                $(this).parent().parent().find('.spinner').show();
359
            } else if (action[0] == reboot) {
360
                $(this).parent().parent().find('.status').text(TRANSITIONS['Rebooting']);
361
                $(this).parent().parent().find('.state').removeClass().addClass('state rebooting-state');
362
                $(this).parent().parent().find('.spinner').show();
363
            }  else if (action[0] == destroy) {
364
                $(this).parent().parent().find('.status').text(TRANSITIONS['Destroying']);
365
                $(this).parent().parent().find('.state').removeClass().addClass('state destroying-state');
366
                $(this).parent().parent().find('.spinner').show();
367
            }
368
            action[0]([action[1]]); // execute action
369
        }
370
    }
371
    $(this).parent().hide();
372
    $(this).parent().parent().children('div.actions').children('a').removeClass('selected');
373
    $(this).parent().parent().children('.state').children('.spinner').show()
374
    $(this).parent().parent().children('div.actions').removeClass('display');
375
    update_confirmations();
376
    return false;
377
});
378

379
$("#machinesview-icon.standard div.confirm_single .no").live('click', function(){
380
    // remove the action from the pending list
381
    var serverID = $(this).parent().parent().parent().attr("id");
382

383
    $(this).parent().parent().children('div.actions').children('a').removeClass('selected');
384
    $(this).parent().parent().children('div.actions').removeClass('display');
385
    for (i=0;i<pending_actions.length;i++){ // if there is a pending action for this server remove it
386
        if (pending_actions[i][1]==serverID){
387
            pending_actions.splice(i,1);
388
        }
389
    }
390
    $(this).parent().hide();
391
    update_confirmations();
392
    return false;
393
});
394

395
$("#machinesview-icon.standard div.action_error .details").live('click', function(){
396
    // remove the action from the pending list
397
    ajax_error($(this).parent().children('.code').text(), undefined, $(this).parent().children('.action').text(), $(this).parent().children('.message').text());
398
    $(this).parent().hide();
399
});
400

401
// TODO: This should be populated with more rules for all available states
402
var actions = { 'reboot':        ['UNKOWN', 'ACTIVE', 'REBOOT'],
403
                'shutdown':      ['UNKOWN', 'ACTIVE', 'REBOOT'],
404
                'console':       ['ACTIVE'],
405
                'start':         ['UNKOWN', 'STOPPED'],
406
                'destroy':       ['UNKOWN', 'ACTIVE', 'STOPPED', 'REBOOT', 'ERROR', 'BUILD']
407
               };
408

409
// update the servers list
410
function update_machines_view(data) {
411
    /*
412
    Go through the servers in the input data. Update existing entries, add
413
    new ones to the list
414
    */
415
    $.each(data.servers.values, function(i,server) {
416
        // get DOM element, if it exists
417
        existing = $('#machinesview-icon.standard #' + server.id);
418
        // get server OS, if it exists
419
        if (!(server.metadata == undefined)) {
420
            var server_image = os_icon(server.metadata);
421
        } else {
422
            var server_image = "unknown"
423
        }
424
        // get server status message, if it exists
425
        var current_message = existing.find(".status").text();
426
        // if multiple machines exist in the DOM, delete all but one
427
        // defensive coding - that shouldn't happen normally
428
        while (existing.length > 1){
429
            existing.remove();
430
        }
431
        // if server already exists in DOM, update its values
432
        if (existing.length){
433
            //  if the status is deleted
434
            if (server.status == 'DELETED') {
435
                // delete server entry from the DOM
436
                log_server_status_change(existing, 'DELETED');
437
                existing.remove();
438
            }
439
            // if the status has changed
440
            else if ( current_message != STATUSES[server.status]) {
441
                /*
442
                Here there are 4 possibilities:
443
                    1. From an active state to an inactive one
444
                    2. From an inactive state to an active one
445
                    3. From an active state to a different active one
446
                    4. From an inactive state to a different inactive one
447
                The last two (3, 4) can be dealt with the same way
448
                */
449
                if (ACTIVE_STATES.indexOf(current_message) >= 0 &&
450
                    INACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
451
                    // from an active state to an inactive one
452
                    log_server_status_change(existing, server.status);
453
                    moved = existing.clone().appendTo("#machinesview-icon.standard .terminated");
454
                    moved.find("img.logo").attr("src",'static/icons/machines/medium/' + server_image + '-off.png');
455
                    existing.remove();
456
                    existing = moved;
457
                    existing.find(".status").text(STATUSES[server.status]);
458
                    existing.find('.spinner').hide();
459
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
460
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
461
                }
462
                else if (INACTIVE_STATES.indexOf(current_message) >= 0 &&
463
                         ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
464
                    // From an inactive state to an active one
465
                    log_server_status_change(existing, server.status);
466
                    moved = existing.clone().appendTo("#machinesview-icon.standard .running");
467
                    moved.find("img.logo").attr('src','static/icons/machines/medium/' + server_image + '-on.png');
468
                    existing.remove();
469
                    existing = moved;
470
                    existing.find(".status").text(STATUSES[server.status]);
471
                    existing.find('.spinner').hide();
472
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
473
                    existing.find('.state').removeClass().addClass('state running-state');
474
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
475
                }
476
                else {
477
                    // handling active to active or inactive to inactive changes
478
                    if (TRANSITIONS[current_message] && TRANSITIONS[current_message] != 'Rebooting') {
479
                        // don't do anything if it is still in transition
480
                    }
481
                    else if ((TRANSITIONS[current_message] == 'Rebooting' && server.status == 'ACTIVE') ||
482
                             (STATUSES['BUILD'] == current_message && server.status == 'ACTIVE')) {
483
                        // if it has been rebooted or just created
484
                        log_server_status_change(existing, server.status);
485
                        existing.find(".status").text(STATUSES[server.status]);
486
                        existing.find('.spinner').hide();
487
                        existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
488
                        existing.find('.state').removeClass().addClass('state running-state');
489
                        setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
490
                    }
491
                    else {
492
                        // in any other case just change the status and ignore spinners/waves
493
                        existing.find(".status").text(STATUSES[server.status]);
494
                        existing.appendTo("#machinesview-icon.standard .running");
495
                        existing.find('.state').removeClass().addClass('state running-state');
496
                    }
497
                }
498
            }
499
            // find and display ips
500
            var ips = get_public_ips(server);
501
            existing.find("a.ip span.public").text(ips['ip4']);
502
        }
503
        // if it doesn't exist and the server is not DELETED, make a new entry
504
        else if ( server.status != 'DELETED') {
505
            // clone the proper template and put basic values in
506
            var machine = $("#machinesview-icon.standard #machine-container-template").clone().attr("id", server.id).fadeIn("slow");
507
            machine.find(".scrollable").scrollable({vertical: true});
508
            machine.find("div.name span.name").text(server.name.substring(0,100));
509
            machine.find("span.imagetag").text(server_image);
510
            machine.find(".status").text(STATUSES[server.status]);
511
            // check server status to select where to append the new server to
512
            if (ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0 ) {
513
                // append to running
514
                machine.find("img.logo").attr("src","static/icons/machines/medium/"+server_image+'-on.png');
515
                machine.appendTo("#machinesview-icon.standard .running");
516
            } else {
517
                // append to terminated
518
                machine.find("img.logo").attr("src","static/icons/machines/medium/"+server_image+'-off.png');
519
                machine.appendTo("#machinesview-icon.standard .terminated");                
520
                if (server.status == "STOPPED") { //if server status us stopped is a different case than status unknown/error
521
                    machine.find('.state').removeClass().addClass('state terminated-state');
522
                } else {
523
                       machine.find('.state').removeClass().addClass('state error-state');
524
                }
525
            }
526
            //show spinner if server is still building or rebooting
527
            if (server.status == 'BUILD' || server.status == 'REBOOT' ) {
528
                machine.find('.spinner').show();
529
                machine.find('.state').removeClass().addClass('state build-state');
530
            }
531
            // find and display flavor parameters
532
            var flavor_params = get_flavor_params(server.flavorRef);
533
            machine.find(".cpu-data").text(flavor_params['cpus']);
534
            machine.find(".ram-data").text(flavor_params['ram']);
535
            machine.find(".disk-data").text(flavor_params['disk']);
536
            // find and display image parameters
537
            var image_params = get_image_params(server.imageRef);
538
            machine.find(".image-data").text(image_params['name'].substring(0,15));
539
            machine.find(".image-size-data").text(image_params['size']);
540
            // find and display ips
541
            var ips = get_public_ips(server);
542
            machine.find("a.ip span.public").text(ips['ip4']);
543
        }
544
        /*
545
        Do some repeated actions that include:
546
            1. Update actions
547
            2. Metadata list updating
548
        */
549
        update_iconview_actions(server.id, server.status);
550
        if (!(server.metadata == undefined)) {
551
                list_metadata_keys(server.id, server.metadata.values);
552
        }
553
        machine.find("img.connect-arrow").hide();
554
    });
555
    /*
556
    Do some standard stuff, repeated each time
557
    FIXME: Can these be moved to a new function?
558
    */
559
    $("#machinesview-icon.standard > div.large-spinner").hide();
560
    // show all separators and hide the last one
561
    $("#machinesview-icon.standard div.machine-container div.separator").show();
562
    $("#machinesview-icon.standard div.machine-container:last-child").find("div.separator").hide();
563
    // the terminated div shows only when terminated machines are available
564
    if ($("#machinesview-icon.standard .terminated div.name").length > 0) {
565
        $("div.terminated").fadeIn("slow");
566
    } else {
567
        $("div.terminated").fadeOut("slow");
568
    }
569
    // show message in case user has no servers!
570
    if ($('#machinesview-icon .machine-container').length < 2) {
571
        showWelcome();
572
    } else {
573
        hideWelcome();
574
    }
575
    // set confirm box position
576
    if (window.innerHeight - CONFIRMBOX_OFFSET < $('#machinesview-icon.standard').height())
577
        $('.confirm_multiple').addClass('fixed');
578
    else
579
        $('.confirm_multiple').removeClass('fixed');
580
}
581

582
// reposition multiple confirmation box on window resize
583
$(window).resize(function(){
584
    if (this.innerHeight - CONFIRMBOX_OFFSET < $('#machinesview-icon').height())
585
        $('.confirm_multiple').addClass('fixed');
586
    else
587
        $('.confirm_multiple').removeClass('fixed');
588
});
589

590
// update metadata list
591
function list_metadata_keys(serverID, keys) {
592
    // empty the list if it already exists
593
    $("#machinesview-icon.standard div.#" +serverID).find("div.items").empty();
594
    //start counter
595
    var i=0;
596
    // show values
597
    for (var key in keys) {
598
        $("#machinesview-icon.standard div.#" +serverID).find(".items").append("<div class='item'>" + key + "</div>");
599
        i++;
600
    }
601
    //hide the metadata controls if we have less than 3 metadata
602
    if (i <= 3) {
603
        $("#machinesview-icon.standard div.#" +serverID).find(".metadata-actions").hide();
604
    }
605
    //show the metadata controls if we have more than 3 metadata
606
    if (i > 3) {
607
        $("#machinesview-icon.standard div.#" +serverID).find(".metadata-actions").show();
608
    }
609
    $("#machinesview-icon.standard div.#" +serverID).find(".metadata-count").text(i);
610
}
611

612
// indicate that the requested action was succesfully completed
613
function display_success(serverID) {
614

615
}
616

617
// indicate that the requested action was not completed
618
function display_failure(status, serverID, action, responseText) {
619
    $('#machinesview-icon.standard #'+serverID+ ' .spinner').hide();
620
    $('#machinesview-icon.standard #'+serverID+ ' .action_error .action').text(action);
621
    $('#machinesview-icon.standard #'+serverID+ ' .action_error .code').text(status);
622
    $('#machinesview-icon.standard #'+serverID+ ' .action_error .message').text(responseText);
623
    $('#machinesview-icon.standard #'+serverID+ ' .action_error').show();
624
}
625

626
// basic functions executed on page load
627
if ( flavors.length == 0 && images.length == 0 ) {
628
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
629
    update_flavors();
630
    // populate image list
631
    update_images();
632
} else if ( flavors.length == 0 && images.length != 0 ) {
633
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
634
    update_flavors();
635
} else if ( flavors.length != 0 && images.length == 0 ) {
636
    // populate image list
637
    update_images();
638
    update_vms(UPDATE_INTERVAL);
639
} else {
640
    // start updating vm list
641
    update_vms(UPDATE_INTERVAL);
642
}
643

644
// set the label of the multiple buttons
645
$('.confirm_multiple button.yes').text('Confirm All');
646
$('.confirm_multiple button.no').text('Cancel All');
647

    
648
</script>