def system_info(verbose=False): def check_module(module): try: return not coreutils.modprobe(module, dry_run=True)[2] except: return False ret = {} ret['software'] = [] installed_list = all_installed() for software_inf in installed_list: v = dict( name=software_inf.name, version='.'.join([str(x) for x in software_inf.version]) ) if verbose: v['string_version'] = software_inf.string_version ret['software'].append(v) ret['os'] = {} ret['os']['version'] = '{0} {1} {2}'.format(linux.os['name'], linux.os['release'], linux.os['codename']).strip() ret['os']['string_version'] = ' '.join(platform.uname()).strip() ret['dist'] = { 'distributor': linux.os['name'].lower(), 'release': str(linux.os['release']), 'codename': linux.os['codename'] } ret['os']['arch'] = linux.os['arch'] ret['storage'] = {} ret['storage']['fstypes'] = [] for fstype in ['xfs', 'ext3', 'ext4']: try: retcode = coreutils.modprobe(fstype, dry_run=True)[1] except: retcode = 1 exe = which('mkfs.%s' % fstype) if not retcode and exe: ret['storage']['fstypes'].append(fstype) # Raid levels support detection if which('mdadm'): for module in ('raid0', 'raid1', 'raid456'): ret['storage'][module] = 1 if check_module(module) else 0 # Lvm2 support detection if which('dmsetup') and all(map(check_module, ('dm_mod', 'dm_snapshot'))): ret['storage']['lvm'] = 1 else: ret['storage']['lvm'] = 0 return ret
def system_info(verbose=False): def check_module(module): try: return not coreutils.modprobe(module, dry_run=True)[2] except: return False ret = {} ret['software'] = [] installed_list = all_installed() for software_inf in installed_list: v = dict(name=software_inf.name, version='.'.join([str(x) for x in software_inf.version])) if verbose: v['string_version'] = software_inf.string_version ret['software'].append(v) ret['os'] = {} ret['os']['version'] = '{0} {1} {2}'.format(linux.os['name'], linux.os['release'], linux.os['codename']).strip() ret['os']['string_version'] = ' '.join(platform.uname()).strip() ret['dist'] = { 'distributor': linux.os['name'].lower(), 'release': str(linux.os['release']), 'codename': linux.os['codename'] } ret['os']['arch'] = linux.os['arch'] ret['storage'] = {} ret['storage']['fstypes'] = [] for fstype in ['xfs', 'ext3', 'ext4']: try: retcode = coreutils.modprobe(fstype, dry_run=True)[1] except: retcode = 1 exe = which('mkfs.%s' % fstype) if not retcode and exe: ret['storage']['fstypes'].append(fstype) # Raid levels support detection if which('mdadm'): for module in ('raid0', 'raid1', 'raid456'): ret['storage'][module] = 1 if check_module(module) else 0 # Lvm2 support detection if which('dmsetup') and all(map(check_module, ('dm_mod', 'dm_snapshot'))): ret['storage']['lvm'] = 1 else: ret['storage']['lvm'] = 0 return ret
def _detach(self, force=False, **kwds): self._check_connection() volume_id = self.id or self._native_vol.id # Remove volume from SCSI host if self.device and \ ((self._native_vol and self._native_vol.virtualmachineid == __cloudstack__['instance_id']) or \ not self._native_vol): if linux.which('lsscsi'): scsi = coreutils.lsscsi().get(self.device) if scsi: LOG.debug('Removing device from SCSI host') name = '/sys/class/scsi_host/host{host}/device/target{host}:{bus}:{target}/{host}:{bus}:{target}:{lun}/delete'.format(**scsi) with open(name, 'w') as fp: fp.write('1') LOG.debug('Detaching volume %s', volume_id) try: self._conn.detachVolume(volume_id) except Exception, e: if 'not attached' in str(e) or \ 'Please specify a VM that is either running or stopped' in str(e): pass else: raise
def mongodb_software_info(): try: mongod = which('mongod') except: raise SoftwareError("Can't find mongodb server executable") else: out = system2((mongod, '--version'))[0] version_string = out.splitlines()[0] m = re.search('[\d\.]+', version_string) if m: return SoftwareInfo('mongodb', m.group(0), out) raise SoftwareError("Can't parse `mongod --version` output")
def apache_software_info(): binary_name = "httpd" if linux.os.redhat_family else "apache2ctl" binary = which(binary_name) if not binary: raise SoftwareError("Can't find executable for apache http server") try: out = system2((binary, '-V'))[0] except PopenError, e: pkg_mgr = pkgmgr.package_mgr() version_string = pkg_mgr.info('apache2')['installed']
def nginx_software_info(): binary = which('nginx', path_append='/usr/local/nginx/sbin') if not binary: raise SoftwareError("Can't find executable for Nginx server") out = system2((binary, '-V'))[1] if not out: raise SoftwareError version_string = out.splitlines()[0] res = re.search('[\d\.]+', version_string) if res: version = res.group(0) return SoftwareInfo('nginx', version, out) raise SoftwareError
def mysql_software_info(): binary = which('mysqld') if not binary: raise SoftwareError("Can't find executable for MySQL server") version_string = system2((binary, '-V'))[0].strip() if not version_string: raise SoftwareError res = re.search('Ver\s+([\d\.]+)', version_string) if res: version = res.group(1) return SoftwareInfo('mysql', version, version_string) raise SoftwareError
def memcached_software_info(): binary = which('memcached') if not binary: raise SoftwareError("Can't find executable for Memcached") out = system2((binary, '-h'))[0] if not out: raise SoftwareError version_string = out.splitlines()[0] res = re.search('memcached\s+([\d\.]+)', version_string) if res: version = res.group(1) return SoftwareInfo('memcached', version, version_string) raise SoftwareError
def chef_software_info(): binary = which('chef-client') if not binary: raise SoftwareError("Can't find executable for chef client") version_string = linux.system((binary, '-v'))[0].strip() if not version_string: raise SoftwareError res = re.search('Chef:\s+([\d\.]+)', version_string) if res: version = res.group(1) return SoftwareInfo('chef', version, version_string) raise SoftwareError
def php_software_info(): binary = which('php') if not binary: raise SoftwareError("Can't find executable for php interpreter") out = system2((binary, '-v'))[0] if not out: raise SoftwareError version_string = out.splitlines()[0] res = re.search('PHP\s+([\d\.]+)', version_string) if res: version = res.group(1) return SoftwareInfo('php', version, out) raise SoftwareError
def apache_software_info(): binary_name = "httpd" if linux.os.redhat_family else "apache2" binary = which(binary_name) if not binary: raise SoftwareError("Can't find executable for apache http server") out = system2((binary, '-V'))[0] if not out: raise SoftwareError version_string = out.splitlines()[0] res = re.search('[\d\.]+', version_string) if res: version = res.group(0) return SoftwareInfo('apache', version, out) raise SoftwareError
def varnish_software_info(): binary = which('varnishd') if not binary: raise SoftwareError("Can't find executable for varnish HTTP accelerator") out = system2((binary, '-V'))[1].strip() if not out: raise SoftwareError version_string = out.splitlines()[0] res = re.search('varnish-([\d\.]+)', version_string) if res: version = res.group(1) return SoftwareInfo('varnish', version, out) raise SoftwareError
def _set_overcommit_option(self): try: with open('/proc/sys/vm/overcommit_memory', 'r') as f: proc = f.read().strip() with open('/etc/sysctl.conf', 'r') as f: match = re.search(r'^\s*vm.overcommit_memory\s*=\s*(\d+)', f.read(), re.M) sysctl = match.group(1) if match else None if (proc == '2') or (proc == sysctl == '0'): LOG.info('Kernel option vm.overcommit_memory is set to %s by user. ' 'Consider changing it to 1 for optimal Redis functioning. ' 'More information here: http://redis.io/topics/admin', proc) else: LOG.debug('Setting vm.overcommit_memory to 1') system2((which('sysctl'), 'vm.overcommit_memory=1')) except: LOG.debug("Failed to set vm.overcommit_memory option", exc_info=sys.exc_info())
def rails_software_info(): binary = which('gem') if not binary: raise SoftwareError("Can't find executable for ruby gem packet manager") out = system2((binary, 'list', 'rails'))[0].strip() if not out: raise SoftwareError res = re.search('\(([\d\.]+)\)', out) if res: version = res.group(1) return SoftwareInfo('rails', version, '') raise SoftwareError
def mysqlproxy_software_info(): binary = which('mysql-proxy') if not binary: raise SoftwareError("Can't find executable for mysql-proxy") version_string = system2((binary, '-V'))[0].strip() if not version_string: raise SoftwareError version_string = version_string.splitlines()[0] res = re.search('mysql-proxy\s+([\d\.]+)', version_string) if res: version = res.group(1) return SoftwareInfo('mysql-proxy', version, version_string) raise SoftwareError
def python_software_info(): binary = which('python') if not binary: raise SoftwareError("Can't find executable for python interpreter") version_string = system2((binary, '-V'))[1].strip() if not version_string: raise SoftwareError version_string = version_string.splitlines()[0] res = re.search('Python\s+([\d\.]+)', version_string) if res: version = res.group(1) return SoftwareInfo('python', version, version_string) raise SoftwareError
def haproxy_software_info(): binary_name = "haproxy" binary = which(binary_name) if not binary: raise SoftwareError("Can't find executable for HAProxy") out = system2((binary, '-v'))[0] if not out: raise SoftwareError() version_string = out.splitlines()[0] res = re.search('[\d\.]+', version_string) if res: version = res.group(0) return SoftwareInfo('haproxy', version, out) raise SoftwareError
def _set_overcommit_option(self): try: with open('/proc/sys/vm/overcommit_memory', 'r') as f: proc = f.read().strip() with open('/etc/sysctl.conf', 'r') as f: match = re.search(r'^\s*vm.overcommit_memory\s*=\s*(\d+)', f.read(), re.M) sysctl = match.group(1) if match else None if (proc == '2') or (proc == sysctl == '0'): LOG.info( 'Kernel option vm.overcommit_memory is set to %s by user. ' 'Consider changing it to 1 for optimal Redis functioning. ' 'More information here: http://redis.io/topics/admin', proc) else: LOG.debug('Setting vm.overcommit_memory to 1') system2((which('sysctl'), 'vm.overcommit_memory=1')) except: LOG.debug("Failed to set vm.overcommit_memory option", exc_info=sys.exc_info())
def _start_stop_reload(self, action): chef_client_bin = linux.which('chef-client') if action == "start": if not self.running: # Stop default chef-client init script if os.path.exists(self._default_init_script): linux.system( (self._default_init_script, "stop"), close_fds=True, preexec_fn=os.setsid, raise_exc=False ) cmd = (chef_client_bin, '--daemonize', '--logfile', '/var/log/chef-client.log', '--pid', self.pid_file) out, err, rcode = linux.system(cmd, close_fds=True, preexec_fn=os.setsid, env=self._env, stdout=open(os.devnull, 'w+'), stderr=open(os.devnull, 'w+'), raise_exc=False) if rcode == 255: LOG.debug('chef-client daemon already started') elif rcode: msg = ( 'Chef failed to start daemonized. ' 'Return code: %s\nOut:%s\nErr:%s' ) raise initdv2.InitdError(msg % (rcode, out, err)) elif action == "stop": if self.running: with open(self.pid_file) as f: pid = int(f.read().strip()) try: os.getpgid(pid) except OSError: os.remove(self.pid_file) else: os.kill(pid, signal.SIGTERM)
def chef_software_info(): binary = which('chef-client') if not binary: raise SoftwareError("Can't find executable for chef client") try: version_string = linux.system((binary, '-v'), shell=bool(linux.os.windows))[0].strip() except OSError as e: if e.errno == 2: # This happen when chef-client has a non existed path in shebang. version_string = None else: raise if not version_string: raise SoftwareError res = re.search('Chef:\s+([\d\.]+)', version_string) if res: version = res.group(1) return SoftwareInfo('chef', version, version_string) raise SoftwareError
def run(self): if not linux.which('euca-bundle-vol'): raise HandlerError('euca-bundle-vol command not found, please install "euca2ools" package') cert_path = pk_path = cloud_cert_path = fstab_path = None try: cert, pk = self._platform.get_cert_pk() cert_path = bus.cnf.write_key('euca-cert.pem', cert) pk_path = bus.cnf.write_key('euca-pk.pem', pk) cloud_cert_path = bus.cnf.write_key('euca-cloud-cert.pem', self._platform.get_ec2_cert()) access_key, secret_key = self._platform.get_access_keys() environ = os.environ.copy() environ.update({ 'EUCALYPTUS_CERT': cloud_cert_path, 'EC2_CERT': cert_path, 'EC2_PRIVATE_KEY': pk_path, 'EC2_USER_ID': self._platform.get_account_id(), 'EC2_ACCESS_KEY': access_key, 'AWS_ACCESS_KEY': access_key, 'EC2_SECRET_KEY': secret_key, 'AWS_SECRET_KEY': secret_key, 'EC2_URL': self._platform.get_access_data('ec2_url'), 'S3_URL': self._platform.get_access_data('s3_url') }) # LOG.info('environ: %s', environ) # LOG.info('============') # LOG.info('EC2_PRIVATE_KEY: %s', open(pk_path).read()) # LOG.info('============') # LOG.info('EC2_CERT: %s', open(cert_path).read()) # LOG.info('============') # LOG.info('EUCALYPTUS_CERT: %s', open(cloud_cert_path).read()) # LOG.info('============') # with open('/etc/fstab') as fp: # fstab_path = bus.cnf.write_key('euca-fstab', fp.read()) # # disable_root_fsck=False - cause current fstab wrapper adds updated entry # # to the end of the file, and this breaks CentOS boot # # because 'mount -a' process fstab sequentically # self._fix_fstab( # filename=fstab_path, # disable_root_fsck=False) coreutils.touch('/.autorelabel') coreutils.touch('/.autofsck') # Create image object for gathering directories exclude list # image = rebundle_hdlr.LinuxImage('/', # os.path.join(self._destination, self._image_name), # self._excludes) excludes = [ self._destination, '/selinux/*', '/var/lib/dhclient', '/var/lib/dhcp', '/var/lib/dhcp3' ] LOG.info('Bundling image') cmd = ( linux.which('euca-bundle-vol'), '--arch', linux.os['arch'], '--size', str(self._image_size), '--destination', self._destination, '--exclude', ','.join(excludes), #'--fstab', fstab_path, '--prefix', self._image_name, '--volume', '/', '--debug' ) LOG.info(' '.join(cmd)) LOG.info(linux.system(cmd, env=environ, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)[0]) LOG.info('Uploading image (with euca-upload-bundle)') #files_prefix = os.path.join(self._destination, self._image_name) #files = glob.glob(files_prefix + '*') #s3_manifest_path = self._upload_image_files(files, files_prefix + '.manifest.xml') manifest = os.path.join(self._destination, self._image_name) + '.manifest.xml' bucket = os.path.basename(self._platform.scalrfs.root()) cmd = ( linux.which('euca-upload-bundle'), '--bucket', bucket, '--manifest', manifest ) LOG.info(' '.join(cmd)) LOG.info(linux.system(cmd, env=environ)[0]) # LOG.info('Registering image (with euca-register)') # cmd = ( # linux.which('euca-register'), # '--name', self._image_name, # '{0}/{1}'.format(bucket, os.path.basename(manifest)) # ) # LOG.info(' '.join(cmd)) # LOG.info(linux.system(cmd, env=environ.copy())[0]) LOG.info('Registering image') s3_manifest_path = '{0}/{1}'.format(bucket, os.path.basename(manifest)) return self._register_image(s3_manifest_path) finally: linux.system('chmod 755 {0}/keys/euca-*'.format(bus.cnf.private_path()), shell=True) linux.system('rm -f {0}/keys/euca-*'.format(bus.cnf.private_path()), shell=True) linux.system('rm -f {0}/{1}.*'.format(self._destination, self._image_name), shell=True)
def run(self): if not linux.which('euca-bundle-vol'): raise HandlerError( 'euca-bundle-vol command not found, please install "euca2ools" package' ) cert_path = pk_path = cloud_cert_path = fstab_path = None try: cert, pk = self._platform.get_cert_pk() cert_path = bus.cnf.write_key('euca-cert.pem', cert) pk_path = bus.cnf.write_key('euca-pk.pem', pk) cloud_cert_path = bus.cnf.write_key('euca-cloud-cert.pem', self._platform.get_ec2_cert()) access_key, secret_key = self._platform.get_access_keys() environ = os.environ.copy() environ.update({ 'EUCALYPTUS_CERT': cloud_cert_path, 'EC2_CERT': cert_path, 'EC2_PRIVATE_KEY': pk_path, 'EC2_USER_ID': self._platform.get_account_id(), 'EC2_ACCESS_KEY': access_key, 'AWS_ACCESS_KEY': access_key, 'EC2_SECRET_KEY': secret_key, 'AWS_SECRET_KEY': secret_key, 'EC2_URL': self._platform.get_access_data('ec2_url'), 'S3_URL': self._platform.get_access_data('s3_url') }) # LOG.info('environ: %s', environ) # LOG.info('============') # LOG.info('EC2_PRIVATE_KEY: %s', open(pk_path).read()) # LOG.info('============') # LOG.info('EC2_CERT: %s', open(cert_path).read()) # LOG.info('============') # LOG.info('EUCALYPTUS_CERT: %s', open(cloud_cert_path).read()) # LOG.info('============') # with open('/etc/fstab') as fp: # fstab_path = bus.cnf.write_key('euca-fstab', fp.read()) # # disable_root_fsck=False - cause current fstab wrapper adds updated entry # # to the end of the file, and this breaks CentOS boot # # because 'mount -a' process fstab sequentically # self._fix_fstab( # filename=fstab_path, # disable_root_fsck=False) coreutils.touch('/.autorelabel') coreutils.touch('/.autofsck') # Create image object for gathering directories exclude list # image = rebundle_hdlr.LinuxImage('/', # os.path.join(self._destination, self._image_name), # self._excludes) excludes = [ self._destination, '/selinux/*', '/var/lib/dhclient', '/var/lib/dhcp', '/var/lib/dhcp3' ] LOG.info('Bundling image') cmd = ( linux.which('euca-bundle-vol'), '--arch', linux.os['arch'], '--size', str(self._image_size), '--destination', self._destination, '--exclude', ','.join(excludes), #'--fstab', fstab_path, '--prefix', self._image_name, '--volume', '/', '--debug') LOG.info(' '.join(cmd)) LOG.info( linux.system(cmd, env=environ, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)[0]) LOG.info('Uploading image (with euca-upload-bundle)') #files_prefix = os.path.join(self._destination, self._image_name) #files = glob.glob(files_prefix + '*') #s3_manifest_path = self._upload_image_files(files, files_prefix + '.manifest.xml') manifest = os.path.join(self._destination, self._image_name) + '.manifest.xml' bucket = os.path.basename(self._platform.scalrfs.root()) cmd = (linux.which('euca-upload-bundle'), '--bucket', bucket, '--manifest', manifest) LOG.info(' '.join(cmd)) LOG.info(linux.system(cmd, env=environ)[0]) # LOG.info('Registering image (with euca-register)') # cmd = ( # linux.which('euca-register'), # '--name', self._image_name, # '{0}/{1}'.format(bucket, os.path.basename(manifest)) # ) # LOG.info(' '.join(cmd)) # LOG.info(linux.system(cmd, env=environ.copy())[0]) LOG.info('Registering image') s3_manifest_path = '{0}/{1}'.format(bucket, os.path.basename(manifest)) return self._register_image(s3_manifest_path) finally: linux.system('chmod 755 {0}/keys/euca-*'.format( bus.cnf.private_path()), shell=True) linux.system('rm -f {0}/keys/euca-*'.format( bus.cnf.private_path()), shell=True) linux.system('rm -f {0}/{1}.*'.format(self._destination, self._image_name), shell=True)
Created on Aug 28, 2012 @author: marat ''' from __future__ import with_statement import os import logging import base64 import collections import time from scalarizr import linux if not linux.which('lvs'): from scalarizr.linux import pkgmgr # set updatedb=True to work over problem on GCE: # E: Problem renaming the file /var/cache/apt/pkgcache.bin.fsF22K to /var/cache/apt/pkgcache.bin pkgmgr.installed('lvm2') LOG = logging.getLogger(__name__) class NotFound(linux.LinuxError): pass def system(*args, **kwargs): kwargs['logger'] = LOG kwargs['close_fds'] = True
def vote(self, votes): if self.try_file('/proc/xen/xenbus') and self._xls_path \ and linux.which('nova-agent') and self._xls_out(): self.LOG.debug('matched user_data') votes[self]['user_data'] += 1 votes['Ec2Pvd']['user_data'] -= 1
from __future__ import with_statement import logging import re import os from scalarizr import linux from scalarizr.linux import coreutils from scalarizr.storage2 import StorageError if not linux.which('mdadm'): from scalarizr.linux import pkgmgr pkgmgr.installed('mdadm', updatedb=True) mdadm_binary = linux.which('mdadm') if not os.path.exists('/proc/mdstat'): coreutils.modprobe('md_mod') LOG = logging.getLogger(__name__) def mdadm(mode, md_device=None, *devices, **long_kwds): """ Example: mdadm.mdadm('create', '/dev/md0', '/dev/loop0', '/dev/loop1', level=0, metadata='default', assume_clean=True, raid_devices=2) """ raise_exc = long_kwds.pop('raise_exc', True) return linux.system(linux.build_cmd_args( mdadm_binary,
def __init__(self): self._xls_path = linux.which('xenstore-ls')
class HttpSource(Source): def __init__(self, url=None): self._logger = logging.getLogger(__name__) self.url = url def update(self, workdir): log = bus.init_op.logger if bus.init_op else self._logger if not os.path.exists(workdir): os.makedirs(workdir) purl = urlparse(self.url) log.info('Downloading %s', self.url) try: hdlrs = [urllib2.HTTPRedirectHandler()] if purl.scheme == 'https': hdlrs.append(urllib2.HTTPSHandler()) opener = urllib2.build_opener(*hdlrs) resp = opener.open(self.url) except urllib2.URLError, e: raise SourceError('Downloading %s failed. %s' % (self.url, e)) tmpdir = tempfile.mkdtemp(dir='/tmp/') tmpdst = os.path.join(tmpdir, os.path.basename(purl.path)) fp = open(tmpdst, 'w+') num_read = 0 while True: buf = resp.read(8192) if not buf: break num_read += len(buf) self._logger.debug('%d bytes downloaded', num_read) fp.write(buf) fp.close() log.info('File saved as %s', tmpdst) try: mime = mimetypes.guess_type(tmpdst) if mime[0] in ('application/x-tar', 'application/zip'): unar = None if mime[0] == 'application/x-tar': unar = ['tar'] if mime[1] == 'gzip': unar += ['-xzf'] elif mime[1] in ('bzip', 'bzip2'): unar += ['-xjf'] else: raise UndefinedSourceError() unar += [tmpdst, '-C', workdir] elif mime[0] == 'application/zip': if not linux.which('unzip'): log.info('Installing unzip de-archiver') pkgmgr.installed('unzip') unar = ['unzip', tmpdst, '-d', workdir] else: raise UndefinedSourceError('Unexpected archive format %s' % str(mime)) log.info('Extracting source from %s into %s', tmpdst, workdir) out = system2(unar)[0] self._logger.info(out) else: log.info('Moving source from %s to %s', tmpdst, workdir) dst = os.path.join(workdir, os.path.basename(tmpdst)) if os.path.isfile(dst): self._logger.debug('Removing already existed file %s', dst) os.remove(dst) shutil.move(tmpdst, workdir) self._logger.info( 'Deploying %s to %s has been completed successfully.', self.url, dst) except: exc = sys.exc_info() if isinstance(exc[0], SourceError): raise raise SourceError, exc[1], exc[2] finally: if os.path.exists(tmpdst): os.remove(tmpdst) if os.path.exists(tmpdir): shutil.rmtree(tmpdir)
from __future__ import with_statement import logging import re import os from scalarizr import linux from scalarizr.linux import coreutils from scalarizr.storage2 import StorageError if not linux.which('mdadm'): from scalarizr.linux import pkgmgr pkgmgr.installed('mdadm', updatedb=True) mdadm_binary = linux.which('mdadm') if not os.path.exists('/proc/mdstat'): coreutils.modprobe('md_mod') LOG = logging.getLogger(__name__) def mdadm(mode, md_device=None, *devices, **long_kwds): """ Example: mdadm.mdadm('create', '/dev/md0', '/dev/loop0', '/dev/loop1', level=0, metadata='default', assume_clean=True, raid_devices=2) """ raise_exc = long_kwds.pop('raise_exc', True) return linux.system(linux.build_cmd_args( mdadm_binary, ['--%s' % mode] + ([md_device] if md_device else []),
''' Created on Aug 28, 2012 @author: marat ''' from __future__ import with_statement import os import logging import base64 import collections from scalarizr import linux if not linux.which('lvs'): from scalarizr.linux import pkgmgr pkgmgr.installed('lvm2') LOG = logging.getLogger(__name__) class NotFound(linux.LinuxError): pass def system(*args, **kwargs): kwargs['logger'] = LOG kwargs['close_fds'] = True ''' To prevent this garbage in stderr (Fedora/CentOS): File descriptor 6 (/tmp/ffik4yjng (deleted)) leaked on lv* invocation.