Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines_single.html @ a70fb308

History | View | Annotate | Download (21 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

153
    $.each(data.servers.values, function(i,server){
154

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

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

163
        // if multiple machines exist in the DOM, delete all but one
164
        // defensive coding - that shouldn't happen normally
165
        while (existing.length > 1){
166
            existing.remove();
167
        }
168
        // get server OS, if it exists
169
        if (!(server.metadata == undefined)) {
170
            var server_image = os_icon(server.metadata);
171
        } else {
172
            var server_image = "unknown"
173
        }
174
        // get server status message, if it exists
175
        var current_message = existing.find(".state-label").text();
176

177
        // server already exists in DOM
178
        if (existing.length){
179
            $("#machinesview-single.single div.single-container:last-child").find("div.separator").show();
180
            //  if the status is deleted, delete it from the DOM
181
            if (server.status == 'DELETED') {
182
                existing.remove();
183
                existing_link.remove();
184
                try {
185
                    console.info(existing.find("div.name span.name").text() + ' removed');
186
                } catch(err) {}
187
            }
188
            // if the status has changed
189
            else if ( current_message != STATUSES[server.status]) {
190
                /*
191
                Here there are 4 possibilities:
192
                    1. From an active state to an inactive one
193
                    2. From an inactive state to an active one
194
                    3. From an active state to a different active one
195
                    4. From an inactive state to a different inactive one
196
                The last two (3, 4) can be dealt with the same way
197
                */
198
                if (ACTIVE_STATES.indexOf(current_message) >= 0 &&
199
                    INACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
200
                    // from an active state to an inactive one
201
                    log_server_status_change(existing, server.status);
202
                    existing.find("img.single-image").attr("src","static/icons/machines/large/" + server_image + '-off.png');
203
                    existing.find(".state-label").text(STATUSES[server.status]);
204
                }
205
                else if (INACTIVE_STATES.indexOf(current_message) >= 0 &&
206
                         ACTIVE_STATES.indexOf(STATUSES[server.status]) >= 0) {
207
                    // From an inactive state to an active one
208
                    log_server_status_change(existing, server.status);
209
                    existing.find("img.single-image").attr("src","static/icons/machines/large/" + server_image + '-on.png');
210
                    existing.find(".state-label").text(STATUSES[server.status]);
211
                }
212
                else {
213
                    // handling active to active or inactive to inactive changes
214
                    if (TRANSITIONS[current_message] && TRANSITIONS[current_message] != 'Rebooting') {
215
                        // don't do anything if it is still in transition
216
                    }
217
                    else if ((TRANSITIONS[current_message] == 'Rebooting' && server.status == 'ACTIVE') ||
218
                             (STATUSES['BUILD'] == current_message && server.status == 'ACTIVE')) {
219
                        // if it has been rebooted or just created
220
                        log_server_status_change(existing, server.status);
221
                        existing.find(".state-label").text(STATUSES[server.status]);
222
                    }
223
                    else {
224
                        // in any other case just change the status and ignore spinners/waves
225
                        existing.find(".state-label").text(STATUSES[server.status]);
226
                    }
227
                }
228
            }
229
            // find and display ips
230
            var ips = get_public_ips(server);
231
            existing.find(".machine-details div.ipv4").text(ips['ip4']);
232
            existing.find(".machine-details div.ipv6").text(ips['ip6']);
233

234
        } else if (server.status != 'DELETED') {
235
            // If it does not exist and it's not deleted, we should create it
236
            var serverwidget = $("#servers-widget-template").clone().attr("id", 'link-' + server.id);
237
            if (server.name.length > 18) {
238
                serverwidget.text(server.name.substring(0,15) + '...');
239
            } else {
240
                serverwidget.text(server.name)
241
            }
242
            serverwidget.appendTo('.servers');
243
            serverwidget.show();
244
            //find and hide the previous selected server
245
            $('.single').find('.single-container').hide();
246
            $('.single .column3').find('.selected').removeClass('selected');
247
            //create and select the new one
248
            var machine = $("#machinesview-single.single #machine-container-template").clone().attr("id", server.id);
249
            machine.find(".machine-details div.name").text(server.name.substring(0,100));
250
            machine.find("img.single-image").attr("src","static/icons/machines/large/"+server_image+'-on.png');
251
            machine.find("span.imagetag").text(server_image);
252
            machine.find(".state-label").text(STATUSES[server.status]);
253
            // find and display ips
254
            var ips = get_public_ips(server);
255
            machine.find(".machine-details div.ipv4").text(ips['ip4']);
256
            machine.find(".machine-details div.ipv6").text(ips['ip6']);
257
            // find and display flavor parameters
258
            var CPUs, RAM, disk, image_name, image_size;
259
            if ( flavors.length > 0 ) {
260
                var current_flavor = '';
261
                for (i=0; i<flavors.length; i++) {
262
                    if (flavors[i]['id'] == server.flavorRef) {
263
                        current_flavor = flavors[i];
264
                    }
265
                }
266
                CPUs = current_flavor['cpu'];
267
                RAM = current_flavor['ram'];
268
                disk = current_flavor['disk'];
269
            } else {
270
                CPUs = 0;
271
                RAM = 0;
272
                disk = 0;
273
            }
274
            if ( images.length > 0 ) {
275
                var current_image = '';
276
                for (i=0; i<images.length; i++) {
277
                    if (images[i]['id'] == server.imageRef) {
278
                        current_image = images[i];
279
                    }
280
                }
281
                image_name = current_image['name'];
282
                image_size = current_image['metadata']['values']['size'];
283
            } else {
284
                image_name = ''
285
                image_size = ''
286
            }
287
            machine.find(".machine-details div.cpus").text(CPUs);
288
            machine.find(".machine-details div.ram").text(RAM);
289
            machine.find(".machine-details div.disk").text(disk);
290
            machine.find(".machine-details div.image-name").text(image_name.substring(0,15));
291
            machine.find(".machine-details div.image-size").text(image_size);
292
            //show off image if server is not active
293
            if (['BUILD', 'ACTIVE', 'REBOOT'].indexOf(server.status) < 0){
294
                    machine.find("img.single-image").attr("src","static/icons/machines/large/"+server_image+'-off.png');
295
            }
296
            //show spinner while machine is building
297
            if (server.status == 'BUILD' ||
298
                [TRANSITIONS['Starting'], TRANSITIONS['Shutting down']].indexOf(existing.find(".status").text()) >= 0 ) {
299
                machine.find('.spinner').show();
300
            }
301
            machine.appendTo("#machinesview-single.single");
302
            //disable reboot and shutdown actions while machine is building
303
            if (server.status == 'BUILD') {
304
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
305
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
306
            }
307
            // show console action only on active servers
308
            if (server.status == 'ACTIVE') {
309
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').show();
310
                $('#machinesview-single.single div.#' + server.id + ' div.action-start').hide();
311
            } else if (server.status == 'REBOOT'){
312
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
313
            } else {
314
                $('#machinesview-single.single div.#' + server.id + ' div.action-console').hide();
315
                $('#machinesview-single.single div.#' + server.id + ' div.action-reboot').hide();
316
                $('#machinesview-single.single div.#' + server.id + ' div.action-shutdown').hide();
317
            }
318
            //show the first machine and select it in the widget
319
            $('.single-container:eq(1)').show();
320
            $('.single .column3').find('.server-name:eq(1)').addClass('selected');
321
        }
322
    });
323

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

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

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

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

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

383
    if ($.cookie('server')) {
384
        $('div#link-' + $.cookie('server')).click();
385
        $.cookie('server', null);
386
    }
387

388
    //if it is the last vm, hide the next button
389
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:last").attr("id")) {
390
        $("#machinesview-single.single .column3 .next").hide()
391
    } else {
392
        $("#machinesview-single.single .column3 .next").show()
393
    }
394

395
    //if it is the first vm, hide the prev button
396
    if ($("#machinesview-single.single .column3 .selected").attr("id") == $("#machinesview-single.single .column3 .server-name:eq(1)").attr("id")) {
397
        $("#machinesview-single.single .column3 .previous").hide()
398
    } else {
399
        $("#machinesview-single.single .column3 .previous").show()
400
    }
401

402
}
403

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

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

440
//hide prev button on startup
441
$("#machinesview-single.single .column3 .previous").hide()
442

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

461
//FIXME: Hide and show welcome depending on number of machines
462
hideWelcome();
463
</script>