Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ 69ba1fcf

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

    
192
<script>
193

194
init_action_indicator_handlers('single');
195

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

464
        // server already exists in DOM
465
        if (existing.length){
466
            $("#machinesview-single.single div.single-container:last-child").find("div.separator").show();
467
            //  if the status is deleted, delete it from the DOM
468
            if (server.status == 'DELETED') {
469
                existing.remove();
470
                existing_link.remove();
471
                //if the deleted vm is the displayed one, display the 1st vm
472
                if (server.id == current_Id) {
473
                    $("#machinesview-single.single div.single-container:eq(1)").show()
474
                    $('#machinesview-single.single .column3').find('.server-name:eq(1)').addClass('column3-selected');
475
                }
476
                try {
477
                    console.info(existing.find(".machine-details div.name").text() + ' removed');
478
                } catch(err) {}
479
            }
480
            // if the status has changed
481
            else if ( current_message != STATUSES[server.status]) {
482
                /*
483
                Here there are 4 possibilities:
484
                    1. From an active state to an inactive one
485
                    2. From an inactive state to an active one
486
                    3. From an active state to a different active one
487
                    4. From an inactive state to a different inactive one
488
                The last two (3, 4) can be dealt with the same way
489
                */
490
                if (ACTIVE_STATES.indexOf(current_message) >= 0 &&
491
                    INACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
492
                    // from an active state to an inactive one
493
                    log_server_status_change(existing, server.status);
494
                    set_machine_os_image(existing, "single", "off", server_image);
495
                    existing.find(".column1 .state-label").text(STATUSES[server.status]);
496
                    existing.find(".connect-border").hide();
497
                    existing.find(".connect-arrow").hide();
498
                    existing.find(".column1 .state .spinner").hide();
499

500
                    if (server.status == "STOPPED") {
501
                        existing.find(".column1 .state").removeClass().addClass("state terminated-state");
502
                    } else {
503
                        existing.find(".column1 .state").removeClass().addClass("state error-state");
504
                    }
505

506
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
507
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
508
                }
509
                else if (INACTIVE_STATES.indexOf(current_message) >= 0 &&
510
                         ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
511
                    // From an inactive state to an active one
512
                    log_server_status_change(existing, server.status);
513
                    set_machine_os_image(existing, "single", "on", server_image);
514
                    existing.find(".column1 .state-label").text(STATUSES[server.status]);
515
                    existing.find(".connect-border").show();
516
                    existing.find(".connect-arrow").show();
517
                    existing.find(".column1 .state .spinner").hide();
518
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
519
                    existing.find(".column1 .state").removeClass().addClass("state running-state");
520
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
521
                }
522
                else {
523
                    // handling active to active or inactive to inactive changes
524
                    if (TRANSITIONS[current_message] && TRANSITIONS[current_message] != 'Rebooting') {
525
                        // don't do anything if it is still in transition
526
                    }
527
                    else if ((TRANSITIONS[current_message] == 'Rebooting' && server.status == 'ACTIVE') ||
528
                             (STATUSES['BUILD'] == current_message && server.status == 'ACTIVE')) {
529
                        // if it has been rebooted or just created
530
                        log_server_status_change(existing, server.status);
531
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
532
                        existing.find(".connect-border").show();
533
                        existing.find(".connect-arrow").show();
534
                        existing.find(".column1 .state .spinner").hide();
535
                        existing.find(".column1 .state").attr('src','static/icons/indicators/medium/wave.gif').show();
536
                        existing.find(".column1 .state").removeClass().addClass("state running-state");
537
                        setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
538
                    }
539
                    else if (STATUSES[server.status] == "Rebooting") { 
540
                        // from running to rebooting
541
                        log_server_status_change(existing, server.status);
542
                        existing.find(".column1 .state").removeClass().addClass('state rebooting-state');
543
                        existing.find('.column1 .state .spinner').show();
544
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
545
                    } else {
546
                        // in any other case just change the status and ignore spinners/waves
547
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
548
                    }
549
                }
550
            }
551
            // find and display ips
552
            var ips = get_public_ips(server);
553
            existing.find(".machine-details div.ipv4").text(ips['ip4']);
554
            existing.find(".machine-details div.ipv6").text(ips['ip6']);
555

556
        } else if (server.status != 'DELETED') {
557
            // If it does not exist and it's not deleted, we should create it
558
            var serverwidget = $("#servers-widget-template").clone().attr("id", 'link-' + server.id);
559
            if (server.name.length > 18) {
560
                serverwidget.text(server.name.substring(0,15) + '...');
561
            } else {
562
                serverwidget.text(server.name)
563
            }
564
            serverwidget.appendTo('.servers');
565
            serverwidget.show();
566
            //find and hide the previously selected server
567
            $('.single').find('.single-container').hide();
568
            $('.single .column3').find('.column3-selected').removeClass('column3-selected');
569
            //create and select the new one
570
            var machine = $("#machinesview-single.single #machine-container-template").clone().attr("id", server.id);
571
            machine.find(".scrollable").scrollable({vertical: true});
572
            machine.find(".machine-details div.name").text(fix_server_name(server.name));
573
            set_machine_os_image(machine, "single", "on", server_image);
574
            machine.find("span.imagetag").text(server_image);
575
            machine.find(".column1 .state-label").text(STATUSES[server.status]);
576
            // find and display flavor parameters
577
            var flavor_params = get_flavor_params(server.flavorRef);
578
            machine.find(".machine-details div.cpus").text(flavor_params['cpus']);
579
            machine.find(".machine-details div.ram").text(flavor_params['ram']);
580
            machine.find(".machine-details div.disk").text(flavor_params['disk']);
581
            // find and display image parameters
582
            var image_params = get_image_params(server.imageRef);
583
            machine.find(".machine-details div.image-name").text(image_params['name'].substring(0,15));
584
            machine.find(".machine-details div.image-size").text(image_params['size']);
585
            // find and display ips
586
            var ips = get_public_ips(server);
587
            machine.find(".machine-details div.ipv4").text(ips['ip4']);
588
            machine.find(".machine-details div.ipv6").text(ips['ip6']);
589
            //show off image if server is not active
590
            if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf(server.status) < 0){
591
                    set_machine_os_image(machine, "single", "off", server_image);
592
                    machine.find(".connect-border").hide();
593
                    machine.find(".connect-arrow").hide();
594
                    if (server.status == "STOPPED") {
595
                        machine.find(".column1 .state").removeClass().addClass("state terminated-state");
596
                    } else {
597
                        machine.find(".column1 .state").removeClass().addClass("state error-state");
598
                    }
599

600
            }
601
            //show spinner while machine is building or rebooting
602
            if (server.status == 'BUILD' ||
603
                [TRANSITIONS['Starting'], TRANSITIONS['Shutting down']].indexOf(existing.find(".status").text().replace(TRANSITION_STATE_APPEND, "")) >= 0 ) {
604
                machine.find(".column1 .state .spinner").show();
605
                machine.find(".connect-border").hide();
606
                machine.find(".connect-arrow").hide();
607
                machine.find(".column1 .state").removeClass().addClass('state build-state');
608
            }
609
            if (server.status == 'REBOOT') {
610
                machine.find(".column1 .state").find('.spinner').show();
611
                machine.find(".connect-border").hide();
612
                machine.find(".connect-arrow").hide();
613
                machine.find(".column1 .state").removeClass().addClass('state rebooting-state');
614
            }
615
            machine.appendTo("#machinesview-single.single");
616
            //disable reboot and shutdown actions while machine is building
617
            if (server.status == 'BUILD') {
618
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
619
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
620
            }
621
            // show console action only on active servers
622
            if (server.status == 'ACTIVE') {
623
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').show();
624
                $('#machinesview-single.single div.#' + server.id + ' div.action-start').hide();
625
                machine.find(".connect-border").show();
626
                machine.find(".connect-arrow").show();
627
            } else if (server.status == 'REBOOT'){
628
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
629
            } else {
630
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
631
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
632
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
633
            }
634

635

636
            //show the first machine and select it in the widget
637
            $('.single-container:eq(1)').show();
638
            $('.single .column3').find('.server-name:eq(1)').addClass('column3-selected');
639

640
            // add stats images error events handlers
641
            $(".cpu-graph img.stats, .network-graph img.stats").error(function(){
642
                $(this).hide();
643
                $(this).parent().find(".stat-error").show();
644
            }).load(function(){
645
                $(this).show();
646
                $(this).parent().find(".stat-error").hide();
647
            });
648
        }
649
        update_iconview_actions(server.id, server.status);
650
        if (!(server.metadata == undefined)) {
651
                list_metadata_keys(server.id, server.metadata.values);
652
        }
653
        if (server.id == current_serverId()) {
654
            get_server_stats(server.id);
655
        }
656
        
657
        server = get_machine(server.id);
658
        existing = $('#machinesview-single.single div.#' + server.id);
659

660
        // if machine in destroy state keep it that way
661
        if (server.status == "DESTROY") {
662
            existing = $('#machinesview-single.single #' + server.id);
663
            if (existing.length) {
664
                existing.find(".column1 .state-label").text(TRANSITIONS['Destroying']);
665
                existing.find(".column1 .state").removeClass().addClass('state destroying-state');
666
                existing.find(".column1 .state .spinner").show();
667
                existing.find(".column1 .wave").hide();
668
            }
669
        }
670

671
        // update progress
672
        if (server.status == 'BUILD' && existing.length > 0) {
673
            var progress_details = get_progress_details(server.id);
674
            existing.find("span.build-progress").show().text(progress_details.msg);
675
        } else {
676
            existing.find("span.build-progress").hide();
677
        }
678

679
    });
680

681
    update_transition_names();
682
    fix_v6_addresses();
683
    // hide pane spinner
684
    $("#machinesview-single.single > div.large-spinner").hide();
685

686
    // show message in case user has no server!
687
    if ($('#machinesview-single div.single-container').length == 1) {
688
        showWelcome();
689
    } else {
690
        hideWelcome();
691
        $('.single .column3').show();
692
    }
693

694
    //enable widget links
695
    $(".server-name").live('click', function() {
696
        $('.single').find('.single-container').hide()
697
        $('.single').find('#' + $(this).attr('id').substring(5)).show();
698
        $('.single .column3').find('.column3-selected').removeClass('column3-selected');
699
        $(this).addClass('column3-selected');
700
        update_prev_next()
701
    });
702

703
    if ($.cookie('server')) {
704
        $('div#link-' + $.cookie('server')).click();
705
        $.cookie('server', null);
706
    }
707

708
    //if it is the last vm, disable the next button
709
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
710
        $("#machinesview-single.single .column3 .next").addClass('disabled');
711
    }
712

713
    //if it is the first vm, disable the prev button
714
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
715
        $("#machinesview-single.single .column3 .previous").addClass('disabled');
716
    }
717
}
718

719
// define these to avoid exceptions
720
function display_reboot_success() {
721
}
722

723
function display_reboot_failure() {
724
}
725

726
// append string to transition states
727
function update_transition_names() {
728
    $(".state-label").each(function(index,el){
729
    var tr_text = $(this).text().replace(TRANSITION_STATE_APPEND,"");
730
    if (TRANSITION_STATES.indexOf(tr_text) >= 0) {
731
            $(this).text(tr_text + TRANSITION_STATE_APPEND);
732
        }
733
    })
734
}
735

736
//get currently displayed serverId
737
function current_serverId() {
738
    return $("#machinesview-single.single").find("div.single-container:visible").attr("id");
739
}
740

741
//enable prev-next buttons
742
$("#machinesview-single.single .column3 .previous").live('click', function() {
743
    // set behavior
744
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
745
        return false;
746
    } else {
747
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
748
        $('#machinesview-single.single').find('#' + current_server).hide();
749
        $('#machinesview-single.single').find('#' + current_server).prev().show();
750
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
751
        $('#machinesview-single.single .column3').find('#link-' + current_server).prev().addClass('column3-selected');
752
        update_prev_next()
753
        return false;
754
    }
755
});
756

757
$("#machinesview-single.single .column3 .next").live('click', function() {
758
    // set behavior
759
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
760
        return false;
761
        } else {
762
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
763
        $('#machinesview-single.single').find('#' + current_server).hide();
764
        $('#machinesview-single.single').find('#' + current_server).next().show();
765
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
766
        $('#machinesview-single.single .column3').find('#link-' + current_server).next().addClass('column3-selected');
767
        update_prev_next()
768
        return false;
769
    }
770
});
771

772

773
//enables-disables previous/next buttons accordingly
774
function update_prev_next() {
775
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
776
        $(".single .column3 .previous").removeClass('disabled');
777
    } else {
778
        //disable class
779
        $(".single .column3 .previous").addClass('disabled');
780
    }
781
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
782
        $(".single .column3 .next").removeClass('disabled');
783
    } else {
784
        //disable class
785
        $(".single .column3 .next").addClass('disabled');
786
    }
787
    get_server_stats(current_serverId());
788
}
789

790
// basic functions executed on page load
791
if ( flavors.length == 0 && images.length == 0 ) {
792
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
793
    update_flavors();
794
    // populate image list
795
    update_images();
796
} else if ( flavors.length == 0 && images.length != 0 ) {
797
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
798
    update_flavors();
799
} else if ( flavors.length != 0 && images.length == 0 ) {
800
    // populate image list
801
    update_images();
802
    update_vms(UPDATE_INTERVAL);
803
} else {
804
    // start updating vm list
805
    update_vms(UPDATE_INTERVAL);
806
}
807

808
//IE specific fixes
809
if ($.browser.msie) {
810
    //IE fix for green arrow hover
811
    $("div.connect-arrow").live("mouseenter", function () {
812
        $(this).addClass("connect-arrow-ie");
813
    });
814
    $("div.connect-arrow").live("mouseleave", function () {
815
        $(this).removeClass("connect-arrow-ie");
816
    });
817
    //IE fix for details button
818
    $("button.details").live("mouseenter", function () {
819
        $(this).css("background-color","#FF7F2A");
820
    });
821
    $("button.details").live("mouseleave", function () {
822
        $(this).css("background-color","transparent");
823
    });
824
}
825

    
826
</script>