From 599dacb3567c6453feb82e7674b59ecd590c9cad Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Thu, 11 Dec 2008 11:08:41 +0000 Subject: [PATCH] documented tag-based access methods and nodegroup new model --- doc/PLCAPI.xml.in | 209 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 194 insertions(+), 15 deletions(-) diff --git a/doc/PLCAPI.xml.in b/doc/PLCAPI.xml.in index f52353e..b3777a0 100644 --- a/doc/PLCAPI.xml.in +++ b/doc/PLCAPI.xml.in @@ -1,4 +1,5 @@ + @@ -122,16 +123,16 @@
Filters - Most of the Get functions take a + Most of the Get methods take a filter argument. Filters may be arrays of integer (and sometimes string) identifiers, or a struct representing a filter on the - attributes of the entities being queried. For example, + attributes of the entities being queried. For example, -# plcsh code fragment (see below) -GetNodes([1,2,3]) -GetNodes({'node_id': [1,2,3]}) +>>> GetNodes([1,2,3]) +>>> GetNodes({'node_id': [1,2,3]}) + Would be equivalent queries. Attributes that are themselves arrays (such as interface_ids @@ -139,28 +140,206 @@ GetNodes({'node_id': [1,2,3]}) filters. Filters support a few extra features illustrated in the following examples. + +
+ Pattern Matching + * can be used in a text value and have the usual meaning, so all nodes in the fr can be obtained with: + GetNodes ( { 'hostname' : '*.fr' } ) + +
+ +
+ Negation + Fields starting with a ~ are negated, so non-local nodes can be fetched with: + GetNodes( { '~peer_id' : None } ) + +
+ +
+ Nueric comparisons + Strictly greater/smaller operations are achieved by prepending the field name like in: + GetEvents( { '>time' : 1178531418 } ) + + Greater/smaller or equal: + GetEvents( { ']event_id' : 2305 } ) + +
+ +
+ Sorting and Clipping + The following 3 special fields can be used to extract only a subset of the results for pagination: + GetNodes( { '-SORT' : 'hostname' , '-OFFSET' : 30 , '-LIMIT' : 25 } + +
+
+ +
+ Tags + + The PLC API comes with a feature called + tags, that basically aims at supporting an + extensible data model. A few classes (as of this writing, Nodes, + Interfaces and Slices) are eligible for being dynamically + extended beyond the basic set of fields that are built into the + database schema. + + Historically, this is a generalization of the concept of + SliceAttribute , and the more recent + concept of InterfaceSetting , that with + release 5.0 have been renamed into SliceTag + and InterfaceTag , + respectively. + +
+ Low level + The low level interface to tags relies on the following items: - Pattern Matching - GetNodes ( { 'hostname' : '*.fr' } ) + + A TagType object basically models a + new column that needs to be added to other objects. In + much the same way as nodes are named through a + hostname , tagtypes are named with a + tagname, plus additional information + (category, description) that is mostly informative. The + convention is to use a category that depicts the type of + objects that the tag type, like e.g. + node/config + - Negation - GetNodes( { '~peer_id' : None } ) + You would then be allowed to attach a value to, say, + a Node, by calling AddNodeTag , and + then as usual change this value with + UpdateNodeTag , or delete it with + DeleteNodeTag . + + +
+ +
+ Accessors + A rather more convenient way to use tags is through + Accessors. This convenience is located in + PLC/Accessors , and allows you to easily define Get + or Set methods dedicated to a given tag. This is for instance + how the GetNodeArch and + SetNodeArch methods are implemented. These methods + greatly simplify tags manipulation as they take care of + - Numeric comparisons - GetEvents( { '>time' : 1178531418 } ) - GetEvents( { ']event_id' : 2305 } ) + Lazily create TagTypes when + needed, - Sorting and Clipping - GetNodes( { '-SORT' : 'hostname' , '-OFFSET' : 30 , '-LIMIT' : 25 } + Create or update the, say, NodeTag + object, as needed. + + Site-specific accessors can be + defined in + /usr/share/plc_api/PLC/Accessors/Accessors_site.py + that will be preserved across updates of the PLCAPI rpm. + + + This mechanism does not currently support setting slice + tags that apply only on a given node or nodegroup. + +
+ +
+ Through regular Add/Get/Update methods + + Finally, tags may also get manipulated through the + AddNode, GetNodes, + and UpdateNode methods: + + + + The define_accessors function in the + Accessors factory has an optional argument named + expose_in_api . When this is set, the + corresponding tag becomes visible from the Add/Get/Update + methods almost as if it was a native tag. + + + + So for instance the following code would be legal and do as expected: + +# create a x86_64 node +>>> AddNode({'hostname':'pl1.foo.com','arch':'x86_64'}) +# get details for pl1.foo.com including tag 'arch' tag +>>> GetNodes(['pl1.foo.com'],['boot_state','node_type','arch']) +# set the 'deployment' tag +>>> UpdateNode('pl1.foo.com',{'deployment':'beta'}) +# get all alpha and beta nodes +>>> GetNodes({'deployment':'*a'},['hostname','deployment']) + + + + + The current limitation about tags as opposed to native + fields is that, for performance, tags won't get returned + when using the implicit set of columns. So for instance: + +# get all details for 'pl1.foo.com' +>>> node=GetNodes(['pl1.foo.com'])[0] +# this did not return the 'arch' tag +>>> 'arch' in node +False + + + + + +
+
+ +
+ Nodegroups + + In earlier versions up to v4.2, NodeGroups + used to be defined extensively. So you would, + basically, create an empty nodegroup instance, and then use + AddNodeToNodeGroup or + DeleteNodeFromNodeGroup to manage the nodegroup's + contents. + + The new model has been redefined as follows. You now define + a nodegroup as the set of nodes for which a given Tag + has a given value, which are defined once and for good + when creating the NodeGroup object. + + So for instance for managing the set of nodes that are + running various levels of software code, PLC has defined two + NodeGroups named alpha + and beta . With the new model, we would now do + something like the following, using the built-in + deployment tag that is created for that purpose: + +>>> AddNodeGroup('alphanodes','deployment','alpha') +21 +>>> AddNodeGroup('betanodes','deployment','beta') +21 +>>> for ng in GetNodeGroups(['alphanodes','betanodes'],['groupname','node_ids']): print ng +{'groupname': u'alphanodes', 'node_ids': []} +{'groupname': u'betanodes', 'node_ids': []} +>>> SetNodeDeployment('vnode01.inria.fr','alpha') +>>> for ng in GetNodeGroups(['alphanodes','betanodes'],['groupname','node_ids']): print ng +{'groupname': u'alphanodes', 'node_ids': [1]} +{'groupname': u'betanodes', 'node_ids': []} +>>> SetNodeDeployment('vnode01.inria.fr','beta') +>>> for ng in GetNodeGroups(['alphanodes','betanodes'],['groupname','node_ids']): print ng +{'groupname': u'alphanodes', 'node_ids': []} +{'groupname': u'betanodes', 'node_ids': [1]} + + +
-
+
PlanetLab shell A command-line program called plcsh -- 2.43.0