Revision b1996c81

b/snf-app/docs/conf.py
1 1
import sys, os
2 2

  
3 3

  
4
project = u'snf-asterias-app'
4
project = u'snf-cyclades-app'
5 5
copyright = u'2012, GRNET'
6 6
version = '0.8'
7 7
release = '0.8'
......
29 29
    'snf-webproject': 'dev',
30 30
    'snf-common': 'dev',
31 31
    'snf-image': 'dev',
32
    'snf-asterias-app': 'dev'
32
    'snf-cyclades-app': 'dev'
33 33
}
34 34

  
35 35
for name, ver in SYNNEFO_PROJECTS.iteritems():
b/snf-app/docs/index.rst
1
.. _snf-asterias-app:
1
.. _snf-cyclades-app:
2 2

  
3
Component snf-asterias-app
3
Component snf-cyclades-app
4 4
==========================
5 5

  
6
synnefo component :ref:`snf-asterias-app <snf-asterias-app>` defines
7
the web application for asterias. It includes the following:
6
synnefo component :ref:`snf-cyclades-app <snf-cyclades-app>` defines
7
the web application for cyclades. It includes the following:
8 8

  
9 9
    * A set of Django applications that define among others:
10 10
        * web UI
......
21 21
--------------
22 22

  
23 23
The logic dispatcher provides the context to run the business logic layer of
24
:ref:`asterias <snf-asterias>`. It must run on :ref:`LOGIC <LOGIC_NODE>` nodes.
24
:ref:`cyclades <snf-cyclades>`. It must run on :ref:`LOGIC <LOGIC_NODE>` nodes.
25 25

  
26 26
The dispatcher retrieves messages from the queue, over AMQP, and calls the
27 27
appropriate handler function, based on the type of the message.
......
32 32
---------
33 33

  
34 34
command :command:`snf-admin` provides the command-line admin interface
35
for :ref:`asterias <snf-asterias>`.
35
for :ref:`cyclades <snf-cyclades>`.
36 36

  
37 37
Package installation
38 38
--------------------
......
40 40
.. todo:: kpap: verify instructions for installation from source.
41 41

  
42 42
Use ``pip`` to install the latest version of the package from source,
43
or request a specific version as ``snf-asterias-app==x.y.z``.
43
or request a specific version as ``snf-cyclades-app==x.y.z``.
44 44

  
45 45
.. code-block:: console
46 46

  
47
   $ pip install snf-asterias-app -f https://docs.dev.grnet.gr/pypi
47
   $ pip install snf-cyclades-app -f https://docs.dev.grnet.gr/pypi
48 48

  
49
On Debian Squeeze, install the ``snf-asterias-app`` Debian package.
49
On Debian Squeeze, install the ``snf-cyclades-app`` Debian package.
50 50

  
51 51
Package configuration
52 52
---------------------
......
55 55
***************
56 56

  
57 57
Please see the configuration section of :ref:`snf-webproject <snf-webproject>`
58
on how to serve :ref:`snf-asterias-app <snf-asterias-app>` as part of a
58
on how to serve :ref:`snf-cyclades-app <snf-cyclades-app>` as part of a
59 59
Django project.
60 60

  
61 61
snf-dispatcher
......
82 82
Package settings
83 83
----------------
84 84

  
85
Component :ref:`snf-asterias-app <snf-asterias-app>` requires the following
85
Component :ref:`snf-cyclades-app <snf-cyclades-app>` requires the following
86 86
settings, as managed by :ref:`snf-common <snf-common>`:
87 87

  
88 88
.. literalinclude:: ../synnefo/app_settings/default/api.py
b/snf-common/docs/conf.py
29 29
    'snf-webproject': 'dev',
30 30
    'snf-common': 'dev',
31 31
    'snf-image': 'dev',
32
    'snf-asterias-app': 'dev'
32
    'snf-cyclades-app': 'dev'
33 33
}
34 34

  
35 35
for name, ver in SYNNEFO_PROJECTS.iteritems():
/dev/null
1
.. _asterias-admin-guide:
2

  
3
===================
4
Administrator Guide
5
===================
6

  
7
This is the asterias administrator guide.
8

  
9
It contains instructions on how to download, install and configure
10
the synnefo components necessary to deploy the Compute Service. It also covers
11
maintenance issues, e.g., upgrades of existing deployments.
12

  
13
The guide assumes you are familiar with all aspects of downloading, installing
14
and configuring packages for the Linux distribution of your choice.
15

  
16
Overview
17
--------
18

  
19
This guide covers the following:
20

  
21
Architecture
22
    Node types needed for a complete deployment of asterias,
23
    and their roles. Throughout this guide, `node` refers to a physical machine
24
    in the deployment.
25
Installation
26
    The installation of services and synnefo software components for a working
27
    deployment of asterias, either from source packages or the provided
28
    packages for Debian Squeeze.
29
Configuration
30
    Configuration of the various software components comprising an asterias
31
    deployment.
32
Upgrades/Changelogs
33
    Upgrades of existing deployments of asterias to newer versions, associated
34
    Changelogs.
35

  
36
.. _asterias-architecture:
37

  
38
Architecture
39
------------
40

  
41
Nodes in an asterias deployment belong in one of the following types.
42
For every type, we list the services that execute on corresponding nodes.
43

  
44
.. _DB_NODE:
45

  
46
DB
47
**
48

  
49
A node [or more than one nodes, if using an HA configuration], running a DB
50
engine supported by the Django ORM layer. The DB is the single source of
51
truth for the servicing of API requests by asterias.
52

  
53
*Services:* PostgreSQL / MySQL
54

  
55
.. _APISERVER_NODE:
56

  
57
APISERVER
58
*********
59
A node running the ``api`` application contained in
60
:ref:`snf-asterias-app <snf-asterias-app>`. Any number of
61
:ref:`APISERVER <APISERVER_NODE>` nodes
62
can be used, in a load-balancing configuration, without any
63
special consideration. Access to a common DB ensures consistency.
64

  
65
*Services:* Web server, vncauthproxy
66

  
67

  
68
.. _QUEUE_NODE:
69

  
70
QUEUE
71
*****
72
A node running the RabbitMQ software, which provides AMQP functionality. More
73
than one :ref:`QUEUE <QUEUE_NODE>` nodes may be deployed, in an HA
74
configuration. Such deployments require shared storage, provided e.g., by DRBD.
75

  
76
*Services:* RabbitMQ [rabbitmq-server]
77

  
78

  
79
.. _LOGIC_NODE:
80

  
81
LOGIC
82
*****
83

  
84
A node running the business logic of synnefo, in Django. It dequeues
85
messages from QUEUE nodes, and provides the context in which business logic
86
functions run. It uses Django ORM to connect to the common DB and update the
87
state of the system, based on notifications received from the rest of the
88
infrastructure, over AMQP.
89

  
90
*Services:* the synnefo logic dispatcher, ``snf-dispatcher``
91

  
92

  
93
.. _GANETI_NODES:
94
.. _GANETI_MASTER:
95
.. _GANETI_NODE:
96
  
97
GANETI-MASTER and GANETI-NODE
98
*****************************
99
A single GANETI-MASTER and a large number of GANETI-NODEs constitute the
100
Ganeti backend for synnefo, which undertakes all VM management functions.
101
Any APISERVER can issue commands to the GANETI-MASTER, over RAPI, to effect
102
changes in the state of the VMs. The GANETI-MASTER runs the Ganeti request
103
queue.
104

  
105
*Services:*
106
    * only on :ref:`GANETI-MASTER <GANETI_MASTER>`:
107
        * the synnefo Ganeti monitoring daemon, ``snf-ganeti-eventd``
108
        * the synnefo Ganeti hook, ``ganeti/snf-ganeti-hook.py``.
109
    * on every :ref:`GANETI-NODE <GANETI_NODE>`:
110
        * a deployment-specific KVM ifup script
111
        * properly configured :ref:`NFDHCPD <asterias-nfdhcpd-setup>`
112

  
113
.. _WEBAPP_NODE:
114

  
115
Installation
116
------------
117

  
118
Installation of asterias is a two step process:
119

  
120
1. install the external services (prerequisites) on which asterias depends
121
2. install the synnefo software components associated with asterias
122

  
123
Prerequisites
124
*************
125
.. _asterias-install-ganeti:
126

  
127
Ganeti installation
128
```````````````````
129
Synnefo requires a working Ganeti installation at the backend. Installation
130
of Ganeti is not covered by this document, please refer to
131
`ganeti documentation <http://docs.ganeti.org/ganeti/current/html>`_ for all the 
132
gory details. A successful Ganeti installation concludes with a working 
133
:ref:`GANETI-MASTER <GANETI_NODES>` and a number of :ref:`GANETI-NODEs <GANETI_NODES>`.
134

  
135
.. _asterias-install-db:
136

  
137
Database
138
````````
139

  
140
Database installation is done as part of the
141
:ref:`snf-webproject <snf-webproject>` component.
142

  
143
.. _asterias-install-rabbitmq:
144

  
145
RabbitMQ 
146
````````
147

  
148
RabbitMQ is used as a generic message broker for asterias. It should be
149
installed on two seperate :ref:`QUEUE <QUEUE_NODE>` nodes in a high availability
150
configuration as described here:
151

  
152
    http://www.rabbitmq.com/pacemaker.html
153

  
154
After installation, create a user and set its permissions:
155

  
156
.. code-block:: console
157

  
158
    $ rabbitmqctl add_user <username> <password>
159
    $ rabbitmqctl set_permissions -p / <username>  "^.*" ".*" ".*"
160

  
161
The values set for the user and password must be mirrored in the
162
``RABBIT_*`` variables in your settings, as managed by
163
:ref:`snf-common <snf-common>`.
164

  
165
.. todo:: Document an active-active configuration based on the latest version
166
   of RabbitMQ.
167

  
168
.. _asterias-install-vncauthproxy:
169

  
170
vncauthproxy
171
````````````
172

  
173
To support OOB console access to the VMs over VNC, the vncauthproxy
174
daemon must be running on every :ref:`APISERVER <APISERVER_NODE>` node.
175

  
176
.. note:: The Debian package for vncauthproxy undertakes all configuration
177
   automatically.
178

  
179
Download and install the latest vncauthproxy from its own repository,
180
at `https://code.grnet.gr/git/vncauthproxy`, or a specific commit:
181

  
182
.. code-block:: console
183

  
184
    $ bin/pip install -e git+https://code.grnet.gr/git/vncauthproxy@INSERT_COMMIT_HERE#egg=vncauthproxy
185

  
186
Create ``/var/log/vncauthproxy`` and set its permissions appropriately.
187

  
188
Alternatively, build and install Debian packages.
189

  
190
.. code-block:: console
191

  
192
    $ git checkout debian
193
    $ dpkg-buildpackage -b -uc -us
194
    # dpkg -i ../vncauthproxy_1.0-1_all.deb
195

  
196
.. warning::
197
    **Failure to build the package on the Mac.**
198

  
199
    ``libevent``, a requirement for gevent which in turn is a requirement for
200
    vncauthproxy is not included in `MacOSX` by default and installing it with
201
    MacPorts does not lead to a version that can be found by the gevent
202
    build process. A quick workaround is to execute the following commands::
203

  
204
        $ cd $SYNNEFO
205
        $ sudo pip install -e git+https://code.grnet.gr/git/vncauthproxy@5a196d8481e171a#egg=vncauthproxy
206
        <the above fails>
207
        $ cd build/gevent
208
        $ sudo python setup.py -I/opt/local/include -L/opt/local/lib build
209
        $ cd $SYNNEFO
210
        $ sudo pip install -e git+https://code.grnet.gr/git/vncauthproxy@5a196d8481e171a#egg=vncauthproxy
211

  
212
.. todo:: Mention vncauthproxy bug, snf-vncauthproxy, inability to install using pip
213
.. todo:: kpap: fix installation commands
214

  
215
.. _asterias-install-nfdhcpd:
216

  
217
NFDHCPD
218
```````
219

  
220
Setup Synnefo-specific networking on the Ganeti backend.
221
This part is deployment-specific and must be customized based on the
222
specific needs of the system administrators.
223

  
224
A reference installation will use a Synnefo-specific KVM ifup script,
225
NFDHCPD and pre-provisioned Linux bridges to support public and private
226
network functionality. For this:
227

  
228
Grab NFDHCPD from its own repository (https://code.grnet.gr/git/nfdhcpd),
229
install it, modify ``/etc/nfdhcpd/nfdhcpd.conf`` to reflect your network
230
configuration.
231

  
232
Install a custom KVM ifup script for use by Ganeti, as
233
``/etc/ganeti/kvm-vif-bridge``, on GANETI-NODEs. A sample implementation is
234
provided under ``/contrib/ganeti-hooks``. Set ``NFDHCPD_STATE_DIR`` to point
235
to NFDHCPD's state directory, usually ``/var/lib/nfdhcpd``.
236

  
237
.. todo:: soc: document NFDHCPD installation, settle on KVM ifup script
238

  
239
.. _asterias-install-snfimage:
240

  
241
snf-image
242
`````````
243

  
244
Install the :ref:`snf-image <snf-image>` Ganeti OS provider for image
245
deployment.
246

  
247
For :ref:`asterias <asterias>` to be able to launch VMs from specified
248
Images, you need the snf-image OS Provider installed on *all* Ganeti nodes.
249

  
250
Please see `https://code.grnet.gr/projects/snf-image/wiki`_
251
for installation instructions and documentation on the design
252
and implementation of snf-image.
253

  
254
Please see `https://code.grnet.gr/projects/snf-image/files`
255
for the latest packages.
256

  
257
Images should be stored in ``extdump``, or ``diskdump`` format in a directory
258
of your choice, configurable as ``IMAGE_DIR`` in 
259
:file:`/etc/default/snf-image`.
260

  
261
synnefo components
262
******************
263

  
264
You need to install the appropriate synnefo software components on each node,
265
depending on its type, see :ref:`Architecture <asterias-architecture>`.
266

  
267
Most synnefo components have dependencies on additional Python packages.
268
The dependencies are described inside each package, and are setup
269
automatically when installing using :command:`pip`, or when installing 
270
using your system's package manager.
271

  
272
Please see the page of each synnefo software component for specific
273
installation instructions, where applicable.
274

  
275
Install the following synnefo components:
276

  
277
Nodes of type :ref:`APISERVER <APISERVER_NODE>`
278
    Components
279
    :ref:`snf-common <snf-common>`,
280
    :ref:`snf-webproject <snf-webproject>`,
281
    :ref:`snf-asterias-app <snf-asterias-app>`
282
Nodes of type :ref:`GANETI-MASTER <GANETI_MASTER>` and :ref:`GANETI-NODE <GANETI_NODE>`
283
    Components
284
    :ref:`snf-common <snf-common>`,
285
    :ref:`snf-asterias-ganeti-tools <snf-asterias-ganeti-tools>`
286
Nodes of type :ref:`LOGIC <LOGIC_NODE>`
287
    Components
288
    :ref:`snf-common <snf-common>`,
289
    :ref:`snf-webproject <snf-webproject>`,
290
    :ref:`snf-asterias-app <snf-asterias-app>`.
291

  
292
Configuration
293
-------------
294

  
295
This section targets the configuration of the prerequisites for asterias,
296
and the configuration of the associated synnefo software components.
297

  
298
synnefo components
299
******************
300

  
301
asterias uses :ref:`snf-common <snf-common>` for settings.
302
Please refer to the configuration sections of
303
:ref:`snf-webproject <snf-webproject>`,
304
:ref:`snf-asterias-app <snf-asterias-app>`,
305
:ref:`snf-asterias-ganeti-tools <snf-asterias-ganeti-tools>` for more
306
information on their configuration.
307

  
308
Ganeti
309
``````
310

  
311
Set ``GANETI_NODES``, ``GANETI_MASTER_IP``, ``GANETI_CLUSTER_INFO`` based on
312
your :ref:`Ganeti installation <asterias-install-ganeti>` and change the
313
`BACKEND_PREFIX_ID`` setting, using an custom ``PREFIX_ID``.
314

  
315
Database
316
````````
317

  
318
Once all components are installed and configured,
319
initialize the Django DB:
320

  
321
.. code-block:: console
322

  
323
   $ snf-manage syncdb
324
   $ snf-manage migrate
325

  
326
and load fixtures ``{users, flavors, images}``, 
327
which make the API usable by end users by defining a sample set of users, 
328
hardware configurations (flavors) and OS images:
329

  
330
.. code-block:: console
331

  
332
   $ snf-manage loaddata /path/to/users.json
333
   $ snf-manage loaddata flavors
334
   $ snf-manage loaddata images
335

  
336
.. warning:: 
337
    Be sure to load a custom users.json and select a unique token 
338
    for each of the initial and any other users defined in this file. 
339
    **DO NOT LEAVE THE SAMPLE AUTHENTICATION TOKENS** enabled in deployed
340
    configurations.
341

  
342
sample users.json file:
343

  
344
.. literalinclude:: ../../synnefo/db/fixtures/users.json
345

  
346
`download <../_static/users.json>`_
347

  
348
RabbitMQ
349
````````
350

  
351
Change ``RABBIT_*`` settings to match your :ref:`RabbitMQ setup
352
<asterias-install-rabbitmq>`.
353

  
354
.. include:: ../../Changelog
/dev/null
1
Administration Tools User's Guide
2
=================================
3

  
4
Configure kamaki
5
----------------
6

  
7
To upload, register or modify an image you will need the **kamaki** tool.
8
Before proceeding make sure that it is configured properly. Verify that
9
*image_url*, *storage_url*, *storage_account*, *storage_container* and
10
*token* are set as needed::
11

  
12
  kamaki config list
13

  
14
To chage a setting use ``kamaki config set``::
15

  
16
  kamaki config set storage_account okeanos
17
  kamaki config set storage_container images
18
  kamaki config set token ...
19

  
20

  
21
Upload an image
22
---------------
23

  
24
You are now ready to upload an image. You can upload it with a Pithos client
25
or use kamaki directly::
26

  
27
  kamaki store upload ubuntu.iso
28

  
29
You can use any Pithos client to verify that the image was uploaded correctly.
30

  
31

  
32
Register the image
33
------------------
34

  
35
To register an image you will need to use the full Pithos URL. To register as
36
a public image the one from the previous example use::
37

  
38
  kamaki glance register Ubuntu pithos://okeanos/images/ubuntu.iso --public
39

  
40
Use ``kamaki glance register`` with no arguments to see a list of available
41
options. A more complete example would be the following::
42

  
43
  kamaki glance register Ubuntu pithos://okeanos/images/ubuntu.iso --public \
44
      --disk-format diskdump --property kernel=3.1.2
45

  
46
To verify that the image was registered successfully use::
47

  
48
  kamaki glance list -l
/dev/null
1
API Guide
2
*********
3

  
4
.. todo:: Document the relation of the API to the OpenStack API v1.1.
5

  
6
This is the guide to the REST API of the synnefo Compute Service.
7
It is meant for users wishing to make calls to the REST API directly.
8

  
9
The :ref:`kamaki <http://docs.dev.grnet.gr/kamaki>` command-line client
10
and associated python library can be used instead of making direct calls to
11
:ref:`asterias <asterias>`.
12

  
13
Overview
14
========
15

  
16
* It is not defined if requests for invalid URLs should return 404 or a Fault.
17
  We return a BadRequest Fault.
18
* It is not defined if requests with a wrong HTTP method should return 405 or a
19
  Fault. We return a BadRequest Fault.
20

  
21

  
22
General API Information
23
=======================
24

  
25
Authentication
26
--------------
27

  
28
* Authentication support is missing.
29

  
30

  
31
Request/Response Types
32
----------------------
33

  
34
* We only support JSON Requests and JSON/XML Responses. XML Requests are not
35
  supported for now.
36

  
37

  
38
Content Compression
39
-------------------
40

  
41
* Optional content compression support is missing.
42

  
43

  
44
Persistent Connections
45
----------------------
46

  
47
* Deployment note: "To prevent abuse, HTTP sessions have a timeout of 20
48
  seconds before being closed."
49

  
50

  
51
Links and References
52
--------------------
53

  
54
* Full URI references support is missing.
55
* Self and bookmark links support is missing.
56

  
57

  
58
Paginated Collections
59
---------------------
60

  
61
* Pagination support is missing.
62

  
63

  
64
Caching
65
-------
66

  
67
* We do not return cached responses.
68

  
69

  
70
Limits
71
------
72

  
73
 * Limits support is missing.
74

  
75

  
76
Efficient Polling with the Changes-Since Parameter
77
--------------------------------------------------
78

  
79
* We only support the changes-since parameter in **List Servers** and **List
80
  Images**.
81
* We assume that garbage collection of deleted servers will only affect servers
82
  deleted ``POLL_TIME`` seconds in the past or earlier. Else we lose the
83
  information of a server getting deleted.
84
* Images do not support a deleted state, so we can not track deletions.
85

  
86

  
87
Versions
88
--------
89

  
90
* Version MIME type support is missing.
91
* Versionless requests are not supported.
92
* We hardcode the ``updated`` field in versions list
93
* Deployment note: The Atom metadata need to be fixed
94

  
95

  
96
Extensions
97
----------
98

  
99
* Extensions support is missing.
100

  
101

  
102
Faults
103
------
104

  
105

  
106
API Operations
107
==============
108

  
109
Servers
110
-------
111

  
112
* ``hostId`` is always empty.
113
* ``affinityId`` is not returned.
114
* ``progress`` is always returned.
115
* ``self`` and ``bookmark`` atom links are not returned.
116
* **Get Server Details** will also return servers with a DELETED state.
117
* **Create Server** ignores ``personality`` of requests.
118
* **Create Server** ignores the disk size of the flavor.
119
* **Create Server** hardcodes the OS.
120
* **Create Server** does not support setting the password in the request.
121

  
122
List Servers
123
............
124

  
125
* **List Servers** returns just ``id`` and ``name`` if details are not
126
  requested.
127
* **List Servers** can return 304 (even though not explicitly stated) when
128
  ``changes-since`` is given.
129

  
130
**Example List Servers: JSON**
131

  
132
.. code-block:: javascript
133

  
134
  {
135
      'servers':
136
          {'values': [
137
              {
138
                  'addresses': {'values': [
139
                          {
140
                              'id': 'public',
141
                              'mac': 'aa:00:00:49:2e:7e',
142
                              'name': 'public',
143
                              'values': [ {'addr': '192.168.32.6', 'version': 4} ]
144
                          }
145
                  ]},
146
                  'created': '2011-04-19T10:18:52.085737+00:00',
147
                  'flavorRef': 1,
148
                  'hostId': '',
149
                  'id': 1,
150
                  'imageRef': 3,
151
                  'metadata': {'values': {'foo': 'bar'}},
152
                  'name': 'My Server',
153
                  'status': 'ACTIVE',
154
                  'updated': u'2011-05-29T14:07:07.037602+00:00'
155
              },
156
              {
157
                  'addresses': {'values': [
158
                          {
159
                              'id': 'public',
160
                              'mac': 'aa:00:00:91:2f:df',
161
                              'name': 'public',
162
                              'values': [ {'addr': '192.168.32.7', 'version': 4} ]
163
                          },
164
                          {
165
                              'id': '2',
166
                              'mac': 'aa:00:00:c3:69:6f',
167
                              'name': 'private'
168
                          },
169
                  ]},
170
                  'created': '2011-05-02T20:51:08.527759+00:00',
171
                  'flavorRef': 1,
172
                  'hostId': '',
173
                  'id': 2,
174
                  'imageRef': 3,
175
                  'name': 'Other Server',
176
                  'progress': 0,
177
                  'status': 'ACTIVE',
178
                  'updated': '2011-05-29T14:59:11.267087+00:00'
179
              }
180
          ]
181
      }
182
  }
183

  
184

  
185
Get Server Stats
186
................
187

  
188
**GET** /servers/*id*/stats
189

  
190
**Normal Response Code**: 200
191

  
192
**Error Response Codes**: computeFault (400, 500), serviceUnavailable (503),
193
unauthorized (401), badRequest (400), itemNotFound (404), overLimit (413)
194

  
195
This operation returns URLs to graphs showing CPU and Network statistics. A
196
``refresh`` attribute is returned as well that is the recommended refresh rate
197
of the stats for the clients.
198

  
199
This operation does not require a request body.
200

  
201
**Example Get Server Stats Response: JSON**:
202

  
203
.. code-block:: javascript
204

  
205
  {
206
      "stats": {
207
          "serverRef": 1,
208
          "refresh": 60,
209
          "cpuBar": "http://stats.okeanos.grnet.gr/b9a1c3ca7e3b9fce75112c43565fb9960b16048c/cpu-bar.png",
210
          "cpuTimeSeries": "http://stats.okeanos.grnet.gr/b9a1c3ca7e3b9fce75112c43565fb9960b16048c/cpu-ts.png",
211
          "netBar": "http://stats.okeanos.grnet.gr/b9a1c3ca7e3b9fce75112c43565fb9960b16048c/net-bar.png",
212
          "netTimeSeries": "http://stats.okeanos.grnet.gr/b9a1c3ca7e3b9fce75112c43565fb9960b16048c/net-ts.png"
213
      }
214
  }
215

  
216
**Example Get Network Details Response: XML**:
217

  
218
.. code-block:: xml
219

  
220
  <?xml version="1.0" encoding="UTF-8"?>
221
  <stats xmlns="http://docs.openstack.org/compute/api/v1.1" xmlns:atom="http://www.w3.org/2005/Atom"
222
      serverRef="1"
223
      refresh="60"
224
      cpuBar="http://stats.okeanos.grnet.gr/b9a1c3ca7e3b9fce75112c43565fb9960b16048c/cpu-bar.png"
225
      cpuTimeSeries="http://stats.okeanos.grnet.gr/b9a1c3ca7e3b9fce75112c43565fb9960b16048c/cpu-ts.png"
226
      netBar="http://stats.okeanos.grnet.gr/b9a1c3ca7e3b9fce75112c43565fb9960b16048c/net-bar.png"
227
      netTimeSeries="http://stats.okeanos.grnet.gr/b9a1c3ca7e3b9fce75112c43565fb9960b16048c/net-ts.png">
228
  </stats>
229

  
230

  
231
Server Addresses
232
----------------
233

  
234
Server Actions
235
--------------
236

  
237
* **Change Password** is not supported.
238
* **Rebuild Server** is not supported.
239
* **Resize Server** is not supported.
240
* **Confirm Resized Server** is not supported.
241
* **Revert Resized Server** is not supported.
242

  
243
We have have extended the API with the following commands:
244

  
245

  
246
Start Server
247
............
248

  
249
**Normal Response Code**: 202
250

  
251
**Error Response Codes**: serviceUnavailable (503), itemNotFound (404)
252

  
253
The start function transitions a server from an ACTIVE to a STOPPED state.
254

  
255
**Example Action Start: JSON**:
256

  
257
.. code-block:: javascript
258

  
259
  {
260
      "start": {}
261
  }
262

  
263
This operation does not return a response body.
264

  
265

  
266
Shutdown Server
267
...............
268

  
269
**Normal Response Code**: 202
270

  
271
**Error Response Codes**: serviceUnavailable (503), itemNotFound (404)
272

  
273
The start function transitions a server from a STOPPED to an ACTIVE state.
274

  
275
**Example Action Shutdown: JSON**:
276

  
277
.. code-block:: javascript
278

  
279
  {
280
      "shutdown": {}
281
  }
282

  
283
This operation does not return a response body.
284

  
285

  
286
Get Server Console
287

  
288
**Normal Response Code**: 200
289

  
290
**Error Response Codes**: computeFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest (400), badMediaType(415), itemNotFound (404), buildInProgress (409), overLimit (413)
291

  
292
The console function arranges for an OOB console of the specified type. Only consoles of type "vnc" are supported for now.
293
    
294
It uses a running instance of vncauthproxy to setup proper VNC forwarding with a random password, then returns the necessary VNC connection info to the caller.
295

  
296
**Example Action Console: JSON**:
297

  
298
.. code-block:: javascript
299

  
300
  {
301
      "console": {
302
          "type": "vnc"
303
      }
304
  }
305

  
306
**Example Action Console Response: JSON**:
307

  
308
.. code-block:: javascript
309

  
310
  {
311
      "console": {
312
          "type": "vnc",
313
          "host": "vm42.ocean.grnet.gr",
314
          "port": 1234,
315
          "password": "IN9RNmaV"
316
      }
317
  }
318

  
319
**Example Action Console Response: XML**:
320

  
321
.. code-block:: xml
322

  
323
  <?xml version="1.0" encoding="UTF-8"?>
324
  <console xmlns="http://docs.openstack.org/compute/api/v1.1" xmlns:atom="http://www.w3.org/2005/Atom"
325
      type="vnc"
326
      host="vm42.ocean.grnet.gr"
327
      port="1234"
328
      password="IN9RNmaV">
329
  </console>
330

  
331

  
332
Set Firewall Profile
333
....................
334

  
335
**Normal Response Code**: 202
336

  
337
**Error Response Codes**: computeFault (400, 500), serviceUnavailable (503),
338
unauthorized (401), badRequest (400), badMediaType(415), itemNotFound (404),
339
buildInProgress (409), overLimit (413)
340

  
341
The firewallProfile function sets a firewall profile for the public interface
342
of a server.
343

  
344
The allowed profiles are: **ENABLED**, **DISABLED** and **PROTECTED**.
345

  
346
**Example Action firewallProfile: JSON**:
347

  
348
.. code-block:: javascript
349

  
350
  {
351
      "firewallProfile": {
352
          "profile": "ENABLED"
353
      }
354
  }
355

  
356
This operation does not return a response body.
357

  
358

  
359
Flavors
360
-------
361

  
362
* ``self`` and ``bookmark`` atom links are not returned.
363
* **List Flavors** returns just ``id`` and ``name`` if details is not requested.
364

  
365

  
366
Images
367
------
368

  
369
* ``progress`` is always returned.
370
* ``self`` and ``bookmark`` atom links are not returned.
371
* **List Images** returns just ``id`` and ``name`` if details are not requested.
372
* **List Images** can return 304 (even though not explicitly stated) when
373
  ``changes-since`` is given. 
374
* **List Images** does not return deleted images when ``changes-since`` is given.
375

  
376

  
377
Metadata
378
--------
379

  
380
* **Update Server Metadata** and **Update Image Metadata** will only return the
381
  metadata that were updated (some could have been skipped).
382

  
383

  
384
Networks
385
--------
386

  
387
This is an extension to the OpenStack API.
388

  
389
A Server can connect to one or more networks identified by a numeric id. Each
390
user has access only to networks created by himself. When a network is deleted,
391
all connections to it are deleted. Likewise, when a server is deleted, all
392
connections of that server are deleted.
393

  
394
There is a special **public** network with the id *public* that can be accessed
395
at */networks/public*. All servers are connected to **public** by default and
396
this network can not be deleted or modified in any way.
397

  
398

  
399
List Networks
400
.............
401

  
402
**GET** /networks
403

  
404
**GET** /networks/detail
405

  
406
**Normal Response Codes**: 200, 203
407

  
408
**Error Response Codes**: computeFault (400, 500), serviceUnavailable (503),
409
unauthorized (401), badRequest (400), overLimit (413)
410

  
411
This operation provides a list of private networks associated with your account.
412

  
413
This operation does not require a request body.
414

  
415
**Example Networks List Response: JSON (detail)**:
416

  
417
.. code-block:: javascript
418

  
419
  {
420
      "networks": {
421
          "values": [
422
              {
423
                  "id": "public",
424
                  "name": "public",
425
                  "created": "2011-04-20T15:31:08.199640+00:00",
426
                  "updated": "2011-05-06T12:47:05.582679+00:00",
427
                  "servers": {
428
                      "values": [1, 2, 3]
429
                  }
430
              },
431
              {
432
                  "id": 2,
433
                  "name": "private",
434
                  "created": "2011-04-20T14:32:08.199640+00:00",
435
                  "updated": "2011-05-06T11:40:05.582679+00:00",
436
                  "servers": {
437
                      "values": [1]
438
                  }
439
              }
440
          ]
441
      }
442
  }
443

  
444
**Example Networks List Response: XML (detail)**:
445

  
446
.. code-block:: xml
447

  
448
  <?xml version="1.0" encoding="UTF-8"?>
449
  <networks xmlns="http://docs.openstack.org/compute/api/v1.1" xmlns:atom="http://www.w3.org/2005/Atom">
450
    <network id="public" name="public" updated="2011-05-02T21:33:25.606672+00:00" created="2011-04-20T15:31:08.199640+00:00">
451
      <servers>
452
        <server id="1"></server>
453
        <server id="2"></server>
454
        <server id="3"></server>
455
      </servers>
456
    </network>
457
    <network id="2" name="private" updated="2011-05-06T12:47:05.582679+00:00" created="2011-04-20T15:31:33.911299+00:00">
458
      <servers>
459
        <server id="1"></server>
460
      </servers>
461
    </network>
462
  </networks>
463

  
464

  
465
Create Network
466
..............
467

  
468
**POST** /networks
469

  
470
**Normal Response Code**: 202
471

  
472
**Error Response Codes**: computeFault (400, 500), serviceUnavailable (503),
473
unauthorized (401), badMediaType(415), badRequest (400), overLimit (413)
474

  
475
This operation asynchronously provisions a new private network.
476

  
477
**Example Create Network Request: JSON**:
478

  
479
.. code-block:: javascript
480

  
481
  {
482
      "network": {
483
          "name": "private_net",
484
      }
485
  }
486

  
487
**Example Create Network Response: JSON**:
488

  
489
.. code-block:: javascript
490

  
491
  {
492
      "network": {
493
          "id": 3,
494
          "name": "private_net",
495
          "created": "2011-04-20T15:31:08.199640+00:00",
496
          "servers": {
497
              "values": []
498
          }
499
      }
500
  }
501

  
502
**Example Create Network Response: XML**:
503

  
504
.. code-block:: xml
505

  
506
  <?xml version="1.0" encoding="UTF-8"?>
507
  <network xmlns="http://docs.openstack.org/compute/api/v1.1" xmlns:atom="http://www.w3.org/2005/Atom"
508
   id="2" name="foob" created="2011-04-20T15:31:08.199640+00:00">
509
    <servers>
510
    </servers>
511
  </network>
512

  
513

  
514
Get Network Details
515
...................
516

  
517
**GET** /networks/*id*
518

  
519
**Normal Response Codes**: 200, 203
520

  
521
**Error Response Codes**: computeFault (400, 500), serviceUnavailable (503),
522
unauthorized (401), badRequest (400), itemNotFound (404), overLimit (413)
523

  
524
This operation returns the details of a specific network by its id.
525

  
526
This operation does not require a request body.
527

  
528
**Example Get Network Details Response: JSON**:
529

  
530
.. code-block:: javascript
531

  
532
  {
533
      "network": {
534
          "id": 3,
535
          "name": "private_net",
536
          "servers": {
537
              "values": [1, 7]
538
          }
539
      }
540
  }
541

  
542
**Example Get Network Details Response: XML**::
543

  
544
  <?xml version="1.0" encoding="UTF-8"?>
545
  <network xmlns="http://docs.openstack.org/compute/api/v1.1" xmlns:atom="http://www.w3.org/2005/Atom"
546
   id="2" name="foob" updated="2011-05-02T21:33:25.606672+00:00" created="2011-04-20T15:31:08.199640+00:00">
547
    <servers>
548
      <server id="1"></server>
549
      <server id="7"></server>
550
    </servers>
551
  </network>
552

  
553

  
554
Update Network Name
555
...................
556

  
557
**PUT** /networks/*id*
558

  
559
**Normal Response Code**: 204
560

  
561
**Error Response Codes**: computeFault (400, 500), serviceUnavailable (503),
562
unauthorized (401), badRequest (400), badMediaType(415), itemNotFound (404),
563
overLimit (413) 
564

  
565
This operation changes the name of the network in the Compute system.
566

  
567
**Example Update Network Name Request: JSON**::
568

  
569
.. code-block:: javascript
570

  
571
  {
572
      "network": {
573
          "name": "new_name"
574
      }
575
  }
576

  
577
This operation does not contain a response body.
578

  
579

  
580
Delete Network
581
..............
582

  
583
**DELETE** /networks/*id*
584

  
585
**Normal Response Code**: 204
586

  
587
**Error Response Codes**: computeFault (400, 500), serviceUnavailable (503),
588
unauthorized (401), itemNotFound (404), unauthorized (401), overLimit (413) 
589

  
590
This operation deletes a network from the system.
591

  
592
This operation does not require a request or a response body.
593

  
594

  
595
Network Actions
596
---------------
597

  
598
Add Server
599
..........
600

  
601
**POST** /networks/*id*/action
602

  
603
**Normal Response Code**: 202
604

  
605
**Error Response Codes**: computeFault (400, 500), serviceUnavailable (503),
606
unauthorized (401), badRequest (400), badMediaType(415), itemNotFound (404),
607
overLimit (413)
608

  
609
This operation adds a server to the specified network.
610

  
611
**Example Action Add: JSON**:
612

  
613
.. code-block:: javascript
614

  
615
  {
616
      "add" : {
617
          "serverRef" : 42
618
      }
619
  }
620

  
621
This operation does not contain a response body.
622

  
623

  
624
Remove Server
625
.............
626

  
627
**POST** /networks/*id*/action
628

  
629
**Normal Response Code**: 202
630

  
631
**Error Response Codes**: computeFault (400, 500), serviceUnavailable (503),
632
unauthorized (401), badRequest (400), badMediaType(415), itemNotFound (404),
633
overLimit (413)
634

  
635
This operation removes a server from the specified network.
636

  
637
**Example Action Remove: JSON**:
638

  
639
.. code-block:: javascript
640

  
641
  {
642
      "remove" : {
643
          "serverRef" : 42
644
      }
645
  }
646

  
647
This operation does not contain a response body.
/dev/null
1
.. _asterias-developer-guide:
2

  
3
===============
4
Developer Guide
5
===============
6

  
7
This is the asterias developer guide.
8

  
9
It is intended for developers, wishing to implement new functionality
10
inside :ref:`asterias <asterias>`.
11

  
12
It assumes thorough familiarity with the :ref:`asterias-admin-guide`.
13

  
14
Building a dev environment
15
--------------------------
16

  
17
virtualenv
18
**********
19

  
20
The easiest method to deploy a development environment is using
21
:command:`virtualenv`. Alternatively, you can use your system's package manager
22
to install any dependencies of synnefo components (e.g. Macports has them all).
23

  
24
   .. code-block:: console
25
   
26
      $ virtualenv ~/synnefo-env
27
      $ source ~/synnefo-env/bin/activate
28
      (synnefo-env)$ 
29

  
30
Virtualenv creates an isolated python environment to the path you pass as the
31
first argument of the command. That means that all packages you install using
32
:command:`pip` or :command:`easy_install` will be placed in
33
``ENV/lib/pythonX.X/site-packages`` and their console scripts in ``ENV/bin/``.
34

  
35
This allows you to develop against multiple versions of packages that your
36
software depends on without messing with system python packages that may be
37
needed in specific versions for other software you have installed on your
38
system.
39

  
40
* It is also recommended to install development helpers:
41

  
42
  .. code-block:: console
43
 
44
     (synnefo-env)$ pip install django_extensions fabric>=1.3
45

  
46
* Create a custom settings directory for :ref:`snf-common <snf-common>` and set
47
  the ``SYNNEFO_SETTINGS_DIR`` environment variable to use development-specific
48
  file:`*.conf` files inside this directory.
49

  
50
  (synnefo-env)$ mkdir ~/synnefo-settings-dir
51
  (synnefo-env)$ export SYNNEFO_SETTINGS_DIR=~/synnefo-settings-dir
52
    
53
  Insert your custom settings in a file such as :file:`$SYNNEFO_SETTINGS_DIR/99-local.conf`:
54

  
55
  .. code-block:: python
56
    
57
        # uncomment this if have django-extensions installed (pip install django_extensions)
58
        #INSTALLED_APPS = list(INSTALLED_APPS) + ['django_extensions']
59

  
60
        DEV_PATH = os.path.abspath(os.path.dirname(__file__))
61
        DATABASES['default']['NAME'] = os.path.join(DEV_PATH, "synnefo.sqlite")
62

  
63
        # development rabitmq configuration
64
        RABBIT_HOST = "<RabbitMQ_host>"
65
        RABBIT_USERNAME = "<RabbitMQ_username>"
66
        RABBIT_PASSWORD = "<RabbitMQ_password>"
67
        RABBIT_VHOST = "/"
68

  
69
        # development ganeti settings
70
        GANETI_MASTER_IP = "<Ganeti_master_IP>"
71
        GANETI_CLUSTER_INFO = (GANETI_MASTER_IP, 5080, "<username>", "<password>")
72
        GANETI_CREATEINSTANCE_KWARGS['disk_template'] = 'plain'
73

  
74
        # This prefix gets used when determining the instance names
75
        # of Synnefo VMs at the Ganeti backend.
76
        # The dash must always appear in the name!
77
        BACKEND_PREFIX_ID = "<your_commit_name>-"
78

  
79
        IGNORE_FLAVOR_DISK_SIZES = True
80

  
81
        # do not actually send emails
82
        # save them as files in /tmp/synnefo-mails
83
        EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
84
        EMAIL_FILE_PATH = '/tmp/synnefo-mails'
85

  
86
        # for UI developers
87
        UI_HANDLE_WINDOW_EXCEPTIONS = False
88

  
89
        # allow login using /?test url
90
        BYPASS_AUTHENTICATION = True 
91

  
92
synnefo source
93
**************
94

  
95
* Clone the repository of the synnefo software components you wish
96
  to work on, e.g.:
97

  
98
   .. code-block:: console
99
   
100
     (synnefo-env)$ git clone https://code.grnet.gr/git/synnefo synnefo
101
     (synnefo-env)$ git clone https://code.grnet.gr/git/pithos pithos
102
   
103
* Install the software components you wish to work on inside the
104
  virtualenv, in development mode:
105

  
106
   .. code-block:: console
107
   
108
      (synnefo-env)$ cd snf-asterias-app
109
      (synnefo-env)$ python setup.py develop -N
110
   
111
* Initialize database:
112

  
113
   .. code-block:: console
114
     
115
      (synnefo-env)$ snf-manage syndb
116
      (synnefo-env)$ snf-manage migrate
117
      (synnefo-env)$ snf-manage loaddata users flavors images
118
  
119
Development tips
120
****************
121

  
122
* Running a development web server:
123

  
124
  .. code-block:: console
125

  
126
     (synnefo-env)$ snf-manage runserver
127

  
128
  or, if you have the ``django_extensions`` and ``werkzeug`` packages installed:
129

  
130
  .. code-block:: console
131

  
132
     (synnefo-env)$ snf-manage runserver_plus
133

  
134
* Opening a python console with the synnefo environment initialized:
135

  
136
  .. code-block:: console
137

  
138
     (synnefo-env)$ snf-manage shell
139

  
140
  or, with the django_extensions package installed:
141

  
142
  .. code-block:: console
143
     
144
     (synnefo-env)$ snf-manage shell_plus
145

  
146

  
147
South Database Migrations
148
-------------------------
149

  
150
.. _asterias-dev-initialmigration:
151

  
152
Initial Migration
153
*****************
154

  
155
To initialize south migrations in your database the following commands must be
156
executed:
157

  
158
.. code-block:: console
159

  
160
   $ snf-manage syncdb --all      # Create / update the database with the south tables
161
   $ snf-manage migrate --fake    # Perform migration in the database
162

  
163

  
164
Note that ``--all`` and ``--fake`` arguments are only needed when you are
165
initializing your database. If you want to migrate a previously create databse
166
to the latest db scheme just run the same commands without those arguments.
167

  
168
If you are trying to migrate a database that already contains the changes that
169
applied from a specific migration script, ``south`` will probably notify you for
170
inconsistent db scheme, a workaround for that issue is to use ``--fake`` option
171
for a specific migration.
172

  
173
For example:
174

  
175

  
176
.. code-block:: console
177

  
178
   $ snf-manage migrate db 0001 --fake
179

  
180
To be sure that all migrations are applied use:
181

  
182
.. code-block:: console
183

  
184
   $ snf-manage migrate db --list
185

  
186
All starred migrations are applied.
187

  
188
Schema migrations
189
*****************
190

  
191
Do not use the syncdb management command. It can only be used the first time
192
and/or if you drop the database and must recreate it from scratch. See
193
:ref:`asterias-dev-initialmigration`.
194

  
195

  
196
Every time you make changes to the database and data migration is not required
197
(WARNING: always perform this with extreme care):
198

  
199
.. code-block:: console
200
   
201
   $ snf-manage schemamigration db --auto
202

  
203
The above will create the migration script. Now this must be applied to the live
204
database:
205

  
206
.. code-block:: console
207

  
208
   $ snf-manage migrate db
209

  
210
Consider this example (adding a field to the ``SynnefoUser`` model):
211

  
212
.. code-block:: console
213

  
214
   $ ./bin/python manage.py schemamigration db --auto
215
   + Added field new_south_test_field on db.SynnefoUser
216

  
217
   Created 0002_auto__add_field_synnefouser_new_south_test_field.py.
218

  
219
You can now apply this migration with:
220

  
221
.. code-block:: console
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

  
229
   Installing json fixture 'initial_data' from '/home/bkarak/devel/synnefo/../synnefo/db/fixtures'.
230
   Installed 1 object(s) from 1 fixture(s)
231

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

  
236
.. code-block:: console
237

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

  
246
Data migrations
247
***************
248

  
249
To do data migration as well, for example rename a field, use the
250
``datamigration`` management command.
251

  
252
In contrast with ``schemamigration``, to perform complex data migration, we
253
must write the script manually. The process is the following:
254

  
255
1. Introduce the changes in the code and fixtures (initial data).
256
2. Execute:
257

  
258
   .. code-block:: console
259

  
260
      $ snf-manage datamigration <migration_name_here>
261

  
262
   For example:
263

  
264
   .. code-block:: console
265

  
266
      $ ./bin/python manage.py datamigration db rename_credit_wallet
267
      Created 0003_rename_credit_wallet.py.
268

  
269
3. Edit the generated script. It contains two methods, ``forwards`` and
270
   ``backwards``.
271

  
272
   For database operations (column additions, alter tables etc), use the
273
   South database API (http://south.aeracode.org/docs/databaseapi.html).
274

  
275
   To access the data, use the database reference (``orm``) provided as
276
   parameter in ``forwards``, ``backwards`` method declarations in the
277
   migration script. For example:
278

  
279
   .. code-block:: python
280

  
281
      class Migration(DataMigration):
282

  
283
      def forwards(self, orm):
284
          orm.SynnefoUser.objects.all()
285

  
286
4. To migrate the database to the latest version, run:
287

  
288
   .. code-block:: console     
289
     
290
      $ snf-manage migrate db
291

  
292
   To see which migrations are applied:
293

  
294
   .. code-block:: console
295

  
296
      $ snf-manage migrate db --list
297

  
298
      db
299
        (*) 0001_initial
300
        (*) 0002_auto__add_field_synnefouser_new_south_test_field
301
        (*) 0003_rename_credit_wallet
302

  
303
.. seealso::
304
    More information and more thorough examples can be found in the South web site,
305
    http://south.aeracode.org/
306

  
307
Test coverage
308
-------------
309

  
310
.. warning:: This section may be out of date.
311

  
312
In order to get code coverage reports you need to install django-test-coverage
313

  
314
.. code-block:: console
315

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff