def test_check_exit_code_boolean(self): processutils.execute('/usr/bin/env', 'false', check_exit_code=False) self.assertRaises(processutils.ProcessExecutionError, processutils.execute, '/usr/bin/env', 'false', check_exit_code=True)
def configure_add(self): """ Configure the Store to use the stored configuration options Any store that needs special configuration should implement this method. If the store was not able to successfully configure itself, it should raise `exceptions.BadStoreConfiguration` """ try: chunk_size = self.conf.glance_store.sheepdog_store_chunk_size self.chunk_size = chunk_size * units.Mi self.READ_CHUNKSIZE = self.chunk_size self.WRITE_CHUNKSIZE = self.READ_CHUNKSIZE self.addr = self.conf.glance_store.sheepdog_store_address self.port = self.conf.glance_store.sheepdog_store_port except cfg.ConfigFileValueError as e: reason = _("Error in store configuration: %s") % e LOG.error(reason) raise exceptions.BadStoreConfiguration(store_name='sheepdog', reason=reason) try: processutils.execute("collie", shell=True) except processutils.ProcessExecutionError as exc: reason = _("Error in store configuration: %s") % exc LOG.error(reason) raise exceptions.BadStoreConfiguration(store_name='sheepdog', reason=reason)
def test_check_exit_code_list(self): processutils.execute('/usr/bin/env', 'sh', '-c', 'exit 101', check_exit_code=(101, 102)) processutils.execute('/usr/bin/env', 'sh', '-c', 'exit 102', check_exit_code=(101, 102)) self.assertRaises(processutils.ProcessExecutionError, processutils.execute, '/usr/bin/env', 'sh', '-c', 'exit 103', check_exit_code=(101, 102)) self.assertRaises(processutils.ProcessExecutionError, processutils.execute, '/usr/bin/env', 'sh', '-c', 'exit 0', check_exit_code=(101, 102))
def _destroy_file(volume): message = _('Could not destroy volume on any configured REST server.') volname = volume['name'] with handle_process_execution_error( message=message, info_message=_LI('Error destroying Volume %s.') % volname, reraise=exception.VolumeBackendAPIException(data=message)): cmd = 'echo ' + volume['name'] + ' > /sys/class/srb/destroy' putils.execute('/bin/sh', '-c', cmd, root_helper='sudo', run_as_root=True)
def test_execute_with_callback(self): on_execute_callback = mock.Mock() on_completion_callback = mock.Mock() processutils.execute("/bin/true") self.assertEqual(0, on_execute_callback.call_count) self.assertEqual(0, on_completion_callback.call_count) processutils.execute("/bin/true", on_execute=on_execute_callback, on_completion=on_completion_callback) self.assertEqual(1, on_execute_callback.call_count) self.assertEqual(1, on_completion_callback.call_count)
def _setup_urls(self): if not self.base_urls: message = _("No url configured") raise exception.VolumeBackendAPIException(data=message) with handle_process_execution_error( message=_LE('Cound not setup urls on the Block Driver.'), info_message=_LI('Error creating Volume'), reraise=False): cmd = 'echo ' + self.base_urls + ' > /sys/class/srb/add_urls' putils.execute('sh', '-c', cmd, root_helper='sudo', run_as_root=True) self.urls_setup = True
def _extend_file(self, volume, new_size): message = _('Could not extend volume on any configured REST server.') with handle_process_execution_error( message=message, info_message=(_LI('Error extending Volume %s.') % volume['name']), reraise=exception.VolumeBackendAPIException(data=message)): size = self._size_int(new_size) * self.OVER_ALLOC_RATIO cmd = 'echo ' + volume['name'] + ' ' cmd += '%dG' % size cmd += ' > /sys/class/srb/extend' putils.execute('/bin/sh', '-c', cmd, root_helper='sudo', run_as_root=True)
def execute(*cmd, **kwargs): """Convenience wrapper around oslo's execute() method. :param cmd: Passed to processutils.execute. :param use_standard_locale: True | False. Defaults to False. If set to True, execute command with standard locale added to environment variables. :returns: (stdout, stderr) from process execution :raises: UnknownArgumentError :raises: ProcessExecutionError """ use_standard_locale = kwargs.pop('use_standard_locale', False) if use_standard_locale: env = kwargs.pop('env_variables', os.environ.copy()) env['LC_ALL'] = 'C' kwargs['env_variables'] = env if kwargs.get('run_as_root') and 'root_helper' not in kwargs: kwargs['root_helper'] = _get_root_helper() result = processutils.execute(*cmd, **kwargs) LOG.debug('Execution completed, command line is "%s"', ' '.join(map(str, cmd))) LOG.debug('Command stdout is: "%s"' % result[0]) LOG.debug('Command stderr is: "%s"' % result[1]) return result
def get_all_physical_volumes(root_helper, vg_name=None): """Static method to get all PVs on a system. :param root_helper: root_helper to use for execute :param vg_name: optional, gathers info for only the specified VG :returns: List of Dictionaries with PV info """ cmd = [ 'env', 'LC_ALL=C', 'pvs', '--noheadings', '--unit=g', '-o', 'vg_name,name,size,free', '--separator', ':', '--nosuffix' ] (out, _err) = putils.execute(*cmd, root_helper=root_helper, run_as_root=True) pvs = out.split() if vg_name is not None: pvs = [pv for pv in pvs if vg_name == pv.split(':')[0]] pv_list = [] for pv in pvs: fields = pv.split(':') pv_list.append({ 'vg': fields[0], 'name': fields[1], 'size': float(fields[2]), 'available': float(fields[3]) }) return pv_list
def _update_info_from_dpkg(self): LOG.debug('Trying dpkg-query command.') try: _vendor = None out, err = putils.execute("dpkg-query", "-W", "-f='${Version}'", self.PACKAGE_NAME) if not out: LOG.info(_LI('No dpkg-query info found for %(pkg)s package.') % {'pkg': self.PACKAGE_NAME}) return False # debian format: [epoch:]upstream_version[-debian_revision] deb_version = out # in case epoch or revision is missing, copy entire string _release = deb_version if ':' in deb_version: deb_epoch, upstream_version = deb_version.split(':') _release = upstream_version if '-' in deb_version: deb_revision = deb_version.split('-')[1] _vendor = deb_revision self._release = _release if _vendor: self._vendor = _vendor return True except Exception as e: LOG.info(_LI('Could not run dpkg-query command: %(msg)s.') % { 'msg': e}) return False
def get_all_physical_volumes(root_helper, vg_name=None): """Static method to get all PVs on a system. :param root_helper: root_helper to use for execute :param vg_name: optional, gathers info for only the specified VG :returns: List of Dictionaries with PV info """ cmd = ['env', 'LC_ALL=C', 'pvs', '--noheadings', '--unit=g', '-o', 'vg_name,name,size,free', '--separator', ':', '--nosuffix'] (out, _err) = putils.execute(*cmd, root_helper=root_helper, run_as_root=True) pvs = out.split() if vg_name is not None: pvs = [pv for pv in pvs if vg_name == pv.split(':')[0]] pv_list = [] for pv in pvs: fields = pv.split(':') pv_list.append({'vg': fields[0], 'name': fields[1], 'size': float(fields[2]), 'available': float(fields[3])}) return pv_list
def _create_file(self, volume): message = _('Could not create volume on any configured REST server.') with handle_process_execution_error( message=message, info_message=_LI('Error creating Volume %s.') % volume['name'], reraise=exception.VolumeBackendAPIException(data=message)): size = self._size_int(volume['size']) * self.OVER_ALLOC_RATIO cmd = 'echo ' + volume['name'] + ' ' cmd += '%dG' % size cmd += ' > /sys/class/srb/create' putils.execute('/bin/sh', '-c', cmd, root_helper='sudo', run_as_root=True) return self._set_device_path(volume)
def _hpssacli(*args): """Wrapper function for executing hpssacli command.""" try: stdout, stderr = processutils.execute("hpssacli", *args) except (OSError, processutils.ProcessExecutionError) as e: raise exception.HPSSAOperationError(reason=e) return stdout, stderr
def test_with_env_variables(self): env_vars = {'SUPER_UNIQUE_VAR': 'The answer is 42'} out, err = processutils.execute('/usr/bin/env', env_variables=env_vars) self.assertEqual(type(out), str) self.assertEqual(type(err), str) self.assertIn('SUPER_UNIQUE_VAR=The answer is 42', out)
def test_as_root(self): # For the following two tests: processutils.execute() does not # prepend the root_helper if we are already running with root privs, # so add it as the first argument to be certain. out, err = processutils.execute('echo', 'a', 'b', 'c', run_as_root=True, root_helper='echo') self.assertIn('a b c', six.text_type(out))
def _do_detach(self, volume, vg): devname = self._device_name(volume) volname = self._get_volname(volume) cmd = 'echo ' + devname + ' > /sys/class/srb/detach' try: putils.execute('/bin/sh', '-c', cmd, root_helper='sudo', run_as_root=True) except putils.ProcessExecutionError: with excutils.save_and_reraise_exception(reraise=True): try: with patched(lvm.LVM, 'activate_lv', self._activate_lv): vg.activate_lv(volname) self._do_deactivate(volume, vg) except putils.ProcessExecutionError: LOG.warning(_LW('All attempts to recover failed detach ' 'of %(volume)s failed.') % {'volume': volname})
def test_no_retry_on_success(self): fd, tmpfilename = tempfile.mkstemp() _, tmpfilename2 = tempfile.mkstemp() try: fp = os.fdopen(fd, 'w+') fp.write("""#!/bin/sh # If we've already run, bail out. grep -q foo "$1" && exit 1 # Mark that we've run before. echo foo > "$1" # Check that stdin gets passed correctly. grep foo """) fp.close() os.chmod(tmpfilename, 0o755) processutils.execute(tmpfilename, tmpfilename2, process_input=b'foo', attempts=2) finally: os.unlink(tmpfilename) os.unlink(tmpfilename2)
def _attach_file(self, volume): name = self._get_volname(volume) devname = self._device_name(volume) LOG.debug('Attaching volume %s as %s', name, devname) count = self._get_attached_count(volume) if count == 0: message = (_('Could not attach volume %(vol)s as %(dev)s ' 'on system.') % {'vol': name, 'dev': devname}) with handle_process_execution_error( message=message, info_message=_LI('Error attaching Volume'), reraise=exception.VolumeBackendAPIException(data=message)): cmd = 'echo ' + name + ' ' + devname cmd += ' > /sys/class/srb/attach' putils.execute('/bin/sh', '-c', cmd, root_helper='sudo', run_as_root=True) else: LOG.debug('Volume %s already attached', name) self._increment_attached_count(volume)
def _run_command(self, command, data, *params): cmd = ("collie vdi %(command)s -a %(addr)s -p %(port)d %(name)s " "%(params)s" % {"command": command, "addr": self.addr, "port": self.port, "name": self.name, "params": " ".join(map(str, params))}) try: return processutils.execute( cmd, process_input=data, shell=True)[0] except processutils.ProcessExecutionError as exc: LOG.error(exc) raise glance_store.BackendException(exc)
def get_lv_info(root_helper, vg_name=None, lv_name=None): """Retrieve info about LVs (all, in a VG, or a single LV). :param root_helper: root_helper to use for execute :param vg_name: optional, gathers info for only the specified VG :param lv_name: optional, gathers info for only the specified LV :returns: List of Dictionaries with LV info """ cmd = [ 'env', 'LC_ALL=C', 'lvs', '--noheadings', '--unit=g', '-o', 'vg_name,name,size', '--nosuffix' ] if lv_name is not None and vg_name is not None: cmd.append("%s/%s" % (vg_name, lv_name)) elif vg_name is not None: cmd.append(vg_name) lvs_start = time.time() try: (out, _err) = putils.execute(*cmd, root_helper=root_helper, run_as_root=True) except putils.ProcessExecutionError as err: with excutils.save_and_reraise_exception(reraise=True) as ctx: if "not found" in err.stderr: ctx.reraise = False msg = _LI("'Not found' when querying LVM info. " "(vg_name=%(vg)s, lv_name=%(lv)s") LOG.info(msg, {'vg': vg_name, 'lv': lv_name}) out = None total_time = time.time() - lvs_start if total_time > 60: LOG.warning(_LW('Took %s seconds to get logical volume info.'), total_time) lv_list = [] if out is not None: volumes = out.split() for vg, name, size in itertools.izip(*[iter(volumes)] * 3): lv_list.append({"vg": vg, "name": name, "size": size}) return lv_list
def _update_info_from_rpm(self): LOG.debug('Trying rpm command.') try: out, err = putils.execute("rpm", "-qa", "--queryformat", "'%{version}\t%{release}\t%{vendor}'", self.PACKAGE_NAME) if not out: LOG.info(_LI('No rpm info found for %(pkg)s package.') % { 'pkg': self.PACKAGE_NAME}) return False parts = out.split() self._version = parts[0] self._release = parts[1] self._vendor = ' '.join(parts[2::]) return True except Exception as e: LOG.info(_LI('Could not run rpm command: %(msg)s.') % {'msg': e}) return False
def get_lv_info(root_helper, vg_name=None, lv_name=None): """Retrieve info about LVs (all, in a VG, or a single LV). :param root_helper: root_helper to use for execute :param vg_name: optional, gathers info for only the specified VG :param lv_name: optional, gathers info for only the specified LV :returns: List of Dictionaries with LV info """ cmd = ['env', 'LC_ALL=C', 'lvs', '--noheadings', '--unit=g', '-o', 'vg_name,name,size', '--nosuffix'] if lv_name is not None and vg_name is not None: cmd.append("%s/%s" % (vg_name, lv_name)) elif vg_name is not None: cmd.append(vg_name) lvs_start = time.time() try: (out, _err) = putils.execute(*cmd, root_helper=root_helper, run_as_root=True) except putils.ProcessExecutionError as err: with excutils.save_and_reraise_exception(reraise=True) as ctx: if "not found" in err.stderr: ctx.reraise = False msg = _LI("'Not found' when querying LVM info. " "(vg_name=%(vg)s, lv_name=%(lv)s") LOG.info(msg, {'vg': vg_name, 'lv': lv_name}) out = None total_time = time.time() - lvs_start if total_time > 60: LOG.warning(_LW('Took %s seconds to get logical volume info.'), total_time) lv_list = [] if out is not None: volumes = out.split() for vg, name, size in itertools.izip(*[iter(volumes)] * 3): lv_list.append({"vg": vg, "name": name, "size": size}) return lv_list
def get_all_volume_groups(root_helper, vg_name=None): """Static method to get all VGs on a system. :param root_helper: root_helper to use for execute :param vg_name: optional, gathers info for only the specified VG :returns: List of Dictionaries with VG info """ cmd = [ 'env', 'LC_ALL=C', 'vgs', '--noheadings', '--unit=g', '-o', 'name,size,free,lv_count,uuid', '--separator', ':', '--nosuffix' ] if vg_name is not None: cmd.append(vg_name) start_vgs = time.time() (out, _err) = putils.execute(*cmd, root_helper=root_helper, run_as_root=True) total_time = time.time() - start_vgs if total_time > 60: LOG.warning(_LW('Took %s seconds to get ' 'volume groups.'), total_time) vg_list = [] if out is not None: vgs = out.split() for vg in vgs: fields = vg.split(':') vg_list.append({ 'name': fields[0], 'size': float(fields[1]), 'available': float(fields[2]), 'lv_count': int(fields[3]), 'uuid': fields[4] }) return vg_list
def get_lvm_version(root_helper): """Static method to get LVM version from system. :param root_helper: root_helper to use for execute :returns: version 3-tuple """ cmd = ['env', 'LC_ALL=C', 'vgs', '--version'] (out, _err) = putils.execute(*cmd, root_helper=root_helper, run_as_root=True) lines = out.split('\n') for line in lines: if 'LVM version' in line: version_list = line.split() # NOTE(gfidente): version is formatted as follows: # major.minor.patchlevel(library API version)[-customisation] version = version_list[2] version_filter = r"(\d+)\.(\d+)\.(\d+).*" r = re.search(version_filter, version) version_tuple = tuple(map(int, r.group(1, 2, 3))) return version_tuple
def get_all_volume_groups(root_helper, vg_name=None): """Static method to get all VGs on a system. :param root_helper: root_helper to use for execute :param vg_name: optional, gathers info for only the specified VG :returns: List of Dictionaries with VG info """ cmd = ['env', 'LC_ALL=C', 'vgs', '--noheadings', '--unit=g', '-o', 'name,size,free,lv_count,uuid', '--separator', ':', '--nosuffix'] if vg_name is not None: cmd.append(vg_name) start_vgs = time.time() (out, _err) = putils.execute(*cmd, root_helper=root_helper, run_as_root=True) total_time = time.time() - start_vgs if total_time > 60: LOG.warning(_LW('Took %s seconds to get ' 'volume groups.'), total_time) vg_list = [] if out is not None: vgs = out.split() for vg in vgs: fields = vg.split(':') vg_list.append({'name': fields[0], 'size': float(fields[1]), 'available': float(fields[2]), 'lv_count': int(fields[3]), 'uuid': fields[4]}) return vg_list
def execute(*cmd, **kwargs): """Convenience wrapper around oslo's execute() method.""" return processutils.execute(*cmd, **kwargs)
def execute(*cmd, **kwargs): """Convenience wrapper around oslo's execute() method.""" if 'run_as_root' in kwargs and 'root_helper' not in kwargs: kwargs['root_helper'] = _get_root_helper() return processutils.execute(*cmd, **kwargs)
def execute(*cmd, **kw): root_helper = kw.pop('root_helper', cfg.CONF.root_helper) run_as_root = kw.pop('run_as_root', True) return processutils.execute(*cmd, run_as_root=run_as_root, root_helper=root_helper, **kw)
def test_as_root_via_shell(self): out, err = processutils.execute('a b c', run_as_root=True, root_helper='echo', shell=True) self.assertIn('a b c', six.text_type(out))
def test_as_root(self): out, err = processutils.execute('a', 'b', 'c', run_as_root=True, root_helper='echo') self.assertIn('a b c', six.text_type(out))
def test_as_root_via_shell(self): out, err = processutils.execute('echo a b c', run_as_root=True, root_helper='echo', shell=True) self.assertIn('a b c', six.text_type(out))
def execute(*cmd, **kwargs): """Convenience wrapper around oslo's execute() method.""" if 'run_as_root' in kwargs and 'root_helper' not in kwargs: kwargs['root_helper'] = get_root_helper() return processutils.execute(*cmd, **kwargs)