Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines.html @ 6902f72e

History | View | Annotate | Download (16.7 kB)

1
{% load i18n %}
2

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

    
5
<!-- the create button -->
6
<div id="createcontainer">
7
    <span id="createbody">Start by creating a new virtual machine:</span><br />
8
    <a id="create" rel="#wizard" href="#">{% trans "Create New +" %}</a>
9
</div>
10

    
11
<!-- changing between standard/list view -->
12
<div id="view-select">
13
    <a id="standard" href="/machines/standard">#</a>
14
    <span class="view-separator">|</span>
15
    <a id="list" href="/machines/list">=</a>
16
</div>
17

    
18
<div id="emptymachineslist"><h1 id="welcomeheader">{% trans "Welcome to the ocean!" %}</h1><br />
19
    <span class="welcomebody">From this panel you will be able to manage your Virtual Machines (VMs). If you don't know what a VM is: take the <a href="#">tour</a>.</span><br /><br />
20
    <span class="welcomebody">The panel is currently empty, because you don't have any VMs yet. You can start by creating your new VM by clicking the blue button on the right. The wizard will guide you through the hole process.</span><br /><br />
21
    <span class="welcomefooter">For more information or text, click <a href="#">here</a>.</span>
22
</div>
23

    
24
<!-- the form -->
25
<form action="#">
26
        <!-- scrollable root element -->
27
        <div class="modal" id="wizard">
28
                <!-- status bar -->
29
                <ul id="status">
30
                        <li class="active"><strong>1.</strong> {% trans "Image" %}</li>
31
                        <li><strong>2.</strong> {% trans "Machine" %}</li>
32
                        <li><strong>3.</strong> {% trans "Review" %}</li>
33
                </ul>
34
                <!-- scrollable items -->
35
                <div class="items">
36
                        <!-- pages -->
37
                        <div class="page">
38
                <h2>{% trans "Select an OS" %}</h2>
39
                <ul class="tabs">
40
                    <li><a href="#">{% trans "standard" %}</a></li>
41
                    <li><a href="#">{% trans "custom" %}</a></li>
42
                </ul>
43
                <div class="panes">
44
                            <li id="image-template" style="display:none">
45
                                    <label for="image.id"> 
46
                            <a>
47
                                <div class="image">
48
                                    <img src="" class="image-logo"/>
49
                                    <strong class="image-title">image.title</strong>
50
                                    <input class="radio" type="radio" name="image-id" id="image-id" />
51
                                    <br />
52
                                    <span class="description">image.description</span> 
53
                                    <span class="size">?? MB</span>                              
54
                                </div>
55
                            </a>
56
                                    </label>
57
                            </li>
58
                    <ul class="pane" id="standard-images">
59
                                            <!-- standard images -->
60
                                    </ul>
61
                    <ul class="pane" id="custom-images">
62
                                            <!-- custom images -->
63
                    </ul>
64
                </div>
65
                                <button type="button" class="prev" id="cancel">{% trans "Cancel" %}</button>
66
                                <button type="button" class="next right">{% trans "Next" %} &raquo;</button>
67
            </div>
68
                        <div class="page">
69
                                <h2>{% trans "Select CPU, RAM and storage" %}</h2>
70
                <ul>
71
                    <li>
72
                        <div class="machine-type">
73
                            <label for="small">
74
                                <input type="radio" id="small" name="machine-type" value="small" checked="true" />
75
                                <strong>{% trans "small" %}</strong>
76
                            </label>
77
                        </div>
78
                        <div class="machine-type">      
79
                            <label for="medium">
80
                                <input type="radio" id="medium" name="machine-type" value="medium" />                  
81
                                <strong>{% trans "medium" %}</strong>
82
                            </label>
83
                        </div>
84
                        <div class="machine-type">
85
                            <label for="large">
86
                                <input type="radio" id="large" name="machine-type" value="large" />
87
                                <strong>{% trans "large" %}</strong>
88
                            </label>
89
                        </div>
90
                        <div class="machine-type">
91
                            <label for="custom">
92
                                <input type="radio" name="machine-type" id="custom" value="large" />
93
                                <strong>{% trans "custom" %}</strong>
94
                            </label>
95
                        </div>
96
                    </li>
97
                    <li>
98
                                    <label><strong class="sliders">CPU (cores)</strong></label>
99
                        <input type="range" id="cpu" style="display:none" />
100
                        <input type="text" class="range" id="cpu-indicator" />
101
                    </li>
102
                    <li>
103
                                    <label><strong class="sliders">RAM (MB)</strong></label>
104
                        <input type="range" id="ram" style="display:none" />
105
                        <input type="text" class="range" id="ram-indicator" />
106

    
107
                    </li>
108
                    <li>
109
                                <label><strong class="sliders">Storage (GB)</strong></label>
110
                        <input type="range" id="storage" style="display:none" />
111
                        <input type="text" class="range" id="storage-indicator" />
112

    
113
                    </li>
114
                    <li>
115
                        <div class="cost">
116
                            {% trans "Cost per hour:" %} 20 {% trans "credits" %} | {% trans "Credits currently in account:" %} 10.000
117
                        </div>
118
                    </li>
119
                </ul>
120
                                <button type="button" class="prev">&laquo; {% trans "Back" %}</button>
121
                                <button type="button" class="next right">{% trans "Next" %} &raquo;</button>
122
            </div>
123
                        <div class="page">
124
                                <h2>{% trans "Confirm your settings" %}</h2>
125
                <ul>
126
                    <li class="required">
127
                        <label>
128
                            <strong>Machine name</strong>
129
                            <input type="text" class="text" name="machine_name" value="My Ubuntu 10.04 x86_64 server"/>
130
                        </label>
131
                    </li>
132
                    <li>
133
                        <strong>{% trans "Image:" %}</strong> <span id="machine_image-label">Ubuntu 10.04 x86_64 server</span>
134
                    </li>
135
                    <li>
136
                        <strong>{% trans "CPU:" %}</strong> <span id="machine_cpu-label">2</span> <span>{% trans "cores" %}</span>
137
                    </li>
138
                    <li>
139
                        <strong>{% trans "RAM:" %}</strong> <span id="machine_ram-label">1024</span><span>MB</span>
140
                    </li>
141
                    <li>
142
                        <strong>{% trans "Storage:" %}</strong> <span id="machine_storage-label">10</span><span>GB</span>
143
                    </li>
144
                    <li>
145
                        <strong>{% trans "Cost per hour:" %}</strong> <span>20 {% trans "credits" %}</span>
146
                    </li>
147
                    <li>
148
                        <strong>{% trans "Remaining credits:" %}</strong> <span>10.000</span>
149
                    </li>
150
                </ul>
151
                                <button type="button" class="prev">&laquo; {% trans "Back" %}</button>
152
                                <button type="button" class="next right" id="start">{% trans "Create VM" %}</button>        
153
            </div>
154
                </div>
155
        </div>
156
</form>
157

    
158
<!-- notification after wizard completion -->
159
<a id="notification" rel="#error-success" href="#"></a>
160

    
161
<div class="modal" id="error-success">
162
    <h3>{% trans "Error!/Success!" %}</h3>
163
    <div><p>{% trans "More details about the result"%}</p></div>
164
</div>
165

    
166
<!-- confirmation before executing an action -->
167
<a id="confirmation" rel="#yes-no" href="#"></a>
168

    
169
<div class="modal" id="yes-no">
170
    <h3>{% trans "You are about to xxx machine yyy" %}</h3>
171
    <p>{% trans "Are you sure you want to proceed?" %}</p>
172
    <button>{% trans "Yes" %}</button>
173
        <button>{% trans "No" %}</button>
174
</div>
175

    
176
<div id="machinesview"></div>
177

    
178
<div class="confirm_multiple">
179
    <p>{% trans "Your actions will affect" %} <span class="actionLen">XX</span> {% trans "machines" %}</p>
180
    <button class="yes">{% trans "Confirm All" %}</button>
181
        <button class="no">{% trans "Cancel All" %}</button>
182
</div>
183

    
184
<div id="machines" class="separator"></div>
185

    
186
<script>
187
// hardcoded image types
188
// TODO: get this from the metadata
189
var image_tags = {
190
                1: 'archlinux',
191
                2: 'centos',
192
                3: 'debian',
193
                4: 'freebsd',
194
                5: 'gentoo',
195
                6: 'netbsd',
196
                7: 'openbsd',
197
                8: 'redhat',
198
                9: 'slackware',
199
                10: 'suse',
200
                11: 'ubuntu',
201
                12: 'windows',
202
                20: 'ubuntu',
203
               };
204

205
// switch to list view
206
$("a#list").click(function(){
207
    list_view(); 
208
    return false;
209
});
210

211
// switch to standard view
212
$("a#standard").click(function(){
213
    standard_view();
214
    return false;
215
});
216

217
// launch VM creation wizard
218
$("a#create").click(function(){
219
    // launch wizard only if images and flavors are found
220
    if (images.length > 0  && flavors.length > 0) {
221
        $("#wizard").scrollable().begin();
222
        $("#wizard").show();
223
        $('a#create').data('overlay').load()   
224
    } else if (images.length == 0 ) {
225
        ajax_error('NO_IMAGES');
226
        return false;   
227
    } else if (flavors.length == 0) {
228
        ajax_error('NO_FLAVORS');
229
        return false;
230
    }
231
});
232

233
// create wizard overlay
234
$(function() { 
235
    $("a#create").overlay({
236
        mask: '#000', 
237
        effect: 'default', 
238
        top: '5%', 
239
        oneInstance: false,
240
        closeOnClick: false
241
    });
242
});
243

244
// wizard
245
$(function() {
246
    var root = $("#wizard").scrollable();
247
    var api = root.scrollable();
248
    // rangeinput with default configuration
249
    // validation logic is done inside the onBeforeSeek callback
250
    api.onBeforeSeek(function(event, i) {
251
            // we are going 1 step backwards so no need for validation
252
            if (api.getIndex() < i) {
253
             // 1. get current page
254
                     var page = root.find(".page").eq(api.getIndex()),
255
                         // 2. .. and all required fields inside the page
256
                         inputs = page.find(".required :input").removeClass("error"),
257
                         // 3. .. which are empty
258
                         empty = inputs.filter(function() {
259
                                return $(this).val().replace(/\s*/g, '') == '';
260
                         });
261
                     // if there are empty fields, then
262
                    if (empty.length) {
263
                            // add a CSS class name "error" for empty & required fields
264
                            empty.addClass("error");
265
                            // cancel seeking of the scrollable by returning false
266
                            return false;
267
                    // everything is good
268
                    } 
269
            }
270
            // update status bar
271
            $("#status li").removeClass("active").eq(i).addClass("active");
272
        // update confirm step
273
        if (api.getIndex()==0) {
274
            var image = $("input[type=radio][name=image-id]:checked");
275
            var imageRef = image.length ? image[0].id : false
276
            if (imageRef) {
277
                var imageName = $("label[for=" + imageRef + "] .image-title").text();
278
                $("#machine_image-label")[0].textContent = imageName;
279
                $("input[type=text][name=machine_name]")[0].value = "My " + imageName + " server";
280
            }
281
        } else if (api.getIndex()==1) {
282
            $("#machine_cpu-label")[0].textContent = $("#cpu-indicator")[0].value;
283
            $("#machine_ram-label")[0].textContent = $("#ram-indicator")[0].value;
284
            $("#machine_storage-label")[0].textContent = $("#storage-indicator")[0].value;
285
        }    
286
    });
287
    // if tab is pressed on the next button seek to next page
288
    root.find("button.next").keydown(function(e) {
289
            if (e.keyCode == 9) {
290
                    // seeks to next tab by executing our validation routine
291
                    api.next();
292
                    e.preventDefault();
293
            }
294
    });
295
});
296

297
// disable sliders in flavor selection
298
function disableSliders() {
299
    $("#cpu").attr('disabled',true);
300
    $("#ram").attr('disabled',true);
301
    $("#storage").attr('disabled',true);
302
}
303

304
// confirm all actions
305
$("div.confirm_multiple .yes").live('click', function(){
306
    while(pending_actions.length > 0){ // if there is a pending action for this server execute it
307
        action = pending_actions.pop(); // extract action
308
        var serverID = action[1];
309
        
310
        if ($.cookie("list") != '1') { // standard view
311
            $('#'+serverID+' .spinner').show();
312
            $('#'+serverID+' .selected').removeClass('selected');
313
            $('#'+serverID+' .display').removeClass('display');
314
        } else { // list view
315
            osIcon = $('#'+serverID).parent().parent().find('.list-logo');
316
            osIcon.attr('os',osIcon.attr('src'));
317
            osIcon.attr('src','static/progress.gif');
318
        }
319
        action[0]([serverID]); // execute action
320
    }
321
    update_confirmations();    
322
});
323

324
// cancel all actions
325
$("div.confirm_multiple .no").live('click', function(){
326
    pending_actions = [];
327
    $('.machine .selected').removeClass('selected');
328
    $('.machine .display').removeClass('display');
329
    update_confirmations();
330
});
331

332
// validate cpu input box
333
$("#cpu-indicator").live('change',function(){
334
    var v = Number(this.value);
335
    var i = cpus.indexOf(v);
336
    if (isNaN(v)) {
337
        $(this).value = cpus[0];
338
        $("#cpu").data('rangeinput').setValue(0);
339
    } else if (i == -1) {
340
        for (var j=0; j < cpus.length; j++)
341
            if (v<cpus[j])
342
                break;
343
        $("#cpu").data('rangeinput').setValue(j);
344
    } else {
345
        $("#cpu").data('rangeinput').setValue(i);
346
    }   
347
    return false;
348
});
349

350
// validate ram input box
351
$("#ram-indicator").live('change',function(){
352
    var v = Number(this.value);
353
    var i = ram.indexOf(v);
354
    if (isNaN(v)) {
355
        $(this).value = cpus[0];
356
        $("#ram").data('rangeinput').setValue(0);
357
    } else if (i == -1) {
358
        for (var j=0; j < ram.length; j++)
359
            if (v<ram[j])
360
                break;
361
        $("#ram").data('rangeinput').setValue(j);
362
    } else {
363
        $("#ram").data('rangeinput').setValue(i);
364
    }   
365
    return false;
366
});
367

368

369
// validate storage input box
370
$("#storage-indicator").live('change',function(){
371
    var v = Number(this.value);
372
    var i = disks.indexOf(v);
373
    if (isNaN(v)) {
374
        $(this).value = disks[0];
375
        $("#storage").data('rangeinput').setValue(0);
376
    } else if (i == -1) {
377
        for (var j=0; j < disks.length; j++)
378
            if (v<disks[j])
379
                break;
380
        $("#storage").data('rangeinput').setValue(j);
381
    } else {
382
        $("#storage").data('rangeinput').setValue(i);
383
    }   
384
    return false;
385
});
386

387
// selecting the small size
388
$("#small").click(function(){
389
    $("#cpu").data('rangeinput').setValue(0);
390
    $("#ram").data('rangeinput').setValue(0);
391
    $("#storage").data('rangeinput').setValue(0);
392
    $("#cpu-indicator")[0].value = cpus[0];
393
    $("#ram-indicator")[0].value = ram[0];
394
    $("#storage-indicator")[0].value = disks[0];
395
});
396

397
// selecting the medium size
398
$("#medium").click(function(){
399
    $("#cpu").data('rangeinput').setValue(1);
400
    $("#ram").data('rangeinput').setValue(1);
401
    $("#storage").data('rangeinput').setValue(1);
402
    $("#cpu-indicator")[0].value = cpus[1];
403
    $("#ram-indicator")[0].value = ram[1];
404
    $("#storage-indicator")[0].value = disks[1];    
405
});
406

407
// selecting the large size
408
$("#large").click(function(){
409
    $("#cpu").data('rangeinput').setValue(2);
410
    $("#ram").data('rangeinput').setValue(2);
411
    $("#storage").data('rangeinput').setValue(2);
412
    $("#cpu-indicator")[0].value = cpus[2];
413
    $("#ram-indicator")[0].value = ram[2];
414
    $("#storage-indicator")[0].value = disks[2];    
415
});
416

417
// selecting the custom flavor enables the sliders
418
$("#custom").click(function(){
419
    $("#cpu").attr('disabled',false);
420
    $("#ram").attr('disabled',false);
421
    $("#storage").attr('disabled',false);
422
    $("strong.sliders").style = 'color: #778899;';
423
});
424

425
// exit the wizard
426
$("#cancel").click(function(){
427
    $("a#create").overlay().close();
428
});
429

430
// starting a new VM through the wizard
431
$("#start").click(function(){
432
    var imageRef = $('input[type=radio][name=image-id]:checked')[0].id.replace('img-radio-','');   
433
    var flavorRef = identify_flavor($("#cpu-indicator")[0].value, $("#storage-indicator")[0].value, $("#ram-indicator")[0].value);
434
    var machineName = $('input[name=machine_name]')[0].value;
435

436
    create_vm(machineName, imageRef, flavorRef);
437

438
    $('a#create').data('overlay').close();
439
    $("#emptymachineslist").hide();
440

441
    try{console.warn('creating ' + $("input[name=machine_name]")[0].value)} catch(err){}
442

443
    $("#wizard").hide();
444
});
445

446
// basic functions executed on page load
447
if (images.length > 0) {
448
    // populate image list
449
    update_wizard_images();
450
}
451
if (flavors.length > 0) {
452
    // configure flavors
453
    update_wizard_flavors(); 
454
}
455
// create tabs for main menu
456
$("ul.tabs").tabs("div.panes ul");
457

    
458
</script>