# 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
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 ?
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,
# 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
# 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
# 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"',
# 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:
# 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)