Revision 43df43aa

b/locale/el/LC_MESSAGES/django.po
7 7
msgstr ""
8 8
"Project-Id-Version: PACKAGE VERSION\n"
9 9
"Report-Msgid-Bugs-To: \n"
10
"POT-Creation-Date: 2011-01-19 11:26+0200\n"
10
"POT-Creation-Date: 2011-01-19 17:39+0200\n"
11 11
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12 12
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 13
"Language-Team: LANGUAGE <LL@li.org>\n"
......
26 26

  
27 27
#: ui/templates/home.html:29
28 28
msgid "manage your virtual machines"
29
msgstr ""
29
msgstr "διαχειριστείτε τις εικονικές μηχανές σας"
30 30

  
31 31
#: ui/templates/home.html:29
32
msgid "instances"
33
msgstr ""
32
msgid "machines"
33
msgstr "μηχανές"
34 34

  
35 35
#: ui/templates/home.html:30
36 36
msgid "manage your storage volumes"
37 37
msgstr "διαχειριστείτε το χώρο σας"
38 38

  
39
#: ui/templates/home.html:30 ui/templates/instances.html:31
39
#: ui/templates/home.html:30 ui/templates/machines.html:31
40 40
msgid "disks"
41 41
msgstr "δίσκοι"
42 42

  
......
52 52
msgid "configure networking"
53 53
msgstr ""
54 54

  
55
#: ui/templates/home.html:32 ui/templates/instances.html:31
55
#: ui/templates/home.html:32 ui/templates/machines.html:31
56 56
msgid "networks"
57 57
msgstr "δίκτυα"
58 58

  
59
#: ui/templates/instances.html:5
59
#: ui/templates/machines.html:5
60 60
msgid "Create New +"
61 61
msgstr "Δημιουργία +"
62 62

  
63
#: ui/templates/instances.html:17
63
#: ui/templates/machines.html:17
64 64
msgid "Running"
65 65
msgstr "Τρέχουν"
66 66

  
67
#: ui/templates/instances.html:31
67
#: ui/templates/machines.html:31
68 68
msgid "Show:"
69 69
msgstr "Δείξε:"
70 70

  
71
#: ui/templates/instances.html:31
71
#: ui/templates/machines.html:31
72 72
msgid "group"
73 73
msgstr "γκρουπ"
74 74

  
75
#: ui/templates/instances.html:34
75
#: ui/templates/machines.html:34
76 76
msgid "Reboot"
77 77
msgstr "Επανεκκίνηση"
78 78

  
79
#: ui/templates/instances.html:35
79
#: ui/templates/machines.html:35
80 80
msgid "Shutdown"
81 81
msgstr "Κλείσιμο"
82 82

  
83
#: ui/templates/instances.html:36
83
#: ui/templates/machines.html:36
84 84
msgid "more"
85 85
msgstr "περισσότερα"
86 86

  
87
#: ui/templates/instances.html:54
87
#: ui/templates/machines.html:54
88 88
msgid "Image"
89 89
msgstr ""
90 90

  
91
#: ui/templates/instances.html:55
91
#: ui/templates/machines.html:55
92 92
msgid "Instance"
93 93
msgstr ""
94 94

  
95
#: ui/templates/instances.html:56
95
#: ui/templates/machines.html:56
96 96
msgid "Review"
97 97
msgstr ""
98 98

  
99
#: ui/templates/instances.html:62
99
#: ui/templates/machines.html:62
100 100
msgid "Select an OS"
101 101
msgstr "Επιλέξτε ένα ΛΣ"
102 102

  
103
#: ui/templates/instances.html:64
103
#: ui/templates/machines.html:64
104 104
msgid "standard"
105 105
msgstr ""
106 106

  
107
#: ui/templates/instances.html:65 ui/templates/instances.html.py:117
107
#: ui/templates/machines.html:65 ui/templates/machines.html.py:117
108 108
msgid "custom"
109 109
msgstr ""
110 110

  
111
#: ui/templates/instances.html:89
111
#: ui/templates/machines.html:89
112 112
msgid "Cancel"
113 113
msgstr "Άκυρο"
114 114

  
115
#: ui/templates/instances.html:90 ui/templates/instances.html.py:140
115
#: ui/templates/machines.html:90 ui/templates/machines.html.py:140
116 116
msgid "Next"
117 117
msgstr "Επόμενο"
118 118

  
119
#: ui/templates/instances.html:93
119
#: ui/templates/machines.html:93
120 120
msgid "Select CPU, RAM and storage"
121 121
msgstr "Επιλέξτε CPU, μνήμη και αποθηκευτικό χώρο"
122 122

  
123
#: ui/templates/instances.html:99
123
#: ui/templates/machines.html:99
124 124
msgid "small"
125 125
msgstr "μικρό"
126 126

  
127
#: ui/templates/instances.html:105
127
#: ui/templates/machines.html:105
128 128
msgid "medium"
129 129
msgstr "μεσαίο"
130 130

  
131
#: ui/templates/instances.html:111
131
#: ui/templates/machines.html:111
132 132
msgid "large"
133 133
msgstr "μεγάλο"
134 134

  
135
#: ui/templates/instances.html:135 ui/templates/instances.html.py:164
135
#: ui/templates/machines.html:135 ui/templates/machines.html.py:164
136 136
msgid "Cost per hour:"
137 137
msgstr "Κόστος ανά ώρα:"
138 138

  
139
#: ui/templates/instances.html:135 ui/templates/instances.html.py:164
139
#: ui/templates/machines.html:135 ui/templates/machines.html.py:164
140 140
msgid "credits"
141 141
msgstr "μονάδες"
142 142

  
143
#: ui/templates/instances.html:135
143
#: ui/templates/machines.html:135
144 144
msgid "Credits currently in account:"
145 145
msgstr "Μονάδες στο λογαριασμό:"
146 146

  
147
#: ui/templates/instances.html:139 ui/templates/instances.html.py:170
147
#: ui/templates/machines.html:139 ui/templates/machines.html.py:170
148 148
msgid "Back"
149 149
msgstr "Πίσω"
150 150

  
151
#: ui/templates/instances.html:143
151
#: ui/templates/machines.html:143
152 152
msgid "Confirm your settings"
153 153
msgstr "Επιβεβαιώστε τις ρυθμίσεις"
154 154

  
155
#: ui/templates/instances.html:152
155
#: ui/templates/machines.html:152
156 156
msgid "Image:"
157 157
msgstr ""
158 158

  
159
#: ui/templates/instances.html:155
159
#: ui/templates/machines.html:155
160 160
msgid "CPU:"
161 161
msgstr ""
162 162

  
163
#: ui/templates/instances.html:158
163
#: ui/templates/machines.html:158
164 164
msgid "RAM:"
165 165
msgstr ""
166 166

  
167
#: ui/templates/instances.html:161
167
#: ui/templates/machines.html:161
168 168
msgid "Storage:"
169 169
msgstr ""
170 170

  
171
#: ui/templates/instances.html:167
171
#: ui/templates/machines.html:167
172 172
msgid "Remaining credits:"
173 173
msgstr "Μονάδες που απομένουν:"
174 174

  
175
#: ui/templates/instances.html:171
175
#: ui/templates/machines.html:171
176 176
msgid "Create VM"
177 177
msgstr "Δημιουργία VM"
178 178

  
179
#: ui/templates/instances.html:179
179
#: ui/templates/machines.html:179
180 180
msgid "Your password is:"
181 181
msgstr "Ο κωδικός σας είναι:"
182 182

  
183
#: ui/templates/instances.html:180
183
#: ui/templates/machines.html:180
184 184
msgid "Please copy this! Without it you can not connect to your VM."
185
msgstr "Παρακαλώ αντιγράψτε τον κωδικό! Χωρίς αυτό δεν θα μπορείτε να συνδεθείτε στο VM"
185
msgstr ""
186
"Παρακαλώ αντιγράψτε τον κωδικό! Χωρίς αυτό δεν θα μπορείτε να συνδεθείτε στο "
187
"VM"
b/ui/static/main.css
92 92
    top: 7px;
93 93
}
94 94

  
95
ul.css-tabs a#instances {
95
ul.css-tabs a#machines {
96 96
    color: #a3bbc5;
97 97
}
98 98

  
99
ul.css-tabs a#instances.current {
99
ul.css-tabs a#machines.current {
100 100
  color: #87aade;
101 101
}
102 102

  
......
682 682
    margin-bottom: 17px;
683 683
}
684 684

  
685
div.list#instancesview {
685
div.list#machinesview {
686 686
min-height: 270px; 
687 687
}
688 688

  
b/ui/templates/home.html
26 26
        </div>
27 27
        <!-- tabs -->
28 28
        <ul class="css-tabs">
29
	        <li><a href="instances" title="{% trans "manage your virtual machines" %}" id="instances">{% trans "instances" %}</a></li>
29
	        <li><a href="machines" title="{% trans "manage your virtual machines" %}" id="machines">{% trans "machines" %}</a></li>
30 30
	        <li><a href="disks" title="{% trans "manage your storage volumes" %}" id="disks">{% trans "disks" %}</a></li>
31 31
	        <li><a href="images" title="{% trans "manage boot images" %}" id="images">{% trans "images" %}</a></li>
32 32
	        <li><a href="networks" title="{% trans "configure networking" %}" id="networks">{% trans "networks" %}</a></li>
33 33
        </ul>
34 34
        <div class="css-panes">
35
	        <div id="instances-pane" class="pane" style="display:block">{% include "instances.html" %}</div>
35
	        <div id="machines-pane" class="pane" style="display:block">{% include "machines.html" %}</div>
36 36
	        <div id="disks-pane" class="pane"></div>
37 37
	        <div id="images-pane" class="pane"></div>
38 38
	        <div id="networks-pane" class="pane"></div>
/dev/null
1
{% load i18n %}
2

  
3
<div id="instances" 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="/instances">#</a>
9
    <span class="view-seperator">|</span>
10
    <a id="list" href="/instances/list">=</a>
11
</div>
12

  
13
<div id="instancesview" class="standard">
14

  
15
    <div class="instance" id="instance-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="path/to/logos" />
24
        <a href="#" class="name">
25
            <h5>Hostname: <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">{% trans "Reboot" %}</a>
35
            <a href="#" class="action">{% 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="instances" 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 "Instance" %}</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="static/os_logos/image.logo" 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="instance-type">
97
                            <label for="small">
98
                                <input type="radio" id="small" name="instance-type" value="small" checked="true" />
99
                                <strong>{% trans "small" %}</strong>
100
                            </label>
101
                        </div>
102
                        <div class="instance-type">      
103
                            <label for="medium">
104
                                <input type="radio" id="medium" name="instance-type" value="medium" />                  
105
                                <strong>{% trans "medium" %}</strong>
106
                            </label>
107
                        </div>
108
                        <div class="instance-type">
109
                            <label for="large">
110
                                <input type="radio" id="large" name="instance-type" value="large" />
111
                                <strong>{% trans "large" %}</strong>
112
                            </label>
113
                        </div>
114
                        <div class="instance-type">
115
                            <label for="custom">
116
                                <input type="radio" name="instance-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>Instance name</strong>
148
                            <input type="text" class="text" name="instance_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
// <![CDATA[ 
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
function update() {
202

  
203
    $("div.running").text('');
204
    $("div.terminated").text('');
205
    $("ul#standard-images").text('');
206
    $("ul#custom-images").text('');
207

  
208
    $.ajax({
209
        url: '/api/v1.0/servers/detail',
210
        type: "GET",
211
    //    async: false,
212
        dataType: "json",
213
        success: function(data) {
214
            $.each(data.servers, function(i,server){
215
                var instance = $('#instance-template').clone().attr("id",server.id).fadeIn("slow");
216
                instance.find("a.name span.name").text(server.name);
217
                instance.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'.png');
218
                instance.find("img.list-logo").attr("src","static/os_logos/"+image_tags[server.imageId]+'.png');
219
                instance.find("a.ip span.public").text(String(server.addresses.public));            
220

  
221
                if (server.status == 'BUILD'){
222
                    instance.find("div.status").text('Building');
223
                    instance.appendTo("div.running");
224
                } else if (server.status == 'ACTIVE') {
225
                    instance.find("div.status").text('Running');
226
                    instance.appendTo("div.running");
227
                } else if (server.status == 'SUSPENDED') {
228
                    instance.find("div.status").text('Terminated');
229
                    instance.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'-off.png');
230
                    instance.appendTo("div.terminated");
231
                    $("#mini.seperator").fadeIn("slow");
232
                } else {
233
                    instance.find("div.status").text('Unknown');
234
                    instance.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'-off.png');
235
                    instance.appendTo("div.terminated");
236
                }
237

  
238

  
239
            });
240
        }
241
    });
242

  
243
    $.ajax({
244
        url: '/api/v1.0/images/detail',
245
        type: "GET",
246
    //    async: false,
247
        dataType: "json",
248
        success: function(data) {
249
            $.each(data.images, function(i,image){
250
                var img = $('#image-template').clone().attr("id","img-"+image.id).fadeIn("slow");
251
                img.find("label").attr('for',"img-radio-" + image.id);
252
                img.find(".image-title").text(image.name);
253
                img.find("input.radio").attr('id',"img-radio-" + image.id);
254
                if (i==0) img.find("input.radio").attr("checked","checked"); 
255
                img.find("img.image-logo").attr('src','static/os_logos/'+image_tags[image.id]+'.png');
256
                if (image.serverId) {
257
                    img.appendTo("ul#custom-images");
258
                } else {
259
                    img.appendTo("ul#standard-images");
260
                }
261
            });
262
        }
263
    });
264
}
265
update();
266
$("#list").click(function(event){
267
    $("div.standard#instancesview").load($("#list").attr("href"));
268
    $("a#standard")[0].className += ' activelink'
269
    this.style.color = '#5f8dd3';
270
    update(); 
271
    return false;
272
});
273

  
274
$("a#standard").click(function(event){
275
    href=$("a#standard").attr("href");
276
    $("div.pane#instances-pane").load(href);
277
    //$("a#standard")[0].className += ' activelink'
278
    //this.style.color = '#5f8dd3';
279
    return false;
280
});
281

  
282
$("ul.tabs").tabs("div.panes ul");
283

  
284
$(":range").rangeinput({progress:true});
285

  
286
function disableSliders() {
287
    $("#cpu").attr('disabled',true);
288
    $("#ram").attr('disabled',true);
289
    $("#storage").attr('disabled',true);
290
}
291

  
292
$("#custom").click(function(event){
293
    $("#cpu").attr('disabled',false);
294
    $("#ram").attr('disabled',false);
295
    $("#storage").attr('disabled',false);
296
    $("strong.sliders").style = 'color: #778899;';
297
});
298

  
299
$("#small").click(function(event){
300
    $("#cpu").data('rangeinput').setValue(1);
301
    $("#ram").data('rangeinput').setValue(256);
302
    $("#storage").data('rangeinput').setValue(5);
303
});
304

  
305
$("#medium").click(function(event){
306
    $("#cpu").data('rangeinput').setValue(4);
307
    $("#ram").data('rangeinput').setValue(1024);
308
    $("#storage").data('rangeinput').setValue(30);
309
});
310

  
311
$("#large").click(function(event){
312
    $("#cpu").data('rangeinput').setValue(8);
313
    $("#ram").data('rangeinput').setValue(4096);
314
    $("#storage").data('rangeinput').setValue(80);
315
});
316

  
317
$("#cancel").click(function(event){
318
    $("a#create[rel]").overlay().close();
319
});
320

  
321
$("#start").click(function(event){
322
    var triggers = $("a#notify").overlay({
323
	    // some mask tweaks suitable for modal dialogs
324
	    mask: {
325
		    color: '#ebecff',
326
		    opacity: '0.9'
327
	    },
328
        top: 'center',
329
	    closeOnClick: false,
330
        oneInstance: false,
331
        load: true,
332
        onClose: function(event){
333
            $("div.pane#instances-pane").load($("a#standard").attr("href"));
334
        }
335
    });
336
    $("#wizard").hide();
337
    update();
338
});
339

  
340
$("a#create").click(function(event){
341
    $("#wizard").scrollable().begin();
342
});
343

  
344
$("#cpu").change(function(event){
345
    $("#custom").click();
346
});
347

  
348
$("#ram").change(function(event){
349
    $("#custom").click();
350
});
351

  
352
$("#storage").change(function(event){
353
    $("#custom").click();
354
});
355

  
356
$(function() { 
357
    $("a#create[rel]").overlay({mask: '#000', effect: 'default', top: '5%', oneInstance: false, closeOnClick: false});
358
});
359

  
360
$(function() {
361
    var root = $("#wizard").scrollable();
362

  
363
    // some variables that we need
364
    var api = root.scrollable();
365

  
366
    // rangeinput with default configuration
367
    // validation logic is done inside the onBeforeSeek callback
368
    api.onBeforeSeek(function(event, i) {
369
	    // we are going 1 step backwards so no need for validation
370
	    if (api.getIndex() < i) {
371
             // 1. get current page
372
		     var page = root.find(".page").eq(api.getIndex()),
373
			 // 2. .. and all required fields inside the page
374
			 inputs = page.find(".required :input").removeClass("error"),
375
			 // 3. .. which are empty
376
			 empty = inputs.filter(function() {
377
				return $(this).val().replace(/\s*/g, '') == '';
378
			 });
379
		     // if there are empty fields, then
380
		    if (empty.length) {
381
			    // add a CSS class name "error" for empty & required fields
382
			    empty.addClass("error");
383
			    // cancel seeking of the scrollable by returning false
384
			    return false;
385
		    // everything is good
386
		    } 
387
	    }
388
	    // update status bar
389
	    $("#status li").removeClass("active").eq(i).addClass("active");
390
    });
391

  
392
    // if tab is pressed on the next button seek to next page
393
    root.find("button.next").keydown(function(e) {
394
	    if (e.keyCode == 9) {
395
		    // seeks to next tab by executing our validation routine
396
		    api.next();
397
		    e.preventDefault();
398
	    }
399
    });
400
// ]]>
401
});
402
</script>
403

  
b/ui/templates/list.html
1
<div id="instancesview" class="list">
1
<div id="machinesview" class="list">
2 2

  
3 3
    <div class="actions">
4 4
        <a>Start</a>
b/ui/templates/machines.html
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

  
15
    <div class="instance" id="instance-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="path/to/logos" />
24
        <a href="#" class="name">
25
            <h5>Hostname: <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">{% trans "Reboot" %}</a>
35
            <a href="#" class="action">{% 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 "Instance" %}</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="static/os_logos/image.logo" 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="instance-type">
97
                            <label for="small">
98
                                <input type="radio" id="small" name="instance-type" value="small" checked="true" />
99
                                <strong>{% trans "small" %}</strong>
100
                            </label>
101
                        </div>
102
                        <div class="instance-type">      
103
                            <label for="medium">
104
                                <input type="radio" id="medium" name="instance-type" value="medium" />                  
105
                                <strong>{% trans "medium" %}</strong>
106
                            </label>
107
                        </div>
108
                        <div class="instance-type">
109
                            <label for="large">
110
                                <input type="radio" id="large" name="instance-type" value="large" />
111
                                <strong>{% trans "large" %}</strong>
112
                            </label>
113
                        </div>
114
                        <div class="instance-type">
115
                            <label for="custom">
116
                                <input type="radio" name="instance-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>Instance name</strong>
148
                            <input type="text" class="text" name="instance_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
// <![CDATA[ 
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
function update() {
202

  
203
    $("div.running").text('');
204
    $("div.terminated").text('');
205
    $("ul#standard-images").text('');
206
    $("ul#custom-images").text('');
207

  
208
    $.ajax({
209
        url: '/api/v1.0/servers/detail',
210
        type: "GET",
211
    //    async: false,
212
        dataType: "json",
213
        success: function(data) {
214
            $.each(data.servers, function(i,server){
215
                var instance = $('#instance-template').clone().attr("id",server.id).fadeIn("slow");
216
                instance.find("a.name span.name").text(server.name);
217
                instance.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'.png');
218
                instance.find("img.list-logo").attr("src","static/os_logos/"+image_tags[server.imageId]+'.png');
219
                instance.find("a.ip span.public").text(String(server.addresses.public));            
220

  
221
                if (server.status == 'BUILD'){
222
                    instance.find("div.status").text('Building');
223
                    instance.appendTo("div.running");
224
                } else if (server.status == 'ACTIVE') {
225
                    instance.find("div.status").text('Running');
226
                    instance.appendTo("div.running");
227
                } else if (server.status == 'SUSPENDED') {
228
                    instance.find("div.status").text('Terminated');
229
                    instance.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'-off.png');
230
                    instance.appendTo("div.terminated");
231
                    $("#mini.seperator").fadeIn("slow");
232
                } else {
233
                    instance.find("div.status").text('Unknown');
234
                    instance.find("img.logo").attr("src","static/machines/"+image_tags[server.imageId]+'-off.png');
235
                    instance.appendTo("div.terminated");
236
                }
237

  
238

  
239
            });
240
        }
241
    });
242

  
243
    $.ajax({
244
        url: '/api/v1.0/images/detail',
245
        type: "GET",
246
    //    async: false,
247
        dataType: "json",
248
        success: function(data) {
249
            $.each(data.images, function(i,image){
250
                var img = $('#image-template').clone().attr("id","img-"+image.id).fadeIn("slow");
251
                img.find("label").attr('for',"img-radio-" + image.id);
252
                img.find(".image-title").text(image.name);
253
                img.find("input.radio").attr('id',"img-radio-" + image.id);
254
                if (i==0) img.find("input.radio").attr("checked","checked"); 
255
                img.find("img.image-logo").attr('src','static/os_logos/'+image_tags[image.id]+'.png');
256
                if (image.serverId) {
257
                    img.appendTo("ul#custom-images");
258
                } else {
259
                    img.appendTo("ul#standard-images");
260
                }
261
            });
262
        }
263
    });
264
}
265
update();
266
$("#list").click(function(event){
267
    $("div.standard#machinesview").load($("#list").attr("href"));
268
    $("a#standard")[0].className += ' activelink'
269
    this.style.color = '#5f8dd3';
270
    update(); 
271
    return false;
272
});
273

  
274
$("a#standard").click(function(event){
275
    href=$("a#standard").attr("href");
276
    $("div.pane#machines-pane").load(href);
277
    //$("a#standard")[0].className += ' activelink'
278
    //this.style.color = '#5f8dd3';
279
    return false;
280
});
281

  
282
$("ul.tabs").tabs("div.panes ul");
283

  
284
$(":range").rangeinput({progress:true});
285

  
286
function disableSliders() {
287
    $("#cpu").attr('disabled',true);
288
    $("#ram").attr('disabled',true);
289
    $("#storage").attr('disabled',true);
290
}
291

  
292
$("#custom").click(function(event){
293
    $("#cpu").attr('disabled',false);
294
    $("#ram").attr('disabled',false);
295
    $("#storage").attr('disabled',false);
296
    $("strong.sliders").style = 'color: #778899;';
297
});
298

  
299
$("#small").click(function(event){
300
    $("#cpu").data('rangeinput').setValue(1);
301
    $("#ram").data('rangeinput').setValue(256);
302
    $("#storage").data('rangeinput').setValue(5);
303
});
304

  
305
$("#medium").click(function(event){
306
    $("#cpu").data('rangeinput').setValue(4);
307
    $("#ram").data('rangeinput').setValue(1024);
308
    $("#storage").data('rangeinput').setValue(30);
309
});
310

  
311
$("#large").click(function(event){
312
    $("#cpu").data('rangeinput').setValue(8);
313
    $("#ram").data('rangeinput').setValue(4096);
314
    $("#storage").data('rangeinput').setValue(80);
315
});
316

  
317
$("#cancel").click(function(event){
318
    $("a#create[rel]").overlay().close();
319
});
320

  
321
$("#start").click(function(event){
322
    var triggers = $("a#notify").overlay({
323
	    // some mask tweaks suitable for modal dialogs
324
	    mask: {
325
		    color: '#ebecff',
326
		    opacity: '0.9'
327
	    },
328
        top: 'center',
329
	    closeOnClick: false,
330
        oneInstance: false,
331
        load: true,
332
        onClose: function(event){
333
            $("div.pane#machines-pane").load($("a#standard").attr("href"));
334
        }
335
    });
336
    $("#wizard").hide();
337
    update();
338
});
339

  
340
$("a#create").click(function(event){
341
    $("#wizard").scrollable().begin();
342
});
343

  
344
$("#cpu").change(function(event){
345
    $("#custom").click();
346
});
347

  
348
$("#ram").change(function(event){
349
    $("#custom").click();
350
});
351

  
352
$("#storage").change(function(event){
353
    $("#custom").click();
354
});
355

  
356
$(function() { 
357
    $("a#create[rel]").overlay({mask: '#000', effect: 'default', top: '5%', oneInstance: false, closeOnClick: false});
358
});
359

  
360
$(function() {
361
    var root = $("#wizard").scrollable();
362

  
363
    // some variables that we need
364
    var api = root.scrollable();
365

  
366
    // rangeinput with default configuration
367
    // validation logic is done inside the onBeforeSeek callback
368
    api.onBeforeSeek(function(event, i) {
369
	    // we are going 1 step backwards so no need for validation
370
	    if (api.getIndex() < i) {
371
             // 1. get current page
372
		     var page = root.find(".page").eq(api.getIndex()),
373
			 // 2. .. and all required fields inside the page
374
			 inputs = page.find(".required :input").removeClass("error"),
375
			 // 3. .. which are empty
376
			 empty = inputs.filter(function() {
377
				return $(this).val().replace(/\s*/g, '') == '';
378
			 });
379
		     // if there are empty fields, then
380
		    if (empty.length) {
381
			    // add a CSS class name "error" for empty & required fields
382
			    empty.addClass("error");
383
			    // cancel seeking of the scrollable by returning false
384
			    return false;
385
		    // everything is good
386
		    } 
387
	    }
388
	    // update status bar
389
	    $("#status li").removeClass("active").eq(i).addClass("active");
390
    });
391

  
392
    // if tab is pressed on the next button seek to next page
393
    root.find("button.next").keydown(function(e) {
394
	    if (e.keyCode == 9) {
395
		    // seeks to next tab by executing our validation routine
396
		    api.next();
397
		    e.preventDefault();
398
	    }
399
    });
400
// ]]>
401
});
402
</script>
403

  
b/ui/urls.py
3 3

  
4 4
urlpatterns = patterns('',
5 5
    (r'^$', 'synnefo.ui.views.home'),
6
    (r'^instances$', 'synnefo.ui.views.instances'),
7
    (r'^alt-instances$', 'synnefo.ui.views.alt_instances'),
8
    (r'^instances/list$', 'synnefo.ui.views.instances_list'),
6
    (r'^machines$', 'synnefo.ui.views.machines'),
7
    (r'^machines/list$', 'synnefo.ui.views.machines_list'),
9 8
    (r'^disks$', 'synnefo.ui.views.disks'),
10 9
    (r'^images$', 'synnefo.ui.views.images'),
11 10
    (r'^networks$', 'synnefo.ui.views.networks'),
b/ui/views.py
15 15
    context = { 'project' : '+nefo', 'request': request, 'current_lang' : get_language() or 'en' }
16 16
    return template('home', context)
17 17

  
18
def instances(request):
18
def machines(request):
19 19
    context = {}
20
    return template('instances', context)
20
    return template('machines', context)
21 21
   
22
def instances_list(request):
22
def machines_list(request):
23 23
    context = {}
24 24
    return template('list', context)
25 25

  

Also available in: Unified diff