Revision fa382f9e

b/docs/commands.rst
1 1
List of commands
2 2
================
3 3

  
4
The commands described bellow are grouped by service. The examples showcase a sample set of group commands. The kamaki interactive shell (check `Usage section <usage.html#interactive-shell>`_ for details) is chosen as the execution environment.
4
The commands described bellow are grouped by service. The examples showcase a
5
sample set of group commands. The kamaki interactive shell (check
6
`Usage section <usage.html#interactive-shell>`_ for details) is chosen as the
7
execution environment.
5 8

  
6 9

  
7 10
user (Identity Manager)
......
14 17
Showcase: get user information
15 18
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16 19

  
17
In the following, the token has been set in a previous step (see `setup section <setup.html>`_ or the `quick setup guide <usage.html#quick-setup>`_)
20
In the following, the token has been set in a previous step (see
21
`setup section <setup.html>`_ or the
22
`quick setup guide <usage.html#quick-setup>`_)
18 23

  
19 24
.. code-block:: console
20 25
    :emphasize-lines: 1,4
......
24 29

  
25 30
    * Authenticate user *
26 31
    [user]: authenticate
27
    auth_token_created:  2012-11-13T14:12:40.917034
28
    auth_token_expires:  2012-12-13T14:12:40.917035
29
    email             :  
30
                       myaccount@grnet.gr
31
                       myotheraccount@grnet.gr
32
    name              :  My Real Name
33
    username          :  usually@an.email.org
34
    uuid              :  ab1cde23-45fg-6h7i-8j9k-10l1m11no2pq
32
    ...
33
    user:
34
        name:  My Real Name
35
        uuid:  ab1cde23-45fg-6h7i-8j9k-10l1m11no2pq
36

  
37
.. note:: actual call returns a full list of service endpoints accessible to
38
    the user with a specific token
35 39

  
36 40
flavor (Compute/Cyclades)
37 41
-------------------------
......
53 57
    * Get details about flavor with id 43 *
54 58
    [flavor]: info 43
55 59
    SNF:disk_template:  drbd
56
    cpu              :  4
57
    disk             :  10
58
    id               :  43
59
    name             :  C4R2048D10
60
    ram              :  2048
60
    cpu :  4
61
    disk:  10
62
    id  :  43
63
    name:  C4R2048D10
64
    ram :  2048
61 65

  
62 66
image (Plankton commands + Compute Image subcommands)
63 67
-----------------------------------------------------
64 68

  
65 69
.. code-block:: text
66 70

  
67
    list       :  List images accessible by user
68
    meta       :  Get image metadata
69
    register   :  (Re)Register an image
70
    unregister :  Unregister an image (does not delete the image file)
71
    shared     :  List shared images
72
    compute    :  Compute Image API commands
73
        list       :  List images
74
        delete     :  Delete image
75
        info       :  Get image details
76
        properties :  Manage properties related to OS installation in an image
71
    list      :  List images accessible by user
72
    meta      :  Get image metadata
73
    register  :  (Re)Register an image
74
    unregister:  Unregister an image (does not delete the image file)
75
    shared    :  List shared images
76
    compute   :  Compute Image API commands
77
        list      :  List images
78
        delete    :  Delete image
79
        info      :  Get image details
80
        properties:  Manage properties related to OS installation in an image
77 81
            add   :  Add a property to an image
78 82
            delete:  Delete a property from an image
79 83
            get   :  Get an image property
80 84
            list  :  List all image properties
81 85
            set   :  Add / update a set of properties for an image
82
    members    :  Manage members (users who can modify an image)
83
        add    :  Add a member to an image
84
        delete :  Remove a member from an image
85
        list   :  List members of an image
86
        set    :  Set the members of an image
86
    members   :  Manage members (users who can modify an image)
87
        add   :  Add a member to an image
88
        delete:  Remove a member from an image
89
        list  :  List members of an image
90
        set   :  Set the members of an image
87 91

  
88 92
Showcase: Pick an image and list the properties
89 93
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......
96 100

  
97 101
    * list all available images *
98 102
    [image]: list
99
    1. Windows Server 2008
103
    926ab1c5-2d85-49d4-aebe-0fce712789b9 Windows Server 2008
100 104
     container_format:  bare
101 105
     disk_format     :  diskdump
102 106
     id              :  926ab1c5-2d85-49d4-aebe-0fce712789b9
103 107
     size            :  11917066240
104 108
     status          :  available
105
    2. Windows Server 2012
109
    78262ee7-949e-4d70-af3a-85360c3de57a Windows Server 2012
106 110
     container_format:  bare
107 111
     disk_format     :  diskdump
108 112
     id              :  78262ee7-949e-4d70-af3a-85360c3de57a
109 113
     size            :  11697913856
110 114
     status          :  available
111
    3. ubuntu
115
    5ed5a29b-292c-4fe0-b32c-2e2b65628635 ubuntu
112 116
     container_format:  bare
113 117
     disk_format     :  diskdump
114 118
     id              :  5ed5a29b-292c-4fe0-b32c-2e2b65628635
115 119
     size            :  2578100224
116 120
     status          :  available
117
    4. Debian_Wheezy_Base
121
    1f8454f0-8e3e-4b6c-ab8e-5236b728dffe Debian_Wheezy_Base
118 122
     container_format:  bare
119 123
     disk_format     :  diskdump
120 124
     id              :  1f8454f0-8e3e-4b6c-ab8e-5236b728dffe
......
170 174
    * See server-create help *
171 175
    [server]: create -h
172 176
    usage: create <name> <flavor id> <image id>
173
            [--personality PERSONALITY] [-h] [--config CONFIG]
177
            [--personality PERSONALITY] [-h] [--config CONFIG] [--cloud CLOUD]
174 178

  
175 179
    Create a server
176 180

  
......
183 187
      -i, --include         Include protocol headers in the output
184 188
      --config CONFIG       Path to configuration file
185 189
      -s, --silent          Do not output anything
190
      --cloud CLOUD         Chose a cloud to connect to
186 191

  
187 192
    * List all available images *
188 193
    [server]: /image compute list
......
216 221
    id       :  11687
217 222
    imageRef :  b2dffe52-64a4-48c3-8a4c-8214cc3165cf
218 223
    metadata : 
219
             values: 
220
                   os   :  debian
221
                   users:  root
224
               os   :  debian
225
               users:  root
222 226
    name     :  My Small Debian Server
223 227
    progress :  0
224 228
    status   :  BUILD
......
281 285
    [network]: info 1409
282 286
      attachments: 
283 287
                 nic-11687-1
284
      cidr       :  192.168.1.0/24
285
      cidr6      :  None
286
      created    :  2012-11-23T17:17:20.560098+00:00
287
      dhcp       :  True
288
      gateway    :  None
289
      gateway6   :  None
290
      id         :  1409
291
      name       :  my network
292
      public     :  False
293
      status     :  ACTIVE
294
      type       :  PRIVATE_MAC_FILTERED
295
      updated    :  2012-11-23T17:18:25.095225+00:00
288
      cidr    :  192.168.1.0/24
289
      cidr6   :  None
290
      created :  2012-11-23T17:17:20.560098+00:00
291
      dhcp    :  True
292
      gateway :  None
293
      gateway6:  None
294
      id      :  1409
295
      name    :  my network
296
      public  :  False
297
      status  :  ACTIVE
298
      type    :  MAC_FILTERED
299
      updated :  2012-11-23T17:18:25.095225+00:00
296 300

  
297 301
    * Get connectivity details on VM with id 11687 *
298 302
    [network]: /server addr 11687
......
431 435
    -rw-rw-r-- 1 ******** ******** 20M Nov 26 15:42 rndm_remote.file
432 436
    [file]: !diff rndm_local.file rndm_remote.file
433 437

  
434
.. Note:: In kamaki shell, ! is used to execute OS shell commands (bash in the above)
438
.. Note:: In kamaki shell, ! is used to execute OS shell commands (e.g. bash)
435 439

  
436
.. warning:: The container:object/path syntax does not function if the container and / or the object path contain one or more : characters. To use containers and objects with : use the --container and --dst-container arguments, e.g. to copy test.py object from grnet:dev container to grnet:deploy ::
440
.. warning:: The container:object/path syntax does not function if the
441
    container and / or the object path contain one or more : characters. To use
442
    containers and objects with : use the --container and --dst-container
443
    arguments, e.g. to copy test.py object from grnet:dev container to
444
    grnet:deploy ::
437 445

  
438 446
        $ kamaki file copy --container=grnet:dev test.py --dst-container=grnet:deploy
b/docs/developers/adding-commands.rst
1 1
Adding Commands
2 2
===============
3 3

  
4
Kamaki commands are implemented as python classes, decorated with a special decorator called *command*. This decorator is a method of kamaki.cli that adds a new command in a CommandTree structure (kamaki.cli.commant_tree). The later is used by interfaces to manage kamaki commands.
4
Kamaki commands are implemented as python classes, decorated with a special
5
decorator called *command*. This decorator is a method of kamaki.cli that adds
6
a new command in a CommandTree structure (kamaki.cli.commant_tree). The later
7
is used by interfaces to manage kamaki commands.
5 8

  
6 9
In the following, a set of kamaki commands will be implemented::
7 10

  
......
10 13
    mygrp2 list all [regular expression] [-l]       //list all subjects
11 14
    mygrp2 info <id> [name]      //get information for subject with id
12 15

  
13
There are two command sets to implement, namely mygrp1 and mygrp2. The first will contain two commands, namely list-all and list-details. The second one will also contain two commands, list-all and info. To avoid ambiguities, command names should rather be prefixed with the group they belong to, e.g. mygrp1-list-all and mygrp2-list-all.
16
There are two command sets to implement, namely mygrp1 and mygrp2. The first
17
will contain two commands, namely list-all and list-details. The second one
18
will also contain two commands, list-all and info. To avoid ambiguities,
19
command names should rather be prefixed with the group they belong to, e.g.
20
mygrp1-list-all and mygrp2-list-all.
14 21

  
15
The first command has the simplest possible syntax: no parameters, no runtime arguments. The second accepts an optional runtime argument with a value. The third features an optional argument and an optional runtime flag argument. The last is an example of a command with an obligatory and an optional argument.
22
The first command has the simplest possible syntax: no parameters, no runtime
23
arguments. The second accepts an optional runtime argument with a value. The
24
third features an optional argument and an optional runtime flag argument. The
25
last is an example of a command with an obligatory and an optional argument.
16 26

  
17 27
Samples of the expected behavior in one-command mode are following:
18 28

  
......
37 47
        ... (mygrp2 client method is called) ...
38 48
    $
39 49

  
40
The above example will be used throughout the present guide for clarification purposes.
50
The above example will be used throughout the present guide.
41 51

  
42 52
The CommandTree structure
43 53
-------------------------
44 54

  
45
CommandTree manages a command by its path. Each command is stored in multiple nodes on the tree, so that the last term is a leaf and the route from root to that leaf represents the command path. For example the commands *file upload*, *file list* and *file info* are stored together as shown bellow::
55
CommandTree manages a command by its path. Each command is stored in multiple
56
nodes on the tree, so that the last term is a leaf and the route from root to
57
that leaf represents the command path. For example the commands *file upload*,
58
*file list* and *file info* are stored together as shown bellow::
46 59

  
47 60
    - file
48 61
    ''''''''|- info
......
61 74
            '''''''|- all
62 75
            |- info
63 76

  
64
Each command group should be stored on a different CommandTree. For that reason, command specification modules should contain a list of CommandTree objects, named *_commands*
77
Each command group should be stored on a different CommandTree. For that
78
reason, command specification modules should contain a list of CommandTree
79
objects, named *_commands*
65 80

  
66
A command group information (name, description) is provided at CommandTree structure initialization:
81
A command group information (name, description) is provided at CommandTree
82
structure initialization:
67 83

  
68 84
.. code-block:: python
69 85

  
......
75 91
The command decorator
76 92
---------------------
77 93

  
78
The *command* decorator mines all the information necessary to build a command specification which is then inserted in a CommanTree instance::
94
The *command* decorator mines all the information necessary to build a command
95
specification which is then inserted in a CommanTree instance::
79 96

  
80 97
    class code  --->  command()  -->  updated CommandTree structure
81 98

  
82
Kamaki interfaces make use of this CommandTree structure. Optimizations are possible by using special parameters on the command decorator method.
99
Kamaki interfaces make use of this CommandTree structure. Optimizations are
100
possible by using special parameters on the command decorator method.
83 101

  
84 102
.. code-block:: python
85 103

  
86 104
    def command(cmd_tree, prefix='', descedants_depth=None):
87 105
    """Load a class as a command
106

  
88 107
        :param cmd_tree: is the CommandTree to be updated with a new command
108

  
89 109
        :param prefix: of the commands allowed to be inserted ('' for all)
110

  
90 111
        :param descedants_depth: is the depth of the tree descedants of the
91 112
            prefix command.
92 113
    """
......
107 128

  
108 129
    ...
109 130

  
110
A list of CommandTree structures must exist in the module scope, with the name _commands, as shown above. Different CommandTree objects correspond to different command groups.
131
A list of CommandTree structures must exist in the module scope, with the name
132
_commands, as shown above. Different CommandTree objects correspond to
133
different command groups.
111 134

  
112 135
Get command description
113 136
-----------------------
114 137

  
115
The description of each command is the first line of the class commend. The following declaration of *mygrp2-info* command has a "*get information for subject with id*" description.
138
The description of each command is the first line of the class commend. The
139
following declaration of *mygrp2-info* command has a "*get information for
140
subject with id*" description.
116 141

  
117 142
.. code-block:: python
118 143

  
......
125 150
Declare run-time argument
126 151
-------------------------
127 152

  
128
The argument mechanism allows the definition of run-time arguments. Some basic argument types are defined at the `argument module <code.html#module-kamaki.cli.argument>`_, but it is not uncommon to extent these classes in order to achieve specialized type checking and syntax control (e.g. at `pithos cli module <code.html#module-kamaki.cli.commands.pithos>`_).
153
The argument mechanism allows the definition of run-time arguments. Some basic
154
argument types are defined at the
155
`argument module <code.html#module-kamaki.cli.argument>`_, but it is not
156
uncommon to extent these classes in order to achieve specialized type checking
157
and syntax control (e.g. at
158
`pithos cli module <code.html#module-kamaki.cli.commands.pithos>`_).
129 159

  
130
To declare a run-time argument on a specific command, the object class should initialize a dict called *arguments* , where Argument objects are stored. Each argument object is a possible run-time argument. Syntax checking happens at client level, while the type checking is implemented in the Argument code (thus, many different Argument types might be needed).
160
To declare a run-time argument on a specific command, the object class should
161
initialize a dict called *arguments* , where Argument objects are stored. Each
162
argument object is a possible run-time argument. Syntax checking happens at
163
client level, while the type checking is implemented in the Argument code
164
(thus, many different Argument types might be needed).`
131 165

  
132 166
.. code-block:: python
133 167

  
......
141 175
        def __init__(self, global_args={}):
142 176
            global_args['match'] = ValueArgument(
143 177
                'Filter results to match string',
144
                '--match')
178
                ('-m', '--match'))
145 179
            self.arguments = global_args
146 180

  
181
or more usually and elegantly:
182

  
183
.. code-block:: python
184

  
185
    from kamaki.cli.argument import ValueArgument
186
    
187
    @command(_mygrp1_commands)
188
    class mygrp1_list_details():
189
    """List of details"""
190

  
191
        arguments = dict(
192
            match=ValueArgument(
193
            'Filter output to match string', ('-m', --match'))
194
        )
195

  
196
Accessing run-time arguments
197
----------------------------
198

  
199
To access run-time arguments, users can use the _command_init interface, which
200
implements __item__ accessors to handle run-time argument values. In specific,
201
an instance of _command_init can use brackets to set or read <argument>.value .
202

  
203
.. code-block:: python
204

  
205
    from kamaki.cli.argument import ValueArgument
206
    from kamaki.cli.commands import _command_init
207
    
208
    @command(_mygrp1_commands)
209
    class mygrp1_list_details(_command_init):
210
        """List of details"""
211

  
212
        arguments = dict(
213
            match=ValueArgument(
214
                'Filter output to match string', ('-m', --match'))
215
        )
216

  
217
        def check_runtime_arguments(self):
218
            ...
219
            assert self['match'] == self.arguments['match'].value
220
            ...
221

  
147 222
The main method and command parameters
148 223
--------------------------------------
149 224

  
150
The command behavior for each command / class is coded in *main*. The parameters of *main* method defines the command parameters part of the syntax. In specific::
225
The command behavior for each command / class is coded in *main*. The
226
parameters of *main* method defines the command parameters part of the syntax.
227
In specific::
151 228

  
152 229
    main(self, param)                   - obligatory parameter <param>
153 230
    main(self, param=None)              - optional parameter [param]
......
159 236
    main(self, *args)                   - arbitary number of params [...]
160 237
    main(self, param1____param2, *args) - <param1:param2> [...]
161 238

  
162
The information that can be mined by *command* for each individual command is presented in the following:
239
The information that can be mined by *command* for each individual command is
240
presented in the following:
163 241

  
164 242
.. code-block:: python
165 243
    :linenos:
......
171 249
    ...
172 250

  
173 251
    @command(_mygrp2_commands)
174
    class mygrp2_list_all(object):
252
    class mygrp2_list_all():
175 253
        """List all subjects"""
176 254

  
177
        def __init__(self, global_args={}):
178
            global_args['list'] = FlagArgument(
179
                'detailed list',
180
                '-l,
181
                False)
182

  
183
            self.arguments = global_args
255
        arguments = dict(FlagArgument('detailed list', '-l'))
184 256

  
185 257
        def main(self, reg_exp=None):
186 258
            ...
......
194 266
Letting kamaki know
195 267
-------------------
196 268

  
197
Kamaki will load a command specification *only* if it is set as a configurable option. To demonstrate this, let the command specifications coded above be stored in a file named *grps.py*.
269
Kamaki will load a command specification *only* if it is set as a configurable
270
option. To demonstrate this, let the command specifications coded above be
271
stored in a file named *grps.py*.
198 272

  
199
The developer should move file *grps.py* to kamaki/cli/commands, the default place for command specifications, although running a command specification from a different path is also a kamaki feature.
273
The developer should move file *grps.py* to kamaki/cli/commands, the default
274
place for command specifications, although running a command specification from
275
a different path is also a kamaki feature.
200 276

  
201 277
The user has to use a configuration file where the following is added:
202 278
::
203 279

  
204
    [mygrp1]
205
    cli=grps
206

  
207
    [mygrp2]
208
    cli=grps
280
    [global]
281
    mygrp1_cli = grps
282
    mygrp2_cli = grps
209 283

  
210
or alternatively:
284
or equivalently:
211 285

  
212 286
.. code-block:: console
213 287

  
214
    $ kamaki config set mygrp1.cli = grps
215
    $ kamaki config set mygrp2.cli = grps
288
    $ kamaki config set mygrp1_cli grps
289
    $ kamaki config set mygrp2_cli grps
216 290

  
217
Command specification modules don't need to live in kamaki/cli/commands, although this is suggested for uniformity. If a command module exist in another path::
291
Command specification modules don't need to live in kamaki/cli/commands,
292
although this is suggested for uniformity. If a command module exist in another
293
path::
218 294

  
219
    [mygrp]
220
    cli=/another/path/grps.py
295
    [global]
296
    mygrp_cli = /another/path/grps.py
221 297

  
222 298
Summary: create a command set
223 299
-----------------------------
......
226 302

  
227 303
    #  File: grps.py
228 304

  
305
    from kamaki.cli.commands import _command_init
229 306
    from kamaki.cli.command_tree import CommandTree
230 307
    from kamaki.cli.argument import ValueArgument, FlagArgument
231 308
    ...
......
243 320

  
244 321

  
245 322
    @command(_mygrp1_commands)
246
    class mygrp1_list_all():
323
    class mygrp1_list_all(_command_init):
247 324
        """show a list"""
248 325

  
249
        arguments = {}
250

  
251 326
        def main(self):
252 327
            ...
253 328

  
254 329

  
255 330
    @command(_mygrp1_commands)
256
    class mygrp1_list_details():
331
    class mygrp1_list_details(_command_init):
257 332
        """show list of details"""
258 333

  
259
        arguments = {}
260

  
261
        def __init__(self, global_args={})
262
            global_args['match'] = ValueArgument(
263
                'Filter results to match string',
264
                '--match')
265
            self.arguments = global_args
334
        arguments = dict(
335
            match=ValueArgument(
336
                'Filter output to match string', ('-m', --match'))
337
        )
266 338

  
267 339
        def main(self):
268 340
            ...
269
            match_value = self.arguments['list'].value
341
            match_value = self['match']
270 342
            ...
271 343

  
272 344

  
273 345
    @command(_mygrp2_commands)
274
    class mygrp2_list_all():
346
    class mygrp2_list_all(_command_init):
275 347
        """list all subjects"""
276 348

  
277
        arguments = {}
278

  
279
        def __init__(self, global_args={})
280
            global_args['match'] = FlagArgument('detailed listing', '-l')
281
            self.arguments = global_args
349
        arguments = dict(
350
            list=FlagArgument('detailed listing', '-l')
351
        )
282 352

  
283 353
        def main(self, regular_expression=None):
284 354
            ...
285
            detail_flag = self.arguments['list'].value
355
            detail_flag = self['list']
286 356
            ...
287 357
            if detail_flag:
288 358
                ...
......
293 363

  
294 364

  
295 365
    @command(_mygrp2_commands)
296
    class mygrp2_info():
366
    class mygrp2_info(_command_init):
297 367
        """get information for subject with id"""
298 368

  
299
        arguments = {}
300

  
301 369
        def main(self, id, name=''):
302 370
            ...
b/docs/developers/clients-api.rst
1 1
Creating applications with kamaki API
2 2
=====================================
3 3

  
4
Kamaki features a clients API for building third-party client applications that
5
communicate with OpenStack and / or Synnefo cloud services. The package is
6
called kamaki.clients and servers as a lib.
4 7

  
5
Kamaki features a clients API for building third-party client applications that communicate with OpenStack and / or Synnefo cloud services. The package is called kamaki.clients and contains a number of 
8
A showcase of an application built on kamaki.clients is kamaki.cli, the command
9
line interface of kamaki.
6 10

  
7
A good example of an application build on kamaki.clients is kamaki.cli, the command line interface of kamaki. 
8

  
9
Since synnefo services are build as OpenStack extensions, an inheritance approach has been chosen for implementing clients for both. In specific, the *compute*, *storage* and *image* modules are clients of the OS compute, OS storage, respectively. On the contrary, all the other modules are Synnefo extensions (*cyclades* extents *compute*, *pithos* and *pithos_rest_api* extent *storage*) or novel synnefo services (e.g. *astakos* for IM, *image* for *plankton*).
11
Since synnefo services are build as OpenStack extensions, an inheritance
12
approach has been chosen for implementing clients for both. In specific,
13
the *compute*, *storage* and *image* modules are clients of the OS compute, OS
14
object-store, respectively. On the contrary, all the other modules are Synnefo
15
extensions (*cyclades* extents *compute*, *pithos* and *pithos_rest_api*
16
extent *storage*) or novel synnefo services (e.g. *astakos* for IM, *image*
17
for *plankton*).
10 18

  
11 19
Setup a client instance
12 20
-----------------------
......
25 33
    my_cyclades_client = CycladesClient(base_url, token)
26 34
    my_pithos_client = PithosClient(base_url, token, account, container)
27 35

  
28
.. note:: *cyclades* and *pithos* clients inherit all methods of *compute* and *storage* clients respectively. Separate compute or storage objects should be used only when implementing applications for strict OS Compute or OS Storage services.
36
.. note:: *cyclades* and *pithos* clients inherit all methods of *compute*
37
    and *storage* clients respectively. Separate compute or storage objects
38
    should be used only when implementing applications for strict OS Compute or
39
    OS Storage services.
29 40

  
30 41
.. note:: *account* variable is usually acquired by the following user call
31 42

  
......
38 49
Use client methods
39 50
------------------
40 51

  
41
Client methods can now be called. Developers are advised to consult :ref:`the-client-api-ref` for details on the available methods and how to use them.
52
Client methods can now be called. Developers are advised to
53
consult :ref:`the-client-api-ref` for details on the available methods and how
54
to use them.
42 55

  
43
In the following example, the *cyclades* and *pithos* clients of example 1.1 are used to extract some information, that is then printed to the standard output.
56
In the following example, the *cyclades* and *pithos* clients of example 1.1
57
are used to extract some information, that is then printed to the standard
58
output.
44 59

  
45 60

  
46 61
.. code-block:: python
......
73 88
Error handling
74 89
--------------
75 90

  
76
The kamaki.clients standard error is ClientError. A ClientError is raised for any kind of kamaki.clients errors (errors reported by servers, type errors in arguments, etc.).
91
The kamaki.clients standard error is ClientError. A ClientError is raised for
92
any kind of kamaki.clients errors (errors reported by servers, type errors in
93
arguments, etc.).
77 94

  
78 95
A ClientError contains::
79 96

  
b/docs/developers/extending-clients-api.rst
1 1
Extending kamaki.clients
2 2
========================
3 3

  
4
By default, kamaki clients are REST clients (they manage HTTP requests and responses to communicate with services).
4
By default, kamaki clients are REST clients (they manage HTTP requests and
5
responses to communicate with services).
5 6

  
6 7
How to build a client
7 8
---------------------
8 9

  
9
All service clients consist of a subclass of the Client class and implement separate client functionalities as member methods. There is also an error class to raise exceptions that can be handled by kamaki interfaces.
10
All service clients consist of a subclass of the Client class and implement
11
separate client functionalities as member methods. There is also an error class
12
to raise exceptions that can be handled by kamaki interfaces.
10 13

  
11 14
.. code-block:: python
12 15
    
......
65 68
Concurrency control
66 69
-------------------
67 70

  
68
Kamaki clients may handle multiple requests at once, using threads. In that case, users might implement their own thread handling mechanism, use an external solution or take advantage of the mechanism featured in kamaki.clients
71
Kamaki clients may handle multiple requests at once, using threads. In that
72
case, users might implement their own thread handling mechanism, use an
73
external solution or take advantage of the mechanism featured in kamaki.clients
69 74

  
70 75
.. code-block:: python
71 76

  
......
94 99
Going agile
95 100
-----------
96 101

  
97
The kamaki.clients package contains a set of fine-grained unit-tests for all its packages. 
102
The kamaki.clients package contains a set of fine-grained unit-tests for all
103
its packages. 
98 104

  
99
.. note:: unit tests require the optional python-mock package, version 1.X or better
105
.. note:: unit tests require the optional python-mock package, version 1.X or
106
    better
100 107

  
101 108
Using the tests
102 109
^^^^^^^^^^^^^^^
......
108 115
    $ git clone https://code.grnet.gr/git/kamaki
109 116
    $ cd kamaki/kamaki/clients
110 117

  
111
In each package under kamaki.clients, there is a test module (test.py) where the tests are implemented. To run all tests, run the test.py file from kamaki.clients
118
In each package under kamaki.clients, there is a test module (test.py) where
119
the tests are implemented. To run all tests, run the test.py file from
120
kamaki.clients
112 121

  
113 122
.. code-block:: console
114 123

  
115 124
    $ python test.py
116 125

  
117
To test a specific class, add the class name as an argument. E.g. for the Client class:
126
To test a specific class, add the class name as an argument. E.g. for the
127
Client class:
118 128

  
119 129
.. code-block:: console
120 130

  
121 131
    $ python test.py Client
122 132

  
123
To test a specific method in a class, apply an extra argument, e.g. for the request method in the Client class:
133
To test a specific method in a class, apply an extra argument, e.g. for the
134
request method in the Client class:
124 135

  
125 136
.. code-block:: console
126 137

  
127 138
    $ python test.py Client request
128 139

  
129
Each package contains a test module (test.py) which is also runnable from the command line. E.g. in the pithos package there is a test module which contains, among others, the **download** sub-test:
140
Each package contains a test module (test.py) which is also runnable from the
141
command line. E.g. in the pithos package there is a test module which
142
contains, among others, the **download** sub-test:
130 143

  
131 144
.. code-block:: console
132 145

  
......
141 154
    # Test kamaki.clients.pithos.PithosClient.download
142 155
    $ python test.py Pithos download
143 156

  
144
To fully test a specific package, run test.py from the package location. E.g. to test everything in kamaki.clients.pithos package:
157
To fully test a specific package, run test.py from the package location. E.g.
158
to test everything in kamaki.clients.pithos package:
145 159

  
146 160
.. code-block:: console
147 161

  
......
151 165
Mechanism
152 166
^^^^^^^^^
153 167

  
154
Each folder / package contains a test.py file, that represents the test module of this package. All test modules contain a set of classes that extent the TestCase class. They also contain a main method to run the tests.
168
Each folder / package contains a test.py file, that represents the test module
169
of this package. All test modules contain a set of classes that extent the
170
TestCase class. They also contain a main method to run the tests.
155 171

  
156
By convention, testing classes are named as <Tested Class> where <Test Class> is the name of the tested class or module. Methods not grouped in classes are tested by classes named after their respective module.
172
By convention, testing classes are named as <Tested Class> where <Test Class>
173
is the name of the tested class or module. Methods not grouped in classes are
174
tested by classes named after their respective module.
157 175

  
158
For example, the kamaki.clients.pithos.PithosClient class is tested by the kamaki.clients.pithos.test.PithosClient class, while the methods in kamaki.clients.utils module are tested by the kamaki.clients.utils.test.Utils testing class.
176
For example, the kamaki.clients.pithos.PithosClient class is tested by the
177
kamaki.clients.pithos.test.PithosClient class, while the methods in
178
kamaki.clients.utils module are tested by the kamaki.clients.utils.test.Utils
179
testing class.
159 180

  
160 181
Adding unit tests
161 182
^^^^^^^^^^^^^^^^^
162
After modifying or extending kamaki.clients method, classes, modules or packages, it is a good practice to also modify or extend the corresponding unit tests. What's more, it is recommended to modify or implement the testing of new behavior before implementing the behavior itself. The aim for kamaki.clients package is an 1 to 1 mapping between methods and their tests.
183

  
184
After modifying or extending kamaki.clients method, classes, modules or
185
packages, it is a good practice to also modify or extend the corresponding
186
unit tests. What's more, it is recommended to modify or implement the testing
187
of new behavior before implementing the behavior itself. The aim for
188
kamaki.clients package is an 1 to 1 mapping between methods and their tests.
163 189

  
164 190
Modifying an existing method
165 191
""""""""""""""""""""""""""""
166 192

  
167
In case of an existing method modification, the programmer has to modify the corresponding test as well. By convention, the test method is located in the test module under the same package, in a TestCase subclass that is named with a name similar to the package or class that contains the tested method.
193
In case of an existing method modification, the programmer has to modify the
194
corresponding test as well. By convention, the test method is located in the
195
test module under the same package, in a TestCase subclass that is named with a
196
name similar to the package or class that contains the tested method.
168 197

  
169
Example 1: to modify the kamaki.clients.utils.filter_in method, the programmer has to also adjust the kamaki.clients.utils.test.Utils.test_filter_in method.
198
Example 1: to modify the kamaki.clients.utils.filter_in method, the programmer
199
has to also adjust the kamaki.clients.utils.test.Utils.test_filter_in method.
170 200

  
171
Example 2: to modify the kamaki.clients.pithos.PithosRestClient.object_get, the programmer has to also adjust the kamaki.clients.pithos.test.PithosRestClient.test_object_get method.
201
Example 2: to modify the kamaki.clients.pithos.PithosRestClient.object_get, the
202
programmer has to also adjust the
203
kamaki.clients.pithos.test.PithosRestClient.test_object_get method.
172 204

  
173 205
Adding a new method
174 206
"""""""""""""""""""
175 207

  
176
Programmers who want to implement a new method in an existing class, are encouraged to implement the corresponding unit test first. In order to do that, they should find the testing class that is mapped to the class or module they need to extend.
208
Programmers who want to implement a new method in an existing class, are
209
encouraged to implement the corresponding unit test first. In order to do that,
210
they should find the testing class that is mapped to the class or module they
211
need to extend.
177 212

  
178
Example 1: To add a **list_special** method to kamaki.clients.astakos.AstakosClient, extend the kamaki.clients.astakos.test.AstakosClient class, as shown bellow:
213
Example 1: To add a **list_special** method to
214
kamaki.clients.astakos.AstakosClient, extend the
215
kamaki.clients.astakos.test.AstakosClient class, as shown bellow:
179 216

  
180 217
.. code-block:: python
181 218

  
......
187 224
            """Test the list_special method"""
188 225
            ...
189 226

  
190
Example 2: To add a **get_random_int** method in kamaki.clients.utils module, extend the kamaki.clients.utils.test.Utils test class, as shown bellow:
227
Example 2: To add a **get_random_int** method in kamaki.clients.utils module,
228
extend the kamaki.clients.utils.test.Utils test class, as shown bellow:
191 229

  
192 230
.. code-block:: python
193 231

  
......
202 240
Implementing a new class or module
203 241
""""""""""""""""""""""""""""""""""
204 242

  
205
Each class or module needs a seperate test sub-module. By convention, each class or module under the kamaki.clients should be located in a separate directory.
243
Each class or module needs a seperate test sub-module. By convention, each
244
class or module under the kamaki.clients should be located in a separate
245
directory.
206 246

  
207
Example 1: To add a NewService class that implements the kamaki.clients.Client interface: 
247
Example 1: To add a NewService class that implements the kamaki.clients.Client
248
interface: 
208 249

  
209 250
* create a new_service package and implement the unit tests in the kamaki.clients.new_service.test module:
210 251

  
......
250 291

  
251 292
    from kamaki.clients.new_service.test import NewService
252 293

  
253
.. note:: If the new class or module is part of an existing sub-package, it is acceptable to append its testing class in the existing test.py file of the sub-package it belongs to. For example, the kamaki.clients.pithos.PithosClient and kamaki.clients.pithos.rest_api.PithosRestClient classes are tested by two different classes (PithosClient and PithosRestClient respectively) in the same module (kamaki.clients.pithos.test).
294
.. note:: If the new class or module is part of an existing sub-package, it is
295
    acceptable to append its testing class in the existing test.py file of the
296
    sub-package it belongs to. For example, the
297
    kamaki.clients.pithos.PithosClient and
298
    kamaki.clients.pithos.rest_api.PithosRestClient classes are tested by two
299
    different classes (PithosClient and PithosRestClient respectively) in the
300
    same module (kamaki.clients.pithos.test).
254 301

  
b/docs/index.rst
10 10

  
11 11
./kamaki is a multipurpose, interactive command-line tool and also a client development API for managing clouds.
12 12

  
13
As a development API, it is an initial implementation of the Synnefo API (`Synnefo IaaS <http://www.synnefo.org/>`_ cloud management software extends OpenStack), while preserving compatibility with the OpenStack API.
13
As a development library, it implements the Synnefo API (
14
`Synnefo IaaS <http://www.synnefo.org/>`_ cloud management software) which
15
extends OpenStack, therefore is also compatible with the OpenStack API.
14 16

  
15 17
./kamaki is open source and released under a 2-clause BSD License.
16 18

  
b/docs/installation.rst
13 13

  
14 14
* Synnefo Linux packages: `http://apt.dev.grnet.gr <http://apt.dev.grnet.gr>`_
15 15

  
16
Linux and Unix-like enviroments
17
-------------------------------
16
Linux and Unix-like environments
17
--------------------------------
18 18

  
19 19
Debian:
20 20
^^^^^^^
b/docs/man/kamaki.rst
180 180
file commands
181 181
**************
182 182

  
183
* append         Append local file to remote
183
* append         Append local file to remote file
184 184
* cat            Print a file to console
185 185
* copy           Copy an object
186 186
* containerlimit Container size limit commands
b/docs/overview.rst
8 8
team of the *Greek Research and Technology Network (GRNET)*, initially as an
9 9
internal project and later as a multipurpose tool for all users.
10 10

  
11
Synnefo is an IaaS system which is based on and extents OpenStack.
12
Synnefo has been deployed in many environments to cover multiple needs. The
13
most notable, deployment is probably the GRNET's
11
Synnefo is an IaaS system which implements and extents OpenStack. Synnefo has
12
been deployed in many environments to cover multiple needs. The most notable
13
deployment is probably the GRNET's
14 14
`~okeanos <http://okeanos.grnet.gr>`_ IaaS service, running in GRNET data
15 15
centers, is used to offer cloud services to the Greek Research and Academic
16 16
Community.
b/docs/setup.rst
11 11
Existing kamaki users should consult the
12 12
`migration guide <#migrating-from-kamaki-0-8-x-to-0-9>`_ first.
13 13

  
14
Kamaki has to be configured to use a specific Synnefo deployment url and a user
15
token.
14
Kamaki has to be configured for a specific Synnefo deployment, with an
15
authentication url and user token pair. Users should also pick an alias to name
16
the cloud configuration. This can be any single word, e.g. "default", "mycloud"
17
or whatever suits kamaki users.
16 18

  
17 19
.. code-block:: console
18 20
    
19
    $ kamaki config set remote.default.url <cloud-authentication-URL>
20
    $ kamaki config set remote.default.token myt0k3n==
21
    $ kamaki config set cloud.<cloud alias>.url <cloud-authentication-URL>
22
    $ kamaki config set cloud.<cloud alias>.token myt0k3n==
21 23

  
22
Since Synnefo version 0.14, a synnefo cloud remote UI offers a single
23
authentication URL, which can to be set as the default URL for kamaki. All
24
service-specific URLs are now retrieved and handled automatically. Users of
25
synnefo clouds >= 0.14 are advised against using any service-specific URLs.
24
If only one cloud is configured, kamaki automatically picks it as the default.
25
Otherwise, a default cloud should be specified:
26

  
27
.. code-block:: console
28

  
29
    $ kamaki config set default_cloud <cloud alias>
30

  
31
Since Synnefo version 0.14, a synnefo cloud UI offers a single authentication
32
URL, which should be set as the cloud URL for kamaki. All service-specific URLs
33
are retrieved and handled automatically by kamaki, through this URL. Users of
34
synnefo clouds >=0.14 are advised against using any service-specific URLs.
26 35

  
27 36
Migrating from kamaki 0.8.X to 0.9
28 37
----------------------------------
29 38

  
30
This section refers to running installations of kamaki version <= 0.8.X
31
To check the current kamaki version:
39
This section refers to running installations of kamaki version <= 0.8.X To
40
check the current kamaki version:
32 41

  
33 42
.. code-block:: console
34 43

  
35 44
    $ kamaki -V
36 45

  
37
Existing kamaki users should convert their configuration files to v3. To do
38
that, kamaki 0.9 inspects the configuration file and suggests a list of config
39
file transformations, which are performed automatically on user permission.
40
This mechanism is invoked when the first API-related kamaki command is fired.
41
We suggest the `user authenticate` command, as shown on example 2.1.
46
Existing kamaki users should convert their configuration files to v9. To do
47
that, kamaki 0.9 can inspect the configuration file and suggests a list of
48
config file transformations, which are performed automatically (after users'
49
permission). This mechanism is invoked when an API-related kamaki command is
50
fired. On example 2.1 we suggest using the `user authenticate` command to fire
51
the kamaki config file conversion mechanism.
42 52

  
43 53
.. code-block:: console
44 54
    :emphasize-lines: 1
......
46 56
    Example 2.1: Convert config file while authenticating user "exampleuser"
47 57

  
48 58
    $ kamaki user authenticate
49
    Config file format version >= 3.0 is required
50
    Configuration file "/home/exampleuser/.kamakirc" format is not up to date
59
    Config file format version >= 9.0 is required
60
    Configuration file: "/home/exampleuser/.kamakirc"
51 61
    but kamaki can fix this:
52 62
    Calculating changes while preserving information
53
    ... rescue global.token => remote.default.token
63
    ... rescue global.token => cloud.default.token
54 64
    ... rescue config.cli => global.config_cli
55 65
    ... rescue history.file => global.history_file
56 66
    ... DONE
......
63 73
        file.url = https://pithos.okeanos.grnet.gr/v1
64 74
        image.url = https://cyclades.okeanos.grnet.gr/plankton
65 75

  
66
    Kamaki is ready to convert the config file to version 3.0
76
    Kamaki is ready to convert the config file to version 9.0
67 77
    Overwrite file /home/exampleuser/.kamakirc ? [Y, y]
68 78

  
69 79
At this point, we should examine the kamaki output. Most options are renamed to
......
78 88
    meaningless and therefore omitted.
79 89

  
80 90
* `global.data_log` option has never been a valid kamaki config option.
81
    In this example, the user accidentally misspelled the terms `log_data`
91
    In this example, the user accidentally misspelled the term `log_data`
82 92
    (which is a valid kamaki config option) as `data_log`. To fix this, the
83 93
    user should set the correct option after the conversion is complete
84 94
    (Example 2.2).
......
105 115

  
106 116
    $ kamaki -c .myfilerc user authenticate
107 117

  
108
Multiple cloud remotes
109
----------------------
118
Multiple clouds
119
---------------
110 120

  
111 121
The following refers to users of multiple Synnefo and/or Open Stack
112 122
deployments. In the following, a Synnefo or Open Stack cloud deployment will
113
frequently be called as a **remote** or a **cloud remote**.
123
frequently be called as a **cloud**.
114 124

  
115
Kamaki supports accessing multiple cloud remotes from the same kamaki setup.
116
Bofore kamaki 0.9, this was possible only by using multiple config files. Since
117
0.9, kamaki supports multiple cloud remotes in the same configuration.
125
Kamaki supports accessing multiple clouds from the same kamaki setup. Before
126
kamaki 0.9, this was possible only by using multiple config files. Since 0.9,
127
kamaki supports multiple clouds in the same configuration.
118 128

  
119
Each cloud remote corresponds to a Synnefo (or Open Stack) cloud deployment.
129
Each cloud corresponds to a Synnefo (or Open Stack) cloud deployment.
120 130
Since Synnefo version 0.14, each deployment offers a single point of
121 131
authentication, as an **authentication URL** and **token** pair. Users can
122 132
retrieve this information through the cloud UI.
123 133

  
124
Once a user has retrieved one URL/token pair per cloud remote, it is time to
125
assign a name to each cloud and let kamaki know about them.
134
Once a user has retrieved one URL/token pair per cloud, it is time to assign a
135
name to each cloud and let kamaki know about them.
126 136

  
127
For example, let the user have access to two remote clouds with the following authentication information ::
137
For example, let the user have access to two clouds with the following authentication information ::
128 138

  
129 139
    cloud alias: devel
130 140
    authentication URL: https://devel.example.com/astakos/identity/v2.0/
......
141 151

  
142 152
.. code-block:: console
143 153

  
144
    $ kamaki config set remote.devel.url https://devel.example.com/astakos/identity/v2.0/
145
    $ kamaki config set remote.devel.token myd3v3170k3n==
154
    $ kamaki config set cloud.devel.url https://devel.example.com/astakos/identity/v2.0/
155
    $ kamaki config set cloud.devel.token myd3v3170k3n==
146 156
    $
147
    $ kamaki config set remote.testing.url https://testing.example.com/astakos/identity/v2.0/
148
    $ kamaki config set remote.testing.token my73571ng70k3n==
157
    $ kamaki config set cloud.testing.url https://testing.example.com/astakos/identity/v2.0/
158
    $ kamaki config set cloud.testing.token my73571ng70k3n==
149 159
    $
150 160

  
151
To check if all settings are loaded, a user may list all remotes, as shown
161
To check if all settings are loaded, a user may list all clouds, as shown
152 162
bellow:
153 163

  
154 164
.. code-block:: console
155 165

  
156
    $ kamaki config get remote
157
     remote.default.url = https://example.com/astakos.identity/v2.0/
158
     remote.default.url = myd3f4u1770k3n==
159
     remote.devel.url = https://devel.example.com/astakos/identity/v2.0/
160
     remote.devel.token = myd3v3170k3n==
161
     remote.testing.url = https://testing.example.com/astakos/identity/v2.0/
162
     remote.testing.token = my73571ng70k3n==
166
    $ kamaki config getcloud 
167
     cloud.default.url = https://example.com/astakos.identity/v2.0/
168
     cloud.default.url = myd3f4u1770k3n==
169
     cloud.devel.url = https://devel.example.com/astakos/identity/v2.0/
170
     cloud.devel.token = myd3v3170k3n==
171
     cloud.testing.url = https://testing.example.com/astakos/identity/v2.0/
172
     cloud.testing.token = my73571ng70k3n==
163 173
    $
164 174

  
165
or query kamaki for a specific cloud remote:
175
or query kamaki for a specific cloud:
166 176

  
167 177
.. code-block:: console
168 178

  
169
    $ kamaki config get remote.devel
170
     remote.devel.url = https://devel.example.com/astakos/identity/v2.0/
171
     remote.devel.token = myd3v3170k3n==
179
    $ kamaki config get cloud.devel
180
     cloud.devel.url = https://devel.example.com/astakos/identity/v2.0/
181
     cloud.devel.token = myd3v3170k3n==
172 182
    $
173 183

  
174
Now kamaki can use any of there remotes, with the **- - cloud** attribute. If
175
the **- - cloud** option is ommited, kamaki will query the `default` cloud remote.
184
Now kamaki can use any of these clouds, with the **- - cloud** attribute. If
185
the **- - cloud** option is ommited, kamaki will query the `default` cloud.
176 186

  
177 187
One way to test this, is the `user athenticate` command:
178 188

  
......
203 213
        name       :  Default User
204 214
    $
205 215

  
206
In interactive cell, the cloud remote is picked when invoking the shell, with
216
In interactive cell, the cloud is picked when invoking the shell, with
207 217
the **- - cloud** option.
208 218

  
209 219
Optional features
......
213 223
`kamaki installation guide <installation.html#install-ansicolors>`_
214 224

  
215 225
* ansicolors
216
    * Make command line / console user interface responses prettier with text formating (colors, bold, etc.)
217
    * Can be switched on/off in kamaki configuration file: colors=on/off
226
    * Add colors to command line / console output
227
    * Can be switched on/off in kamaki configuration file: `colors = on/off`
218 228
    * Has not been tested on non unix / linux based platforms
219 229

  
220 230
* mock 
221 231
    * For kamaki contributors only
222
    * Allow unittests to run on kamaki.clients package
232
    * Allow unit tests to run on kamaki.clients package
223 233
    * Needs mock version 1.X or better
224 234

  
225 235
* astakosclient
226 236
    * For advanced users mostly
227 237
    * Allows the use of a full astakos command line client
228 238

  
229
Any of the above features can be installed at any time before or after kamaki installation.
239
Any of the above features can be installed at any time before or after kamaki
240
installation.
230 241

  
231 242
Configuration options
232 243
---------------------
......
238 249
    colors in the output, maximum threads per connection, custom logging or
239 250
    history files, etc.
240 251

  
241
* cloud-related (remote.XXX)
242
    information needed to connect and use one or more remote clouds. There are
243
    some mandatory options (url, token) and some advanced / optional (e.g.
244
    service-specific url overrides or versions)
252
* cloud-related
253
    information needed to connect and use one or more clouds. There are some
254
    mandatory options (URL, token) and some advanced / optional (e.g.
255
    service-specific URL overrides or versions)
245 256

  
246 257
Kamaki comes with preset default values to all kamaki-releated configuration
247 258
options. Cloud-related information is not included in presets and should be
248
provided. Kamaki-related options can also be modified.
259
provided by the user. Kamaki-related options can also be modified.
249 260

  
250 261
There are two ways of managing configuration options: edit the config file or
251 262
use the kamaki config command.
......
257 268
installation stores options in *.kamakirc* file located at the user home
258 269
directory.
259 270

  
260

  
261 271
If a user needs to switch between different kamaki-related setups, Kamaki can
262
explicitly load configuration files with the **- - config** (or **- c**)
263
option:
272
explicitly load configuration files with the **- - config** (or **- c**) option
264 273

  
265 274
.. code-block:: console
266 275

  
267 276
    $ kamaki --config <custom_config_file_path> [other options]
268 277

  
269
.. note:: For access to multiple cloud remotes, users do NOT need to create
270
    multiple configuration files. Instead, we suggest using a single
271
    configuration file with multiple remote setups. More details can be found
272
    at the `multiple remotes guide <#multiple-cloud-remotes>`_.
278
.. note:: For accessing multiple clouds, users do NOT need to create multiple
279
    configuration files. Instead, we suggest using a single configuration file
280
    with multiple cloud setups. More details can be found at the
281
    `multiple clouds guide <#multiple-clouds>`_.
273 282

  
274 283
Modifying options at runtime
275 284
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......
297 306

  
298 307
* kamaki config set <group.option> <value>
299 308
    set the group.option to value. If no group is given, the defaults to
300
    *global*
309
    *global*.
301 310

  
302 311
* kamaki config delete <group.option>
303 312
    delete a configuration option. If no group is given, the defaults to
......
305 314

  
306 315
The above commands cause option values to be permanently stored in the Kamaki configuration file.
307 316

  
308
The commands above can also be used for **cloud remotes** handling, using the
309
`remote.` prefix. The remote handling cases are similar but with slightly
310
different semantics:
311

  
312
* kamaki config get remote[.<cloud alias>[.option]]
313
    * remote
314
        list all cloud remotes (including `default`) and their settings
315
    * remote.<cloud alias>
316
        list settings of the cloud remote aliased as <cloud alias>. If no
317
        special is configured, use the term `remote.default`
318
    * remote.<cloud alias>.<option>
317
The commands above can also be used for **clouds** handling, using the `cloud.`
318
prefix. The cloud handling cases are similar but with slightly different
319
semantics:
320

  
321
* kamaki config get cloud[.<cloud alias>[.option]]
322
    * cloud 
323
        list all clouds and their settings
324
    * cloud.<cloud alias>
325
        list settings of the cloud aliased as <cloud alias>. If no
326
        special is configured, use the term `cloud.default`
327
    * cloud.<cloud alias>.<option>
319 328
        show the value of the specified option. If no special alias is
320
        configured, use `remote.default.<option>`
329
        configured, use `cloud.default.<option>`
321 330

  
322
* kamaki config set remote.<cloud alias>.<option> <value>
323
    If the remote alias <cloud alias> does not exist, create it. Then, create
324
    (or update) the option <option> of this cloud remote, by setting its value
331
* kamaki config set cloud.<cloud alias>.<option> <value>
332
    If the cloud alias <cloud alias> does not exist, create it. Then, create
333
    (or update) the option <option> of this cloud, by setting its value
325 334
    to <value>.
326 335

  
327
* kamaki config delete remote.<cloud alias>[.<option>]
328
    * remote.<cloud alias>
336
* kamaki config delete cloud.<cloud alias>[.<option>]
337
    * cloud.<cloud alias>
329 338
        delete the cloud alias <cloud alias> and all its options
330
    * remote.<cloud alias>.<option>
331
        delete the <option> and its value from the cloud remote aliased as
339
    * cloud.<cloud alias>.<option>
340
        delete the <option> and its value from the cloud cloud aliased as
332 341
        <cloud alias>
333 342

  
343
.. note:: To see if a default cloud is configured, get the default_cloud value
344

  
345
    .. code-block:: console
346

  
347
        $ kamaki config get default_cloud
348

  
334 349
Editing the configuration file
335 350
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
336 351

  
......
358 373
    max_threads = 7
359 374
    colors = off
360 375

  
361
    [remote "default"]
376
    [cloud "default"]
362 377
    url =
363 378
    token =
364 379

  
365 380
A bunch of configuration options are created and set to their default options,
366 381
except the log_file option which is set to whatever the specified value.
367 382

  
368
The [remote "default"] section is special and is used to configure the default
369
cloud remote. Kamaki will not be able to run without setting the url and token
383
The [cloud "default"] section is special and is used to configure the default
384
cloud cloud. Kamaki will not be able to run without setting the url and token
370 385
values to that section.
371 386

  
372
More cloud remotes can be created  on the side of the default remote, e.g
373
using the examples at the `multiple remotes guide <#multiple-cloud-remotes>`_::
387
More clouds can be created  on the side of the default cloud, e.g using the
388
examples at the `multiple clouds guide <#multiple-clouds>`_ ::
374 389

  
375
    [remote "devel"]
390
    [cloud "devel"]
376 391
    url = https://devel.example.com/astakos/identity/v2.0/
377 392
    token = myd3v3170k3n==
378 393

  
379
    [remote "testing"]
394
    [cloud "testing"]
380 395
    url = https://testing.example.com/astakos/identity/v2.0/
381 396
    token = my73571ng70k3n==
382 397

  
......
449 464

  
450 465
    kamaki config set livetest_cli livetest
451 466

  
452
In most tests, livetest will run as long as the default remote is configured
467
In most tests, livetest will run as long as the default cloud is configured
453 468
correctly. Some commands, though, need some extra settings related to the cloud
454 469
the test is performed against, or the example files used in kamaki.
455 470

  
456 471
Here is a list of settings needed:
457 472

  
458 473
* for all tests::
459
    * livetest.testremote = <the cloud alias this test will run against>
474
    * livetest.testcloud = <the cloud alias this test will run against>
460 475

  
461 476
* for astakos client::
462 477
    * livetest.astakos_details = <A file with an authentication output>
b/docs/usage.rst
22 22
.. code-block:: console
23 23
    :emphasize-lines: 1
24 24

  
25
    Example 1.1: Set default authentication user and token
25
    Example 1.1: Set authentication URL, user token and cloud alias "default"
26 26

  
27
    $ kamaki config set remote.default.url <authentication URL>
28
    $ kamaki config set remote.default.token myt0k3n==
27
    $ kamaki config set cloud.default.url <authentication URL>
28
    $ kamaki config set cloud.default.token myt0k3n==
29

  
30
.. note:: The term *default* can be replaced by any arbitary term chosen by
31
    the user. This term will serve as a cloud alias for kamaki users, and can
32
    be easily modified.
29 33

  
30 34
Shell vs one-command
31 35
--------------------
......
36 40

  
37 41
In favor of interactive shell behavior:
38 42

  
39
* tab completion for commands (if supported by host OS)
40
* session history with ↑ or ↓ keys
43
* tab completion for commands (if supported by host command line shell)
44
* session history with ↑ or ↓ keys (if supported by host command line shell)
41 45
* shorter commands with command context switching
42 46
* re-run old commands with /history
43 47

  
......
67 71

  
68 72
    Example 2.2.2: Run kamaki shell with custom configuration file
69 73

  
70
    $ kamaki --config myconfig.file
74
    $ kamaki -c myconfig.file
71 75

  
72 76

  
73 77
Run as one-command
......
126 130
                            Path to configuration file
127 131
      -o OPTIONS, --options OPTIONS
128 132
                            Override a config value
129
      --cloud CLOUD         Chose a remote cloud to connect to
133
      --cloud CLOUD         Chose a cloud to connect to
130 134
      -h, --help            Show help message
131 135

  
132 136
    Options:
133 137
     - - - -
134
    config  :  Kamaki configurations
135
    file    :  Pithos+/Storage API commands
136
    flavor  :  Cyclades/Compute API flavor commands
137
    history :  Kamaki command history
138
    image   :  Cyclades/Plankton API image commands
138
    config :  Kamaki configurations
139
    file   :  Pithos+/Storage API commands
140
    flavor :  Cyclades/Compute API flavor commands
141
    history:  Kamaki command history
142
    image  :  Cyclades/Plankton API image commands
139 143
    image compute:  Cyclades/Compute API image commands
140
    network :  Cyclades/Compute API network commands
141
    server  :  Cyclades/Compute API server commands
142
    user    :  Astakos API commands
144
    network:  Cyclades/Compute API network commands
145
    server :  Cyclades/Compute API server commands
146
    user   :  Astakos API commands
143 147

  
144 148
.. code-block:: console
145 149
    :emphasize-lines: 1,2
......
161 165
                            Path to configuration file
162 166
      -o OPTIONS, --options OPTIONS
163 167
                            Override a config value
164
      --cloud CLOUD         Chose a remote cloud to connect to
168
      --cloud CLOUD         Chose a cloud to connect to
165 169
      -h, --help            Show help message
166 170

  
167 171
    Options:
......
195 199
    List Virtual Machines accessible by user
196 200
    User Authentication:    
197 201
    * to check authentication: /user authenticate    
198
    * to set authentication token: /config set remote.default.token <token>
202
    * to set authentication token: /config set cloud.default.token <token>
199 203

  
200 204
    optional arguments:
201 205
    -v, --verbose         More info at response
......
207 211
                          Path to configuration file
208 212
    -o OPTIONS, --options OPTIONS
209 213
                          Override a config value
210
    --cloud CLOUD         Chose a remote cloud to connect to
214
    --cloud CLOUD         Chose a cloud to connect to
211 215
    -h, --help            Show help message
212 216
    --since SINCE         show only items since date (' d/m/Y H:M:S ')
213 217
    --enumerate           Enumerate results
......
333 337
    Example 3.4.1: List the trash container contents, containing c1_
334 338
    
335 339

  
336
    $ kamaki file list -o global.pithos_container=trash| grep c1_
340
    $ kamaki file list -o cloud.default.pithos_container=trash| grep c1_
337 341
    c1_1370859409.0 20KB
338 342
    c1_1370859414.0 9MB
339 343
    c1_1370859409.1 110B
......
610 614
    [file]: /user authenticate
611 615
    (401) UNAUTHORIZED Invalid X-Auth-Token
612 616

  
613
    [file]: /config get remote.default.token
617
    [file]: /config get cloud.default.token
614 618
    my3xp1r3dt0k3n==
615 619

  
616
    [file]: /config set remote.default.token myfr35ht0k3n==
620
    [file]: /config set cloud.default.token myfr35ht0k3n==
617 621

  
618
    [file]: /config get remote.default
619
    remote.default.url = https://astakos.example.com/astakos/identity/2.0/
620
    remote.default.token = myfr35ht0k3n==
622
    [file]: /config get cloud.default
623
    cloud.default.url = https://astakos.example.com/astakos/identity/2.0/
624
    cloud.default.token = myfr35ht0k3n==
621 625

  
622 626
    [file]: list
623 627
    1.  pithos (10MB, 2 objects)
624 628
    2.  trash (0B, 0 objects)
625 629

  
626 630
.. note:: The error messages on this example where shortened for clarity.
627
Actual kamaki error messages are more helpful and descriptive.
631
    Actual kamaki error messages are more helpful and descriptive.
628 632

  
629 633
The following example compares some equivalent calls that run
630 634
*user-authenticate* after a *file-list* 401 failure.
......
669 673
Using config
670 674
^^^^^^^^^^^^
671 675

  
672
The configuration mechanism of kamaki is detailed at the
676
The configuration mechanism of kamaki is detailed in the
673 677
`setup section <setup.html>`_ and it is common for both interaction modes. In
674 678
specific, the configuration mechanism is implemented as a command group, namely
675 679
`config`. Using the config commands is as straightforward as any other kamaki
......
693 697
.. code-block:: console
694 698
    :emphasize-lines: 1
695 699

  
696
    Example 4.4.1: Set default storage container
700
    Example 4.4.1: Set default storage container (cloud: default)
697 701

  
698 702

  
699 703
    [file]: list
......
705 709
    1.  D mydir/
706 710
    2.  20M mydir/rndm_local.file
707 711
    
708
    [file]: /config set pithos_container mycontainer
712
    [file]: /config set cloud.default.pithos_container mycontainer
709 713

  
710 714
    [file]: list
711 715
    1.  D mydir/
......
718 722
.. code-block:: console
719 723
    :emphasize-lines: 1
720 724

  
721
    Example 4.4.2: Delete a setting option
725
    Example 4.4.2: Delete a setting option (cloud: default)
722 726

  
723 727

  
724
    [file]: /config delete pithos_container
728
    [file]: /config delete cloud.default.pithos_container
725 729

  
726 730
    [file]: list
727 731
    1.  mycontainer (32MB, 2 objects)
b/kamaki/cli/__init__.py
197 197
    if exists(cnf.path) and guess < 0.9:
198 198
        print('Config file format version >= 9.0 is required')
199 199
        print('Configuration file: %s' % cnf.path)
200
        print('but kamaki can fix this:')
200
        print('Attempting to fix this:')
201 201
        print('Calculating changes while preserving information')
202 202
        lost_terms = cnf.rescue_old_file()
203 203
        print('... DONE')
204 204
        if lost_terms:
205 205
            print 'The following information will NOT be preserved:'
206 206
            print '\t', '\n\t'.join(lost_terms)
207
        print('Kamaki is ready to convert the config file to version 3.0')
207
        print('Kamaki is ready to convert the config file')
208 208
        stdout.write('Create (overwrite) file %s ? [y/N] ' % cnf.path)
209 209
        from sys import stdin
210 210
        reply = stdin.readline()
......
216 216
            raise CLIError(
217 217
                'Invalid format for config file %s' % cnf.path,
218 218
                importance=3, details=[
219
                    'Please, update config file to v3.0',
219
                    'Please, update config file',
220 220
                    'For automatic conversion, rerun and say Y'])
221 221

  
222 222

  
b/kamaki/cli/commands/config.py
76 76
                if section in ('cloud',):
77 77
                    prefix = '%s.%s' % (section, key)
78 78
                    for k, v in val.items():
79
                        print('%s..%s = %s' % (prefix, k, v))
79
                        print('%s.%s = %s' % (prefix, k, v))
80 80
                else:
81 81
                    print('%s.%s = %s' % (section, key, val))
82 82

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

Also available in: Unified diff