def _stop_dnsmasq(self): # Shutdown dnsmasq which is typically used by nova-network # to provide dhcp leases and since nova currently doesn't # seem to shut them down itself (why not?) we have to do it for it.. # # TODO(harlowja) file a bug to get that fixed... to_kill = [] for proc in psutil.process_iter(): if proc.name.find("dnsmasq") == -1: continue cwd = '' cmdline = '' with sh.Rooted(True): cwd = proc.getcwd() cmdline = " ".join(proc.cmdline) to_try = False for t in [cwd, cmdline]: if t.lower().find("nova") != -1: to_try = True if to_try: to_kill.append(proc.pid) if len(to_kill): utils.log_iterable( to_kill, header= "Killing leftover nova dnsmasq processes with process ids", logger=LOG) for pid in to_kill: with sh.Rooted(True): sh.kill(pid)
def stop(self, app_name): trace_dir = self.runtime.get_option('trace_dir') if not sh.isdir(trace_dir): msg = "No trace directory found from which to stop: %s" % (app_name) raise excp.StopException(msg) with sh.Rooted(True): fn_name = FORK_TEMPL % (app_name) (pid_file, stderr_fn, stdout_fn) = self._form_file_names(fn_name) pid = self._extract_pid(pid_file) if not pid: msg = "Could not extract a valid pid from %s" % (pid_file) raise excp.StopException(msg) (killed, attempts) = sh.kill(pid) # Trash the files if it worked if killed: LOG.debug("Killed pid %s after %s attempts." % (pid, attempts)) LOG.debug("Removing pid file %s" % (pid_file)) sh.unlink(pid_file) LOG.debug("Removing stderr file %r" % (stderr_fn)) sh.unlink(stderr_fn) LOG.debug("Removing stdout file %r" % (stdout_fn)) sh.unlink(stdout_fn) trace_fn = tr.trace_filename(trace_dir, fn_name) if sh.isfile(trace_fn): LOG.debug("Removing %r trace file %r" % (app_name, trace_fn)) sh.unlink(trace_fn) else: msg = "Could not stop %r after %s attempts" % (app_name, attempts) raise excp.StopException(msg)
def get_available(self): base = Helper._get_yum_base() with sh.Rooted(True): pkgs = base.doPackageLists() avail = list(pkgs.available) avail.extend(pkgs.installed) return avail
def _make_yum_base(): global _yum_base if _yum_base is None: # This seems needed... # otherwise 'cannot open Packages database in /var/lib/rpm' starts to happen with sh.Rooted(True): _yum_base = YumBase() _yum_base.setCacheDir(force=True) return _yum_base
def _get_yum_base(): if Helper._yum_base is None: # This 'root' seems needed... # otherwise 'cannot open Packages database in /var/lib/rpm' starts to happen with sh.Rooted(True): _yum_base = YumBase() _yum_base.setCacheDir(force=True) Helper._yum_base = _yum_base return Helper._yum_base
def clear_domains(self, virt_type, inst_prefix): libvirt = None try: # A late import is done since this code could be used before libvirt is actually # installed, and that will cause the top level python import to fail which will # make anvil not work, so import it dynamically to bypass the previous mechanism libvirt = importer.import_module('libvirt') except RuntimeError as e: pass if not libvirt: LOG.warn( "Could not clear out libvirt domains, libvirt not available for python." ) return virt_protocol = LIBVIRT_PROTOCOL_MAP.get(virt_type) if not virt_protocol: LOG.warn( "Could not clear out libvirt domains, no known protocol for virt type: %s", colorizer.quote(virt_type)) return with sh.Rooted(True): LOG.info( "Attempting to clear out leftover libvirt domains using protocol: %s", colorizer.quote(virt_protocol)) try: self.restart_service() self.wait_active() except (excp.StartException, IOError) as e: LOG.warn("Could not restart the libvirt daemon due to: %s", e) return try: conn = libvirt.open(virt_protocol) except libvirt.libvirtError as e: LOG.warn( "Could not connect to libvirt using protocol %s due to: %s", colorizer.quote(virt_protocol), e) return with contextlib.closing(conn) as ch: try: defined_domains = ch.listDefinedDomains() kill_domains = list() for domain in defined_domains: if domain.startswith(inst_prefix): kill_domains.append(domain) if kill_domains: utils.log_iterable( kill_domains, logger=LOG, header="Found %s old domains to destroy" % (len(kill_domains))) for domain in sorted(kill_domains): self._destroy_domain(libvirt, ch, domain) except libvirt.libvirtError, e: LOG.warn("Could not clear out libvirt domains due to: %s", e)
def _begin_start(self, app_name, app_pth, app_wkdir, args): fn_name = FORK_TEMPL % (app_name) (pid_fn, stderr_fn, stdout_fn) = self._form_file_names(fn_name) trace_info = dict() trace_info[PID_FN] = pid_fn trace_info[STDERR_FN] = stderr_fn trace_info[STDOUT_FN] = stdout_fn trace_info[ARGS] = json.dumps(args) trace_fn = self._do_trace(fn_name, trace_info) LOG.debug("Forking %r by running command %r with args (%s)" % (app_name, app_pth, " ".join(args))) with sh.Rooted(True): sh.fork(app_pth, app_wkdir, pid_fn, stdout_fn, stderr_fn, *args) return trace_fn
def _configure_db_confs(self): LOG.info("Fixing up %s mysql configs.", colorizer.quote(self.distro.name)) new_lines = [] for line in sh.load_file(DBInstaller.MYSQL_CONF).splitlines(): if line.startswith('skip-grant-tables'): new_lines.append('#' + line) elif line.startswith('bind-address'): new_lines.append('#' + line) new_lines.append('bind-address = 0.0.0.0') else: new_lines.append(line) with sh.Rooted(True): sh.write_file_and_backup(DBInstaller.MYSQL_CONF, utils.joinlinesep(*new_lines))
def _setup_logs(self, clear=False): log_fns = [self.access_log, self.error_log] utils.log_iterable(log_fns, logger=LOG, header="Adjusting %s log files" % (len(log_fns))) for fn in log_fns: with sh.Rooted(True): if clear: sh.unlink(fn, True) sh.touch_file(fn, die_if_there=False, tracewriter=self.tracewriter) sh.chmod(fn, 0666) return len(log_fns)
def configure(self): configs_made = nova.NovaInstaller.configure(self) driver_canon = nhelper.canon_virt_driver(self.get_option('virt_driver')) if driver_canon == 'libvirt': # Create a libvirtd user group if not sh.group_exists('libvirtd'): cmd = ['groupadd', 'libvirtd'] sh.execute(*cmd, run_as_root=True) if not sh.isfile(LIBVIRT_POLICY_FN): contents = self._get_policy(self._get_policy_users()) with sh.Rooted(True): sh.mkdirslist(sh.dirname(LIBVIRT_POLICY_FN)) sh.write_file(LIBVIRT_POLICY_FN, contents) configs_made += 1 return configs_made
def get_installed(self, name): base = Helper._get_yum_base() # This 'root' seems needed... # otherwise 'cannot open Packages database in /var/lib/rpm' starts to happen # even though we are just doing a read-only operation, which # is pretty odd... with sh.Rooted(True): pkgs = base.doPackageLists(pkgnarrow='installed', ignore_case=True, patterns=[name]) if pkgs.installed: whats_installed = list(pkgs.installed) else: whats_installed = [] return whats_installed
def _config_fix_httpd(self): LOG.info("Fixing up: %s", colorizer.quote(HorizonInstaller.HTTPD_CONF)) (user, group) = self._get_apache_user_group() new_lines = [] for line in sh.load_file(HorizonInstaller.HTTPD_CONF).splitlines(): # Directives in the configuration files are case-insensitive, # but arguments to directives are often case sensitive... # NOTE(harlowja): we aren't handling multi-line fixups... if re.match("^\s*User\s+(.*)$", line, re.I): line = "User %s" % (user) if re.match("^\s*Group\s+(.*)$", line, re.I): line = "Group %s" % (group) if re.match("^\s*Listen\s+(.*)$", line, re.I): line = "Listen 0.0.0.0:80" new_lines.append(line) with sh.Rooted(True): sh.write_file_and_backup(HorizonInstaller.HTTPD_CONF, utils.joinlinesep(*new_lines))
def store_current_settings(c_settings): try: # Remove certain keys that just shouldn't be saved to_save = dict(c_settings) for k in ['action', 'verbose', 'dryrun']: if k in c_settings: to_save.pop(k, None) with sh.Rooted(True): with open(SETTINGS_FN, 'w') as fh: fh.write("# Anvil last used settings\n") fh.write( utils.add_header(SETTINGS_FN, utils.prettify_yaml(to_save))) fh.flush() (uid, gid) = sh.get_suids() sh.chown(SETTINGS_FN, uid, gid) except Exception as e: LOG.debug("Failed writing to %s due to %s", SETTINGS_FN, e)
def _fix_log_dir(self): # This seems needed... # # Due to the following: # <<< Restarting rabbitmq-server: RabbitMQ is not running # <<< sh: /var/log/rabbitmq/startup_log: Permission denied # <<< FAILED - check /var/log/rabbitmq/startup_{log, _err} # # See: http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2011-March/011916.html # This seems like a bug, since we are just using service init and service restart... # And not trying to run this service directly... base_dir = sh.joinpths("/var/log", 'rabbitmq') if sh.isdir(base_dir): with sh.Rooted(True): # Seems like we need root perms to list that directory... for fn in sh.listdir(base_dir): if re.match("(.*?)(err|log)$", fn, re.I): sh.chmod(sh.joinpths(base_dir, fn), 0666)
def stop(self, app_name): # The location of the pid file should be in the attached # runtimes trace directory, so see if we can find said file # and then attempt to kill the pid that exists in that file # which if succesffully will signal to the rest of this code # that we can go through and cleanup the other remnants of said # pid such as the stderr/stdout files that were being written to... trace_dir = self.runtime.get_option('trace_dir') if not sh.isdir(trace_dir): msg = "No trace directory found from which to stop: %r" % (app_name) raise excp.StopException(msg) with sh.Rooted(True): fork_fns = self._form_file_names(app_name) skip_kill = True pid = None try: pid = fork_fns.extract_pid() skip_kill = False except IOError as e: if e.errno == errno.ENOENT: pass else: skip_kill = False if not skip_kill and pid is None: msg = "Could not extract a valid pid from %r" % (fork_fns.pid) raise excp.StopException(msg) # Bother trying to kill said process? if not skip_kill: (killed, attempts) = sh.kill(pid) else: (killed, attempts) = (True, 0) # Trash the files if it worked if killed: if not skip_kill: LOG.debug("Killed pid '%s' after %s attempts.", pid, attempts) for leftover_fn in fork_fns.as_list(): if sh.exists(leftover_fn): LOG.debug("Removing forking related file %r", (leftover_fn)) sh.unlink(leftover_fn) else: msg = "Could not stop %r after %s attempts" % (app_name, attempts) raise excp.StopException(msg)
def get_installed(name, version=None): # This seems needed... # otherwise 'cannot open Packages database in /var/lib/rpm' starts to happen with sh.Rooted(True): yb = _make_yum_base() pkg_obj = yb.doPackageLists(pkgnarrow='installed', ignore_case=True, patterns=[name]) whats_installed = pkg_obj.installed if not whats_installed: return None # Compare whats installed to a fake package that will # represent what might be installed... fake_pkg = PackageObject() fake_pkg.name = name if version: fake_pkg.version = str(version) for installed_pkg in whats_installed: if installed_pkg.verGE(fake_pkg): return installed_pkg return None
def _begin_start(self, app_name, app_pth, app_wkdir, args): fork_fns = self._form_file_names(app_name) trace_fn = fork_fns.trace # Ensure all arguments for this app in string format args = [str(i) for i in args if i is not None] if trace_fn: # Not needed, but useful to know where the files are located at # # TODO(harlowja): use this info instead of forming the filenames # repeatly trace_info = {} trace_info.update(fork_fns.as_dict()) # Useful to know what args were sent along trace_info[ARGS] = json.dumps(args) run_trace = tr.TraceWriter(trace_fn) for (k, v) in trace_info.items(): if v is not None: run_trace.trace(k, v) LOG.debug("Forking %r by running command %r with args (%s)" % (app_name, app_pth, " ".join(args))) with sh.Rooted(True): sh.fork(app_pth, app_wkdir, fork_fns.pid, fork_fns.stdout, fork_fns.stderr, *args) return trace_fn
def ensure_anvil_dir(): if not sh.isdir(ANVIL_DIR): with sh.Rooted(True): os.makedirs(ANVIL_DIR) (uid, gid) = sh.get_suids() sh.chown_r(ANVIL_DIR, uid, gid)
def ensure_anvil_dirs(): for d in ["/etc/anvil/", '/usr/share/anvil/']: with sh.Rooted(True): sh.mkdir(d, adjust_suids=True)