Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ a5bc3755

History | View | Annotate | Download (22.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="column1">
43
            <img src="static/icons/machines/large/ubuntu-on.png" class="single-image" />
44
            <div class="state">
45
                <span class="state-label">{% trans "Running" %}</span>
46
            </div>
47
            <div class="single-actions">
48
                <div class="single-action action-start">{% trans "Start" %}</a></div>
49
                <div class="single-action action-console">{% trans "Console" %}</a></div>
50
                <div class="single-action action-reboot">{% trans "Reboot" %}</a></div>
51
                <div class="single-action action-shutdown">{% trans "Shutdown" %}</a></div>
52
                <div class="single-action action-destroy">{% trans "Destroy" %}</a></div>
53
            </div>
54
        </div>
55
        <div class="column2">
56
            <div class="machine-labels">
57
                <div class="machine-label name">{% trans "Name" %}:</div>
58
                <div class="machine-label cpus">{% trans "CPUs" %}:</div>
59
                <div class="machine-label ram">{% trans "RAM (MB)" %}:</div>
60
                <div class="machine-label disk">{% trans "System Disk (GB)" %}:</div>
61
                <div class="machine-label image-name">{% trans "Image Name" %}:</div>
62
                <div class="machine-label image-size">{% trans "Image Size (GB)" %}:</div>
63
                <div class="machine-label ipv4">{% trans "Public IPv4" %}:</div>
64
                <div class="machine-label ipv6">{% trans "Public IPv6" %}:</div>
65
                <div class="machine-label groups">{% trans "Groups" %}:</div>
66
            </div>
67
            <div class="machine-details">
68
                <div class="machine-detail name">My Desktop</div>
69
                <div class="machine-detail cpus">4</div>
70
                <div class="machine-detail ram">2048</div>
71
                <div class="machine-detail disk">100</div>
72
                <div class="machine-detail image-name">windos_XP_blah_blah</div>
73
                <div class="machine-detail image-size">2.3</div>
74
                <div class="machine-detail ipv4">no ipv4</div>
75
                <div class="machine-detail ipv6">2001:db8:1f70::999:de8:7648:6e8</div>
76
                <div class="machine-detail groups">
77
                    <div class="machine-detail group">group</div>
78
                </div>
79
            </div>
80
        </div>
81
        <div class="disks">
82
            {% trans "disks" %}<span class="toggler">&#710;</span>
83
        </div>
84
        <div class="disks-content">
85

    
86
        </div>
87
        <div class="networks">
88
            {% trans "networks" %}<span class="toggler">&#710;</span>
89
        </div>
90
        <div class="networks-content">
91

    
92
        </div>
93
        <div class="stats">
94
            {% trans "stats" %}<span class="toggler">&#710;</span>
95
        </div>
96
        <div class="stats-content">
97

    
98
        </div>
99
    </div>
100
    <div class="column3">
101
        <div class="controls">
102
            <div class="previous">
103
                &lt;{% trans "previous" %}
104
            </div>
105
            <div class="next">
106
                {% trans "next" %}&gt;
107
            </div>
108
        </div>
109
        <div class="separator">
110
        </div>
111
        <div class="servers">
112
            <div class="server-name" id="servers-widget-template" style="display:none;">server1</div>
113
        </div>
114
    </div>
115
</div>
116

    
117
<script>
118

119
//hide the all of the info contents
120
$("#machinesview-single.single .disks-content").hide();
121
$("#machinesview-single.single .networks-content").hide();
122
$("#machinesview-single.single .stats-content").hide();
123

124
// intercept start click
125
$("#machinesview-single.single div.action-start").live('click', function(){
126
    var serverID = $(this).parent().parent().parent().attr("id");
127
    var serverName = $(this).parent().parent().parent().find(".machine-details div.name").text();
128
    var found = false;
129
    $(this).parent().children('a').removeClass('selected');
130
    $(this).addClass('selected');
131
    $(this).parent().addClass('display')
132
    $(this).parent().parent().find('.action_error').hide();
133

134
    for (i=0;i<pending_actions.length;i++){ // if there is already a pending action for this server replace it
135
        if (pending_actions[i][1]==serverID){
136
            pending_actions[i][0] = start;
137
            found = true
138
        }
139
    }
140
    if (!found) // no pending action for this server was found, so let's just add it to the list
141
        pending_actions.push([start, serverID, serverName])
142
    update_confirmations()
143
    return false;
144
});
145

146
// update the servers list
147
function update_machines_view(data){
148
    /*
149
    Go through the servers in the input data. Update existing entries, add
150
    new ones to the list
151
    */
152
    $.each(data.servers.values, function(i,server){
153

154
        existing = $('#machinesview-single.single #' + server.id);
155
        existing_link = $('#machinesview-single div.column3 #link-' + server.id);
156

157
        //hide next button if there is only one vm
158
        if (data.servers.values.length == 1) {
159
            $("#machinesview-single.single .column3 .next").hide();
160
        }
161

162
        // if multiple machines exist in the DOM, delete all but one
163
        // defensive coding - that shouldn't happen normally
164
        while (existing.length > 1){
165
            existing.remove();
166
        }
167

168
        var server_image = os_icon(server.metadata);
169

170
        // server already exists in DOM
171
        if (existing.length){
172
            $("#machinesview-single.single div.single-container:last-child").find("div.separator").show();
173
            //  if the status is deleted, delete it from the DOM
174
            if (server.status == 'DELETED') {
175
                existing.remove();
176
                existing_link.remove();
177
                try {
178
                    console.info(existing.find("div.name span.name").text() + ' removed');
179
                } catch(err) {}
180
            } else if (existing.find(".status").text() != STATUSES[server.status]) {
181
                try { // firebug console logging
182
                    console.info(existing.find("div.name span.name").text() + ' from '
183
                                + existing.find(".status").text() + ' to ' + STATUSES[server.status]);
184
                } catch(err) {}
185
                // show console action only on active servers, else hide it
186
                if (server.status == 'ACTIVE') {
187
                    $('#machinesview-single.single div.#' + server.id + ' div.action-console').show();
188
                } else {
189
                    $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
190
                }
191
                // show reboot and shutdown actions on active of rebooting servers
192
                if (server.status == 'ACTIVE' || server.status == 'REBOOT') {
193
                    $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').show();
194
                    $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').show();
195
                    $('#machinesview-single.single div.#' + server.id + ' div.action-destroy').show();
196
                }
197
                if (['BUILD','ACTIVE','REBOOT'].indexOf(server.status) >= 0 &&
198
                    [STATUSES['STOPPED'], STATUSES['ERROR'],
199
                     TRANSITIONS['Starting']].indexOf(existing.find(".status").text()) >= 0) {
200
                    // from stopped, on error or starting to building, active or rebooting
201
                    // starting is not an api state, it means the vm is stopped or on error
202
                    existing.find("img.single-image").attr("src","static/icons/machines/large/" + server_image + '-on.png');
203
                    existing.find(".state-label").text(STATUSES[server.status]);
204
                } else if (['STOPPED','ERROR'].indexOf(server.status) >= 0 &&
205
                           [STATUSES['ACTIVE'], STATUSES['BUILD'], STATUSES['REBOOT'],
206
                            TRANSITIONS['Shutting down'], TRANSITIONS['Starting']].indexOf(existing.find(".status").text()) >= 0) {
207
                    // from active, building, rebooting, or shutting down to stopped or on error
208
                    // shutting down is not an api state, it means the server is active
209
                    existing.find("img.single-image").attr("src","static/icons/machines/large/" + server_image + '-off.png');
210
                    existing.find(".state-label").text(STATUSES[server.status]);
211
                } else if (['BUILD','ACTIVE','REBOOT'].indexOf(server.status) >= 0 &&
212
                            [STATUSES['ACTIVE'], STATUSES['BUILD'],
213
                             STATUSES['REBOOT']].indexOf(existing.find(".status").text()) >= 0) {
214
                    // the server changes status
215
                    existing.find(".state-label").text(STATUSES[server.status]);
216
                } else if (['STOPPED','ERROR'].indexOf(server.status) >= 0 &&
217
                    [STATUSES['STOPPED'],
218
                     STATUSES['ERROR']].indexOf(existing.find(".status").text()) >= 0) {
219
                    // the server changes status
220
                    existing.find(".state-label").text(STATUSES[server.status]);
221
                }
222
                existing.find('.spinner').hide();
223
                existing.find(' .wave').attr('src','static/wave.gif').show();
224
                setTimeout("$('#" + server.id +" .wave').attr('src','').hide()", 3000);
225
                // show spinner while the server is rebooting, starting or shutting down
226
                if ([STATUSES['REBOOT'],
227
                    TRANSITIONS['Starting'], TRANSITIONS['Shutting down']].indexOf(existing.find(".status").text()) >= 0 ) {
228
                    existing.find(' .wave').hide();
229
                    existing.find('.spinner').show();
230
                }
231
            } else if (existing.find(".status").text() == STATUSES['REBOOT'] && server.status == 'REBOOT') {
232
                    $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
233
            }
234
            // find and display ips
235
            var ips = get_public_ips(server);
236
            existing.find(".machine-details div.ipv4").text(ips['ip4']);
237
            existing.find(".machine-details div.ipv6").text(ips['ip6']);
238
        } else if (server.status != 'DELETED') {
239
            // If it does not exist and it's not deleted, we should create it
240
            var serverwidget = $("#servers-widget-template").clone().attr("id", 'link-' + server.id);
241
            if (server.name.length > 18) {
242
                serverwidget.text(server.name.substring(0,15) + '...');
243
            } else {
244
                serverwidget.text(server.name)
245
            }
246
            serverwidget.appendTo('.servers');
247
            serverwidget.show();
248
            //find and hide the previous selected server
249
            $('.single').find('.single-container').hide();
250
            $('.single .column3').find('.selected').removeClass('selected');
251
            //create and select the new one
252
            var machine = $("#machinesview-single.single #machine-container-template").clone().attr("id", server.id);
253
            machine.find(".machine-details div.name").text(server.name.substring(0,100));
254
            machine.find("img.single-image").attr("src","static/icons/machines/large/"+server_image+'-on.png');
255
            machine.find("span.imagetag").text(server_image);
256
            machine.find(".state-label").text(STATUSES[server.status]);
257
            // find and display ips
258
            var ips = get_public_ips(server);
259
            machine.find(".machine-details div.ipv4").text(ips['ip4']);
260
            machine.find(".machine-details div.ipv6").text(ips['ip6']);
261
            // find and display flavor parameters
262
            var CPUs, RAM, disk, image_name, image_size;
263
            if ( flavors.length > 0 ) {
264
                var current_flavor = '';
265
                for (i=0; i<flavors.length; i++) {
266
                    if (flavors[i]['id'] == server.flavorRef) {
267
                        current_flavor = flavors[i];
268
                    }
269
                }
270
                CPUs = current_flavor['cpu'];
271
                RAM = current_flavor['ram'];
272
                disk = current_flavor['disk'];
273
            } else {
274
                CPUs = 0;
275
                RAM = 0;
276
                disk = 0;
277
            }
278
            if ( images.length > 0 ) {
279
                var current_image = '';
280
                for (i=0; i<images.length; i++) {
281
                    if (images[i]['id'] == server.imageRef) {
282
                        current_image = images[i];
283
                    }
284
                }
285
                image_name = current_image['name'];
286
                image_size = current_image['metadata']['values']['size'];
287
            } else {
288
                image_name = ''
289
                image_size = ''
290
            }
291
            machine.find(".machine-details div.cpus").text(CPUs);
292
            machine.find(".machine-details div.ram").text(RAM);
293
            machine.find(".machine-details div.disk").text(disk);
294
            machine.find(".machine-details div.image-name").text(image_name.substring(0,15));
295
            machine.find(".machine-details div.image-size").text(image_size);
296
            //show off image if server is not active
297
            if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf(server.status) < 0){
298
                    machine.find("img.single-image").attr("src","static/icons/machines/large/"+server_image+'-off.png');
299
            }
300
            //show spinner while machine is building
301
            if (server.status == 'BUILD' ||
302
                [TRANSITIONS['Starting'], TRANSITIONS['Shutting down']].indexOf(existing.find(".status").text()) >= 0 ) {
303
                machine.find('.spinner').show();
304
            }
305
            machine.appendTo("#machinesview-single.single");
306
            //disable reboot and shutdown actions while machine is building
307
            if (server.status == 'BUILD') {
308
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
309
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
310
            }
311
            // show console action only on active servers
312
            if (server.status == 'ACTIVE') {
313
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').show();
314
                $('#machinesview-single.single div.#' + server.id + ' div.action-start').hide();
315
            } else if (server.status == 'REBOOT'){
316
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
317
            } else {
318
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
319
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
320
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
321
            }
322
        }
323
    });
324

325
    $("#machinesview-single.single > div.large-spinner").hide();
326

327
    // show message in case user has no servers!
328
    //if ($('.single-container').length < 2) {
329
    //    showWelcome();
330
    //} else {
331
    //    hideWelcome();
332
    //}
333

334
    // set confirm box position
335
    if (window.innerHeight - 220 < $('#machinesview-single').height())
336
        $('.confirm_multiple').addClass('fixed');
337
    else
338
        $('.confirm_multiple').removeClass('fixed');
339

340
    //show the first machine and select it in the widget
341
    $('.single-container:eq(1)').show();
342
    $('.single .column3').find('.server-name:eq(1)').addClass('selected');
343

344
    //enable widget links
345
    $(".server-name").live('click', function() {
346
        $('.single').find('.single-container').hide()
347
        $('.single').find('#' + $(this).attr('id').substring(5)).show();
348
        $('.single .column3').find('.selected').removeClass('selected');
349
        $(this).addClass('selected');
350
        $(".single .column3 .previous").show();
351
        $(".single .column3 .next").show();
352
        if ($(this).attr("id") == $(".single .column3 .server-name:eq(1)").attr("id")) {
353
            $(".single .column3 .previous").hide();
354
        } else if ($(this).attr("id") == $(".single .column3 .server-name:last").attr("id")) {
355
            $(".single .column3 .next").hide();
356
        }
357
    });
358

359
    //toggle content
360
    $("div.disks").toggle(function() {
361
            $(this).find('.toggler').html("&#711;");
362
            $(this).next(".disks-content").slideToggle(600);
363
            return false;
364
        }, function() {
365
            $(this).find('.toggler').html('&#710;');
366
            $(this).next(".disks-content").slideToggle(600);
367
            return false;
368
    });
369
    $("div.networks").toggle(function() {
370
            $(this).find('.toggler').html("&#711;");
371
            $(this).next(".networks-content").slideToggle(600);
372
            return false;
373
        }, function() {
374
            $(this).find('.toggler').html('&#710;');
375
            $(this).next(".networks-content").slideToggle(600);
376
            return false;
377
    });
378
    $("div.stats").toggle(function() {
379
            $(this).find('.toggler').html("&#711;");
380
            $(this).next(".stats-content").slideToggle(600);
381
            return false;
382
        }, function() {
383
            $(this).find('.toggler').html('&#710;');
384
            $(this).next(".stats-content").slideToggle(600);
385
            return false;
386
    });
387

388
    if ($.cookie('server')) {
389
        $('div#link-' + $.cookie('server')).click();
390
        $.cookie('server', null);
391
    }
392

393
    //if it is the last vm, hide the next button
394
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
395
        $("#machinesview-single.single .column3 .next").hide()
396
    } else {
397
        $("#machinesview-single.single .column3 .next").show()
398
    }
399

400
    //if it is the first vm, hide the prev button
401
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
402
        $("#machinesview-single.single .column3 .previous").hide()
403
    } else {
404
        $("#machinesview-single.single .column3 .previous").show()
405
    }
406

407
}
408

409
//enable prev-next buttons
410
$("#machinesview-single.single .column3 .previous").live('click', function(){
411
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
412
        return false;
413
    } else {
414
        current_server = $('#machinesview-single.single .column3').find('.selected').attr("id").substring(5);
415
        $('#machinesview-single.single').find('#' + current_server).hide();
416
        $('#machinesview-single.single').find('#' + current_server).prev().show();
417
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('selected');
418
        $('#machinesview-single.single .column3').find('#link-' + current_server).prev().addClass('selected');
419
        if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
420
            $(this).hide()
421
        }
422
        $("#machinesview-single.single .column3 .next").show()
423
    }
424
});
425

426
$("#machinesview-single.single .column3 .next").live('click', function(){
427
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
428
        return false;
429
        } else {
430
        current_server = $('#machinesview-single.single .column3').find('.selected').attr("id").substring(5);
431
        $('#machinesview-single.single').find('#' + current_server).hide();
432
        $('#machinesview-single.single').find('#' + current_server).next().show();
433
        $('#machinesview-single.single .column3').find('#link-' + current_server).removeClass('selected');
434
        $('#machinesview-single.single .column3').find('#link-' + current_server).next().addClass('selected');
435
        //if it is the last vm, hide the next button
436
        if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
437
            $(this).hide()
438
        }
439
        $("#machinesview-single.single .column3 .previous").show();
440
    }
441
});
442

443
//hide prev button on startup
444
$("#machinesview-single.single .column3 .previous").hide()
445

446
// basic functions executed on page load
447
if ( flavors.length == 0 && images.length == 0 ) {
448
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
449
    update_flavors();
450
    // populate image list
451
    update_images();
452
} else if ( flavors.length == 0 && images.length != 0 ) {
453
    // configure flavors, this also calls update_vms(UPDATE_INTERVAL)
454
    update_flavors();
455
} else if ( flavors.length != 0 && images.length == 0 ) {
456
    // populate image list
457
    update_images();
458
    update_vms(UPDATE_INTERVAL);
459
} else {
460
    // start updating vm list
461
    update_vms(UPDATE_INTERVAL);
462
}
463

464
//FIXME: Hide and show welcome depending on number of machines
465
hideWelcome();
466
</script>