def check_service(self, status, which, notes=""): """ Check if the service command is available or the old init.d system has to be used. :param status: The status list with possible problems. :param which: The service to check for. :param notes: A manual not to attach. """ # TODO: This should be improved. Removing would be hard has we need execute multiple service restarts, so this # needs to work. if notes != "": notes = " (NOTE: %s)" % notes rc = 0 if self.checked_family in ("redhat", "suse"): if os.path.exists("/etc/rc.d/init.d/%s" % which): rc = utils.subprocess_call(self.logger, "/sbin/service %s status > /dev/null 2>/dev/null" % which, shell=True) if rc != 0: status.append("service %s is not running%s" % (which, notes)) return elif self.checked_family == "debian": # we still use /etc/init.d if os.path.exists("/etc/init.d/%s" % which): rc = utils.subprocess_call(self.logger, "/etc/init.d/%s status /dev/null 2>/dev/null" % which, shell=True) if rc != 0: status.append("service %s is not running%s" % (which, notes)) return else: status.append("Unknown distribution type, cannot check for running service %s" % which) return
def run(self): """ Simply hardlinks directories that are cobbler managed. This is a /very/ simple command but may grow more complex and intelligent over time. """ # FIXME: if these directories become configurable some # changes will be required here. self.logger.info( "now hardlinking to save space, this may take some time.") rc = utils.subprocess_call(self.logger, self.hardlink_cmd, shell=True) # FIXME: how about settings? (self.settings.webdir) webdir = "/var/www/cobbler" if os.path.exists("/srv/www"): webdir = "/srv/www/cobbler" rc = utils.subprocess_call( self.logger, self.hardlink + " -c -v " + webdir + "/distro_mirror /var/www/cobbler/repo_mirror", shell=True) return rc
def check_service(self, status, which, notes=""): if notes != "": notes = " (NOTE: %s)" % notes rc = 0 if self.checked_family in ("redhat", "suse"): if os.path.exists("/etc/rc.d/init.d/%s" % which): rc = utils.subprocess_call( self.logger, "/sbin/service %s status > /dev/null 2>/dev/null" % which, shell=True) if rc != 0: status.append( _("service %s is not running%s") % (which, notes)) return elif self.checked_family == "debian": # we still use /etc/init.d if os.path.exists("/etc/init.d/%s" % which): rc = utils.subprocess_call( self.logger, "/etc/init.d/%s status /dev/null 2>/dev/null" % which, shell=True) if rc != 0: status.append( _("service %s is not running%s") % (which, notes)) return else: status.append( _("Unknown distribution type, cannot check for running service %s" % which)) return
def run(api, args, logger) -> int: """ Run the trigger via this method, meaning in this case that depending on the settings dns and/or dhcp services are restarted. :param api: The api to resolve settings. :param args: This parameter is not used currently. :param logger: The logger to audit the action with. :return: The return code of the service restarts. """ settings = api.settings() which_dhcp_module = module_loader.get_module_name("dhcp", "module").strip() which_dns_module = module_loader.get_module_name("dns", "module").strip() # special handling as we don't want to restart it twice has_restarted_dnsmasq = False rc = 0 if settings.manage_dhcp: if which_dhcp_module == "managers.isc": if settings.restart_dhcp: rc = utils.subprocess_call(logger, "dhcpd -t -q", shell=True) if rc != 0: logger.error("dhcpd -t failed") return 1 dhcp_service_name = utils.dhcp_service_name() dhcp_restart_command = "service %s restart" % dhcp_service_name rc = utils.subprocess_call(logger, dhcp_restart_command, shell=True) elif which_dhcp_module == "managers.dnsmasq": if settings.restart_dhcp: rc = utils.subprocess_call(logger, "service dnsmasq restart") has_restarted_dnsmasq = True else: logger.error("unknown DHCP engine: %s" % which_dhcp_module) rc = 411 if settings.manage_dns and settings.restart_dns: if which_dns_module == "managers.bind": named_service_name = utils.named_service_name() dns_restart_command = "service %s restart" % named_service_name rc = utils.subprocess_call(logger, dns_restart_command, shell=True) elif which_dns_module == "managers.dnsmasq" and not has_restarted_dnsmasq: rc = utils.subprocess_call(logger, "service dnsmasq restart", shell=True) elif which_dns_module == "managers.dnsmasq" and has_restarted_dnsmasq: rc = 0 elif which_dns_module == "managers.ndjbdns": # N-DJBDNS picks up configuration changes automatically and does not need to be restarted. pass else: logger.error("unknown DNS engine: %s" % which_dns_module) rc = 412 return rc
def clean_link_cache(self): """ All files which are linked into the cache will be deleted so the cache can be rebuild. """ for dirtree in [os.path.join(self.bootloc, 'images'), self.settings.webdir]: cachedir = os.path.join(dirtree, '.link_cache') if os.path.isdir(cachedir): cmd = "find %s -maxdepth 1 -type f -links 1 -exec rm -f '{}' ';'" % cachedir utils.subprocess_call(cmd)
def createrepo_walker(self, repo, dirname, fnames): """ Used to run createrepo on a copied Yum mirror. :param repo: The repository object to run for. :param dirname: The directory to run in. :param fnames: Not known what this is for. """ if os.path.exists(dirname) or repo['breed'] == 'rsync': utils.remove_yum_olddata(dirname) # add any repo metadata we can use mdoptions = [] if os.path.isfile("%s/.origin/repodata/repomd.xml" % (dirname)): if HAS_LIBREPO: rd = self.librepo_getinfo("%s/.origin" % (dirname)) elif HAS_YUM: rmd = yum.repoMDObject.RepoMD( '', "%s/.origin/repodata/repomd.xml" % (dirname)) rd = rmd.repoData else: utils.die(self.logger, "yum/librepo is required to use this feature") if "group" in rd: if HAS_LIBREPO: groupmdfile = rd['group']['location_href'] else: groupmdfile = rmd.getData("group").location[1] mdoptions.append("-g %s" % groupmdfile) if "prestodelta" in rd: # need createrepo >= 0.9.7 to add deltas if utils.get_family() in ("redhat", "suse"): cmd = "/usr/bin/rpmquery --queryformat=%{VERSION} createrepo" createrepo_ver = utils.subprocess_get(self.logger, cmd) if not createrepo_ver[0:1].isdigit(): cmd = "/usr/bin/rpmquery --queryformat=%{VERSION} createrepo_c" createrepo_ver = utils.subprocess_get( self.logger, cmd) if utils.compare_versions_gt(createrepo_ver, "0.9.7"): mdoptions.append("--deltas") else: self.logger.error( "this repo has presto metadata; you must upgrade createrepo to >= 0.9.7 first and then need to resync the repo through Cobbler." ) blended = utils.blender(self.api, False, repo) flags = blended.get("createrepo_flags", "(ERROR: FLAGS)") try: cmd = "createrepo %s %s %s" % (" ".join(mdoptions), flags, pipes.quote(dirname)) utils.subprocess_call(self.logger, cmd) except: utils.log_exc(self.logger) self.logger.error("createrepo failed.") del fnames[:] # we're in the right place
def check_for_wget_curl(self, status): """ Check to make sure wget or curl is installed :param status: The status list with possible problems. """ rc_wget = utils.subprocess_call(self.logger, "wget --help") rc_curl = utils.subprocess_call(self.logger, "curl --help") if rc_wget != 0 and rc_curl != 0: status.append("Neither wget nor curl are installed and/or available in $PATH. Cobbler requires that one of these utilities be installed.")
def check_for_wget_curl(self, status): """ Check to make sure wget or curl is installed """ rc1 = utils.subprocess_call(self.logger, "which wget") rc2 = utils.subprocess_call(self.logger, "which curl") if rc1 != 0 and rc2 != 0: status.append( "Neither wget nor curl are installed and/or available in $PATH. Cobbler requires that one of these utilities be installed." )
def run(api, args, logger): settings = api.settings() manage_dhcp = str(settings.manage_dhcp).lower() manage_dns = str(settings.manage_dns).lower() restart_dhcp = str(settings.restart_dhcp).lower() restart_dns = str(settings.restart_dns).lower() which_dhcp_module = module_loader.get_module_name("dhcp", "module").strip() which_dns_module = module_loader.get_module_name("dns", "module").strip() # special handling as we don't want to restart it twice has_restarted_dnsmasq = False rc = 0 if manage_dhcp != "0": if which_dhcp_module == "manage_isc": if restart_dhcp != "0": rc = utils.subprocess_call(logger, "dhcpd -t -q", shell=True) if rc != 0: logger.error("dhcpd -t failed") return 1 dhcp_service_name = utils.dhcp_service_name(api) dhcp_restart_command = "service %s restart" % dhcp_service_name rc = utils.subprocess_call(logger, dhcp_restart_command, shell=True) elif which_dhcp_module == "manage_dnsmasq": if restart_dhcp != "0": rc = utils.subprocess_call(logger, "service dnsmasq restart") has_restarted_dnsmasq = True else: logger.error("unknown DHCP engine: %s" % which_dhcp_module) rc = 411 if manage_dns != "0" and restart_dns != "0": if which_dns_module == "manage_bind": named_service_name = utils.named_service_name(api) dns_restart_command = "service %s restart" % named_service_name rc = utils.subprocess_call(logger, dns_restart_command, shell=True) elif which_dns_module == "manage_dnsmasq" and not has_restarted_dnsmasq: rc = utils.subprocess_call(logger, "service dnsmasq restart", shell=True) elif which_dns_module == "manage_dnsmasq" and has_restarted_dnsmasq: rc = 0 elif which_dns_module == "manage_ndjbdns": # N-DJBDNS picks up configuration changes automatically and does not need to be restarted. pass else: logger.error("unknown DNS engine: %s" % which_dns_module) rc = 412 return rc
def modacl(self, isadd, isuser, who): """ Modify the acls for Cobbler on the filesystem. :param isadd: If true then the ``who`` will be added. If false then ``who`` will be removed. :type isadd: bool :param isuser: If true then the ``who`` may be a user. If false then ``who`` may be a group. :type isuser: bool :param who: The user or group to be added or removed. """ snipdir = self.settings.autoinstall_snippets_dir tftpboot = self.settings.tftpboot_location PROCESS_DIRS = { "/var/log/cobbler": "rwx", "/var/log/cobbler/tasks": "rwx", "/var/lib/cobbler": "rwx", "/etc/cobbler": "rwx", tftpboot: "rwx", "/var/lib/cobbler/triggers": "rwx" } if not snipdir.startswith("/var/lib/cobbler/"): PROCESS_DIRS[snipdir] = "r" cmd = "-R" if isadd: cmd = "%s -m" % cmd else: cmd = "%s -x" % cmd if isuser: cmd = "%s u:%s" % (cmd, who) else: cmd = "%s g:%s" % (cmd, who) for d in PROCESS_DIRS: how = PROCESS_DIRS[d] if isadd: cmd2 = "%s:%s" % (cmd, how) else: cmd2 = cmd cmd2 = "%s %s" % (cmd2, d) rc = utils.subprocess_call(self.logger, "setfacl -d %s" % cmd2, shell=True) if not rc == 0: utils.die(self.logger, "command failed") rc = utils.subprocess_call(self.logger, "setfacl %s" % cmd2, shell=True) if not rc == 0: utils.die(self.logger, "command failed")
def run(self): """ Simply hardlinks directories that are Cobbler managed. """ self.logger.info( "now hardlinking to save space, this may take some time.") utils.subprocess_call(self.hardlink_cmd, shell=True) hardlink_cmd = "%s -c -v %s/distro_mirror %s/repo_mirror" % ( self.hardlink, self.webdir, self.webdir) return utils.subprocess_call(hardlink_cmd, shell=True)
def run(api, args, logger): settings = api.settings() manage_dhcp = str(settings.manage_dhcp).lower() manage_dns = str(settings.manage_dns).lower() manage_tftpd = str(settings.manage_tftpd).lower() restart_dhcp = str(settings.restart_dhcp).lower() restart_dns = str(settings.restart_dns).lower() which_dhcp_module = module_loader.get_module_from_file( "dhcp", "module", just_name=True).strip() which_dns_module = module_loader.get_module_from_file( "dns", "module", just_name=True).strip() # special handling as we don't want to restart it twice has_restarted_dnsmasq = False rc = 0 if manage_dhcp != "0": if which_dhcp_module == "manage_isc": if restart_dhcp != "0": rc = utils.subprocess_call(logger, "dhcpd -t -q", shell=True) if rc != 0: logger.error("dhcpd -t failed") return 1 rc = utils.subprocess_call(logger, "service dhcpd restart", shell=True) elif which_dhcp_module == "manage_dnsmasq": if restart_dhcp != "0": rc = utils.subprocess_call(logger, "service dnsmasq restart") has_restarted_dnsmasq = True else: logger.error("unknown DHCP engine: %s" % which_dhcp_module) rc = 411 if manage_dns != "0" and restart_dns != "0": if which_dns_module == "manage_bind": rc = utils.subprocess_call(logger, "service named restart", shell=True) elif which_dns_module == "manage_dnsmasq" and not has_restarted_dnsmasq: rc = utils.subprocess_call(logger, "service dnsmasq restart", shell=True) elif which_dns_module == "manage_dnsmasq" and has_restarted_dnsmasq: rc = 0 else: logger.error("unknown DNS engine: %s" % which_dns_module) rc = 412 return rc
def run(api,args,logger): settings = api.settings() scm_track_enabled = str(settings.scm_track_enabled).lower() mode = str(settings.scm_track_mode).lower() if scm_track_enabled not in [ "y", "yes", "1", "true" ]: # feature disabled return 0 if mode == "git": old_dir = os.getcwd() os.chdir("/var/lib/cobbler") if os.getcwd() != "/var/lib/cobbler": raise "danger will robinson" if not os.path.exists("/var/lib/cobbler/.git"): rc = utils.subprocess_call(logger,"git init",shell=True) # FIXME: if we know the remote user of an XMLRPC call # use them as the author rc = utils.subprocess_call(logger,"git add --all config",shell=True) rc = utils.subprocess_call(logger,"git add --all kickstarts",shell=True) rc = utils.subprocess_call(logger,"git add --all snippets",shell=True) rc = utils.subprocess_call(logger,"git commit -m 'API update' --author 'cobbler <*****@*****.**>'",shell=True) os.chdir(old_dir) return 0 elif mode == "hg": # use mercurial old_dir = os.getcwd() os.chdir("/var/lib/cobbler") if os.getcwd() != "/var/lib/cobbler": raise "danger will robinson" if not os.path.exists("/var/lib/cobbler/.hg"): rc = utils.subprocess_call(logger,"hg init",shell=True) # FIXME: if we know the remote user of an XMLRPC call # use them as the user rc = utils.subprocess_call(logger,"hg add config",shell=True) rc = utils.subprocess_call(logger,"hg add kickstarts",shell=True) rc = utils.subprocess_call(logger,"hg add snippets",shell=True) rc = utils.subprocess_call(logger,"hg commit -m 'API update' --user 'cobbler <*****@*****.**>'",shell=True) os.chdir(old_dir) return 0 else: raise CX("currently unsupported SCM type: %s" % mode)
def copy_bootloaders(self): """ Copy bootloaders to the configured tftpboot directory NOTE: we support different arch's if defined in /etc/cobbler/settings. """ src = self.settings.bootloaders_dir dest = self.bootloc # unfortunately using shutils copy_tree the dest directory must not exist, # but we must not delete an already partly synced /srv/tftp dir here. # rsync is very convenient here, being very fast on an already copied folder utils.subprocess_call(self.logger, "rsync -rpt --copy-links --exclude=.cobbler_postun_cleanup {src}/ {dest}".format(src=src, dest=dest, shell=False)) src = self.settings.grubconfig_dir utils.subprocess_call(self.logger, "rsync -rpt --copy-links --exclude=README.grubconfig {src}/ {dest}".format(src=src, dest=dest, shell=False))
def run(api,args,logger): settings = api.settings() manage_dhcp = str(settings.manage_dhcp).lower() manage_dns = str(settings.manage_dns).lower() restart_bin = str(settings.restart_bin).lower() restart_dhcp = str(settings.restart_dhcp).lower() restart_dns = str(settings.restart_dns).lower() dhcpd_bin = str(settings.dhcpd_bin).lower() dhcpd_init = str(settings.dhcpd_init).lower() omapi_enabled = str(settings.omapi_enabled).lower() omapi_port = str(settings.omapi_port).lower() which_dhcp_module = module_loader.get_module_from_file("dhcp","module",just_name=True).strip() which_dns_module = module_loader.get_module_from_file("dns","module",just_name=True).strip() # special handling as we don't want to restart it twice has_restarted_dnsmasq = False rc = 0 if manage_dhcp != "0": if which_dhcp_module == "manage_isc": if not omapi_enabled in [ "1", "true", "yes", "y" ] and restart_dhcp: rc = utils.subprocess_call(logger, "%s -t -q" % dhcpd_bin, shell=True) if rc != 0: logger.error("%s -t failed" % dhcpd_bin) return 1 rc = utils.subprocess_call(logger,"%s %s restart" % (restart_bin, dhcpd_init), shell=True) elif which_dhcp_module == "manage_dnsmasq": if restart_dhcp: rc = utils.subprocess_call(logger, "/sbin/service dnsmasq restart") has_restarted_dnsmasq = True else: logger.error("unknown DHCP engine: %s" % which_dhcp_module) rc = 411 if manage_dns != "0" and restart_dns != "0": if which_dns_module == "manage_bind": rc = utils.subprocess_call(logger, "/sbin/service named restart", shell=True) elif which_dns_module == "manage_dnsmasq" and not has_restarted_dnsmasq: rc = utils.subprocess_call(logger, "/sbin/service dnsmasq restart", shell=True) elif which_dns_module == "manage_dnsmasq" and has_restarted_dnsmasq: rc = 0 else: logger.error("unknown DNS engine: %s" % which_dns_module) rc = 412 return rc
def createrepo_walker(self, repo, dirname: str, fnames): """ Used to run createrepo on a copied Yum mirror. :param repo: The repository object to run for. :param dirname: The directory to run in. :param fnames: Not known what this is for. """ if os.path.exists(dirname) or repo.breed == RepoBreeds.RSYNC: utils.remove_yum_olddata(dirname) # add any repo metadata we can use mdoptions = [] origin_path = os.path.join(dirname, ".origin") repodata_path = os.path.join(origin_path, "repodata") if os.path.isfile(os.path.join(repodata_path, "repomd.xml")): rd = self.librepo_getinfo(origin_path) if "group" in rd: groupmdfile = rd['group']['location_href'] mdoptions.append("-g %s" % os.path.join(origin_path, groupmdfile)) if "prestodelta" in rd: # need createrepo >= 0.9.7 to add deltas if utils.get_family() in ("redhat", "suse"): cmd = "/usr/bin/rpmquery --queryformat=%{VERSION} createrepo" createrepo_ver = utils.subprocess_get(cmd) if not createrepo_ver[0:1].isdigit(): cmd = "/usr/bin/rpmquery --queryformat=%{VERSION} createrepo_c" createrepo_ver = utils.subprocess_get(cmd) if utils.compare_versions_gt(createrepo_ver, "0.9.7"): mdoptions.append("--deltas") else: self.logger.error( "this repo has presto metadata; you must upgrade createrepo to >= 0.9.7 " "first and then need to resync the repo through Cobbler." ) blended = utils.blender(self.api, False, repo) flags = blended.get("createrepo_flags", "(ERROR: FLAGS)") try: cmd = "createrepo %s %s %s" % (" ".join(mdoptions), flags, pipes.quote(dirname)) utils.subprocess_call(cmd) except: utils.log_exc() self.logger.error("createrepo failed.") del fnames[:] # we're in the right place
def sync_dhcp(self): restart_dhcp = str(self.settings.restart_dhcp).lower() service_name = utils.dhcp_service_name(self.api) if restart_dhcp != "0": rc = utils.subprocess_call(self.logger, "dhcpd -t -q", shell=True) if rc != 0: error_msg = "dhcpd -t failed" self.logger.error(error_msg) raise CX(error_msg) service_restart = "service %s restart" % service_name rc = utils.subprocess_call(self.logger, service_restart, shell=True) if rc != 0: error_msg = "%s failed" % service_name self.logger.error(error_msg) raise CX(error_msg)
def wget_sync(self, repo): """ Handle mirroring of directories using wget :param repo: The repo object to sync via wget. """ repo_mirror = repo.mirror.strip() if repo.rpm_list != "" and repo.rpm_list != []: self.logger.warning( "--rpm-list is not supported for wget'd repositories") # FIXME: don't hardcode dest_path = os.path.join(self.settings.webdir + "/repo_mirror", repo.name) # FIXME: wrapper for subprocess that logs to logger cmd = "wget -N -np -r -l inf -nd -P %s %s" % (pipes.quote(dest_path), pipes.quote(repo_mirror)) rc = utils.subprocess_call(self.logger, cmd) if rc != 0: utils.die(self.logger, "cobbler reposync failed") repo_walker(dest_path, self.createrepo_walker, repo) self.create_local_file(dest_path, repo)
def update_permissions(self, repo_path): """ Verifies that permissions and contexts after an rsync are as expected. Sending proper rsync flags should prevent the need for this, though this is largely a safeguard. """ # all_path = os.path.join(repo_path, "*") owner = "root:" + utils.get_http_user() cmd1 = "chown -R " + owner + " %s" % repo_path utils.subprocess_call(self.logger, cmd1) cmd2 = "chmod -R 755 %s" % repo_path utils.subprocess_call(self.logger, cmd2)
def rsync_sync(self, repo): """ Handle copying of rsync:// and rsync-over-ssh repos. """ if not repo.mirror_locally: utils.die( self.logger, "rsync:// urls must be mirrored locally, yum cannot access them directly" ) if repo.rpm_list != "" and repo.rpm_list != []: self.logger.warning( "--rpm-list is not supported for rsync'd repositories") # FIXME: don't hardcode dest_path = os.path.join(self.settings.webdir + "/repo_mirror", repo.name) spacer = "" if not repo.mirror.startswith( "rsync://") and not repo.mirror.startswith("/"): spacer = "-e ssh" if not repo.mirror.strip().endswith("/"): repo.mirror = "%s/" % repo.mirror # FIXME: wrapper for subprocess that logs to logger cmd = "rsync -rltDv --copy-unsafe-links --delete-after %s --delete --exclude-from=/etc/cobbler/rsync.exclude %s %s" % ( spacer, pipes.quote(repo.mirror), pipes.quote(dest_path)) rc = utils.subprocess_call(self.logger, cmd) if rc != 0: utils.die(self.logger, "cobbler reposync failed") repo_walker(dest_path, self.createrepo_walker, repo) self.create_local_file(dest_path, repo)
def restart_service(self): """ This syncs the dhcp server with it's new config files. Basically this restarts the service to apply the changes. """ service_name = utils.dhcp_service_name() ret = 0 if self.settings.restart_dhcp: ret = utils.subprocess_call("dhcpd -t -q", shell=True) if ret != 0: self.logger.error("dhcpd -t failed") service_restart = "service %s restart" % service_name ret = utils.subprocess_call(service_restart, shell=True) if ret != 0: self.logger.error("%s service failed", service_name) return ret
def restart_dhcp(self, service_name): """ This syncs the dhcp server with it's new config files. Basically this restarts the service to apply the changes. :param service_name: TODO """ return_code_service_restart = 0 return_code_service_restart = utils.subprocess_call("{} -t -q".format(service_name), shell=True) if return_code_service_restart != 0: self.logger.error("Testing config - {} -t failed".format(service_name)) service_restart = "service {} restart".format(service_name) return_code_service_restart = utils.subprocess_call(service_restart, shell=True) if return_code_service_restart != 0: self.logger.error("{} service failed".format(service_name)) return return_code_service_restart
def check_service(self, status, which, notes=""): """ Check if the service command is available or the old init.d system has to be used. :param status: The status list with possible problems. :param which: The service to check for. :param notes: A manual not to attach. """ if notes != "": notes = " (NOTE: %s)" % notes return_code = 0 if utils.is_supervisord(): with ServerProxy('http://localhost:9001/RPC2') as server: process_info = server.supervisor.getProcessInfo(which) if process_info['statename'] != "RUNNING": status.append("service %s is not running%s" % (which, notes)) return elif utils.is_systemd(): return_code = utils.subprocess_call( "systemctl status %s > /dev/null 2>/dev/null" % which, shell=True) if return_code != 0: status.append("service %s is not running%s" % (which, notes)) return elif self.checked_family in ("redhat", "suse"): if os.path.exists("/etc/rc.d/init.d/%s" % which): return_code = utils.subprocess_call( "/sbin/service %s status > /dev/null 2>/dev/null" % which, shell=True) if return_code != 0: status.append("service %s is not running%s" % (which, notes)) return elif self.checked_family == "debian": # we still use /etc/init.d if os.path.exists("/etc/init.d/%s" % which): return_code = utils.subprocess_call( "/etc/init.d/%s status /dev/null 2>/dev/null" % which, shell=True) if return_code != 0: status.append("service %s is not running%s" % (which, notes)) return else: status.append( "Unknown distribution type, cannot check for running service %s" % which) return
def sync_dhcp(self): restart_dhcp = str(self.settings.restart_dhcp).lower() if restart_dhcp != "0": rc = utils.subprocess_call(self.logger, "service dnsmasq restart") if rc != 0: error_msg = "service dnsmasq restart failed" self.logger.error(error_msg) raise CX(error_msg)
def test_subprocess_call(): # Arrange # Act result = utils.subprocess_call("echo Test") # Assert assert result == 0
def modacl(self, isadd, isuser, who): snipdir = self.settings.autoinstall_snippets_dir tftpboot = self.settings.tftpboot_location PROCESS_DIRS = { "/var/log/cobbler": "rwx", "/var/log/cobbler/tasks": "rwx", "/var/lib/cobbler": "rwx", "/etc/cobbler": "rwx", tftpboot: "rwx", "/var/lib/cobbler/triggers": "rwx" } if not snipdir.startswith("/var/lib/cobbler/"): PROCESS_DIRS[snipdir] = "r" cmd = "-R" if isadd: cmd = "%s -m" % cmd else: cmd = "%s -x" % cmd if isuser: cmd = "%s u:%s" % (cmd, who) else: cmd = "%s g:%s" % (cmd, who) for d in PROCESS_DIRS: how = PROCESS_DIRS[d] if isadd: cmd2 = "%s:%s" % (cmd, how) else: cmd2 = cmd cmd2 = "%s %s" % (cmd2, d) rc = utils.subprocess_call(self.logger, "setfacl -d %s" % cmd2, shell=True) if not rc == 0: utils.die(self.logger, "command failed") rc = utils.subprocess_call(self.logger, "setfacl %s" % cmd2, shell=True) if not rc == 0: utils.die(self.logger, "command failed")
def sync_dhcp(self): """ This syncs the dhcp server with it's new config files. Basically this restarts the service to apply the changes. """ service_name = utils.dhcp_service_name() if self.settings.restart_dhcp: rc = utils.subprocess_call(self.logger, "dhcpd -t -q", shell=True) if rc != 0: error_msg = "dhcpd -t failed" self.logger.error(error_msg) raise CX(error_msg) service_restart = "service %s restart" % service_name rc = utils.subprocess_call(self.logger, service_restart, shell=True) if rc != 0: error_msg = "%s failed" % service_name self.logger.error(error_msg) raise CX(error_msg)
def rsync_sync(self, repo): """ Handle copying of rsync:// and rsync-over-ssh repos. :param repo: The repo to sync via rsync. """ if not repo.mirror_locally: utils.die("rsync:// urls must be mirrored locally, yum cannot access them directly") if repo.rpm_list != "" and repo.rpm_list != []: self.logger.warning("--rpm-list is not supported for rsync'd repositories") # FIXME: don't hardcode dest_path = os.path.join(self.settings.webdir + "/repo_mirror", repo.name) spacer = "" if not repo.mirror.startswith("rsync://") and not repo.mirror.startswith("/"): spacer = "-e ssh" if not repo.mirror.strip().endswith("/"): repo.mirror = "%s/" % repo.mirror flags = '' for x in repo.rsyncopts: if repo.rsyncopts[x]: flags += " %s %s" % (x, repo.rsyncopts[x]) else: flags += " %s" % x if flags == '': flags = self.settings.reposync_rsync_flags cmd = "rsync %s --delete-after %s --delete --exclude-from=/etc/cobbler/rsync.exclude %s %s" \ % (flags, spacer, pipes.quote(repo.mirror), pipes.quote(dest_path)) rc = utils.subprocess_call(cmd) if rc != 0: utils.die("cobbler reposync failed") # If ran in archive mode then repo should already contain all repodata and does not need createrepo run archive = False if '--archive' in flags: archive = True else: # split flags and skip all --{options} as we need to look for combined flags like -vaH fl = flags.split() for f in fl: if f.startswith('--'): pass else: if 'a' in f: archive = True break if not archive: repo_walker(dest_path, self.createrepo_walker, repo) self.create_local_file(dest_path, repo)
def run(api,args,logger): settings = api.settings() manage_dhcp = str(settings.manage_dhcp).lower() manage_dns = str(settings.manage_dns).lower() manage_tftpd = str(settings.manage_tftpd).lower() restart_dhcp = str(settings.restart_dhcp).lower() restart_dns = str(settings.restart_dns).lower() which_dhcp_module = module_loader.get_module_from_file("dhcp","module",just_name=True).strip() which_dns_module = module_loader.get_module_from_file("dns","module",just_name=True).strip() # special handling as we don't want to restart it twice has_restarted_dnsmasq = False rc = 0 if manage_dhcp != "0": if which_dhcp_module == "manage_isc": if restart_dhcp != "0": rc = utils.subprocess_call(logger, "dhcpd -t -q", shell=True) if rc != 0: logger.error("dhcpd -t failed") return 1 rc = utils.subprocess_call(logger,"service dhcpd restart", shell=True) elif which_dhcp_module == "manage_dnsmasq": if restart_dhcp != "0": rc = utils.subprocess_call(logger, "service dnsmasq restart") has_restarted_dnsmasq = True else: logger.error("unknown DHCP engine: %s" % which_dhcp_module) rc = 411 if manage_dns != "0" and restart_dns != "0": if which_dns_module == "manage_bind": rc = utils.subprocess_call(logger, "service named restart", shell=True) elif which_dns_module == "manage_dnsmasq" and not has_restarted_dnsmasq: rc = utils.subprocess_call(logger, "service dnsmasq restart", shell=True) elif which_dns_module == "manage_dnsmasq" and has_restarted_dnsmasq: rc = 0 else: logger.error("unknown DNS engine: %s" % which_dns_module) rc = 412 return rc
def run(api, args, logger): """ This method runs the trigger, meaning in this case that old puppet certs are automatically removed via puppetca. The list of args should have two elements: - 0: system or profile - 1: the name of the system or profile :param api: The api to resolve external information with. :param args: Already described above. :param logger: The logger to audit the action with. :return: "0" on success. If unsuccessful this raises an exception. """ objtype = args[0] name = args[1] if objtype != "system": return 0 settings = api.settings() if not str( settings.puppet_auto_setup).lower() in ["1", "yes", "y", "true"]: return 0 if not str(settings.remove_old_puppet_certs_automatically).lower() in [ "1", "yes", "y", "true" ]: return 0 system = api.find_system(name) system = utils.blender(api, False, system) hostname = system["hostname"] if not re.match(r'[\w-]+\..+', hostname): search_domains = system['name_servers_search'] if search_domains: hostname += '.' + search_domains[0] if not re.match(r'[\w-]+\..+', hostname): default_search_domains = system['default_name_servers_search'] if default_search_domains: hostname += '.' + default_search_domains[0] puppetca_path = settings.puppetca_path cmd = [puppetca_path, 'cert', 'clean', hostname] rc = 0 try: rc = utils.subprocess_call(logger, cmd, shell=False) except: if logger is not None: logger.warning("failed to execute %s" % puppetca_path) if rc != 0: if logger is not None: logger.warning("puppet cert removal for %s failed" % name) return 0
def check_dnsmasq_bin(self, status): """ Check if dnsmasq is installed. :param status: The status list with possible problems. """ return_code = utils.subprocess_call(self.logger, "dnsmasq --help") if return_code != 0: status.append("dnsmasq is not installed and/or in path")
def check_bind_bin(self, status): """ Check if bind is installed. :param status: The status list with possible problems. """ return_code = utils.subprocess_call(self.logger, "named -v") # it should return something like "BIND 9.6.1-P1-RedHat-9.6.1-6.P1.fc11" if return_code != 0: status.append("named is not installed and/or in path")
def sync_dhcp(self): """ This restarts the dhcp server and thus applied the newly written config files. """ if self.settings.restart_dhcp: rc = utils.subprocess_call(self.logger, "service dnsmasq restart") if rc != 0: error_msg = "service dnsmasq restart failed" self.logger.error(error_msg) raise CX(error_msg)
def run(api, args, logger): objtype = args[0] # "system" or "profile" name = args[1] # name of system or profile # ip = args[2] # ip or "?" if objtype != "system": return 0 settings = api.settings() if not str(settings.puppet_auto_setup).lower() in ["1", "yes", "y", "true"]: return 0 if not str(settings.remove_old_puppet_certs_automatically).lower() in ["1", "yes", "y", "true"]: return 0 system = api.find_system(name) system = utils.blender(api, False, system) hostname = system["hostname"] if not re.match(r'[\w-]+\..+', hostname): search_domains = system['name_servers_search'] if search_domains: hostname += '.' + search_domains[0] if not re.match(r'[\w-]+\..+', hostname): default_search_domains = system['default_name_servers_search'] if default_search_domains: hostname += '.' + default_search_domains[0] puppetca_path = settings.puppetca_path cmd = [puppetca_path, 'cert', 'clean', hostname] rc = 0 try: rc = utils.subprocess_call(logger, cmd, shell=False) except: if logger is not None: logger.warning("failed to execute %s" % puppetca_path) if rc != 0: if logger is not None: logger.warning("puppet cert removal for %s failed" % name) return 0
def run(api,args,logger): rc = utils.subprocess_call(logger, "/usr/local/bin/cobbler-replicate", shell=True) return rc
def yum_process_comps_file(self, comps_path, distro): """ When importing Fedora/EL certain parts of the install tree can also be used as yum repos containing packages that might not yet be available via updates in yum. This code identifies those areas. Existing repodata will be used as-is, but repodate is created for earlier, non-yum based, installers. """ if os.path.exists(os.path.join(comps_path, "repodata")): keeprepodata = True masterdir = "repodata" else: # older distros... masterdir = "base" keeprepodata = False # figure out what our comps file is ... self.logger.info("looking for %(p1)s/%(p2)s/*comps*.xml" % {"p1": comps_path, "p2": masterdir}) files = glob.glob("%s/%s/*comps*.xml" % (comps_path, masterdir)) if len(files) == 0: self.logger.info("no comps found here: %s" % os.path.join(comps_path, masterdir)) return # no comps xml file found # pull the filename from the longer part comps_file = files[0].split("/")[-1] try: # store the yum configs on the filesystem so we can use them later. # and configure them in the automated installation file post section, # etc counter = len(distro.source_repos) # find path segment for yum_url (changing filesystem path to http:// trailing fragment) seg = comps_path.rfind("distro_mirror") urlseg = comps_path[(seg + len("distro_mirror") + 1):] fname = os.path.join(self.settings.webdir, "distro_mirror", "config", "%s-%s.repo" % (distro.name, counter)) repo_url = "http://@@http_server@@/cobbler/distro_mirror/config/%s-%s.repo" % (distro.name, counter) repo_url2 = "http://@@http_server@@/cobbler/distro_mirror/%s" % (urlseg) distro.source_repos.append([repo_url, repo_url2]) config_dir = os.path.dirname(fname) if not os.path.exists(config_dir): os.makedirs(config_dir) # NOTE: the following file is now a Cheetah template, so it can be remapped # during sync, that's why we have the @@http_server@@ left as templating magic. # repo_url2 is actually no longer used. (?) config_file = open(fname, "w+") config_file.write("[core-%s]\n" % counter) config_file.write("name=core-%s\n" % counter) config_file.write("baseurl=http://@@http_server@@/cobbler/distro_mirror/%s\n" % (urlseg)) config_file.write("enabled=1\n") config_file.write("gpgcheck=0\n") config_file.write("priority=$yum_distro_priority\n") config_file.close() # don't run creatrepo twice -- this can happen easily for Xen and PXE, when # they'll share same repo files. if keeprepodata: self.logger.info("Keeping repodata as-is :%s/repodata" % comps_path) self.found_repos[comps_path] = 1 elif comps_path not in self.found_repos: utils.remove_yum_olddata(comps_path) cmd = "createrepo %s --groupfile %s %s" % (self.settings.createrepo_flags, os.path.join(comps_path, masterdir, comps_file), comps_path) utils.subprocess_call(self.logger, cmd, shell=True) self.found_repos[comps_path] = 1 # for older distros, if we have a "base" dir parallel with "repodata", we need to copy comps.xml up one... p1 = os.path.join(comps_path, "repodata", "comps.xml") p2 = os.path.join(comps_path, "base", "comps.xml") if os.path.exists(p1) and os.path.exists(p2): shutil.copyfile(p1, p2) except: self.logger.error("error launching createrepo (not installed?), ignoring") utils.log_exc(self.logger)