Statistics
| Branch: | Tag: | Revision:

root / ui / templates / machines.html @ fb66080c

History | View | Annotate | Download (17.6 kB)

1
{% load i18n %}
2

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

    
5
<a id="create" rel="#wizard" href="#">{% trans "Create New +" %}</a>
6
<a id="notify" rel="#misc" href="#"></a>
7
<div id="view-select">
8
    <a id="standard" class="current" href="/machines">#</a>
9
    <span class="view-seperator">|</span>
10
    <a id="list" href="/machines/list">=</a>
11
</div>
12

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

    
41
    <div class="running"></div>
42
    <div id="mini" class="seperator"></div>
43
    <div class="terminated"></div>
44
</div>
45

    
46
<div id="machines" class="seperator"></div>
47

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

    
87
                    </ul>
88
                </div>
89
                                <button type="button" class="prev" id="cancel">{% trans "Cancel" %}</button>
90
                                <button type="button" class="next right">{% trans "Next" %} &raquo;</button>
91
            </div>
92
                        <div class="page">
93
                                <h2>{% trans "Select CPU, RAM and storage" %}</h2>
94
                <ul>
95
                    <li>
96
                        <div class="machine-type">
97
                            <label for="small">
98
                                <input type="radio" id="small" name="machine-type" value="small" checked="true" />
99
                                <strong>{% trans "small" %}</strong>
100
                            </label>
101
                        </div>
102
                        <div class="machine-type">      
103
                            <label for="medium">
104
                                <input type="radio" id="medium" name="machine-type" value="medium" />                  
105
                                <strong>{% trans "medium" %}</strong>
106
                            </label>
107
                        </div>
108
                        <div class="machine-type">
109
                            <label for="large">
110
                                <input type="radio" id="large" name="machine-type" value="large" />
111
                                <strong>{% trans "large" %}</strong>
112
                            </label>
113
                        </div>
114
                        <div class="machine-type">
115
                            <label for="custom">
116
                                <input type="radio" name="machine-type" id="custom" value="large" />
117
                                <strong>{% trans "custom" %}</strong>
118
                            </label>
119
                        </div>
120
                    </li>
121
                    <li>
122
                                    <label><strong class="sliders">CPU (cores)</strong></label>
123
                        <input type="range" id="cpu" value="1" max="8" min="1" />
124
                    </li>
125
                    <li>
126
                                    <label><strong class="sliders">RAM (MB)</strong></label>
127
                        <input type="range" id="ram" value="256" max="2048" min="256" step="256" />
128
                    </li>
129
                    <li>
130
                                <label><strong class="sliders">Storage (GB)</strong></label>
131
                        <input type="range" id="storage" value="5" step="1" max="100" min="2" />
132
                    </li>
133
                    <li>
134
                        <div class="cost">
135
                            {% trans "Cost per hour:" %} 20 {% trans "credits" %} | {% trans "Credits currently in account:" %} 10.000
136
                        </div>
137
                    </li>
138
                </ul>
139
                                <button type="button" class="prev">&laquo; {% trans "Back" %}</button>
140
                                <button type="button" class="next right">{% trans "Next" %} &raquo;</button>
141
            </div>
142
                        <div class="page">
143
                                <h2>{% trans "Confirm your settings" %}</h2>
144
                <ul>
145
                    <li class="required">
146
                        <label>
147
                            <strong>Machine name</strong>
148
                            <input type="text" class="text" name="machine_name" value="My Ubuntu 10.04 x86_64 server"/>
149
                        </label>
150
                    </li>
151
                    <li>
152
                        <strong>{% trans "Image:" %}</strong> <span>Ubuntu 10.04 x86_64 server</span>
153
                    </li>
154
                    <li>
155
                        <strong>{% trans "CPU:" %}</strong> <span>2 cores</span>
156
                    </li>
157
                    <li>
158
                        <strong>{% trans "RAM:" %}</strong> <span>1024MB</span>
159
                    </li>
160
                    <li>
161
                        <strong>{% trans "Storage:" %}</strong> <span>10GB</span>
162
                    </li>
163
                    <li>
164
                        <strong>{% trans "Cost per hour:" %}</strong> <span>20 {% trans "credits" %}</span>
165
                    </li>
166
                    <li>
167
                        <strong>{% trans "Remaining credits:" %}</strong> <span>10.000</span>
168
                    </li>
169
                </ul>
170
                                <button type="button" class="prev">&laquo; {% trans "Back" %}</button>
171
                                <button type="button" class="next right" id="start">{% trans "Create VM" %}</button>        
172
            </div>
173
                </div>
174
        </div>
175
</form>
176

    
177
<div class="modal" id="misc">
178
    <h3>Your VM is being created!</h3>
179
    <p>{% trans "Your password is:" %}<strong> sdeEFre</strong></p>
180
    <p>{% trans "Please copy this! Without it you can not connect to your VM." %}</p>
181
</div>
182

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

201
// create tabs for main menu
202
$("ul.tabs").tabs("div.panes ul");
203

204
// get and show list of running and terminated machines
205
function update() {
206

207
    $(".running").text('');
208
    $(".terminated").text('');
209
    $("ul#standard-images").text('');
210
    $("ul#custom-images").text('');
211
    $.ajax({
212
        url: '/api/v1.0/servers/detail',
213
        type: "GET",
214
        //async: false,
215
        dataType: "json",
216
        success: function(data) {
217
            if ($(".running a.name").toArray().length + $(".terminated a.name").toArray().length == 0) {
218
            
219
                $.each(data.servers, function(i,server){
220
                    var machine = $("#machine-template").clone().attr("id", server.id).fadeIn("slow");
221
                    machine.find("input[type='checkbox']").attr("id", "input-" + server.id);
222
                    machine.find("input[type='checkbox']").attr("class", server.status);
223
                    machine.find("a.name span.name").text(server.name);
224
                    machine.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'.png');
225
                    machine.find("img.list-logo").attr("src","static/os_logos/"+image_tags[server.imageId]+'.png');
226
                    machine.find("img.list-logo").attr("title",image_tags[server.imageId]);
227
                    machine.find("span.imagetag").text(image_tags[server.imageId]);
228
    
229
                    machine.find("a.ip span.public").text(String(server.addresses.public).replace(',',' '));            
230
    
231
                    if (server.status == 'PE_VM_MIGRATING'){
232
                        machine.find(".status").text('Building');
233
                        machine.appendTo(".running");
234
                    } else if (server.status == 'PE_VM_RUNNING') {
235
                        machine.find(".status").text('Running');
236
                        machine.appendTo(".running");
237
                    } else if (server.status == 'PE_VM_SUSPENDED') {
238
                        machine.find(".status").text('Terminated');
239
                        machine.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'-off.png');
240
                        machine.find("img.list-logo").attr("src","static/os_logos/"+image_tags[server.imageId]+'-off.png');
241
                        machine.appendTo(".terminated");
242
                        $("#mini.seperator").fadeIn("slow");
243
                    } else {
244
                        machine.find(".status").text('Unknown');
245
                        machine.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'-off.png');
246
                        machine.find("img.list-logo").attr("src","static/os_logos/"+image_tags[server.imageId]+'-off.png');
247
                        machine.appendTo(".terminated");
248
                    }
249
                });
250
            }
251
            $("div.machine:last-child").find("div.seperator").hide();
252
            $("#spinner").hide();
253
            $(".list table").show();
254
            $(".list table").tablesorter({ 
255
                headers: { 0: { sorter: false}, 6: { sorter: false }}, 
256
                sortMultiSortKey: "ctrlKey" }).show();
257
            $(".list .actions").show();
258
        }
259
    });
260

261
    $.ajax({
262
        url: '/api/v1.0/images/detail',
263
        type: "GET",
264
        //async: false,
265
        dataType: "json",
266
        success: function(data) {
267
            $.each(data.images, function(i,image){
268
                var img = $('#image-template').clone().attr("id","img-"+image.id).fadeIn("slow");
269
                img.find("label").attr('for',"img-radio-" + image.id);
270
                img.find(".image-title").text(image.name);
271
                img.find(".description").text(image.description);
272
                img.find("input.radio").attr('id',"img-radio-" + image.id);
273
                if (i==0) img.find("input.radio").attr("checked","checked"); 
274
                img.find("img.image-logo").attr('src','static/os_logos/'+image_tags[image.id]+'.png');
275
                if (image.serverId) {
276
                    img.appendTo("ul#custom-images");
277
                } else {
278
                    img.appendTo("ul#standard-images");
279
                }
280
            });
281
        }
282
    });
283
}
284

285
// switch to list view
286
$("#list").click(function(){
287
    $.cookie("list", '1');
288
    $("div.standard#machinesview").load($("#list").attr("href"));
289
    $("a#standard")[0].className += ' activelink'
290
    this.style.color = '#5f8dd3';
291
    update();
292
    return false;
293
});
294

295
// switch to standard view
296
$("a#standard").click(function(){
297
    $.cookie("list", '0');
298
    href=$("a#standard").attr("href");
299
    $("div.pane#machines-pane").load(href);
300
    //$("a#standard")[0].className += ' activelink'
301
    //this.style.color = '#5f8dd3';
302
    return false;
303
});
304

305
if ($.cookie("list") == '1') {
306
    $("#list").click();
307
} else {
308
    // execute the above function to populate the list
309
    update();
310
}
311

312
// launch VM creation wizard
313
$("a#create").click(function(){
314
    $("#wizard").scrollable().begin();
315
});
316

317
// wizard
318
$(function() {
319
    var root = $("#wizard").scrollable();
320

321
    // some variables that we need
322
    var api = root.scrollable();
323

324
    // rangeinput with default configuration
325
    // validation logic is done inside the onBeforeSeek callback
326
    api.onBeforeSeek(function(event, i) {
327
            // we are going 1 step backwards so no need for validation
328
            if (api.getIndex() < i) {
329
             // 1. get current page
330
                     var page = root.find(".page").eq(api.getIndex()),
331
                         // 2. .. and all required fields inside the page
332
                         inputs = page.find(".required :input").removeClass("error"),
333
                         // 3. .. which are empty
334
                         empty = inputs.filter(function() {
335
                                return $(this).val().replace(/\s*/g, '') == '';
336
                         });
337
                     // if there are empty fields, then
338
                    if (empty.length) {
339
                            // add a CSS class name "error" for empty & required fields
340
                            empty.addClass("error");
341
                            // cancel seeking of the scrollable by returning false
342
                            return false;
343
                    // everything is good
344
                    } 
345
            }
346
            // update status bar
347
            $("#status li").removeClass("active").eq(i).addClass("active");
348
    });
349

350
    // if tab is pressed on the next button seek to next page
351
    root.find("button.next").keydown(function(e) {
352
            if (e.keyCode == 9) {
353
                    // seeks to next tab by executing our validation routine
354
                    api.next();
355
                    e.preventDefault();
356
            }
357
    });
358
});
359

360
// sliders for selecting VM flavor
361
$(":range").rangeinput({progress:true});
362

363
// disable sliders in flavor selection
364
function disableSliders() {
365
    $("#cpu").attr('disabled',true);
366
    $("#ram").attr('disabled',true);
367
    $("#storage").attr('disabled',true);
368
}
369

370
// selecting the small size
371
$("#small").click(function(){
372
    $("#cpu").data('rangeinput').setValue(1);
373
    $("#ram").data('rangeinput').setValue(256);
374
    $("#storage").data('rangeinput').setValue(5);
375
});
376

377
// selecting the medium size
378
$("#medium").click(function(){
379
    $("#cpu").data('rangeinput').setValue(4);
380
    $("#ram").data('rangeinput').setValue(1024);
381
    $("#storage").data('rangeinput').setValue(30);
382
});
383

384
// selecting the large size
385
$("#large").click(function(){
386
    $("#cpu").data('rangeinput').setValue(8);
387
    $("#ram").data('rangeinput').setValue(4096);
388
    $("#storage").data('rangeinput').setValue(80);
389
});
390

391
// selecting the custom flavor enables the sliders
392
$("#custom").click(function(){
393
    $("#cpu").attr('disabled',false);
394
    $("#ram").attr('disabled',false);
395
    $("#storage").attr('disabled',false);
396
    $("strong.sliders").style = 'color: #778899;';
397
});
398

399
// get cpu value for custom flavor
400
$("#cpu").change(function(){
401
    $("#custom").click();
402
});
403

404
// get ram value for custom flavor
405
$("#ram").change(function(){
406
    $("#custom").click();
407
});
408

409
// get storage value for custom flavor
410
$("#storage").change(function(){
411
    $("#custom").click();
412
});
413

414
// exit the wizard
415
$("#cancel").click(function(){
416
    $("a#create[rel]").overlay().close();
417
});
418

419
// starting a new VM through the wizard
420
$("#start").click(function(){
421
    // send create call
422
    $.ajax({
423
    url: '/api/v1.0/servers',
424
    type: "POST",
425
    data: {
426
        "create": {"foo" : "foo"}
427
        },
428
    //TODO: get the real data
429
    //async: false,
430
    dataType: "json",
431
    success: function() {}
432
    });
433
    // bring up notification
434
    var triggers = $("a#notify").overlay({
435
            // some mask tweaks suitable for modal dialogs
436
            mask: {
437
                    color: '#ebecff',
438
                    opacity: '0.9'
439
            },
440
        top: 'center',
441
            closeOnClick: false,
442
        oneInstance: false,
443
        load: true,
444
        onClose: function(){
445
            $("div.pane#machines-pane").load($("a#standard").attr("href"));
446
        }
447
    });
448
    $("#wizard").hide();
449
    update();
450
});
451

452
// generate notification after completing all wizard steps
453
$(function() { 
454
    $("a#create[rel]").overlay({
455
        mask: '#000', 
456
        effect: 'default', 
457
        top: '5%', 
458
        oneInstance: false,
459
        closeOnClick: false
460
    });
461
});
462

463
// reboot action
464
$("div.actions a.action-reboot").live('click', function(){
465
    var serverID = $(this).parent().parent().attr("id");
466
    $.ajax({
467
            url: '/api/v1.0/servers/' + serverID + '/action',
468
            type: "POST",
469
            data: {
470
                    "reboot": '{"type" : "HARD"}'
471
                    },
472
            //async: false,
473
            dataType: "json",
474
            success: function() {}
475
    });
476
});
477

478
// shutdown action
479
$("div.actions a.action-shutdown").live('click', function(){
480
    var serverID = $(this).parent().parent().attr("id");
481
        $.ajax({
482
                url: '/api/v1.0/servers/' + serverID + '/action',
483
                type: "POST",
484
                data: {
485
                        "shutdown": '{"timeout" : "5"}'
486
                        },
487
                //async: false,
488
                dataType: "json",
489
                success: function() {}
490
        });
491
});
492
</script>