From 9360f3989e2484d0528e68fb72bff90fa0643ced Mon Sep 17 00:00:00 2001 From: Stavros Sachtouris Date: Fri, 14 Jun 2013 17:51:40 +0300 Subject: [PATCH] Fix deprecated terms in documentation Conflicts: kamaki/cli/config.py --- docs/commands.rst | 112 ++++++++-------- docs/developers/adding-commands.rst | 186 +++++++++++++++++--------- docs/developers/clients-api.rst | 33 +++-- docs/developers/extending-clients-api.rst | 93 +++++++++---- docs/index.rst | 4 +- docs/installation.rst | 4 +- docs/man/kamaki.rst | 2 +- docs/overview.rst | 6 +- docs/setup.rst | 203 ++++++++++++++++------------- docs/usage.rst | 64 ++++----- kamaki/cli/__init__.py | 6 +- kamaki/cli/commands/config.py | 2 +- kamaki/cli/commands/pithos.py | 3 +- kamaki/cli/utils.py | 3 +- kamaki/clients/pithos/__init__.py | 1 + 15 files changed, 442 insertions(+), 280 deletions(-) diff --git a/docs/commands.rst b/docs/commands.rst index b0dae5a..63a2263 100644 --- a/docs/commands.rst +++ b/docs/commands.rst @@ -1,7 +1,10 @@ List of commands ================ -The commands described bellow are grouped by service. The examples showcase a sample set of group commands. The kamaki interactive shell (check `Usage section `_ for details) is chosen as the execution environment. +The commands described bellow are grouped by service. The examples showcase a +sample set of group commands. The kamaki interactive shell (check +`Usage section `_ for details) is chosen as the +execution environment. user (Identity Manager) @@ -14,7 +17,9 @@ user (Identity Manager) Showcase: get user information ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In the following, the token has been set in a previous step (see `setup section `_ or the `quick setup guide `_) +In the following, the token has been set in a previous step (see +`setup section `_ or the +`quick setup guide `_) .. code-block:: console :emphasize-lines: 1,4 @@ -24,14 +29,13 @@ In the following, the token has been set in a previous step (see `setup section * Authenticate user * [user]: authenticate - auth_token_created: 2012-11-13T14:12:40.917034 - auth_token_expires: 2012-12-13T14:12:40.917035 - email : - myaccount@grnet.gr - myotheraccount@grnet.gr - name : My Real Name - username : usually@an.email.org - uuid : ab1cde23-45fg-6h7i-8j9k-10l1m11no2pq + ... + user: + name: My Real Name + uuid: ab1cde23-45fg-6h7i-8j9k-10l1m11no2pq + +.. note:: actual call returns a full list of service endpoints accessible to + the user with a specific token flavor (Compute/Cyclades) ------------------------- @@ -53,37 +57,37 @@ Showcase: show details for flavor with id 43 * Get details about flavor with id 43 * [flavor]: info 43 SNF:disk_template: drbd - cpu : 4 - disk : 10 - id : 43 - name : C4R2048D10 - ram : 2048 + cpu : 4 + disk: 10 + id : 43 + name: C4R2048D10 + ram : 2048 image (Plankton commands + Compute Image subcommands) ----------------------------------------------------- .. code-block:: text - list : List images accessible by user - meta : Get image metadata - register : (Re)Register an image - unregister : Unregister an image (does not delete the image file) - shared : List shared images - compute : Compute Image API commands - list : List images - delete : Delete image - info : Get image details - properties : Manage properties related to OS installation in an image + list : List images accessible by user + meta : Get image metadata + register : (Re)Register an image + unregister: Unregister an image (does not delete the image file) + shared : List shared images + compute : Compute Image API commands + list : List images + delete : Delete image + info : Get image details + properties: Manage properties related to OS installation in an image add : Add a property to an image delete: Delete a property from an image get : Get an image property list : List all image properties set : Add / update a set of properties for an image - members : Manage members (users who can modify an image) - add : Add a member to an image - delete : Remove a member from an image - list : List members of an image - set : Set the members of an image + members : Manage members (users who can modify an image) + add : Add a member to an image + delete: Remove a member from an image + list : List members of an image + set : Set the members of an image Showcase: Pick an image and list the properties ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -96,25 +100,25 @@ Showcase: Pick an image and list the properties * list all available images * [image]: list - 1. Windows Server 2008 + 926ab1c5-2d85-49d4-aebe-0fce712789b9 Windows Server 2008 container_format: bare disk_format : diskdump id : 926ab1c5-2d85-49d4-aebe-0fce712789b9 size : 11917066240 status : available - 2. Windows Server 2012 + 78262ee7-949e-4d70-af3a-85360c3de57a Windows Server 2012 container_format: bare disk_format : diskdump id : 78262ee7-949e-4d70-af3a-85360c3de57a size : 11697913856 status : available - 3. ubuntu + 5ed5a29b-292c-4fe0-b32c-2e2b65628635 ubuntu container_format: bare disk_format : diskdump id : 5ed5a29b-292c-4fe0-b32c-2e2b65628635 size : 2578100224 status : available - 4. Debian_Wheezy_Base + 1f8454f0-8e3e-4b6c-ab8e-5236b728dffe Debian_Wheezy_Base container_format: bare disk_format : diskdump id : 1f8454f0-8e3e-4b6c-ab8e-5236b728dffe @@ -170,7 +174,7 @@ Showcase: Create a server * See server-create help * [server]: create -h usage: create - [--personality PERSONALITY] [-h] [--config CONFIG] + [--personality PERSONALITY] [-h] [--config CONFIG] [--cloud CLOUD] Create a server @@ -183,6 +187,7 @@ Showcase: Create a server -i, --include Include protocol headers in the output --config CONFIG Path to configuration file -s, --silent Do not output anything + --cloud CLOUD Chose a cloud to connect to * List all available images * [server]: /image compute list @@ -216,9 +221,8 @@ Showcase: Create a server id : 11687 imageRef : b2dffe52-64a4-48c3-8a4c-8214cc3165cf metadata : - values: - os : debian - users: root + os : debian + users: root name : My Small Debian Server progress : 0 status : BUILD @@ -281,18 +285,18 @@ Showcase: Connect a network to a VM [network]: info 1409 attachments: nic-11687-1 - cidr : 192.168.1.0/24 - cidr6 : None - created : 2012-11-23T17:17:20.560098+00:00 - dhcp : True - gateway : None - gateway6 : None - id : 1409 - name : my network - public : False - status : ACTIVE - type : PRIVATE_MAC_FILTERED - updated : 2012-11-23T17:18:25.095225+00:00 + cidr : 192.168.1.0/24 + cidr6 : None + created : 2012-11-23T17:17:20.560098+00:00 + dhcp : True + gateway : None + gateway6: None + id : 1409 + name : my network + public : False + status : ACTIVE + type : MAC_FILTERED + updated : 2012-11-23T17:18:25.095225+00:00 * Get connectivity details on VM with id 11687 * [network]: /server addr 11687 @@ -431,8 +435,12 @@ Showcase: Upload and download a file -rw-rw-r-- 1 ******** ******** 20M Nov 26 15:42 rndm_remote.file [file]: !diff rndm_local.file rndm_remote.file -.. Note:: In kamaki shell, ! is used to execute OS shell commands (bash in the above) +.. Note:: In kamaki shell, ! is used to execute OS shell commands (e.g. bash) -.. 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 :: +.. 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 :: $ kamaki file copy --container=grnet:dev test.py --dst-container=grnet:deploy diff --git a/docs/developers/adding-commands.rst b/docs/developers/adding-commands.rst index 68b9af1..efe5265 100644 --- a/docs/developers/adding-commands.rst +++ b/docs/developers/adding-commands.rst @@ -1,7 +1,10 @@ Adding Commands =============== -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. +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. In the following, a set of kamaki commands will be implemented:: @@ -10,9 +13,16 @@ In the following, a set of kamaki commands will be implemented:: mygrp2 list all [regular expression] [-l] //list all subjects mygrp2 info [name] //get information for subject with id -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. +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. -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. +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. Samples of the expected behavior in one-command mode are following: @@ -37,12 +47,15 @@ Samples of the expected behavior in one-command mode are following: ... (mygrp2 client method is called) ... $ -The above example will be used throughout the present guide for clarification purposes. +The above example will be used throughout the present guide. The CommandTree structure ------------------------- -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:: +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:: - file ''''''''|- info @@ -61,9 +74,12 @@ The example used in the present, should result to the creation of two trees:: '''''''|- all |- info -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* +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* -A command group information (name, description) is provided at CommandTree structure initialization: +A command group information (name, description) is provided at CommandTree +structure initialization: .. code-block:: python @@ -75,18 +91,23 @@ A command group information (name, description) is provided at CommandTree struc The command decorator --------------------- -The *command* decorator mines all the information necessary to build a command specification which is then inserted in a CommanTree instance:: +The *command* decorator mines all the information necessary to build a command +specification which is then inserted in a CommanTree instance:: class code ---> command() --> updated CommandTree structure -Kamaki interfaces make use of this CommandTree structure. Optimizations are possible by using special parameters on the command decorator method. +Kamaki interfaces make use of this CommandTree structure. Optimizations are +possible by using special parameters on the command decorator method. .. code-block:: python def command(cmd_tree, prefix='', descedants_depth=None): """Load a class as a command + :param cmd_tree: is the CommandTree to be updated with a new command + :param prefix: of the commands allowed to be inserted ('' for all) + :param descedants_depth: is the depth of the tree descedants of the prefix command. """ @@ -107,12 +128,16 @@ A command specification developer should create a new module (python file) with ... -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. +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. Get command description ----------------------- -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. +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. .. code-block:: python @@ -125,9 +150,18 @@ The description of each command is the first line of the class commend. The foll Declare run-time argument ------------------------- -The argument mechanism allows the definition of run-time arguments. Some basic argument types are defined at the `argument module `_, 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 `_). +The argument mechanism allows the definition of run-time arguments. Some basic +argument types are defined at the +`argument module `_, 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 `_). -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). +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).` .. code-block:: python @@ -141,13 +175,56 @@ To declare a run-time argument on a specific command, the object class should in def __init__(self, global_args={}): global_args['match'] = ValueArgument( 'Filter results to match string', - '--match') + ('-m', '--match')) self.arguments = global_args +or more usually and elegantly: + +.. code-block:: python + + from kamaki.cli.argument import ValueArgument + + @command(_mygrp1_commands) + class mygrp1_list_details(): + """List of details""" + + arguments = dict( + match=ValueArgument( + 'Filter output to match string', ('-m', --match')) + ) + +Accessing run-time arguments +---------------------------- + +To access run-time arguments, users can use the _command_init interface, which +implements __item__ accessors to handle run-time argument values. In specific, +an instance of _command_init can use brackets to set or read .value . + +.. code-block:: python + + from kamaki.cli.argument import ValueArgument + from kamaki.cli.commands import _command_init + + @command(_mygrp1_commands) + class mygrp1_list_details(_command_init): + """List of details""" + + arguments = dict( + match=ValueArgument( + 'Filter output to match string', ('-m', --match')) + ) + + def check_runtime_arguments(self): + ... + assert self['match'] == self.arguments['match'].value + ... + The main method and command parameters -------------------------------------- -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:: +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:: main(self, param) - obligatory parameter main(self, param=None) - optional parameter [param] @@ -159,7 +236,8 @@ The command behavior for each command / class is coded in *main*. The parameters main(self, *args) - arbitary number of params [...] main(self, param1____param2, *args) - [...] -The information that can be mined by *command* for each individual command is presented in the following: +The information that can be mined by *command* for each individual command is +presented in the following: .. code-block:: python :linenos: @@ -171,16 +249,10 @@ The information that can be mined by *command* for each individual command is pr ... @command(_mygrp2_commands) - class mygrp2_list_all(object): + class mygrp2_list_all(): """List all subjects""" - def __init__(self, global_args={}): - global_args['list'] = FlagArgument( - 'detailed list', - '-l, - False) - - self.arguments = global_args + arguments = dict(FlagArgument('detailed list', '-l')) def main(self, reg_exp=None): ... @@ -194,30 +266,34 @@ This will load the following information on the CommandTree: Letting kamaki know ------------------- -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*. +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*. -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. +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. The user has to use a configuration file where the following is added: :: - [mygrp1] - cli=grps - - [mygrp2] - cli=grps + [global] + mygrp1_cli = grps + mygrp2_cli = grps -or alternatively: +or equivalently: .. code-block:: console - $ kamaki config set mygrp1.cli = grps - $ kamaki config set mygrp2.cli = grps + $ kamaki config set mygrp1_cli grps + $ kamaki config set mygrp2_cli grps -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:: +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:: - [mygrp] - cli=/another/path/grps.py + [global] + mygrp_cli = /another/path/grps.py Summary: create a command set ----------------------------- @@ -226,6 +302,7 @@ Summary: create a command set # File: grps.py + from kamaki.cli.commands import _command_init from kamaki.cli.command_tree import CommandTree from kamaki.cli.argument import ValueArgument, FlagArgument ... @@ -243,46 +320,39 @@ Summary: create a command set @command(_mygrp1_commands) - class mygrp1_list_all(): + class mygrp1_list_all(_command_init): """show a list""" - arguments = {} - def main(self): ... @command(_mygrp1_commands) - class mygrp1_list_details(): + class mygrp1_list_details(_command_init): """show list of details""" - arguments = {} - - def __init__(self, global_args={}) - global_args['match'] = ValueArgument( - 'Filter results to match string', - '--match') - self.arguments = global_args + arguments = dict( + match=ValueArgument( + 'Filter output to match string', ('-m', --match')) + ) def main(self): ... - match_value = self.arguments['list'].value + match_value = self['match'] ... @command(_mygrp2_commands) - class mygrp2_list_all(): + class mygrp2_list_all(_command_init): """list all subjects""" - arguments = {} - - def __init__(self, global_args={}) - global_args['match'] = FlagArgument('detailed listing', '-l') - self.arguments = global_args + arguments = dict( + list=FlagArgument('detailed listing', '-l') + ) def main(self, regular_expression=None): ... - detail_flag = self.arguments['list'].value + detail_flag = self['list'] ... if detail_flag: ... @@ -293,10 +363,8 @@ Summary: create a command set @command(_mygrp2_commands) - class mygrp2_info(): + class mygrp2_info(_command_init): """get information for subject with id""" - arguments = {} - def main(self, id, name=''): ... diff --git a/docs/developers/clients-api.rst b/docs/developers/clients-api.rst index bcd731e..6f54f80 100644 --- a/docs/developers/clients-api.rst +++ b/docs/developers/clients-api.rst @@ -1,12 +1,20 @@ Creating applications with kamaki API ===================================== +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 servers as a lib. -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 +A showcase of an application built on kamaki.clients is kamaki.cli, the command +line interface of kamaki. -A good example of an application build on kamaki.clients is kamaki.cli, the command line interface of kamaki. - -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*). +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 +object-store, 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*). Setup a client instance ----------------------- @@ -25,7 +33,10 @@ External applications may instantiate one or more kamaki clients. my_cyclades_client = CycladesClient(base_url, token) my_pithos_client = PithosClient(base_url, token, account, container) -.. 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. +.. 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. .. note:: *account* variable is usually acquired by the following user call @@ -38,9 +49,13 @@ External applications may instantiate one or more kamaki clients. Use client methods ------------------ -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. +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. -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. +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. .. code-block:: python @@ -73,7 +88,9 @@ In the following example, the *cyclades* and *pithos* clients of example 1.1 are Error handling -------------- -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.). +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.). A ClientError contains:: diff --git a/docs/developers/extending-clients-api.rst b/docs/developers/extending-clients-api.rst index dda5855..e206a95 100644 --- a/docs/developers/extending-clients-api.rst +++ b/docs/developers/extending-clients-api.rst @@ -1,12 +1,15 @@ Extending kamaki.clients ======================== -By default, kamaki clients are REST clients (they manage HTTP requests and responses to communicate with services). +By default, kamaki clients are REST clients (they manage HTTP requests and +responses to communicate with services). How to build a client --------------------- -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. +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. .. code-block:: python @@ -65,7 +68,9 @@ External applications must instantiate a MyNewClient object. Concurrency control ------------------- -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 +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 .. code-block:: python @@ -94,9 +99,11 @@ Kamaki clients may handle multiple requests at once, using threads. In that case Going agile ----------- -The kamaki.clients package contains a set of fine-grained unit-tests for all its packages. +The kamaki.clients package contains a set of fine-grained unit-tests for all +its packages. -.. note:: unit tests require the optional python-mock package, version 1.X or better +.. note:: unit tests require the optional python-mock package, version 1.X or + better Using the tests ^^^^^^^^^^^^^^^ @@ -108,25 +115,31 @@ To run the tests, the kamaki source code has to be downloaded. $ git clone https://code.grnet.gr/git/kamaki $ cd kamaki/kamaki/clients -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 +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 .. code-block:: console $ python test.py -To test a specific class, add the class name as an argument. E.g. for the Client class: +To test a specific class, add the class name as an argument. E.g. for the +Client class: .. code-block:: console $ python test.py Client -To test a specific method in a class, apply an extra argument, e.g. for the request method in the Client class: +To test a specific method in a class, apply an extra argument, e.g. for the +request method in the Client class: .. code-block:: console $ python test.py Client request -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: +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: .. code-block:: console @@ -141,7 +154,8 @@ Each package contains a test module (test.py) which is also runnable from the co # Test kamaki.clients.pithos.PithosClient.download $ python test.py Pithos download -To fully test a specific package, run test.py from the package location. E.g. to test everything in kamaki.clients.pithos package: +To fully test a specific package, run test.py from the package location. E.g. +to test everything in kamaki.clients.pithos package: .. code-block:: console @@ -151,31 +165,54 @@ To fully test a specific package, run test.py from the package location. E.g. to Mechanism ^^^^^^^^^ -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. +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. -By convention, testing classes are named as where is the name of the tested class or module. Methods not grouped in classes are tested by classes named after their respective module. +By convention, testing classes are named as where +is the name of the tested class or module. Methods not grouped in classes are +tested by classes named after their respective module. -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. +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. Adding unit tests ^^^^^^^^^^^^^^^^^ -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. + +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. Modifying an existing method """""""""""""""""""""""""""" -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. +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. -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. +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. -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. +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. Adding a new method """"""""""""""""""" -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. +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. -Example 1: To add a **list_special** method to kamaki.clients.astakos.AstakosClient, extend the kamaki.clients.astakos.test.AstakosClient class, as shown bellow: +Example 1: To add a **list_special** method to +kamaki.clients.astakos.AstakosClient, extend the +kamaki.clients.astakos.test.AstakosClient class, as shown bellow: .. code-block:: python @@ -187,7 +224,8 @@ Example 1: To add a **list_special** method to kamaki.clients.astakos.AstakosCli """Test the list_special method""" ... -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: +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: .. code-block:: python @@ -202,9 +240,12 @@ Example 2: To add a **get_random_int** method in kamaki.clients.utils module, ex Implementing a new class or module """""""""""""""""""""""""""""""""" -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. +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. -Example 1: To add a NewService class that implements the kamaki.clients.Client interface: +Example 1: To add a NewService class that implements the kamaki.clients.Client +interface: * create a new_service package and implement the unit tests in the kamaki.clients.new_service.test module: @@ -250,5 +291,11 @@ Example 1: To add a NewService class that implements the kamaki.clients.Client i from kamaki.clients.new_service.test import NewService -.. 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). +.. 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). diff --git a/docs/index.rst b/docs/index.rst index e582bf5..c428e9f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,7 +10,9 @@ Kamaki project documentation ./kamaki is a multipurpose, interactive command-line tool and also a client development API for managing clouds. -As a development API, it is an initial implementation of the Synnefo API (`Synnefo IaaS `_ cloud management software extends OpenStack), while preserving compatibility with the OpenStack API. +As a development library, it implements the Synnefo API ( +`Synnefo IaaS `_ cloud management software) which +extends OpenStack, therefore is also compatible with the OpenStack API. ./kamaki is open source and released under a 2-clause BSD License. diff --git a/docs/installation.rst b/docs/installation.rst index d458d28..339971e 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -13,8 +13,8 @@ have it up and running in all platforms running python 2.6 or 2.7. * Synnefo Linux packages: `http://apt.dev.grnet.gr `_ -Linux and Unix-like enviroments -------------------------------- +Linux and Unix-like environments +-------------------------------- Debian: ^^^^^^^ diff --git a/docs/man/kamaki.rst b/docs/man/kamaki.rst index 0eb9d36..a3566fb 100644 --- a/docs/man/kamaki.rst +++ b/docs/man/kamaki.rst @@ -180,7 +180,7 @@ network commands file commands ************** -* append Append local file to remote +* append Append local file to remote file * cat Print a file to console * copy Copy an object * containerlimit Container size limit commands diff --git a/docs/overview.rst b/docs/overview.rst index dcf2404..4cb4848 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -8,9 +8,9 @@ Kamaki was created on 2011 by the Synnefo (http://www.synnefo.org) development team of the *Greek Research and Technology Network (GRNET)*, initially as an internal project and later as a multipurpose tool for all users. -Synnefo is an IaaS system which is based on and extents OpenStack. -Synnefo has been deployed in many environments to cover multiple needs. The -most notable, deployment is probably the GRNET's +Synnefo is an IaaS system which implements and extents OpenStack. Synnefo has +been deployed in many environments to cover multiple needs. The most notable +deployment is probably the GRNET's `~okeanos `_ IaaS service, running in GRNET data centers, is used to offer cloud services to the Greek Research and Academic Community. diff --git a/docs/setup.rst b/docs/setup.rst index 1f66c56..f621ca1 100644 --- a/docs/setup.rst +++ b/docs/setup.rst @@ -11,34 +11,44 @@ Quick Setup Existing kamaki users should consult the `migration guide <#migrating-from-kamaki-0-8-x-to-0-9>`_ first. -Kamaki has to be configured to use a specific Synnefo deployment url and a user -token. +Kamaki has to be configured for a specific Synnefo deployment, with an +authentication url and user token pair. Users should also pick an alias to name +the cloud configuration. This can be any single word, e.g. "default", "mycloud" +or whatever suits kamaki users. .. code-block:: console - $ kamaki config set remote.default.url - $ kamaki config set remote.default.token myt0k3n== + $ kamaki config set cloud..url + $ kamaki config set cloud..token myt0k3n== -Since Synnefo version 0.14, a synnefo cloud remote UI offers a single -authentication URL, which can to be set as the default URL for kamaki. All -service-specific URLs are now retrieved and handled automatically. Users of -synnefo clouds >= 0.14 are advised against using any service-specific URLs. +If only one cloud is configured, kamaki automatically picks it as the default. +Otherwise, a default cloud should be specified: + +.. code-block:: console + + $ kamaki config set default_cloud + +Since Synnefo version 0.14, a synnefo cloud UI offers a single authentication +URL, which should be set as the cloud URL for kamaki. All service-specific URLs +are retrieved and handled automatically by kamaki, through this URL. Users of +synnefo clouds >=0.14 are advised against using any service-specific URLs. Migrating from kamaki 0.8.X to 0.9 ---------------------------------- -This section refers to running installations of kamaki version <= 0.8.X -To check the current kamaki version: +This section refers to running installations of kamaki version <= 0.8.X To +check the current kamaki version: .. code-block:: console $ kamaki -V -Existing kamaki users should convert their configuration files to v3. To do -that, kamaki 0.9 inspects the configuration file and suggests a list of config -file transformations, which are performed automatically on user permission. -This mechanism is invoked when the first API-related kamaki command is fired. -We suggest the `user authenticate` command, as shown on example 2.1. +Existing kamaki users should convert their configuration files to v9. To do +that, kamaki 0.9 can inspect the configuration file and suggests a list of +config file transformations, which are performed automatically (after users' +permission). This mechanism is invoked when an API-related kamaki command is +fired. On example 2.1 we suggest using the `user authenticate` command to fire +the kamaki config file conversion mechanism. .. code-block:: console :emphasize-lines: 1 @@ -46,11 +56,11 @@ We suggest the `user authenticate` command, as shown on example 2.1. Example 2.1: Convert config file while authenticating user "exampleuser" $ kamaki user authenticate - Config file format version >= 3.0 is required - Configuration file "/home/exampleuser/.kamakirc" format is not up to date + Config file format version >= 9.0 is required + Configuration file: "/home/exampleuser/.kamakirc" but kamaki can fix this: Calculating changes while preserving information - ... rescue global.token => remote.default.token + ... rescue global.token => cloud.default.token ... rescue config.cli => global.config_cli ... rescue history.file => global.history_file ... DONE @@ -63,7 +73,7 @@ We suggest the `user authenticate` command, as shown on example 2.1. file.url = https://pithos.okeanos.grnet.gr/v1 image.url = https://cyclades.okeanos.grnet.gr/plankton - Kamaki is ready to convert the config file to version 3.0 + Kamaki is ready to convert the config file to version 9.0 Overwrite file /home/exampleuser/.kamakirc ? [Y, y] At this point, we should examine the kamaki output. Most options are renamed to @@ -78,7 +88,7 @@ Let's take a look at the discarded options: meaningless and therefore omitted. * `global.data_log` option has never been a valid kamaki config option. - In this example, the user accidentally misspelled the terms `log_data` + In this example, the user accidentally misspelled the term `log_data` (which is a valid kamaki config option) as `data_log`. To fix this, the user should set the correct option after the conversion is complete (Example 2.2). @@ -105,26 +115,26 @@ steps described above. $ kamaki -c .myfilerc user authenticate -Multiple cloud remotes ----------------------- +Multiple clouds +--------------- The following refers to users of multiple Synnefo and/or Open Stack deployments. In the following, a Synnefo or Open Stack cloud deployment will -frequently be called as a **remote** or a **cloud remote**. +frequently be called as a **cloud**. -Kamaki supports accessing multiple cloud remotes from the same kamaki setup. -Bofore kamaki 0.9, this was possible only by using multiple config files. Since -0.9, kamaki supports multiple cloud remotes in the same configuration. +Kamaki supports accessing multiple clouds from the same kamaki setup. Before +kamaki 0.9, this was possible only by using multiple config files. Since 0.9, +kamaki supports multiple clouds in the same configuration. -Each cloud remote corresponds to a Synnefo (or Open Stack) cloud deployment. +Each cloud corresponds to a Synnefo (or Open Stack) cloud deployment. Since Synnefo version 0.14, each deployment offers a single point of authentication, as an **authentication URL** and **token** pair. Users can retrieve this information through the cloud UI. -Once a user has retrieved one URL/token pair per cloud remote, it is time to -assign a name to each cloud and let kamaki know about them. +Once a user has retrieved one URL/token pair per cloud, it is time to assign a +name to each cloud and let kamaki know about them. -For example, let the user have access to two remote clouds with the following authentication information :: +For example, let the user have access to two clouds with the following authentication information :: cloud alias: devel authentication URL: https://devel.example.com/astakos/identity/v2.0/ @@ -141,38 +151,38 @@ The user should let kamaki know about these setups: .. code-block:: console - $ kamaki config set remote.devel.url https://devel.example.com/astakos/identity/v2.0/ - $ kamaki config set remote.devel.token myd3v3170k3n== + $ kamaki config set cloud.devel.url https://devel.example.com/astakos/identity/v2.0/ + $ kamaki config set cloud.devel.token myd3v3170k3n== $ - $ kamaki config set remote.testing.url https://testing.example.com/astakos/identity/v2.0/ - $ kamaki config set remote.testing.token my73571ng70k3n== + $ kamaki config set cloud.testing.url https://testing.example.com/astakos/identity/v2.0/ + $ kamaki config set cloud.testing.token my73571ng70k3n== $ -To check if all settings are loaded, a user may list all remotes, as shown +To check if all settings are loaded, a user may list all clouds, as shown bellow: .. code-block:: console - $ kamaki config get remote - remote.default.url = https://example.com/astakos.identity/v2.0/ - remote.default.url = myd3f4u1770k3n== - remote.devel.url = https://devel.example.com/astakos/identity/v2.0/ - remote.devel.token = myd3v3170k3n== - remote.testing.url = https://testing.example.com/astakos/identity/v2.0/ - remote.testing.token = my73571ng70k3n== + $ kamaki config getcloud + cloud.default.url = https://example.com/astakos.identity/v2.0/ + cloud.default.url = myd3f4u1770k3n== + cloud.devel.url = https://devel.example.com/astakos/identity/v2.0/ + cloud.devel.token = myd3v3170k3n== + cloud.testing.url = https://testing.example.com/astakos/identity/v2.0/ + cloud.testing.token = my73571ng70k3n== $ -or query kamaki for a specific cloud remote: +or query kamaki for a specific cloud: .. code-block:: console - $ kamaki config get remote.devel - remote.devel.url = https://devel.example.com/astakos/identity/v2.0/ - remote.devel.token = myd3v3170k3n== + $ kamaki config get cloud.devel + cloud.devel.url = https://devel.example.com/astakos/identity/v2.0/ + cloud.devel.token = myd3v3170k3n== $ -Now kamaki can use any of there remotes, with the **- - cloud** attribute. If -the **- - cloud** option is ommited, kamaki will query the `default` cloud remote. +Now kamaki can use any of these clouds, with the **- - cloud** attribute. If +the **- - cloud** option is ommited, kamaki will query the `default` cloud. One way to test this, is the `user athenticate` command: @@ -203,7 +213,7 @@ One way to test this, is the `user athenticate` command: name : Default User $ -In interactive cell, the cloud remote is picked when invoking the shell, with +In interactive cell, the cloud is picked when invoking the shell, with the **- - cloud** option. Optional features @@ -213,20 +223,21 @@ For installing any or all of the following, consult the `kamaki installation guide `_ * ansicolors - * Make command line / console user interface responses prettier with text formating (colors, bold, etc.) - * Can be switched on/off in kamaki configuration file: colors=on/off + * Add colors to command line / console output + * Can be switched on/off in kamaki configuration file: `colors = on/off` * Has not been tested on non unix / linux based platforms * mock * For kamaki contributors only - * Allow unittests to run on kamaki.clients package + * Allow unit tests to run on kamaki.clients package * Needs mock version 1.X or better * astakosclient * For advanced users mostly * Allows the use of a full astakos command line client -Any of the above features can be installed at any time before or after kamaki installation. +Any of the above features can be installed at any time before or after kamaki +installation. Configuration options --------------------- @@ -238,14 +249,14 @@ There are two kinds of configuration options: colors in the output, maximum threads per connection, custom logging or history files, etc. -* cloud-related (remote.XXX) - information needed to connect and use one or more remote clouds. There are - some mandatory options (url, token) and some advanced / optional (e.g. - service-specific url overrides or versions) +* cloud-related + information needed to connect and use one or more clouds. There are some + mandatory options (URL, token) and some advanced / optional (e.g. + service-specific URL overrides or versions) Kamaki comes with preset default values to all kamaki-releated configuration options. Cloud-related information is not included in presets and should be -provided. Kamaki-related options can also be modified. +provided by the user. Kamaki-related options can also be modified. There are two ways of managing configuration options: edit the config file or use the kamaki config command. @@ -257,19 +268,17 @@ Kamaki setups are stored in configuration files. By default, a Kamaki installation stores options in *.kamakirc* file located at the user home directory. - If a user needs to switch between different kamaki-related setups, Kamaki can -explicitly load configuration files with the **- - config** (or **- c**) -option: +explicitly load configuration files with the **- - config** (or **- c**) option .. code-block:: console $ kamaki --config [other options] -.. note:: For access to multiple cloud remotes, users do NOT need to create - multiple configuration files. Instead, we suggest using a single - configuration file with multiple remote setups. More details can be found - at the `multiple remotes guide <#multiple-cloud-remotes>`_. +.. note:: For accessing multiple clouds, users do NOT need to create multiple + configuration files. Instead, we suggest using a single configuration file + with multiple cloud setups. More details can be found at the + `multiple clouds guide <#multiple-clouds>`_. Modifying options at runtime ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -297,7 +306,7 @@ Kamaki config command allows users to see and manage all configuration options. * kamaki config set set the group.option to value. If no group is given, the defaults to - *global* + *global*. * kamaki config delete delete a configuration option. If no group is given, the defaults to @@ -305,32 +314,38 @@ Kamaki config command allows users to see and manage all configuration options. The above commands cause option values to be permanently stored in the Kamaki configuration file. -The commands above can also be used for **cloud remotes** handling, using the -`remote.` prefix. The remote handling cases are similar but with slightly -different semantics: - -* kamaki config get remote[.[.option]] - * remote - list all cloud remotes (including `default`) and their settings - * remote. - list settings of the cloud remote aliased as . If no - special is configured, use the term `remote.default` - * remote..