Revision bc055d09

b/docs/admin-guide.rst
1
.. _admin-guide:
2

  
3
Synnefo Administrator's Guide
4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5

  
6
This is the complete Synnefo Administrator's Guide.
7

  
8
Quick Installation
9
==================
10

  
11
The quick installation guide describes how to install the whole synnefo stack
12
in just two physical nodes, for testing purposes. This guide is useful to those
13
interested in deploying synnefo in large scale, as a starting point that will
14
help them get familiar with the synnefo components and overall architecture, as
15
well as the interconnection between different services. Such an installation,
16
also provides a quick preview of the basic synnefo features, although we would
17
like to think that synnefo unveils its real power while scaling.
18

  
19
| :ref:`Administrator's quick installation guide <quick-install-admin-guide>`
20
| This guide will walk you through a complete installation using debian packages.
21

  
22
Common administrative tasks
23
===========================
24

  
25
If you installed Synnefo successfully and have a working deployment, here are
26
some common administrative tasks that you may find useful.
27

  
28
The "kamaki" API client
29
-----------------------
30

  
31
To upload, register or modify an image you will need the **kamaki** tool.
32
Before proceeding make sure that it is configured properly. Verify that
33
*image_url*, *storage_url*, and *token* are set as needed:
34

  
35
.. code-block:: console
36

  
37
   $ kamaki config list
38

  
39
To chage a setting use ``kamaki config set``:
40

  
41
.. code-block:: console
42

  
43
   $ kamaki config set image_url https://cyclades.example.com/plankton
44
   $ kamaki config set storage_url https://pithos.example.com/v1
45
   $ kamaki config set token ...
46

  
47
Upload Image
48
------------
49

  
50
As a shortcut, you can configure a default account and container that will be
51
used by the ``kamaki store`` commands:
52

  
53
.. code-block:: console
54

  
55
   $ kamaki config set storage_account images@example.com
56
   $ kamaki config set storage_container images
57

  
58
If the container does not exist, you will have to create it before uploading
59
any images:
60

  
61
.. code-block:: console
62

  
63
   $ kamaki store create images
64

  
65
You are now ready to upload an image. You can upload it with a Pithos+ client,
66
or use kamaki directly:
67

  
68
.. code-block:: console
69

  
70
   $ kamaki store upload ubuntu.iso
71

  
72
You can use any Pithos+ client to verify that the image was uploaded correctly.
73
The full Pithos URL for the previous example will be
74
``pithos://images@example.com/images/ubuntu.iso``.
75

  
76

  
77
Register Image
78
--------------
79

  
80
To register an image you will need to use the full Pithos+ URL. To register as
81
a public image the one from the previous example use:
82

  
83
.. code-block:: console
84

  
85
   $ kamaki glance register Ubuntu pithos://images@example.com/images/ubuntu.iso --public
86

  
87
The ``--public`` flag is important, if missing the registered image will not
88
be listed by ``kamaki glance list``.
89

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

  
93
.. code-block:: console
94

  
95
   $ kamaki glance register Ubuntu pithos://images@example.com/images/ubuntu.iso \
96
            --public --disk-format diskdump --property kernel=3.1.2
97

  
98
To verify that the image was registered successfully use:
99

  
100
.. code-block:: console
101

  
102
   $ kamaki glance list -l
103

  
104

  
105
Admin tool: snf-manage
106
----------------------
107

  
108
``snf-manage`` is a tool used to perform various administrative tasks. It needs
109
to be able to access the django database, so the following should be able to
110
import the Django settings.
111

  
112
Additionally, administrative tasks can be performed via the admin web interface
113
located in /admin. Only users of type ADMIN can access the admin pages. To change
114
the type of a user to ADMIN, snf-admin can be used:
115

  
116
.. code-block:: console
117

  
118
   $ snf-manage user modify 42 --type ADMIN
119

  
120
Reconciliation mechanism
121
------------------------
122

  
123
On certain occasions, such as a Ganeti or RabbitMQ failure, the VM state in the
124
system's database may differ from that in the Ganeti installation. The
125
reconciliation process is designed to bring the system's database in sync with
126
what Ganeti knows about each VM, and is able to detect the following three
127
conditions:
128

  
129
 * Stale DB servers without corresponding Ganeti instances
130
 * Orphan Ganeti instances, without corresponding DB entries
131
 * Out-of-sync operstate for DB entries wrt to Ganeti instances
132

  
133
The reconciliation mechanism runs as a management command, e.g., as follows:
134
[PYTHONPATH needs to contain the parent of the synnefo Django project
135
directory]:
136

  
137
.. code-block:: console
138

  
139
   $ export PYTHONPATH=/srv:$PYTHONPATH
140
   $ snf-manage reconcile --detect-all -v 2
141

  
142
Please see ``snf-manage reconcile --help`` for all the details.
143

  
144
The administrator can also trigger reconciliation of operating state manually,
145
by issuing a Ganeti ``OP_INSTANCE_QUERY_DATA`` command on a Synnefo VM, using
146
gnt-instance info.
147

  
148
Logging
149
-------
150

  
151
Logging in Synnefo is using Python's logging module. The module is configured
152
using dictionary configuration, whose format is described here:
153

  
154
http://docs.python.org/release/2.7.1/library/logging.html#logging-config-dictschema
155

  
156
Note that this is a feature of Python 2.7 that we have backported for use in
157
Python 2.6.
158

  
159
The logging configuration dictionary is defined in settings.d/00-logging.conf
160
and is broken in 4 separate dictionaries:
161

  
162
  * LOGGING is the logging configuration used by the web app. By default all
163
    loggers fall back to the main 'synnefo' logger. The subloggers can be
164
    changed accordingly for finer logging control. e.g. To disable debug
165
    messages from the API set the level of 'synnefo.api' to 'INFO'.
166
  
167
  * DISPATCHER_LOGGING is the logging configuration of the logic/dispatcher.py
168
    command line tool.
169
  
170
  * SNFADMIN_LOGGING is the logging configuration of the snf-admin tool.
171
    Consider using matching configuration for snf-admin and the synnefo.admin
172
    logger of the web app.
173

  
174
Please note the following:
175

  
176
  * As of Synnefo v0.7, by default the Django webapp logs to syslog, the
177
    dispatcher logs to /var/log/synnefo/dispatcher.log and the console,
178
    snf-admin logs to the console.
179
  * Different handlers can be set to different logging levels:
180
    for example, everything may appear to the console, but only INFO and higher
181
    may actually be stored in a longer-term logfile
182

  
183

  
184
Scaling up to multiple nodes
185
============================
186

  
187
Here we will describe how to deploy all services, interconnected with each
188
other, on multiple physical nodes. For now, if you installed successfully using
189
the quick installation guide and need more details, please refer to each
190
component's own documentation.
191

  
192
Upgrade Notes
193
=============
194

  
195
Cyclades upgrade notes
196
----------------------
197

  
198
.. toctree::
199
   :maxdepth: 2
200

  
201
   cyclades-upgrade
202

  
203
Changelog
204
=========
/dev/null
1
Administration
2
==============
3

  
4
This file contains notes related to administration of a working Synnefo
5
deployment. This document should be read *after* README.deploy, which contains
6
step-by-step Synnefo deployment instructions.
7

  
8

  
9
Database
10
--------
11

  
12
MySQL: manage.py dbshell seems to ignore the setting of 'init_command'
13
       in settings.DATABASES
14

  
15

  
16
Reconciliation mechanism
17
------------------------
18

  
19
On certain occasions, such as a Ganeti or RabbitMQ failure, the VM state in the
20
system's database may differ from that in the Ganeti installation. The
21
reconciliation process is designed to bring the system's database in sync with
22
what Ganeti knows about each VM, and is able to detect the following three
23
conditions:
24

  
25
 * Stale DB servers without corresponding Ganeti instances
26
 * Orphan Ganeti instances, without corresponding DB entries
27
 * Out-of-sync operstate for DB entries wrt to Ganeti instances
28

  
29
The reconciliation mechanism runs as a management command, e.g., as follows:
30
[PYTHONPATH needs to contain the parent of the synnefo Django project
31
directory]:
32

  
33
/srv/synnefo$ export PYTHONPATH=/srv:$PYTHONPATH
34
vkoukis@dev67:~/synnefo [reconc]$ ./manage.py reconcile --detect-all -v 2
35

  
36
Please see ./manage.py reconcile --help for all the details.
37

  
38
The administrator can also trigger reconciliation of operating state manually,
39
by issuing a Ganeti OP_INSTANCE_QUERY_DATA command on a Synnefo VM, using
40
gnt-instance info.
41

  
42

  
43
Logging
44
-------
45

  
46
Logging in Synnefo is using Python's logging module. The module is configured
47
using dictionary configuration, whose format is described here:
48

  
49
http://docs.python.org/release/2.7.1/library/logging.html#logging-config-dictschema
50

  
51
Note that this is a feature of Python 2.7 that we have backported for use in
52
Python 2.6.
53

  
54
The logging configuration dictionary is defined in settings.d/00-logging.conf
55
and is broken in 4 separate dictionaries:
56

  
57
  * LOGGING is the logging configuration used by the web app. By default all
58
    loggers fall back to the main 'synnefo' logger. The subloggers can be
59
    changed accordingly for finer logging control. e.g. To disable debug
60
    messages from the API set the level of 'synnefo.api' to 'INFO'.
61
  
62
  * DISPATCHER_LOGGING is the logging configuration of the logic/dispatcher.py
63
    command line tool.
64
  
65
  * SNFADMIN_LOGGING is the logging configuration of the snf-admin tool.
66
    Consider using matching configuration for snf-admin and the synnefo.admin
67
    logger of the web app.
68

  
69
Please note the following:
70
  * As of Synnefo v0.7, by default the Django webapp logs to syslog, the
71
    dispatcher logs to /var/log/synnefo/dispatcher.log and the console,
72
    snf-admin logs to the console.
73
  * Different handlers can be set to different logging levels:
74
    for example, everything may appear to the console, but only INFO and higher
75
    may actually be stored in a longer-term logfile.
76

  
77

  
78
Admin Tools
79
-----------
80

  
81
snf-admin is a tool used to perform various administrative tasks. It needs to
82
be able to access the django database, so the following should be able to import
83
the Django settings.
84

  
85
Additionally, administrative tasks can be performed via the admin web interface
86
located in /admin. Only users of type ADMIN can access the admin pages. To change
87
the type of a user to ADMIN, snf-admin can be used:
88

  
89
   snf-admin user modify 42 --type ADMIN
b/docs/archipelago.rst
1
.. _archipelago:
2

  
3
Volume Service (archipelago)
4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5

  
6
`Coming Soon ...`
b/docs/astakos.rst
1
.. _astakos:
2

  
3
Identity Management Service (astakos)
4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5

  
6
Astakos is the synnefo Identity Management Service.
7

  
8
Astakos Architecture
9
====================
/dev/null
1
.. _cyclades-admin-guide:
2

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

  
7
This is the cyclades 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 cyclades,
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 cyclades, either from source packages or the provided
28
    packages for Debian Squeeze.
29
Configuration
30
    Configuration of the various software components comprising an cyclades
31
    deployment.
32
Upgrades/Changelogs
33
    Upgrades of existing deployments of cyclades to newer versions, associated
34
    Changelogs.
35

  
36
.. _cyclades-architecture:
37

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

  
41
Nodes in an cyclades 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 cyclades.
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-cyclades-app <snf-cyclades-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 <cyclades-nfdhcpd-setup>`
112

  
113
.. _WEBAPP_NODE:
114

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

  
118
Installation of cyclades is a two step process:
119

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

  
123
Prerequisites
124
*************
125
.. _cyclades-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
.. _cyclades-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
.. _cyclades-install-rabbitmq:
144

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

  
148
RabbitMQ is used as a generic message broker for cyclades. 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
.. _cyclades-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
.. _cyclades-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
.. _cyclades-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:`cyclades <cyclades>` 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 <cyclades-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-cyclades-app <snf-cyclades-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-cyclades-gtools <snf-cyclades-gtools>`
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-cyclades-app <snf-cyclades-app>`.
291

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

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

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

  
301
cyclades 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-cyclades-app <snf-cyclades-app>`,
305
:ref:`snf-cyclades-gtools <snf-cyclades-gtools>` 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 <cyclades-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
<cyclades-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*, and *token* are set as needed:
10

  
11
.. code-block:: console
12

  
13
  kamaki config list
14

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

  
17
.. code-block:: console
18

  
19
  kamaki config set image_url https://cyclades.example.com/plankton
20
  kamaki config set storage_url https://pithos.example.com/v1
21
  kamaki config set token ...
22

  
23

  
24
Upload an image
25
---------------
26

  
27
As a shortcut, you can configure a default account and container that will be
28
used by the ``kamaki store`` commands:
29

  
30
.. code-block:: console
31

  
32
  kamaki config set storage_account images@example.com
33
  kamaki config set storage_container images
34

  
35
If the container does not exist, you will have to create it before uploading
36
any images:
37

  
38
.. code-block:: console
39

  
40
  kamaki store create images
41

  
42
You are now ready to upload an image. You can upload it with a Pithos client
43
or use kamaki directly:
44

  
45
.. code-block:: console
46

  
47
  kamaki store upload ubuntu.iso
48

  
49
You can use any Pithos client to verify that the image was uploaded correctly.
50
The full Pithos URL for the previous example will be
51
``pithos://images@example.com/images/ubuntu.iso``.
52

  
53

  
54
Register the image
55
------------------
56

  
57
To register an image you will need to use the full Pithos URL. To register as
58
a public image the one from the previous example use:
59

  
60
.. code-block:: console
61

  
62
  kamaki glance register Ubuntu pithos://images@example.com/images/ubuntu.iso --public
63

  
64
The ``--public`` flag is important, if missing the registered image will not
65
be listed by ``kamaki glance list``.
66

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

  
70
.. code-block:: console
71

  
72
  kamaki glance register Ubuntu pithos://images@example.com/images/ubuntu.iso \
73
      --public --disk-format diskdump --property kernel=3.1.2
74

  
75
To verify that the image was registered successfully use:
76

  
77
.. code-block:: console
78

  
79
  kamaki glance list -l
/dev/null
1
.. _cyclades-developer-guide:
2

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

  
7
This is the cyclades developer guide.
8

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

  
12
It assumes thorough familiarity with the :ref:`cyclades-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-cyclades-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
.. _cyclades-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:`cyclades-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

  
316
   $ pip install django-test-coverage
317

  
318
Then configure the test runner inside Django settings:
319

  
320
.. code-block:: python
321

  
322
   TEST_RUNNER = 'django-test-coverage.runner.run_tests'
323

  
324

  
325
Internationalization
326
--------------------
327

  
328
This section describes how to translate static strings in Django projects:
329

  
330
0. From our project's base, we add directory locale
331

  
332
   .. code-block:: console
333
   
334
      $ mkdir locale
335
   
336
then we add on the settings.py the language code e.g.,
337

  
338
   .. code-block:: python
339
   
340
      LANGUAGES = (
341
          ('el', u'Greek'),
342
          ('en', u'English'),)
343
   
344
1. For each language we want to add, we run ``makemessages`` from the project's
345
   base:
346

  
347
   .. code-block:: python
348

  
349
      $ ./bin/django-admin.py makemessages -l el -e html,txt,py
350
      (./bin/django-admin.py makemessages -l el -e html,txt,py --ignore=lib/\*)
351

  
352
   This will add the Greek language, and we specify that :file:`*.html`,
353
   :file:`*.txt` and :file:`*.py` files contain translatable strings
354

  
355
2. We translate our strings:
356

  
357
   On :file:`.py` files, e.g., :file:`views.py`, first import ``gettext``:
358
   
359
   .. code-block:: python
360

  
361
      from django.utils.translation import gettext_lazy as _
362

  
363
   Then every ``string`` to be translated becomes:  ``_('string')``
364
   e.g.:
365

  
366
   .. code-block:: python
367

  
368
      help_text=_("letters and numbers only"))
369
      'title': _('Ubuntu 10.10 server 64bit'),
370

  
371
   On django templates (``html`` files), on the beggining of the file we add
372
   ``{% load i18n %}`` then rewrite every string that needs to be translated,
373
   as ``{% trans "string" %}``. For example: ``{% trans "Home" %}``
374

  
375
3. When all strings have been translated, run:
376

  
377
   .. code-block:: console
378

  
379
      $ django-admin.py makemessages -l el -e html,txt,py
380

  
381
   processing language ``el``. This creates (or updates) the :file:`po` file
382
   for the Greek language. We run this command each time we add new strings to
383
   be translated.  After that, we can translate our strings in the :file:`po`
384
   file (:file:`locale/el/LC_MESSAGES/django.po`)
385

  
386
4. When the :file:`po` file is ready, run
387
    
388
   .. code-block:: console
389

  
390
      $ ./bin/django-admin.py compilemessages
391

  
392
   This compiles the ``po`` files to ``mo``. Our strings will appear translated
393
   once we change the language (e.g., from a dropdown menu in the page)
394

  
395
.. seealso::
396
    http://docs.djangoproject.com/en/dev/topics/i18n/internationalization/
397

  
398

  
399
Building source packages
400
------------------------
401

  
402
.. warning:: This section may be out of date.
403

  
404
To create a python package from the Synnefo source code run
405

  
406
.. code-block:: bash
407

  
408
    $ cd snf-cyclades-app
409
    $ python setup.py sdist
410

  
411
this command will create a ``tar.gz`` python source package inside ``dist`` directory.
412

  
413

  
414
Building documentation
415
----------------------
416

  
417
Make sure you have ``sphinx`` installed.
418

  
419
.. code-block:: bash
420
    
421
    $ cd snf-cyclades-app/docs
422
    $ make html
423

  
424
.. note::
425

  
426
   The theme define in the Sphinx configuration file ``conf.py`` is ``nature``,
427
   not available in the version of Sphinx shipped with Debian Squeeze. Replace
428
   it with ``default`` to build with a Squeeze-provided Sphinx.
429

  
430
html files are generated in the ``snf-cyclades-app/docs/_build/html`` directory.
431

  
432

  
433
Continuous integration with Jenkins
434
-----------------------------------
435
.. warning:: This section may be out of date.
436

  
437
Preparing a GIT mirror
438
**********************
439

  
440
Jenkins cannot currently work with Git over encrypted HTTP. To solve this
441
problem we currently mirror the central Git repository locally on the jenkins
442
installation machine. To setup such a mirror do the following:
443

  
444
edit .netrc::
445

  
446
    machine code.grnet.gr
447
    login accountname
448
    password accountpasswd
449

  
450
Create the mirror::
451

  
452
    git clone --mirror https://code.grnet.gr/git/synnefo synnefo
453

  
454
Setup cron to pull from the mirror periodically. Ideally, Git mirror updates
455
should run just before Jenkins jobs check the mirror for changes::
456

  
457
    4,14,24,34,44,54 * * * * cd /path/to/mirror && git fetch && git remote prune origin
458

  
459
Jenkins setup
460
*************
461

  
462
The following instructions will setup Jenkins to run synnefo tests with the
463
SQLite database. To run the tests on MySQL and/or Postgres, step 5 must be
464
replicated. Also, the correct configuration file must be copied (line 6 of the
465
build script).
466

  
467
1. Install and start Jenkins. On Debian Squeeze:
468

  
469
   wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | apt-key add -
470
   echo "deb http://pkg.jenkins-ci.org/debian binary/" >>/etc/apt/sources.list
471
   echo "deb http://ppa.launchpad.net/chris-lea/zeromq/ubuntu lucid main" >> /etc/apt/sources.list
472
   sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C7917B12  
473
   sudo apt-get update
474
   sudo apt-get install jenkins
475

  
476
   Also install the following packages:
477

  
478
   apt-get install python-virtualenv libcurl3-gnutls libcurl3-gnutls-dev
479
                   uuid-dev libmysqlclient-dev libpq-dev libsqlite-dev
480
                   python-dev libzmq-dev
481

  
482
2. After Jenkins starts, go to
483

  
484
   http://$HOST:8080/pluginManager/
485

  
486
   and install the following plug-ins at
487

  
488
   -Jenkins Cobertura Plugin
489
   -Jenkins Email Extension Plugin
490
   -Jenkins GIT plugin
491
   -Jenkins SLOCCount Plug-in
492
   -Hudson/Jenkins Violations plugin
493

  
494
3. Configure the Jenkins user's Git details:
495
   su jenkins
496
   git config --global user.email "buildbot@lists.grnet.gr"
497
   git config --global user.name "Buildbot"
498

  
499
4. Make sure that all system-level dependencies specified in README.develop
500
   are correctly installed
501

  
502
5. Create a new "free-style software" job and set the following values::
503

  
504
    Project name: synnefo
505
    Source Code Management: Git
506
    URL of repository: Jenkins Git does not support HTTPS for checking out directly
507
                        from the repository. The temporary solution is to checkout
508
                        with a cron script in a directory and set the checkout path
509
                        in this field
510
    Branches to build: master and perhaps others
511
    Git->Advanced->Local subdirectory for repo (optional): synnefo
512
    Git->Advanced->Prune remote branches before build: check
513
    Repository browser: redmineweb,
514
                         URL: https://code.grnet.gr/projects/synnefo/repository/
515
    Build Triggers->Poll SCM: check
516
                     Schedule: # every five minutes
517
                   0,5,10,15,20,25,30,35,40,45,50,55 * * * * 
518

  
519
    Build -> Add build step-> Execute shell
520

  
521
    Command::
522

  
523
        #!/bin/bash -ex
524
        cd synnefo
525
        mkdir -p reports
526
        /usr/bin/sloccount --duplicates --wide --details api util ui logic auth > reports/sloccount.sc
527
        cp conf/ci/manage.py .
528
        if [ ! -e requirements.pip ]; then cp conf/ci/pip-1.2.conf requirements.pip; fi
529
        cat settings.py.dist conf/ci/settings.py.sqlite > settings.py
530
        python manage.py update_ve
531
        python manage.py hudson api db logic 
532

  
533
    Post-build Actions->Publish JUnit test result report: check
534
                         Test report XMLs: synnefo/reports/TEST-*.xml
535

  
536
    Post-build Actions->Publish Cobertura Coverage Report: check
537
                         Cobertura xml report pattern: synnefo/reports/coverage.xml
538

  
539
    Post-build Actions->Report Violations: check
540
                         pylint[XML filename pattern]: synnefo/reports/pylint.report
541

  
542
    Post-build Actions->Publish SLOCCount analysis results
543
                         SLOCCount reports: synnefo/reports/sloccount.sc
544
                         (also, remember to install sloccount at /usr/bin)
545

  
546
.. seealso::
547
    http://sites.google.com/site/kmmbvnr/home/django-hudson-tutorial
b/docs/cyclades.rst
1 1
.. _cyclades:
2 2

  
3
Compute Service (cyclades)
4
--------------------------
3
Compute and Network Service (cyclades)
4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5 5

  
6
Cyclades is the the synnefo Compute Service and implements OpenStack Compute API v1.1.
6
Cyclades is the the synnefo Compute and Network Service.
7 7

  
8
Cyclades need the following synnefo components:
8
It implements OpenStack Compute API v1.1 + synnefo extensions.
9 9

  
10 10
.. todo:: list synnefo components needed by cyclades
11 11

  
12
.. _cyclades-architecture:
12 13

  
13 14
Cyclades Architecture
14 15
=====================
15 16

  
16 17
.. todo:: document the overall cyclades architecture
17 18

  
19
Nodes in an cyclades deployment belong in one of the following types.
20
For every type, we list the services that execute on corresponding nodes.
21
Throughout this guide, `node` refers to a physical machine in the deployment.
18 22

  
19
Cyclades as a standalone Service
20
================================
23
.. _DB_NODE:
21 24

  
22
.. todo:: document what does that mean, what are the limitations, how to install.
25
DB
26
--
23 27

  
28
A node [or more than one nodes, if using an HA configuration], running a DB
29
engine supported by the Django ORM layer. The DB is the single source of
30
truth for the servicing of API requests by cyclades.
24 31

  
25
Cyclades interconnected with other synnefo Services
26
===================================================
32
*Services:* PostgreSQL / MySQL
27 33

  
28
.. todo:: document with which services it can connect, why and how.
34
.. _APISERVER_NODE:
29 35

  
36
APISERVER
37
---------
30 38

  
31
Cyclades Guides
32
===============
39
A node running the ``api`` application contained in
40
:ref:`snf-cyclades-app <snf-cyclades-app>`. Any number of
41
:ref:`APISERVER <APISERVER_NODE>` nodes
42
can be used, in a load-balancing configuration, without any
43
special consideration. Access to a common DB ensures consistency.
33 44

  
34
.. todo:: document the Compute Service.
45
*Services:* Web server, vncauthproxy
46

  
47

  
48
.. _QUEUE_NODE:
49

  
50
QUEUE
51
-----
52

  
53
A node running the RabbitMQ software, which provides AMQP functionality. More
54
than one :ref:`QUEUE <QUEUE_NODE>` nodes may be deployed, in an HA
55
configuration. Such deployments require shared storage, provided e.g., by DRBD.
56

  
57
*Services:* RabbitMQ [rabbitmq-server]
58

  
59

  
60
.. _LOGIC_NODE:
61

  
62
LOGIC
63
-----
64

  
65
A node running the business logic of synnefo, in Django. It dequeues
66
messages from QUEUE nodes, and provides the context in which business logic
67
functions run. It uses Django ORM to connect to the common DB and update the
68
state of the system, based on notifications received from the rest of the
69
infrastructure, over AMQP.
70

  
71
*Services:* the synnefo logic dispatcher, ``snf-dispatcher``
72

  
73

  
74
.. _GANETI_NODES:
75
.. _GANETI_MASTER:
76
.. _GANETI_NODE:
77

  
78
GANETI-MASTER and GANETI-NODE
79
-----------------------------
80

  
81
A single GANETI-MASTER and a large number of GANETI-NODEs constitute the
82
Ganeti backend for synnefo, which undertakes all VM management functions.
83
Any APISERVER can issue commands to the GANETI-MASTER, over RAPI, to effect
84
changes in the state of the VMs. The GANETI-MASTER runs the Ganeti request
85
queue.
86

  
87
*Services:*
88
    * only on :ref:`GANETI-MASTER <GANETI_MASTER>`:
89
        * the synnefo Ganeti monitoring daemon, ``snf-ganeti-eventd``
90
        * the synnefo Ganeti hook, ``ganeti/snf-ganeti-hook.py``.
91
    * on every :ref:`GANETI-NODE <GANETI_NODE>`:
92
        * a deployment-specific KVM ifup script
93
        * properly configured :ref:`NFDHCPD <cyclades-nfdhcpd-setup>`
35 94

  
36
.. toctree::
37
   :maxdepth: 2
38 95

  
39
   cyclades-admin-guide
40
   cyclades-api-guide
41
   cyclades-admin-tools
42
   cyclades-dev-guide
43
   cyclades-upgrade
44 96
..   src/design
45 97
..   src/dev
46 98
..   src/user
b/docs/dev-guide.rst
1
.. _dev-guide:
2

  
3
Synnefo Developer's Guide
4
^^^^^^^^^^^^^^^^^^^^^^^^^
5

  
6
This is the complete Synnefo Developer's Guide
7

  
8
Tying it all up with kamaki
9
===========================
10

  
11
kamaki
12
------
13

  
14
Compute API (Cyclades)
15
======================
16

  
17
This is the Cyclades Compute API:
18

  
19
.. toctree::
20
   :maxdepth: 2
21

  
22
   Compute API <cyclades-api-guide>
23

  
24
Network API (Cyclades)
25
======================
26

  
27
Network API body
28

  
29
Images API (Plankton)
30
=====================
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff