Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_icon.html @ a70fb308

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

    
159
<script>
160
CONFIRMBOX_OFFSET = 200;
161

162
// actions on machine mouseover
163
$("#machinesview-icon.standard .machine").live('mouseover', function() {
164
    // show connect button only if the machine is active
165
    if ($(this).find('.status').text() == STATUSES['ACTIVE']) {
166
        $(this).find("div.connect-arrow").show();
167
        $(this).find("div.connect-border").show();
168
    }
169
});
170

171
// actions on machine mouseout
172
$("#machinesview-icon.standard .machine").live('mouseout', function() {
173
    // hide connect button
174
    $(this).find("div.connect-arrow").hide();
175
    $(this).find("div.connect-border").hide();
176
});
177

178
// actions on connect arrow border mouseover
179
$("#machinesview-icon.standard .running div.connect-border").live('mouseover', function() {
180
    $(this).next().addClass('border-hover');
181
});
182

183
// actions on connect arrow border mouseout
184
$("#machinesview-icon.standard .running div.connect-border").live('mouseout', function() {
185
    $(this).next().removeClass('border-hover');
186
});
187

188
// open console on machine logo click
189
$("#machinesview-icon.standard .running img.logo").live('click', function(){
190
    $(this).parent().parent().find("a.action-console").click();
191
    return false;
192
});
193

194
// open console on connect arrow click
195
$("#machinesview-icon.standard .running div.connect-arrow").live('click', function(){
196
    $(this).parent().parent().find("a.action-console").click();
197
    return false;
198
});
199

200
// open console on connect arrow border click
201
$("#machinesview-icon.standard .running div.connect-border").live('click', function(){
202
    $(this).parent().parent().find("a.action-console").click();
203
    return false;
204
});
205

206
//hide the all of the info contents
207
$("#machinesview-icon.standard .info-content").hide();
208
//toggle the component with class info-content
209
$("#machinesview-icon.standard div.info").live('click', function() {
210
    if ($(this).find('.toggler').hasClass('up')) {
211
        $(this).find('.toggler').removeClass('up');
212
        $(this).find('.toggler').addClass('down');
213
        $(this).find('.info-label').removeClass('darker');
214
        $(this).parent().removeClass('light-background');
215
    } else {
216
        $(this).find('.toggler').removeClass('down');
217
        $(this).find('.toggler').addClass('up');
218
        $(this).find('.info-label').addClass('darker');
219
        $(this).parent().addClass('light-background');
220
    }
221
    $(this).find(".info-content").slideToggle(600);
222
    return false;
223
});
224

225
// intercept manage metadata click
226
$("#machinesview-icon.standard a.manage-metadata").live('click', function() {
227
    // get server name and server ID
228
    var serverID = $(this).parent().parent().parent().parent().parent().parent().attr("id");
229
    var serverName = $(this).parent().parent().parent().parent().parent().find("span.name").text();
230
    // set server name to all related metadata dialogs
231
    $("#metadata-wizard div.machine-name").text(serverName);
232
    if ($(this).parent().parent().parent().parent().parent().parent().hasClass('terminated')) {
233
        $("#metadata-wizard div#on-off").text('off');
234
    } else {
235
        $("#metadata-wizard div#on-off").text('on');
236
    }
237
    // set server id to all related metadata dialogs
238
    $("#metadata-wizard p").text(serverID);
239
    show_metadata_wizard();
240
    return false;
241
});
242

243
//initiate machine renaming
244
$("#machinesview-icon.standard .rename, #machinesview-icon.standard h5.editable span.name").live('click', function() {
245
    $(this).parent().find('.name').html("<input id=\"txtEdit\" type=\"text\" class=\"nametextbox\" value=\"" +
246
                                        $(this).parent().find('.name').text() +
247
                                        "\" / ><span class=\"oldValue\">" +
248
                                        $(this).parent().find('.name').text() + "</span>");
249
    $(this).parent().find('.rename').hide();
250
    $(this).parent().find(".editbuttons").fadeIn();
251
    $(this).parent().find(".nametextbox").focus().select();
252
    $(this).parent().removeClass('editable');
253

254
    //submit wizard by pressing enter on the name textbox
255
    $("#txtEdit").keydown(function (e) {
256
        if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
257
            $(this).parent().parent().find('div.editbuttons span.save').click();
258
            return false;
259
        } else if ((e.which && e.which == 27) || (e.keyCode && e.keyCode == 27)) {
260
            $(this).parent().parent().find('div.editbuttons span.cancel').click();
261
            return true;
262
        }
263
    });
264
    return false;
265
});
266

267
//rename machine
268
$("#machinesview-icon.standard .editbuttons .save").live('click', function() {
269
    serverID = $(this).closest('.machine-container').attr("id");
270
    serverName = $(this).parent().parent().find('.name').find('.nametextbox').val();
271
    if (serverName.trim() == ''){
272
        return false;
273
    }
274
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.nametextbox').val());
275
    $(this).parent().parent().find(".editbuttons").fadeOut("fast");
276
    $(this).parent().parent().find(".rename").fadeIn("slow");
277
    rename(serverID, serverName);
278
    return false;
279
});
280

281
//cancel renaming
282
$("#machinesview-icon.standard .editbuttons .cancel").live('click', function() {
283
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.oldValue').text());
284
    $(this).parent().parent().find(".editbuttons").hide();
285
    $(this).parent().parent().find(".rename").fadeIn();
286
    $(this).parent().parent().addClass('editable');
287
    return false;
288
});
289

290
// intercept reboot click
291
$("#machinesview-icon.standard div.actions a.action-reboot").live('click', function() {
292
    // get server id and server name from DOM
293
    var serverID = $(this).closest("div.machine-container").attr("id");
294
    var serverName = $(this).closest("div.machine").find("div.name span.name").text();
295
    var found = false;
296
    // show/hide proper menus
297
    $(this).parent().parent().find('a').removeClass('selected');
298
    $(this).addClass('selected');
299
    $(this).parent().parent().addClass('display');
300
    $(this).closest("div.machine").find('.action_error').hide();
301
    // if there is already a pending action for this server replace it
302
    for (i=0; i<pending_actions.length; i++) {
303
        if (pending_actions[i][1]==serverID) {
304
            pending_actions[i][0] = reboot;
305
            found = true
306
        }
307
    }
308
    // no pending action for this server was found, so let's just add it to the list
309
    if (!found)
310
        pending_actions.push([reboot, serverID, serverName])
311
    // pass the proper action to update confirmation boxes
312
    update_confirmations();
313
    return false;
314
});
315

316
// intercept shutdown click
317
$("#machinesview-icon.standard div.actions a.action-shutdown").live('click', function() {
318
    // get server id and server name from DOM
319
    var serverID = $(this).closest("div.machine-container").attr("id");
320
    var serverName = $(this).closest("div.machine").find("div.name span.name").text();
321
    var found = false;
322
    // show/hide proper menus
323
    $(this).parent().parent().find('a').removeClass('selected');
324
    $(this).addClass('selected');
325
    $(this).parent().parent().addClass('display');
326
    $(this).closest("div.machine").find('.action_error').hide();
327
    // if there is already a pending action for this server replace it
328
    for (i=0; i<pending_actions.length; i++) {
329
        if (pending_actions[i][1]==serverID) {
330
            pending_actions[i][0] = shutdown;
331
            found = true
332
        }
333
    }
334
    // no pending action for this server was found, so let's just add it to the list
335
    if (!found)
336
        pending_actions.push([shutdown, serverID, serverName])
337
    update_confirmations();
338
    return false;
339
});
340

341
// intercept start click
342
$("#machinesview-icon.standard div.actions a.action-start").live('click', function() {
343
    // get server id and server name from DOM
344
    var serverID = $(this).closest("div.machine-container").attr("id");
345
    var serverName = $(this).closest("div.machine").find("div.name span.name").text();
346
    var found = false;
347
    // show/hide proper menus
348
    $(this).parent().parent().find('a').removeClass('selected');
349
    $(this).addClass('selected');
350
    $(this).parent().parent().addClass('display');
351
    $(this).closest("div.machine").find('.action_error').hide();
352
    // if there is already a pending action for this server replace it
353
    for (i=0; i<pending_actions.length; i++) {
354
        if (pending_actions[i][1]==serverID) {
355
            pending_actions[i][0] = start;
356
            found = true
357
        }
358
    }
359
    // no pending action for this server was found, so let's just add it to the list
360
    if (!found)
361
        pending_actions.push([start, serverID, serverName])
362
    update_confirmations();
363
    return false;
364
});
365

366
// intercept console click
367
$("#machinesview-icon.standard div.actions a.action-console").live('click', function() {
368
    // get server id and server name from DOM
369
    var serverID = $(this).closest("div.machine-container").attr("id");
370
    var serverName = $(this).closest("div.machine").find("div.name span.name").text();
371
    var found = false;
372
    // show/hide proper menus
373
    $(this).parent().parent().find('a').removeClass('selected');
374
    $(this).addClass('selected');
375
    $(this).parent().parent().addClass('display');
376
    $(this).closest("div.machine").find('.action_error').hide();
377
    // if there is already a pending action for this server replace it
378
    for (i=0; i<pending_actions.length; i++) {
379
        if (pending_actions[i][1]==serverID) {
380
            pending_actions[i][0] = open_console;
381
            found = true
382
        }
383
    }
384
    // no pending action for this server was found, so let's just add it to the list
385
    if (!found)
386
        pending_actions.push([open_console, serverID, serverName])
387
    update_confirmations();
388
    return false;
389
});
390

391

392
// intercept destroy click
393
$("#machinesview-icon.standard div.actions a.action-destroy").live('click', function() {
394
    // get server id and server name from DOM
395
    var serverID = $(this).closest("div.machine-container").attr("id");
396
    var serverName = $(this).closest("div.machine").find("div.name span.name").text();
397
    var found = false;
398
    // show/hide proper menus
399
    $(this).parent().parent().find('a').removeClass('selected');
400
    $(this).addClass('selected');
401
    $(this).parent().parent().addClass('display');
402
    $(this).closest("div.machine").find('.action_error').hide();
403
    // if there is already a pending action for this server replace it
404
    for (i=0; i<pending_actions.length; i++) {
405
        if (pending_actions[i][1]==serverID) {
406
            pending_actions[i][0] = destroy;
407
            found = true
408
        }
409
    }
410
    // no pending action for this server was found, so let's just add it to the list
411
    if (!found)
412
        pending_actions.push([destroy, serverID, serverName])
413
    update_confirmations();
414
    return false;
415
});
416

417
$("#machinesview-icon.standard div.confirm_single button.yes").live('click', function(){
418
    var serverID = $(this).closest("div.machine-container").attr("id");
419
    // if there is a pending action for this server execute it
420
    for (i=0; i<pending_actions.length; i++) {
421
        if (pending_actions[i][1]==serverID){
422
            action = pending_actions.splice(i,1)[0]; // extract action
423
            // change the status text in cases where no api state exists
424
            if (action[0] == start) {
425
                $(this).closest("div.machine").find('.status').text(TRANSITIONS['Starting']);
426
                $(this).closest("div.machine").find('.state').removeClass().addClass('state starting-state');
427
                $(this).closest("div.machine").find('.spinner').show();
428
            } else if (action[0] == shutdown) {
429
                $(this).closest("div.machine").find('.status').text(TRANSITIONS['Shutting down']);
430
                $(this).closest("div.machine").find('.state').removeClass().addClass('state shutting-state');
431
                $(this).closest("div.machine").find('.spinner').show();
432
            } else if (action[0] == reboot) {
433
                $(this).closest("div.machine").find('.status').text(TRANSITIONS['Rebooting']);
434
                $(this).closest("div.machine").find('.state').removeClass().addClass('state rebooting-state');
435
                $(this).closest("div.machine").find('.spinner').show();
436
            }  else if (action[0] == destroy) {
437
                $(this).closest("div.machine").find('.status').text(TRANSITIONS['Destroying']);
438
                $(this).closest("div.machine").find('.state').removeClass().addClass('state destroying-state');
439
                $(this).closest("div.machine").find('.spinner').show();
440
            }
441
            action[0]([action[1]]); // execute action
442
        }
443
    }
444
    $(this).parent().hide();
445
    $(this).closest('div.actions').find('a').removeClass('selected');
446
    $(this).closest("div.machine").children('.state').children('.spinner').show()
447
    $(this).closest("div.machine").children('div.actions').removeClass('display');
448
    update_confirmations();
449
    return false;
450
});
451

452
$("#machinesview-icon.standard div.confirm_single button.no").live('click', function(){
453
    // remove the action from the pending list
454
    var serverID = $(this).closest("div.machine-container").attr("id");
455

456
    $(this).closest('div.action-container').children('a').removeClass('selected');
457
    $(this).closest('div.actions').removeClass('display');
458
    for (i=0; i<pending_actions.length; i++) { // if there is a pending action for this server remove it
459
        if (pending_actions[i][1]==serverID) {
460
            pending_actions.splice(i,1);
461
        }
462
    }
463
    $(this).parent().hide();
464
    update_confirmations();
465
    return false;
466
});
467

468
$("#machinesview-icon.standard div.action_error .details").live('click', function(){
469
    // remove the action from the pending list
470
    ajax_error($(this).parent().children('.code').text(), undefined, $(this).parent().children('.action').text(), $(this).parent().children('.message').text());
471
    $(this).parent().hide();
472
});
473

474
// TODO: This should be populated with more rules for all available states
475
var actions = { 'reboot':        ['UNKOWN', 'ACTIVE', 'REBOOT'],
476
                'shutdown':      ['UNKOWN', 'ACTIVE', 'REBOOT'],
477
                'console':       ['ACTIVE'],
478
                'start':         ['UNKOWN', 'STOPPED'],
479
                'destroy':       ['UNKOWN', 'ACTIVE', 'STOPPED', 'REBOOT', 'ERROR', 'BUILD']
480
               };
481

482
// update the servers list
483
function update_machines_view(data) {
484
    /*
485
    Go through the servers in the input data. Update existing entries, add
486
    new ones to the list
487
    */
488
    $.each(data.servers.values, function(i,server) {
489
        // get DOM element, if it exists
490
        existing = $('#machinesview-icon.standard #' + server.id);
491
        // get server OS, if it exists
492
        if (!(server.metadata == undefined)) {
493
            var server_image = os_icon(server.metadata);
494
        } else {
495
            var server_image = "unknown"
496
        }
497
        // get server status message, if it exists
498
        var current_message = existing.find(".status").text();
499
        // if multiple machines exist in the DOM, delete all but one
500
        // defensive coding - that shouldn't happen normally
501
        while (existing.length > 1){
502
            existing.remove();
503
        }
504
        // if server already exists in DOM, update its values
505
        if (existing.length){
506
            //  if the status is deleted
507
            if (server.status == 'DELETED') {
508
                // delete server entry from the DOM
509
                log_server_status_change(existing, 'DELETED');
510
                existing.remove();
511
            }
512
            // if the status has changed
513
            else if ( current_message != STATUSES[server.status]) {
514
                /*
515
                Here there are 4 possibilities:
516
                    1. From an active state to an inactive one
517
                    2. From an inactive state to an active one
518
                    3. From an active state to a different active one
519
                    4. From an inactive state to a different inactive one
520
                The last two (3, 4) can be dealt with the same way
521
                */
522
                if (ACTIVE_STATES.indexOf(current_message) >= 0 &&
523
                    INACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
524
                    // from an active state to an inactive one
525
                    log_server_status_change(existing, server.status);
526
                    moved = existing.clone().appendTo("#machinesview-icon.standard .terminated");
527
                    moved.find("img.logo").attr("src",'static/icons/machines/medium/' + server_image + '-off.png');
528
                    existing.remove();
529
                    existing = moved;
530
                    existing.find(".status").text(STATUSES[server.status]);
531
                    existing.find('.spinner').hide();
532
                    if ($("div.terminated").find("div.machine-container").length > 0) {
533
                        $("div.terminated").show();
534
                    }
535
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
536
                    existing.find('.state').removeClass().addClass('state terminated-state');
537
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
538
                }
539
                else if (INACTIVE_STATES.indexOf(current_message) >= 0 &&
540
                         ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
541
                    // From an inactive state to an active one
542
                    log_server_status_change(existing, server.status);
543
                    moved = existing.clone().appendTo("#machinesview-icon.standard .running");
544
                    moved.find("img.logo").attr('src','static/icons/machines/medium/' + server_image + '-on.png');
545
                    existing.remove();
546
                    existing = moved;
547
                    existing.find(".status").text(STATUSES[server.status]);
548
                    existing.find('.spinner').hide();
549
                    if ($("div.terminated").find("div.machine-container").length == 0) {
550
                        $("div.terminated").hide();
551
                    }
552
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
553
                    existing.find('.state').removeClass().addClass('state running-state');
554
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
555
                }
556
                else {
557
                    // handling active to active or inactive to inactive changes
558
                    if (TRANSITIONS[current_message] && TRANSITIONS[current_message] != 'Rebooting') {
559
                        // don't do anything if it is still in transition
560
                    }
561
                    else if ((TRANSITIONS[current_message] == 'Rebooting' && server.status == 'ACTIVE') ||
562
                             (STATUSES['BUILD'] == current_message && server.status == 'ACTIVE')) {
563
                        // if it has been rebooted or just created
564
                        log_server_status_change(existing, server.status);
565
                        existing.find(".status").text(STATUSES[server.status]);
566
                        existing.find('.spinner').hide();
567
                        existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
568
                        existing.find('.state').removeClass().addClass('state running-state');
569
                        setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
570
                    }
571
                    else {
572
                        // in any other case just change the status and ignore spinners/waves
573
                        existing.find(".status").text(STATUSES[server.status]);
574
                        existing.appendTo("#machinesview-icon.standard .running");
575
                        existing.find('.state').removeClass().addClass('state running-state');
576
                    }
577
                }
578
            }
579
            // find and display ips
580
            var ips = get_public_ips(server);
581
            existing.find("a.ip span.public").text(ips['ip4']);
582
        }
583
        // if it doesn't exist and the server is not DELETED, make a new entry
584
        else if ( server.status != 'DELETED') {
585
            // clone the proper template and put basic values in
586
            var machine = $("#machinesview-icon.standard #machine-container-template").clone().attr("id", server.id).fadeIn("slow");
587
            machine.find(".scrollable").scrollable({vertical: true});
588
            machine.find("div.name span.name").text(server.name.substring(0,100));
589
            machine.find("span.imagetag").text(server_image);
590
            machine.find(".status").text(STATUSES[server.status]);
591
            // check server status to select where to append the new server to
592
            if (ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0 ) {
593
                // append to running
594
                machine.find("img.logo").attr("src","static/icons/machines/medium/"+server_image+'-on.png');
595
                machine.appendTo("#machinesview-icon.standard .running");
596
            } else {
597
                // append to terminated
598
                machine.find("img.logo").attr("src","static/icons/machines/medium/"+server_image+'-off.png');
599
                machine.appendTo("#machinesview-icon.standard .terminated");
600
                if (server.status == "STOPPED") { //if server status us stopped is a different case than status unknown/error
601
                    machine.find('.state').removeClass().addClass('state terminated-state');
602
                } else {
603
                       machine.find('.state').removeClass().addClass('state error-state');
604
                }
605
            }
606
            //show spinner if server is still building or rebooting
607
            if (server.status == 'BUILD') {
608
                machine.find('.spinner').show();
609
                machine.find('.state').removeClass().addClass('state build-state');
610
            }
611
            if (server.status == 'REBOOT') {
612
                machine.find('.spinner').show();
613
                machine.find('.state').removeClass().addClass('state rebooting-state');
614
            }
615
            // find and display flavor parameters
616
            var flavor_params = get_flavor_params(server.flavorRef);
617
            machine.find(".cpu-data").text(flavor_params['cpus']);
618
            machine.find(".ram-data").text(flavor_params['ram']);
619
            machine.find(".disk-data").text(flavor_params['disk']);
620
            // find and display image parameters
621
            var image_params = get_image_params(server.imageRef);
622
            machine.find(".image-data").text(image_params['name'].substring(0,15));
623
            machine.find(".image-size-data").text(image_params['size']);
624
            // find and display ips
625
            var ips = get_public_ips(server);
626
            machine.find("a.ip span.public").text(ips['ip4']);
627
        }
628
        /*
629
        Do some repeated actions that include:
630
            1. Update actions
631
            2. Metadata list updating
632
        */
633
        update_iconview_actions(server.id, server.status);
634
        if (!(server.metadata == undefined)) {
635
                list_metadata_keys(server.id, server.metadata.values);
636
        }
637
    });
638
    /*
639
    Do some standard stuff, repeated each time
640
    FIXME: Can these be moved to a new function?
641
    */
642
    $("div.running > div.large-spinner").hide();
643
    // show all separators and hide the last one
644
    $("#machinesview-icon.standard div.machine-container div.separator").show();
645
    $("#machinesview-icon.standard div.machine-container:last-child").find("div.separator").hide();
646
    // the terminated div shows only when terminated machines are available
647
    if ($("#machinesview-icon.standard .terminated div.name").length > 0) {
648
        $("div.terminated").fadeIn("slow");
649
    } else {
650
        $("div.terminated").fadeOut("slow");
651
    }
652
    // show message in case user has no servers!
653
    if ($('#machinesview-icon .machine-container').length < 2) {
654
        showWelcome();
655
    } else {
656
        hideWelcome();
657
    }
658
    // set confirm box position
659
    if (window.innerHeight - CONFIRMBOX_OFFSET < $('#machinesview-icon.standard').height()) {
660
        $('.confirm_multiple').addClass('fixed');
661
    } else {
662
        $('.confirm_multiple').removeClass('fixed');
663
    }
664
}
665

666
// reposition multiple confirmation box on window resize
667
$(window).resize(function(){
668
    if (this.innerHeight - CONFIRMBOX_OFFSET < $('#machinesview-icon').height())
669
        $('.confirm_multiple').addClass('fixed');
670
    else
671
        $('.confirm_multiple').removeClass('fixed');
672
});
673

674
// update metadata list
675
function list_metadata_keys(serverID, keys) {
676
    // empty the list if it already exists
677
    $("#machinesview-icon.standard div.#" +serverID).find("div.items").empty();
678
    //start counter
679
    var i=0;
680
    // show values
681
    for (var key in keys) {
682
        $("#machinesview-icon.standard div.#" +serverID).find(".items").append("<div class='item'>" + key + "</div>");
683
        i++;
684
    }
685
    //hide the metadata controls if we have less than 3 metadata
686
    if (i <= 3) {
687
        $("#machinesview-icon.standard div.#" +serverID).find(".metadata-actions").hide();
688
    }
689
    //show the metadata controls if we have more than 3 metadata
690
    if (i > 3) {
691
        $("#machinesview-icon.standard div.#" +serverID).find(".metadata-actions").show();
692
    }
693
    $("#machinesview-icon.standard div.#" +serverID).find(".metadata-count").text(i);
694
}
695

696
// indicate that the requested action was succesfully completed
697
function display_success(serverID) {
698

699
}
700

701
// indicate that the requested action was not completed
702
function display_failure(status, serverID, action, responseText) {
703
    $('#machinesview-icon.standard #'+serverID+ ' .spinner').hide();
704
    $('#machinesview-icon.standard #'+serverID+ ' .action_error .action').text(action);
705
    $('#machinesview-icon.standard #'+serverID+ ' .action_error .code').text(status);
706
    $('#machinesview-icon.standard #'+serverID+ ' .action_error .message').text(responseText);
707
    $('#machinesview-icon.standard #'+serverID+ ' .action_error').show();
708
}
709

710
// basic functions executed on page load
711
if ( flavors.length == 0 && images.length == 0 ) {
712
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
713
    update_flavors();
714
    // populate image list
715
    update_images();
716
} else if ( flavors.length == 0 && images.length != 0 ) {
717
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
718
    update_flavors();
719
} else if ( flavors.length != 0 && images.length == 0 ) {
720
    // populate image list
721
    update_images();
722
    update_vms(UPDATE_INTERVAL);
723
} else {
724
    // start updating vm list
725
    update_vms(UPDATE_INTERVAL);
726
}
727

728
// set the label of the multiple buttons
729
$('.confirm_multiple button.yes').text('Confirm All');
730
$('.confirm_multiple button.no').text('Cancel All');
731

    
732
</script>