Statistics
| Branch: | Tag: | Revision:

root / ui / static / synnefo.js @ d19719cd

History | View | Annotate | Download (13.7 kB)

1
var flavors = [], images = [], servers = [], disks = [], cpus = [], ram = [];
2

    
3
function list_view() {
4
    $.cookie("list", '1'); // set list cookie
5
    $("div#machinesview").load($("#list").attr("href"), function(){
6
        $("a#standard")[0].className += ' activelink';
7
        $("a#list")[0].className = '';
8
    });
9
    return false;
10
}
11

    
12
function standard_view() {
13
    $.cookie("list", '0');
14
    href=$("a#standard").attr("href");
15
    $("div#machinesview").load(href, function(){
16
        $("a#list")[0].className += ' activelink';
17
        $("a#standard")[0].className = '';
18
    });
19
    return false;
20
}
21

    
22
function choose_view() {
23
    if ($.cookie("list")=='1') {
24
        list_view();
25
    } else {
26
        standard_view();
27
    }
28
}
29

    
30
function toggleMenu() {
31
    var primary = $("ul.css-tabs li a.primary");
32
    var secondary = $("ul.css-tabs li a.secondary");
33
    var all = $("ul.css-tabs li a");                        
34
    var toggled = $('ul.css-tabs li a.current').hasClass('secondary');
35
    
36
    // if anything is still moving, do nothing
37
    if ($(":animated").length) {
38
        return;
39
    } 
40
    
41
    // nothing is current to begin with
42
    $('ul.css-tabs li a.current').removeClass('current');
43
    
44
    // move stuff around
45
    all.animate({top:'30px'}, {complete: function() { 
46
        $(this).hide();
47
        if (toggled) {
48
            primary.show();
49
            primary.animate({top:'9px'}, {complete: function() {
50
                $('ul.css-tabs li a.primary#machines').addClass('current');
51
                $('a#machines').click();                                   
52
            }});
53
        } else {
54
            secondary.show();
55
            secondary.animate({top:'9px'}, {complete: function() {
56
                $('ul.css-tabs li a.secondary#files').addClass('current');
57
                $('a#files').click();                                                                           
58
            }});
59
        }                                              
60
    }});
61
    
62
    // rotate arrow icon
63
    if (toggled) {
64
        $("#arrow").rotate({animateAngle: (0), bind:[{"click":function(){toggleMenu()}}]});
65
        $("#arrow").rotateAnimation(0);                    
66
    } else {
67
        $("#arrow").rotate({animateAngle: (-180), bind:[{"click":function(){toggleMenu()}}]});
68
        $("#arrow").rotateAnimation(-180);
69
    }            
70
}
71

    
72
// confirmation overlay generation
73
function confirm_action(action_string, action_function, serverIDs, serverNames) {
74
    if (serverIDs.length == 1){
75
        $("#yes-no h3").text('You are about to ' + action_string + ' vm ' + serverNames[0]);
76
    } else if (serverIDs.length > 1){
77
        $("#yes-no h3").text('You are about to ' + action_string + ' ' + serverIDs.length + ' machines');
78
    } else {
79
        return false;
80
    }
81
    // action confirmation overlay
82
    var triggers = $("a#confirmation").overlay({
83
            // some mask tweaks suitable for modal dialogs
84
            mask: {
85
                    color: '#ebecff',
86
                    opacity: '0.9'
87
            },
88
        top: 'center',
89
        load: false
90
    });
91
    // yes or no?
92
    var buttons = $("#yes-no button").click(function(e) {
93
            // get user input
94
            var yes = buttons.index(this) === 0;
95
        //close the confirmation window
96
        $("a#confirmation").overlay().close(); 
97
        // return true=yes or false=no
98
        if (yes) {
99
            action_function(serverIDs);
100
        }
101
    });
102
    $("a#confirmation").data('overlay').load();
103
    return false;
104
}
105

    
106
var changes_since = '';
107
// get and show a list of running and terminated machines
108
function update_vms(interval) {
109
    try{ console.info('updating machines'); } catch(err){}
110

    
111
    $.ajax({
112
        url: '/api/v1.0/servers/detail?changes_since=' + changes_since,
113
        type: "GET",
114
        timeout: TIMEOUT,
115
        dataType: "json",
116
        error: function(jqXHR, textStatus, errorThrown) {
117
                                        // don't forget to try again later
118
                                        if (interval) { 
119
                                                setTimeout(update_vms,interval,interval);
120
                                        }
121
                                        // as for now, just show an error message
122
                    if (jqXHR.status != undefined) {
123
                                                ajax_error(jqXHR.status);
124
                                        } else {
125
                                                ajax_error();
126
                                        }                                
127
                    return false;
128
                    },
129
        success: function(data, textStatus, jqXHR) {
130
            changes_since = '';
131
            try {
132
                                servers = data.servers;
133
                        } catch(err) { ajax_error('400');}
134
                        update_machines_view(data);
135
                        if (interval) {
136
                                setTimeout(update_vms,interval,interval);
137
                        }
138
        }
139
    });
140
    return false;
141
}
142

    
143
// get and show a list of available standard and custom images
144
function update_images() { 
145
    $.ajax({
146
        url: '/api/v1.0/images/detail',
147
        type: "GET",
148
        //async: false,
149
        dataType: "json",
150
        timeout: TIMEOUT,
151
        error: function(jqXHR, textStatus, errorThrown) { 
152
                    ajax_error(jqXHR.status);
153
                    },
154
        success: function(data, textStatus, jqXHR) {
155
            try {
156
                                images = data.images;
157
                        } catch(err){
158
                                ajax_error("NO_IMAGES");
159
                        }
160
            if ($("ul#standard-images li").toArray().length + $("ul#custom-images li").toArray().length == 0) {
161
                $.each(data.images, function(i,image){
162
                    var img = $('#image-template').clone().attr("id","img-"+image.id).fadeIn("slow");
163
                    img.find("label").attr('for',"img-radio-" + image.id);
164
                    img.find(".image-title").text(image.name);
165
                    img.find(".description").text(image.description);
166
                    img.find(".size").text(image.size);
167
                    img.find("input.radio").attr('id',"img-radio-" + image.id);
168
                    if (i==0) img.find("input.radio").attr("checked","checked"); 
169
                    img.find("img.image-logo").attr('src','static/os_logos/'+image_tags[image.id]+'.png');
170
                    if (image.serverId) {
171
                        img.appendTo("ul#custom-images");
172
                    } else {
173
                        img.appendTo("ul#standard-images");
174
                    }
175
                });
176
            }
177
        }
178
    });
179
    return false;
180
}
181

    
182
Array.prototype.unique = function () {
183
        var r = new Array();
184
        o:for(var i = 0, n = this.length; i < n; i++)
185
        {
186
                for(var x = 0, y = r.length; x < y; x++)
187
                {
188
                        if(r[x]==this[i])
189
                        {
190
                                continue o;
191
                        }
192
                }
193
                r[r.length] = this[i];
194
        }
195
        return r;
196
}
197

    
198
// get and configure flavor selection
199
function update_flavors() { 
200
    $.ajax({
201
        url: '/api/v1.0/flavors/detail',
202
        type: "GET",
203
        //async: false,
204
        dataType: "json",
205
        timeout: TIMEOUT,
206
        error: function(jqXHR, textStatus, errorThrown) { 
207
            try {
208
                                ajax_error(jqXHR.status);
209
                        } catch (err) {
210
                                ajax_error(err);
211
                        }
212
        },
213
        success: function(data, textStatus, jqXHR) {
214
            flavors = data.flavors;
215
            $.each(flavors, function(i, flavor) {
216
                cpus[i] = flavor['cpu'];
217
                disks[i] = flavor['disk'];
218
                ram[i] = flavor['ram'];
219
            });
220
            cpus = cpus.unique();
221
            disks = disks.unique();
222
            ram = ram.unique();
223
            // sliders for selecting VM flavor
224
            $("#cpu:range").rangeinput({min:0,
225
                                       value:0,
226
                                       step:1,
227
                                       progress: true,
228
                                       max:cpus.length-1});
229
            
230
            $("#storage:range").rangeinput({min:0,
231
                                       value:0,
232
                                       step:1,
233
                                       progress: true,
234
                                       max:disks.length-1});
235

    
236
            $("#ram:range").rangeinput({min:0,
237
                                       value:0,
238
                                       step:1,
239
                                       progress: true,
240
                                       max:ram.length-1});
241
            $("#small").click();
242
            
243
            // update the indicators when sliding
244
            $("#cpu:range").data().rangeinput.onSlide(function(event,value){
245
                $("#cpu-indicator")[0].value = cpus[Number(value)];
246
            });
247
            $("#cpu:range").data().rangeinput.change(function(event,value){
248
                $("#custom").click();                                
249
                        });                        
250
            $("#ram:range").data().rangeinput.onSlide(function(event,value){
251
                $("#ram-indicator")[0].value = ram[Number(value)];
252
            });
253
            $("#ram:range").data().rangeinput.change(function(event,value){
254
                $("#custom").click();
255
            });                        
256
            $("#storage:range").data().rangeinput.onSlide(function(event,value){
257
                $("#storage-indicator")[0].value = disks[Number(value)];
258
            });
259
            $("#storage:range").data().rangeinput.change(function(event,value){
260
                $("#custom").click();
261
            });                        
262
        }
263
    });
264
    return false;
265
}
266
// return flavorRef from cpu, disk, ram values
267
function identify_flavor(cpu, disk, ram){
268
    for (i=0;i<flavors.length;i++){
269
        if (flavors[i]['cpu'] == cpu && flavors[i]['disk']==disk && flavors[i]['ram']==ram) {
270
            return flavors[i]['id']
271
        }
272
    }
273
    return 0;
274
}
275

    
276
// update the actions in the 
277
function updateActions() {
278
        var states = [];
279
        var on = [];
280
        var checked = $("table.list-machines tbody input[type='checkbox']:checked");
281
        // disable all actions to begin with
282
        for (action in actions) {
283
                $("#action-" + action).removeClass('enabled');
284
        }
285

    
286
        // are there multiple machines selected?
287
        if (checked.length>1)
288
                states[0] = 'multiple';
289
        
290
        // check the states of selected machines
291
        checked.each(function(i,checkbox) {
292
                states[states.length] = checkbox.className;
293
                var ip = $("#" + checkbox.id.replace('input-','') + ".ip span.public").text();
294
                if (ip.replace('undefined','').length)
295
                        states[states.length] = 'network';
296
        });
297

    
298
        // decide which actions should be enabled
299
        for (a in actions) {
300
                var enabled = false;
301
                for (var s =0; s<states.length; s++) {
302
                        if (actions[a].indexOf(states[s]) != -1 ) {
303
                                enabled = true;
304
                        } else {
305
                                enabled = false;
306
                                break;
307
                        }
308
                }
309
                if (enabled)
310
                        on[on.length]=a;
311
        }
312
        // enable those actions
313
        for (action in on) {
314
                $("#action-" + on[action]).addClass('enabled');
315
        }
316
}
317

    
318
// reboot action
319
function reboot(serverIDs){
320
        if (!serverIDs.length){
321
                ajax_success('DEFAULT');
322
                return false;
323
        }        
324
    // ajax post reboot call
325
    var payload = {
326
        "reboot": {"type" : "HARD"}
327
    };
328
    serverID = serverIDs.pop();
329
        
330
        $.ajax({
331
                url: '/api/v1.0/servers/' + serverID + '/action',
332
                type: "POST",        
333
                dataType: "json",
334
                data: JSON.stringify(payload),
335
                timeout: TIMEOUT,
336
                error: function(jqXHR, textStatus, errorThrown) {
337
                                        ajax_error(jqXHR.status);
338
                                },
339
                success: function(data, textStatus, jqXHR) {
340
                                        if ( jqXHR.status == '202') {
341
                        try {
342
                            console.info('rebooted ' + serverID);
343
                        } catch(err) {}                   
344
                                                reboot(serverIDs);
345
                                        } else {
346
                                                ajax_error(jqXHR.status);
347
                                        }
348
                                }
349
    });
350

    
351
    return false;
352
}
353

    
354
// shutdown action
355
function shutdown(serverIDs) {
356
        if (!serverIDs.length){
357
                ajax_success('DEFAULT');
358
                return false;
359
        }
360
    // ajax post shutdown call
361
    var payload = {
362
        "shutdown": {"timeout" : "5"}
363
    };   
364

    
365
        serverID = serverIDs.pop()
366
    $.ajax({
367
            url: '/api/v1.0/servers/' + serverID + '/action',
368
            type: "POST",
369
            dataType: "json",
370
        data: JSON.stringify(payload),
371
        timeout: TIMEOUT,
372
        error: function(jqXHR, textStatus, errorThrown) { 
373
                    ajax_error(jqXHR.status);
374
                    },
375
        success: function(data, textStatus, jqXHR) {
376
                    if ( jqXHR.status == '202') {
377
                                                try {
378
                            console.info('suspended ' + serverID);
379
                        } catch(err) {}                                       
380
                        shutdown(serverIDs);
381
                    } else {
382
                        ajax_error(jqXHR.status);
383
                    }
384
                }             
385
    });
386

    
387
    return false;    
388
}
389

    
390
// destroy action
391
function destroy(serverIDs) {
392
        if (!serverIDs.length){
393
                ajax_success('DEFAULT');
394
                return false;
395
        }
396
    // ajax post destroy call can have an empty request body
397
    var payload = {};   
398

    
399
        serverID = serverIDs.pop()
400
    $.ajax({
401
            url: '/api/v1.0/servers/' + serverID,
402
            type: "DELETE",
403
            dataType: "json",
404
        data: JSON.stringify(payload),
405
        timeout: TIMEOUT,
406
        error: function(jqXHR, textStatus, errorThrown) { 
407
                    ajax_error(jqXHR.status);
408
                    },
409
        success: function(data, textStatus, jqXHR) {
410
                    if ( jqXHR.status == '202') {
411
                                                try {
412
                            console.info('destroyed ' + serverID);
413
                        } catch (err) {}                                        
414
                        destroy(serverIDs);
415
                    } else {
416
                        ajax_error(jqXHR.status);
417
                    }
418
                }             
419
    });
420

    
421
    return false;    
422
}
423

    
424
// start action
425
function start(serverIDs){
426
        if (!serverIDs.length){
427
                ajax_success('DEFAULT');
428
                return false;
429
        }        
430
    // ajax post start call
431
    var payload = {
432
        "start": {"type" : "NORMAL"}
433
    };   
434

    
435
        serverID = serverIDs.pop()
436
    $.ajax({
437
        url: '/api/v1.0/servers/' + serverID + '/action',
438
        type: "POST",
439
        dataType: "json",
440
        data: JSON.stringify(payload),
441
        timeout: TIMEOUT,
442
        error: function(jqXHR, textStatus, errorThrown) { 
443
                    ajax_error(jqXHR.status);
444
                    },
445
        success: function(data, textStatus, jqXHR) {
446
                    if ( jqXHR.status == '202') {
447
                                            try {
448
                            console.info('started ' + serverID);
449
                        } catch(err) {}                      
450
                        start(serverIDs);
451
                    } else {
452
                        ajax_error(jqXHR.status);
453
                    }
454
                }
455
    });
456

    
457
    return false;
458
}