Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ 7af53e78

History | View | Annotate | Download (35.4 kB)

1
<!--
2
Copyright 2011 GRNET S.A. All rights reserved.
3

4
Redistribution and use in source and binary forms, with or
5
without modification, are permitted provided that the following
6
conditions are met:
7

8
  1. Redistributions of source code must retain the above
9
     copyright notice, this list of conditions and the following
10
     disclaimer.
11

12
  2. Redistributions in binary form must reproduce the above
13
     copyright notice, this list of conditions and the following
14
     disclaimer in the documentation and/or other materials
15
     provided with the distribution.
16

17
THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
POSSIBILITY OF SUCH DAMAGE.
29

30
The views and conclusions contained in the software and
31
documentation are those of the authors and should not be
32
interpreted as representing official policies, either expressed
33
or implied, of GRNET S.A.
34
-->
35

    
36
{% load i18n %}
37

    
38
<!-- the 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 (GB)" %}:</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">no ipv4</div>
79
                    <div class="machine-detail ipv6">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="http://stats.okeanos.grnet.gr/test/cpu-ts.png" class="stats" />
152
                </div>
153
            </div>
154
            <div class="single-network">
155
                <div class="network-usage">
156
                    {% trans "Network Utilization" %}
157
                </div>
158
                <div class="network-graph">
159
                    <img src="http://stats.okeanos.grnet.gr/test/net-ts.png" class="stats" />
160
                </div>
161
            </div>
162
        </div>
163
    </div>
164
    <div class="column3" style="display:none;">
165
        <div class="controls">
166
            <div class="previous" style="display:block;">
167
                <div class="prev-arrow"></div>
168
                <div class="prev-label">
169
                    {% trans "previous" %}
170
                </div>
171
            </div>
172
            <div class="next" style="display:block;">
173
                <div class="next-arrow"></div>
174
                <div class="next-label">
175
                    {% trans "next" %}
176
                </div>
177
            </div>
178
        </div>
179
        <div class="separator">
180
        </div>
181
        <div class="servers">
182
            <div class="server-name" id="servers-widget-template" style="display:none;">server1</div>
183
        </div>
184
    </div>
185
</div>
186

    
187
<script>
188

189
init_action_indicator_handlers('single');
190

191
//hide the all of the tags contents
192
$("#machinesview-single.single .tags-content").hide();
193

194
// handle connect machine image states
195
$("div.connect-arrow, .single-image").live('mouseenter',
196
    function() {
197
        // ugly check to see if machine is running
198
        if ($(this).parent().find(".terminated-state").length > 0) { return };
199
        set_machine_os_image($(this).parent().parent(), "single", "hover", undefined, 1);
200
    });
201

202
$("div.connect-arrow, .single-image").live('mouseleave',
203
    function() {
204
        if ($(this).parent().find(".terminated-state").length > 0) { return };
205
        set_machine_os_image($(this).parent().parent(), "single", "hover", undefined, 1, "hover");
206
    });
207

208
$("div.connect-arrow, .single-image").live('mousedown',
209
    function() {
210
        if ($(this).parent().find(".terminated-state").length > 0) { return };
211
        set_machine_os_image($(this).parent().parent(), "single", "click", undefined, 1);
212
    });
213

214
$("div.connect-arrow, .single-image").live('mouseup',
215
    function() {
216
        if ($(this).parent().find(".terminated-state").length > 0) { return };
217
        set_machine_os_image($(this).parent().parent(), "single", "click", undefined, 1, "click");
218
    });
219

220
//toggle the component with class tags-content
221
$("#machinesview-single.single div.tags-header").live('click', function() {
222
    if ($(this).find('.toggler').hasClass('up')) {
223
        $(this).find('.toggler').removeClass('up');
224
        $(this).find('.toggler').addClass('down');
225
        $(this).find('.tags-label').removeClass('darker');
226
        $(this).parent().parent().removeClass('light-background');
227
    } else {
228
        $(this).find('.toggler').removeClass('down');
229
        $(this).find('.toggler').addClass('up');
230
        $(this).find('.tags-label').addClass('darker');
231
        $(this).parent().parent().addClass('light-background');
232
    }
233
    $(this).parent().parent().find(".tags-content").slideToggle(600);
234
    return false;
235
});
236

237
// indicate that the requested action was not completed
238
function display_failure(status, serverID, action, responseText) {
239
    $('#machinesview-single.single #'+serverID+ ' .spinner').hide();
240
    $('#machinesview-single.single #'+serverID+ ' .action_error .action').text(action);
241
    $('#machinesview-single.single #'+serverID+ ' .action_error .code').text(status);
242
    $('#machinesview-single.single #'+serverID+ ' .action_error .message').text(responseText);
243
    $('#machinesview-single.single #'+serverID+ ' .action_error').show();
244
}
245

246
// cancel action
247
$("#machinesview-single.single div.confirm_single .no").live('click', function(){
248
    pending_actions = [];
249
    $('#machinesview-single').find('div.single-action').removeClass("selected");
250
    update_confirmations();
251
});
252

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

275
//show error popup box
276
$("#machinesview-single.single div.action_error .details").live('click', function(){
277
    // remove the action from the pending list
278
    ajax_error($(this).parent().children('.code').text(), undefined, $(this).parent().children('.action').text(), $(this).parent().children('.message').text());
279
    $(this).parent().hide();
280
});
281

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

316
// intercept manage metadata click
317
$("#machinesview-single.single a.manage-metadata").live('click', function() {
318
    // get server name and server ID
319
    var serverID = $(this).parent().parent().parent().parent().parent().attr("id");
320
    var serverName = $(this).closest('.machine-container').find("div.machine-details div.name").text();
321
    if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf($(this).parent().parent().parent().parent().parent().find(".status").text()) < 0) {
322
        $("#metadata-wizard div#on-off").text('on');
323
    } else {
324
        $("#metadata-wizard div#on-off").text('off');
325
    }
326
    // set server name to all related metadata dialogs
327
    $("#metadata-wizard div.machine-name").text(serverName);
328
    // set server id to all related metadata dialogs
329
    $("#metadata-wizard p").text(serverID);
330
    show_metadata_wizard();
331
    return false;
332
});
333

334
// intercept start click
335
$("#machinesview-single.single div.action-start").live('click', function(){
336
    var serverID = $(this).closest(".single-container").attr("id");
337
    var serverName = $(this).closest("div.upper").find(".machine-details div.name").text();
338
    $('#machinesview-single').find('div.single-action').removeClass('selected');
339
    $(this).addClass('selected');
340
    $(this).parent().parent().find('.action_error').hide();
341
    // reset pending actions so not to allow multiple actions in this view
342
    pending_actions = [];
343
    pending_actions.push([start, serverID, serverName]);
344
    update_confirmations();
345
    return false;
346
});
347

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

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

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

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

404
// open console on connect arrow click
405
$("#machinesview-single.single div.connect-arrow").live('click', function(){
406
    $(this).parent().parent().find("div.action-console").click();
407
    return false;
408
});
409

410
// connect to machine on connect arrow border click
411
$("#machinesview-single.single div.connect-border").live('click', function(){
412
    var serverID = $(this).closest(".single-container").attr("id");
413
    machine_connect([machine_connect, serverID]);
414
    return false;
415
});
416

417
// update the servers list
418
function update_machines_view(data){
419
    /*
420
    Go through the servers in the input data. Update existing entries, add
421
    new ones to the list
422
    */
423

424
    $.each(data.servers.values, function(i,server){
425

426
        existing = $('#machinesview-single.single #' + server.id);
427
        existing_link = $('#machinesview-single div.column3 #link-' + server.id);
428
        var current_Id = current_serverId();
429

430
        // if multiple machines exist in the DOM, delete all but one
431
        // defensive coding - that shouldn't happen normally
432
        while (existing.length > 1){
433
            existing.remove();
434
        }
435
        // get server OS, if it exists
436
        if (!(server.metadata == undefined)) {
437
            var server_image = os_icon(server.metadata);
438
        } else {
439
            var server_image = "unknown"
440
        }
441
        // get server status message, if it exists
442
        var current_message = existing.find(".state-label").text();
443

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

524
        } else if (server.status != 'DELETED') {
525
            // If it does not exist and it's not deleted, we should create it
526
            var serverwidget = $("#servers-widget-template").clone().attr("id", 'link-' + server.id);
527
            if (server.name.length > 18) {
528
                serverwidget.text(server.name.substring(0,15) + '...');
529
            } else {
530
                serverwidget.text(server.name)
531
            }
532
            serverwidget.appendTo('.servers');
533
            serverwidget.show();
534
            //find and hide the previously selected server
535
            $('.single').find('.single-container').hide();
536
            $('.single .column3').find('.column3-selected').removeClass('column3-selected');
537
            //create and select the new one
538
            var machine = $("#machinesview-single.single #machine-container-template").clone().attr("id", server.id);
539
            machine.find(".scrollable").scrollable({vertical: true});
540
            machine.find(".machine-details div.name").text(server.name.substring(0,30));
541
            set_machine_os_image(machine, "single", "on", server_image);
542
            machine.find("span.imagetag").text(server_image);
543
            machine.find(".column1 .state-label").text(STATUSES[server.status]);
544
            // find and display flavor parameters
545
            var flavor_params = get_flavor_params(server.flavorRef);
546
            machine.find(".machine-details div.cpus").text(flavor_params['cpus']);
547
            machine.find(".machine-details div.ram").text(flavor_params['ram']);
548
            machine.find(".machine-details div.disk").text(flavor_params['disk']);
549
            // find and display image parameters
550
            var image_params = get_image_params(server.imageRef);
551
            machine.find(".machine-details div.image-name").text(image_params['name'].substring(0,15));
552
            machine.find(".machine-details div.image-size").text(image_params['size']);
553
            // find and display ips
554
            var ips = get_public_ips(server);
555
            machine.find(".machine-details div.ipv4").text(ips['ip4']);
556
            machine.find(".machine-details div.ipv6").text(ips['ip6']);
557
            //show off image if server is not active
558
            if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf(server.status) < 0){
559
                    set_machine_os_image(machine, "single", "off", server_image);
560
                    machine.find(".connect-border").hide();
561
                    machine.find(".connect-arrow").hide();
562
                    machine.find(".column1 .state").removeClass().addClass("state terminated-state");
563
            }
564
            //show spinner while machine is building or rebooting
565
            if (server.status == 'BUILD' ||
566
                [TRANSITIONS['Starting'], TRANSITIONS['Shutting down']].indexOf(existing.find(".status").text()) >= 0 ) {
567
                machine.find(".column1 .state .spinner").show();
568
                machine.find(".connect-border").hide();
569
                machine.find(".connect-arrow").hide();
570
                machine.find(".column1 .state").removeClass().addClass('state build-state');
571
            }
572
            if (server.status == 'REBOOT') {
573
                machine.find(".column1 .state").find('.spinner').show();
574
                machine.find(".connect-border").hide();
575
                machine.find(".connect-arrow").hide();
576
                machine.find(".column1 .state").removeClass().addClass('state rebooting-state');
577
            }
578
            machine.appendTo("#machinesview-single.single");
579
            //disable reboot and shutdown actions while machine is building
580
            if (server.status == 'BUILD') {
581
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
582
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
583
            }
584
            // show console action only on active servers
585
            if (server.status == 'ACTIVE') {
586
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').show();
587
                $('#machinesview-single.single div.#' + server.id + ' div.action-start').hide();
588
                machine.find(".connect-border").show();
589
                machine.find(".connect-arrow").show();
590
            } else if (server.status == 'REBOOT'){
591
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
592
            } else {
593
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
594
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
595
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
596
            }
597
            //show the first machine and select it in the widget
598
            $('.single-container:eq(1)').show();
599
            $('.single .column3').find('.server-name:eq(1)').addClass('column3-selected');
600
        }
601
        update_iconview_actions(server.id, server.status);
602
        if (!(server.metadata == undefined)) {
603
                list_metadata_keys(server.id, server.metadata.values);
604
        }
605
    });
606

607
    // hide pane spinner
608
    $("#machinesview-single.single > div.large-spinner").hide();
609

610
    // show message in case user has no server!
611
    if ($('#machinesview-single div.single-container').length == 1) {
612
        showWelcome();
613
    } else {
614
        hideWelcome();
615
        $('.single .column3').show();
616
    }
617

618
    //enable widget links
619
    $(".server-name").live('click', function() {
620
        $('.single').find('.single-container').hide()
621
        $('.single').find('#' + $(this).attr('id').substring(5)).show();
622
        $('.single .column3').find('.column3-selected').removeClass('column3-selected');
623
        $(this).addClass('column3-selected');
624
        update_prev_next()
625
    });
626

627
    if ($.cookie('server')) {
628
        $('div#link-' + $.cookie('server')).click();
629
        $.cookie('server', null);
630
    }
631

632
    //if it is the last vm, disable the next button
633
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
634
        $("#machinesview-single.single .column3 .next").addClass('disabled');
635
    }
636

637
    //if it is the first vm, disable the prev button
638
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
639
        $("#machinesview-single.single .column3 .previous").addClass('disabled');
640
    }
641
}
642

643
//get currently displayed serverId
644
function current_serverId() {
645
    return $("#machinesview-single.single").find("div.single-container:visible").attr("id");
646
}
647

648
//enable prev-next buttons
649
$("#machinesview-single.single .column3 .previous").live('click', function() {
650
    // set behavior
651
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
652
        return false;
653
    } else {
654
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
655
        $('#machinesview-single.single').find('#' + current_server).hide();
656
        $('#machinesview-single.single').find('#' + current_server).prev().show();
657
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
658
        $('#machinesview-single.single .column3').find('#link-' + current_server).prev().addClass('column3-selected');
659
        update_prev_next()
660
        return false;
661
    }
662
});
663

664
$("#machinesview-single.single .column3 .next").live('click', function() {
665
    // set behavior
666
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
667
        return false;
668
        } else {
669
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
670
        $('#machinesview-single.single').find('#' + current_server).hide();
671
        $('#machinesview-single.single').find('#' + current_server).next().show();
672
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
673
        $('#machinesview-single.single .column3').find('#link-' + current_server).next().addClass('column3-selected');
674
        update_prev_next()
675
        return false;
676
    }
677
});
678

679

680
//enables-disables previous/next buttons accordingly
681
function update_prev_next() {
682
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
683
        $(".single .column3 .previous").removeClass('disabled');
684
    } else {
685
        //disable class
686
        $(".single .column3 .previous").addClass('disabled');
687
    }
688
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
689
        $(".single .column3 .next").removeClass('disabled');
690
    } else {
691
        //disable class
692
        $(".single .column3 .next").addClass('disabled');
693
    }
694
}
695

696
// basic functions executed on page load
697
if ( flavors.length == 0 && images.length == 0 ) {
698
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
699
    update_flavors();
700
    // populate image list
701
    update_images();
702
} else if ( flavors.length == 0 && images.length != 0 ) {
703
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
704
    update_flavors();
705
} else if ( flavors.length != 0 && images.length == 0 ) {
706
    // populate image list
707
    update_images();
708
    update_vms(UPDATE_INTERVAL);
709
} else {
710
    // start updating vm list
711
    update_vms(UPDATE_INTERVAL);
712
}
713

714
//IE specific fixes
715
if ($.browser.msie) {
716
    //IE fix for green arrow hover
717
    $("div.connect-arrow").live("mouseenter", function () {
718
        $(this).addClass("connect-arrow-ie");
719
    });
720
    $("div.connect-arrow").live("mouseleave", function () {
721
        $(this).removeClass("connect-arrow-ie");
722
    });
723
    //IE fix for details button
724
    $("button.details").live("mouseenter", function () {
725
        $(this).css("background-color","#FF7F2A");
726
    });
727
    $("button.details").live("mouseleave", function () {
728
        $(this).css("background-color","transparent");
729
    });
730
}
731

    
732
</script>