def cleanup(self, domain, locked=False): """ remove all files related to an object template including any intermediate build files """ key = None try: if not locked: key = self.get_remove_key() lock_queue.acquire(key) if self.template_type == "object": # Can't call remove() here because it relies on the new domain. qdir = self.config.get("broker", "quattordir") # Only one or the other of .xml/.xml.gz should be there... # it doesn't hurt to clean up both. xmldir = os.path.join(qdir, "build", "xml", domain, self.plenary_core) xmlfile = os.path.join(xmldir, self.plenary_template + ".xml") remove_file(xmlfile, logger=self.logger) xmlgzfile = xmlfile + ".gz" remove_file(xmlgzfile, logger=self.logger) # Name used up to and including panc 9.2 depfile = xmlfile + ".dep" remove_file(depfile, logger=self.logger) # Name used by panc 9.4 and higher depfile = os.path.join(xmldir, self.plenary_template + ".dep") remove_file(depfile, logger=self.logger) try: os.removedirs(xmldir) except OSError: pass builddir = self.config.get("broker", "builddir") maindir = os.path.join(builddir, "domains", domain, "profiles", self.plenary_core) mainfile = os.path.join(maindir, self.plenary_template + TEMPLATE_EXTENSION) remove_file(mainfile, logger=self.logger) try: os.removedirs(maindir) except OSError: pass self.removed = True else: # Non-object templates do not depend on the domain, so calling # remove() is fine self.remove(locked=True) except: if not locked: self.restore_stash() raise finally: if not locked: lock_queue.release(key)
def cleanup(self, domain, locked=False): """ remove all files related to an object template including any intermediate build files """ key = None try: if not locked: key = self.get_remove_key() lock_queue.acquire(key) if self.template_type == "object": # Can't call remove() here because it relies on the new domain. qdir = self.config.get("broker", "quattordir") # Only one or the other of .xml/.xml.gz should be there... # it doesn't hurt to clean up both. xmldir = os.path.join(qdir, "build", "xml", domain, self.plenary_core) xmlfile = os.path.join(xmldir, self.plenary_template + ".xml") remove_file(xmlfile, logger=self.logger) xmlgzfile = xmlfile + ".gz" remove_file(xmlgzfile, logger=self.logger) # Name used up to and including panc 9.2 depfile = xmlfile + ".dep" remove_file(depfile, logger=self.logger) # Name used by panc 9.4 and higher depfile = os.path.join(xmldir, self.plenary_template + ".dep") remove_file(depfile, logger=self.logger) try: os.removedirs(xmldir) except OSError: pass builddir = self.config.get("broker", "builddir") maindir = os.path.join(builddir, "domains", domain, "profiles", self.plenary_core) mainfile = os.path.join( maindir, self.plenary_template + TEMPLATE_EXTENSION) remove_file(mainfile, logger=self.logger) try: os.removedirs(maindir) except OSError: pass self.removed = True else: # Non-object templates do not depend on the domain, so calling # remove() is fine self.remove(locked=True) except: if not locked: self.restore_stash() raise finally: if not locked: lock_queue.release(key)
def remove(self, locked=False): """ remove this plenary template """ key = None try: if not locked: key = self.get_remove_key() lock_queue.acquire(key) self.stash() remove_file(self.plenary_file, logger=self.logger) try: os.removedirs(self.plenary_directory) except OSError: pass self.removed = True # Most of the error handling routines would restore_stash... # but there's no need here if the remove failed. :) finally: if not locked: lock_queue.release(key) return
def del_cluster(session, logger, dbcluster, config): cluster = str(dbcluster.name) if hasattr(dbcluster, 'members') and dbcluster.members: raise ArgumentError("%s is still in use by clusters: %s." % (format(dbcluster), ", ".join([c.name for c in dbcluster.members]))) elif dbcluster.hosts: hosts = ", ".join([h.fqdn for h in dbcluster.hosts]) raise ArgumentError("%s is still in use by hosts: %s." % (format(dbcluster), hosts)) cluster_plenary = Plenary.get_plenary(dbcluster, logger=logger) resources = PlenaryCollection(logger=logger) if dbcluster.resholder: for res in dbcluster.resholder.resources: resources.append(Plenary.get_plenary(res)) domain = dbcluster.branch.name session.delete(dbcluster) session.flush() key = cluster_plenary.get_remove_key() with CompileKey.merge([key, resources.get_remove_key()]): cluster_plenary.cleanup(domain, locked=True) # And we also want to remove the profile itself profiles = config.get("broker", "profilesdir") # Only one of these should exist, but it doesn't hurt # to try to clean up both. xmlfile = os.path.join(profiles, "clusters", cluster + ".xml") remove_file(xmlfile, logger=logger) xmlgzfile = xmlfile + ".gz" remove_file(xmlgzfile, logger=logger) # And the cached template created by ant remove_file(os.path.join(config.get("broker", "quattordir"), "objects", "clusters", cluster + TEMPLATE_EXTENSION), logger=logger) resources.remove(locked=True) build_index(config, session, profiles, logger=logger) return
def del_cluster(session, logger, dbcluster, config): cluster = str(dbcluster.name) if hasattr(dbcluster, 'members') and dbcluster.members: raise ArgumentError( "%s is still in use by clusters: %s." % (format(dbcluster), ", ".join([c.name for c in dbcluster.members]))) elif dbcluster.hosts: hosts = ", ".join([h.fqdn for h in dbcluster.hosts]) raise ArgumentError("%s is still in use by hosts: %s." % (format(dbcluster), hosts)) cluster_plenary = Plenary.get_plenary(dbcluster, logger=logger) resources = PlenaryCollection(logger=logger) if dbcluster.resholder: for res in dbcluster.resholder.resources: resources.append(Plenary.get_plenary(res)) domain = dbcluster.branch.name session.delete(dbcluster) session.flush() key = cluster_plenary.get_remove_key() with CompileKey.merge([key, resources.get_remove_key()]): cluster_plenary.cleanup(domain, locked=True) # And we also want to remove the profile itself profiles = config.get("broker", "profilesdir") # Only one of these should exist, but it doesn't hurt # to try to clean up both. xmlfile = os.path.join(profiles, "clusters", cluster + ".xml") remove_file(xmlfile, logger=logger) xmlgzfile = xmlfile + ".gz" remove_file(xmlgzfile, logger=logger) # And the cached template created by ant remove_file(os.path.join(config.get("broker", "quattordir"), "objects", "clusters", cluster + TEMPLATE_EXTENSION), logger=logger) resources.remove(locked=True) build_index(config, session, profiles, logger=logger) return
run_git(command, path=temprepo, logger=logger, loglevel=CLIENT_INFO) # FIXME: Run tests before pushing back to template-king if rebase: target_ref = "+" + dbsandbox.name else: target_ref = dbsandbox.name run_git(["push", "origin", target_ref], path=temprepo, logger=logger) except ProcessException, e: raise ArgumentError("\n%s%s" % (e.out, e.err)) finally: remove_file(filename, logger=logger) remove_dir(tempdir, logger=logger) client_command = "git fetch" if not sync or not dbsandbox.autosync: return client_command for domain in dbsandbox.trackers: if not domain.autosync: continue try: sync_domain(domain, logger=logger) except ProcessException, e: logger.warn("Error syncing domain %s: %s" % (domain.name, e)) return client_command
ref = "HEAD:%s" % (dbsandbox.name) command = ["pull", filename, ref] if rebase: command.append("--force") run_git(command, path=temprepo, logger=logger, loglevel=CLIENT_INFO) # FIXME: Run tests before pushing back to template-king if rebase: target_ref = "+" + dbsandbox.name else: target_ref = dbsandbox.name run_git(["push", "origin", target_ref], path=temprepo, logger=logger) except ProcessException, e: raise ArgumentError("\n%s%s" % (e.out, e.err)) finally: remove_file(filename, logger=logger) remove_dir(tempdir, logger=logger) client_command = "git fetch" if not sync or not dbsandbox.autosync: return client_command for domain in dbsandbox.trackers: if not domain.autosync: continue try: sync_domain(domain, logger=logger) except ProcessException, e: logger.warn("Error syncing domain %s: %s" % (domain.name, e)) return client_command
def render(self, session, logger, hostname, **arguments): # removing the plenary host requires a compile lock, however # we want to avoid deadlock by the fact that we're messing # with two locks here, so we want to be careful. We grab the # plenaryhost early on (in order to get the filenames filled # in from the db info before we delete it from the db. We then # hold onto those references until we've completed the db # cleanup and if all of that is successful, then we delete the # plenary file (which doesn't require re-evaluating any stale # db information) after we've released the delhost lock. delplenary = False # Any service bindings that we need to clean up afterwards bindings = PlenaryCollection(logger=logger) resources = PlenaryCollection(logger=logger) with DeleteKey("system", logger=logger) as key: # Check dependencies, translate into user-friendly message dbhost = hostname_to_host(session, hostname) host_plenary = Plenary.get_plenary(dbhost, logger=logger) domain = dbhost.branch.name deps = get_host_dependencies(session, dbhost) if (len(deps) != 0): deptext = "\n".join([" %s" % d for d in deps]) raise ArgumentError("Cannot delete host %s due to the " "following dependencies:\n%s." % (hostname, deptext)) archetype = dbhost.archetype.name dbmachine = dbhost.machine oldinfo = DSDBRunner.snapshot_hw(dbmachine) ip = dbmachine.primary_ip fqdn = dbmachine.fqdn for si in dbhost.services_used: plenary = PlenaryServiceInstanceServer(si) bindings.append(plenary) logger.info("Before deleting host '%s', removing binding '%s'" % (fqdn, si.cfg_path)) del dbhost.services_used[:] if dbhost.resholder: for res in dbhost.resholder.resources: resources.append(Plenary.get_plenary(res)) # In case of Zebra, the IP may be configured on multiple interfaces for iface in dbmachine.interfaces: if ip in iface.addresses: iface.addresses.remove(ip) if dbhost.cluster: dbcluster = dbhost.cluster dbcluster.hosts.remove(dbhost) set_committed_value(dbhost, '_cluster', None) dbcluster.validate() dbdns_rec = dbmachine.primary_name dbmachine.primary_name = None dbmachine.host = None session.delete(dbhost) delete_dns_record(dbdns_rec) session.flush() delplenary = True if dbmachine.vm_container: bindings.append(Plenary.get_plenary(dbmachine.vm_container)) if archetype != 'aurora' and ip is not None: dsdb_runner = DSDBRunner(logger=logger) dsdb_runner.update_host(dbmachine, oldinfo) dsdb_runner.commit_or_rollback("Could not remove host %s from " "DSDB" % hostname) if archetype == 'aurora': logger.client_info("WARNING: removing host %s from AQDB and " "*not* changing DSDB." % hostname) # Past the point of no return... commit the transaction so # that we can free the delete lock. session.commit() # Only if we got here with no exceptions do we clean the template # Trying to clean up after any errors here is really difficult # since the changes to dsdb have already been made. if (delplenary): key = host_plenary.get_remove_key() with CompileKey.merge([key, bindings.get_write_key(), resources.get_remove_key()]) as key: host_plenary.cleanup(domain, locked=True) # And we also want to remove the profile itself profiles = self.config.get("broker", "profilesdir") # Only one of these should exist, but it doesn't hurt # to try to clean up both. xmlfile = os.path.join(profiles, fqdn + ".xml") remove_file(xmlfile, logger=logger) xmlgzfile = xmlfile + ".gz" remove_file(xmlgzfile, logger=logger) # And the cached template created by ant remove_file(os.path.join(self.config.get("broker", "quattordir"), "objects", fqdn + TEMPLATE_EXTENSION), logger=logger) bindings.write(locked=True) resources.remove(locked=True) build_index(self.config, session, profiles, logger=logger) return
def render(self, session, logger, hostname, **arguments): # removing the plenary host requires a compile lock, however # we want to avoid deadlock by the fact that we're messing # with two locks here, so we want to be careful. We grab the # plenaryhost early on (in order to get the filenames filled # in from the db info before we delete it from the db. We then # hold onto those references until we've completed the db # cleanup and if all of that is successful, then we delete the # plenary file (which doesn't require re-evaluating any stale # db information) after we've released the delhost lock. delplenary = False # Any service bindings that we need to clean up afterwards bindings = PlenaryCollection(logger=logger) resources = PlenaryCollection(logger=logger) with DeleteKey("system", logger=logger) as key: # Check dependencies, translate into user-friendly message dbhost = hostname_to_host(session, hostname) host_plenary = Plenary.get_plenary(dbhost, logger=logger) domain = dbhost.branch.name deps = get_host_dependencies(session, dbhost) if (len(deps) != 0): deptext = "\n".join([" %s" % d for d in deps]) raise ArgumentError("Cannot delete host %s due to the " "following dependencies:\n%s." % (hostname, deptext)) archetype = dbhost.archetype.name dbmachine = dbhost.machine oldinfo = DSDBRunner.snapshot_hw(dbmachine) ip = dbmachine.primary_ip fqdn = dbmachine.fqdn for si in dbhost.services_used: plenary = PlenaryServiceInstanceServer(si) bindings.append(plenary) logger.info( "Before deleting host '%s', removing binding '%s'" % (fqdn, si.cfg_path)) del dbhost.services_used[:] if dbhost.resholder: for res in dbhost.resholder.resources: resources.append(Plenary.get_plenary(res)) # In case of Zebra, the IP may be configured on multiple interfaces for iface in dbmachine.interfaces: if ip in iface.addresses: iface.addresses.remove(ip) if dbhost.cluster: dbcluster = dbhost.cluster dbcluster.hosts.remove(dbhost) set_committed_value(dbhost, '_cluster', None) dbcluster.validate() dbdns_rec = dbmachine.primary_name dbmachine.primary_name = None dbmachine.host = None session.delete(dbhost) delete_dns_record(dbdns_rec) session.flush() delplenary = True if dbmachine.vm_container: bindings.append(Plenary.get_plenary(dbmachine.vm_container)) if archetype != 'aurora' and ip is not None: dsdb_runner = DSDBRunner(logger=logger) dsdb_runner.update_host(dbmachine, oldinfo) dsdb_runner.commit_or_rollback("Could not remove host %s from " "DSDB" % hostname) if archetype == 'aurora': logger.client_info("WARNING: removing host %s from AQDB and " "*not* changing DSDB." % hostname) # Past the point of no return... commit the transaction so # that we can free the delete lock. session.commit() # Only if we got here with no exceptions do we clean the template # Trying to clean up after any errors here is really difficult # since the changes to dsdb have already been made. if (delplenary): key = host_plenary.get_remove_key() with CompileKey.merge( [key, bindings.get_write_key(), resources.get_remove_key()]) as key: host_plenary.cleanup(domain, locked=True) # And we also want to remove the profile itself profiles = self.config.get("broker", "profilesdir") # Only one of these should exist, but it doesn't hurt # to try to clean up both. xmlfile = os.path.join(profiles, fqdn + ".xml") remove_file(xmlfile, logger=logger) xmlgzfile = xmlfile + ".gz" remove_file(xmlgzfile, logger=logger) # And the cached template created by ant remove_file(os.path.join( self.config.get("broker", "quattordir"), "objects", fqdn + TEMPLATE_EXTENSION), logger=logger) bindings.write(locked=True) resources.remove(locked=True) build_index(self.config, session, profiles, logger=logger) return