Commit 9360f398 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Fix deprecated terms in documentation

Conflicts:

	kamaki/cli/config.py
parent af22ea25
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 <usage.html#interactive-shell>`_ 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 <usage.html#interactive-shell>`_ 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 <setup.html>`_ or the `quick setup guide <usage.html#quick-setup>`_)
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>`_)
.. 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 <name> <flavor id> <image id>
[--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
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 <id> [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 <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>`_).
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>`_).
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 <argument>.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 <param>
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) - <param1:param2> [...]
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=''):
...
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::
......
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