Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines.html @ dddb9274

History | View | Annotate | Download (30.1 kB)

1
{% load i18n %}
2

    
3
<div id="machines" class="seperator"></div>
4

    
5
<!-- the create button -->
6
<a id="create" rel="#wizard" href="#">{% trans "Create New +" %}</a>
7

    
8
<!-- changing between standard/list view -->
9
<div id="view-select">
10
    <a id="standard" class="current" href="/machines">#</a>
11
    <span class="view-seperator">|</span>
12
    <a id="list" href="/machines/list">=</a>
13
</div>
14

    
15
<!-- the standard view -->
16
<div id="machinesview" class="standard">
17
    <div id="spinner"></div>
18
    <div class="machine" id="machine-template" style="display:none">
19
        <div class="state">
20
            <div class="status">{% trans "Running" %}</div>
21
            <div class="indicator"></div>
22
            <div class="indicator"></div>
23
            <div class="indicator"></div>
24
            <div class="indicator"></div>
25
        </div>
26
        <img class="logo" src="" />
27
        <a href="#" class="name">
28
            <h5>Νame: <span class="name">node.name</span><span class="rename"></span></h5>
29
        </a>
30
        <a href="#" class="ip">
31
            <h5>IP: <span class="public">node.public_ip</span></h5>
32
        </a>
33
        <h5 class="settings">
34
            {% trans "Show:" %} <a href="#">{% trans "disks" %}</a> | <a href="#">{% trans "networks" %}</a> | <a href="#">{% trans "group" %}</a>
35
        </h5>
36
        <div class="actions">
37
            <a href="#" class="action-start">{% trans "Start" %}</a>
38
            <a href="#" class="action-reboot">{% trans "Reboot" %}</a>
39
            <a href="#" class="action-shutdown">{% trans "Shutdown" %}</a>
40
            <a href="#" class="more">{% trans "more &hellip;" %}</a>
41
        </div>
42
        <div class="seperator"></div>
43
    </div>
44

    
45
    <div class="running"></div>
46
    <div id="mini" class="seperator"></div>
47
    <div class="terminated"></div>
48
</div>
49

    
50
<div id="machines" class="seperator"></div>
51

    
52
<!-- the form -->
53
<form action="#">
54
        <!-- scrollable root element -->
55
        <div class="modal" id="wizard">
56
                <!-- status bar -->
57
                <ul id="status">
58
                        <li class="active"><strong>1.</strong> {% trans "Image" %}</li>
59
                        <li><strong>2.</strong> {% trans "Machine" %}</li>
60
                        <li><strong>3.</strong> {% trans "Review" %}</li>
61
                </ul>
62
                <!-- scrollable items -->
63
                <div class="items">
64
                        <!-- pages -->
65
                        <div class="page">
66
                <h2>{% trans "Select an OS" %}</h2>
67
                <ul class="tabs">
68
                    <li><a href="#">{% trans "standard" %}</a></li>
69
                    <li><a href="#">{% trans "custom" %}</a></li>
70
                </ul>
71
                <div class="panes">
72
                            <li id="image-template" style="display:none">
73
                                    <label for="image.id"> 
74
                            <a><div class="image">
75
                                <img src="" class="image-logo"/>
76
                                <strong class="image-title">image.title</strong>
77
                                <input class="radio" type="radio" name="image-id" id="image-id" />
78
                                <br />
79
                                <span class="description">image.description</span> 
80
                                <span class="size">?? MB</span>
81
                                
82
                            </div></a>
83
                                    </label>
84
                            </li>
85
                    <ul class="pane" id="standard-images">
86
                                            <!-- standard images -->
87
                                    </ul>
88
                    <ul class="pane" id="custom-images">
89
                                            <!-- custom images -->
90

    
91
                    </ul>
92
                </div>
93
                                <button type="button" class="prev" id="cancel">{% trans "Cancel" %}</button>
94
                                <button type="button" class="next right">{% trans "Next" %} &raquo;</button>
95
            </div>
96
                        <div class="page">
97
                                <h2>{% trans "Select CPU, RAM and storage" %}</h2>
98
                <ul>
99
                    <li>
100
                        <div class="machine-type">
101
                            <label for="small">
102
                                <input type="radio" id="small" name="machine-type" value="small" checked="true" />
103
                                <strong>{% trans "small" %}</strong>
104
                            </label>
105
                        </div>
106
                        <div class="machine-type">      
107
                            <label for="medium">
108
                                <input type="radio" id="medium" name="machine-type" value="medium" />                  
109
                                <strong>{% trans "medium" %}</strong>
110
                            </label>
111
                        </div>
112
                        <div class="machine-type">
113
                            <label for="large">
114
                                <input type="radio" id="large" name="machine-type" value="large" />
115
                                <strong>{% trans "large" %}</strong>
116
                            </label>
117
                        </div>
118
                        <div class="machine-type">
119
                            <label for="custom">
120
                                <input type="radio" name="machine-type" id="custom" value="large" />
121
                                <strong>{% trans "custom" %}</strong>
122
                            </label>
123
                        </div>
124
                    </li>
125
                    <li>
126
                                    <label><strong class="sliders">CPU (cores)</strong></label>
127
                        <input type="range" id="cpu" style="display:none" />
128
                        <input type="text" class="range" id="cpu-indicator" />
129
                    </li>
130
                    <li>
131
                                    <label><strong class="sliders">RAM (MB)</strong></label>
132
                        <input type="range" id="ram" style="display:none" />
133
                        <input type="text" class="range" id="ram-indicator" />
134

    
135
                    </li>
136
                    <li>
137
                                <label><strong class="sliders">Storage (GB)</strong></label>
138
                        <input type="range" id="storage" style="display:none" />
139
                        <input type="text" class="range" id="storage-indicator" />
140

    
141
                    </li>
142
                    <li>
143
                        <div class="cost">
144
                            {% trans "Cost per hour:" %} 20 {% trans "credits" %} | {% trans "Credits currently in account:" %} 10.000
145
                        </div>
146
                    </li>
147
                </ul>
148
                                <button type="button" class="prev">&laquo; {% trans "Back" %}</button>
149
                                <button type="button" class="next right">{% trans "Next" %} &raquo;</button>
150
            </div>
151
                        <div class="page">
152
                                <h2>{% trans "Confirm your settings" %}</h2>
153
                <ul>
154
                    <li class="required">
155
                        <label>
156
                            <strong>Machine name</strong>
157
                            <input type="text" class="text" name="machine_name" value="My Ubuntu 10.04 x86_64 server"/>
158
                        </label>
159
                    </li>
160
                    <li>
161
                        <strong>{% trans "Image:" %}</strong> <span id="machine_image-label">Ubuntu 10.04 x86_64 server</span>
162
                    </li>
163
                    <li>
164
                        <strong>{% trans "CPU:" %}</strong> <span id="machine_cpu-label">2</span> <span>{% trans "cores" %}</span>
165
                    </li>
166
                    <li>
167
                        <strong>{% trans "RAM:" %}</strong> <span id="machine_ram-label">1024</span><span>MB</span>
168
                    </li>
169
                    <li>
170
                        <strong>{% trans "Storage:" %}</strong> <span id="machine_storage-label">10</span><span>GB</span>
171
                    </li>
172
                    <li>
173
                        <strong>{% trans "Cost per hour:" %}</strong> <span>20 {% trans "credits" %}</span>
174
                    </li>
175
                    <li>
176
                        <strong>{% trans "Remaining credits:" %}</strong> <span>10.000</span>
177
                    </li>
178
                </ul>
179
                                <button type="button" class="prev">&laquo; {% trans "Back" %}</button>
180
                                <button type="button" class="next right" id="start">{% trans "Create VM" %}</button>        
181
            </div>
182
                </div>
183
        </div>
184
</form>
185

    
186
<!-- notification after wizard completion -->
187
<a id="notification" rel="#error-success" href="#"></a>
188

    
189
<div class="modal" id="error-success">
190
    <h3>{% trans "Error!/Success!" %}</h3>
191
    <p>{% trans "More details about the result"%}</p>
192
</div>
193

    
194
<!-- confirmation before executing an action -->
195
<a id="confirmation" rel="#yes-no" href="#"></a>
196

    
197
<div class="modal" id="yes-no">
198
    <h3>{% trans "You are about to xxx machine yyy" %}</h3>
199
    <p>{% trans "Are you sure you want to proceed?" %}</p>
200
    <button>{% trans "Yes" %}</button>
201
        <button>{% trans "No" %}</button>
202
</div>
203

    
204
<script type="text/javascript"> 
205
var TIMEOUT = {{timeout}};
206
</script>
207

    
208
<script>
209
// hardcoded image types
210
var image_tags = {
211
                1: 'archlinux',
212
                2: 'centos',
213
                3: 'debian',
214
                4: 'freebsd',
215
                5: 'gentoo',
216
                6: 'netbsd',
217
                7: 'openbsd',
218
                8: 'redhat',
219
                9: 'slackware',
220
                10: 'suse',
221
                11: 'ubuntu',
222
                12: 'windows',
223
                20: 'ubuntu',
224
               };
225

226
// ajax error checking  
227
function ajax_error(jqXHR) {; 
228
    // prepare the error message
229
    $("#error-success h3").text('{% trans "Error!" %}');
230
    // check the error code
231
    switch (jqXHR.status) {
232
        case 400: // YY error/message
233
            $("#error-success p").text('{% trans "A Bad Request has been made." %}');
234
            break;
235
        case 404: // YY error/message
236
            $("#error-success p").text('{% trans "Your request has failed." %}');
237
            break;
238
        case 501: // XX error/message
239
            $("#error-success p").text('{% trans "There has been an Internal Error. Our administrators have been notified." %}');
240
            break;
241
        case 503: // XX error/message
242
            $("#error-success p").text('{% trans "This service is unavailble right now, please try again later." %}');
243
            break;
244
        default: // XXYY error/message
245
            $("#error-success p").text('{% trans "An Error has happened. Our administrators have been notified." %}');
246
    }
247
    // bring up error notification
248
    var triggers = $("a#notification").overlay({
249
            // some mask tweaks suitable for modal dialogs
250
            mask: {
251
                    color: '#ebecff',
252
                    opacity: '0.9'
253
            },
254
        top: 'center',
255
            closeOnClick: false,
256
        oneInstance: false,
257
        load: true,
258
        onClose: function(){
259
            $("div.pane#machines-pane").load($("a#standard").attr("href"));
260
        }
261
    });
262
    return false;
263
}
264

265
// ajax success checking
266
function ajax_success() {
267
    // prepare the error message
268
    $("#error-success h3").text('Success!');
269
    $("#error-success p").text('Your request has been succefully executed.');
270
    // bring up success notification
271
    var triggers = $("a#notification").overlay({
272
            // some mask tweaks suitable for modal dialogs
273
            mask: {
274
                    color: '#ebecff',
275
                    opacity: '0.9'
276
            },
277
        top: 'center',
278
            closeOnClick: false,
279
        oneInstance: false,
280
        load: true,
281
        onClose: function(){
282
            $("div.pane#machines-pane").load($("a#standard").attr("href"));
283
        }
284
    });
285
    return false;
286
}
287

288
// confirmation overlay generation
289
function confirm_action(action_string, action_function, serverID, serverName) {
290
    $("#yes-no h3").text('You are about to ' + action_string + ' vm ' + serverName);
291
    // action confirmation overlay
292
    var triggers = $("a#confirmation").overlay({
293
            // some mask tweaks suitable for modal dialogs
294
            mask: {
295
                    color: '#ebecff',
296
                    opacity: '0.9'
297
            },
298
        top: 'center',
299
        load: true
300
    });
301
    // yes or no?
302
    var buttons = $("#yes-no button").click(function(e) {
303
            // get user input
304
            var yes = buttons.index(this) === 0;
305
        //close the confirmation window
306
        $("a#confirmation").overlay().close(); 
307
        // return true=yes or false=no
308
        if (yes) {
309
            action_function(serverID);
310
        } else {
311
            // reload page
312
            $("div.pane#machines-pane").load($("a#standard").attr("href"));
313
        }
314
    });
315
    return false;
316
}
317

318
// get and show a list of running and terminated machines
319
function update_vms() {
320

321
    $(".running").text('');
322
    $(".terminated").text('');
323
    $("ul#standard-images").text('');
324
    $("ul#custom-images").text('');
325

326
    $.ajax({
327
        url: '/api/v1.0/servers/detail',
328
        type: "GET",
329
        timeout: TIMEOUT,
330
        dataType: "json",
331
        error: function(jqXHR, textStatus, errorThrown) { 
332
                    ajax_error(jqXHR);
333
                    return false;
334
                    },
335
        success: function(data, textStatus, jqXHR) {
336
            if ($(".running a.name").length + $(".terminated a.name").length == 0) {
337
            
338
                $.each(data.servers, function(i,server){
339
                    // if the machine is deleted it should not be included in any list
340
                    if (server.status == 'DELETED') {
341
                        return;
342
                    }
343
                    var machine = $("#machine-template").clone().attr("id", server.id).fadeIn("slow");
344
                    machine.find("input[type='checkbox']").attr("id", "input-" + server.id);
345
                    machine.find("input[type='checkbox']").attr("class", server.status);
346
                    machine.find("a.name span.name").text(server.name);
347
                    machine.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'.png');
348
                    machine.find("img.list-logo").attr("src","static/os_logos/"+image_tags[server.imageId]+'.png');
349
                    machine.find("img.list-logo").attr("title",image_tags[server.imageId]);
350
                    machine.find("span.imagetag").text(image_tags[server.imageId]);
351
    
352
                    machine.find("a.ip span.public").text(String(server.addresses.public.ip.addr).replace(',',' '));            
353
    
354
                    // TODO: handle SHARE_IP, SHARE_IP_NO_CONFIG, DELETE_IP, REBUILD, QUEUE_RESIZE, PREP_RESIZE, RESIZE, VERIFY_RESIZE, PASSWORD, RESCUE
355
                    if (server.status == 'BUILD'){
356
                        machine.find(".status").text('Building');
357
                        machine.appendTo(".running");
358
                    } else if (server.status == 'ACTIVE') {
359
                        machine.find(".status").text('Running');
360
                        machine.appendTo(".running"); 
361
                    } else if (server.status == 'REBOOT' || server.status == 'HARD_REBOOT') {
362
                        machine.find(".status").text('Rebooting');
363
                        machine.appendTo(".running");
364
                    } else if (server.status == 'STOPPED') {
365
                        machine.find(".status").text('Stopped');
366
                        machine.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'-off.png');
367
                        machine.find("img.list-logo").attr("src","static/os_logos/"+image_tags[server.imageId]+'-off.png');
368
                        machine.appendTo(".terminated");
369
                    } else if (server.status == 'ERROR') {
370
                        machine.find(".status").text('Error');
371
                        machine.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'-off.png');
372
                        machine.find("img.list-logo").attr("src","static/os_logos/"+image_tags[server.imageId]+'-off.png');
373
                        machine.appendTo(".terminated");
374
                    } 
375
                    else {
376
                        machine.find(".status").text('Unknown');
377
                        machine.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'-off.png');
378
                        machine.find("img.list-logo").attr("src","static/os_logos/"+image_tags[server.imageId]+'-off.png');
379
                        machine.appendTo(".terminated");
380
                    }
381
                });
382
            }
383
            $("#spinner").hide();
384
            $("div.machine:last-child").find("div.seperator").hide();
385
            // if the terminated list is populated then the seperator must be shown
386
            if ($(".terminated a.name").length > 0) {
387
                $("#mini.seperator").fadeIn("slow");
388
            }
389
            // creating the table in list view, if there are machines to show
390
            if ($("div.list table.list-machines tbody").length > 0) {
391
                $("div.list table.list-machines").dataTable({
392
                    "bInfo": false,
393
                    "bPaginate": false,
394
                            "bAutoWidth": false,
395
                            "bSort": true,    
396
                    "bStateSave": true,
397
                    //"sScrollY": "250px",
398
                    //"sScrollX": "500px",
399
                    //"sScrollXInner": "480px",
400
                    "aoColumnDefs": [
401
                        { "bSortable": false, "aTargets": [ 0 ] }
402
                    ]
403
                });
404
                $("div.list table.list-machines").show();
405
                $("div.list div.actions").show();
406
            }
407
        }
408
    });
409
    return false;
410
}
411

412
// get and show a list of anvailable standard and custom images
413
function update_images() { 
414
    $.ajax({
415
        url: '/api/v1.0/images/detail',
416
        type: "GET",
417
        //async: false,
418
        dataType: "json",
419
        timeout: TIMEOUT,
420
        error: function(jqXHR, textStatus, errorThrown) { 
421
                    ajax_error(jqXHR);
422
                    },
423
        success: function(data, textStatus, jqXHR) {
424
            if ($("ul#standard-images li").toArray().length + $("ul#custom-images li").toArray().length == 0) {
425
                $.each(data.images, function(i,image){
426
                    var img = $('#image-template').clone().attr("id","img-"+image.id).fadeIn("slow");
427
                    img.find("label").attr('for',"img-radio-" + image.id);
428
                    img.find(".image-title").text(image.name);
429
                    img.find(".description").text(image.description);
430
                    img.find(".size").text(image.size);
431
                    img.find("input.radio").attr('id',"img-radio-" + image.id);
432
                    if (i==0) img.find("input.radio").attr("checked","checked"); 
433
                    img.find("img.image-logo").attr('src','static/os_logos/'+image_tags[image.id]+'.png');
434
                    if (image.serverId) {
435
                        img.appendTo("ul#custom-images");
436
                    } else {
437
                        img.appendTo("ul#standard-images");
438
                    }
439
                });
440
            }
441
        }
442
    });
443
    return false;
444
}
445

446
var flavors = {}, disks = [], cpus = [], ram = [];
447

448
Array.prototype.unique = function () {
449
        var r = new Array();
450
        o:for(var i = 0, n = this.length; i < n; i++)
451
        {
452
                for(var x = 0, y = r.length; x < y; x++)
453
                {
454
                        if(r[x]==this[i])
455
                        {
456
                                continue o;
457
                        }
458
                }
459
                r[r.length] = this[i];
460
        }
461
        return r;
462
}
463

464
// get and configure flavor selection
465
function update_flavors() { 
466
    $.ajax({
467
        url: '/api/v1.0/flavors/detail',
468
        type: "GET",
469
        //async: false,
470
        dataType: "json",
471
        timeout: TIMEOUT,
472
        error: function(jqXHR, textStatus, errorThrown) { 
473
            ajax_error(jqXHR);
474
        },
475
        success: function(data, textStatus, jqXHR) {
476
            flavors = data.flavors;
477
            $.each(flavors, function(i, flavor) {
478
                cpus[i] = flavor['cpu'];
479
                disks[i] = flavor['disk'];
480
                ram[i] = flavor['ram'];
481
            });
482
            cpus = cpus.unique();
483
            disks = disks.unique();
484
            ram = ram.unique();
485
            // sliders for selecting VM flavor
486
            $("#cpu:range").rangeinput({min:0,
487
                                       value:0,
488
                                       step:1,
489
                                       progress: true,
490
                                       max:cpus.length-1});
491
            
492
            $("#storage:range").rangeinput({min:0,
493
                                       value:0,
494
                                       step:1,
495
                                       progress: true,
496
                                       max:disks.length-1});
497

498
            $("#ram:range").rangeinput({min:0,
499
                                       value:0,
500
                                       step:1,
501
                                       progress: true,
502
                                       max:ram.length-1});
503
            $("#small").click();
504

505
        }
506
    });
507
    return false;
508
}
509
// return flavorId from cpu, disk, ram values
510
function identify_flavor(cpu, disk, ram){
511
    for (i=0;i<flavors.length;i++){
512
        if (flavors[i]['cpu'] == cpu && flavors[i]['disk']==disk && flavors[i]['ram']==ram) {
513
            return flavors[i]['id']
514
        }
515
    }
516
    return 0;
517
}
518

519
// switch to list view
520
$("#list").click(function(){
521
    $.cookie("list", '1'); // set list cookie
522
    $("div.standard#machinesview").load($("#list").attr("href"));
523
    $("a#standard")[0].className += ' activelink'
524
    this.style.color = '#5f8dd3';
525
    update_vms();
526
    return false;
527
});
528

529
// switch to standard view
530
$("a#standard").click(function(){
531
    $.cookie("list", '0');
532
    href=$("a#standard").attr("href");
533
    $("div.pane#machines-pane").load(href);
534
    return false;
535
});
536

537
// redirect to list view if the list cookie is set
538
if ($.cookie("list") == '1') {
539
    $("#list").click();
540
} else {
541
    // execute the update function to populate the list
542
    update_vms();
543
}
544

545
// launch VM creation wizard
546
$("a#create").click(function(){
547
    // populate image list
548
    update_images();
549
    // configure flavors
550
    update_flavors(); 
551
    // launch the wizard
552
    $("#wizard").scrollable().begin();
553
});
554

555
// create wizard overlay
556
$(function() { 
557
    $("a#create").overlay({
558
        mask: '#000', 
559
        effect: 'default', 
560
        top: '5%', 
561
        oneInstance: false,
562
        closeOnClick: false
563
    });
564
});
565

566
// wizard
567
$(function() {
568
    var root = $("#wizard").scrollable();
569

570
    // some variables that we need
571
    var api = root.scrollable();
572

573
    // rangeinput with default configuration
574
    // validation logic is done inside the onBeforeSeek callback
575
    api.onBeforeSeek(function(event, i) {
576
            // we are going 1 step backwards so no need for validation
577
            if (api.getIndex() < i) {
578
             // 1. get current page
579
                     var page = root.find(".page").eq(api.getIndex()),
580
                         // 2. .. and all required fields inside the page
581
                         inputs = page.find(".required :input").removeClass("error"),
582
                         // 3. .. which are empty
583
                         empty = inputs.filter(function() {
584
                                return $(this).val().replace(/\s*/g, '') == '';
585
                         });
586
                     // if there are empty fields, then
587
                    if (empty.length) {
588
                            // add a CSS class name "error" for empty & required fields
589
                            empty.addClass("error");
590
                            // cancel seeking of the scrollable by returning false
591
                            return false;
592
                    // everything is good
593
                    } 
594
            }
595
            // update status bar
596
            $("#status li").removeClass("active").eq(i).addClass("active");
597
        
598
        // update confirm step
599
        var image = $("input[type=radio][name=image-id]:checked");
600
        var imageId = image.length ? image[0].id : false
601
        if (imageId) {
602
            var imageName = $("label[for=" + imageId + "] .image-title").text();
603
            $("#machine_image-label")[0].textContent = imageName;
604
            $("input[type=text][name=machine_name]")[0].value = "My " + imageName + " server";
605
        }
606
        $("#machine_cpu-label")[0].textContent = $("#cpu-indicator")[0].value;
607
        $("#machine_ram-label")[0].textContent = $("#ram-indicator")[0].value;
608
        $("#machine_storage-label")[0].textContent = $("#storage-indicator")[0].value;
609
        
610
    });
611

612
    // if tab is pressed on the next button seek to next page
613
    root.find("button.next").keydown(function(e) {
614
            if (e.keyCode == 9) {
615
                    // seeks to next tab by executing our validation routine
616
                    api.next();
617
                    e.preventDefault();
618
            }
619
    });
620

621
});
622

623
// disable sliders in flavor selection
624
function disableSliders() {
625
    $("#cpu").attr('disabled',true);
626
    $("#ram").attr('disabled',true);
627
    $("#storage").attr('disabled',true);
628
}
629

630
// selecting the small size
631
$("#small").click(function(){
632
    $("#cpu").data('rangeinput').setValue(0);
633
    $("#ram").data('rangeinput').setValue(0);
634
    $("#storage").data('rangeinput').setValue(0);
635
    $("#cpu-indicator")[0].value = cpus[0];
636
    $("#ram-indicator")[0].value = ram[0];
637
    $("#storage-indicator")[0].value = disks[0];
638
});
639

640
// selecting the medium size
641
$("#medium").click(function(){
642
    $("#cpu").data('rangeinput').setValue(1);
643
    $("#ram").data('rangeinput').setValue(1);
644
    $("#storage").data('rangeinput').setValue(1);
645
    $("#cpu-indicator")[0].value = cpus[1];
646
    $("#ram-indicator")[0].value = ram[1];
647
    $("#storage-indicator")[0].value = disks[1];    
648
});
649

650
// selecting the large size
651
$("#large").click(function(){
652
    $("#cpu").data('rangeinput').setValue(2);
653
    $("#ram").data('rangeinput').setValue(2);
654
    $("#storage").data('rangeinput').setValue(2);
655
    $("#cpu-indicator")[0].value = cpus[2];
656
    $("#ram-indicator")[0].value = ram[2];
657
    $("#storage-indicator")[0].value = disks[2];    
658
});
659

660
// selecting the custom flavor enables the sliders
661
$("#custom").click(function(){
662
    $("#cpu").attr('disabled',false);
663
    $("#ram").attr('disabled',false);
664
    $("#storage").attr('disabled',false);
665
    $("strong.sliders").style = 'color: #778899;';
666
});
667

668
// get cpu value for custom flavor
669
$("#cpu:range").change(function(event, value){
670
    $("#custom").click();
671
    // update cpu indicator
672
    $("#cpu-indicator")[0].value = cpus[Number(value)];
673
});
674

675
// get ram value for custom flavor
676
$("#ram:range").change(function(event, value){
677
    $("#custom").click();
678
    // update ram indicator
679
    $("#ram-indicator")[0].value = ram[Number(value)];
680
});
681

682
// get storage value for custom flavor
683
$("#storage:range").change(function(event, value){
684
    $("#custom").click();
685
    // update disk indicator
686
    $("#storage-indicator")[0].value = disks[Number(value)];
687
    return false;
688
});
689

690
// exit the wizard
691
$("#cancel").click(function(){
692
    $("a#create").overlay().close();
693
});
694

695
// starting a new VM through the wizard
696
$("#start").click(function(){
697
    //TODO: get the real data
698
    var flavorId = identify_flavor($("#cpu-indicator")[0].value, $("#storage-indicator")[0].value, $("#ram-indicator")[0].value);
699
    var payload = {
700
        "server": {
701
            "name": "image-name",
702
            "imageId": 1,
703
            "flavorId" : flavorId,
704
            "metadata" : {
705
                "My Server Name" : $("input[name=machine_name]")[0].value
706
            },
707
        }
708
    };
709

710
    $.ajax({
711
    url: "/api/v1.0/servers",
712
    type: "POST",
713
    dataType: "json",    
714
    data: JSON.stringify(payload),
715
    timeout: TIMEOUT,
716
    error: function(jqXHR, textStatus, errorThrown) { 
717
                ajax_error(jqXHR);
718
           },
719
    success: function(data, textStatus, jqXHR) {
720
                if ( jqXHR.status == '202') {
721
                    ajax_success(jqXHR);                   
722
                } else {
723
                    ajax_error(jqXHR);
724
                }
725
            }
726
    });
727
    console.warn('creating ' + $("input[name=machine_name]")[0].value)
728

729
    $("#wizard").hide();
730
});
731

732
// reboot action
733
function reboot(serverID){
734
    // ajax post reboot call
735
    var payload = {
736
        "reboot": {"type" : "HARD"}
737
    };   
738

739
    $.ajax({
740
        url: '/api/v1.0/servers/' + serverID + '/action',
741
        type: "POST",        
742
        dataType: "json",
743
        data: JSON.stringify(payload),
744
        timeout: TIMEOUT,
745
        error: function(jqXHR, textStatus, errorThrown) { 
746
                    ajax_error(jqXHR);
747
                    },
748
        success: function(data, textStatus, jqXHR) {
749
                    if ( jqXHR.status == '202') {
750
                        ajax_success(jqXHR);
751
                    } else {
752
                        ajax_error(jqXHR);
753
                    }}
754
    });
755
    console.warn('rebooting ' + serverID);    
756
    return false;
757
}
758

759
// shutdown action
760
function shutdown(serverID) {
761
    // ajax post shutdown call
762
    var payload = {
763
        "shutdown": {"timeout" : "5"}
764
    };   
765

766
    $.ajax({
767
            url: '/api/v1.0/servers/' + serverID + '/action',
768
            type: "POST",
769
            dataType: "json",
770
        data: JSON.stringify(payload),
771
        timeout: TIMEOUT,
772
        error: function(jqXHR, textStatus, errorThrown) { 
773
                    ajax_error(jqXHR);
774
                    },
775
        success: function(data, textStatus, jqXHR) {
776
                    if ( jqXHR.status == '202') {
777
                        ajax_success(jqXHR);
778
                    } else {
779
                        ajax_error(jqXHR);
780
                    }}             
781
    });
782
    console.warn('shutting down ' + serverID);        
783
    return false;    
784
}
785

786

787
// start action
788
function start(serverID){
789
    // ajax post start call
790
    var payload = {
791
        "start": {"type" : "NORMAL"}
792
    };   
793

794
    $.ajax({
795
        url: '/api/v1.0/servers/' + serverID + '/action',
796
        type: "POST",
797
        dataType: "json",
798
        data: JSON.stringify(payload),
799
        timeout: TIMEOUT,
800
        error: function(jqXHR, textStatus, errorThrown) { 
801
                    ajax_error(jqXHR);
802
                    },
803
        success: function(data, textStatus, jqXHR) {
804
                    if ( jqXHR.status == '202') {
805
                        ajax_success(jqXHR);
806
                    } else {
807
                        ajax_error(jqXHR);
808
                    }}
809
    });
810
    console.warn('starting ' + serverID);        
811
    return false;
812
}
813

814

815
// basic functions executed on page load
816

817
// create tabs for main menu
818
$("ul.tabs").tabs("div.panes ul");
819

820
// intercept reboot click 
821
$("div.actions a.action-reboot").live('click', function(){ 
822
    var serverID = $(this).parent().parent().attr("id");
823
    var serverName = $(this).parent().prevAll("a.name").find("span.name").text();
824
    confirm_action('reboot', reboot, serverID, serverName);
825
    return false;
826
});
827

828
// intercept shutdown click
829
$("div.actions a.action-shutdown").live('click', function(){ 
830
    var serverID = $(this).parent().parent().attr("id");
831
    var serverName = $(this).parent().prevAll("a.name").find("span.name").text();
832
    confirm_action('shutdown', shutdown, serverID, serverName);
833
    return false;
834
});
835
// intercept start click
836
$("div.actions a.action-start").live('click', function(){ 
837
    var serverID = $(this).parent().parent().attr("id");
838
    var serverName = $(this).parent().prevAll("a.name").find("span.name").text();
839
    confirm_action('start', start, serverID, serverName);
840
    return false;
841
});
842
</script>