Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ 6dd01959

History | View | Annotate | Download (37.9 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 (MB)" %}:</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 ipv4-text">no ipv4</div>
79
                    <div class="machine-detail ipv6 ipv6-text">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="./static/icons/indicators/small/progress.gif" 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="./static/icons/indicators/small/progress.gif" 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(".connect-arrow:visible").length == 0) { return };
199
        set_machine_os_image($(this).parent().parent(), "single", "hover", undefined, 1);
200
        var parent = $(this).parent().parent();
201
        parent.find(".connect-arrow").show().addClass('border-hover');
202
    });
203

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

213
$("div.connect-arrow, .single-image").live('mousedown',
214
    function() {
215
        if ($(this).parent().find(".connect-arrow:visible").length == 0) { return };
216
        set_machine_os_image($(this).parent().parent(), "single", "click", undefined, 1);
217
    });
218

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

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

242
// indicate that the requested action was not completed
243
function display_failure(status, serverID, action, responseText) {
244
    $('#machinesview-single.single #'+serverID+ ' .spinner').hide();
245
    $('#machinesview-single.single #'+serverID+ ' .action_error .action').text(action);
246
    $('#machinesview-single.single #'+serverID+ ' .action_error .code').text(status);
247
    $('#machinesview-single.single #'+serverID+ ' .action_error .message').text(responseText);
248
    $('#machinesview-single.single #'+serverID+ ' .action_error').show();
249
}
250

251
// cancel action
252
$("#machinesview-single.single div.confirm_single .no").live('click', function(){
253
    pending_actions = [];
254
    $('#machinesview-single').find('div.single-action').removeClass("selected");
255
    update_confirmations();
256
});
257

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

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

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

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

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

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

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

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

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

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

418
// connect to machine on connect arrow click
419
$("#machinesview-single.single div.connect-arrow").live('click', function(){
420
    var serverID = $(this).closest(".single-container").attr("id");
421
    machine_connect([machine_connect, serverID]);
422
    return false;
423
});
424

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

432
// update the servers list
433
function update_machines_view(data){
434
    /*
435
    Go through the servers in the input data. Update existing entries, add
436
    new ones to the list
437
    */
438

439
    $.each(data.servers.values, function(i,server){
440

441
        existing = $('#machinesview-single.single #' + server.id);
442
        existing_link = $('#machinesview-single div.column3 #link-' + server.id);
443
        var current_Id = current_serverId();
444

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

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

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

619

620
            //show the first machine and select it in the widget
621
            $('.single-container:eq(1)').show();
622
            $('.single .column3').find('.server-name:eq(1)').addClass('column3-selected');
623
        }
624
        update_iconview_actions(server.id, server.status);
625
        if (!(server.metadata == undefined)) {
626
                list_metadata_keys(server.id, server.metadata.values);
627
        }
628
        if (server.id == current_serverId()) {
629
            get_server_stats(server.id);
630
        }
631

632
        // if machine in destroy state keep it that way
633
        var server = get_machine(server.id);
634
        if (server.status == "DESTROY") {
635
            existing = $('#machinesview-single.single #' + server.id);
636
            if (existing.length) {
637
                existing.find(".column1 .state-label").text(TRANSITIONS['Destroying']);
638
                existing.find(".column1 .state").removeClass().addClass('state destroying-state');
639
                existing.find(".column1 .state .spinner").show();
640
                existing.find(".column1 .wave").hide();
641
            }
642
        }
643
    });
644

645
    update_transition_names();
646
    fix_v6_addresses();
647
    // hide pane spinner
648
    $("#machinesview-single.single > div.large-spinner").hide();
649

650
    // show message in case user has no server!
651
    if ($('#machinesview-single div.single-container').length == 1) {
652
        showWelcome();
653
    } else {
654
        hideWelcome();
655
        $('.single .column3').show();
656
    }
657

658
    //enable widget links
659
    $(".server-name").live('click', function() {
660
        $('.single').find('.single-container').hide()
661
        $('.single').find('#' + $(this).attr('id').substring(5)).show();
662
        $('.single .column3').find('.column3-selected').removeClass('column3-selected');
663
        $(this).addClass('column3-selected');
664
        update_prev_next()
665
    });
666

667
    if ($.cookie('server')) {
668
        $('div#link-' + $.cookie('server')).click();
669
        $.cookie('server', null);
670
    }
671

672
    //if it is the last vm, disable the next button
673
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
674
        $("#machinesview-single.single .column3 .next").addClass('disabled');
675
    }
676

677
    //if it is the first vm, disable the prev button
678
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
679
        $("#machinesview-single.single .column3 .previous").addClass('disabled');
680
    }
681
}
682

683
// define these to avoid exceptions
684
function display_reboot_success() {
685
}
686

687
function display_reboot_failure() {
688
}
689

690
// append string to transition states
691
function update_transition_names() {
692
    $(".state-label").each(function(index,el){
693
    var tr_text = $(this).text().replace(TRANSITION_STATE_APPEND,"");
694
    if (TRANSITION_STATES.indexOf(tr_text) >= 0) {
695
            $(this).text(tr_text + TRANSITION_STATE_APPEND);
696
        }
697
    })
698
}
699

700
//get currently displayed serverId
701
function current_serverId() {
702
    return $("#machinesview-single.single").find("div.single-container:visible").attr("id");
703
}
704

705
//enable prev-next buttons
706
$("#machinesview-single.single .column3 .previous").live('click', function() {
707
    // set behavior
708
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
709
        return false;
710
    } else {
711
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
712
        $('#machinesview-single.single').find('#' + current_server).hide();
713
        $('#machinesview-single.single').find('#' + current_server).prev().show();
714
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
715
        $('#machinesview-single.single .column3').find('#link-' + current_server).prev().addClass('column3-selected');
716
        update_prev_next()
717
        return false;
718
    }
719
});
720

721
$("#machinesview-single.single .column3 .next").live('click', function() {
722
    // set behavior
723
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
724
        return false;
725
        } else {
726
        current_server = $('#machinesview-single.single .column3').find('.column3-selected').attr("id").substring(5);
727
        $('#machinesview-single.single').find('#' + current_server).hide();
728
        $('#machinesview-single.single').find('#' + current_server).next().show();
729
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('column3-selected');
730
        $('#machinesview-single.single .column3').find('#link-' + current_server).next().addClass('column3-selected');
731
        update_prev_next()
732
        return false;
733
    }
734
});
735

736

737
//enables-disables previous/next buttons accordingly
738
function update_prev_next() {
739
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
740
        $(".single .column3 .previous").removeClass('disabled');
741
    } else {
742
        //disable class
743
        $(".single .column3 .previous").addClass('disabled');
744
    }
745
    if ($("#machinesview-single.single .column3 .column3-selected").attr("id") != $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
746
        $(".single .column3 .next").removeClass('disabled');
747
    } else {
748
        //disable class
749
        $(".single .column3 .next").addClass('disabled');
750
    }
751
    get_server_stats(current_serverId());
752
}
753

754
// basic functions executed on page load
755
if ( flavors.length == 0 && images.length == 0 ) {
756
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
757
    update_flavors();
758
    // populate image list
759
    update_images();
760
} else if ( flavors.length == 0 && images.length != 0 ) {
761
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
762
    update_flavors();
763
} else if ( flavors.length != 0 && images.length == 0 ) {
764
    // populate image list
765
    update_images();
766
    update_vms(UPDATE_INTERVAL);
767
} else {
768
    // start updating vm list
769
    update_vms(UPDATE_INTERVAL);
770
}
771

772
//IE specific fixes
773
if ($.browser.msie) {
774
    //IE fix for green arrow hover
775
    $("div.connect-arrow").live("mouseenter", function () {
776
        $(this).addClass("connect-arrow-ie");
777
    });
778
    $("div.connect-arrow").live("mouseleave", function () {
779
        $(this).removeClass("connect-arrow-ie");
780
    });
781
    //IE fix for details button
782
    $("button.details").live("mouseenter", function () {
783
        $(this).css("background-color","#FF7F2A");
784
    });
785
    $("button.details").live("mouseleave", function () {
786
        $(this).css("background-color","transparent");
787
    });
788
}
789

    
790
</script>