Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ b39f68e6

History | View | Annotate | Download (33.8 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'></div>
45
                <div class='connect-arrow'></div>
46
                <img src="static/icons/machines/large/ubuntu-on.png" 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
                    <img class="spinner" style="display:none" src="static/icons/indicators/medium/progress.gif" />
56
                    <img class="wave" style="display:none" src="static/icons/indicators/medium/wave.gif" />
57
                </div>
58
            </div>
59
            <div class="column2">
60
                <div class="machine-labels">
61
                    <div class="machine-label name">{% trans "Name" %}:</div>
62
                    <div class="machine-label cpus">{% trans "CPUs" %}:</div>
63
                    <div class="machine-label ram">{% trans "RAM (MB)" %}:</div>
64
                    <div class="machine-label disk">{% trans "System Disk (GB)" %}:</div>
65
                    <div class="machine-label image-name">{% trans "Image Name" %}:</div>
66
                    <div class="machine-label image-size">{% trans "Image Size (GB)" %}:</div>
67
                    <div class="machine-label ipv4">{% trans "Public IPv4" %}:</div>
68
                    <div class="machine-label ipv6">{% trans "Public IPv6" %}:</div>
69
                </div>
70
                <div class="machine-details">
71
                    <div class="machine-detail name">My Desktop</div>
72
                    <div class="machine-detail cpus">4</div>
73
                    <div class="machine-detail ram">2048</div>
74
                    <div class="machine-detail disk">100</div>
75
                    <div class="machine-detail image-name">windos_XP_blah_blah</div>
76
                    <div class="machine-detail image-size">2.3</div>
77
                    <div class="machine-detail ipv4">no ipv4</div>
78
                    <div class="machine-detail ipv6">2001:db8:1f70::999:de8:7648:6e8</div>
79
                </div>
80
                <div class="tags">
81
                    <div class="tags-header">
82
                        <div class="tags-label">{% trans "Tags" %}</div>
83
                        <div class="toggler down"></div>
84
                    </div>
85
                    <div class="tags-content">
86
                        <div class="metadata-keys-container">
87
                            <div class="scrollable vertical">
88
                                <div class="items">
89
                                </div>
90
                            </div>
91
                            <div class="metadata-actions">
92
                                <div class="prev"></div>
93
                                <div class="next"></div>
94
                            </div>
95
                        </div>
96
                        <a href="#" class="manage-metadata">{% trans "Manage Tags" %}</a>
97
                    </div>
98
                </div>
99
            </div>
100
            <div class="single-actions">
101
                <div class="action-container start">
102
                    <div class="single-action action-start">{% trans "Start" %}</div>
103
                    <div class="confirm_single">
104
                        <button class="yes">{% trans "Confirm" %}</button>
105
                        <button class="no">X</button>
106
                    </div>
107
                </div>
108
                <div class="action-container reboot">
109
                    <div class="single-action action-reboot">{% trans "Reboot" %}</div>
110
                    <div class="confirm_single">
111
                        <button class="yes">{% trans "Confirm" %}</button>
112
                        <button class="no">X</button>
113
                    </div>
114
                </div>
115
                <div class="action-container shutdown">
116
                    <div class="single-action action-shutdown">{% trans "Shutdown" %}</div>
117
                    <div class="confirm_single">
118
                        <button class="yes">{% trans "Confirm" %}</button>
119
                        <button class="no">X</button>
120
                    </div>
121
                </div>
122
                <div class="action-container console">
123
                    <div class="single-action action-console">{% trans "Console" %}</div>
124
                    <div class="confirm_single">
125
                        <button class="yes">{% trans "Confirm" %}</button>
126
                        <button class="no">X</button>
127
                    </div>
128
                </div>
129
                <div class="action-container destroy">
130
                    <div class="single-action action-destroy">{% trans "Destroy" %}</div>
131
                    <div class="confirm_single">
132
                        <button class="yes">{% trans "Confirm" %}</button>
133
                        <button class="no">X</button>
134
                    </div>
135
                </div>
136
            </div>
137
            <div class="action_error" align="center">
138
                {% trans "<span>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
139
                <span class="code"></span>
140
                <span class="message"></span>
141
                <button class="details">{% trans "Details" %}</button>
142
            </div>
143
        </div>
144
        <div class="lower">
145
            <div class="single-cpu">
146
                <div class="cpu-usage">
147
                    {% trans "CPU Usage" %}
148
                </div>
149
                <div class="cpu-graph">
150

    
151
                </div>
152
            </div>
153
            <div class="single-network">
154
                <div class="network-usage">
155
                    {% trans "Network Usage" %}
156
                </div>
157
                <div class="network-graph">
158

    
159
                </div>
160
            </div>
161
        </div>
162
    </div>
163
    <div class="column3" style="display:none;">
164
        <div class="controls">
165
            <div class="previous" style="display:block;">
166
                <div class="prev-arrow"></div>
167
                <div class="prev-label">
168
                    {% trans "previous" %}
169
                </div>
170
            </div>
171
            <div class="next" style="display:block;">
172
                <div class="next-arrow"></div>
173
                <div class="next-label">
174
                    {% trans "next" %}
175
                </div>
176
            </div>
177
        </div>
178
        <div class="separator">
179
        </div>
180
        <div class="servers">
181
            <div class="server-name" id="servers-widget-template" style="display:none;">server1</div>
182
        </div>
183
    </div>
184
</div>
185

    
186
<script>
187

188
//hide the all of the tags contents
189
$("#machinesview-single.single .tags-content").hide();
190

191
//toggle the component with class tags-content
192
$("#machinesview-single.single div.tags-header").live('click', function() {
193
    if ($(this).find('.toggler').hasClass('up')) {
194
        $(this).find('.toggler').removeClass('up');
195
        $(this).find('.toggler').addClass('down');
196
        $(this).find('.tags-label').removeClass('darker');
197
        $(this).parent().parent().removeClass('light-background');
198
    } else {
199
        $(this).find('.toggler').removeClass('down');
200
        $(this).find('.toggler').addClass('up');
201
        $(this).find('.tags-label').addClass('darker');
202
        $(this).parent().parent().addClass('light-background');
203
    }
204
    $(this).parent().parent().find(".tags-content").slideToggle(600);
205
    return false;
206
});
207

208
// indicate that the requested action was not completed
209
function display_failure(status, serverID, action, responseText) {
210
    $('#machinesview-single.single #'+serverID+ ' .spinner').hide();
211
    $('#machinesview-single.single #'+serverID+ ' .action_error .action').text(action);
212
    $('#machinesview-single.single #'+serverID+ ' .action_error .code').text(status);
213
    $('#machinesview-single.single #'+serverID+ ' .action_error .message').text(responseText);
214
    $('#machinesview-single.single #'+serverID+ ' .action_error').show();
215
}
216

217
// cancel action
218
$("#machinesview-single.single div.confirm_single .no").live('click', function(){
219
    pending_actions = [];
220
    $('#machinesview-single').find('div.single-action').removeClass("selected");
221
    update_confirmations();
222
});
223

224
// update metadata list
225
function list_metadata_keys(serverID, keys) {
226
    // empty the list if it already exists
227
    $("#machinesview-single.single div.#" +serverID).find("div.items").empty();
228
    //start counter
229
    var i=0;
230
    // show values
231
    for (var key in keys) {
232
        $("#machinesview-single.single div.#" +serverID).find(".items").append("<div class='item'>" + key + "</div>");
233
        i++;
234
    }
235
    //hide the metadata controls if we have less than 3 metadata
236
    if (i <= 3) {
237
        $("#machinesview-single.single div.#" +serverID).find(".metadata-actions").hide();
238
    }
239
    //show the metadata controls if we have more than 3 metadata
240
    if (i > 3) {
241
        $("#machinesview-single.single div.#" +serverID).find(".metadata-actions").show();
242
    }
243
    $("#machinesview-single.single div.#" +serverID).find(".metadata-count").text(i);
244
}
245

246
//show error popup box
247
$("#machinesview-single.single div.action_error .details").live('click', function(){
248
    // remove the action from the pending list
249
    ajax_error($(this).parent().children('.code').text(), undefined, $(this).parent().children('.action').text(), $(this).parent().children('.message').text());
250
    $(this).parent().hide();
251
});
252

253
//confirm action
254
$("#machinesview-single.single div.confirm_single .yes").live('click', function(){
255
    var serverID = $(this).closest(".single-container").attr("id");
256
    for (i=0;i<pending_actions.length;i++){ // if there is a pending action for this server execute it
257
        if (pending_actions[i][1]==serverID){
258
            action = pending_actions.splice(i,1)[0]; // extract action
259
            // change the status text in cases where no api state exists
260
            if (action[0] == start) {
261
                $(this).closest(".single-container").find(".column1 .state-label").text(TRANSITIONS['Starting']);
262
                $(this).closest(".single-container").find(".column1 .state").removeClass().addClass('state starting-state');
263
                $(this).closest(".single-container").find(".column1 .state .spinner").show();
264
            } else if (action[0] == shutdown) {
265
                $(this).closest(".single-container").find(".column1 .state-label").text(TRANSITIONS['Shutting down']);
266
                $(this).closest(".single-container").find(".column1 .state").removeClass().addClass('state shutting-state');
267
                $(this).closest(".single-container").find(".column1 .state .spinner").show();
268
            } else if (action[0] == reboot) {
269
                $(this).closest(".single-container").find(".column1 .state-label").text(TRANSITIONS['Rebooting']);
270
                $(this).closest(".single-container").find(".column1 .state").removeClass().addClass('state rebooting-state');
271
                $(this).closest(".single-container").find(".column1 .state .spinner").show();
272
            }  else if (action[0] == destroy) {
273
                $(this).closest(".single-container").find(".column1 .state-label").text(TRANSITIONS['Destroying']);
274
                $(this).closest(".single-container").find(".column1 .state").removeClass().addClass('state destroying-state');
275
                $(this).closest(".single-container").find(".column1 .state .spinner").show();
276
            }
277
            action[0]([action[1]]); // execute action
278
        }
279
    }
280
    $(this).parent().hide();
281
    $(this).closest('div.action-container').children('div.single-action').removeClass('selected');
282
    $(this).parent().parent().find('.state').children('.spinner').show();
283
    update_confirmations();
284
    return false;
285
});
286

287
// intercept manage metadata click
288
$("#machinesview-single.single a.manage-metadata").live('click', function() {
289
    // get server name and server ID
290
    var serverID = $(this).parent().parent().parent().parent().parent().attr("id");
291
    var serverName = $(this).closest('.machine-container').find("div.machine-details div.name").text();
292
    if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf($(this).parent().parent().parent().parent().parent().find(".status").text()) < 0) {
293
        $("#metadata-wizard div#on-off").text('on');
294
    } else {
295
        $("#metadata-wizard div#on-off").text('off');
296
    }
297
    // set server name to all related metadata dialogs
298
    $("#metadata-wizard div.machine-name").text(serverName);
299
    // set server id to all related metadata dialogs
300
    $("#metadata-wizard p").text(serverID);
301
    show_metadata_wizard();
302
    return false;
303
});
304

305
// intercept start click
306
$("#machinesview-single.single div.action-start").live('click', function(){
307
    var serverID = $(this).closest(".single-container").attr("id");
308
    var serverName = $(this).closest("div.upper").find(".machine-details div.name").text();
309
    $('#machinesview-single').find('div.single-action').removeClass('selected');
310
    $(this).addClass('selected');
311
    $(this).parent().parent().find('.action_error').hide();
312
    // reset pending actions so not to allow multiple actions in this view
313
    pending_actions = [];
314
    pending_actions.push([start, serverID, serverName]);
315
    update_confirmations();
316
    return false;
317
});
318

319
// intercept shutdown click
320
$("#machinesview-single.single div.action-shutdown").live('click', function(){
321
    var serverID = $(this).closest(".single-container").attr("id");
322
    var serverName = $(this).closest("div.upper").find(".machine-details div.name").text();
323
    $('#machinesview-single').find('div.single-action').removeClass('selected');
324
    $(this).addClass('selected');
325
    $(this).parent().parent().find('.action_error').hide();
326
    // reset pending actions so not to allow multiple actions in this view
327
    pending_actions = [];
328
    pending_actions.push([shutdown, serverID, serverName]);
329
    update_confirmations();
330
    return false;
331
});
332

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

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

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

375
// open console on connect arrow click
376
$("#machinesview-single.single div.connect-arrow").live('click', function(){
377
    $(this).parent().parent().find("div.action-console").click();
378
    return false;
379
});
380

381
// open console on connect arrow border click
382
$("#machinesview-single.single div.connect-border").live('click', function(){
383
    $(this).parent().parent().find("div.action-console").click();
384
    return false;
385
});
386

387
// update the servers list
388
function update_machines_view(data){
389
    /*
390
    Go through the servers in the input data. Update existing entries, add
391
    new ones to the list
392
    */
393

394
    $.each(data.servers.values, function(i,server){
395

396
        existing = $('#machinesview-single.single #' + server.id);
397
        existing_link = $('#machinesview-single div.column3 #link-' + server.id);
398
        var current_Id = current_serverId();
399

400
        // if multiple machines exist in the DOM, delete all but one
401
        // defensive coding - that shouldn't happen normally
402
        while (existing.length > 1){
403
            existing.remove();
404
        }
405
        // get server OS, if it exists
406
        if (!(server.metadata == undefined)) {
407
            var server_image = os_icon(server.metadata);
408
        } else {
409
            var server_image = "unknown"
410
        }
411
        // get server status message, if it exists
412
        var current_message = existing.find(".state-label").text();
413

414
        // server already exists in DOM
415
        if (existing.length){
416
            $("#machinesview-single.single div.single-container:last-child").find("div.separator").show();
417
            //  if the status is deleted, delete it from the DOM
418
            if (server.status == 'DELETED') {
419
                existing.remove();
420
                existing_link.remove();
421
                //if the deleted vm is the displayed one, display the 1st vm
422
                if (server.id == current_Id) {
423
                    $("#machinesview-single.single div.single-container:eq(1)").show()
424
                    $('#machinesview-single.single .column3').find('.server-name:eq(1)').addClass('column3-selected');
425
                }
426
                try {
427
                    console.info(existing.find(".machine-details div.name").text() + ' removed');
428
                } catch(err) {}
429
            }
430
            // if the status has changed
431
            else if ( current_message != STATUSES[server.status]) {
432
                /*
433
                Here there are 4 possibilities:
434
                    1. From an active state to an inactive one
435
                    2. From an inactive state to an active one
436
                    3. From an active state to a different active one
437
                    4. From an inactive state to a different inactive one
438
                The last two (3, 4) can be dealt with the same way
439
                */
440
                if (ACTIVE_STATES.indexOf(current_message) >= 0 &&
441
                    INACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
442
                    // from an active state to an inactive one
443
                    log_server_status_change(existing, server.status);
444
                    existing.find("img.single-image").attr("src","static/icons/machines/large/" + server_image + '-off.png');
445
                    existing.find(".column1 .state-label").text(STATUSES[server.status]);
446
                    existing.find(".connect-border").hide();
447
                    existing.find(".connect-arrow").hide();
448
                    existing.find(".column1 .state .spinner").hide();
449
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
450
                    existing.find(".column1 .state").removeClass().addClass("state terminated-state");
451
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
452
                }
453
                else if (INACTIVE_STATES.indexOf(current_message) >= 0 &&
454
                         ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
455
                    // From an inactive state to an active one
456
                    log_server_status_change(existing, server.status);
457
                    existing.find("img.single-image").attr("src","static/icons/machines/large/" + server_image + '-on.png');
458
                    existing.find(".column1 .state-label").text(STATUSES[server.status]);
459
                    existing.find(".connect-border").show();
460
                    existing.find(".connect-arrow").show();
461
                    existing.find(".column1 .state .spinner").hide();
462
                    existing.find(' .wave').attr('src','static/icons/indicators/medium/wave.gif').show();
463
                    existing.find(".column1 .state").removeClass().addClass("state running-state");
464
                    setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
465
                }
466
                else {
467
                    // handling active to active or inactive to inactive changes
468
                    if (TRANSITIONS[current_message] && TRANSITIONS[current_message] != 'Rebooting') {
469
                        // don't do anything if it is still in transition
470
                    }
471
                    else if ((TRANSITIONS[current_message] == 'Rebooting' && server.status == 'ACTIVE') ||
472
                             (STATUSES['BUILD'] == current_message && server.status == 'ACTIVE')) {
473
                        // if it has been rebooted or just created
474
                        log_server_status_change(existing, server.status);
475
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
476
                        existing.find(".connect-border").show();
477
                        existing.find(".connect-arrow").show();
478
                        existing.find(".column1 .state .spinner").hide();
479
                        existing.find(".column1 .state").attr('src','static/icons/indicators/medium/wave.gif').show();
480
                        existing.find(".column1 .state").removeClass().addClass("state running-state");
481
                        setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
482
                    }
483
                    else {
484
                        // in any other case just change the status and ignore spinners/waves
485
                        existing.find(".column1 .state-label").text(STATUSES[server.status]);
486
                    }
487
                }
488
            }
489
            // find and display ips
490
            var ips = get_public_ips(server);
491
            existing.find(".machine-details div.ipv4").text(ips['ip4']);
492
            existing.find(".machine-details div.ipv6").text(ips['ip6']);
493

494
        } else if (server.status != 'DELETED') {
495
            // If it does not exist and it's not deleted, we should create it
496
            var serverwidget = $("#servers-widget-template").clone().attr("id", 'link-' + server.id);
497
            if (server.name.length > 18) {
498
                serverwidget.text(server.name.substring(0,15) + '...');
499
            } else {
500
                serverwidget.text(server.name)
501
            }
502
            serverwidget.appendTo('.servers');
503
            serverwidget.show();
504
            //find and hide the previously selected server
505
            $('.single').find('.single-container').hide();
506
            $('.single .column3').find('.column3-selected').removeClass('column3-selected');
507
            //create and select the new one
508
            var machine = $("#machinesview-single.single #machine-container-template").clone().attr("id", server.id);
509
            machine.find(".scrollable").scrollable({vertical: true});
510
            machine.find(".machine-details div.name").text(server.name.substring(0,40));
511
            machine.find("img.single-image").attr("src","static/icons/machines/large/"+server_image+'-on.png');
512
            machine.find("span.imagetag").text(server_image);
513
            machine.find(".column1 .state-label").text(STATUSES[server.status]);
514
            // find and display flavor parameters
515
            var flavor_params = get_flavor_params(server.flavorRef);
516
            machine.find(".machine-details div.cpus").text(flavor_params['cpus']);
517
            machine.find(".machine-details div.ram").text(flavor_params['ram']);
518
            machine.find(".machine-details div.disk").text(flavor_params['disk']);
519
            // find and display image parameters
520
            var image_params = get_image_params(server.imageRef);
521
            machine.find(".machine-details div.image-name").text(image_params['name'].substring(0,15));
522
            machine.find(".machine-details div.image-size").text(image_params['size']);
523
            // find and display ips
524
            var ips = get_public_ips(server);
525
            machine.find(".machine-details div.ipv4").text(ips['ip4']);
526
            machine.find(".machine-details div.ipv6").text(ips['ip6']);
527
            //show off image if server is not active
528
            if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf(server.status) < 0){
529
                    machine.find("img.single-image").attr("src","static/icons/machines/large/"+server_image+'-off.png');
530
                    machine.find(".connect-border").hide();
531
                    machine.find(".connect-arrow").hide();
532
                    machine.find(".column1 .state").removeClass().addClass("state terminated-state");
533
            }
534
            //show spinner while machine is building or rebooting
535
            if (server.status == 'BUILD' ||
536
                [TRANSITIONS['Starting'], TRANSITIONS['Shutting down']].indexOf(existing.find(".status").text()) >= 0 ) {
537
                machine.find(".column1 .state .spinner").show();
538
                machine.find(".connect-border").hide();
539
                machine.find(".connect-arrow").hide();
540
                machine.find(".column1 .state").removeClass().addClass('state build-state');
541
            }
542
            if (server.status == 'REBOOT') {
543
                machine.find(".column1 .state").find('.spinner').show();
544
                machine.find(".connect-border").hide();
545
                machine.find(".connect-arrow").hide();
546
                machine.find(".column1 .state").removeClass().addClass('state rebooting-state');
547
            }
548
            machine.appendTo("#machinesview-single.single");
549
            //disable reboot and shutdown actions while machine is building
550
            if (server.status == 'BUILD') {
551
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
552
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
553
            }
554
            // show console action only on active servers
555
            if (server.status == 'ACTIVE') {
556
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').show();
557
                $('#machinesview-single.single div.#' + server.id + ' div.action-start').hide();
558
                machine.find(".connect-border").show();
559
                machine.find(".connect-arrow").show();
560
            } else if (server.status == 'REBOOT'){
561
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
562
            } else {
563
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
564
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
565
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
566
            }
567
            //show the first machine and select it in the widget
568
            $('.single-container:eq(1)').show();
569
            $('.single .column3').find('.server-name:eq(1)').addClass('column3-selected');
570
        }
571
        update_iconview_actions(server.id, server.status);
572
        if (!(server.metadata == undefined)) {
573
                list_metadata_keys(server.id, server.metadata.values);
574
        }
575
    });
576

577
    // hide pane spinner
578
    $("#machinesview-single.single > div.large-spinner").hide();
579

580
    // show message in case user has no server!
581
    if ($('#machinesview-single div.single-container').length == 1) {
582
        showWelcome();
583
    } else {
584
        hideWelcome();
585
        $('.single .column3').show();
586
    }
587

588
    //enable widget links
589
    $(".server-name").live('click', function() {
590
        $('.single').find('.single-container').hide()
591
        $('.single').find('#' + $(this).attr('id').substring(5)).show();
592
        $('.single .column3').find('.column3-selected').removeClass('column3-selected');
593
        $(this).addClass('column3-selected');
594
        update_prev_next()
595
    });
596

597
    if ($.cookie('server')) {
598
        $('div#link-' + $.cookie('server')).click();
599
        $.cookie('server', null);
600
    }
601

602
    //if it is the last vm, disable the next button
603
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
604
        $("#machinesview-single.single .column3 .next").addClass('disabled');
605
    }
606

607
    //if it is the first vm, disable the prev button
608
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
609
        $("#machinesview-single.single .column3 .previous").addClass('disabled');
610
    }
611
}
612

613
//get currently displayed serverId
614
function current_serverId() {
615
    return $("#machinesview-single.single").find("div.single-container:visible").attr("id");
616
}
617

618
//enable prev-next buttons
619
$("#machinesview-single.single .column3 .previous").live('click', function() {
620
    // set behavior
621
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
622
        return false;
623
    } else {
624
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
625
        $('#machinesview-single.single').find('#' + current_server).hide();
626
        $('#machinesview-single.single').find('#' + current_server).prev().show();
627
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
628
        $('#machinesview-single.single .column3').find('#link-' + current_server).prev().addClass('column3-selected');
629
        update_prev_next()
630
        return false;
631
    }
632
});
633

634
$("#machinesview-single.single .column3 .next").live('click', function() {
635
    // set behavior
636
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
637
        return false;
638
        } else {
639
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
640
        $('#machinesview-single.single').find('#' + current_server).hide();
641
        $('#machinesview-single.single').find('#' + current_server).next().show();
642
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
643
        $('#machinesview-single.single .column3').find('#link-' + current_server).next().addClass('column3-selected');
644
        update_prev_next()
645
        return false;
646
    }
647
});
648

649

650
//enables-disables previous/next buttons accordingly
651
function update_prev_next() {
652
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
653
        $(".single .column3 .previous").removeClass('disabled');
654
    } else {
655
        //disable class
656
        $(".single .column3 .previous").addClass('disabled');
657
    }
658
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
659
        $(".single .column3 .next").removeClass('disabled');
660
    } else {
661
        //disable class
662
        $(".single .column3 .next").addClass('disabled');
663
    }
664
}
665

666
// basic functions executed on page load
667
if ( flavors.length == 0 && images.length == 0 ) {
668
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
669
    update_flavors();
670
    // populate image list
671
    update_images();
672
} else if ( flavors.length == 0 && images.length != 0 ) {
673
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
674
    update_flavors();
675
} else if ( flavors.length != 0 && images.length == 0 ) {
676
    // populate image list
677
    update_images();
678
    update_vms(UPDATE_INTERVAL);
679
} else {
680
    // start updating vm list
681
    update_vms(UPDATE_INTERVAL);
682
}
683

684
//IE specific fixes
685
if ($.browser.msie) {
686
    //IE fix for green arrow hover
687
    $("div.connect-arrow").live("mouseenter", function () {
688
        $(this).addClass("connect-arrow-ie");
689
    });
690
    $("div.connect-arrow").live("mouseleave", function () {
691
        $(this).removeClass("connect-arrow-ie");
692
    });
693
}
694

    
695
</script>