Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ 55e4b353

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

624

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

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

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

660
        // update progress
661
        if (server.status == 'BUILD' && existing.length > 0) {
662
            var progress_details = get_progress_details(server.id);
663
            existing.find("span.build-progress").show().text(progress_details.msg);
664
        } else {
665
            existing.find("span.build-progress").hide();
666
        }
667

668
    });
669

670
    update_transition_names();
671
    fix_v6_addresses();
672
    // hide pane spinner
673
    $("#machinesview-single.single > div.large-spinner").hide();
674

675
    // show message in case user has no server!
676
    if ($('#machinesview-single div.single-container').length == 1) {
677
        showWelcome();
678
    } else {
679
        hideWelcome();
680
        $('.single .column3').show();
681
    }
682

683
    //enable widget links
684
    $(".server-name").live('click', function() {
685
        $('.single').find('.single-container').hide()
686
        $('.single').find('#' + $(this).attr('id').substring(5)).show();
687
        $('.single .column3').find('.column3-selected').removeClass('column3-selected');
688
        $(this).addClass('column3-selected');
689
        update_prev_next()
690
    });
691

692
    if ($.cookie('server')) {
693
        $('div#link-' + $.cookie('server')).click();
694
        $.cookie('server', null);
695
    }
696

697
    //if it is the last vm, disable the next button
698
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
699
        $("#machinesview-single.single .column3 .next").addClass('disabled');
700
    }
701

702
    //if it is the first vm, disable the prev button
703
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
704
        $("#machinesview-single.single .column3 .previous").addClass('disabled');
705
    }
706
}
707

708
// define these to avoid exceptions
709
function display_reboot_success() {
710
}
711

712
function display_reboot_failure() {
713
}
714

715
// append string to transition states
716
function update_transition_names() {
717
    $(".state-label").each(function(index,el){
718
    var tr_text = $(this).text().replace(TRANSITION_STATE_APPEND,"");
719
    if (TRANSITION_STATES.indexOf(tr_text) >= 0) {
720
            $(this).text(tr_text + TRANSITION_STATE_APPEND);
721
        }
722
    })
723
}
724

725
//get currently displayed serverId
726
function current_serverId() {
727
    return $("#machinesview-single.single").find("div.single-container:visible").attr("id");
728
}
729

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

746
$("#machinesview-single.single .column3 .next").live('click', function() {
747
    // set behavior
748
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
749
        return false;
750
        } else {
751
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
752
        $('#machinesview-single.single').find('#' + current_server).hide();
753
        $('#machinesview-single.single').find('#' + current_server).next().show();
754
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
755
        $('#machinesview-single.single .column3').find('#link-' + current_server).next().addClass('column3-selected');
756
        update_prev_next()
757
        return false;
758
    }
759
});
760

761

762
//enables-disables previous/next buttons accordingly
763
function update_prev_next() {
764
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
765
        $(".single .column3 .previous").removeClass('disabled');
766
    } else {
767
        //disable class
768
        $(".single .column3 .previous").addClass('disabled');
769
    }
770
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
771
        $(".single .column3 .next").removeClass('disabled');
772
    } else {
773
        //disable class
774
        $(".single .column3 .next").addClass('disabled');
775
    }
776
    get_server_stats(current_serverId());
777
}
778

779
// basic functions executed on page load
780
if ( flavors.length == 0 && images.length == 0 ) {
781
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
782
    update_flavors();
783
    // populate image list
784
    update_images();
785
} else if ( flavors.length == 0 && images.length != 0 ) {
786
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
787
    update_flavors();
788
} else if ( flavors.length != 0 && images.length == 0 ) {
789
    // populate image list
790
    update_images();
791
    update_vms(UPDATE_INTERVAL);
792
} else {
793
    // start updating vm list
794
    update_vms(UPDATE_INTERVAL);
795
}
796

797
//IE specific fixes
798
if ($.browser.msie) {
799
    //IE fix for green arrow hover
800
    $("div.connect-arrow").live("mouseenter", function () {
801
        $(this).addClass("connect-arrow-ie");
802
    });
803
    $("div.connect-arrow").live("mouseleave", function () {
804
        $(this).removeClass("connect-arrow-ie");
805
    });
806
    //IE fix for details button
807
    $("button.details").live("mouseenter", function () {
808
        $(this).css("background-color","#FF7F2A");
809
    });
810
    $("button.details").live("mouseleave", function () {
811
        $(this).css("background-color","transparent");
812
    });
813
}
814

    
815
</script>