Merge from head.
authorFaiyaz Ahmed <faiyaza@cs.princeton.edu>
Wed, 2 May 2007 03:59:33 +0000 (03:59 +0000)
committerFaiyaz Ahmed <faiyaza@cs.princeton.edu>
Wed, 2 May 2007 03:59:33 +0000 (03:59 +0000)
PLC/Methods/AddSlice.py
PLC/Methods/AddSliceAttribute.py
PLC/Methods/GetSliceTicket.py
PLC/Methods/GetSlivers.py
PLC/Methods/UpdateSliceAttribute.py
PLC/Methods/__init__.py
PLC/SliceAttributes.py
PLC/Slices.py
planetlab4.sql

index cbb0d85..5642519 100644 (file)
@@ -42,11 +42,11 @@ class AddSlice(Method):
         slice_fields = dict(filter(can_update, slice_fields.items()))
 
         # 1. Lowercase.
-        # 2. Begins with login_base (only letters).
+        # 2. Begins with login_base (letters or numbers).
         # 3. Then single underscore after login_base.
         # 4. Then letters, numbers, or underscores.
         name = slice_fields['name']
-        good_name = r'^[a-z]+_[a-z0-9_]+$'
+        good_name = r'^[a-z0-9]+_[a-zA-Z0-9_]+$'
         if not name or \
            not re.match(good_name, name):
             raise PLCInvalidArgument, "Invalid slice name"
index 22e7a38..aec3047 100644 (file)
@@ -5,6 +5,7 @@ from PLC.SliceAttributeTypes import SliceAttributeType, SliceAttributeTypes
 from PLC.Slices import Slice, Slices
 from PLC.Nodes import Node, Nodes
 from PLC.SliceAttributes import SliceAttribute, SliceAttributes
+from PLC.NodeGroups import NodeGroup, NodeGroups
 from PLC.InitScripts import InitScript, InitScripts
 from PLC.Auth import Auth
 
@@ -34,12 +35,15 @@ class AddSliceAttribute(Method):
         Mixed(SliceAttribute.fields['value'],
              InitScript.fields['initscript_id']),
         Mixed(Node.fields['node_id'],
-              Node.fields['hostname'])
+              Node.fields['hostname'],
+             None),
+       Mixed(NodeGroup.fields['nodegroup_id'],
+              NodeGroup.fields['name'])
         ]
 
     returns = Parameter(int, 'New slice_attribute_id (> 0) if successful')
 
-    def call(self, auth, slice_id_or_name, attribute_type_id_or_name, value, node_id_or_hostname = None):
+    def call(self, auth, slice_id_or_name, attribute_type_id_or_name, value, node_id_or_hostname = None, nodegroup_id_or_name = None):
         slices = Slices(self.api, [slice_id_or_name])
         if not slices:
             raise PLCInvalidArgument, "No such slice"
@@ -64,7 +68,7 @@ class AddSliceAttribute(Method):
 
        # if initscript is specified, validate value
        if attribute_type['name'] in ['plc_initscript_id']:
-           initscripts = InitScripts(self.api, [value])
+           initscripts = InitScripts(self.api, {'enabled': True, 'initscript_id': int(value)})
            if not initscripts: 
                raise PLCInvalidArgument, "No such plc initscript"      
 
@@ -85,6 +89,15 @@ class AddSliceAttribute(Method):
 
             slice_attribute['node_id'] = node['node_id']
 
+       # Sliver attribute shared accross nodes if nodegroup is sepcified
+       if nodegroup_id_or_name is not None:
+           nodegroups = NodeGroups(self.api, [nodegroup_id_or_name])
+           if not nodegroups:
+               raise PLCInvalidArgument, "No such nodegroup"
+           nodegroup = nodegroups[0]
+       
+           slice_attribute['nodegroup_id'] = nodegroup['nodegroup_id']
+
         slice_attribute.sync()
        self.event_objects = {'SliceAttribute': [slice_attribute['slice_attribute_id']]}
 
index 822d003..cd73f7b 100644 (file)
@@ -6,6 +6,7 @@ from PLC.Parameter import Parameter, Mixed
 from PLC.Slices import Slice, Slices
 from PLC.Auth import Auth
 from PLC.GPG import gpg_sign, gpg_verify
+from PLC.InitScripts import InitScript, InitScripts
 
 from PLC.Methods.GetSlivers import get_slivers
 
@@ -53,9 +54,12 @@ class GetSliceTicket(Method):
 
         # Tickets are the canonicalized XML-RPC methodResponse
         # representation of a partial GetSlivers() response, i.e.,
+       
+       initscripts = InitScripts(self.api, {'enabled': True})
 
         data = {
             'timestamp': int(time.time()),
+           'initscripts': initscripts,
             'slivers': get_slivers(self.api, [slice['slice_id']]),
             }
 
index ee1d632..434429d 100644 (file)
@@ -72,6 +72,15 @@ def get_slivers(api, slice_filter, node = None):
                 attributes.append({'name': sliver_attribute['name'],
                                    'value': sliver_attribute['value']})
 
+       # set nodegroup slice attributes
+       for slice_attribute in filter(lambda a: a['nodegroup_id'] in node['nodegroup_ids'], slice_attributes):
+           # Do not set any nodegroup slice attributes for
+            # which there is at least one sliver attribute
+            # already set.
+           if slice_attribute['name'] not in slice_attributes:
+               attributes.append({'name': slice_attribute['name'],
+                                  'value': slice_attribute['value']})
+
         for slice_attribute in filter(lambda a: a['node_id'] is None, slice_attributes):
             # Do not set any global slice attributes for
             # which there is at least one sliver attribute
@@ -196,7 +205,7 @@ class GetSlivers(Method):
 
         slivers = get_slivers(self.api, system_slice_ids + node['slice_ids'], node)
 
-       #node.update_last_contact()
+       node.update_last_contact()
 
         return {
             'timestamp': timestamp,
index 80122ac..43cf1f3 100644 (file)
@@ -3,6 +3,7 @@ from PLC.Method import Method
 from PLC.Parameter import Parameter, Mixed
 from PLC.SliceAttributes import SliceAttribute, SliceAttributes
 from PLC.Slices import Slice, Slices
+from PLC.InitScripts import InitScript, InitScripts
 from PLC.Auth import Auth
 
 class UpdateSliceAttribute(Method):
@@ -22,7 +23,8 @@ class UpdateSliceAttribute(Method):
     accepts = [
         Auth(),
         SliceAttribute.fields['slice_attribute_id'],
-        SliceAttribute.fields['value']
+       Mixed(SliceAttribute.fields['value'],
+              InitScript.fields['initscript_id'])
         ]
 
     returns = Parameter(int, '1 if successful')
@@ -54,8 +56,13 @@ class UpdateSliceAttribute(Method):
             if slice_attribute['min_role_id'] is not None and \
                min(self.caller['role_ids']) > slice_attribute['min_role_id']:
                 raise PLCPermissionDenied, "Not allowed to update the specified attribute"
+       
+       if slice_attribute['name'] in ['plc_initscript_id']:
+            initscripts = InitScripts(self.api, {'enabled': True, 'initscript_id': int(value)})
+            if not initscripts:
+                raise PLCInvalidArgument, "No such plc initscript"     
 
-        slice_attribute['value'] = value
+        slice_attribute['value'] = unicode(value)
         slice_attribute.sync()
        self.event_objects = {'SliceAttribute': [slice_attribute['slice_attribute_id']]}
         return 1
index 915e3d5..f491ff9 100644 (file)
@@ -1 +1 @@
-methods = 'AddAddressType AddAddressTypeToAddress AddBootState AddConfFile AddConfFileToNodeGroup AddConfFileToNode AddKeyType AddMessage AddNetworkMethod AddNetworkType AddNodeGroup AddNodeNetwork AddNode AddNodeToNodeGroup AddNodeToPCU AddPCU AddPeer AddPersonKey AddPerson AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSiteAddress AddSite AddSliceAttribute AddSliceAttributeType AddSliceInstantiation AddSlice AddSliceToNodes AdmAddAddressType AdmAddNodeGroup AdmAddNodeNetwork AdmAddNode AdmAddNodeToNodeGroup AdmAddPersonKey AdmAddPerson AdmAddPersonToSite AdmAddSitePowerControlUnit AdmAddSite AdmAssociateNodeToPowerControlUnitPort AdmAuthCheck AdmDeleteAddressType AdmDeleteAllPersonKeys AdmDeleteNodeGroup AdmDeleteNodeNetwork AdmDeleteNode AdmDeletePersonKeys AdmDeletePerson AdmDeleteSitePowerControlUnit AdmDeleteSite AdmDisassociatePowerControlUnitPort AdmGenerateNodeConfFile AdmGetAllAddressTypes AdmGetAllKeyTypes AdmGetAllNodeNetworks AdmGetAllRoles AdmGetNodeGroupNodes AdmGetNodeGroups AdmGetNodes AdmGetPersonKeys AdmGetPersonRoles AdmGetPersonSites AdmGetPersons AdmGetPowerControlUnitNodes AdmGetPowerControlUnits AdmGetSiteNodes AdmGetSitePersons AdmGetSitePIs AdmGetSitePowerControlUnits AdmGetSites AdmGetSiteTechContacts AdmGrantRoleToPerson AdmIsPersonInRole AdmQueryConfFile AdmQueryNode AdmQueryPerson AdmQueryPowerControlUnit AdmQuerySite AdmRebootNode AdmRemoveNodeFromNodeGroup AdmRemovePersonFromSite AdmRevokeRoleFromPerson AdmSetPersonEnabled AdmSetPersonPrimarySite AdmUpdateNodeGroup AdmUpdateNodeNetwork AdmUpdateNode AdmUpdatePerson AdmUpdateSitePowerControlUnit AdmUpdateSite AnonAdmGetNodeGroups AuthCheck BlacklistKey BootCheckAuthentication BootGetNodeDetails BootNotifyOwners BootUpdateNode DeleteAddress DeleteAddressTypeFromAddress DeleteAddressType DeleteBootState DeleteConfFileFromNodeGroup DeleteConfFileFromNode DeleteConfFile DeleteKey DeleteKeyType DeleteMessage DeleteNetworkMethod DeleteNetworkType DeleteNodeFromNodeGroup DeleteNodeFromPCU DeleteNodeGroup DeleteNodeNetwork DeleteNode DeletePCU DeletePeer DeletePersonFromSite DeletePersonFromSlice DeletePerson DeleteRoleFromPerson DeleteRole DeleteSession DeleteSite DeleteSliceAttribute DeleteSliceAttributeType DeleteSliceFromNodes DeleteSliceInstantiation DeleteSlice GetAddresses GetAddressTypes GetBootStates GetConfFiles GetEventObjects GetEvents GetKeys GetKeyTypes GetMessages GetNetworkMethods GetNetworkTypes GetNodeGroups GetNodeNetworks GetNodes GetPCUs GetPeerData GetPeerName GetPeers GetPersons GetRoles GetSession GetSites GetSliceAttributes GetSliceAttributeTypes GetSliceInstantiations GetSlices GetSliceTicket GetSlivers NotifyPersons RebootNode RefreshPeer ResetPassword SetPersonPrimarySite SliceCreate SliceDelete SliceExtendedInfo SliceGetTicket SliceInfo SliceListNames SliceListUserSlices SliceNodesAdd SliceNodesDel SliceNodesList SliceRenew SliceTicketGet SliceUpdate SliceUserAdd SliceUserDel SliceUsersList UpdateAddress UpdateAddressType UpdateConfFile UpdateKey UpdateMessage UpdateNodeGroup UpdateNodeNetwork UpdateNode UpdatePCU UpdatePeer UpdatePerson UpdateSite UpdateSliceAttribute UpdateSliceAttributeType UpdateSlice VerifyPerson  system.listMethods  system.methodHelp  system.methodSignature  system.multicall'.split()
+methods = 'AddAddressType AddAddressTypeToAddress AddBootState AddConfFile AddConfFileToNodeGroup AddConfFileToNode AddInitScript AddKeyType AddMessage AddNetworkMethod AddNetworkType AddNodeGroup AddNodeNetwork AddNode AddNodeToNodeGroup AddNodeToPCU AddPCU AddPeer AddPersonKey AddPerson AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSiteAddress AddSite AddSliceAttribute AddSliceAttributeType AddSliceInstantiation AddSlice AddSliceToNodes AdmAddAddressType AdmAddNodeGroup AdmAddNodeNetwork AdmAddNode AdmAddNodeToNodeGroup AdmAddPersonKey AdmAddPerson AdmAddPersonToSite AdmAddSitePowerControlUnit AdmAddSite AdmAssociateNodeToPowerControlUnitPort AdmAuthCheck AdmDeleteAddressType AdmDeleteAllPersonKeys AdmDeleteNodeGroup AdmDeleteNodeNetwork AdmDeleteNode AdmDeletePersonKeys AdmDeletePerson AdmDeleteSitePowerControlUnit AdmDeleteSite AdmDisassociatePowerControlUnitPort AdmGenerateNodeConfFile AdmGetAllAddressTypes AdmGetAllKeyTypes AdmGetAllNodeNetworks AdmGetAllRoles AdmGetNodeGroupNodes AdmGetNodeGroups AdmGetNodes AdmGetPersonKeys AdmGetPersonRoles AdmGetPersonSites AdmGetPersons AdmGetPowerControlUnitNodes AdmGetPowerControlUnits AdmGetSiteNodes AdmGetSitePersons AdmGetSitePIs AdmGetSitePowerControlUnits AdmGetSites AdmGetSiteTechContacts AdmGrantRoleToPerson AdmIsPersonInRole AdmQueryConfFile AdmQueryNode AdmQueryPerson AdmQueryPowerControlUnit AdmQuerySite AdmRebootNode AdmRemoveNodeFromNodeGroup AdmRemovePersonFromSite AdmRevokeRoleFromPerson AdmSetPersonEnabled AdmSetPersonPrimarySite AdmUpdateNodeGroup AdmUpdateNodeNetwork AdmUpdateNode AdmUpdatePerson AdmUpdateSitePowerControlUnit AdmUpdateSite AnonAdmGetNodeGroups AuthCheck BlacklistKey BootCheckAuthentication BootGetNodeDetails BootNotifyOwners BootUpdateNode DeleteAddress DeleteAddressTypeFromAddress DeleteAddressType DeleteBootState DeleteConfFileFromNodeGroup DeleteConfFileFromNode DeleteConfFile DeleteInitScript DeleteKey DeleteKeyType DeleteMessage DeleteNetworkMethod DeleteNetworkType DeleteNodeFromNodeGroup DeleteNodeFromPCU DeleteNodeGroup DeleteNodeNetwork DeleteNode DeletePCU DeletePeer DeletePersonFromSite DeletePersonFromSlice DeletePerson DeleteRoleFromPerson DeleteRole DeleteSession DeleteSite DeleteSliceAttribute DeleteSliceAttributeType DeleteSliceFromNodes DeleteSliceInstantiation DeleteSlice GetAddresses GetAddressTypes GetBootStates GetConfFiles GetEventObjects GetEvents GetInitScripts GetKeys GetKeyTypes GetMessages GetNetworkMethods GetNetworkTypes GetNodeGroups GetNodeNetworks GetNodes GetPCUs GetPeerData GetPeerName GetPeers GetPersons GetRoles GetSession GetSites GetSliceAttributes GetSliceAttributeTypes GetSliceInstantiations GetSlicesMD5 GetSlices GetSliceTicket GetSlivers NotifyPersons RebootNode RefreshPeer ResetPassword SetPersonPrimarySite SliceCreate SliceDelete SliceExtendedInfo SliceGetTicket SliceInfo SliceListNames SliceListUserSlices SliceNodesAdd SliceNodesDel SliceNodesList SliceRenew SliceTicketGet SliceUpdate SliceUserAdd SliceUserDel SliceUsersList UpdateAddress UpdateAddressType UpdateConfFile UpdateInitScript UpdateKey UpdateMessage UpdateNodeGroup UpdateNodeNetwork UpdateNode UpdatePCU UpdatePeer UpdatePerson UpdateSite UpdateSliceAttribute UpdateSliceAttributeType UpdateSlice VerifyPerson  system.listMethods  system.methodHelp  system.methodSignature  system.multicall'.split()
index 71b47e6..cfc0298 100644 (file)
@@ -16,6 +16,7 @@ class SliceAttribute(Row):
         'slice_attribute_id': Parameter(int, "Slice attribute identifier"),
         'slice_id': Parameter(int, "Slice identifier"),
         'node_id': Parameter(int, "Node identifier, if a sliver attribute"),
+       'nodegroup_id': Parameter(int, "Nodegroup identifier, if a sliver attribute"),
         'attribute_type_id': SliceAttributeType.fields['attribute_type_id'],
         'name': SliceAttributeType.fields['name'],
         'description': SliceAttributeType.fields['description'],
index c8f6e81..d3b6f78 100644 (file)
@@ -61,7 +61,7 @@ class Slice(Row):
         # 2. Begins with login_base (letters or numbers).
         # 3. Then single underscore after login_base.
         # 4. Then letters, numbers, or underscores.
-        good_name = r'^[a-z0-9]+_[a-z0-9_]+$'
+        good_name = r'^[a-z0-9]+_[a-zA-Z0-9_]+$'
         if not name or \
            not re.match(good_name, name):
             raise PLCInvalidArgument, "Invalid slice name"
index 0b5c819..f14d403 100644 (file)
@@ -606,11 +606,13 @@ CREATE TABLE slice_attribute (
     slice_attribute_id serial PRIMARY KEY, -- Slice attribute identifier
     slice_id integer REFERENCES slices NOT NULL, -- Slice identifier
     node_id integer REFERENCES nodes, -- Sliver attribute if set
+    nodegroup_id integer REFERENCES nodegroups, -- Node group attribute if set
     attribute_type_id integer REFERENCES slice_attribute_types NOT NULL, -- Attribute type identifier
     value text
 ) WITH OIDS;
 CREATE INDEX slice_attribute_slice_id_idx ON slice_attribute (slice_id);
 CREATE INDEX slice_attribute_node_id_idx ON slice_attribute (node_id);
+CREATE INDEX slice_attribute_nodegroup_id_idx ON slice_attribute (nodegroup_id);
 
 CREATE VIEW slice_attributes AS
 SELECT slice_id,
@@ -978,6 +980,7 @@ SELECT
 slice_attribute.slice_attribute_id,
 slice_attribute.slice_id,
 slice_attribute.node_id,
+slice_attribute.nodegroup_id,
 slice_attribute_types.attribute_type_id,
 slice_attribute_types.name,
 slice_attribute_types.description,