From 53575785544f1cfbd7dc1a6a739f24f93eae1e33 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Wed, 1 Dec 2010 15:44:49 +0100 Subject: [PATCH 1/1] define_accessors accepts a list of classes if needed service plc start accessors ensures consistency b/w the accessors definition and the tag_types in the db revised std accessors accordingly --- PLC/Accessor.py | 25 ++++++++++++++++++++++--- PLC/Accessors/Accessors_site.py | 13 ++++--------- PLC/Accessors/Accessors_standard.py | 17 ++++------------- PLC/Accessors/Factory.py | 22 ++++++++++++++++------ 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/PLC/Accessor.py b/PLC/Accessor.py index fb12f3d..e02d29e 100644 --- a/PLC/Accessor.py +++ b/PLC/Accessor.py @@ -9,6 +9,8 @@ # by the Factory, you need to restart your python instance / web server # as the cached information then becomes wrong +from PLC.Debug import log + from PLC.TagTypes import TagTypes, TagType from PLC.Roles import Roles, Role @@ -27,12 +29,13 @@ This is implemented as a singleton, so we can cache results over time""" self.api=api # 'tagname'=>'tag_id' self.cache={} + self.hash_name_to_role=dict ( [ (role['name'],role) for role in Roles(api)] ) def has_cache (self,tagname): return self.cache.has_key(tagname) def get_cache (self,tagname): return self.cache[tagname] def set_cache (self,tagname,tag_type): self.cache[tagname]=tag_type - def locate_or_create_tag (self, tagname, category, description, roles): + def locate_or_create_tag (self, tagname, category, description, roles, enforce=False): "search tag type from tagname & create if needed" # cached ? @@ -42,6 +45,22 @@ This is implemented as a singleton, so we can cache results over time""" tag_types = TagTypes (self.api, {'tagname':tagname}) if tag_types: tag_type = tag_types[0] + # enforce should only be set by the 'service plc start accessors' sequence + if enforce: + try: + tag_type.update({'category':category,'description':description}) + tag_type.sync() + roles_to_add = set(roles).difference(set(tag_type['roles'])) + for rolename in roles_to_add: + tag_type.add_role(self.hash_name_to_role[rolename]) + roles_to_delete = set(tag_type['roles']).difference(set(roles)) + for rolename in roles_to_delete: + tag_type.remove_role(self.hash_name_to_role[rolename]) + except: + # this goes in boot.log ... + print >> log, "WARNING, Could not enforce tag type, tagname=%s\n"%tagname + traceback.print_exc(file=log) + else: # not found: create it tag_type_fields = {'tagname':tagname, @@ -70,12 +89,12 @@ This is implemented as a singleton, so we can cache results over time""" # this is designed to be part of the 'service plc start' sequence # it ensures the creation of all the tagtypes defined - # in the various accessors + # in the various accessors, and enforces consistency to the DB # it's not easy to have define_accessors do this because at # load-time as we do not have an instance of API yet def run_all_tag_locators (self): for (name, tag_locator) in Accessor.tag_locators.items(): - tag_locator(self) + tag_locator(self,enforce=True) #################### # make it a singleton so we can cache stuff in there over time diff --git a/PLC/Accessors/Accessors_site.py b/PLC/Accessors/Accessors_site.py index 7955395..cce0c51 100644 --- a/PLC/Accessors/Accessors_site.py +++ b/PLC/Accessors/Accessors_site.py @@ -4,21 +4,16 @@ # Accessors_site.py is the place where you can define your own local tag accessors # this will not be overwritten through rpm upgrades # +# Historical note: now that Sites are taggable too, the name may be confusing, +# think of this as Accessors_local.py +# # to ensure creation of new tag_types, just run # service plc start accessors -# also for the running service to take the new accessors into account, you need to +# also for the running API to take the new accessors into account, you need to # apachectl restart # or to stay on the safe side, simply do # service plc restart # -# please note however that if a tag_type already exists in the DB, then -# changing the corresponding accessors creation code WILL NOT alter the -# tag_type in the DB; that applies to roles and other desc. or categ. -# you will thus need to apply them manually -# -# Now that Sites are taggable too, the name may be confusing, think of is as -# Accessors_local.py -# # methods denotes the set of methods (names) that get inserted into the API # it is updated by define_accessors diff --git a/PLC/Accessors/Accessors_standard.py b/PLC/Accessors/Accessors_standard.py index 680dfd5..e07c8be 100644 --- a/PLC/Accessors/Accessors_standard.py +++ b/PLC/Accessors/Accessors_standard.py @@ -33,26 +33,17 @@ define_accessors(current_module, Slice, "Initscript","initscript", # xxx the accessor factory should enforce the category, descriptions and roles provided here. # BootManager might need to set any of these 3, so 'node' needs to be in set_roles -define_accessors(current_module, Slice, "Arch", "arch", +# to tweaks the installed version on nodes and slivers +define_accessors(current_module, [Slice,Node], "Arch", "arch", "node/slice/config", "node arch or slivers arch", set_roles=["pi","user","tech","node"], expose_in_api=True) -define_accessors(current_module, Slice, "Pldistro", "pldistro", +define_accessors(current_module, [Slice,Node], "Pldistro", "pldistro", "node/slice/config", "PlanetLab distribution to use for node or slivers", set_roles=["pi","user","tech","node"], expose_in_api=True) -define_accessors(current_module, Slice, "Fcdistro", "fcdistro", +define_accessors(current_module, [Slice,Node], "Fcdistro", "fcdistro", "node/slice/config", "Fedora or CentOS distribution to use for node or slivers", set_roles=["pi","user","tech","node"], expose_in_api=True) -# Ditto for the GetNodeFlavour method -define_accessors(current_module, Node, "Arch", "arch", - "node/slice/config", "node arch or slivers arch", - set_roles=["pi","user","tech"], expose_in_api=True) -define_accessors(current_module, Node, "Pldistro", "pldistro", - "node/slice/config", "PlanetLab distribution to use for node or slivers", - set_roles=["pi","user","tech"], expose_in_api=True) -define_accessors(current_module, Node, "Fcdistro", "fcdistro", - "node/slice/config", "Fedora or CentOS distribution to use for node or slivers", - set_roles=["pi","user","tech"], expose_in_api=True) # node deployment (alpha, beta, ...) define_accessors(current_module, Node, "Deployment", "deployment", "node/operation", 'typically "alpha", "beta", or "production"', diff --git a/PLC/Accessors/Factory.py b/PLC/Accessors/Factory.py index 3ad0bc1..e4ef578 100644 --- a/PLC/Accessors/Factory.py +++ b/PLC/Accessors/Factory.py @@ -72,10 +72,19 @@ tech_roles = [ 'admin', 'pi', 'tech' ] # the convention here is that methodsuffix should be mixed case, e.g. MyStuff # while tagname is expected to be lowercase # you then end up with e.g. GetPersonMyStuff -def define_accessors (module, objclass, methodsuffix, tagname, - category, description, - get_roles=all_roles, set_roles=admin_roles, - expose_in_api = False): + +# the entry point accepts a single class or a list of classes +def define_accessors (module, objclasses, *args, **kwds): + if not isinstance(objclasses,list): + objclasses=[objclasses] + for objclass in objclasses: + define_accessors_ (module, objclass, *args, **kwds) + +# this is for one class +def define_accessors_ (module, objclass, methodsuffix, tagname, + category, description, + get_roles=all_roles, set_roles=admin_roles, + expose_in_api = False): if objclass not in taggable_classes: try: @@ -131,11 +140,12 @@ def define_accessors (module, objclass, methodsuffix, tagname, # locate the tag and create it if needed # this method is attached to the Accessor class - def tag_locator (self): + def tag_locator (self, enforce=False): return self.locate_or_create_tag (tagname=tagname, category=category, description=description, - roles=set_roles) + roles=set_roles, + enforce=enforce) # attach it to the Accessor class Accessor.register_tag_locator(locator_name,tag_locator) -- 2.43.0