From 54d86177513c26f52e4aa7947e5bbc8ba91969ff Mon Sep 17 00:00:00 2001 From: Michael Fenn Date: Mon, 5 Aug 2013 19:15:37 -0400 Subject: Metadata: Don't update XML on gratuitous profile update Check to see if the profile that is being set by set_profile exactly matches the existing profile list. If it does, then avoid writing out a new clients.xml. This simple optimization reduces the amount of clients.xml rewriting that occurs if you have a bunch of clients running bcfg2 -p at the same time (for example, during a cluster rebuild). --- src/lib/Bcfg2/Server/Plugins/Metadata.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Metadata.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py index e8962d707..973acb89a 100644 --- a/src/lib/Bcfg2/Server/Plugins/Metadata.py +++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py @@ -980,9 +980,10 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, profiles = [g for g in self.clientgroups[client] if g in self.groups and self.groups[g].is_profile] - self.logger.info("Changing %s profile from %s to %s" % + if profiles != [profile]: + self.logger.info("Changing %s profile from %s to %s" % (client, profiles, profile)) - self.update_client(client, dict(profile=profile)) + self.update_client(client, dict(profile=profile)) if client in self.clientgroups: for prof in profiles: self.clientgroups[client].remove(prof) -- cgit v1.2.3-1-g7c22 From 8b6a550d6dfa086935bf695ded1cdad89a383ff4 Mon Sep 17 00:00:00 2001 From: Michael Fenn Date: Mon, 5 Aug 2013 19:29:25 -0400 Subject: Make pylint happy --- src/lib/Bcfg2/Server/Plugins/Metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Metadata.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py index 973acb89a..512090ac5 100644 --- a/src/lib/Bcfg2/Server/Plugins/Metadata.py +++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py @@ -982,7 +982,7 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, if g in self.groups and self.groups[g].is_profile] if profiles != [profile]: self.logger.info("Changing %s profile from %s to %s" % - (client, profiles, profile)) + (client, profiles, profile)) self.update_client(client, dict(profile=profile)) if client in self.clientgroups: for prof in profiles: -- cgit v1.2.3-1-g7c22 From a96a3301d5a2b0630795709c00e80f938fed10a4 Mon Sep 17 00:00:00 2001 From: Michael Fenn Date: Mon, 5 Aug 2013 19:55:56 -0400 Subject: Found a stray write that should be part of the new client case --- src/lib/Bcfg2/Server/Plugins/Metadata.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Metadata.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py index 512090ac5..0e2277239 100644 --- a/src/lib/Bcfg2/Server/Plugins/Metadata.py +++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py @@ -1005,8 +1005,8 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, self.add_client(client, dict(profile=profile)) self.clients.append(client) self.clientgroups[client] = [profile] - if not self._use_db: - self.clients_xml.write() + if not self._use_db: + self.clients_xml.write() def set_version(self, client, version): """Set version for provided client.""" -- cgit v1.2.3-1-g7c22 From 936b8aa2b6329ddf45c1032171c16d0eaea99b37 Mon Sep 17 00:00:00 2001 From: Michael Fenn Date: Mon, 5 Aug 2013 21:19:41 -0400 Subject: Make updating the structures conditional on profile changing Based on the expectations of the tests, I am reasonably confident that updating the in memory structures is logically part of changing the client's profile so I put it in the if block --- src/lib/Bcfg2/Server/Plugins/Metadata.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Metadata.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py index 0e2277239..e62b3f77f 100644 --- a/src/lib/Bcfg2/Server/Plugins/Metadata.py +++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py @@ -984,12 +984,12 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, self.logger.info("Changing %s profile from %s to %s" % (client, profiles, profile)) self.update_client(client, dict(profile=profile)) - if client in self.clientgroups: - for prof in profiles: - self.clientgroups[client].remove(prof) - self.clientgroups[client].append(profile) - else: - self.clientgroups[client] = [profile] + if client in self.clientgroups: + for prof in profiles: + self.clientgroups[client].remove(prof) + self.clientgroups[client].append(profile) + else: + self.clientgroups[client] = [profile] else: self.logger.info("Creating new client: %s, profile %s" % (client, profile)) -- cgit v1.2.3-1-g7c22 From 4bf1c82868357e5c357e0b656419af37a99a8545 Mon Sep 17 00:00:00 2001 From: Michael Fenn Date: Tue, 6 Aug 2013 16:01:12 -0400 Subject: Get profile by building metadata instead of guessing Rather than doing some ad-hoc lookups of internal data structures stpierre suggested that it'd be better to use the normal metadata build procedures. This implements that and adjusts the tests. --- src/lib/Bcfg2/Server/Plugins/Metadata.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Metadata.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py index e62b3f77f..cc0456334 100644 --- a/src/lib/Bcfg2/Server/Plugins/Metadata.py +++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py @@ -978,18 +978,21 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, self.logger.error(msg) raise Bcfg2.Server.Plugin.PluginExecutionError(msg) - profiles = [g for g in self.clientgroups[client] - if g in self.groups and self.groups[g].is_profile] - if profiles != [profile]: + metadata = self.core.build_metadata(client) + if metadata.profile != profile: self.logger.info("Changing %s profile from %s to %s" % - (client, profiles, profile)) + (client, metadata.profile, profile)) self.update_client(client, dict(profile=profile)) if client in self.clientgroups: - for prof in profiles: - self.clientgroups[client].remove(prof) + if metadata.profile in self.clientgroups[client]: + self.clientgroups[client].remove(metadata.profile) self.clientgroups[client].append(profile) else: self.clientgroups[client] = [profile] + else: + self.logger.debug( + "Ignoring %s request to change profile from %s to %s" + % (client, metadata.profile, profile)) else: self.logger.info("Creating new client: %s, profile %s" % (client, profile)) -- cgit v1.2.3-1-g7c22 From 7e9787c947e99b68317f5420951a296cea858daa Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 7 Aug 2013 11:37:38 -0400 Subject: Plugin: added new Caching interface This gives a single unified interface for expiring caches, no matter the plugin. This will be particularly useful with the MultiprocessingCore, as certain calls must be dispatched to child processes to expire their caches. --- src/lib/Bcfg2/Server/Plugins/Metadata.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Metadata.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py index cc0456334..03323d64b 100644 --- a/src/lib/Bcfg2/Server/Plugins/Metadata.py +++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py @@ -487,6 +487,7 @@ class MetadataGroup(tuple): # pylint: disable=E0012,R0924 class Metadata(Bcfg2.Server.Plugin.Metadata, + Bcfg2.Server.Plugin.Caching, Bcfg2.Server.Plugin.ClientRunHooks, Bcfg2.Server.Plugin.DatabaseBacked): """This class contains data for bcfg2 server metadata.""" @@ -495,6 +496,7 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, def __init__(self, core, datastore, watch_clients=True): Bcfg2.Server.Plugin.Metadata.__init__(self) + Bcfg2.Server.Plugin.Caching.__init__(self) Bcfg2.Server.Plugin.ClientRunHooks.__init__(self) Bcfg2.Server.Plugin.DatabaseBacked.__init__(self, core, datastore) self.watch_clients = watch_clients @@ -934,13 +936,16 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, self.groups[gname] self.states['groups.xml'] = True + def expire_cache(self, key=None): + self.core.metadata_cache.expire(key) + def HandleEvent(self, event): """Handle update events for data files.""" for handles, event_handler in self.handlers.items(): if handles(event): # clear the entire cache when we get an event for any # metadata file - self.core.metadata_cache.expire() + self.expire_cache() event_handler(event) if False not in list(self.states.values()) and self.debug_flag: -- cgit v1.2.3-1-g7c22