Statistics
| Branch: | Tag: | Revision:

root / docs / admin-guide.rst @ edd28bbf

History | View | Annotate | Download (67 kB)

1
.. _admin-guide:
2

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

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

    
8

    
9
.. _syn+archip:
10

    
11
General Synnefo Architecture
12
============================
13

    
14
The following figure shows a detailed view of the whole Synnefo architecture
15
and how it interacts with multiple Ganeti clusters. We hope that after reading
16
the Administrator's Guide you will be able to understand every component and
17
all the interactions between them.
18

    
19
.. image:: images/synnefo-arch2.png
20
   :width: 100%
21
   :target: _images/synnefo-arch2.png
22

    
23
Synnefo also supports RADOS as an alternative storage backend for
24
Files/Images/VM disks. You will find the :ref:`corresponding figure
25
<syn+archip+rados>` later in this guide.
26

    
27

    
28
Identity Service (Astakos)
29
==========================
30

    
31

    
32
Authentication methods
33
----------------------
34

    
35
Astakos supports multiple authentication methods:
36

    
37
 * local username/password
38
 * LDAP / Active Directory
39
 * SAML 2.0 (Shibboleth) federated logins
40
 * Google
41
 * Twitter
42
 * LinkedIn
43

    
44
.. _shibboleth-auth:
45

    
46
Shibboleth Authentication
47
~~~~~~~~~~~~~~~~~~~~~~~~~
48

    
49
Astakos can delegate user authentication to a Shibboleth federation.
50

    
51
To setup shibboleth, install package::
52

    
53
  apt-get install libapache2-mod-shib2
54

    
55
Change appropriately the configuration files in ``/etc/shibboleth``.
56

    
57
Add in ``/etc/apache2/sites-available/synnefo-ssl``::
58

    
59
  ShibConfig /etc/shibboleth/shibboleth2.xml
60
  Alias      /shibboleth-sp /usr/share/shibboleth
61

    
62
  <Location /ui/login/shibboleth>
63
    AuthType shibboleth
64
    ShibRequireSession On
65
    ShibUseHeaders On
66
    require valid-user
67
  </Location>
68

    
69
and before the line containing::
70

    
71
  ProxyPass        / http://localhost:8080/ retry=0
72

    
73
add::
74

    
75
  ProxyPass /Shibboleth.sso !
76

    
77
Then, enable the shibboleth module::
78

    
79
  a2enmod shib2
80

    
81
After passing through the apache module, the following tokens should be
82
available at the destination::
83

    
84
  eppn # eduPersonPrincipalName
85
  Shib-InetOrgPerson-givenName
86
  Shib-Person-surname
87
  Shib-Person-commonName
88
  Shib-InetOrgPerson-displayName
89
  Shib-EP-Affiliation
90
  Shib-Session-ID
91

    
92
Finally, add 'shibboleth' in ``ASTAKOS_IM_MODULES`` list. The variable resides
93
inside the file ``/etc/synnefo/20-snf-astakos-app-settings.conf``
94

    
95
Twitter Authentication
96
~~~~~~~~~~~~~~~~~~~~~~
97

    
98
To enable twitter authentication while signed in under a Twitter account,
99
visit dev.twitter.com/apps.
100

    
101
Click Create an application.
102

    
103
Fill the necessary information and for callback URL give::
104

    
105
    https://node1.example.com/ui/login/twitter/authenticated
106

    
107
Finally, add 'twitter' in ``ASTAKOS_IM_MODULES`` list. The variable resides
108
inside the file ``/etc/synnefo/20-snf-astakos-app-settings.conf``
109

    
110
Google Authentication
111
~~~~~~~~~~~~~~~~~~~~~
112

    
113
To enable google authentication while signed in under a Google account,
114
visit https://code.google.com/apis/console/.
115

    
116
Under API Access select Create another client ID, select Web application,
117
expand more options in Your site or hostname section and in Authorized
118
Redirect URIs add:
119

    
120

    
121
Fill the necessary information and for callback URL give::
122

    
123
    https://node1.example.com/ui/login/google/authenticated
124

    
125
Finally, add 'google' in ``ASTAKOS_IM_MODULES`` list. The variable resides
126
inside the file ``/etc/synnefo/20-snf-astakos-app-settings.conf``
127

    
128

    
129
Working with Astakos
130
--------------------
131

    
132
User registration
133
~~~~~~~~~~~~~~~~~
134

    
135
When a new user signs up, he/she is not directly marked as active. You can see 
136
his/her state by running (on the machine that runs the Astakos app):
137

    
138
.. code-block:: console
139

    
140
   $ snf-manage user-list
141

    
142
More detailed user status is provided in the `status` field of the `user-show` 
143
command:
144

    
145
.. code-block:: console
146

    
147
  $ snf-manage user-show <user-id>
148

    
149
  id                  : 6
150
  uuid                : 78661411-5eed-412f-a9ea-2de24f542c2e
151
  status              : Accepted/Active (accepted policy: manual)
152
  email               : user@synnefo.org
153
  ....
154

    
155
Based on the `astakos-app` configuration, there are several ways for a user to
156
get verified and activated in order to be able to login. We discuss the user
157
verification and activation flow in the following section.
158

    
159
User activation flow
160
````````````````````
161

    
162
A user can register for an account using the astakos signup form. Once the form
163
is submited successfully a user entry is created in astakos database. That entry
164
is passed through the astakos activation backend which handles whether the user
165
should be automatically verified and activated.
166

    
167
Email verification
168
``````````````````
169

    
170
The verification process takes place in order to ensure that the user owns the
171
email provided during the signup process. By default, after each successful
172
signup astakos notifies user with an verification url via email. 
173

    
174
At this stage:
175

    
176
    * subsequent registrations invalidate and delete the previous registrations 
177
      of the same email address.
178

    
179
    * in case user misses the initial notification, additional emails can be
180
      send either via the url which is prompted to the user if he tries to
181
      login, or by the administrator using the ``snf-manage user-activation-send
182
      <userid>`` command.
183

    
184
    * administrator may also enforce a user to get verified using the
185
      ``snf-manage user-modify --verify <userid>`` command.
186

    
187
Account activation
188
``````````````````
189

    
190
Once the user gets verified, it is time for Astakos to decide whether or not to
191
proceed through user activation process. If ``ASTAKOS_MODERATION_ENABLED``
192
setting is set to ``False`` (default value) user gets activated automatically. 
193

    
194
In case the moderation is enabled Astakos may still automatically activate the
195
user in the following cases:
196

    
197
    * User email matches any of the regular expressions defined in
198
      ``ASTAKOS_RE_USER_EMAIL_PATTERNS`` (defaults to ``[]``)
199
    * User used a signup method (e.g. ``shibboleth``) for which automatic
200
      activation is enabled (see 
201
      :ref:`authentication methods policies <auth_methods_policies>`).
202

    
203
If all of the above fail to trigger automatic activation, an email is sent to
204
the persons listed in ``HELPDESK``, ``MANAGERS`` and ``ADMINS`` settings,
205
notifing that there is a new user pending for moderation and that it's up to
206
the administrator to decide if the user should be activated. The UI also shows
207
a corresponding 'pending moderation' message to the user. The administrator can
208
activate a user using the ``snf-manage user-modify`` command:
209

    
210
.. code-block:: console
211

    
212
    # command to activate a pending user
213
    $ snf-manage user-modify --accept <userid>
214

    
215
    # command to reject a pending user
216
    $ snf-manage user-modify --reject --reject-reason="spammer" <userid>
217

    
218
Once the activation process finishes, a greeting message is sent to the user
219
email address and a notification for the activation to the persons listed in
220
``HELPDESK``, ``MANAGERS`` and ``ADMINS`` settings. Once activated the user is
221
able to login and access the Synnefo services.
222

    
223
Additional authentication methods
224
`````````````````````````````````
225

    
226
Astakos supports third party logins from external identity providers. This
227
can be usefull since it allows users to use their existing credentials to 
228
login to astakos service.
229

    
230
Currently astakos supports the following identity providers:
231

    
232
    * `Shibboleth <http://www.internet2.edu/shibboleth>`_ (module name
233
      ``shibboleth``)
234
    * `Google <https://developers.google.com/accounts/docs/OAuth2>`_ (module
235
      name ``google``)
236
    * `Twitter <https://dev.twitter.com/docs/auth>`_ (module name ``twitter``)
237
    * `LinkedIn <http://developer.linkedin.com/documents/authentication>`_
238
      (module name ``linkedin``)
239

    
240
To enable any of the above modules (by default only ``local`` accounts are
241
allowed), retrieve and set the required provider settings and append the 
242
module name in ``ASTAKOS_IM_MODULES``.
243

    
244
.. code-block:: python
245

    
246
    # settings from https://code.google.com/apis/console/
247
    ASTAKOS_GOOGLE_CLIENT_ID = '1111111111-epi60tvimgha63qqnjo40cljkojcann3.apps.googleusercontent.com'
248
    ASTAKOS_GOOGLE_SECRET = 'tNDQqTDKlTf7_LaeUcWTWwZM'
249
    
250
    # let users signup and login using their google account
251
    ASTAKOS_IM_MODULES = ['local', 'google']
252

    
253

    
254
.. _auth_methods_policies:
255

    
256
Authentication method policies
257
``````````````````````````````
258

    
259
Astakos allows you to override the default policies for each enabled provider 
260
separately by adding the approriate settings in your ``.conf`` files in the 
261
following format:
262

    
263
**ASTAKOS_AUTH_PROVIDER_<module>_<policy>_POLICY**
264

    
265
Available policies are:
266

    
267
    * **CREATE** Users can signup using that provider (default: ``True``) 
268
    * **REMOVE/ADD** Users can remove/add login method from their profile 
269
      (default: ``True``)
270
    * **AUTOMODERATE** Automatically activate users that signup using that
271
      provider (default: ``False``)
272
    * **LOGIN** Whether or not users can use the provider to login (default:
273
      ``True``).
274

    
275
e.g. to enable automatic activation for your academic users, while keeping 
276
locally signed up users under moderation you can apply the following settings.
277

    
278
.. code-block:: python
279

    
280
    ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_AUTOMODERATE_POLICY = True
281
    ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_REMOVE_POLICY = False
282

    
283
User login
284
~~~~~~~~~~
285

    
286
During the logging procedure, the user is authenticated by the respective
287
identity provider.
288

    
289
If ``ASTAKOS_RECAPTCHA_ENABLED`` is set and the user fails several times
290
(``ASTAKOS_RATELIMIT_RETRIES_ALLOWED`` setting) to provide the correct
291
credentials for a local account, he/she is then prompted to solve a captcha
292
challenge.
293

    
294
Upon success, the system renews the token (if it has expired), logins the user
295
and sets the cookie, before redirecting the user to the ``next`` parameter
296
value.
297

    
298
Setting quota limits
299
~~~~~~~~~~~~~~~~~~~~
300

    
301
Set default quota
302
`````````````````
303
To inspect current default base quota limits, run::
304

    
305
   # snf-manage resource-list
306

    
307
You can modify the default base quota limit for all future users with::
308

    
309
   # snf-manage resource-modify <resource_name> --default-quota <value>
310

    
311
Set base quota for individual users
312
```````````````````````````````````
313

    
314
For individual users that need different quota than the default
315
you can set it for each resource like this::
316

    
317
    # use this to display quota / uuid
318
    # snf-manage user-show 'uuid or email' --quota
319

    
320
    # snf-manage user-modify <user-uuid> --base-quota 'cyclades.vm' 10
321

    
322
You can set base quota for all existing users, with possible exceptions, using::
323

    
324
    # snf-manage user-modify --all --base-quota cyclades.vm 10 --exclude uuid1,uuid2
325

    
326
All quota for which values different from the default have been set,
327
can be listed with::
328

    
329
    # snf-manage quota-list --with-custom=True
330

    
331

    
332
Enable the Projects feature
333
~~~~~~~~~~~~~~~~~~~~~~~~~~~
334

    
335
If you want to enable the projects feature so that users may apply
336
on their own for resources by creating and joining projects,
337
in ``20-snf-astakos-app-settings.conf`` set::
338

    
339
    # this will make the 'projects' page visible in the dashboard
340
    ASTAKOS_PROJECTS_VISIBLE = True
341

    
342
You can change the maximum allowed number of pending project applications
343
per user with::
344

    
345
    # snf-manage resource-modify astakos.pending_app --default-quota <number>
346

    
347
You can also set a user-specific limit with::
348

    
349
    # snf-manage user-modify <user-uuid> --base-quota 'astakos.pending_app' 5
350

    
351
When users apply for projects they are not automatically granted
352
the resources. They must first be approved by the administrator.
353

    
354
To list pending project applications in astakos::
355

    
356
    # snf-manage project-list --pending
357

    
358
Note the last column, the application id. To approve it::
359

    
360
    # <app id> from the last column of project-list
361
    # snf-manage project-control --approve <app id>
362

    
363
To deny an application::
364

    
365
    # snf-manage project-control --deny <app id>
366

    
367
Users designated as *project admins* can approve, deny, or modify
368
an application through the web interface. In
369
``20-snf-astakos-app-settings.conf`` set::
370

    
371
    # UUIDs of users that can approve or deny project applications from the web.
372
    ASTAKOS_PROJECT_ADMINS = [<uuid>, ...]
373

    
374

    
375
Astakos advanced operations
376
---------------------------
377

    
378
Adding "Terms of Use"
379
~~~~~~~~~~~~~~~~~~~~~
380

    
381
Astakos supports versioned terms-of-use. First of all you need to create an
382
html file that will contain your terms. For example, create the file
383
``/usr/share/synnefo/sample-terms.html``, which contains the following:
384

    
385
.. code-block:: console
386

    
387
   <h1>My cloud service terms</h1>
388

    
389
   These are the example terms for my cloud service
390

    
391
Then, add those terms-of-use with the snf-manage command:
392

    
393
.. code-block:: console
394

    
395
   $ snf-manage term-add /usr/share/synnefo/sample-terms.html
396

    
397
Your terms have been successfully added and you will see the corresponding link
398
appearing in the Astakos web pages' footer.
399

    
400
During the account registration, if there are approval terms, the user is
401
presented with an "I agree with the Terms" checkbox that needs to get checked
402
in order to proceed.
403

    
404
In case there are new approval terms that the user has not signed yet, the
405
``signed_terms_required`` view decorator redirects to the ``approval_terms``
406
view, so the user will be presented with the new terms the next time he/she
407
logins.
408

    
409
Enabling reCAPTCHA
410
~~~~~~~~~~~~~~~~~~
411

    
412
Astakos supports the `reCAPTCHA <http://www.google.com/recaptcha>`_ feature.
413
If enabled, it protects the Astakos forms from bots. To enable the feature, go
414
to https://www.google.com/recaptcha/admin/create and create your own reCAPTCHA
415
key pair. Then edit ``/etc/synnefo/20-snf-astakos-app-settings.conf`` and set
416
the corresponding variables to reflect your newly created key pair. Finally, set
417
the ``ASTAKOS_RECAPTCHA_ENABLED`` variable to ``True``:
418

    
419
.. code-block:: console
420

    
421
   ASTAKOS_RECAPTCHA_PUBLIC_KEY = 'example_recaptcha_public_key!@#$%^&*('
422
   ASTAKOS_RECAPTCHA_PRIVATE_KEY = 'example_recaptcha_private_key!@#$%^&*('
423

    
424
   ASTAKOS_RECAPTCHA_ENABLED = True
425

    
426
Restart the service on the Astakos node(s) and you are ready:
427

    
428
.. code-block:: console
429

    
430
   # /etc/init.d/gunicorn restart
431

    
432
Checkout your new Sign up page. If you see the reCAPTCHA box, you have setup
433
everything correctly.
434

    
435

    
436
Astakos internals
437
-----------------
438

    
439
X-Auth-Token
440
~~~~~~~~~~~~
441

    
442
Alice requests a specific resource from a cloud service e.g.: Pithos. In the
443
request she supplies the `X-Auth-Token` to identify whether she is eligible to
444
perform the specific task. The service contacts Astakos through its
445
``/account/v1.0/authenticate`` api call (see :ref:`authenticate-api-label`)
446
providing the specific ``X-Auth-Token``. Astakos checkes whether the token
447
belongs to an active user and it has not expired and returns a dictionary
448
containing user related information. Finally the service uses the ``uniq``
449
field included in the dictionary as the account string to identify the user
450
accessible resources.
451

    
452
.. _authentication-label:
453

    
454
Django Auth methods and Backends
455
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
456

    
457
Astakos incorporates Django user authentication system and extends its User model.
458

    
459
Since username field of django User model has a limitation of 30 characters,
460
AstakosUser is **uniquely** identified by the ``email`` instead. Therefore,
461
``astakos.im.authentication_backends.EmailBackend`` is served to authenticate a
462
user using email if the first argument is actually an email, otherwise tries
463
the username.
464

    
465
A new AstakosUser instance is assigned with a uui as username and also with a
466
``auth_token`` used by the cloud services to authenticate the user.
467
``astakos.im.authentication_backends.TokenBackend`` is also specified in order
468
to authenticate the user using the email and the token fields.
469

    
470
Logged on users can perform a number of actions:
471

    
472
 * access and edit their profile via: ``/im/profile``.
473
 * change their password via: ``/im/password``
474
 * send feedback for grnet services via: ``/im/send_feedback``
475
 * logout (and delete cookie) via: ``/im/logout``
476

    
477
Internal Astakos requests are handled using cookie-based Django user sessions.
478

    
479
External systems should forward to the ``/login`` URI. The server,
480
depending on its configuration will redirect to the appropriate login page.
481
When done with logging in, the service's login URI should redirect to the URI
482
provided with next, adding user and token parameters, which contain the email
483
and token fields respectively.
484

    
485
The login URI accepts the following parameters:
486

    
487
======================  =========================
488
Request Parameter Name  Value
489
======================  =========================
490
next                    The URI to redirect to when the process is finished
491
renew                   Force token renewal (no value parameter)
492
force                   Force logout current user (no value parameter)
493
======================  =========================
494

    
495
External systems inside the ``ASTAKOS_COOKIE_DOMAIN`` scope can acquire the
496
user information by the cookie identified by ``ASTAKOS_COOKIE_NAME`` setting
497
(set during the login procedure).
498

    
499
Finally, backend systems having acquired a token can use the
500
:ref:`authenticate-api-label` API call from a private network or through HTTPS.
501

    
502

    
503
Compute/Network/Image Service (Cyclades)
504
========================================
505

    
506
Working with Cyclades
507
---------------------
508

    
509
Managing Ganeti Backends
510
~~~~~~~~~~~~~~~~~~~~~~~~
511

    
512
Since v0.11, Synnefo is able to manage multiple Ganeti clusters (backends)
513
making it capable to scale linearly to tens of thousands of VMs. Backends
514
can be dynamically added or removed via `snf-manage` commands.
515

    
516
Each newly created VM is allocated to a Ganeti backend by the Cyclades backend
517
allocator. The VM is "pinned" to this backend, and can not change through its
518
lifetime. The backend allocator decides in which backend to spawn the VM based
519
on the available resources of each backend, trying to balance the load between
520
them. Also, Networks are created to all Ganeti backends, in order to ensure
521
that VMs residing on different backends can be connected to the same networks.
522

    
523
A backend can be marked as `drained` in order to be excluded from automatic
524
servers allocation and not receive new servers. Also, a backend can be marked
525
as `offline` to denote that the backend is not healthy (e.g. broken master)
526
and avoid the penalty of connection timeouts.
527

    
528
Finally, Cyclades is able to manage Ganeti backends with different enabled
529
hypervisors (`kvm`, `xen`), and different enabled disk templates.
530

    
531
Listing existing backends
532
`````````````````````````
533
To list all the Ganeti backends known to Synnefo, we run:
534

    
535
.. code-block:: console
536

    
537
   $ snf-manage backend-list
538

    
539
Adding a new Ganeti backend
540
```````````````````````````
541
Backends are dynamically added under the control of Synnefo with `snf-manage
542
backend-add` command. In this section it is assumed that a Ganeti cluster,
543
named ``cluster.example.com`` is already up and running and configured to be
544
able to host Synnefo VMs.
545

    
546
To add this Ganeti cluster, we run:
547

    
548
.. code-block:: console
549

    
550
   $ snf-manage backend-add --clustername=cluster.example.com --user="synnefo_user" --pass="synnefo_pass"
551

    
552
where ``clustername`` is the Cluster hostname of the Ganeti cluster, and
553
``user`` and ``pass`` are the credentials for the `Ganeti RAPI user
554
<http://docs.ganeti.org/ganeti/2.2/html/rapi.html#users-and-passwords>`_.  All
555
backend attributes can be also changed dynamically using the `snf-manage
556
backend-modify` command.
557

    
558
``snf-manage backend-add`` will also create all existing public networks to
559
the new backend. You can verify that the backend is added, by running
560
`snf-manage backend-list`.
561

    
562
Note that no VMs will be spawned to this backend, since by default it is in a
563
``drained`` state after addition in order to manually verify the state of the
564
backend.
565

    
566
So, after making sure everything works as expected, make the new backend active
567
by un-setting the ``drained`` flag. You can do this by running:
568

    
569
.. code-block:: console
570

    
571
   $ snf-manage backend-modify --drained=False <backend_id>
572

    
573
Allocation of VMs in Ganeti backends
574
````````````````````````````````````
575
As already mentioned, the Cyclades backend allocator is responsible for
576
allocating new VMs to backends. This allocator does not choose the exact Ganeti
577
node that will host the VM but just the Ganeti backend. The exact node is
578
chosen by the Ganeti cluster's allocator (hail).
579

    
580
The decision about which backend will host a VM is based on the available
581
resources. The allocator computes a score for each backend, that shows its load
582
factor, and the one with the minimum score is chosen. The admin can exclude
583
backends from the allocation phase by marking them as ``drained`` by running:
584

    
585
.. code-block:: console
586

    
587
   $ snf-manage backend-modify --drained=True <backend_id>
588

    
589
The backend resources are periodically updated, at a period defined by
590
the ``BACKEND_REFRESH_MIN`` setting, or by running `snf-manage
591
backend-update-status` command. It is advised to have a cron job running this
592
command at a smaller interval than ``BACKEND_REFRESH_MIN`` in order to remove
593
the load of refreshing the backends stats from the VM creation phase.
594

    
595
Finally, the admin can decide to have a user's VMs being allocated to a
596
specific backend, with the ``BACKEND_PER_USER`` setting. This is a mapping
597
between users and backends. If the user is found in ``BACKEND_PER_USER``, then
598
Synnefo allocates all his/hers VMs to the specific backend in the variable,
599
even if is marked as drained (useful for testing).
600

    
601
Allocation based on disk-templates
602
**********************************
603

    
604
Besides the available resources of each Ganeti backend, the allocator takes
605
into consideration the disk template of the instance when trying to allocate it
606
to a Ganeti backend. Specifically, the allocator checks if the flavor of the
607
instance belongs to the available disk templates of each Ganeti backend.
608

    
609
A Ganeti cluster has a list of enabled disk templates
610
(`--enabled-disk-templates`) and a list of allowed disk templates for new
611
instances (`--ipolicy-disk-templates`). See the `gnt-cluster` manpage for more
612
details about these options.
613

    
614
When Synnefo allocates an instance, it checks whether the disk template of the
615
new instance belongs both in the enabled and ipolicy disk templates. You can
616
see the list of the available disk-templates by running `snf-manage
617
backend-list`. This list should be updated automatically after changing
618
these options in Ganeti and it can also be updated by running `snf-manage
619
backend-update-status`.
620

    
621
So the administrator, can route instances on different backends based on their
622
flavor disk template, by modifying the enabled or ipolicy disk templates of
623
each backend.  Also, the administrator can route instances between different
624
nodes of the same Ganeti backend, by modifying the same options at the
625
nodegroup level (see `gnt-group` manpage for mor details).
626

    
627
Removing an existing Ganeti backend
628
```````````````````````````````````
629
In order to remove an existing backend from Synnefo, you must first make
630
sure that there are not active servers in the backend, and then run:
631

    
632
.. code-block:: console
633

    
634
   # snf-manage backend-remove <backend_id>
635

    
636

    
637

    
638
Managing Virtual Machines
639
~~~~~~~~~~~~~~~~~~~~~~~~~
640

    
641
As mentioned, Cyclades uses Ganeti for management of VMs. The administrator can
642
handle Cyclades VMs just like any other Ganeti instance, via `gnt-instance`
643
commands. All Ganeti instances that belong to Synnefo, are separated from
644
others, by a prefix in their names. This prefix is defined in
645
``BACKEND_PREFIX_ID`` setting in
646
``/etc/synnefo/20-snf-cyclades-app-backend.conf``.
647

    
648
Apart from handling instances directly in the Ganeti level, a number of `snf-manage`
649
commands are available:
650

    
651
* ``snf-manage server-list``: List servers
652
* ``snf-manage server-show``: Show information about a server in the Cyclades DB
653
* ``snf-manage server-inspect``: Inspect the state of a server both in DB and Ganeti
654
* ``snf-manage server-modify``: Modify the state of a server in the Cycldes DB
655
* ``snf-manage server-create``: Create a new server
656
* ``snf-manage server-import``: Import an existing Ganeti instance to Cyclades
657

    
658

    
659
Managing Virtual Networks
660
~~~~~~~~~~~~~~~~~~~~~~~~~
661

    
662
Cyclades is able to create and manage Virtual Networks. Networking is
663
desployment specific and must be customized based on the specific needs of the
664
system administrator. For better understanding of networking please refer to
665
the :ref:`Network <networks>` section.
666

    
667
Exactly as Cyclades VMs can be handled like Ganeti instances, Cyclades Networks
668
can also by handled as Ganeti networks, via `gnt-network commands`. All Ganeti
669
networks that belong to Synnefo are named with the prefix
670
`${BACKEND_PREFIX_ID}-net-`.
671

    
672
There are also the following `snf-manage` commands for managing networks:
673

    
674
* ``snf-manage network-list``: List networks
675
* ``snf-manage network-show``: Show information about a network in the Cyclades DB
676
* ``snf-manage network-inspect``: Inspect the state of the network in DB and Ganeti backends
677
* ``snf-manage network-modify``: Modify the state of a network in the Cycldes DB
678
* ``snf-manage network-create``: Create a new network
679
* ``snf-manage network-remove``: Remove an existing network
680

    
681
Managing Network Resources
682
``````````````````````````
683

    
684
Proper operation of the Cyclades Network Service depends on the unique
685
assignment of specific resources to each type of virtual network. Specifically,
686
these resources are:
687

    
688
* IP addresses. Cyclades creates a Pool of IPs for each Network, and assigns a
689
  unique IP address to each VM, thus connecting it to this Network. You can see
690
  the IP pool of each network by running `snf-manage network-inspect
691
  <network_ID>`. IP pools are automatically created and managed by Cyclades,
692
  depending on the subnet of the Network.
693
* Bridges corresponding to physical VLANs, which are required for networks of
694
  type `PRIVATE_PHYSICAL_VLAN`.
695
* One Bridge corresponding to one physical VLAN which is required for networks of
696
  type `PRIVATE_MAC_PREFIX`.
697

    
698
IPv4 addresses
699
**************
700

    
701
An allocation pool of IPv4 addresses is automatically created for every network
702
with an IPv4 subnet. By default, the allocation pool contains the range of IP
703
addresses that are included in the subnet, except from the gateway and the
704
broadcast address of the network. The range of IP addresses can be restricted
705
using the `--allocation-pool` option of `snf-manage network-create` command.
706
The admin can externally reserve IP addresses to exclude them from automatic
707
allocation with the `--add-reserved-ips` option of `snf-manage network-modify`
708
command. For example the following command will reserve two IP addresses from
709
network with ID `42`:
710

    
711
.. code-block:: console
712

    
713
 snf-manage network-modify --add-reserved-ips=10.0.0.21,10.0.0.22 42
714

    
715
.. warning:: Externally reserving IP addresses is also available at the Ganeti.
716
 However, when using Cyclades with multiple Ganeti backends, the handling of
717
 IP pools must be performed from Cyclades!
718

    
719
Bridges
720
*******
721

    
722
As already mentioned Cyclades use a pool of Bridges that must correspond
723
to Physical VLAN at the Ganeti level. A bridge from the pool is assigned to
724
each network of flavor `PHYSICAL_VLAN`. Creation of this pool is done
725
using `snf-manage pool-create` command. For example the following command
726
will create a pool containing the brdiges from `prv1` to `prv21`.
727

    
728
.. code-block:: console
729

    
730
   # snf-manage pool-create --type=bridge --base=prv --size=20
731

    
732
You can verify the creation of the pool, and check its contents by running:
733

    
734
.. code-block:: console
735

    
736
   # snf-manage pool-list
737
   # snf-manage pool-show --type=bridge 1
738

    
739
Finally you can use the `pool-modify` management command in order to externally
740
reserve the values from pool, extend or shrink the pool if possible.
741

    
742
MAC Prefixes
743
************
744

    
745
Cyclades also use a pool of MAC prefixes to assign to networks of flavor
746
`MAC_FILTERED`. Handling of this pool is done exactly as with pool of bridges,
747
except that the type option must be set to mac-prefix:
748

    
749
.. code-block:: console
750

    
751
   # snf-manage pool-create --type=mac-prefix --base=aa:00:0 --size=65536
752

    
753
The above command will create a pool of MAC prefixes from ``aa:00:1`` to
754
``b9:ff:f``. The MAC prefix pool is responsible for providing only unicast and
755
locally administered MAC addresses, so many of these prefixes will be
756
externally reserved, to exclude from allocation.
757

    
758
Pool reconciliation
759
*******************
760

    
761
The management command `snf-manage reconcile-pools` can be used that all the
762
above mentioned pools are consistent and that all values that come from the
763
pool are not used more than once.
764

    
765

    
766
Cyclades advanced operations
767
----------------------------
768

    
769
Reconciliation mechanism
770
~~~~~~~~~~~~~~~~~~~~~~~~
771

    
772
On certain occasions, such as a Ganeti or RabbitMQ failure, the state of
773
Cyclades database may differ from the real state of VMs and networks in the
774
Ganeti backends. The reconciliation process is designed to synchronize
775
the state of the Cyclades DB with Ganeti. There are two management commands
776
for reconciling VMs and Networks
777

    
778
Reconciling Virtual Machines
779
````````````````````````````
780

    
781
Reconciliation of VMs detects the following conditions:
782

    
783
 * Stale DB servers without corresponding Ganeti instances
784
 * Orphan Ganeti instances, without corresponding DB entries
785
 * Out-of-sync state for DB entries wrt to Ganeti instances
786

    
787
To detect all inconsistencies you can just run:
788

    
789
.. code-block:: console
790

    
791
  $ snf-manage reconcile-servers
792

    
793
Adding the `--fix-all` option, will do the actual synchronization:
794

    
795
.. code-block:: console
796

    
797
  $ snf-manage reconcile-servers --fix-all
798

    
799
Please see ``snf-manage reconcile-servers --help`` for all the details.
800

    
801
Reconciling Networks
802
````````````````````
803

    
804
Reconciliation of Networks detects the following conditions:
805

    
806
  * Stale DB networks without corresponding Ganeti networks
807
  * Orphan Ganeti networks, without corresponding DB entries
808
  * Private networks that are not created to all Ganeti backends
809

    
810
To detect all inconsistencies you can just run:
811

    
812
.. code-block:: console
813

    
814
  $ snf-manage reconcile-networks
815

    
816
Adding the `--fix-all` option, will do the actual synchronization:
817

    
818
.. code-block:: console
819

    
820
  $ snf-manage reconcile-networks --fix-all
821

    
822
Please see ``snf-manage reconcile-networks --help`` for all the details.
823

    
824
Reconciling Pools
825
`````````````````
826

    
827
Reconciliation of pools will check the consistency of available pools by
828
checking that the values from each pool are not used more than once, and also
829
that the only reserved values in a pool are the ones used. Pool reconciliation
830
will check pools of bridges, MAC prefixes, and IPv4 addresses for all networks.
831

    
832
.. code-block:: console
833

    
834
  $ snf-manage reconcile-pools
835
  $ snf-manage reconcile-pools --fix
836

    
837
Cyclades internals
838
------------------
839

    
840
Asynchronous communication with Ganeti backends
841
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
842
Synnefo uses Google Ganeti backends for VM cluster management. In order for
843
Cyclades to be able to handle thousands of user requests, Cyclades and Ganeti
844
communicate asynchronously. Briefly, requests are submitted to Ganeti through
845
Ganeti's RAPI/HTTP interface, and then asynchronous notifications about the
846
progress of Ganeti jobs are being created and pushed upwards to Cyclades. The
847
architecture and communication with a Ganeti backend is shown in the graph
848
below:
849

    
850
.. image:: images/cyclades-ganeti-communication.png
851
   :width: 50%
852
   :target: _images/cyclades-ganeti-communication.png
853

    
854
The Cyclades API server is responsible for handling user requests. Read-only
855
requests are directly served by looking up the Cyclades DB. If the request
856
needs an action in the Ganeti backend, Cyclades submit jobs to the Ganeti
857
master using the `Ganeti RAPI interface
858
<http://docs.ganeti.org/ganeti/2.2/html/rapi.html>`_.
859

    
860
While Ganeti executes the job, `snf-ganeti-eventd`, and `snf-progress-monitor`
861
are monitoring the progress of the job and send corresponding messages to the
862
RabbitMQ servers. These components are part of `snf-cyclades-gtools` and must
863
be installed on all Ganeti nodes. Specially:
864

    
865
* *snf-ganeti-eventd* sends messages about operations affecting the operating
866
  state of instances and networks. Works by monitoring the Ganeti job queue.
867
* *snf-progress_monitor* sends messages about the progress of the Image deployment
868
  phase which is done by the Ganeti OS Definition `snf-image`.
869

    
870
Finally, `snf-dispatcher` consumes messages from the RabbitMQ queues, processes
871
these messages and properly updates the state of the Cyclades DB. Subsequent
872
requests to the Cyclades API, will retrieve the updated state from the DB.
873

    
874

    
875
Synnefo management commands ("snf-manage")
876
==========================================
877

    
878
Each Synnefo service, Astakos, Pithos and Cyclades are controlled by the
879
administrator using the "snf-manage" admin tool. This tool is an extension of
880
the Django command-line management utility. It is run on the host that runs
881
each service and provides different types of commands depending the services
882
running on the host. If you are running more than one service on the same host
883
"snf-manage" adds all the corresponding commands for each service dynamically,
884
providing a unified admin environment.
885

    
886
To run "snf-manage" you just type:
887

    
888
.. code-block:: console
889

    
890
   # snf-manage <command> [arguments]
891

    
892
on the corresponding host that runs the service. For example, if you have all
893
services running on different physical hosts you would do:
894

    
895
.. code-block:: console
896

    
897
   root@astakos-host # snf-manage <astakos-command> [argument]
898
   root@pithos-host # snf-manage <pithos-command> [argument]
899
   root@cyclades-host # snf-manage <cyclades-command> [argument]
900

    
901
If you have all services running on the same host you would do:
902

    
903
.. code-block:: console
904

    
905
   root@synnefo-host # snf-manage <{astakos,pithos,cyclades}-command> [argument]
906

    
907
Note that you cannot execute a service's command on a host that is not running
908
this service. For example, the following will return an error if Astakos and
909
Cyclades are installed on different physical hosts:
910

    
911
.. code-block:: console
912

    
913
   root@astakos-host # snf-manage <cyclades-command> [argument]
914
   Unknown command: 'cyclades-command'
915
   Type 'snf-manage help' for usage.
916

    
917
This is the complete list of "snf-manage" commands for each service.
918

    
919
Astakos snf-manage commands
920
---------------------------
921

    
922
============================  ===========================
923
Name                          Description
924
============================  ===========================
925
fix-superusers                Transform superusers created by syncdb into AstakosUser instances
926
cleanup-full                  Cleanup sessions and session catalog
927
commission-list               List pending commissions
928
commission-show               Show details for a pending commission
929
component-add                 Register a component
930
component-list                List components
931
component-modify              Modify component attributes
932
component-show                Show component details
933
project-control               Manage projects and applications
934
project-list                  List projects
935
project-show                  Show project details
936
quota-list                    List user quota
937
quota-verify                  Check the integrity of user quota
938
reconcile-resources-astakos   Reconcile resource usage of Quotaholder with Astakos DB
939
resource-list                 List resources
940
resource-modify               Modify a resource's default base quota and boolean flags
941
service-export-astakos        Export Astakos services and resources in JSON format
942
service-import                Register services
943
service-list                  List services
944
service-show                  Show service details
945
term-add                      Add approval terms
946
user-activation-send          Send user activation
947
user-add                      Add user
948
authpolicy-add                Create a new authentication provider policy profile
949
authpolicy-list               List existing authentication provider policy profiles
950
authpolicy-remove             Remove an authentication provider policy
951
authpolicy-set                Assign an existing authentication provider policy profile to a user or group
952
authpolicy-show               Show authentication provider profile details
953
group-add                     Create a group with the given name
954
group-list                    List available groups
955
user-list                     List users
956
user-modify                   Modify user
957
user-show                     Show user details
958
============================  ===========================
959

    
960
Pithos snf-manage commands
961
--------------------------
962

    
963
============================  ===========================
964
Name                          Description
965
============================  ===========================
966
reconcile-commissions-pithos  Display unresolved commissions and trigger their recovery
967
service-export-pithos         Export Pithos services and resources in JSON format
968
reconcile-resources-pithos    Detect unsynchronized usage between Astakos and Pithos DB resources and synchronize them if specified so.
969
============================  ===========================
970

    
971
Cyclades snf-manage commands
972
----------------------------
973

    
974
============================== ===========================
975
Name                           Description
976
============================== ===========================
977
backend-add                    Add a new Ganeti backend
978
backend-list                   List backends
979
backend-modify                 Modify a backend
980
backend-update-status          Update backend statistics for instance allocation
981
backend-remove                 Remove a Ganeti backend
982
enforce-resources-cyclades     Check and fix quota violations for Cyclades resources
983
server-create                  Create a new server
984
server-show                    Show server details
985
server-list                    List servers
986
server-modify                  Modify a server
987
server-import                  Import an existing Ganeti VM into synnefo
988
server-inspect                 Inspect a server in DB and Ganeti
989
network-create                 Create a new network
990
network-list                   List networks
991
network-modify                 Modify a network
992
network-inspect                Inspect network state in DB and Ganeti
993
network-remove                 Delete a network
994
flavor-create                  Create a new flavor
995
flavor-list                    List flavors
996
flavor-modify                  Modify a flavor
997
image-list                     List images
998
image-show                     Show image details
999
pool-create                    Create a bridge or mac-prefix pool
1000
pool-show                      Show pool details
1001
pool-list                      List pools
1002
pool-modify                    Modify a pool
1003
pool-remove                    Delete a pool
1004
port-create                    Create a port connecting a server to a network
1005
port-inspect                   Inspect the state of a port in DB and Ganeti
1006
port-list                      List ports
1007
port-remove                    Delete a port
1008
floating-ip-create             Create a new floating IP
1009
floating-ip-attach             Attach a floating IP to a server
1010
floating-ip-detach             Detach a floating IP from a server
1011
floating-ip-list               List floating IPs
1012
floating-ip-remove             Delete a floating IP
1013
queue-inspect                  Inspect the messages of a RabbitMQ queue
1014
queue-retry                    Resend messages from Dead Letter queues to original exchanges
1015
service-export-cyclades        Export Cyclades services and resources in JSON format
1016
subnet-create                  Create a subnet
1017
subnet-inspect                 Inspect a subnet in DB
1018
subnet-list                    List subnets
1019
subnet-modify                  Modify a subnet
1020
reconcile-servers              Reconcile servers of Synnefo DB with state of Ganeti backend
1021
reconcile-networks             Reconcile networks of Synnefo DB with state of Ganeti backend
1022
reconcile-pools                Check consistency of pool resources
1023
reconcile-commissions-cyclades Detect and resolve pending commissions to Quotaholder
1024
reconcile-resources-cyclades   Reconcile resource usage of Astakos with Cyclades DB.
1025
============================== ===========================
1026

    
1027

    
1028
Astakos helper scripts
1029
======================
1030

    
1031
Astakos includes two scripts to facilitate the installation procedure.
1032
Running:
1033

    
1034
.. code-block:: console
1035

    
1036
   snf-component-register [<component_name>]
1037

    
1038
automates the registration of the standard Synnefo components (astakos,
1039
cyclades, and pithos) in astakos database. It internally uses the script:
1040

    
1041
.. code-block:: console
1042

    
1043
   snf-service-export <component_name> <base_url>
1044

    
1045
which simulates the export of service and resource definitions of the
1046
standard Synnefo components.
1047

    
1048

    
1049
Pithos managing accounts
1050
========================
1051

    
1052
Pithos provides a utility tool for managing accounts.
1053
To run you just type:
1054

    
1055
.. code-block:: console
1056

    
1057
   # pithos-manage-accounts <command> [arguments]
1058

    
1059
This is the list of the available commands:
1060

    
1061
============================  ===========================
1062
Name                          Description
1063
============================  ===========================
1064
delete                        Remove an account from the Pithos DB
1065
export-quota                  Export account quota in a file
1066
list                          List existing/dublicate accounts
1067
merge                         Move an account contents in another account
1068
set-container-quota           Set container quota for all or a specific account
1069
============================  ===========================
1070

    
1071

    
1072
The "kamaki" API client
1073
=======================
1074

    
1075
To upload, register or modify an image you will need the **kamaki** tool.
1076
Before proceeding make sure that it is configured properly. Verify that
1077
*image.url*, *file.url*, *user.url* and *token* are set as needed:
1078

    
1079
.. code-block:: console
1080

    
1081
   $ kamaki config list
1082

    
1083
To change a setting use ``kamaki config set``:
1084

    
1085
.. code-block:: console
1086

    
1087
   $ kamaki config set image.url https://cyclades.example.com/image
1088
   $ kamaki config set file.url https://pithos.example.com/v1
1089
   $ kamaki config set user.url https://accounts.example.com
1090
   $ kamaki config set token ...
1091

    
1092
To test that everything works, try authenticating the current account with
1093
kamaki:
1094

    
1095
.. code-block:: console
1096

    
1097
  $ kamaki user authenticate
1098

    
1099
This will output user information.
1100

    
1101
Upload Image
1102
------------
1103

    
1104
By convention, images are stored in a container called ``images``. Check if the
1105
container exists, by listing all containers in your account:
1106

    
1107
.. code-block:: console
1108

    
1109
   $ kamaki file list
1110

    
1111
If the container ``images`` does not exist, create it:
1112

    
1113
.. code-block:: console
1114

    
1115
  $ kamaki file create images
1116

    
1117
You are now ready to upload an image to container ``images``. You can upload it
1118
with a Pithos client, or use kamaki directly:
1119

    
1120
.. code-block:: console
1121

    
1122
   $ kamaki file upload ubuntu.iso images
1123

    
1124
You can use any Pithos client to verify that the image was uploaded correctly,
1125
or you can list the contents of the container with kamaki:
1126

    
1127
.. code-block:: console
1128

    
1129
  $ kamaki file list images
1130

    
1131
The full Pithos URL for the previous example will be
1132
``pithos://u53r-un1qu3-1d/images/ubuntu.iso`` where ``u53r-un1qu3-1d`` is the
1133
unique user id (uuid).
1134

    
1135
Register Image
1136
--------------
1137

    
1138
To register an image you will need to use the full Pithos URL. To register as
1139
a public image the one from the previous example use:
1140

    
1141
.. code-block:: console
1142

    
1143
   $ kamaki image register Ubuntu pithos://u53r-un1qu3-1d/images/ubuntu.iso --public
1144

    
1145
The ``--public`` flag is important, if missing the registered image will not
1146
be listed by ``kamaki image list``.
1147

    
1148
Use ``kamaki image register`` with no arguments to see a list of available
1149
options. A more complete example would be the following:
1150

    
1151
.. code-block:: console
1152

    
1153
   $ kamaki image register Ubuntu pithos://u53r-un1qu3-1d/images/ubuntu.iso \
1154
            --public --disk-format diskdump --property kernel=3.1.2
1155

    
1156
To verify that the image was registered successfully use:
1157

    
1158
.. code-block:: console
1159

    
1160
   $ kamaki image list --name-like=ubuntu
1161

    
1162

    
1163
Miscellaneous
1164
=============
1165

    
1166
.. _branding:
1167

    
1168
Branding
1169
--------
1170

    
1171
Since Synnefo v0.14, you are able to adapt the Astakos, Pithos and Cyclades Web
1172
UI to your company’s visual identity. This is possible using the snf-branding
1173
component, which is automatically installed on the nodes running the API
1174
servers for Astakos, Pithos and Cyclades. 
1175

    
1176
Configuration
1177
~~~~~~~~~~~~~
1178

    
1179
This can be done by modifing the settings provided by the snf-branding component
1180
to match your service identity. The settings for the snf-branding application
1181
can be found inside the configuration file ``/etc/synnefo/15-snf-branding.conf``
1182
on the nodes that have Astakos, Pithos and Cyclades installed.
1183

    
1184
By default, the global service name is "Synnefo" and the company name is
1185
"GRNET". These names and their respective logos and URLs are used throughout
1186
the Astakos, Pithos and Cyclades UI.
1187

    
1188
**Names and URLs:**
1189

    
1190
The first group of branding customization refers to the service's and company's
1191
information.
1192

    
1193
You can overwrite the company and the service name and URL respectively by
1194
uncommenting and setting the following:
1195

    
1196
.. code-block:: python
1197
  
1198
  # setting used in Astakos Dashboard/Projects pages
1199
  BRANDING_SERVICE_NAME = 'My cloud'
1200
  BRANDING_SERVICE_URL = 'http://www.mycloud.synnefo.org/'
1201

    
1202
  # settings used in Astakos, Pithos, Cyclades footer only if 
1203
  # BRANDING_SHOW_COPYRIGHT is set to True
1204
  BRANDING_SHOW_COPYRIGHT = True
1205
  BRANDING_COMPANY_NAME = 'Company LTD'
1206
  BRANDING_COMPANY_URL = 'https://www.company-ltd.synnefo.org/'
1207

    
1208

    
1209
**Copyright and footer options:**
1210

    
1211
By default, no Copyright message is shown in the UI footer. If you want to make
1212
it visible in the footer of Astakos, Pithos and Cyclades UI, you can uncomment
1213
and set to ``True`` the ``BRANDING_SHOW_COPYRIGHT`` setting:
1214

    
1215
.. code-block:: python
1216

    
1217
  #BRANDING_SHOW_COPYRIGHT = False
1218

    
1219
Copyright message defaults to 'Copyright (c) 2011-<current_year>
1220
<BRANDING_COMPANY_NAME>.' but you can overwrite it to a completely custom one by
1221
setting the following option:
1222

    
1223
.. code-block:: python
1224

    
1225
  BRANDING_COPYRIGHT_MESSAGE = 'Copyright (c) 2011-2013 GRNET'
1226

    
1227
If you want to include a custom message in the footer, you can uncomment and 
1228
set the ``BRANDING_FOOTER_EXTRA_MESSAGE`` setting. You can use html markup. 
1229
Your custom message will appear  above Copyright message at the Compute 
1230
templates and the Dashboard UI.
1231

    
1232
.. code-block:: python
1233

    
1234
  #BRANDING_FOOTER_EXTRA_MESSAGE = ''
1235

    
1236

    
1237
**Images:**
1238

    
1239
The Astakos, Pithos and Cyclades Web UI has some logos and images.
1240
 
1241
The branding-related images are presented in  the following table:
1242

    
1243
===============  ============================  =========
1244
Image            Name/extension  convention    Usage
1245
===============  ============================  =========
1246
Favicon          favicon.ico                   Favicon for all services
1247
Dashboard logo   dashboard_logo.png            Visible in all Astakos UI pages
1248
Compute logo     compute_logo.png              Visible in all Cyclades UI pages
1249
Console logo     console_logo.png              Visible in the Cyclades Console Window
1250
Storage logo     storage_logo.png              Visible in all Pithos UI pages
1251
===============  ============================  =========
1252

    
1253
There are two methods  available for replacing all, or individual, 
1254
branding-related images:
1255

    
1256
1. Create a new directory inside ``/usr/share/synnefo/static/`` (e.g.
1257
   ``mybranding``) and place there some or all of your images.
1258

    
1259
   If you want to replace all of your images, keep the name/extension
1260
   conventions as indicated in the above table and change the
1261
   ``BRANDING_IMAGE_MEDIA_URL`` setting accordingly:
1262

    
1263
   .. code-block:: python
1264
        
1265
      # using relative path
1266
      BRANDING_IMAGE_MEDIA_URL= '/static/mybranding/images/' 
1267

    
1268
      # or if you already host them in a separate domain (e.g. cdn)
1269
      BRANDING_IMAGE_MEDIA_URL= 'https://cdn.synnefo.org/branding/images/'
1270

    
1271

    
1272
   If you wish to replace individual images, **do not uncomment**
1273
   ``BRANDING_IMAGE_MEDIA_URL``, but instead provide a relative path, pointing to
1274
   the file inside your directory for each ``BRANDING_<image>_URL`` that you wish
1275
   to replace.
1276

    
1277
2. Upload some or all of your images to a server and replace each 
1278
   ``BRANDING_<image>_URL`` with the absolute url of the image (i.e.
1279
   ``BRANDING_DASHBOARD_URL = 'https://www.synnefo.com/images/my_dashboard.jpg'``).
1280

    
1281
   Note that the alternative text  for each image tag inside html documents is 
1282
   alt=“BRANDING_SERVICE_NAME {Dashboard, Compute. Console, Storage}” respectively.
1283

    
1284
.. note:: Retina optimized images:
1285

    
1286
   Synnefo UI is optimized for Retina displays. As far as images are concerned,  
1287
   `retina.js <http://retinajs.com/>`_ is used.
1288

    
1289
   Retina.js checks each image on a page to see if there is a high-resolution 
1290
   version of that image on your server. If a high-resolution variant exists, 
1291
   the script will swap in that image in-place.
1292

    
1293
   The script assumes you use  `Apple's prescribed high-resolution modifier (@2x)
1294
   <http://developer.apple.com/library/ios/#documentation/2DDrawing/Conceptual/
1295
   DrawingPrintingiOS/SupportingHiResScreensInViews/SupportingHiResScreensInViews
1296
   .html#//apple_ref/doc/uid/TP40010156-CH15-SW1>`_ to denote high-resolution 
1297
   image variants on your server.
1298

    
1299
   For each of the images that you wish the script to  replace, you must have a 
1300
   high-resolution variant in the same folder  named correctly and it will be 
1301
   detected automatically. For example if your image is in <my_directory> and is 
1302
   named "my_image.jpg" the script will look in the same directory for an image 
1303
   named "my_image@2x.jpg".
1304

    
1305
   In case that you don’t want to use a high-resolution image, the 
1306
   normal-resolution image will be visible.
1307

    
1308
More branding
1309
~~~~~~~~~~~~~
1310

    
1311
Although, it is not 100% branding-related, further verbal customization is
1312
feasible. 
1313

    
1314
**EMAILS**
1315

    
1316
The output of all email `*`.txt files will be already customized to contain your
1317
company and service names but you can further alter their content if you feel it
1318
best fits your needs as simple as creasynnefo template.    
1319

    
1320
In order to overwrite one or more email-templates you need to place your 
1321
modified <email-file>.txt files respecting the following structure:
1322
  
1323
  **/etc/synnefo/templates/**
1324
      **im/**
1325
          | activation_email.txt
1326
          | email.txt
1327
          | invitation.txt
1328
          | switch_accounts_email.txt
1329
          | welcome_email.txt
1330
          **projects/**
1331
              | project_approval_notification.txt
1332
              | project_denial_notification.txt    
1333
              | project_membership_change_notification.txt
1334
              | project_membership_enroll_notification.txt
1335
              | project_membership_leave_request_notification.txt
1336
              | project_membership_request_notification.txt
1337
              | project_suspension_notification.txt
1338
              | project_termination_notification.txt
1339
      **registration/**
1340
          | email_change_email.txt
1341
          | password_email.txt
1342

    
1343
Feel free to omit any of the above files you do not wish to overwrite.
1344

    
1345
Below is a list of all emails sent by Synnefo to users along with a short 
1346
description and a link to their content:
1347

    
1348
* ``snf-astakos-app/astakos/im/templates/im/email.txt``
1349
  Base email template. Contains a contact email and a “thank you” message.
1350
  (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/email.txt>`_)
1351
* ``snf-astakos-app/astakos/im/templates/im/activation_email.txt`` Email sent to
1352
  user that prompts  him/her to click on a link provided to activate the account.
1353
  Extends “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/activation_email.txt>`_)
1354
* ``snf-astakos-app/astakos/im/templates/im/invitation.txt`` Email sent to an
1355
  invited user. He/she has to click on a link provided to activate the account.
1356
  Extends “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/invitation.txt>`_)
1357
* ``snf-astakos-app/astakos/im/templates/im/switch_accounts_email.txt`` Email
1358
  sent to user upon his/her request to associate this email address with a
1359
  shibboleth account. He/she has to click on a link provided to activate the
1360
  association. Extends “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/switch_accounts_email.txt>`_)
1361
* ``snf-astakos-app/astakos/im/templates/im/welcome_email.txt`` Email sent to
1362
  inform the user that his/ her account has been activated. Extends “email.txt”
1363
  (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/welcome_email.txt>`_)
1364
* ``snf-astakos-app/astakos/im/templates/registration/email_change_email.txt``
1365
  Email sent to user when he/she has requested new email address assignment. The
1366
  user has to click on a link provided to validate this action. Extends
1367
  “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/registration/email_change_email.txt>`_)
1368
* ``snf-astakos-app/astakos/im/templates/registration/password_email.txt`` Email
1369
  sent for resetting password purpose. The user has to click on a link provided
1370
  to validate this action. Extends “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/registration/password_email.txt>`_)
1371
* ``snf-astakos-app/astakos/im/templates/im/projects/project_approval_notification.txt``
1372
  Informs  the project owner that his/her project has been approved. Extends
1373
  “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/projects/project_approval_notification.txt>`_)
1374
* ``snf-astakos-app/astakos/im/templates/im/projects/project_denial_notification.txt``
1375
  Informs the project owner that his/her  project application has been denied
1376
  explaining the reasons. Extends “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/projects/project_denial_notification.txt>`_)
1377
* ``snf-astakos-app/astakos/im/templates/im/projects/project_membership_change_notification.txt``
1378
  An email is sent to a user containing information about his project membership
1379
  (whether he has been accepted, rejected or removed). Extends “email.txt” (`Link
1380
  <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/projects/project_membership_change_notification.txt>`_)
1381
* ``snf-astakos-app/astakos/im/templates/im/projects/project_membership_enroll_notification.txt``
1382
  Informs a user that he/she  has been enrolled to a project. Extends
1383
  “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/projects/project_membership_enroll_notification.txt>`_)
1384
* ``snf-astakos-app/astakos/im/templates/im/projects/project_membership_leave_request_notification.txt``
1385
  An email is sent to the project owner to make him aware of a  user having
1386
  requested to leave his project. Extends “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/projects/project_membership_leave_request_notification.txt>`_)
1387
* ``snf-astakos-app/astakos/im/templates/im/projects/project_membership_request_notification.txt``
1388
  An email is sent to the project owner to make him/her aware of a user having
1389
  requested to join  his project. Extends “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/projects/project_membership_request_notification.txt>`_)
1390
* ``snf-astakos-app/astakos/im/templates/im/projects/project_suspension_notification.txt``
1391
  An email is sent to the project owner to make him/her aware of his/her project
1392
  having been suspended. Extends “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/projects/project_suspension_notification.txt>`_)
1393
* ``snf-astakos-app/astakos/im/templates/im/projects/project_termination_notification.txt``
1394
  An email is sent to the project owner to make him/her aware of his/her project
1395
  having been terminated. Extends “email.txt” (`Link <https://code.grnet.gr/projects/synnefo/repository/revisions/master/changes/snf-astakos-app/astakos/im/templates/im/projects/project_termination_notification.txt>`_)
1396

    
1397
.. warning:: Django templates language:
1398

    
1399
  If you choose to  overwrite these email templates, be mindful of the necessary 
1400
  information contained in django template variables that must not be omitted, 
1401
  such as the activation link for activating one’s account and many more. 
1402
  These variables are contained into {{}} inside the templates.
1403

    
1404

    
1405
.. RabbitMQ
1406

    
1407
RabbitMQ Broker
1408
---------------
1409

    
1410
Queue nodes run the RabbitMQ sofware, which provides AMQP functionality. To
1411
guarantee high-availability, more than one Queue nodes should be deployed, each
1412
of them belonging to the same `RabbitMQ cluster
1413
<http://www.rabbitmq.com/clustering.html>`_. Synnefo uses the RabbitMQ
1414
active/active `High Available Queues <http://www.rabbitmq.com/ha.html>`_ which
1415
are mirrored between two nodes within a RabbitMQ cluster.
1416

    
1417
The RabbitMQ nodes that form the cluster, are declared to Synnefo through the
1418
`AMQP_HOSTS` setting. Each time a Synnefo component needs to connect to
1419
RabbitMQ, one of these nodes is chosen in a random way. The client that Synnefo
1420
uses to connect to RabbitMQ, handles connection failures transparently and
1421
tries to reconnect to a different node. As long as one of these nodes are up
1422
and running, functionality of Synnefo should not be downgraded by the RabbitMQ
1423
node failures.
1424

    
1425
All the queues that are being used are declared as durable, meaning that
1426
messages are persistently stored to RabbitMQ, until they get successfully
1427
processed by a client.
1428

    
1429
Currently, RabbitMQ is used by the following components:
1430

    
1431
* `snf-ganeti-eventd` and `snf-progress-monitor`:
1432
  These components send messages concerning the status and progress of
1433
  jobs in the Ganeti backend.
1434
* `snf-dispatcher`: This daemon, consumes the messages that are sent from
1435
  the above components, and updates the Cyclades DB accordingly.
1436

    
1437

    
1438
Installation
1439
~~~~~~~~~~~~
1440

    
1441
Please check the RabbitMQ documentation which covers extensively the
1442
`installation of RabbitMQ server <http://www.rabbitmq.com/download.html>`_ and
1443
the setup of a `RabbitMQ cluster <http://www.rabbitmq.com/clustering.html>`_.
1444
Also, check out the `web management plugin
1445
<http://www.rabbitmq.com/management.html>`_ that can be useful for managing and
1446
monitoring RabbitMQ.
1447

    
1448
For a basic installation of RabbitMQ on two nodes (node1 and node2) you can do
1449
the following:
1450

    
1451
On both nodes, install rabbitmq-server and create a Synnefo user:
1452

    
1453
.. code-block:: console
1454

    
1455
  $ apt-get install rabbitmq-server
1456
  $ rabbitmqctl add_user synnefo "example_pass"
1457
  $ rabbitmqctl set_permissions synnefo  ".*" ".*" ".*"
1458

    
1459
Also guarantee that both nodes share the same cookie, by running:
1460

    
1461
.. code-block:: console
1462

    
1463
  $ scp node1:/var/lib/rabbitmq/.erlang.cookie node2:/var/lib/rabbitmq/.erlang.cookie
1464

    
1465
and restart the nodes:
1466

    
1467
.. code-block:: console
1468

    
1469
  $ /etc/init.d/rabbitmq-server restart
1470

    
1471

    
1472
To setup the RabbitMQ cluster run:
1473

    
1474
.. code-block:: console
1475

    
1476
  root@node2: rabbitmqctl stop_app
1477
  root@node2: rabbitmqctl reset
1478
  root@node2: rabbitmqctl cluster rabbit@node1 rabbit@node2
1479
  root@node2: rabbitmqctl start_app
1480

    
1481
You can verify that the cluster is set up correctly by running:
1482

    
1483
.. code-block:: console
1484

    
1485
  root@node2: rabbitmqctl cluster_status
1486

    
1487

    
1488
Logging
1489
-------
1490

    
1491
Logging in Synnefo is using Python's logging module. The module is configured
1492
using dictionary configuration, whose format is described here:
1493

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

    
1496
Note that this is a feature of Python 2.7 that we have backported for use in
1497
Python 2.6.
1498

    
1499
The logging configuration dictionary is defined in
1500
``/etc/synnefo/10-snf-webproject-logging.conf``
1501

    
1502
The administrator can have finer logging control by modifying the
1503
``LOGGING_SETUP`` dictionary, and defining subloggers with different handlers
1504
and log levels.  e.g. To enable debug messages only for the API set the level
1505
of 'synnefo.api' to ``DEBUG``
1506

    
1507
By default, the Django webapp and snf-manage logs to syslog, while
1508
`snf-dispatcher` logs to `/var/log/synnefo/dispatcher.log`.
1509

    
1510

    
1511
.. _scale-up:
1512

    
1513
Scaling up to multiple nodes
1514
============================
1515

    
1516
Here we will describe how should a large scale Synnefo deployment look like. Make
1517
sure you are familiar with Synnefo and Ganeti before proceeding with this section.
1518
This means you should at least have already set up successfully a working Synnefo
1519
deployment as described in the :ref:`Admin's Installation Guide
1520
<quick-install-admin-guide>` and also read the Administrator's Guide until this
1521
section.
1522

    
1523
Graph of a scale-out Synnefo deployment
1524
---------------------------------------
1525

    
1526
Each box in the following graph corresponds to a distinct physical node:
1527

    
1528
.. image:: images/synnefo-arch2-roles.png
1529
   :width: 100%
1530
   :target: _images/synnefo-arch2-roles.png
1531

    
1532
The above graph is actually the same with the one at the beginning of this
1533
:ref:`guide <admin-guide>`, with the only difference that here we show the
1534
Synnefo roles of each physical node. These roles are described in the
1535
following section.
1536

    
1537
.. _physical-node-roles:
1538

    
1539
Physical Node roles
1540
-------------------
1541

    
1542
As appears in the previous graph, a scale-out Synnefo deployment consists of
1543
multiple physical nodes that have the following roles:
1544

    
1545
* **WEBSERVER**: A web server running in front of gunicorn (e.g.: Apache, nginx)
1546
* **ASTAKOS**: The Astakos application (gunicorn)
1547
* **ASTAKOS_DB**: The Astakos database (postgresql)
1548
* **PITHOS**: The Pithos application (gunicorn)
1549
* **PITHOS_DB**: The Pithos database (postgresql)
1550
* **CYCLADES**: The Cyclades application (gunicorn)
1551
* **CYCLADES_DB**: The Cyclades database (postgresql)
1552
* **MQ**: The message queue (RabbitMQ)
1553
* **GANETI_MASTER**: The Ganeti master of a Ganeti cluster
1554
* **GANETI_NODE** : A VM-capable Ganeti node of a Ganeti cluster
1555

    
1556
You will probably also have:
1557

    
1558
* **CMS**: The CMS used as a frotend portal for the Synnefo services
1559
* **NS**: A nameserver serving all other Synnefo nodes and resolving Synnefo FQDNs
1560
* **CLIENT**: A machine that runs the Synnefo clients (e.g.: kamaki, Web UI),
1561
              most of the times, the end user's local machine
1562

    
1563
From this point we will also refer to the following groups of roles:
1564

    
1565
* **SYNNEFO**: [ **ASTAKOS**, **ASTAKOS_DB**, **PITHOS**, **PITHOS_DB**, **CYCLADES**, **CYCLADES_DB**, **MQ**, **CMS**]
1566
* **G_BACKEND**: [**GANETI_MASTER**, **GANETI_NODE**]
1567

    
1568
Of course, when deploying Synnefo you can combine multiple of the above roles on a
1569
single physical node, but if you are trying to scale out, the above separation
1570
gives you significant advantages.
1571

    
1572
So, in the next section we will take a look on what components you will have to
1573
install on each physical node depending on its Synnefo role. We assume the graph's
1574
architecture.
1575

    
1576
Components for each role
1577
------------------------
1578

    
1579
When deploying Synnefo in large scale, you need to install different Synnefo
1580
or/and third party components on different physical nodes according to their
1581
Synnefo role, as stated in the previous section.
1582

    
1583
Specifically:
1584

    
1585
Role **WEBSERVER**
1586
    * Synnefo components: `None`
1587
    * 3rd party components: Apache
1588
Role **ASTAKOS**
1589
    * Synnefo components: `snf-webproject`, `snf-astakos-app`
1590
    * 3rd party components: Django, Gunicorn
1591
Role **ASTAKOS_DB**
1592
    * Synnefo components: `None`
1593
    * 3rd party components: PostgreSQL
1594
Role **PITHOS**
1595
    * Synnefo components: `snf-webproject`, `snf-pithos-app`, `snf-pithos-webclient`
1596
    * 3rd party components: Django, Gunicorn
1597
Role **PITHOS_DB**
1598
    * Synnefo components: `None`
1599
    * 3rd party components: PostgreSQL
1600
Role **CYCLADES**
1601
    * Synnefo components: `snf-webproject`, `snf-cyclades-app`, `snf-vncauthproxy`
1602
    * 3rd party components: Django Gunicorn
1603
Role **CYCLADES_DB**
1604
    * Synnefo components: `None`
1605
    * 3rd party components: PostgreSQL
1606
Role **MQ**
1607
    * Synnefo components: `None`
1608
    * 3rd party components: RabbitMQ
1609
Role **GANETI_MASTER**
1610
    * Synnefo components: `snf-cyclades-gtools`
1611
    * 3rd party components: Ganeti
1612
Role **GANETI_NODE**
1613
    * Synnefo components: `snf-cyclades-gtools`, `snf-network`, `snf-image`, `nfdhcpd`
1614
    * 3rd party components: Ganeti
1615
Role **CMS**
1616
    * Synnefo components: `snf-webproject`, `snf-cloudcms`
1617
    * 3rd party components: Django, Gunicorn
1618
Role **NS**
1619
    * Synnefo components: `None`
1620
    * 3rd party components: BIND
1621
Role **CLIENT**
1622
    * Synnefo components: `kamaki`, `snf-image-creator`
1623
    * 3rd party components: `None`
1624

    
1625
Example scale out installation
1626
------------------------------
1627

    
1628
In this section we describe an example of a medium scale installation which
1629
combines multiple roles on 10 different physical nodes. We also provide a
1630
:ref:`guide <i-synnefo>` to help with such an install.
1631

    
1632
We assume that we have the following 10 physical nodes with the corresponding
1633
roles:
1634

    
1635
Node1:
1636
    **WEBSERVER**, **ASTAKOS**
1637
      Guide sections:
1638
        * :ref:`apt <i-apt>`
1639
        * :ref:`gunicorn <i-gunicorn>`
1640
        * :ref:`apache <i-apache>`
1641
        * :ref:`snf-webproject <i-webproject>`
1642
        * :ref:`snf-astakos-app <i-astakos>`
1643
Node2:
1644
    **WEBSERVER**, **PITHOS**
1645
      Guide sections:
1646
        * :ref:`apt <i-apt>`
1647
        * :ref:`gunicorn <i-gunicorn>`
1648
        * :ref:`apache <i-apache>`
1649
        * :ref:`snf-webproject <i-webproject>`
1650
        * :ref:`snf-pithos-app <i-pithos>`
1651
        * :ref:`snf-pithos-webclient <i-pithos>`
1652
Node3:
1653
    **WEBSERVER**, **CYCLADES**
1654
      Guide sections:
1655
        * :ref:`apt <i-apt>`
1656
        * :ref:`gunicorn <i-gunicorn>`
1657
        * :ref:`apache <i-apache>`
1658
        * :ref:`snf-webproject <i-webproject>`
1659
        * :ref:`snf-cyclades-app <i-cyclades>`
1660
        * :ref:`snf-vncauthproxy <i-cyclades>`
1661
Node4:
1662
    **WEBSERVER**, **CMS**
1663
      Guide sections:
1664
        * :ref:`apt <i-apt>`
1665
        * :ref:`gunicorn <i-gunicorn>`
1666
        * :ref:`apache <i-apache>`
1667
        * :ref:`snf-webproject <i-webproject>`
1668
        * :ref:`snf-cloudcms <i-cms>`
1669
Node5:
1670
    **ASTAKOS_DB**, **PITHOS_DB**, **CYCLADES_DB**
1671
      Guide sections:
1672
        * :ref:`apt <i-apt>`
1673
        * :ref:`postgresql <i-db>`
1674
Node6:
1675
    **MQ**
1676
      Guide sections:
1677
        * :ref:`apt <i-apt>`
1678
        * :ref:`rabbitmq <i-mq>`
1679
Node7:
1680
    **GANETI_MASTER**, **GANETI_NODE**
1681
      Guide sections:
1682
        * :ref:`apt <i-apt>`
1683
        * :ref:`general <i-backends>`
1684
        * :ref:`ganeti <i-ganeti>`
1685
        * :ref:`snf-cyclades-gtools <i-gtools>`
1686
        * :ref:`snf-network <i-network>`
1687
        * :ref:`snf-image <i-image>`
1688
        * :ref:`nfdhcpd <i-network>`
1689
Node8:
1690
    **GANETI_NODE**
1691
      Guide sections:
1692
        * :ref:`apt <i-apt>`
1693
        * :ref:`general <i-backends>`
1694
        * :ref:`ganeti <i-ganeti>`
1695
        * :ref:`snf-cyclades-gtools <i-gtools>`
1696
        * :ref:`snf-network <i-network>`
1697
        * :ref:`snf-image <i-image>`
1698
        * :ref:`nfdhcpd <i-network>`
1699
Node9:
1700
    **GANETI_NODE**
1701
      Guide sections:
1702
        `Same as Node8`
1703
Node10:
1704
    **GANETI_NODE**
1705
      Guide sections:
1706
        `Same as Node8`
1707

    
1708
All sections: :ref:`Scale out Guide <i-synnefo>`
1709

    
1710

    
1711
Upgrade Notes
1712
=============
1713

    
1714
.. toctree::
1715
   :maxdepth: 1
1716

    
1717
   v0.12 -> v0.13 <upgrade/upgrade-0.13>
1718
   v0.13 -> v0.14 <upgrade/upgrade-0.14>
1719
   v0.14 -> v0.14.2 <upgrade/upgrade-0.14.2>
1720
   v0.14.5 -> v0.14.6 <upgrade/upgrade-0.14.6>
1721
   v0.14.7 -> v0.14.8 <upgrade/upgrade-0.14.8>
1722
   v0.14.9 -> v0.14.10 <upgrade/upgrade-0.14.10>
1723
   v0.14 -> v0.15 <upgrade/upgrade-0.15>
1724

    
1725

    
1726
Changelog, NEWS
1727
===============
1728

    
1729

    
1730
* v0.14.10 :ref:`Changelog <Changelog-0.14.10>`, :ref:`NEWS <NEWS-0.14.10>`
1731
* v0.14.9 :ref:`Changelog <Changelog-0.14.9>`, :ref:`NEWS <NEWS-0.14.9>`
1732
* v0.14.8 :ref:`Changelog <Changelog-0.14.8>`, :ref:`NEWS <NEWS-0.14.8>`
1733
* v0.14.7 :ref:`Changelog <Changelog-0.14.7>`, :ref:`NEWS <NEWS-0.14.7>`
1734
* v0.14.6 :ref:`Changelog <Changelog-0.14.6>`, :ref:`NEWS <NEWS-0.14.6>`
1735
* v0.14.5 :ref:`Changelog <Changelog-0.14.5>`, :ref:`NEWS <NEWS-0.14.5>`
1736
* v0.14.4 :ref:`Changelog <Changelog-0.14.4>`, :ref:`NEWS <NEWS-0.14.4>`
1737
* v0.14.3 :ref:`Changelog <Changelog-0.14.3>`, :ref:`NEWS <NEWS-0.14.3>`
1738
* v0.14.2 :ref:`Changelog <Changelog-0.14.2>`, :ref:`NEWS <NEWS-0.14.2>`
1739
* v0.14 :ref:`Changelog <Changelog-0.14>`, :ref:`NEWS <NEWS-0.14>`
1740
* v0.13 :ref:`Changelog <Changelog-0.13>`, :ref:`NEWS <NEWS-0.13>`