Statistics
| Branch: | Tag: | Revision:

root / README.develop @ ac3c3a4b

History | View | Annotate | Download (9.3 kB)

1 bbd4f788 Georgios Gousios
DEVELOP.txt - Information on how to setup a development environment. 
2 bbd4f788 Georgios Gousios
3 bbd4f788 Georgios Gousios
Dependencies
4 bbd4f788 Georgios Gousios
------------
5 bbd4f788 Georgios Gousios
6 602d6541 Vangelis Koukis
Synnefo is written in Python 2.6 and depends on the following Python modules
7 602d6541 Vangelis Koukis
[package versions confirmed to be compatible are in braces]
8 bbd4f788 Georgios Gousios
9 602d6541 Vangelis Koukis
- django 1.2 [Django==1.2.4]
10 602d6541 Vangelis Koukis
- simplejson [simplejson==2.1.3]
11 602d6541 Vangelis Koukis
- selenium [?]
12 602d6541 Vangelis Koukis
- pyzmq-static [pyzmq==2.0.10.1]
13 602d6541 Vangelis Koukis
- pycurl [pycurl==7.19.0]
14 602d6541 Vangelis Koukis
- python-dateutil  [python-dateutil==1.4.1]
15 6fc64f55 Georgios Gousios
  WARNING: version python-dateutil==2.0 downloaded by pip known *not* to work
16 6fc64f55 Georgios Gousios
           with Python 2.6
17 9ad94f0a Vassilios Karakoidas
- south [south==0.7.1]
18 bbd4f788 Georgios Gousios
19 bbd4f788 Georgios Gousios
also, depending on the database engine of choice, on one of the following:
20 602d6541 Vangelis Koukis
- MySQL-python [MySQL-python==1.2.3]
21 602d6541 Vangelis Koukis
- psycopg2 [psycopg2==2.4]
22 f5e590e4 Georgios Gousios
23 f5e590e4 Georgios Gousios
24 bbd4f788 Georgios Gousios
Preparing the development environment
25 bbd4f788 Georgios Gousios
-------------------------------------
26 bbd4f788 Georgios Gousios
27 bbd4f788 Georgios Gousios
1. Prepare the system 
28 bbd4f788 Georgios Gousios
The easiest method is to setup a working environment through virtualenv. 
29 bbd4f788 Georgios Gousios
Alternatively, you can use your system's package manager to install
30 bbd4f788 Georgios Gousios
the dependencies (e.g. Macports has them all).
31 bbd4f788 Georgios Gousios
32 6fc64f55 Georgios Gousios
*On Snow Leopard and linux (64-bit), you have to set the following environment
33 6fc64f55 Georgios Gousios
variable for pip to compile the dependencies correctly.
34 bbd4f788 Georgios Gousios
35 bbd4f788 Georgios Gousios
	$export ARCHFLAGS="-arch x86_64"
36 bbd4f788 Georgios Gousios
37 602d6541 Vangelis Koukis
*On Ubuntu, a few more packages must be installed before installing the
38 bbd4f788 Georgios Gousios
prerequisite Python libraries
39 bbd4f788 Georgios Gousios
40 bbd4f788 Georgios Gousios
	$sudo aptitude install libcurl3-gnutls libcurl3-gnutls-dev uuid-dev 
41 bbd4f788 Georgios Gousios
42 bbd4f788 Georgios Gousios
2. Checkout the code and install the Python prerequisites. This assumes
43 bbd4f788 Georgios Gousios
that python is already installed on the host.
44 bbd4f788 Georgios Gousios
45 bbd4f788 Georgios Gousios
    $ sudo easy_install virtualenv
46 bbd4f788 Georgios Gousios
    $ git clone https://user@code.grnet.gr/git/synnefo synnefo
47 bbd4f788 Georgios Gousios
    $ virtualenv --python=python2.6 synnefo --no-site-packages
48 bbd4f788 Georgios Gousios
    ...
49 bbd4f788 Georgios Gousios
    $ cd synnefo
50 602d6541 Vangelis Koukis
    $ ./bin/pip install <list_of_prerequisites>
51 bbd4f788 Georgios Gousios
52 83d51c7b Georgios Gousios
3. At this point you should have all required dependencies installed. Now you
53 bbd4f788 Georgios Gousios
have to select a database engine. The choices are: postgres, mysql and sqlite.
54 bbd4f788 Georgios Gousios
55 bbd4f788 Georgios Gousios
-SQLite
56 bbd4f788 Georgios Gousios
The python sqlite driver is available by default with Python so no additional 
57 bbd4f788 Georgios Gousios
configuration is required. Also, most self-respecting systems have the sqlite 
58 bbd4f788 Georgios Gousios
library installed by default.   
59 bbd4f788 Georgios Gousios
60 bbd4f788 Georgios Gousios
-MySQL
61 bbd4f788 Georgios Gousios
MySQL must be installed first
62 bbd4f788 Georgios Gousios
63 bbd4f788 Georgios Gousios
*Ubuntu - Debian
64 bbd4f788 Georgios Gousios
	$sudo apt-get install libmysqlclient-dev
65 bbd4f788 Georgios Gousios
66 bbd4f788 Georgios Gousios
*MacPorts
67 bbd4f788 Georgios Gousios
	$sudo port install mysql5
68 bbd4f788 Georgios Gousios
69 bbd4f788 Georgios Gousios
Install the MySQL python library
70 bbd4f788 Georgios Gousios
71 bbd4f788 Georgios Gousios
	$ bin/pip install MySQL-python
72 bbd4f788 Georgios Gousios
73 bbd4f788 Georgios Gousios
Note: On MacOSX with Mysql install from MacPorts the above command will fail
74 bbd4f788 Georgios Gousios
complaining that it cannot find the mysql_config command. Do the following and
75 bbd4f788 Georgios Gousios
restart the installation
76 bbd4f788 Georgios Gousios
77 bbd4f788 Georgios Gousios
	$ echo "mysql_config = /opt/local/bin/mysql_config5" >> ./build/MySQL-python/site.cfg
78 bbd4f788 Georgios Gousios
79 bbd4f788 Georgios Gousios
Configure a MySQL db/account for synnefo
80 bbd4f788 Georgios Gousios
81 bbd4f788 Georgios Gousios
	$ mysql -u root -p
82 bbd4f788 Georgios Gousios
83 bbd4f788 Georgios Gousios
	mysql> create database synnefo;
84 bbd4f788 Georgios Gousios
	mysql> show databases;
85 bbd4f788 Georgios Gousios
	mysql> GRANT ALL on synnefo.* TO username IDENTIFIED BY 'password';
86 bbd4f788 Georgios Gousios
 
87 bbd4f788 Georgios Gousios
-Postgres
88 bbd4f788 Georgios Gousios
89 bbd4f788 Georgios Gousios
#Ubuntu - Debian
90 bbd4f788 Georgios Gousios
	$ sudo apt-get install postgresql-8.4 libpq-dev
91 bbd4f788 Georgios Gousios
92 bbd4f788 Georgios Gousios
#MacPorts
93 bbd4f788 Georgios Gousios
	$ sudo port install postgresql84
94 bbd4f788 Georgios Gousios
95 bbd4f788 Georgios Gousios
Install the postgres Python library
96 bbd4f788 Georgios Gousios
97 bbd4f788 Georgios Gousios
	$ bin/pip install psycopg2
98 bbd4f788 Georgios Gousios
99 bbd4f788 Georgios Gousios
Configure a postgres db/account for synnefo
100 7fb0fc9f Vangelis Koukis
	Become the postgres user, connect to PostgreSQL:
101 7fb0fc9f Vangelis Koukis
	$ sudo su - postgres 
102 7fb0fc9f Vangelis Koukis
	$ psql
103 7fb0fc9f Vangelis Koukis
	
104 7fb0fc9f Vangelis Koukis
	Run the following commands:
105 7fb0fc9f Vangelis Koukis
	DROP DATABASE synnefo;
106 7fb0fc9f Vangelis Koukis
	DROP USER username;
107 7fb0fc9f Vangelis Koukis
	CREATE USER username WITH PASSWORD 'password';
108 7fb0fc9f Vangelis Koukis
	CREATE DATABASE synnefo;
109 7fb0fc9f Vangelis Koukis
	GRANT ALL PRIVILEGES ON DATABASE synnefo TO username;
110 7fb0fc9f Vangelis Koukis
	ALTER DATABASE synnefo OWNER TO username;
111 7fb0fc9f Vangelis Koukis
	ALTER USER username CREATEDB;
112 7fb0fc9f Vangelis Koukis
113 7fb0fc9f Vangelis Koukis
The last line enables the newly created user to create own databases. This is
114 7fb0fc9f Vangelis Koukis
needed for Django to create and drop the test_synnefo database for unit
115 7fb0fc9f Vangelis Koukis
testing.
116 bbd4f788 Georgios Gousios
	
117 83d51c7b Georgios Gousios
4. At this point you should have a working DB. Now configure Django to access it: 
118 bbd4f788 Georgios Gousios
Copy the default configuration file 
119 bbd4f788 Georgios Gousios
120 bbd4f788 Georgios Gousios
    $ cp settings.py.dist settings.py
121 bbd4f788 Georgios Gousios
    
122 83d51c7b Georgios Gousios
and then copy/edit according to the database used:  
123 bbd4f788 Georgios Gousios
    
124 bbd4f788 Georgios Gousios
-SQLite
125 bbd4f788 Georgios Gousios
126 bbd4f788 Georgios Gousios
	PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) + '/'
127 bbd4f788 Georgios Gousios
128 bbd4f788 Georgios Gousios
	DATABASES = {
129 bbd4f788 Georgios Gousios
	    'default': {
130 83d51c7b Georgios Gousios
		'ENGINE': 'django.db.backends.sqlite3',
131 83d51c7b Georgios Gousios
		'NAME': PROJECT_PATH + 'synnefo.db' #WARN: This must be an absolute path
132 bbd4f788 Georgios Gousios
	    }
133 bbd4f788 Georgios Gousios
	}
134 bbd4f788 Georgios Gousios
135 bbd4f788 Georgios Gousios
-MySQL
136 bbd4f788 Georgios Gousios
	DATABASES = {
137 bbd4f788 Georgios Gousios
	    'default': {
138 83d51c7b Georgios Gousios
		'ENGINE': 'django.db.backends.mysql', 
139 bbd4f788 Georgios Gousios
		'NAME': 'synnefo',
140 bbd4f788 Georgios Gousios
		'USER': 'USERNAME'
141 bbd4f788 Georgios Gousios
		'PASSWORD': 'PASSWORD',
142 bbd4f788 Georgios Gousios
		'HOST': 'HOST',
143 bbd4f788 Georgios Gousios
		'PORT': 'PORT',
144 bbd4f788 Georgios Gousios
		'OPTIONS': {
145 bbd4f788 Georgios Gousios
		    'init_command': 'SET storage_engine=INNODB',
146 bbd4f788 Georgios Gousios
		}
147 bbd4f788 Georgios Gousios
	    }
148 bbd4f788 Georgios Gousios
	}
149 bbd4f788 Georgios Gousios
150 bbd4f788 Georgios Gousios
-Postgres    
151 bbd4f788 Georgios Gousios
152 bbd4f788 Georgios Gousios
    DATABASES = {
153 bbd4f788 Georgios Gousios
	    'default': {
154 83d51c7b Georgios Gousios
		'ENGINE': 'django.db.backends.postgresql_psycopg2',
155 bbd4f788 Georgios Gousios
		'NAME': 'DATABASE',
156 bbd4f788 Georgios Gousios
		'USER': 'USERNAME',
157 bbd4f788 Georgios Gousios
		'PASSWORD': 'PASSWORD',
158 bbd4f788 Georgios Gousios
		'HOST': 'HOST',
159 bbd4f788 Georgios Gousios
		'PORT': 'PORT',
160 bbd4f788 Georgios Gousios
	    }
161 bbd4f788 Georgios Gousios
	}
162 bbd4f788 Georgios Gousios
163 83d51c7b Georgios Gousios
5. Try it out. The following command will attempt to connect to the DB and 
164 bbd4f788 Georgios Gousios
print out DDL statements. It should not fail.
165 bbd4f788 Georgios Gousios
166 bbd4f788 Georgios Gousios
	$ ./bin/python manage.py sql db
167 bbd4f788 Georgios Gousios
	
168 83d51c7b Georgios Gousios
6. Create the DB and (optionally) load test data
169 bbd4f788 Georgios Gousios
    
170 bbd4f788 Georgios Gousios
    $ ./bin/python manage.py syncdb
171 bbd4f788 Georgios Gousios
	$ ./bin/python manage.py loaddata db/fixtures/flavors.json
172 bbd4f788 Georgios Gousios
	$ ./bin/python manage.py loaddata db/fixtures/images.json
173 f5e590e4 Georgios Gousios
174 4cf8adf8 Vangelis Koukis
The following fixtures can be loaded optionally depending on
175 f5e590e4 Georgios Gousios
testing requirements:
176 f5e590e4 Georgios Gousios
177 bbd4f788 Georgios Gousios
	$ ./bin/python manage.py loaddata db/fixtures/vms.json
178 f5e590e4 Georgios Gousios
	$ ./bin/python manage.py loaddata db/fixtures/disks.json
179 83d51c7b Georgios Gousios
180 83d51c7b Georgios Gousios
7. Set the BACKEND_PREFIX_ID variable to some unique prefix, e.g. your commit
181 83d51c7b Georgios Gousios
username 
182 83d51c7b Georgios Gousios
183 83d51c7b Georgios Gousios
8. Start the system
184 4cf8adf8 Vangelis Koukis
    $ ./bin/python db/db_controller.py  # DB synch daemon
185 4cf8adf8 Vangelis Koukis
    $ ./bin/python manage.py runserver  # Django
186 f5e590e4 Georgios Gousios
187 f5e590e4 Georgios Gousios
9. (Hopefully) Done
188 bbd4f788 Georgios Gousios
189 6fc64f55 Georgios Gousios
South Database Migrations
190 9ad94f0a Vassilios Karakoidas
------------------------
191 9ad94f0a Vassilios Karakoidas
192 6fc64f55 Georgios Gousios
*Schema migrations:
193 6fc64f55 Georgios Gousios
194 9ad94f0a Vassilios Karakoidas
First, remember to add the south app to settings.py (it is already included in the
195 9ad94f0a Vassilios Karakoidas
settings.py.dist).
196 9ad94f0a Vassilios Karakoidas
197 6fc64f55 Georgios Gousios
In addition, do not use the syncdb management command. It can only be used
198 6fc64f55 Georgios Gousios
the first time and/or if you drop the database and must recreate it from scratch.
199 9ad94f0a Vassilios Karakoidas
200 6fc64f55 Georgios Gousios
The first schema support for migrations is initialized with the following
201 9ad94f0a Vassilios Karakoidas
command:
202 9ad94f0a Vassilios Karakoidas
203 9ad94f0a Vassilios Karakoidas
    $ ./bin/python schemamigration db --initial
204 9ad94f0a Vassilios Karakoidas
205 9ad94f0a Vassilios Karakoidas
Each time you make changes to the database and data migration is not required (WARNING: always
206 9ad94f0a Vassilios Karakoidas
perform this with extreme care):
207 9ad94f0a Vassilios Karakoidas
208 9ad94f0a Vassilios Karakoidas
    $ ./bin/python schemamigration db --auto
209 9ad94f0a Vassilios Karakoidas
210 9ad94f0a Vassilios Karakoidas
The above will create the migration script. Now this must be applied to the live database.
211 9ad94f0a Vassilios Karakoidas
212 9ad94f0a Vassilios Karakoidas
    $ ./bin/python migrate db
213 9ad94f0a Vassilios Karakoidas
214 9ad94f0a Vassilios Karakoidas
Consider this example (adding a field to the SynnefoUser model):
215 9ad94f0a Vassilios Karakoidas
216 9ad94f0a Vassilios Karakoidas
    bkarak@nefarian:~/devel/synnefo$ ./bin/python manage.py schemamigration db --auto
217 9ad94f0a Vassilios Karakoidas
     + Added field new_south_test_field on db.SynnefoUser
218 6fc64f55 Georgios Gousios
     Created 0002_auto__add_field_synnefouser_new_south_test_field.py.
219 6fc64f55 Georgios Gousios
220 6fc64f55 Georgios Gousios
  You can now apply this migration with: ./manage.py migrate db
221 6fc64f55 Georgios Gousios
222 d79d8208 Vassilios Karakoidas
    $ ./manage.py migrate db
223 9ad94f0a Vassilios Karakoidas
     Running migrations for db:
224 9ad94f0a Vassilios Karakoidas
     - Migrating forwards to 0002_auto__add_field_synnefouser_new_south_test_field.
225 9ad94f0a Vassilios Karakoidas
     > db:0002_auto__add_field_synnefouser_new_south_test_field
226 9ad94f0a Vassilios Karakoidas
     - Loading initial data for db.
227 9ad94f0a Vassilios Karakoidas
    Installing json fixture 'initial_data' from '/home/bkarak/devel/synnefo/../synnefo/db/fixtures'.
228 9ad94f0a Vassilios Karakoidas
    Installed 1 object(s) from 1 fixture(s)
229 9ad94f0a Vassilios Karakoidas
230 9ad94f0a Vassilios Karakoidas
South needs some extra definitions to the model to preserve and migrate the existing data, for example, if we add a field
231 6fc64f55 Georgios Gousios
in a model, we should declare its default value. If not, South will propably fail, after indicating the error.
232 6fc64f55 Georgios Gousios
233 d79d8208 Vassilios Karakoidas
    $ ./bin/python manage.py schemamigration db --auto
234 d79d8208 Vassilios Karakoidas
     ? The field 'SynnefoUser.new_south_field_2' does not have a default specified, yet is NOT NULL.
235 d79d8208 Vassilios Karakoidas
     ? Since you are adding or removing this field, you MUST specify a default
236 d79d8208 Vassilios Karakoidas
     ? value to use for existing rows. Would you like to:
237 d79d8208 Vassilios Karakoidas
     ?  1. Quit now, and add a default to the field in models.py
238 d79d8208 Vassilios Karakoidas
     ?  2. Specify a one-off value to use for existing columns now
239 d79d8208 Vassilios Karakoidas
     ? Please select a choice: 1
240 6fc64f55 Georgios Gousios
241 6fc64f55 Georgios Gousios
*Data migrations:
242 9ad94f0a Vassilios Karakoidas
243 9ad94f0a Vassilios Karakoidas
If we need to do data migration as well, for example rename a field, we use tha 'datamigration' management command.
244 9ad94f0a Vassilios Karakoidas
245 2e19b161 Vassilios Karakoidas
In contrast with schemamigration, to perform complex data migration, we must write the script manually. The process is
246 2e19b161 Vassilios Karakoidas
the following:
247 2e19b161 Vassilios Karakoidas
248 2e19b161 Vassilios Karakoidas
    1. Introduce the changes in the code and fixtures (initial data).
249 2e19b161 Vassilios Karakoidas
    2. Execute:
250 2e19b161 Vassilios Karakoidas
251 2e19b161 Vassilios Karakoidas
    $ ./bin/python manage.py datamigration <migration_name_here>
252 2e19b161 Vassilios Karakoidas
253 2e19b161 Vassilios Karakoidas
    For example:
254 2e19b161 Vassilios Karakoidas
255 2e19b161 Vassilios Karakoidas
    $ ./bin/python manage.py datamigration db rename_credit_wallet
256 2e19b161 Vassilios Karakoidas
    Created 0003_rename_credit_wallet.py.
257 2e19b161 Vassilios Karakoidas
258 2e19b161 Vassilios Karakoidas
    3. We edit the generated script. It contains two methods: forwards and backwards.
259 2e19b161 Vassilios Karakoidas
260 2e19b161 Vassilios Karakoidas
    For database operations (column additions, alter tables etc) we use the South database API
261 2e19b161 Vassilios Karakoidas
    (http://south.aeracode.org/docs/databaseapi.html).
262 2e19b161 Vassilios Karakoidas
263 d79d8208 Vassilios Karakoidas
    To access the data, we use the database reference (orm) provided as parameter in forwards, backwards method declarations
264 d79d8208 Vassilios Karakoidas
    in the migration script. For example:
265 2e19b161 Vassilios Karakoidas
266 2e19b161 Vassilios Karakoidas
    class Migration(DataMigration):
267 2e19b161 Vassilios Karakoidas
268 2e19b161 Vassilios Karakoidas
    def forwards(self, orm):
269 2e19b161 Vassilios Karakoidas
        orm.SynnefoUser.objects.all()
270 2e19b161 Vassilios Karakoidas
271 2e19b161 Vassilios Karakoidas
    4. To migrate the database to the latest version, we execute:
272 2e19b161 Vassilios Karakoidas
273 2e19b161 Vassilios Karakoidas
    ./manage.py migrate db
274 2e19b161 Vassilios Karakoidas
275 2e19b161 Vassilios Karakoidas
To see which migrations are applied:
276 2e19b161 Vassilios Karakoidas
277 2e19b161 Vassilios Karakoidas
    $ ./bin/python manage.py migrate db --list
278 2e19b161 Vassilios Karakoidas
279 2e19b161 Vassilios Karakoidas
      db
280 2e19b161 Vassilios Karakoidas
        (*) 0001_initial
281 2e19b161 Vassilios Karakoidas
        (*) 0002_auto__add_field_synnefouser_new_south_test_field
282 2e19b161 Vassilios Karakoidas
        (*) 0003_rename_credit_wallet
283 2e19b161 Vassilios Karakoidas
284 2e19b161 Vassilios Karakoidas
More information and more thorough examples can be found in the South web site.
285 2e19b161 Vassilios Karakoidas
286 2e19b161 Vassilios Karakoidas
http://south.aeracode.org/
287 2e19b161 Vassilios Karakoidas
288 bbd4f788 Georgios Gousios
UI Testing
289 bbd4f788 Georgios Gousios
----------
290 83d51c7b Georgios Gousios
The functional ui tests require the Selenium server and the synnefo app to 
291 83d51c7b Georgios Gousios
be running.
292 bbd4f788 Georgios Gousios
293 bbd4f788 Georgios Gousios
    $ wget http://selenium.googlecode.com/files/selenium-server-standalone-2.0b2.jar
294 bbd4f788 Georgios Gousios
    $ java -jar selenium-server-standalone-2.0b2.jar &
295 bbd4f788 Georgios Gousios
    $ ./bin/python manage.py runserver &
296 bbd4f788 Georgios Gousios
    $ ./bin/python manage.py test ui
297 bbd4f788 Georgios Gousios
298 bbd4f788 Georgios Gousios
Test coverage
299 bbd4f788 Georgios Gousios
-------------
300 bbd4f788 Georgios Gousios
301 bbd4f788 Georgios Gousios
In order to get code coverage reports you need to install django-test-coverage
302 bbd4f788 Georgios Gousios
   
303 bbd4f788 Georgios Gousios
   $ ./bin/pip install django-test-coverage
304 bbd4f788 Georgios Gousios
305 bbd4f788 Georgios Gousios
Then edit your settings.py and configure the test runner:
306 bbd4f788 Georgios Gousios
307 bbd4f788 Georgios Gousios
   TEST_RUNNER = 'django-test-coverage.runner.run_tests'