Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ 9ac432ec

History | View | Annotate | Download (41.1 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
        has_ip = vm_has_public_ip(singleview_closest_vm(this));
203
        // ugly check to see if machine is running
204
        if ($(this).parent().find(".connect-arrow:visible").length == 0 || !has_ip) { return };
205
        set_machine_os_image($(this).parent().parent(), "single", "hover", undefined, 1);
206
        var parent = $(this).parent().parent();
207
        parent.find(".connect-arrow").show().addClass('border-hover');
208
    });
209

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

220
$("div.connect-arrow, .single-image").live('mousedown',
221
    function() {
222
        has_ip = vm_has_public_ip(singleview_closest_vm(this));
223
        if ($(this).parent().find(".connect-arrow:visible").length == 0 || !has_ip) { return };
224
        set_machine_os_image($(this).parent().parent(), "single", "click", undefined, 1);
225
    });
226

227
$("div.connect-arrow, .single-image").live('mouseup',
228
    function() {
229
        has_ip = vm_has_public_ip(singleview_closest_vm(this));
230
        if ($(this).parent().find(".connect-arrow:visible").length == 0 || !has_ip) { return };
231
        set_machine_os_image($(this).parent().parent(), "single", "click", undefined, 1, "click");
232
    });
233

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

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

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

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

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

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

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

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

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

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

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

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

419
// connect to machine on machine logo click
420
$("#machinesview-single.single div.single-image").live('click', function(){
421
    if ($(this).parent().find(".connect-arrow:visible").length == 0) { return };
422
    has_ip = vm_has_public_ip(singleview_closest_vm(this));
423
    if (!has_ip) { return }
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 click
430
$("#machinesview-single.single div.connect-arrow").live('click', function(){
431
    var serverID = $(this).closest(".single-container").attr("id");
432
    machine_connect([machine_connect, serverID]);
433
    return false;
434
});
435

436
// connect to machine on connect arrow border click
437
$("#machinesview-single.single div.connect-border").live('click', function(){
438
    var serverID = $(this).closest(".single-container").attr("id");
439
    machine_connect([machine_connect, serverID]);
440
    return false;
441
});
442

443
// update the servers list
444
function update_machines_view(data){
445
    /*
446
    Go through the servers in the input data. Update existing entries, add
447
    new ones to the list
448
    */
449

450
    $.each(data.servers.values, function(i,server){
451

452
        existing = $('#machinesview-single.single #' + server.id);
453
        existing_link = $('#machinesview-single div.column3 #link-' + server.id);
454
        var current_Id = current_serverId();
455

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

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

506
                    if (server.status == "STOPPED") {
507
                        existing.find(".column1 .state").removeClass().addClass("state terminated-state");
508
                    } else {
509
                        existing.find(".column1 .state").removeClass().addClass("state error-state");
510
                    }
511

512
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
513
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
514
                }
515
                else if (INACTIVE_STATES.indexOf(current_message) >= 0 &&
516
                         ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
517
                    // From an inactive state to an active one
518
                    log_server_status_change(existing, server.status);
519
                    set_machine_os_image(existing, "single", "on", server_image);
520
                    existing.find(".column1 .state-label").text(STATUSES[server.status]);
521

522
                    vm = get_machine(existing.attr("id"));
523
                    has_ip = vm_has_public_ip(vm);
524

525
                    if (has_ip) {
526
                        existing.find(".connect-border").show();
527
                        existing.find(".connect-arrow").show();
528
                    } else {
529
                        existing.find(".connect-border").hide();
530
                        existing.find(".connect-arrow").hide();
531
                    }
532

533
                    existing.find(".column1 .state .spinner").hide();
534
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
535
                    existing.find(".column1 .state").removeClass().addClass("state running-state");
536
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
537
                }
538
                else {
539
                    // handling active to active or inactive to inactive changes
540
                    if (TRANSITIONS[current_message] && TRANSITIONS[current_message] != 'Rebooting') {
541
                        // don't do anything if it is still in transition
542
                    }
543
                    else if ((TRANSITIONS[current_message] == 'Rebooting' && server.status == 'ACTIVE') ||
544
                             (STATUSES['BUILD'] == current_message && server.status == 'ACTIVE')) {
545
                        // if it has been rebooted or just created
546
                        log_server_status_change(existing, server.status);
547
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
548
                        vm = get_machine(existing.attr("id"));
549
                        has_ip = vm_has_public_ip(vm);
550

551
                        if (has_ip) {
552
                            existing.find(".connect-border").show();
553
                            existing.find(".connect-arrow").show();
554
                        } else {
555
                            existing.find(".connect-border").hide();
556
                            existing.find(".connect-arrow").hide();
557
                        }
558
                        existing.find(".column1 .state .spinner").hide();
559
                        existing.find(".column1 .state").attr('src','static/icons/indicators/medium/wave.gif').show();
560
                        existing.find(".column1 .state").removeClass().addClass("state running-state");
561
                        setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
562
                    }
563
                    else if (STATUSES[server.status] == "Rebooting") { 
564
                        // from running to rebooting
565
                        log_server_status_change(existing, server.status);
566
                        existing.find(".column1 .state").removeClass().addClass('state rebooting-state');
567
                        existing.find('.column1 .state .spinner').show();
568
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
569
                    } else {
570
                        // in any other case just change the status and ignore spinners/waves
571
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
572
                    }
573
                }
574
            }
575
            // find and display ips
576
            var ips = get_public_ips(server);
577
            existing.find(".machine-details div.ipv4").text(ips['ip4']);
578
            existing.find(".machine-details div.ipv6").text(ips['ip6']);
579

580
        } else if (server.status != 'DELETED') {
581
            // If it does not exist and it's not deleted, we should create it
582
            var serverwidget = $("#servers-widget-template").clone().attr("id", 'link-' + server.id);
583
            if (server.name.length > 18) {
584
                serverwidget.text(server.name.substring(0,15) + '...');
585
            } else {
586
                serverwidget.text(server.name)
587
            }
588
            serverwidget.appendTo('.servers');
589
            serverwidget.show();
590
            //find and hide the previously selected server
591
            $('.single').find('.single-container').hide();
592
            $('.single .column3').find('.column3-selected').removeClass('column3-selected');
593
            //create and select the new one
594
            var machine = $("#machinesview-single.single #machine-container-template").clone().attr("id", server.id);
595
            machine.find(".scrollable").scrollable({vertical: true});
596
            machine.find(".machine-details div.name").text(fix_server_name(server.name));
597
            set_machine_os_image(machine, "single", "on", server_image);
598
            machine.find("span.imagetag").text(server_image);
599
            machine.find(".column1 .state-label").text(STATUSES[server.status]);
600
            // find and display flavor parameters
601
            var flavor_params = get_flavor_params(server.flavorRef);
602
            machine.find(".machine-details div.cpus").text(flavor_params['cpus']);
603
            machine.find(".machine-details div.ram").text(flavor_params['ram']);
604
            machine.find(".machine-details div.disk").text(flavor_params['disk']);
605
            // find and display image parameters
606
            var image_params = get_image_params(server.imageRef);
607
            machine.find(".machine-details div.image-name").text(image_params['name'].substring(0,15));
608
            machine.find(".machine-details div.image-size").text(image_params['size']);
609
            // find and display ips
610
            var ips = get_public_ips(server);
611
            machine.find(".machine-details div.ipv4").text(ips['ip4']);
612
            machine.find(".machine-details div.ipv6").text(ips['ip6']);
613
            //show off image if server is not active
614
            if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf(server.status) < 0){
615
                    set_machine_os_image(machine, "single", "off", server_image);
616
                    machine.find(".connect-border").hide();
617
                    machine.find(".connect-arrow").hide();
618
                    if (server.status == "STOPPED") {
619
                        machine.find(".column1 .state").removeClass().addClass("state terminated-state");
620
                    } else {
621
                        machine.find(".column1 .state").removeClass().addClass("state error-state");
622
                    }
623

624
            }
625
            //show spinner while machine is building or rebooting
626
            if (server.status == 'BUILD' ||
627
                [TRANSITIONS['Starting'], TRANSITIONS['Shutting down']].indexOf(existing.find(".status").text().replace(TRANSITION_STATE_APPEND, "")) >= 0 ) {
628
                machine.find(".column1 .state .spinner").show();
629
                machine.find(".connect-border").hide();
630
                machine.find(".connect-arrow").hide();
631
                machine.find(".column1 .state").removeClass().addClass('state build-state');
632
            }
633
            if (server.status == 'REBOOT') {
634
                machine.find(".column1 .state").find('.spinner').show();
635
                machine.find(".connect-border").hide();
636
                machine.find(".connect-arrow").hide();
637
                machine.find(".column1 .state").removeClass().addClass('state rebooting-state');
638
            }
639
            machine.appendTo("#machinesview-single.single");
640
            //disable reboot and shutdown actions while machine is building
641
            if (server.status == 'BUILD') {
642
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
643
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
644
            }
645
            // show console action only on active servers
646
            if (server.status == 'ACTIVE') {
647
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').show();
648
                $('#machinesview-single.single div.#' + server.id + ' div.action-start').hide();
649

650
                vm = get_machine(machine.attr("id"));
651
                has_ip = vm_has_public_ip(vm);
652

653
                if (has_ip) {
654
                    machine.find(".connect-border").show();
655
                    machine.find(".connect-arrow").show();
656
                } else {
657
                    machine.find(".connect-border").hide();
658
                    machine.find(".connect-arrow").hide();
659
                }
660

661
            } else if (server.status == 'REBOOT'){
662
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
663
            } else {
664
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
665
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
666
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
667
            }
668

669

670
            //show the first machine and select it in the widget
671
            $('.single-container:eq(1)').show();
672
            $('.single .column3').find('.server-name:eq(1)').addClass('column3-selected');
673

674
            // add stats images error events handlers
675
            $(".cpu-graph img.stats, .network-graph img.stats").error(function(){
676
                $(this).hide();
677
                $(this).parent().find(".stat-error").show();
678
            }).load(function(){
679
                // skip initial image
680
                if ($(this).attr("src") == "./static/placeholder.png") {
681
                    $(this).hide();
682
                    return;
683
                }
684
                $(this).show();
685
                $(this).parent().find(".stat-error").hide();
686
            });
687
        }
688
        update_iconview_actions(server.id, server.status);
689
        if (!(server.metadata == undefined)) {
690
                list_metadata_keys(server.id, server.metadata.values);
691
        }
692
        if (server.id == current_serverId()) {
693
            get_server_stats(server.id);
694
        }
695
        
696
        server = get_machine(server.id);
697
        existing = $('#machinesview-single.single div.#' + server.id);
698

699
        // if machine in destroy state keep it that way
700
        if (server.status == "DESTROY") {
701
            existing = $('#machinesview-single.single #' + server.id);
702
            if (existing.length) {
703
                existing.find(".column1 .state-label").text(TRANSITIONS['Destroying']);
704
                existing.find(".column1 .state").removeClass().addClass('state destroying-state');
705
                existing.find(".column1 .state .spinner").show();
706
                existing.find(".column1 .wave").hide();
707
            }
708
        }
709

710
        // update progress
711
        if (server.status == 'BUILD' && existing.length > 0) {
712
            var progress_details = get_progress_details(server.id);
713
            existing.find("span.build-progress").show().text(progress_details.msg);
714
        } else {
715
            existing.find("span.build-progress").hide();
716
        }
717

718
    });
719

720
    update_transition_names();
721
    fix_v6_addresses();
722
    // hide pane spinner
723
    $("#machinesview-single.single > div.large-spinner").hide();
724

725
    // show message in case user has no server!
726
    if ($('#machinesview-single div.single-container').length == 1) {
727
        showWelcome();
728
    } else {
729
        hideWelcome();
730
        $('.single .column3').show();
731
    }
732

733
    //enable widget links
734
    $(".server-name").live('click', function() {
735
        $('.single').find('.single-container').hide()
736
        $('.single').find('#' + $(this).attr('id').substring(5)).show();
737
        $('.single .column3').find('.column3-selected').removeClass('column3-selected');
738
        $(this).addClass('column3-selected');
739
        update_prev_next()
740
    });
741

742
    if ($.cookie('server')) {
743
        $('div#link-' + $.cookie('server')).click();
744
        $.cookie('server', null);
745
    }
746

747
    //if it is the last vm, disable the next button
748
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
749
        $("#machinesview-single.single .column3 .next").addClass('disabled');
750
    }
751

752
    //if it is the first vm, disable the prev button
753
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
754
        $("#machinesview-single.single .column3 .previous").addClass('disabled');
755
    }
756
}
757

758
// define these to avoid exceptions
759
function display_reboot_success() {
760
}
761

762
function display_reboot_failure() {
763
}
764

765
function display_success() {
766
}
767

768
// append string to transition states
769
function update_transition_names() {
770
    $(".state-label").each(function(index,el){
771
    var tr_text = $(this).text().replace(TRANSITION_STATE_APPEND,"");
772
    if (TRANSITION_STATES.indexOf(tr_text) >= 0) {
773
            $(this).text(tr_text + TRANSITION_STATE_APPEND);
774
        }
775
    })
776
}
777

778
//get currently displayed serverId
779
function current_serverId() {
780
    return $("#machinesview-single.single").find("div.single-container:visible").attr("id");
781
}
782

783
//enable prev-next buttons
784
$("#machinesview-single.single .column3 .previous").live('click', function() {
785
    // set behavior
786
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
787
        return false;
788
    } else {
789
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
790
        $('#machinesview-single.single').find('#' + current_server).hide();
791
        $('#machinesview-single.single').find('#' + current_server).prev().show();
792
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
793
        $('#machinesview-single.single .column3').find('#link-' + current_server).prev().addClass('column3-selected');
794
        update_prev_next()
795
        return false;
796
    }
797
});
798

799
$("#machinesview-single.single .column3 .next").live('click', function() {
800
    // set behavior
801
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
802
        return false;
803
        } else {
804
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
805
        $('#machinesview-single.single').find('#' + current_server).hide();
806
        $('#machinesview-single.single').find('#' + current_server).next().show();
807
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
808
        $('#machinesview-single.single .column3').find('#link-' + current_server).next().addClass('column3-selected');
809
        update_prev_next()
810
        return false;
811
    }
812
});
813

814

815
//enables-disables previous/next buttons accordingly
816
function update_prev_next() {
817
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
818
        $(".single .column3 .previous").removeClass('disabled');
819
    } else {
820
        //disable class
821
        $(".single .column3 .previous").addClass('disabled');
822
    }
823
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
824
        $(".single .column3 .next").removeClass('disabled');
825
    } else {
826
        //disable class
827
        $(".single .column3 .next").addClass('disabled');
828
    }
829
    get_server_stats(current_serverId());
830
}
831

832
// basic functions executed on page load
833
if ( flavors.length == 0 && images.length == 0 ) {
834
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
835
    update_flavors();
836
    // populate image list
837
    update_images();
838
} else if ( flavors.length == 0 && images.length != 0 ) {
839
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
840
    update_flavors();
841
} else if ( flavors.length != 0 && images.length == 0 ) {
842
    // populate image list
843
    update_images();
844
    update_vms(UPDATE_INTERVAL);
845
} else {
846
    // start updating vm list
847
    update_vms(UPDATE_INTERVAL);
848
}
849

850
//IE specific fixes
851
if ($.browser.msie) {
852
    //IE fix for green arrow hover
853
    $("div.connect-arrow").live("mouseenter", function () {
854
        $(this).addClass("connect-arrow-ie");
855
    });
856
    $("div.connect-arrow").live("mouseleave", function () {
857
        $(this).removeClass("connect-arrow-ie");
858
    });
859
    //IE fix for details button
860
    $("button.details").live("mouseenter", function () {
861
        $(this).css("background-color","#FF7F2A");
862
    });
863
    $("button.details").live("mouseleave", function () {
864
        $(this).css("background-color","transparent");
865
    });
866
}
867

    
868
</script>