Statistics
| Branch: | Tag: | Revision:

root / README.develop @ d79d8208

History | View | Annotate | Download (9.3 kB)

1
DEVELOP.txt - Information on how to setup a development environment. 
2

    
3
Dependencies
4
------------
5

    
6
Synnefo is written in Python 2.6 and depends on the following Python modules
7
[package versions confirmed to be compatible are in braces]
8

    
9
- django 1.2 [Django==1.2.4]
10
- simplejson [simplejson==2.1.3]
11
- selenium [?]
12
- pyzmq-static [pyzmq==2.0.10.1]
13
- pycurl [pycurl==7.19.0]
14
- python-dateutil  [python-dateutil==1.4.1]
15
  WARNING: version python-dateutil==2.0 downloaded by pip known *not* to work
16
           with Python 2.6
17
- south [south==0.7.1]
18

    
19
also, depending on the database engine of choice, on one of the following:
20
- MySQL-python [MySQL-python==1.2.3]
21
- psycopg2 [psycopg2==2.4]
22

    
23

    
24
Preparing the development environment
25
-------------------------------------
26

    
27
1. Prepare the system 
28
The easiest method is to setup a working environment through virtualenv. 
29
Alternatively, you can use your system's package manager to install
30
the dependencies (e.g. Macports has them all).
31

    
32
*On Snow Leopard and linux (64-bit), you have to set the following environment
33
variable for pip to compile the dependencies correctly.
34

    
35
	$export ARCHFLAGS="-arch x86_64"
36

    
37
*On Ubuntu, a few more packages must be installed before installing the
38
prerequisite Python libraries
39

    
40
	$sudo aptitude install libcurl3-gnutls libcurl3-gnutls-dev uuid-dev 
41

    
42
2. Checkout the code and install the Python prerequisites. This assumes
43
that python is already installed on the host.
44

    
45
    $ sudo easy_install virtualenv
46
    $ git clone https://user@code.grnet.gr/git/synnefo synnefo
47
    $ virtualenv --python=python2.6 synnefo --no-site-packages
48
    ...
49
    $ cd synnefo
50
    $ ./bin/pip install <list_of_prerequisites>
51

    
52
3. At this point you should have all required dependencies installed. Now you
53
have to select a database engine. The choices are: postgres, mysql and sqlite.
54

    
55
-SQLite
56
The python sqlite driver is available by default with Python so no additional 
57
configuration is required. Also, most self-respecting systems have the sqlite 
58
library installed by default.   
59

    
60
-MySQL
61
MySQL must be installed first
62

    
63
*Ubuntu - Debian
64
	$sudo apt-get install libmysqlclient-dev
65

    
66
*MacPorts
67
	$sudo port install mysql5
68

    
69
Install the MySQL python library
70

    
71
	$ bin/pip install MySQL-python
72

    
73
Note: On MacOSX with Mysql install from MacPorts the above command will fail
74
complaining that it cannot find the mysql_config command. Do the following and
75
restart the installation
76

    
77
	$ echo "mysql_config = /opt/local/bin/mysql_config5" >> ./build/MySQL-python/site.cfg
78

    
79
Configure a MySQL db/account for synnefo
80

    
81
	$ mysql -u root -p
82

    
83
	mysql> create database synnefo;
84
	mysql> show databases;
85
	mysql> GRANT ALL on synnefo.* TO username IDENTIFIED BY 'password';
86
 
87
-Postgres
88

    
89
#Ubuntu - Debian
90
	$ sudo apt-get install postgresql-8.4 libpq-dev
91

    
92
#MacPorts
93
	$ sudo port install postgresql84
94

    
95
Install the postgres Python library
96

    
97
	$ bin/pip install psycopg2
98

    
99
Configure a postgres db/account for synnefo
100
	Become the postgres user, connect to PostgreSQL:
101
	$ sudo su - postgres 
102
	$ psql
103
	
104
	Run the following commands:
105
	DROP DATABASE synnefo;
106
	DROP USER username;
107
	CREATE USER username WITH PASSWORD 'password';
108
	CREATE DATABASE synnefo;
109
	GRANT ALL PRIVILEGES ON DATABASE synnefo TO username;
110
	ALTER DATABASE synnefo OWNER TO username;
111
	ALTER USER username CREATEDB;
112

    
113
The last line enables the newly created user to create own databases. This is
114
needed for Django to create and drop the test_synnefo database for unit
115
testing.
116
	
117
4. At this point you should have a working DB. Now configure Django to access it: 
118
Copy the default configuration file 
119

    
120
    $ cp settings.py.dist settings.py
121
    
122
and then copy/edit according to the database used:  
123
    
124
-SQLite
125

    
126
	PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) + '/'
127

    
128
	DATABASES = {
129
	    'default': {
130
		'ENGINE': 'django.db.backends.sqlite3',
131
		'NAME': PROJECT_PATH + 'synnefo.db' #WARN: This must be an absolute path
132
	    }
133
	}
134

    
135
-MySQL
136
	DATABASES = {
137
	    'default': {
138
		'ENGINE': 'django.db.backends.mysql', 
139
		'NAME': 'synnefo',
140
		'USER': 'USERNAME'
141
		'PASSWORD': 'PASSWORD',
142
		'HOST': 'HOST',
143
		'PORT': 'PORT',
144
		'OPTIONS': {
145
		    'init_command': 'SET storage_engine=INNODB',
146
		}
147
	    }
148
	}
149

    
150
-Postgres    
151

    
152
    DATABASES = {
153
	    'default': {
154
		'ENGINE': 'django.db.backends.postgresql_psycopg2',
155
		'NAME': 'DATABASE',
156
		'USER': 'USERNAME',
157
		'PASSWORD': 'PASSWORD',
158
		'HOST': 'HOST',
159
		'PORT': 'PORT',
160
	    }
161
	}
162

    
163
5. Try it out. The following command will attempt to connect to the DB and 
164
print out DDL statements. It should not fail.
165

    
166
	$ ./bin/python manage.py sql db
167
	
168
6. Create the DB and (optionally) load test data
169
    
170
    $ ./bin/python manage.py syncdb
171
	$ ./bin/python manage.py loaddata db/fixtures/flavors.json
172
	$ ./bin/python manage.py loaddata db/fixtures/images.json
173

    
174
The following fictures can be loaded optionally depending on
175
testing requirements:
176

    
177
	$ ./bin/python manage.py loaddata db/fixtures/vms.json
178
	$ ./bin/python manage.py loaddata db/fixtures/initial_data.json
179
	$ ./bin/python manage.py loaddata db/fixtures/disks.json
180

    
181
7. Set the BACKEND_PREFIX_ID variable to some unique prefix, e.g. your commit
182
username 
183

    
184
8. Start the system
185
    $ ./bin/python db/db_controller.py  #DB synch daemon
186
    $ ./bin/python manage.py runserver  #Django
187

    
188
9. (Hopefully) Done
189

    
190
South Database Migrations
191
------------------------
192

    
193
*Schema migrations:
194

    
195
First, remember to add the south app to settings.py (it is already included in the
196
settings.py.dist).
197

    
198
In addition, do not use the syncdb management command. It can only be used
199
the first time and/or if you drop the database and must recreate it from scratch.
200

    
201
The first schema support for migrations is initialized with the following
202
command:
203

    
204
    $ ./bin/python schemamigration db --initial
205

    
206
Each time you make changes to the database and data migration is not required (WARNING: always
207
perform this with extreme care):
208

    
209
    $ ./bin/python schemamigration db --auto
210

    
211
The above will create the migration script. Now this must be applied to the live database.
212

    
213
    $ ./bin/python migrate db
214

    
215
Consider this example (adding a field to the SynnefoUser model):
216

    
217
    bkarak@nefarian:~/devel/synnefo$ ./bin/python manage.py schemamigration db --auto
218
     + Added field new_south_test_field on db.SynnefoUser
219
     Created 0002_auto__add_field_synnefouser_new_south_test_field.py.
220

    
221
  You can now apply this migration with: ./manage.py migrate db
222

    
223
    $ ./manage.py migrate db
224
     Running migrations for db:
225
     - Migrating forwards to 0002_auto__add_field_synnefouser_new_south_test_field.
226
     > db:0002_auto__add_field_synnefouser_new_south_test_field
227
     - Loading initial data for db.
228
    Installing json fixture 'initial_data' from '/home/bkarak/devel/synnefo/../synnefo/db/fixtures'.
229
    Installed 1 object(s) from 1 fixture(s)
230

    
231
South needs some extra definitions to the model to preserve and migrate the existing data, for example, if we add a field
232
in a model, we should declare its default value. If not, South will propably fail, after indicating the error.
233

    
234
    $ ./bin/python manage.py schemamigration db --auto
235
     ? The field 'SynnefoUser.new_south_field_2' does not have a default specified, yet is NOT NULL.
236
     ? Since you are adding or removing this field, you MUST specify a default
237
     ? value to use for existing rows. Would you like to:
238
     ?  1. Quit now, and add a default to the field in models.py
239
     ?  2. Specify a one-off value to use for existing columns now
240
     ? Please select a choice: 1
241

    
242
*Data migrations:
243

    
244
If we need to do data migration as well, for example rename a field, we use tha 'datamigration' management command.
245

    
246
In contrast with schemamigration, to perform complex data migration, we must write the script manually. The process is
247
the following:
248

    
249
    1. Introduce the changes in the code and fixtures (initial data).
250
    2. Execute:
251

    
252
    $ ./bin/python manage.py datamigration <migration_name_here>
253

    
254
    For example:
255

    
256
    $ ./bin/python manage.py datamigration db rename_credit_wallet
257
    Created 0003_rename_credit_wallet.py.
258

    
259
    3. We edit the generated script. It contains two methods: forwards and backwards.
260

    
261
    For database operations (column additions, alter tables etc) we use the South database API
262
    (http://south.aeracode.org/docs/databaseapi.html).
263

    
264
    To access the data, we use the database reference (orm) provided as parameter in forwards, backwards method declarations
265
    in the migration script. For example:
266

    
267
    class Migration(DataMigration):
268

    
269
    def forwards(self, orm):
270
        orm.SynnefoUser.objects.all()
271

    
272
    4. To migrate the database to the latest version, we execute:
273

    
274
    ./manage.py migrate db
275

    
276
To see which migrations are applied:
277

    
278
    $ ./bin/python manage.py migrate db --list
279

    
280
      db
281
        (*) 0001_initial
282
        (*) 0002_auto__add_field_synnefouser_new_south_test_field
283
        (*) 0003_rename_credit_wallet
284

    
285
More information and more thorough examples can be found in the South web site.
286

    
287
http://south.aeracode.org/
288

    
289
UI Testing
290
----------
291
The functional ui tests require the Selenium server and the synnefo app to 
292
be running.
293

    
294
    $ wget http://selenium.googlecode.com/files/selenium-server-standalone-2.0b2.jar
295
    $ java -jar selenium-server-standalone-2.0b2.jar &
296
    $ ./bin/python manage.py runserver &
297
    $ ./bin/python manage.py test ui
298

    
299
Test coverage
300
-------------
301

    
302
In order to get code coverage reports you need to install django-test-coverage
303
   
304
   $ ./bin/pip install django-test-coverage
305

    
306
Then edit your settings.py and configure the test runner:
307

    
308
   TEST_RUNNER = 'django-test-coverage.runner.run_tests'