Commit 5dc7a813 authored by Vassilios Karakoidas's avatar Vassilios Karakoidas
Browse files

Merge branch 'master' into logic-refactoring

Conflicts:
	README
parents f87aed2a e941164c
Synnefo
README
=======
Installation
------------
$ sudo easy_install virtualenv
....
$ git clone https://user@code.grnet.gr/git/synnefo synnefo
$ virtualenv --python=python2.6 synnefo --no-site-packages
...
$ cd synnefo
$ ./bin/pip install django django-piston pycurl simplejson selenium pyzmq-static
...
...
$ cp settings.py.dist settings.py
$ ./bin/python manage.py syncdb
$ cd db
$ ../bin/python db_controller.py
...
$ cd synnefo
$ ./bin/python manage.py runserver
This is the top-level documentation file for the Synnefo cloud management
web application.
Notes
------
1) On ubuntu systems:
sudo aptitude install libcurl3-gnutls libcurl3-gnutls-dev
Consult:
-README.develop: for information on how to setup a development environment
-README.deploy : for information on how to deploy the application
-README.i18n : for information on application internationalization
2) jQuery.ajax POST is not working unless you edit lib/python2.6/site-packages/piston/utils.py.
On def content_type change:
ctype = self.request.META.get('CONTENT_TYPE', type_formencoded)
to
ctype = self.request.META.get('CONTENT_TYPE', type_formencoded).split(";")[0]
3) On Ubuntu 10.04 (tested by mgogoulos) you'll have to install zmq-static with:
sudo aptitude install uuid-dev
./bin/pip install pyzmq-static
4) Also see README.DB, which describes setting up a DB with various backends.
5) The checkout directory name "synnefo" is mandatory
6) For Mac computers with Snow Leopard, you may have a problem installing pycurl. Remember to set 64-bit arch when you install it.
env ARCHFLAGS="-arch x86_64" ./bin/pip install pycurl
Testing
License
-------
The functional ui tests require the Selenium server and the synnefo app to be running.
$ wget http://selenium.googlecode.com/files/selenium-server-standalone-2.0b2.jar
$ java -jar selenium-server-standalone-2.0b2.jar &
$ ./bin/python manage.py runserver &
$ ./bin/python manage.py test ui
Test coverage
=============
In order to get code coverage reports you need to install django-test-coverage
$ ./bin/pip install django-test-coverage
Cloud is distributed under the terms of ....
Then edit your settings.py and configure the test runner:
The application source code is under copyright
TEST_RUNNER = 'django-test-coverage.runner.run_tests'
Copyright 2010 Greek Research and Technology Network
*** SQLite
Django configuration in ettings.py:
PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) + '/'
DATABASES = {
'default': {
'ENGINE': 'sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
# ATTENTION: This *must* be the absolute path if using sqlite3.
# See: http://docs.djangoproject.com/en/dev/ref/settings/#name
'NAME': PROJECT_PATH + 'database.sqlite' # Or path to database file if using sqlite3.
}
}
Database initialization:
[the following commands assume the DB is at "./database.sqlite"]
recreate db, load db/fixtures/initial_data.json:
$ rm database.sqlite
$ bin/python manage.py syncdb
load fixtures, as necessary [take a look under db/fixtures/]:
$ bin/python manage.py loaddata db/fixtures/flavors.json
$ bin/python manage.py loaddata db/fixtures/vms.json
...
*** MySQL
Django configuration in settings.py:
DATABASES = {
'default': {
'ENGINE': 'mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
# ATTENTION: This *must* be the absolute path if using sqlite3.
# See: http://docs.djangoproject.com/en/dev/ref/settings/#name
'NAME': 'synnefo', # Or path to database file if using sqlite3.
'USER': 'USERNAME', # Not used with sqlite3.
'PASSWORD': 'PASSWORD', # Not used with sqlite3.
'HOST': 'HOST', # Set to empty string for localhost. Not used with sqlite3.
'PORT': 'PORT', # Set to empty string for default. Not used with sqlite3.
# Have MySQL use InnoDB as the storage engine for newly created tables
'OPTIONS': {
'init_command': 'SET storage_engine=INNODB',
}
}
}
Server setup [not necessary for client operation]:
a) Install MySQL server, set password for user 'root'
b) Modify /etc/mysql/my.cnf to bind on public IP if you want to allow
allow connections from foreign hosts.
c) Create database:
$ mysql -u root -p
mysql> create database synnefo;
mysql> show databases;
mysql> GRANT ALL on synnefo.* TO username IDENTIFIED BY 'password';
Client setup:
d) Install the MySQL client
# apt-get install libmysqlclient-dev
$ bin/pip install MySQL-python
libmysqlclient-dev provides mysql_config, otherwise installing MySQL-python fails with:
EnvironmentError: mysql_config not found
*** PostgreSQL
Django configuration in settings.py:
DATABASES = {
'default': {
'ENGINE': 'postgresql_psycopg2', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
# ATTENTION: This *must* be the absolute path if using sqlite3.
# See: http://docs.djangoproject.com/en/dev/ref/settings/#name
'NAME': 'DATABASE', # Or path to database file if using sqlite3.
'USER': 'USERNAME', # Not used with sqlite3.
'PASSWORD': 'PASSWORD', # Not used with sqlite3.
'HOST': 'HOST', # Set to empty string for localhost. Not used with sqlite3.
'PORT': 'PORT', # Set to empty string for default. Not used with sqlite3.
}
}
Client setup:
# apt-get install postgresql-client-8.4
attempt a connection:
$ psql -h HOST -p PORT -U USERNAME
# apt-get install libpq-dev
$ bin/pip install psycopg2
......@@ -5,7 +5,7 @@ Dependencies
Synnefo depends on the following Python modules
- django
- django 1.2
- django-piston
- simplejson
- selenium
......@@ -15,6 +15,18 @@ also, depending on the database engine of choice, on one of the following:
- MySQL-python
- psycopg2
Temporary fix - to be removed soon
----------------------------------
After going through the installation instructions below, the following fix must
be applied.
jQuery.ajax POST is not working unless you edit lib/python2.6/site-packages/piston/utils.py.
On def content_type change:
ctype = self.request.META.get('CONTENT_TYPE', type_formencoded)
to
ctype = self.request.META.get('CONTENT_TYPE', type_formencoded).split(";")[0]
Preparing the development environment
-------------------------------------
......@@ -43,7 +55,7 @@ that python is already installed on the host.
$ cd synnefo
$ ./bin/pip install django django-piston pycurl simplejson selenium pyzmq-static
2. At this point you should have all required dependencies installed. Now you
3. At this point you should have all required dependencies installed. Now you
have to select a database engine. The choices are: postgres, mysql and sqlite.
-SQLite
......@@ -91,15 +103,29 @@ Install the postgres Python library
$ bin/pip install psycopg2
Configure a postgres db/account for synnefo
<TODO>
Become the postgres user, connect to PostgreSQL:
$ sudo su - postgres
$ psql
Run the following commands:
DROP DATABASE synnefo;
DROP USER username;
CREATE USER username WITH PASSWORD 'password';
CREATE DATABASE synnefo;
GRANT ALL PRIVILEGES ON DATABASE synnefo TO username;
ALTER DATABASE synnefo OWNER TO username;
ALTER USER username CREATEDB;
The last line enables the newly created user to create own databases. This is
needed for Django to create and drop the test_synnefo database for unit
testing.
3. At this point you should have a working DB. Now configure Django to access it:
4. At this point you should have a working DB. Now configure Django to access it:
Copy the default configuration file
$ cp settings.py.dist settings.py
and then edit according to the database used:
and then copy/edit according to the database used:
-SQLite
......@@ -107,15 +133,15 @@ and then edit according to the database used:
DATABASES = {
'default': {
'ENGINE': 'sqlite3', # ATTENTION: This *must* be the absolute path if using sqlite3.
'NAME': PROJECT_PATH + 'database.sqlite'
'ENGINE': 'django.db.backends.sqlite3',
'NAME': PROJECT_PATH + 'synnefo.db' #WARN: This must be an absolute path
}
}
-MySQL
DATABASES = {
'default': {
'ENGINE': 'mysql',
'ENGINE': 'django.db.backends.mysql',
'NAME': 'synnefo',
'USER': 'USERNAME'
'PASSWORD': 'PASSWORD',
......@@ -131,7 +157,7 @@ and then edit according to the database used:
DATABASES = {
'default': {
'ENGINE': 'postgresql_psycopg2',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'DATABASE',
'USER': 'USERNAME',
'PASSWORD': 'PASSWORD',
......@@ -140,29 +166,37 @@ and then edit according to the database used:
}
}
4. Try it out. The following command will attempt to connec to the DB and
5. Try it out. The following command will attempt to connect to the DB and
print out DDL statements. It should not fail.
$ ./bin/python manage.py sql db
5. Create the DB and (optionally) load test data
6. Create the DB and (optionally) load test data
$ ./bin/python manage.py syncdb
$ ./bin/python manage.py loaddata db/fixtures/flavors.json
$ ./bin/python manage.py loaddata db/fixtures/images.json
The following fictures can be loaded optionally depending on
testing requirements:
$ ./bin/python manage.py loaddata db/fixtures/vms.json
6. Start the system
$ cd db
$ ../bin/python db_controller.py
$ cd ..
$ ./bin/python manage.py runserver
7. Done
$ ./bin/python manage.py loaddata db/fixtures/initial_data.json
$ ./bin/python manage.py loaddata db/fixtures/disks.json
7. Set the BACKEND_PREFIX_ID variable to some unique prefix, e.g. your commit
username
8. Start the system
$ ./bin/python db/db_controller.py #DB synch daemon
$ ./bin/python manage.py runserver #Django
9. (Hopefully) Done
UI Testing
----------
The functional ui tests require the Selenium server and the synnefo app to be running.
The functional ui tests require the Selenium server and the synnefo app to
be running.
$ wget http://selenium.googlecode.com/files/selenium-server-standalone-2.0b2.jar
$ java -jar selenium-server-standalone-2.0b2.jar &
......
......@@ -2,7 +2,6 @@
#
# Copyright © 2010 Greek Research and Technology Network
from django.conf import settings
from django.utils import simplejson as json
from django.http import HttpResponse
from piston.handler import BaseHandler, AnonymousBaseHandler
......@@ -10,7 +9,6 @@ from synnefo.api.faults import fault, noContent, accepted, created, notModified
from synnefo.api.helpers import instance_to_server, paginator
from synnefo.util.rapi import GanetiRapiClient, GanetiApiError, CertificateError
from synnefo.db.models import *
from time import sleep
import random
import string
import logging
......
......@@ -3,7 +3,7 @@ from django import forms
from django.db import models
from django.utils.encoding import iri_to_uri
from django.utils.translation import gettext_lazy as _
from models import *
from synnefo.db.models import *
class LimitForm(forms.ModelForm):
class Meta:
......
......@@ -6,7 +6,7 @@
# Copyright 2010 Greek Research and Technology Network
#
from db.models import *
from synnefo.db.models import VirtualMachine
from logic import credits
......
......@@ -6,7 +6,7 @@
# Copyright 2010 Greek Research and Technology Network
#
from db.models import *
from synnefo.db.models import *
from django.db.models import F
from datetime import datetime
......
......@@ -7,7 +7,6 @@
"created": "2011-02-06 00:00:00",
"updated": "2011-02-06 00:00:00",
"state": "ACTIVE",
"description": "Full Debian Squeeze Installation",
"size": 5678
}
},
......@@ -97,7 +96,6 @@
"created": "2011-02-10 00:00:00",
"updated": "2011-02-10 00:00:00",
"state": "ACTIVE",
"description": "Full Slackware 13.1 Installation",
"size": 1234,
"owner": 1,
"sourcevm": 1001
......
......@@ -6,7 +6,7 @@
from django.core.management.base import NoArgsCommand
from db import bill_calculator
from synnefo.db import bill_calculator
class Command(NoArgsCommand):
help = ''
......
......@@ -6,7 +6,7 @@
from django.core.management.base import NoArgsCommand
from db import charger
from synnefo.db import charger
class Command(NoArgsCommand):
help = 'Charge the users for VM usage'
......
......@@ -6,7 +6,7 @@
from django.core.management.base import NoArgsCommand
from db import credit_allocator
from synnefo.db import credit_allocator
class Command(NoArgsCommand):
help = 'Add credits to users according to their monthly rate'
......
......@@ -6,7 +6,7 @@
from django.core.management.base import NoArgsCommand
from db import db_controller
from synnefo.db import db_controller
class Command(NoArgsCommand):
help = ''
......
......@@ -6,7 +6,7 @@
# Copyright 2010 Greek Research and Technology Network
#
from db.models import *
from synnefo.db.models import *
from django.test import TestCase
......
......@@ -518,7 +518,7 @@ div.machine {
div.machine div.actions {
float: right;
width: 70px;
margin:-60px -70px 0 0;
margin:0px -70px 0 0;
font-weight: normal;
}
......@@ -933,9 +933,11 @@ div.action_error {
}
div.confirm_multiple {
width: 690px;
position: fixed;
bottom: 0;
width: 700px;
height: 30px;
margin: 0 0 10px -30px;
margin: 0 0 0px -36px;
}
div.confirm_multiple p {
......@@ -1085,22 +1087,25 @@ div.list table #selection div.expand-icon {
top: -11px;
}
div.list table thead tr th ul {
ul.dropdown-selector {
background-color: #E6EEEE;
position: absolute;
margin-left: -4px;
margin-left: 1px;
display: block;
top: 255px;
font-size:9pt;
width:40px;
}
div.list table thead tr th ul li {
padding: 5px;
ul.dropdown-selector li {
padding: 4px;
}
div.list table thead tr th ul li:hover {
ul.dropdown-selector li:hover {
background-color: #87AADE;
}
div.list table thead tr th ul li a{
ul.dropdown-selector li a{
color: black;
text-decoration: none;
}
......@@ -1146,7 +1151,10 @@ div.list table thead #name {
}
.wave {
background: url("../static/wave.gif") !important;
border: none;
margin: -5px 0px 0 0px !important;
float:right !important;
clear: both;
}
.hidden {
......
......@@ -15,28 +15,21 @@ function ISODateString(d){
}
function update_confirmations(){
$('div.confirm_single').hide(); // hide all confirm boxes to begin with
// hide all confirm boxes to begin with
$('div.confirm_single').hide();
$('div.confirm_multiple').hide();
// standard view only
if ($.cookie("list") != '1') {
for (i=0;i<pending_actions.length;i++){ // show single confirms
for (i=0;i<pending_actions.length;i++){
// show single confirms
$("div.machine#"+pending_actions[i][1]+' .confirm_single').show();
}
}
if (pending_actions.length>1 || $.cookie("list") == '1' && pending_actions.length == 1){ // if more than one pending action show multiple confirm box
// if more than one pending action show multiple confirm box
if (pending_actions.length>1 || $.cookie("list") == '1' && pending_actions.length == 1){
$('div.confirm_multiple span.actionLen').text(pending_actions.length);
// set the label of the buttons in list view
if ($.cookie("list") == '1') {
$('div.confirm_multiple button.yes').text('Confirm');
$('div.confirm_multiple button.no').text('Cancel');
}
// set the label of the buttons in standard view
else {
$('div.confirm_multiple button.yes').text('Confirm All');
$('div.confirm_multiple button.no').text('Cancel All');
}
$('div.confirm_multiple').show();
}
}
......@@ -381,7 +374,7 @@ function identify_flavor(cpu, disk, ram){
return 0;
}
// update the actions in the
// update the actions in list view
function updateActions() {
var states = [];
var on = [];
......
ui/static/wave.gif

4.7 KB | W: | H:

ui/static/wave.gif

4.79 KB | W: | H:

ui/static/wave.gif
ui/static/wave.gif
ui/static/wave.gif
ui/static/wave.gif
  • 2-up
  • Swipe
  • Onion skin
......@@ -25,12 +25,7 @@
<tr>
<th id="selection" class="select-running">
<input type="checkbox"/>
<div class="expand-icon"></div>
<ul style="display: none">
<li class="select-all" ><a href="#">all</a></li>
<li class="select-none"><a href="#">none</a></li>
<li class="select-group"><a href="#">group</a></li>
</ul>
<div class="expand-icon"></div>
</th>
<th id="os">OS</th>
<th id="name">Name</th>
......@@ -41,6 +36,11 @@
</thead>
<tbody class="machines"></tbody>
</table>
<ul class="dropdown-selector" style="display: none">
<li class="select-all" ><a href="#">all</a></li>
<li class="select-none"><a href="#">none</a></li>
<li class="select-group"><a href="#">group</a></li>
</ul>
</div>
<script>
......@@ -54,33 +54,33 @@ $("table thead tr th#selection :checkbox").live('change', function() {
$(":checkbox").attr("checked", false);
}
updateActions();
return false;
});
// select all/none/group from drop down menu
$("table thead tr th#selection ul li").live('click', function() {
// all or none?
if ( $(this).attr("class") == "select-all" || $(this).attr("class") == "select-none") {
var all = ($(this).attr("class") == "select-all");
// toggle checkboxes
$(":checkbox").attr("checked", all);
} else if ($(this).attr("class") == "select-group"){
// TODO: This shoud select only the vms in the selected group
// right now the folowing has the functionality of select-all
$(":checkbox").attr("checked", true);
}
// update actions
updateActions();
return false;
// select all from drop down menu
$("ul.dropdown-selector li.select-all a").live('click', function() {
$(":checkbox").attr("checked", true);
$(".dropdown-selector").slideToggle('medium');
return false;
});
// menu toggle, running menu
$("table.list-machines thead tr th#selection div.expand-icon").live('click', function () {
$("table.list-machines thead tr th#selection ul").slideToggle('medium');
return false;
// select none from drop down menu
$("ul.dropdown-selector li.select-none a").live('click', function() {
$(":checkbox").attr("checked", false);
$(".dropdown-selector").slideToggle('medium');
return false;
});
// select group from drop down menu
$("ul.dropdown-selector li.select-group a").live('click', function() {
$(":checkbox").attr("checked", true);
$(".dropdown-selector").slideToggle('medium');
return false;
});
$("table.list-machines thead tr th#selection ul").live('click', function () {
$("table.list-machines thead tr th#selection ul").slideToggle('medium');
// menu toggle, running menu
$("table.list-machines thead tr th#selection .expand-icon").click( function (obj) {
$(".dropdown-selector").slideToggle('medium');
return false;
});
......@@ -104,6 +104,10 @@ $("tbody input[type='checkbox']").live('change', function() {
update_confirmations();
});
$("div.confirm_multiple button").click(function() {
$(".selected").removeClass('selected');
});
// destroy action
$("a.enabled#action-destroy").live('click', function() {
var checked = $("table.list-machines tbody input[type='checkbox']:checked");
......@@ -171,7 +175,7 @@ function update_machines_view(data){