Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ a09987c3

History | View | Annotate | Download (38.6 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 single view -->
39
<div id="machinesview-single" class="single">
40
    <div class="large-spinner"></div>
41
    <div class="single-container" id="machine-container-template" style="display:none;" >
42
        <div class="upper">
43
            <div class="column1">
44
                <div class='connect-border' title='{% trans 'Connect  machine' %}'></div>
45
                <div class='connect-arrow' title='{% trans 'Connect  machine' %}'></div>
46
                <div class="single-image" />
47
                <div class="state">
48
                    <span class="state-label">{% trans "Running" %}</span>
49
                    <div class="indicators">
50
                        <div class="indicator1"></div>
51
                        <div class="indicator2"></div>
52
                        <div class="indicator3"></div>
53
                        <div class="indicator4"></div>
54
                    </div>
55
                    <div class="action-indicator" style="display:none"></div>
56
                    <img class="spinner" style="display:none" src="static/icons/indicators/medium/progress.gif" />
57
                    <img class="wave" style="display:none" src="static/icons/indicators/medium/wave.gif" />
58
                </div>
59
            </div>
60
            <div class="column2">
61
                <div class="machine-labels">
62
                    <div class="machine-label name">{% trans "Name" %}:</div>
63
                    <div class="machine-label cpus">{% trans "CPUs" %}:</div>
64
                    <div class="machine-label ram">{% trans "RAM (MB)" %}:</div>
65
                    <div class="machine-label disk">{% trans "System Disk (GB)" %}:</div>
66
                    <div class="machine-label image-name">{% trans "Image Name" %}:</div>
67
                    <div class="machine-label image-size">{% trans "Image Size (MB)" %}:</div>
68
                    <div class="machine-label ipv4">{% trans "Public IPv4" %}:</div>
69
                    <div class="machine-label ipv6">{% trans "Public IPv6" %}:</div>
70
                </div>
71
                <div class="machine-details">
72
                    <div class="machine-detail name">My Desktop</div>
73
                    <div class="machine-detail cpus">4</div>
74
                    <div class="machine-detail ram">2048</div>
75
                    <div class="machine-detail disk">100</div>
76
                    <div class="machine-detail image-name">windos_XP_blah_blah</div>
77
                    <div class="machine-detail image-size">2.3</div>
78
                    <div class="machine-detail ipv4 ipv4-text">no ipv4</div>
79
                    <div class="machine-detail ipv6 ipv6-text">2001:db8:1f70::999:de8:7648:6e8</div>
80
                </div>
81
                <div class="tags">
82
                    <div class="tags-header">
83
                        <div class="tags-label">{% trans "Tags" %}</div>
84
                        <div class="toggler down"></div>
85
                    </div>
86
                    <div class="tags-content">
87
                        <div class="metadata-keys-container">
88
                            <div class="scrollable vertical">
89
                                <div class="items">
90
                                </div>
91
                            </div>
92
                            <div class="metadata-actions">
93
                                <div class="prev"></div>
94
                                <div class="next"></div>
95
                            </div>
96
                        </div>
97
                        <a href="#" class="manage-metadata">{% trans "Manage Tags" %}</a>
98
                    </div>
99
                </div>
100
            </div>
101
            <div class="single-actions">
102
                <div class="action-container start">
103
                    <div class="single-action action-start">{% trans "Start" %}</div>
104
                    <div class="confirm_single">
105
                        <button class="yes">{% trans "Confirm" %}</button>
106
                        <button class="no">X</button>
107
                    </div>
108
                </div>
109
                <div class="action-container reboot">
110
                    <div class="single-action action-reboot">{% trans "Reboot" %}</div>
111
                    <div class="confirm_single">
112
                        <button class="yes">{% trans "Confirm" %}</button>
113
                        <button class="no">X</button>
114
                    </div>
115
                </div>
116
                <div class="action-container shutdown">
117
                    <div class="single-action action-shutdown">{% trans "Shutdown" %}</div>
118
                    <div class="confirm_single">
119
                        <button class="yes">{% trans "Confirm" %}</button>
120
                        <button class="no">X</button>
121
                    </div>
122
                </div>
123
                <div class="action-container console">
124
                    <div class="single-action action-console">{% trans "Console" %}</div>
125
                    <div class="confirm_single">
126
                        <button class="yes">{% trans "Confirm" %}</button>
127
                        <button class="no">X</button>
128
                    </div>
129
                </div>
130
                <div class="action-container destroy">
131
                    <div class="single-action action-destroy">{% trans "Destroy" %}</div>
132
                    <div class="confirm_single">
133
                        <button class="yes">{% trans "Confirm" %}</button>
134
                        <button class="no">X</button>
135
                    </div>
136
                </div>
137
            </div>
138
            <div class="action_error" align="center">
139
                {% trans "<span>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
140
                <span class="code"></span>
141
                <span class="message"></span>
142
                <button class="details">{% trans "Details" %}</button>
143
            </div>
144
        </div>
145
        <div class="lower">
146
            <div class="single-cpu">
147
                <div class="cpu-usage">
148
                    {% trans "CPU Utilization" %}
149
                </div>
150
                <div class="cpu-graph">
151
                    <img src="./static/placeholder.png" class="stats series" />
152
                    <img src="./static/icons/indicators/small/progress.gif" class="stat-busy" />
153
                    <div class='stat-error'>{% trans "Could not fetch CPU stats graph." %}</div>
154
                </div>
155
            </div>
156
            <div class="single-network">
157
                <div class="network-usage">
158
                    {% trans "Network Utilization" %}
159
                </div>
160
                <div class="network-graph">
161
                    <img src="./static/placeholder.png" class="stats series" />
162
                    <img src="./static/icons/indicators/small/progress.gif" class="stat-busy" />
163
                    <div class='stat-error'>{% trans "Could not fetch Net stats graph." %}</div>
164
                </div>
165
            </div>
166
        </div>
167
    </div>
168
    <div class="column3" style="display:none;">
169
        <div class="controls">
170
            <div class="previous" style="display:block;">
171
                <div class="prev-arrow"></div>
172
                <div class="prev-label">
173
                    {% trans "previous" %}
174
                </div>
175
            </div>
176
            <div class="next" style="display:block;">
177
                <div class="next-arrow"></div>
178
                <div class="next-label">
179
                    {% trans "next" %}
180
                </div>
181
            </div>
182
        </div>
183
        <div class="separator">
184
        </div>
185
        <div class="servers">
186
            <div class="server-name" id="servers-widget-template" style="display:none;">server1</div>
187
        </div>
188
    </div>
189
</div>
190

    
191
<script>
192

193
init_action_indicator_handlers('single');
194

195
//hide the all of the tags contents
196
$("#machinesview-single.single .tags-content").hide();
197

198
// handle connect machine image states
199
$("div.connect-arrow, .single-image").live('mouseenter',
200
    function() {
201
        // ugly check to see if machine is running
202
        if ($(this).parent().find(".connect-arrow:visible").length == 0) { return };
203
        set_machine_os_image($(this).parent().parent(), "single", "hover", undefined, 1);
204
        var parent = $(this).parent().parent();
205
        parent.find(".connect-arrow").show().addClass('border-hover');
206
    });
207

208
$("div.connect-arrow, .single-image").live('mouseleave',
209
    function() {
210
        if ($(this).parent().find(".connect-arrow:visible").length == 0) { return };
211
        set_machine_os_image($(this).parent().parent(), "single", "hover", undefined, 1, "hover");
212
        set_machine_os_image($(this).parent().parent(), "single", "click", undefined, 1, "click");
213
        var parent = $(this).parent().parent();
214
        parent.find(".connect-arrow").removeClass('border-hover');
215
    });
216

217
$("div.connect-arrow, .single-image").live('mousedown',
218
    function() {
219
        if ($(this).parent().find(".connect-arrow:visible").length == 0) { return };
220
        set_machine_os_image($(this).parent().parent(), "single", "click", undefined, 1);
221
    });
222

223
$("div.connect-arrow, .single-image").live('mouseup',
224
    function() {
225
        if ($(this).parent().find(".connect-arrow:visible").length == 0) { return };
226
        set_machine_os_image($(this).parent().parent(), "single", "click", undefined, 1, "click");
227
    });
228

229
//toggle the component with class tags-content
230
$("#machinesview-single.single div.tags-header").live('click', function() {
231
    if ($(this).find('.toggler').hasClass('up')) {
232
        $(this).find('.toggler').removeClass('up');
233
        $(this).find('.toggler').addClass('down');
234
        $(this).find('.tags-label').removeClass('darker');
235
        $(this).parent().parent().removeClass('light-background');
236
    } else {
237
        $(this).find('.toggler').removeClass('down');
238
        $(this).find('.toggler').addClass('up');
239
        $(this).find('.tags-label').addClass('darker');
240
        $(this).parent().parent().addClass('light-background');
241
    }
242
    $(this).parent().parent().find(".tags-content").slideToggle(600);
243
    return false;
244
});
245

246
// indicate that the requested action was not completed
247
function display_failure(status, serverID, action, responseText) {
248
    $('#machinesview-single.single #'+serverID+ ' .spinner').hide();
249
    $('#machinesview-single.single #'+serverID+ ' .action_error .action').text(action);
250
    $('#machinesview-single.single #'+serverID+ ' .action_error .code').text(status);
251
    $('#machinesview-single.single #'+serverID+ ' .action_error .message').text(responseText);
252
    $('#machinesview-single.single #'+serverID+ ' .action_error').show();
253
}
254

255
// cancel action
256
$("#machinesview-single.single div.confirm_single .no").live('click', function(){
257
    pending_actions = [];
258
    $('#machinesview-single').find('div.single-action').removeClass("selected");
259
    update_confirmations();
260
});
261

262
// update metadata list
263
function list_metadata_keys(serverID, keys) {
264
    // empty the list if it already exists
265
    $("#machinesview-single.single div.#" +serverID).find("div.items").empty();
266
    //start counter
267
    var i=0;
268
    // show values
269
    for (var key in keys) {
270
        $("#machinesview-single.single div.#" +serverID).find(".items").append("<div class='item'>" + key + ": " + keys[key].substring(0,40) + "</div>");
271
        i++;
272
    }
273
    //hide the metadata controls if we have less than 3 metadata
274
    if (i <= 3) {
275
        $("#machinesview-single.single div.#" +serverID).find(".metadata-actions").hide();
276
    }
277
    //show the metadata controls if we have more than 3 metadata
278
    if (i > 3) {
279
        $("#machinesview-single.single div.#" +serverID).find(".metadata-actions").show();
280
    }
281
    $("#machinesview-single.single div.#" +serverID).find(".metadata-count").text(i);
282
}
283

284
//show error popup box
285
$("#machinesview-single.single div.action_error .details").live('click', function(){
286
    // remove the action from the pending list
287
    ajax_error($(this).parent().children('.code').text(), undefined, $(this).parent().children('.action').text(), $(this).parent().children('.message').text());
288
    $(this).parent().hide();
289
});
290

291
//confirm action
292
$("#machinesview-single.single div.confirm_single .yes").live('click', function(){
293
    var serverID = $(this).closest(".single-container").attr("id");
294
    for (i=0;i<pending_actions.length;i++){ // if there is a pending action for this server execute it
295
        if (pending_actions[i][1]==serverID){
296
            action = pending_actions.splice(i,1)[0]; // extract action
297
            // change the status text in cases where no api state exists
298
            if (action[0] == start) {
299
                $(this).closest(".single-container").find(".column1 .state-label").text(TRANSITIONS['Starting']);
300
                $(this).closest(".single-container").find(".column1 .state").removeClass().addClass('state starting-state');
301
                $(this).closest(".single-container").find(".column1 .state .spinner").show();
302
            } else if (action[0] == shutdown) {
303
                $(this).closest(".single-container").find(".column1 .state-label").text(TRANSITIONS['Shutting down']);
304
                $(this).closest(".single-container").find(".column1 .state").removeClass().addClass('state shutting-state');
305
                $(this).closest(".single-container").find(".column1 .state .spinner").show();
306
            } else if (action[0] == reboot) {
307
                $(this).closest(".single-container").find(".column1 .state-label").text(TRANSITIONS['Rebooting']);
308
                $(this).closest(".single-container").find(".column1 .state").removeClass().addClass('state rebooting-state');
309
                $(this).closest(".single-container").find(".column1 .state .spinner").show();
310
            }  else if (action[0] == destroy) {
311
                $(this).closest(".single-container").find(".column1 .state-label").text(TRANSITIONS['Destroying']);
312
                $(this).closest(".single-container").find(".column1 .state").removeClass().addClass('state destroying-state');
313
                $(this).closest(".single-container").find(".column1 .state .spinner").show();
314
            }
315
            action[0]([action[1]]); // execute action
316
        }
317
    }
318
    $(this).parent().hide();
319
    $(this).closest('div.action-container').children('div.single-action').removeClass('selected');
320
    $(this).parent().parent().find('.state').children('.spinner').show();
321
    update_transition_names();
322
    update_confirmations();
323
    return false;
324
});
325

326
// intercept manage metadata click
327
$("#machinesview-single.single a.manage-metadata").live('click', function() {
328
    // get server name and server ID
329
    var serverID = $(this).parent().parent().parent().parent().parent().attr("id");
330
    var serverName = $(this).closest('.machine-container').find("div.machine-details div.name").text();
331
    if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf($(this).parent().parent().parent().parent().parent().find(".status").text()) < 0) {
332
        $("#metadata-wizard div#on-off").text('on');
333
    } else {
334
        $("#metadata-wizard div#on-off").text('off');
335
    }
336
    // set server name to all related metadata dialogs
337
    $("#metadata-wizard div.machine-name").text(serverName);
338
    // set server id to all related metadata dialogs
339
    $("#metadata-wizard p").text(serverID);
340
    show_metadata_wizard();
341
    return false;
342
});
343

344
// intercept start click
345
$("#machinesview-single.single div.action-start").live('click', function(){
346
    var serverID = $(this).closest(".single-container").attr("id");
347
    var serverName = $(this).closest("div.upper").find(".machine-details div.name").text();
348
    $('#machinesview-single').find('div.single-action').removeClass('selected');
349
    $(this).addClass('selected');
350
    $(this).parent().parent().find('.action_error').hide();
351
    // reset pending actions so not to allow multiple actions in this view
352
    pending_actions = [];
353
    pending_actions.push([start, serverID, serverName]);
354
    update_confirmations();
355
    return false;
356
});
357

358
// intercept shutdown click
359
$("#machinesview-single.single div.action-shutdown").live('click', function(){
360
    var serverID = $(this).closest(".single-container").attr("id");
361
    var serverName = $(this).closest("div.upper").find(".machine-details div.name").text();
362
    $('#machinesview-single').find('div.single-action').removeClass('selected');
363
    $(this).addClass('selected');
364
    $(this).parent().parent().find('.action_error').hide();
365
    // reset pending actions so not to allow multiple actions in this view
366
    pending_actions = [];
367
    pending_actions.push([shutdown, serverID, serverName]);
368
    update_confirmations();
369
    return false;
370
});
371

372
// intercept reboot click
373
$("#machinesview-single.single div.action-reboot").live('click', function(){
374
    var serverID = $(this).closest(".single-container").attr("id");
375
    var serverName = $(this).closest("div.upper").find(".machine-details div.name").text();
376
    $('#machinesview-single').find('div.single-action').removeClass('selected');
377
    $(this).addClass('selected');
378
    $(this).parent().parent().find('.action_error').hide();
379
    // reset pending actions so not to allow multiple actions in this view
380
    pending_actions = [];
381
    pending_actions.push([reboot, serverID, serverName]);
382
    update_confirmations();
383
    return false;
384
});
385

386
// intercept destroy click
387
$("#machinesview-single.single div.action-destroy").live('click', function(){
388
    var serverID = $(this).closest(".single-container").attr("id");
389
    var serverName = $(this).closest("div.upper").find(".machine-details div.name").text();
390
    $('#machinesview-single').find('div.single-action').removeClass('selected');
391
    $(this).addClass('selected');
392
    $(this).parent().parent().find('.action_error').hide();
393
    // reset pending actions so not to allow multiple actions in this view
394
    pending_actions = [];
395
    pending_actions.push([destroy, serverID, serverName]);
396
    update_confirmations();
397
    return false;
398
});
399

400
// intercept console click
401
$("#machinesview-single.single div.action-console").live('click', function(){
402
    var serverID = $(this).closest(".single-container").attr("id");
403
    var serverName = $(this).closest("div.upper").find(".machine-details div.name").text();
404
    $('#machinesview-single').find('div.single-action').removeClass('selected');
405
    $(this).addClass('selected');
406
    $(this).parent().parent().find('.action_error').hide();
407
    // reset pending actions so not to allow multiple actions in this view
408
    pending_actions = [];
409
    pending_actions.push([open_console, serverID, serverName]);
410
    update_confirmations();
411
    return false;
412
});
413

414
// connect to machine on machine logo click
415
$("#machinesview-single.single div.single-image").live('click', function(){
416
    if ($(this).parent().find(".connect-arrow:visible").length == 0) { return };
417
    var serverID = $(this).closest(".single-container").attr("id");
418
    machine_connect([machine_connect, serverID]);
419
    return false;
420
});
421

422
// connect to machine on connect arrow click
423
$("#machinesview-single.single div.connect-arrow").live('click', function(){
424
    var serverID = $(this).closest(".single-container").attr("id");
425
    machine_connect([machine_connect, serverID]);
426
    return false;
427
});
428

429
// connect to machine on connect arrow border click
430
$("#machinesview-single.single div.connect-border").live('click', function(){
431
    var serverID = $(this).closest(".single-container").attr("id");
432
    machine_connect([machine_connect, serverID]);
433
    return false;
434
});
435

436
// update the servers list
437
function update_machines_view(data){
438
    /*
439
    Go through the servers in the input data. Update existing entries, add
440
    new ones to the list
441
    */
442

443
    $.each(data.servers.values, function(i,server){
444

445
        existing = $('#machinesview-single.single #' + server.id);
446
        existing_link = $('#machinesview-single div.column3 #link-' + server.id);
447
        var current_Id = current_serverId();
448

449
        // if multiple machines exist in the DOM, delete all but one
450
        // defensive coding - that shouldn't happen normally
451
        while (existing.length > 1){
452
            existing.remove();
453
        }
454
        // get server OS, if it exists
455
        if (!(server.metadata == undefined)) {
456
            var server_image = os_icon(server.metadata);
457
        } else {
458
            var server_image = "unknown"
459
        }
460
        // get server status message, if it exists
461
        var current_message = existing.find(".state-label").text().replace(TRANSITION_STATE_APPEND, "");
462

463
        // server already exists in DOM
464
        if (existing.length){
465
            $("#machinesview-single.single div.single-container:last-child").find("div.separator").show();
466
            //  if the status is deleted, delete it from the DOM
467
            if (server.status == 'DELETED') {
468
                existing.remove();
469
                existing_link.remove();
470
                //if the deleted vm is the displayed one, display the 1st vm
471
                if (server.id == current_Id) {
472
                    $("#machinesview-single.single div.single-container:eq(1)").show()
473
                    $('#machinesview-single.single .column3').find('.server-name:eq(1)').addClass('column3-selected');
474
                }
475
                try {
476
                    console.info(existing.find(".machine-details div.name").text() + ' removed');
477
                } catch(err) {}
478
            }
479
            // if the status has changed
480
            else if ( current_message != STATUSES[server.status]) {
481
                /*
482
                Here there are 4 possibilities:
483
                    1. From an active state to an inactive one
484
                    2. From an inactive state to an active one
485
                    3. From an active state to a different active one
486
                    4. From an inactive state to a different inactive one
487
                The last two (3, 4) can be dealt with the same way
488
                */
489
                if (ACTIVE_STATES.indexOf(current_message) >= 0 &&
490
                    INACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
491
                    // from an active state to an inactive one
492
                    log_server_status_change(existing, server.status);
493
                    set_machine_os_image(existing, "single", "off", server_image);
494
                    existing.find(".column1 .state-label").text(STATUSES[server.status]);
495
                    existing.find(".connect-border").hide();
496
                    existing.find(".connect-arrow").hide();
497
                    existing.find(".column1 .state .spinner").hide();
498
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
499
                    existing.find(".column1 .state").removeClass().addClass("state terminated-state");
500
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
501
                }
502
                else if (INACTIVE_STATES.indexOf(current_message) >= 0 &&
503
                         ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
504
                    // From an inactive state to an active one
505
                    log_server_status_change(existing, server.status);
506
                    set_machine_os_image(existing, "single", "on", server_image);
507
                    existing.find(".column1 .state-label").text(STATUSES[server.status]);
508
                    existing.find(".connect-border").show();
509
                    existing.find(".connect-arrow").show();
510
                    existing.find(".column1 .state .spinner").hide();
511
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
512
                    existing.find(".column1 .state").removeClass().addClass("state running-state");
513
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
514
                }
515
                else {
516
                    // handling active to active or inactive to inactive changes
517
                    if (TRANSITIONS[current_message] && TRANSITIONS[current_message] != 'Rebooting') {
518
                        // don't do anything if it is still in transition
519
                    }
520
                    else if ((TRANSITIONS[current_message] == 'Rebooting' && server.status == 'ACTIVE') ||
521
                             (STATUSES['BUILD'] == current_message && server.status == 'ACTIVE')) {
522
                        // if it has been rebooted or just created
523
                        log_server_status_change(existing, server.status);
524
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
525
                        existing.find(".connect-border").show();
526
                        existing.find(".connect-arrow").show();
527
                        existing.find(".column1 .state .spinner").hide();
528
                        existing.find(".column1 .state").attr('src','static/icons/indicators/medium/wave.gif').show();
529
                        existing.find(".column1 .state").removeClass().addClass("state running-state");
530
                        setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
531
                    }
532
                    else if (STATUSES[server.status] == "Rebooting") { 
533
                        // from running to rebooting
534
                        log_server_status_change(existing, server.status);
535
                        existing.find(".column1 .state").removeClass().addClass('state rebooting-state');
536
                        existing.find('.column1 .state .spinner').show();
537
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
538
                    } else {
539
                        // in any other case just change the status and ignore spinners/waves
540
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
541
                    }
542
                }
543
            }
544
            // find and display ips
545
            var ips = get_public_ips(server);
546
            existing.find(".machine-details div.ipv4").text(ips['ip4']);
547
            existing.find(".machine-details div.ipv6").text(ips['ip6']);
548

549
        } else if (server.status != 'DELETED') {
550
            // If it does not exist and it's not deleted, we should create it
551
            var serverwidget = $("#servers-widget-template").clone().attr("id", 'link-' + server.id);
552
            if (server.name.length > 18) {
553
                serverwidget.text(server.name.substring(0,15) + '...');
554
            } else {
555
                serverwidget.text(server.name)
556
            }
557
            serverwidget.appendTo('.servers');
558
            serverwidget.show();
559
            //find and hide the previously selected server
560
            $('.single').find('.single-container').hide();
561
            $('.single .column3').find('.column3-selected').removeClass('column3-selected');
562
            //create and select the new one
563
            var machine = $("#machinesview-single.single #machine-container-template").clone().attr("id", server.id);
564
            machine.find(".scrollable").scrollable({vertical: true});
565
            machine.find(".machine-details div.name").text(fix_server_name(server.name));
566
            set_machine_os_image(machine, "single", "on", server_image);
567
            machine.find("span.imagetag").text(server_image);
568
            machine.find(".column1 .state-label").text(STATUSES[server.status]);
569
            // find and display flavor parameters
570
            var flavor_params = get_flavor_params(server.flavorRef);
571
            machine.find(".machine-details div.cpus").text(flavor_params['cpus']);
572
            machine.find(".machine-details div.ram").text(flavor_params['ram']);
573
            machine.find(".machine-details div.disk").text(flavor_params['disk']);
574
            // find and display image parameters
575
            var image_params = get_image_params(server.imageRef);
576
            machine.find(".machine-details div.image-name").text(image_params['name'].substring(0,15));
577
            machine.find(".machine-details div.image-size").text(image_params['size']);
578
            // find and display ips
579
            var ips = get_public_ips(server);
580
            machine.find(".machine-details div.ipv4").text(ips['ip4']);
581
            machine.find(".machine-details div.ipv6").text(ips['ip6']);
582
            //show off image if server is not active
583
            if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf(server.status) < 0){
584
                    set_machine_os_image(machine, "single", "off", server_image);
585
                    machine.find(".connect-border").hide();
586
                    machine.find(".connect-arrow").hide();
587
                    machine.find(".column1 .state").removeClass().addClass("state terminated-state");
588
            }
589
            //show spinner while machine is building or rebooting
590
            if (server.status == 'BUILD' ||
591
                [TRANSITIONS['Starting'], TRANSITIONS['Shutting down']].indexOf(existing.find(".status").text().replace(TRANSITION_STATE_APPEND, "")) >= 0 ) {
592
                machine.find(".column1 .state .spinner").show();
593
                machine.find(".connect-border").hide();
594
                machine.find(".connect-arrow").hide();
595
                machine.find(".column1 .state").removeClass().addClass('state build-state');
596
            }
597
            if (server.status == 'REBOOT') {
598
                machine.find(".column1 .state").find('.spinner').show();
599
                machine.find(".connect-border").hide();
600
                machine.find(".connect-arrow").hide();
601
                machine.find(".column1 .state").removeClass().addClass('state rebooting-state');
602
            }
603
            machine.appendTo("#machinesview-single.single");
604
            //disable reboot and shutdown actions while machine is building
605
            if (server.status == 'BUILD') {
606
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
607
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
608
            }
609
            // show console action only on active servers
610
            if (server.status == 'ACTIVE') {
611
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').show();
612
                $('#machinesview-single.single div.#' + server.id + ' div.action-start').hide();
613
                machine.find(".connect-border").show();
614
                machine.find(".connect-arrow").show();
615
            } else if (server.status == 'REBOOT'){
616
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
617
            } else {
618
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
619
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
620
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
621
            }
622

623

624
            //show the first machine and select it in the widget
625
            $('.single-container:eq(1)').show();
626
            $('.single .column3').find('.server-name:eq(1)').addClass('column3-selected');
627

628
            // add stats images error events handlers
629
            $(".cpu-graph img.stats, .network-graph img.stats").error(function(){
630
                $(this).hide();
631
                $(this).parent().find(".stat-error").show();
632
            }).load(function(){
633
                $(this).show();
634
                $(this).parent().find(".stat-error").hide();
635
            });
636
        }
637
        update_iconview_actions(server.id, server.status);
638
        if (!(server.metadata == undefined)) {
639
                list_metadata_keys(server.id, server.metadata.values);
640
        }
641
        if (server.id == current_serverId()) {
642
            get_server_stats(server.id);
643
        }
644

645
        // if machine in destroy state keep it that way
646
        var server = get_machine(server.id);
647
        if (server.status == "DESTROY") {
648
            existing = $('#machinesview-single.single #' + server.id);
649
            if (existing.length) {
650
                existing.find(".column1 .state-label").text(TRANSITIONS['Destroying']);
651
                existing.find(".column1 .state").removeClass().addClass('state destroying-state');
652
                existing.find(".column1 .state .spinner").show();
653
                existing.find(".column1 .wave").hide();
654
            }
655
        }
656
    });
657

658
    update_transition_names();
659
    fix_v6_addresses();
660
    // hide pane spinner
661
    $("#machinesview-single.single > div.large-spinner").hide();
662

663
    // show message in case user has no server!
664
    if ($('#machinesview-single div.single-container').length == 1) {
665
        showWelcome();
666
    } else {
667
        hideWelcome();
668
        $('.single .column3').show();
669
    }
670

671
    //enable widget links
672
    $(".server-name").live('click', function() {
673
        $('.single').find('.single-container').hide()
674
        $('.single').find('#' + $(this).attr('id').substring(5)).show();
675
        $('.single .column3').find('.column3-selected').removeClass('column3-selected');
676
        $(this).addClass('column3-selected');
677
        update_prev_next()
678
    });
679

680
    if ($.cookie('server')) {
681
        $('div#link-' + $.cookie('server')).click();
682
        $.cookie('server', null);
683
    }
684

685
    //if it is the last vm, disable the next button
686
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
687
        $("#machinesview-single.single .column3 .next").addClass('disabled');
688
    }
689

690
    //if it is the first vm, disable the prev button
691
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
692
        $("#machinesview-single.single .column3 .previous").addClass('disabled');
693
    }
694
}
695

696
// define these to avoid exceptions
697
function display_reboot_success() {
698
}
699

700
function display_reboot_failure() {
701
}
702

703
// append string to transition states
704
function update_transition_names() {
705
    $(".state-label").each(function(index,el){
706
    var tr_text = $(this).text().replace(TRANSITION_STATE_APPEND,"");
707
    if (TRANSITION_STATES.indexOf(tr_text) >= 0) {
708
            $(this).text(tr_text + TRANSITION_STATE_APPEND);
709
        }
710
    })
711
}
712

713
//get currently displayed serverId
714
function current_serverId() {
715
    return $("#machinesview-single.single").find("div.single-container:visible").attr("id");
716
}
717

718
//enable prev-next buttons
719
$("#machinesview-single.single .column3 .previous").live('click', function() {
720
    // set behavior
721
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
722
        return false;
723
    } else {
724
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
725
        $('#machinesview-single.single').find('#' + current_server).hide();
726
        $('#machinesview-single.single').find('#' + current_server).prev().show();
727
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
728
        $('#machinesview-single.single .column3').find('#link-' + current_server).prev().addClass('column3-selected');
729
        update_prev_next()
730
        return false;
731
    }
732
});
733

734
$("#machinesview-single.single .column3 .next").live('click', function() {
735
    // set behavior
736
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
737
        return false;
738
        } else {
739
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
740
        $('#machinesview-single.single').find('#' + current_server).hide();
741
        $('#machinesview-single.single').find('#' + current_server).next().show();
742
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
743
        $('#machinesview-single.single .column3').find('#link-' + current_server).next().addClass('column3-selected');
744
        update_prev_next()
745
        return false;
746
    }
747
});
748

749

750
//enables-disables previous/next buttons accordingly
751
function update_prev_next() {
752
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
753
        $(".single .column3 .previous").removeClass('disabled');
754
    } else {
755
        //disable class
756
        $(".single .column3 .previous").addClass('disabled');
757
    }
758
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
759
        $(".single .column3 .next").removeClass('disabled');
760
    } else {
761
        //disable class
762
        $(".single .column3 .next").addClass('disabled');
763
    }
764
    get_server_stats(current_serverId());
765
}
766

767
// basic functions executed on page load
768
if ( flavors.length == 0 && images.length == 0 ) {
769
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
770
    update_flavors();
771
    // populate image list
772
    update_images();
773
} else if ( flavors.length == 0 && images.length != 0 ) {
774
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
775
    update_flavors();
776
} else if ( flavors.length != 0 && images.length == 0 ) {
777
    // populate image list
778
    update_images();
779
    update_vms(UPDATE_INTERVAL);
780
} else {
781
    // start updating vm list
782
    update_vms(UPDATE_INTERVAL);
783
}
784

785
//IE specific fixes
786
if ($.browser.msie) {
787
    //IE fix for green arrow hover
788
    $("div.connect-arrow").live("mouseenter", function () {
789
        $(this).addClass("connect-arrow-ie");
790
    });
791
    $("div.connect-arrow").live("mouseleave", function () {
792
        $(this).removeClass("connect-arrow-ie");
793
    });
794
    //IE fix for details button
795
    $("button.details").live("mouseenter", function () {
796
        $(this).css("background-color","#FF7F2A");
797
    });
798
    $("button.details").live("mouseleave", function () {
799
        $(this).css("background-color","transparent");
800
    });
801
}
802

    
803
</script>