Statistics
| Branch: | Tag: | Revision:

root / ui / static / synnefo.js @ 146b6003

History | View | Annotate | Download (13.6 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
// get and show a list of running and terminated machines
107
function update_vms(interval) {
108
    try{ console.info('updating machines'); } catch(err){}
109

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

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

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

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

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

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

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

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

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

    
349
    return false;
350
}
351

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

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

    
385
    return false;    
386
}
387

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

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

    
419
    return false;    
420
}
421

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

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

    
455
    return false;
456
}