def updateGeoRepKeys(userName, geoRepPubKeys): try: userInfo = getpwnam(userName) homeDir = userInfo[5] uid = userInfo[2] gid = userInfo[3] except KeyError as e: raise ge.GlusterGeoRepUserNotFoundException(err=[str(e)]) sshDir = homeDir + "/.ssh" authKeysFile = sshDir + "/authorized_keys" if not os.path.exists(sshDir): try: os.makedirs(sshDir, 0o700) os.chown(sshDir, uid, gid) if selinux.is_selinux_enabled(): selinux.restorecon(sshDir) except OSError as e: raise ge.GlusterGeoRepPublicKeyWriteFailedException(err=[str(e)]) newKeys = [" ".join(l.split()[:-1]) for l in geoRepPubKeys] newKeyDict = dict(zip(newKeys, geoRepPubKeys)) try: with open(authKeysFile) as f: existingKeyLines = f.readlines() except IOError as e: if e.errno == errno.ENOENT: existingKeyLines = [] else: raise ge.GlusterGeoRepPublicKeyWriteFailedException(err=[str(e)]) try: existingKeys = [" ".join(l.split()[:-1]) for l in existingKeyLines] existingKeyDict = dict(zip(existingKeys, existingKeyLines)) outLines = existingKeyLines outKeys = set(newKeyDict).difference(set(existingKeyDict)) outLines.extend([newKeyDict[k] for k in outKeys if newKeyDict[k]]) safeWrite(authKeysFile, ''.join(outLines)) os.chmod(authKeysFile, 0o600) os.chown(authKeysFile, uid, gid) if selinux.is_selinux_enabled(): selinux.restorecon(authKeysFile) except (IOError, OSError) as e: raise ge.GlusterGeoRepPublicKeyWriteFailedException(err=[str(e)])
def __init__(self): self.tabs = [] self.xml = xml xml.signal_connect("on_quit_activate", self.destroy) xml.signal_connect("on_delete_clicked", self.delete) xml.signal_connect("on_add_clicked", self.add) xml.signal_connect("on_properties_clicked", self.properties) xml.signal_connect("on_local_clicked", self.on_local_clicked) self.add_page(statusPage.statusPage(xml)) if selinux.is_selinux_enabled() > 0: try: self.add_page(booleansPage.booleansPage(xml)) self.add_page(fcontextPage.fcontextPage(xml)) self.add_page(loginsPage.loginsPage(xml)) self.add_page(usersPage.usersPage(xml)) self.add_page(portsPage.portsPage(xml)) self.add_page(modulesPage.modulesPage(xml)) # modules self.add_page(domainsPage.domainsPage(xml)) # domains except ValueError as e: self.error(e.message) xml.signal_connect("on_quit_activate", self.destroy) xml.signal_connect("on_policy_activate", self.policy) xml.signal_connect("on_logging_activate", self.logging) xml.signal_connect("on_about_activate", self.on_about_activate) self.add_menu = xml.get_widget("add_menu_item") self.properties_menu = xml.get_widget("properties_menu_item") self.delete_menu = xml.get_widget("delete_menu_item")
def run(options={}): """main loop for this plugin""" _success = 1 _message = 'toggle unsuccessful, selinux setting unchanged' if 'dryrun' in options: if options['dryrun'] == True: _success = 0 _message = 'I would have toggled selinux enforcing setting' return _success, _message # First, is SELinux available on this system? if selinux.is_selinux_enabled(): try: is_enforce = selinux.security_getenforce() except OSError: _success, _message = 1, 'SELinux is not available on this host' return _success, _message else: print 'selinux disabled, will not be able to toggle setting' sys.exit(1) _success, _message = toggle_selinux(is_enforce) return _success, _message
def selinux_enabled(self): if not HAVE_SELINUX: return False if selinux.is_selinux_enabled() == 1: return True else: return False
def symlink_atomically(srcpath, dstpath, force=False, preserve_context=True): """Create a symlink, optionally replacing dstpath atomically, optionally setting or preserving SELinux context.""" dstdname = os.path.dirname(dstpath) dstbname = os.path.basename(dstpath) run_restorecon = False ctx = None if preserve_context and selinux.is_selinux_enabled() <= 0: preserve_context = False else: try: ret, ctx = selinux.lgetfilecon(dstpath) if ret < 0: raise RuntimeError("getfilecon(%r) failed" % dstpath) except OSError as e: if e.errno == errno.ENOENT: run_restorecon = True else: raise if not force: os.symlink(srcpath, dstpath) if preserve_context: selinux.restorecon(dstpath) else: dsttmp = None for attempt in range(tempfile.TMP_MAX): _dsttmp = tempfile.mktemp( prefix=dstbname + os.extsep, dir=dstdname) try: os.symlink(srcpath, _dsttmp) except OSError as e: if e.errno == errno.EEXIST: # try again continue raise else: dsttmp = _dsttmp break if dsttmp is None: raise IOError( errno.EEXIST, "No suitable temporary symlink could be created.") if preserve_context and not run_restorecon: selinux.lsetfilecon(dsttmp, ctx) try: os.rename(dsttmp, dstpath) except: # clean up os.remove(dsttmp) raise if run_restorecon: selinux.restorecon(dstpath)
def read_cmdline(self): for f in ("selinux", "debug", "leavebootorder", "testing", "extlinux", "nombr", "gpt", "noefi"): self.set_cmdline_bool(f) if not selinux.is_selinux_enabled(): self.selinux = 0
def diff(self, file_struct): self._validate_struct(file_struct) temp_file, temp_dirs = self.process(file_struct) path = file_struct['path'] sectx_result = '' result = '' try: cur_sectx = lgetfilecon(path)[1] except OSError: # workarounding BZ 690238 cur_sectx = None if not is_selinux_enabled(): cur_sectx = None if cur_sectx == None: cur_sectx = '' if file_struct.has_key('selinux_ctx') and file_struct['selinux_ctx']: if cur_sectx != file_struct['selinux_ctx']: sectx_result = "SELinux contexts differ: actual: [%s], expected: [%s]\n" % (cur_sectx, file_struct['selinux_ctx']) if file_struct['filetype'] == 'symlink': try: curlink = os.readlink(path) newlink = os.readlink(temp_file) if curlink == newlink: result = '' else: result = "Link targets differ for [%s]: actual: [%s], expected: [%s]\n" % (path, curlink, newlink) except OSError, e: if e.errno == 22: result = "Deployed symlink is no longer a symlink!" else: raise e
def get_current_mode(self): if selinux.is_selinux_enabled(): if selinux.security_getenforce() > 0: return ENFORCING else: return PERMISSIVE else: return DISABLED
def default_container_context(): if selinux.is_selinux_enabled() != 0: fd = open(selinux.selinux_lxc_contexts_path()) for i in fd.readlines(): name, context = i.split("=") if name.strip() == "file": return context.strip("\n\" ") return ""
def main(): module = AnsibleModule( argument_spec=dict( name=dict(type='str', required=True), persistent=dict(type='bool', default=False), state=dict(type='bool', required=True), ), supports_check_mode=True, ) if not HAVE_SELINUX: module.fail_json(msg="This module requires libselinux-python support") if not HAVE_SEMANAGE: module.fail_json(msg="This module requires libsemanage-python support") if not selinux.is_selinux_enabled(): module.fail_json(msg="SELinux is disabled on this host.") name = module.params['name'] persistent = module.params['persistent'] state = module.params['state'] result = dict( name=name, ) if hasattr(selinux, 'selinux_boolean_sub'): # selinux_boolean_sub allows sites to rename a boolean and alias the old name # Feature only available in selinux library since 2012. name = selinux.selinux_boolean_sub(name) if not has_boolean_value(module, name): module.fail_json(msg="SELinux boolean %s does not exist." % name) cur_value = get_boolean_value(module, name) if cur_value == state: module.exit_json(changed=False, state=cur_value, **result) if module.check_mode: module.exit_json(changed=True) if persistent: r = semanage_boolean_value(module, name, state) else: r = set_boolean_value(module, name, state) result['changed'] = r if not r: module.fail_json(msg="Failed to set boolean %s to %s" % (name, state)) try: selinux.security_commit_booleans() except: module.fail_json(msg="Failed to commit pending boolean %s value" % name) module.exit_json(**result)
def __init__(self): # # mode of operation # self.testing = False self.debug = False # # minor modes # self.uevents = False # # enable/disable functionality # self.selinux = selinux.is_selinux_enabled() self.multipath = True self.dmraid = True self.ibft = True self.noiswmd = False self.gfs2 = True self.jfs = True self.reiserfs = True # for this flag to take effect, # blockdev.mpath.set_friendly_names(flags.multipath_friendly_names) must # be called prior to calling Blivet.reset() or DeviceTree.populate() self.multipath_friendly_names = True # set to False since automatic updates of a device's information # or state should not be necessary by default self.auto_dev_updates = False # set to False by default since a forced reset for file contexts # is ordinary not necessary self.selinux_reset_fcon = False # set to True since we want to keep these around by default self.keep_empty_ext_partitions = True # set to False to suppress the default LVM behavior of saving # backup metadata in /etc/lvm/{archive,backup} self.lvm_metadata_backup = True # whether to include nodev filesystems in the devicetree self.include_nodev = False # whether to enable discard for newly created devices # (so far only for LUKS) self.discard_new = False self.boot_cmdline = {} self.update_from_boot_cmdline() self.allow_imperfect_devices = True self.debug_threads = False
def test_default_container_context(self): default = util.default_container_context() if selinux.is_selinux_enabled(): # newer policies use container_file_t self.assertTrue(default in ['system_u:object_r:container_file_t:s0', 'system_u:object_r:svirt_sandbox_file_t:s0']) else: self.assertEqual(default, '')
def overwrite_safely(path, content, preserve_mode=True, preserve_context=True): """Safely overwrite a file by creating a temporary file in the same directory, writing it, moving it over the original file, eventually preserving file mode and SELinux context.""" path = os.path.realpath(path) dir_ = os.path.dirname(path) base = os.path.basename(path) fd = None f = None tmpname = None exists = os.path.exists(path) if preserve_context and selinux.is_selinux_enabled() <= 0: preserve_context = False try: fd, tmpname = tempfile.mkstemp(prefix=base + os.path.extsep, dir=dir_) if exists and preserve_mode: shutil.copymode(path, tmpname) if exists and preserve_context: ret, ctx = selinux.getfilecon(path) if ret < 0: raise RuntimeError("getfilecon(%r) failed" % path) f = os.fdopen(fd, "w") fd = None f.write(content) f.close() f = None os.rename(tmpname, path) if preserve_context: if exists: selinux.setfilecon(path, ctx) else: selinux.restorecon(path) finally: if f: f.close() elif fd: os.close(fd) if tmpname and os.path.isfile(tmpname): try: os.unlink(tmpname) except: pass
def read_cmdline(self): for f in ("selinux", "debug", "leavebootorder", "testing", "extlinux", "gpt", "dnf"): self.set_cmdline_bool(f) if "rpmarch" in self.cmdline: self.targetarch = self.cmdline.get("rpmarch") if not selinux.is_selinux_enabled(): self.selinux = 0
def _late_setup(self): self._selinux_enabled = selinux.is_selinux_enabled() if not os.path.exists(ohostedcons.FileLocations.VDSMCERT): self._generateVDSMcerts() self._copy_vdsm_pki() if not os.path.exists( ohostedcons.FileLocations.LIBVIRT_SPICE_SERVER_CERT ): self._generateSPICEcerts() self._getSPICEcerts()
def main(): module = AnsibleModule( argument_spec={ 'ports': { 'required': True, }, 'proto': { 'required': True, 'choices': ['tcp', 'udp'], }, 'setype': { 'required': True, }, 'state': { 'required': True, 'choices': ['present', 'absent'], }, 'reload': { 'required': False, 'type': 'bool', 'default': 'yes', }, }, supports_check_mode=True ) if not HAVE_SELINUX: module.fail_json(msg="This module requires libselinux-python") if not HAVE_SEOBJECT: module.fail_json(msg="This module requires policycoreutils-python") if not selinux.is_selinux_enabled(): module.fail_json(msg="SELinux is disabled on this host.") ports = [x.strip() for x in str(module.params['ports']).split(',')] proto = module.params['proto'] setype = module.params['setype'] state = module.params['state'] do_reload = module.params['reload'] result = { 'ports': ports, 'proto': proto, 'setype': setype, 'state': state, } if state == 'present': result['changed'] = semanage_port_add(module, ports, proto, setype, do_reload) elif state == 'absent': result['changed'] = semanage_port_del(module, ports, proto, setype, do_reload) else: module.fail_json(msg='Invalid value of argument "state": {0}'.format(state)) module.exit_json(**result)
def selinux_role(self): """Setup proper selinux role. this must be called at beginning of process to adjust proper roles for selinux. it will re-execute the process with same arguments. This has similar effect of: # chcon -t rpm_exec_t executable.py We must do this dynamic as this class is to be used at bootstrap stage, so we cannot put any persistent selinux policy changes, and have no clue if filesystem where we put scripts supports extended attributes, or if we have proper role for chcon. """ try: import selinux except ImportError: with self.transaction(): self.install(['libselinux-python']) if self.buildTransaction(): self.processTransaction() # # on fedora-18 for example # the selinux core is updated # so we fail resolving symbols # solution is re-execute the process # after installation. # self._sink.reexec() os.execv(sys.executable, [sys.executable] + sys.argv) os._exit(1) if selinux.is_selinux_enabled(): rc, ctx = selinux.getcon() if rc != 0: raise Exception(_('Cannot get selinux context')) ctx1 = selinux.context_new(ctx) if not ctx1: raise Exception(_('Cannot create selinux context')) if selinux.context_role_get(ctx1) != 'system_r': if selinux.context_role_set(ctx1, 'system_r') != 0: raise Exception( _('Cannot set role within selinux context') ) if selinux.setexeccon(selinux.context_str(ctx1)) != 0: raise Exception( _('Cannot set selinux exec context') ) self._sink.reexec() os.execv(sys.executable, [sys.executable] + sys.argv) os._exit(1)
def __copy_from_user(self, user_path, profile_path): global has_selinux os.chown(user_path, os.geteuid(), os.getegid()) shutil.move(user_path, profile_path) if has_selinux: if selinux.is_selinux_enabled() > 0: rc, con = selinux.matchpathcon(profile_path, 0) if rc == 0: selinux.setfilecon(profile_path, con) dprint("Moved %s back from %s", user_path, profile_path)
def silent_restorecon(path): """Execute selinux restorecon cmd to determined file Args path -- full path to file """ try: if selinux.is_selinux_enabled(): selinux.restorecon(path) except: __PRINT_AND_LOG("restorecon {p} failed".format(p=path), "error")
def _silent_restorecon(path): """Execute selinux restorecon cmd to determined file Args path -- full path to file """ try: if selinux.is_selinux_enabled(): selinux.restorecon(path) except: _LOG.error("restorecon %s failed" % path)
def _early_customization(self): self.dialog.note( _( 'During customization use CTRL-D to abort.' ) ) self.cli = self.environment[ohostedcons.VDSMEnv.VDS_CLI] self._check_existing_pools() domain_type = self.environment[ohostedcons.StorageEnv.DOMAIN_TYPE] if domain_type is None: domain_type = self.dialog.queryString( name='OVEHOSTED_STORAGE_DOMAIN_TYPE', note=_( 'Please specify the storage ' 'you would like to use (@VALUES@)[@DEFAULT@]: ' ), prompt=True, caseSensitive=True, validValues=( ohostedcons.DomainTypes.GLUSTERFS, ohostedcons.DomainTypes.ISCSI, ohostedcons.DomainTypes.FC, ohostedcons.DomainTypes.NFS3, ohostedcons.DomainTypes.NFS4, ), default=ohostedcons.DomainTypes.NFS3, ) if domain_type == ohostedcons.DomainTypes.NFS3: self.storageType = ohostedcons.VDSMConstants.NFS_DOMAIN self.protocol_version = 3 elif domain_type == ohostedcons.DomainTypes.NFS4: self.storageType = ohostedcons.VDSMConstants.NFS_DOMAIN self.protocol_version = 4 elif domain_type == ohostedcons.DomainTypes.GLUSTERFS: self.storageType = ohostedcons.VDSMConstants.GLUSTERFS_DOMAIN elif domain_type == ohostedcons.DomainTypes.ISCSI: self.storageType = ohostedcons.VDSMConstants.ISCSI_DOMAIN elif domain_type == ohostedcons.DomainTypes.FC: self.storageType = ohostedcons.VDSMConstants.FC_DOMAIN else: raise RuntimeError( _( 'Invalid domain type: "{dtype}"' ).format( dtype=self.environment[ ohostedcons.StorageEnv.DOMAIN_TYPE ], ) ) self.environment[ohostedcons.StorageEnv.DOMAIN_TYPE] = domain_type self._selinux_enabled = selinux.is_selinux_enabled()
def read_cmdline(self): for f in ("selinux", "debug"): self.set_cmdline_bool(f) if "rpmarch" in self.cmdline: self.targetarch = self.cmdline.get("rpmarch") if not selinux.is_selinux_enabled(): self.selinux = 0 if "gpt" in self.cmdline: self.gpt = True
def selinux_enabled(self): if not HAVE_SELINUX: seenabled = self.get_bin_path('selinuxenabled') if seenabled is not None: (rc,out,err) = self.run_command(seenabled) if rc == 0: self.fail_json(msg="Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!") return False if selinux.is_selinux_enabled() == 1: return True else: return False
def copyfile(srcpath, dstpath, copy_mode_from_dst=True, run_restorecon=True): """Copy srcpath to dstpath. Abort operation if e.g. not enough space is available. Attempt to atomically replace dstpath if it exists.""" if issamefile(srcpath, dstpath, catch_stat_exceptions=OSError): return dstpath = os.path.abspath(dstpath) dstdname = os.path.dirname(dstpath) dstbname = os.path.basename(dstpath) srcfile = open(srcpath, "rb") dsttmpfile = tempfile.NamedTemporaryFile( prefix=dstbname + os.path.extsep, dir=dstdname, delete=False) mode_copied = False if copy_mode_from_dst: # attempt to copy mode from destination file (if it exists, # otherwise fall back to copying it from the source file below) try: shutil.copymode(dstpath, dsttmpfile.name) mode_copied = True except (shutil.Error, OSError): pass if not mode_copied: shutil.copymode(srcpath, dsttmpfile.name) data = None while data != "": data = srcfile.read(BLOCKSIZE) try: dsttmpfile.write(data) except: srcfile.close() dsttmpfile.close() os.unlink(dsttmpfile.name) raise srcfile.close() dsttmpfile.close() os.rename(dsttmpfile.name, dstpath) if run_restorecon and selinux.is_selinux_enabled() > 0: selinux.restorecon(dstpath)
def __init__(self): # # mode of operation # self.testing = False self.installer_mode = False self.debug = False # # minor modes # self.uevents = False # # minor modes (installer-specific) # self.automated_install = False self.live_install = False self.image_install = False # # enable/disable functionality # self.selinux = selinux.is_selinux_enabled() self.multipath = True self.dmraid = True self.ibft = True self.noiswmd = False self.gfs2 = True self.jfs = True self.reiserfs = True self.arm_platform = None self.gpt = False self.multipath_friendly_names = True # set to False to suppress the default LVM behavior of saving # backup metadata in /etc/lvm/{archive,backup} self.lvm_metadata_backup = True # whether to include nodev filesystems in the devicetree (only # meaningful when flags.installer_mode is False) self.include_nodev = False self.boot_cmdline = {} self.update_from_boot_cmdline() self.allow_imperfect_devices = True self.debug_threads = False
def collect(self, module=None, collected_facts=None): facts_dict = {} selinux_facts = {} # If selinux library is missing, only set the status and selinux_python_present since # there is no way to tell if SELinux is enabled or disabled on the system # without the library. if not HAVE_SELINUX: selinux_facts['status'] = 'Missing selinux Python library' facts_dict['selinux'] = selinux_facts facts_dict['selinux_python_present'] = False return facts_dict # Set a boolean for testing whether the Python library is present facts_dict['selinux_python_present'] = True if not selinux.is_selinux_enabled(): selinux_facts['status'] = 'disabled' else: selinux_facts['status'] = 'enabled' try: selinux_facts['policyvers'] = selinux.security_policyvers() except (AttributeError, OSError): selinux_facts['policyvers'] = 'unknown' try: (rc, configmode) = selinux.selinux_getenforcemode() if rc == 0: selinux_facts['config_mode'] = SELINUX_MODE_DICT.get(configmode, 'unknown') else: selinux_facts['config_mode'] = 'unknown' except (AttributeError, OSError): selinux_facts['config_mode'] = 'unknown' try: mode = selinux.security_getenforce() selinux_facts['mode'] = SELINUX_MODE_DICT.get(mode, 'unknown') except (AttributeError, OSError): selinux_facts['mode'] = 'unknown' try: (rc, policytype) = selinux.selinux_getpolicytype() if rc == 0: selinux_facts['type'] = policytype else: selinux_facts['type'] = 'unknown' except (AttributeError, OSError): selinux_facts['type'] = 'unknown' facts_dict['selinux'] = selinux_facts return facts_dict
def _silent_restorecon(self, path): """ Execute selinux restorecon cmd to determined file Args path -- full path to file """ try: if selinux.is_selinux_enabled(): selinux.restorecon(path) except: self.logger.error("restorecon %s failed" % path, exc_info=True)
def main(): module = AnsibleModule( argument_spec = dict( name=dict(required=True), persistent=dict(default='no', type='bool'), state=dict(required=True, type='bool') ), supports_check_mode=True ) if not HAVE_SELINUX: module.fail_json(msg="This module requires libselinux-python support") if not HAVE_SEMANAGE: module.fail_json(msg="This module requires libsemanage-python support") if not selinux.is_selinux_enabled(): module.fail_json(msg="SELinux is disabled on this host.") name = module.params['name'] persistent = module.params['persistent'] state = module.params['state'] result = {} result['name'] = name if not has_boolean_value(module, name): module.fail_json(msg="SELinux boolean %s does not exist." % name) cur_value = get_boolean_value(module, name) if cur_value == state: result['state'] = cur_value result['changed'] = False module.exit_json(**result) if module.check_mode: module.exit_json(changed=True) if persistent: r = semanage_boolean_value(module, name, state) else: r = set_boolean_value(module, name, state) result['changed'] = r if not r: module.fail_json(msg="Failed to set boolean %s to %s" % (name, value)) try: selinux.security_commit_booleans() except: module.fail_json(msg="Failed to commit pending boolean %s value" % name) module.exit_json(**result)
def __create_selinuxfs(self): arglist = ["/bin/mount", "--bind", "/dev/null", self._instroot + self.__selinux_mountpoint + "/load"] subprocess.call(arglist, close_fds = True) if kickstart.selinux_enabled(self.ks): # label the fs like it is a root before the bind mounting arglist = ["/sbin/setfiles", "-F", "-r", self._instroot, selinux.selinux_file_context_path(), self._instroot] subprocess.call(arglist, close_fds = True) # these dumb things don't get magically fixed, so make the user generic # if selinux exists on the host we need to lie to the chroot if selinux.is_selinux_enabled(): for f in ("/proc", "/sys"): arglist = ["/usr/bin/chcon", "-u", "system_u", self._instroot + f] subprocess.call(arglist, close_fds = True)
def selinux_context(path): context = [None, None, None, None] if HAVE_SELINUX and selinux.is_selinux_enabled(): try: # note: the selinux module uses byte strings on python2 and text # strings on python3 ret = selinux.lgetfilecon_raw(to_native(path)) except OSError: return context if ret[0] != -1: # Limit split to 4 because the selevel, the last in the list, # may contain ':' characters context = ret[1].split(':', 3) return context
def main(): module = AnsibleModule(argument_spec=dict( policy=dict(required=False), state=dict(choices=['enforcing', 'permissive', 'disabled'], required=True), configfile=dict(aliases=['conf', 'file'], default='/etc/selinux/config')), supports_check_mode=True) # global vars changed = False msgs = [] configfile = module.params['configfile'] policy = module.params['policy'] state = module.params['state'] runtime_enabled = selinux.is_selinux_enabled() runtime_policy = selinux.selinux_getpolicytype()[1] runtime_state = 'disabled' if (runtime_enabled): # enabled means 'enforcing' or 'permissive' if (selinux.security_getenforce()): runtime_state = 'enforcing' else: runtime_state = 'permissive' config_policy = get_config_policy(configfile) config_state = get_config_state(configfile) # check to see if policy is set if state is not 'disabled' if (state != 'disabled'): if not policy: module.fail_json( msg='policy is required if state is not \'disabled\'') else: if not policy: policy = config_policy # check changed values and run changes if (policy != runtime_policy): if module.check_mode: module.exit_json(changed=True) # cannot change runtime policy msgs.append('reboot to change the loaded policy') changed = True if (policy != config_policy): if module.check_mode: module.exit_json(changed=True) msgs.append('config policy changed from \'%s\' to \'%s\'' % (config_policy, policy)) set_config_policy(policy, configfile) changed = True if (state != runtime_state): if module.check_mode: module.exit_json(changed=True) if (state == 'disabled'): msgs.append('state change will take effect next reboot') else: if (runtime_enabled): set_state(state) msgs.append('runtime state changed from \'%s\' to \'%s\'' % (runtime_state, state)) else: msgs.append('state change will take effect next reboot') changed = True if (state != config_state): if module.check_mode: module.exit_json(changed=True) msgs.append('config state changed from \'%s\' to \'%s\'' % (config_state, state)) set_config_state(state, configfile) changed = True module.exit_json(changed=changed, msg=', '.join(msgs), configfile=configfile, policy=policy, state=state)
def client(self, cache, job): """Run cache echo command operation. :param cache: Caching object used to template items within a command. :type cache: Object :param job: Information containing the original job specification. :type job: Dictionary :returns: tuple """ if not selinux.is_selinux_enabled(): return (None, "SELinux is not enabled.", True, None) if not AVAILABLE_SELINUX: return ( None, "The required selinux library is not installed", False, None, ) if not AVAILABLE_SEOBJECT: return ( None, "The required seobject library is not installed", False, None, ) target = job["target"] ftype = job.get("ftype") setype = job["setype"] seuser = job.get("seuser") selevel = job.get("selevel") secontext = seobject.fcontextRecords("") secontext.set_reload(job["reload"]) ( existing, orig_seuser, orig_selevel, ) = self.semanage_exists(secontext, target, ftype) if existing: if not seuser: seuser = orig_seuser if not selevel: selevel = orig_selevel secontext.modify(target, setype, ftype, selevel, seuser) else: if not seuser: seuser = "******" if not selevel: selevel = "s0" secontext.add(target, setype, ftype, selevel, seuser) return job["target"], None, True, None
# All rights reserved. # from __future__ import absolute_import import selinux import sys import time # PKI Deployment Imports from .. import pkiconfig as config from ..pkiconfig import pki_selinux_config_ports as ports from .. import pkimessages as log from .. import pkiscriptlet seobject = None if selinux.is_selinux_enabled(): try: import seobject except ImportError: # TODO: Fedora 22 has an incomplete Python 3 package # sepolgen is missing. if sys.version_info.major == 2: raise # PKI Deployment Selinux Setup Scriptlet class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): suffix = "(/.*)?" def restore_context(self, mdict):
def make_stat_info(self, path, file_stat): # Returns the stat information as required by the API ret = {} fields = { 'mode': stat.ST_MODE, 'user': stat.ST_UID, 'group': stat.ST_GID, 'size': stat.ST_SIZE, 'mtime': stat.ST_MTIME, 'ctime': stat.ST_CTIME, } for label, st in fields.items(): ret[label] = file_stat[st] # server expects things like 644, 700, etc. ret['mode'] = deci_to_octal(ret['mode'] & 07777) #print ret['size'] #if ret['size'] > self.get_maximum_file_size(): # die(4, "File %s exceeds the maximum file size (%s)" % # (path, ret['size'])) uid = ret['user'] gid = ret['group'] pw_name = self._uid_cache.get(uid) if not pw_name: try: pw_name = pwd.getpwuid(uid)[0] except KeyError: print "Error looking up user id %s" % (uid, ) if pw_name: ret['user'] = pw_name self._uid_cache[uid] = pw_name gr_name = self._gid_cache.get(gid) if not gr_name: try: gr_name = grp.getgrgid(gid)[0] except KeyError: print "Error looking up group id %s" % (gid, ) if gr_name: ret['group'] = gr_name self._gid_cache[gid] = gr_name # if selinux is disabled or on RHEL4 we do not send the selinux_ctx # flag at all - see bug 644985 - SELinux context cleared from # RHEL4 rhncfg-client try: selinux_ctx = lgetfilecon(path)[1] except OSError: selinux_ctx = None if is_selinux_enabled(): ret['selinux_ctx'] = selinux_ctx else: ret['selinux_ctx'] = '' return ret
def selinux_label_port(port, remove_label=False): """ Either set or remove an SELinux label(ldap_port_t) for a TCP port :param port: The TCP port to be labeled :type port: str :param remove_label: Set True if the port label should be removed :type remove_label: boolean :raises: ValueError: Error message """ try: import selinux except ImportError: log.debug('selinux python module not found, skipping port labeling.') return if not selinux.is_selinux_enabled(): log.debug('selinux is disabled, skipping port relabel') return # We only label ports that ARE NOT in the default policy that comes with # a RH based system. port = int(port) selinux_default_ports = [389, 636, 3268, 3269, 7389] if port in selinux_default_ports: log.debug('port {} already in {}, skipping port relabel'.format( port, selinux_default_ports)) return label_set = False label_ex = None policies = _get_selinux_port_policies(port) for policy in policies: if "ldap_port_t" == policy['type']: label_set = True # Port already has our label if port in policy['ports']: # The port is within the range, just return return break elif not remove_label: # Port belongs to someone else (bad) # This is only an issue during setting a label, not removing a label raise ValueError( "Port {} was already labeled with: ({}) Please choose a different port number" .format(port, policy['type'])) if (remove_label and label_set) or (not remove_label and not label_set): for i in range(5): try: result = subprocess.run([ "semanage", "port", "-d" if remove_label else "-a", "-t", "ldap_port_t", "-p", "tcp", str(port) ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) args = ' '.join(ensure_list_str(result.args)) stdout = ensure_str(result.stdout) stderr = ensure_str(result.stderr) log.debug(f"CMD: {args} ; STDOUT: {stdout} ; STDERR: {stderr}") return except (OSError, subprocess.CalledProcessError) as e: label_ex = e time.sleep(3) raise ValueError("Failed to mangle port label: " + str(label_ex))
import os import selinux import tempfile import unittest import blivet from tests import loopbackedtestcase import blivet.formats.fs as fs from blivet.size import Size @unittest.skipUnless(selinux.is_selinux_enabled() == 1, "SELinux is disabled") class SELinuxContextTestCase(loopbackedtestcase.LoopBackedTestCase): """Testing SELinux contexts. """ def __init__(self, methodName='run_test'): super(SELinuxContextTestCase, self).__init__(methodName=methodName, device_spec=[Size("100 MiB")]) def setUp(self): self.installer_mode = blivet.flags.installer_mode super(SELinuxContextTestCase, self).setUp() def test_mounting_ext2fs(self): """ Test that lost+found directory gets assigned correct SELinux context if installer_mode is True, and retains some random old context if installer_mode is False. """ LOST_AND_FOUND_CONTEXT = 'system_u:object_r:lost_found_t:s0' an_fs = fs.Ext2FS(device=self.loop_devices[0], label="test")
def selinux_label_port(port, remove_label=False): """ Either set or remove an SELinux label(ldap_port_t) for a TCP port :param port: The TCP port to be labelled :type port: str :param remove_label: Set True if the port label should be removed :type remove_label: boolean :raises: ValueError: Error message """ try: import selinux except ImportError: log.debug('selinux python module not found, skipping port labeling.') return try: import sepolicy except ImportError: log.debug('sepolicy python module not found, skipping port labeling.') return if not selinux.is_selinux_enabled(): log.debug('selinux is disabled, skipping port relabel') return # We only label ports that ARE NOT in the default policy that comes with # a RH based system. selinux_default_ports = [389, 636, 3268, 3269, 7389] if port in selinux_default_ports: log.debug('port %s already in %s, skipping port relabel' % (port, selinux_default_ports)) return label_set = False label_ex = None policies = [ p for p in sepolicy.info(sepolicy.PORT) if p['protocol'] == 'tcp' if port in range(p['low'], p['high'] + 1) if p['type'] not in ['unreserved_port_t', 'reserved_port_t', 'ephemeral_port_t'] ] for policy in policies: if "ldap_port_t" == policy['type']: label_set = True # Port already has our label if policy['low'] != policy['high']: # We have a range if port in range(policy['low'], policy['high'] + 1): # The port is within the range, just return return break elif not remove_label: # Port belongs to someone else (bad) # This is only an issue during setting a label, not removing a label raise ValueError( "Port {} was already labelled with: ({}) Please choose a different port number" .format(port, policy['type'])) if (remove_label and label_set) or (not remove_label and not label_set): for i in range(5): try: subprocess.check_call([ "semanage", "port", "-d" if remove_label else "-a", "-t", "ldap_port_t", "-p", "tcp", str(port) ]) return except (OSError, subprocess.CalledProcessError) as e: label_ex = e time.sleep(3) raise ValueError("Failed to mangle port label: " + str(label_ex))
def destroy(self, deployer): if not bool(selinux.is_selinux_enabled()): config.pki_log.info(log.SELINUX_DISABLED_DESTROY_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) return self.rv config.pki_log.info(log.SELINUX_DESTROY_1, __name__, extra=config.PKI_INDENTATION_LEVEL_1) # check first if any transactions are required if (len(ports) == 0 and deployer.mdict['pki_instance_name'] == config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME): return self.rv # A maximum of 10 tries to delete the SELinux contexts counter = 1 max_tries = 10 while True: try: # remove SELinux contexts when removing the last subsystem if len(deployer.instance.tomcat_instance_subsystems()) == 0: trans = seobject.semanageRecords("targeted") trans.start() if deployer.mdict['pki_instance_name'] != \ config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME: fcon = seobject.fcontextRecords() config.pki_log.info( "deleting selinux fcontext \"%s\"", deployer.mdict['pki_instance_path'] + self.suffix, extra=config.PKI_INDENTATION_LEVEL_2) fcon.delete( deployer.mdict['pki_instance_path'] + self.suffix, "") config.pki_log.info( "deleting selinux fcontext \"%s\"", deployer.mdict['pki_instance_log_path'] + self.suffix, extra=config.PKI_INDENTATION_LEVEL_2) fcon.delete( deployer.mdict['pki_instance_log_path'] + self.suffix, "") config.pki_log.info( "deleting selinux fcontext \"%s\"", deployer.mdict['pki_instance_configuration_path'] + self.suffix, extra=config.PKI_INDENTATION_LEVEL_2) fcon.delete( deployer.mdict['pki_instance_configuration_path'] + self.suffix, "") config.pki_log.info( "deleting selinux fcontext \"%s\"", deployer.mdict['pki_database_path'] + self.suffix, extra=config.PKI_INDENTATION_LEVEL_2) fcon.delete( deployer.mdict['pki_database_path'] + self.suffix, "") port_records = seobject.portRecords() for port in ports: config.pki_log.info( "deleting selinux port %s", port, extra=config.PKI_INDENTATION_LEVEL_2) port_records.delete(port, "tcp") trans.finish() break except ValueError as e: error_message = str(e) config.pki_log.debug(error_message) if error_message.strip() == \ "Could not start semanage transaction": counter += 1 if counter >= max_tries: raise time.sleep(5) config.pki_log.debug( "Retrying to remove selinux context ...") else: raise return self.rv
#!/usr/bin/python # # Copyright (C) 2013 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. from selinux import is_selinux_enabled if is_selinux_enabled(): print "selinux is enabled" else: print "selinux is disabled"
def __init__(self, gate, uuid): cpuInfo = read_cpuinfo() memory = read_memory() self.UUID = uuid self.os = gate.process('distro', software.read_os(), WITHHELD_MAGIC_STRING) self.defaultRunlevel = gate.process('run_level', software.read_runlevel(), -1) self.bogomips = gate.process('cpu', cpuInfo.get('bogomips', 0), 0) self.cpuVendor = gate.process('cpu', cpuInfo.get('type', ''), WITHHELD_MAGIC_STRING) self.cpuModel = gate.process('cpu', cpuInfo.get('model', ''), WITHHELD_MAGIC_STRING) self.cpu_stepping = gate.process('cpu', cpuInfo.get('cpu_stepping', 0), 0) self.cpu_family = gate.process('cpu', cpuInfo.get('cpu_family', ''), '') self.cpu_model_num = gate.process('cpu', cpuInfo.get('cpu_model_num', 0), 0) self.numCpus = gate.process('cpu', cpuInfo.get('count', 0), 0) self.cpuSpeed = gate.process('cpu', cpuInfo.get('speed', 0), 0) self.systemMemory = gate.process('ram_size', memory['ram'], 0) self.systemSwap = gate.process('swap_size', memory['swap'], 0) self.kernelVersion = gate.process('kernel', os.uname()[2], WITHHELD_MAGIC_STRING) if gate.grants('language'): try: self.language = os.environ['LANG'] except KeyError: try: status, lang = commands.getstatusoutput( "grep LANG /etc/sysconfig/i18n") if status == 0: self.language = lang.split('"')[1] else: self.language = 'Unknown' except: self.language = 'Unknown' else: self.language = WITHHELD_MAGIC_STRING tempform = platform.machine() self.platform = gate.process('arch', tempform, WITHHELD_MAGIC_STRING) if gate.grants('vendor'): #self.systemVendor = hostInfo.get('system.vendor' try: self.systemVendor = cat( '/sys/devices/virtual/dmi/id/sys_vendor')[0].strip() except: self.systemVendor = 'Unknown' else: self.systemVendor = WITHHELD_MAGIC_STRING if gate.grants('model'): try: self.systemModel = cat( '/sys/devices/virtual/dmi/id/product_name' )[0].strip() + ' ' + cat( '/sys/devices/virtual/dmi/id/product_version')[0].strip() except: self.systemModel = 'Unknown' #hostInfo was removed with the hal restructure #if not self.systemModel: #self.systemModel = hostInfo.get('system.hardware.product') #if hostInfo.get('system.hardware.version'): #self.systemModel += ' ' + hostInfo.get('system.hardware.version') #if not self.systemModel: #self.systemModel = 'Unknown' else: self.systemModel = WITHHELD_MAGIC_STRING if gate.grants('form_factor'): try: formfactor_id = int( cat('/sys/devices/virtual/dmi/id/chassis_type')[0].strip()) self.formfactor = FORMFACTOR_LIST[formfactor_id] except: self.formfactor = 'Unknown' else: self.formfactor = WITHHELD_MAGIC_STRING if tempform == 'ppc64': if hostInfo.get('openfirmware.model'): if hostInfo['openfirmware.model'][:3] == 'IBM': self.systemVendor = 'IBM' model = hostInfo['openfirmware.model'][4:8] model_map = { '8842': 'JS20', '6779': 'JS21', '6778': 'JS21', '7988': 'JS21', '8844': 'JS21', '0200': 'QS20', '0792': 'QS21', } try: model_name = model_map[model] self.systemModel = gate.process('model', model_name) self.formfactor = gate.process('form_factor', 'Blade') except KeyError: pass if gate.grants('selinux'): try: import selinux try: if selinux.is_selinux_enabled() == 1: self.selinux_enabled = SELINUX_ENABLED else: self.selinux_enabled = SELINUX_DISABLED except: self.selinux_enabled = SELINUX_DISABLED try: self.selinux_policy = selinux.selinux_getpolicytype()[1] except: self.selinux_policy = "Unknown" try: enforce = selinux.security_getenforce() if enforce == 0: self.selinux_enforce = "Permissive" elif enforce == 1: self.selinux_enforce = "Enforcing" elif enforce == -1: self.selinux_enforce = "Disabled" else: self.selinux_enforce = "FUBARD" except: self.selinux_enforce = "Unknown" except ImportError: self.selinux_enabled = SELINUX_DISABLED self.selinux_policy = "Not Installed" self.selinux_enforce = "Not Installed" else: self.selinux_enabled = SELINUX_WITHHELD self.selinux_policy = WITHHELD_MAGIC_STRING self.selinux_enforce = WITHHELD_MAGIC_STRING
def default_ro_container_context(): if selinux.is_selinux_enabled() != 0: return selinux.getfilecon("/usr")[1] return ""
def convert_db(self): dbtype = self.get_dbtype() if dbtype is None: raise ValueError( "NSS database {} does not exist".format(self.directory) ) elif dbtype == 'sql': raise ValueError( "NSS database {} already in SQL format".format(self.directory) ) logger.info( "Convert NSSDB %s from DBM to SQL format", self.directory ) basecmd = [ 'certutil', '-d', 'sql:{}'.format(self.directory), '-f', self.password_file, ] # See https://fedoraproject.org/wiki/Changes/NSSDefaultFileFormatSql cmd = basecmd + [ '-N', '-@', self.password_file ] logger.debug('Command: %s', ' '.join(map(str, cmd))) subprocess.check_call(cmd) migration = ( ('cert8.db', 'cert9.db'), ('key3.db', 'key4.db'), ('secmod.db', 'pkcs11.txt'), ) for oldname, newname in migration: oldname = os.path.join(self.directory, oldname) newname = os.path.join(self.directory, newname) oldstat = os.stat(oldname) os.chmod(newname, stat.S_IMODE(oldstat.st_mode)) os.chown(newname, oldstat.st_uid, oldstat.st_gid) if selinux is not None and selinux.is_selinux_enabled(): selinux.restorecon(self.directory, recursive=True) # list certs to verify DB if self.get_dbtype() != 'sql': raise RuntimeError( "Migration of NSS database {} was not successfull.".format( self.directory ) ) with open(os.devnull, 'wb') as f: subprocess.check_call(basecmd + ['-L'], stdout=f) for oldname, _ in migration: # pylint: disable=unused-variable oldname = os.path.join(self.directory, oldname) os.rename(oldname, oldname + '.migrated') logger.info("Migration successful")
def get_runtime_status(ignore_selinux_state=False): return True if ignore_selinux_state is True else selinux.is_selinux_enabled( )
def is_selinux_enabled(): return selinux.is_selinux_enabled()
""" Base class for tools that handle POSIX (Path) entries """ import os import sys import pwd import grp import stat import copy import shutil import Bcfg2.Client.Tools import Bcfg2.Client.XML from Bcfg2.Compat import oct_mode try: import selinux HAS_SELINUX = selinux.is_selinux_enabled() except ImportError: HAS_SELINUX = False try: import posix1e HAS_ACLS = True # map between permissions characters and numeric ACL constants ACL_MAP = dict(r=posix1e.ACL_READ, w=posix1e.ACL_WRITE, x=posix1e.ACL_EXECUTE) except ImportError: HAS_ACLS = False ACL_MAP = dict(r=4, w=2, x=1)
def _process_file(self, *args): owner_report = "%s:%s" group_report = "%s:%s" perm_report = "%s:%s" selinux_report = "%s|%s" src, dst, file, type, info = args[:5] owner_status = "" group_status = "" perm_status = "" selinux_status = "" status = [] stat_err = 0 #Stat the destination file try: dst_stat = os.lstat(dst) except: stat_err = 1 if type != 'symlink': src_user = info['username'] if not stat_err: #check for owner differences dst_uid = dst_stat[stat.ST_UID] try: dst_user = pwd.getpwuid(dst_uid)[0] except KeyError: # Orphan UID with no name,return unknown dst_user = "******" % (dst_uid, ) else: dst_user = "******" #owner_status gets displayed with the verbose option. if src_user == dst_user: owner_status = "" else: owner_status = owner_report % (src_user, dst_user) status.append('user') src_group = info['groupname'] if not stat_err: #check for group differences dst_gid = dst_stat[stat.ST_GID] try: dst_group = grp.getgrgid(dst_gid)[0] except KeyError: # Orphan GID with no name,return unknown dst_group = "unknown(GID %d)" % (dst_gid, ) else: dst_group = "missing" #group_status gets displayed with the verbose option. if src_group == dst_group: group_status = "" else: group_status = group_report % (src_group, dst_group) status.append('group') #check for permissions differences src_perm = str(info['filemode']) if not stat_err: #The mode returned by stat is decimal, but won't match the value in file_info unless it's octal. #Unfortunately, the mode in file_info looks like the octal value of the mode, except it's in decimal. #The solution I came up with is to convert them both into strings, rip off the leading '0' from the #mode returned by stat, use the resulting strings. It sucks, but it seems to work (for now). dst_perm = str(oct(stat.S_IMODE(dst_stat[stat.ST_MODE]))) else: dst_perm = "missing" #rip off the leading '0' from the mode returned by stat() if dst_perm[0] == '0': dst_perm = dst_perm[1:] #perm_status gets displayed with the verbose option. if src_perm == dst_perm: perm_status = "" else: perm_status = perm_report % (src_perm, dst_perm) status.append('mode') # compare selinux contexts if info.has_key('selinux_ctx'): src_selinux = info['selinux_ctx'] if src_selinux: if not stat_err: try: dst_selinux = lgetfilecon(dst)[1] except OSError: dst_selinux = "" if not is_selinux_enabled(): dst_selinux = "" if dst_selinux == None: dst_selinux = "" else: dst_selinux = "missing" if src_selinux == dst_selinux: selinux_status = "" else: selinux_status = selinux_report % (src_selinux, dst_selinux) status.append('selinux') #figure out the ultimate value of status. if stat_err: status = ["missing"] elif type == 'symlink': if not os.path.islink(file): status = ["missing"] elif os.readlink(file) != info['symlink']: status.append('target-link-modified') elif type == 'directory': if not os.path.isdir(file): status = ["missing"] elif not os.access(dst, os.R_OK): status = ["missing"] else: src_sha1 = utils.sha1_file(src) dst_sha1 = utils.sha1_file(dst) if src_sha1 != dst_sha1: status.append('modified') return { "status": ','.join(status), "owner": owner_status, "group": group_status, "mode": perm_status, "selinux": selinux_status, "file": file, }
on_travis_ci, ) requires_root = pytest.mark.skipif( os.geteuid() != 0, reason="requires root") requires_unprivileged_user = pytest.mark.skipif( os.geteuid() == 0, reason="This test can not run as root") requires_sanlock = pytest.mark.skipif( isinstance(sanlock, compat.MissingModule), reason="sanlock is not available") requires_selinux = pytest.mark.skipif( not selinux.is_selinux_enabled(), reason="Selinux is not enabled") xfail_python3 = pytest.mark.xfail( six.PY3, reason="needs porting to python 3") xfail_python37 = pytest.mark.xfail( sys.version_info[:2] == (3, 7), reason="needs porting to python 3.7") # Note: This cannot be strict since in oVirt CI we run with older qemu-img # version that does not reproduce this issue. xfail_requires_target_is_zero = pytest.mark.xfail( not qemuimg.target_is_zero_supported(), reason="requires qemu-img convert --target-is-zero introdued in 5.1.0", strict=False) broken_on_ci = pytest.mark.skipif(
def have_selinux(): return bool(selinux) and bool(selinux.is_selinux_enabled())
def _validation(self): self._selinux_enabled = selinux.is_selinux_enabled()
def run(self, ybo, product, version, release, variant="", bugurl="", isfinal=False, workdir=None, outputdir=None, buildarch=None, volid=None, domacboot=True, remove_temp=False): assert self._configured if domacboot: try: runcmd(["rpm", "-q", "hfsplus-tools"]) except CalledProcessError: logger.critical( "you need to install hfsplus-tools to create mac images") sys.exit(1) # set up work directory self.workdir = workdir or tempfile.mkdtemp(prefix="pylorax.work.") if not os.path.isdir(self.workdir): os.makedirs(self.workdir) # set up log directory logdir = '/var/log/lorax' if not os.path.isdir(logdir): os.makedirs(logdir) self.init_stream_logging() self.init_file_logging(logdir) logger.debug("using work directory {0.workdir}".format(self)) logger.debug("using log directory {0}".format(logdir)) # set up output directory self.outputdir = outputdir or tempfile.mkdtemp(prefix="pylorax.out.") if not os.path.isdir(self.outputdir): os.makedirs(self.outputdir) logger.debug("using output directory {0.outputdir}".format(self)) # do we have root privileges? logger.info("checking for root privileges") if not os.geteuid() == 0: logger.critical("no root privileges") sys.exit(1) # is selinux disabled? # With selinux in enforcing mode the rpcbind package required for # dracut nfs module, which is in turn required by anaconda module, # will not get installed, because it's preinstall scriptlet fails, # resulting in an incomplete initial ramdisk image. # The reason is that the scriptlet runs tools from the shadow-utils # package in chroot, particularly groupadd and useradd to add the # required rpc group and rpc user. This operation fails, because # the selinux context on files in the chroot, that the shadow-utils # tools need to access (/etc/group, /etc/passwd, /etc/shadow etc.), # is wrong and selinux therefore disallows access to these files. logger.info("checking the selinux mode") if selinux.is_selinux_enabled() and selinux.security_getenforce(): logger.critical("selinux must be disabled or in Permissive mode") sys.exit(1) # do we have a proper yum base object? logger.info("checking yum base object") if not isinstance(ybo, yum.YumBase): logger.critical("no yum base object") sys.exit(1) self.inroot = ybo.conf.installroot logger.debug("using install root: {0}".format(self.inroot)) if not buildarch: buildarch = get_buildarch(ybo) logger.info("setting up build architecture") self.arch = ArchData(buildarch) for attr in ('buildarch', 'basearch', 'libdir'): logger.debug("self.arch.%s = %s", attr, getattr(self.arch, attr)) logger.info("setting up build parameters") product = DataHolder(name=product, version=version, release=release, variant=variant, bugurl=bugurl, isfinal=isfinal) self.product = product logger.debug("product data: %s" % product) # NOTE: if you change isolabel, you need to change pungi to match, or # the pungi images won't boot. isolabel = volid or "{0.name} {0.version} {1.basearch}".format( self.product, self.arch) if len(isolabel) > 32: logger.fatal("the volume id cannot be longer than 32 characters") sys.exit(1) templatedir = self.conf.get("lorax", "sharedir") # NOTE: rb.root = ybo.conf.installroot (== self.inroot) rb = RuntimeBuilder(product=self.product, arch=self.arch, yum=ybo, templatedir=templatedir) logger.info("installing runtime packages") rb.yum.conf.skip_broken = self.conf.getboolean("yum", "skipbroken") rb.install() # write .buildstamp buildstamp = BuildStamp(self.product.name, self.product.version, self.product.bugurl, self.product.isfinal, self.arch.buildarch) buildstamp.write(joinpaths(self.inroot, ".buildstamp")) if self.debug: rb.writepkglists(joinpaths(logdir, "pkglists")) rb.writepkgsizes(joinpaths(logdir, "original-pkgsizes.txt")) logger.info("doing post-install configuration") rb.postinstall() # write .discinfo discinfo = DiscInfo(self.product.release, self.arch.basearch) discinfo.write(joinpaths(self.outputdir, ".discinfo")) logger.info("backing up installroot") installroot = joinpaths(self.workdir, "installroot") linktree(self.inroot, installroot) logger.info("generating kernel module metadata") rb.generate_module_data() logger.info("cleaning unneeded files") rb.cleanup() if self.debug: rb.writepkgsizes(joinpaths(logdir, "final-pkgsizes.txt")) logger.info("creating the runtime image") runtime = "images/install.img" compression = self.conf.get("compression", "type") compressargs = self.conf.get("compression", "args").split() if self.conf.getboolean("compression", "bcj"): if self.arch.bcj: compressargs += ["-Xbcj", self.arch.bcj] else: logger.info("no BCJ filter for arch %s", self.arch.basearch) rb.create_runtime(joinpaths(installroot, runtime), compression=compression, compressargs=compressargs) logger.info("preparing to build output tree and boot images") treebuilder = TreeBuilder(product=self.product, arch=self.arch, inroot=installroot, outroot=self.outputdir, runtime=runtime, isolabel=isolabel, domacboot=domacboot, templatedir=templatedir) logger.info("rebuilding initramfs images") dracut_args = ["--xz", "--install", "/.buildstamp"] anaconda_args = dracut_args + ["--add", "anaconda pollcdrom"] treebuilder.rebuild_initrds(add_args=anaconda_args) # Build upgrade.img. It'd be nice if these could coexist in the same # image, but that would increase the size of the anaconda initramfs, # which worries some people (esp. PPC tftpboot). So they're separate. try: # If possible, use the 'fedup' plymouth theme themes = runcmd_output(['plymouth-set-default-theme', '--list'], root=installroot) if 'fedup' in themes.splitlines(): os.environ['PLYMOUTH_THEME_NAME'] = 'fedup' except RuntimeError: pass upgrade_args = dracut_args + ["--add", "system-upgrade"] treebuilder.rebuild_initrds(add_args=upgrade_args, prefix="upgrade") logger.info("populating output tree and building boot images") treebuilder.build() # write .treeinfo file and we're done treeinfo = TreeInfo(self.product.name, self.product.version, self.product.variant, self.arch.basearch) for section, data in treebuilder.treeinfo_data.items(): treeinfo.add_section(section, data) treeinfo.write(joinpaths(self.outputdir, ".treeinfo")) # cleanup if remove_temp: remove(self.workdir)
def spawn(self, deployer): if config.str2bool(deployer.mdict['pki_skip_installation']): logger.info('Skipping SELinux setup') return if not selinux.is_selinux_enabled() or seobject is None: logger.info('SELinux disabled') return logger.info('Creating SELinux contexts') # A maximum of 10 tries to create the SELinux contexts counter = 0 max_tries = 10 while True: try: # check first if any transactions are required if len(ports) == 0 and deployer.mdict['pki_instance_name'] == \ config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME: self.restore_context(deployer.mdict) return # add SELinux contexts when adding the first subsystem if len(deployer.instance.tomcat_instance_subsystems()) == 1: trans = seobject.semanageRecords("targeted") trans.start() if deployer.mdict['pki_instance_name'] != \ config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME: fcon = seobject.fcontextRecords(trans) logger.info( "adding selinux fcontext \"%s\"", deployer.mdict['pki_instance_path'] + self.suffix) fcon.add( deployer.mdict['pki_instance_path'] + self.suffix, config.PKI_INSTANCE_SELINUX_CONTEXT, "", "s0", "") logger.info( "adding selinux fcontext \"%s\"", deployer.mdict['pki_instance_log_path'] + self.suffix) fcon.add( deployer.mdict['pki_instance_log_path'] + self.suffix, config.PKI_LOG_SELINUX_CONTEXT, "", "s0", "") logger.info( "adding selinux fcontext \"%s\"", deployer.mdict['pki_instance_configuration_path'] + self.suffix) fcon.add( deployer.mdict['pki_instance_configuration_path'] + self.suffix, config.PKI_CFG_SELINUX_CONTEXT, "", "s0", "") logger.info( "adding selinux fcontext \"%s\"", deployer.mdict['pki_server_database_path'] + self.suffix) fcon.add( deployer.mdict['pki_server_database_path'] + self.suffix, config.PKI_CERTDB_SELINUX_CONTEXT, "", "s0", "") port_records = seobject.portRecords(trans) for port in ports: logger.info("adding selinux port %s", port) port_records.add( port, "tcp", "s0", config.PKI_PORT_SELINUX_CONTEXT) trans.finish() self.restore_context(deployer.mdict) break except ValueError as e: error_message = str(e) logger.error(error_message) if error_message.strip() == \ "Could not start semanage transaction": counter += 1 if counter >= max_tries: raise time.sleep(5) logger.debug("Retrying to setup the selinux context ...") else: raise
def destroy(self, deployer): if not bool(selinux.is_selinux_enabled()): logger.info('SELinux disabled') return # check first if any transactions are required if (len(ports) == 0 and deployer.mdict['pki_instance_name'] == config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME): return logger.info('Removing SELinux contexts') # A maximum of 10 tries to delete the SELinux contexts max_tries = 10 for counter in range(1, max_tries): try: # remove SELinux contexts when removing the last subsystem if len(deployer.instance.tomcat_instance_subsystems()) == 0: trans = seobject.semanageRecords("targeted") trans.start() if deployer.mdict['pki_instance_name'] != \ config.PKI_DEPLOYMENT_DEFAULT_TOMCAT_INSTANCE_NAME: fcon = seobject.fcontextRecords(trans) file_records = fcon.get_all() if self.context_exists(file_records, deployer.mdict['pki_instance_path'] + self.suffix): logger.info( "deleting selinux fcontext \"%s\"", deployer.mdict['pki_instance_path'] + self.suffix) fcon.delete( deployer.mdict['pki_instance_path'] + self.suffix, "") if self.context_exists(file_records, deployer.mdict['pki_instance_log_path'] + self.suffix): logger.info( "deleting selinux fcontext \"%s\"", deployer.mdict['pki_instance_log_path'] + self.suffix) fcon.delete( deployer.mdict['pki_instance_log_path'] + self.suffix, "") if self.context_exists(file_records, deployer.mdict['pki_instance_configuration_path'] + self.suffix): logger.info( "deleting selinux fcontext \"%s\"", deployer.mdict['pki_instance_configuration_path'] + self.suffix) fcon.delete( deployer.mdict['pki_instance_configuration_path'] + self.suffix, "") if self.context_exists(file_records, deployer.mdict['pki_server_database_path'] + self.suffix): logger.info( "deleting selinux fcontext \"%s\"", deployer.mdict['pki_server_database_path'] + self.suffix) fcon.delete( deployer.mdict['pki_server_database_path'] + self.suffix, "") port_records = seobject.portRecords(trans) port_record_values = port_records.get_all() for port in ports: if self.context_exists(port_record_values, port): logger.info("deleting selinux port %s", port) port_records.delete(port, "tcp") trans.finish() break except ValueError as e: error_message = str(e) logger.error(error_message) if error_message.strip() == \ "Could not start semanage transaction": if counter >= max_tries: raise time.sleep(5) logger.debug("Retrying to remove selinux context ...") else: raise
def selinux_role(self): """Setup proper selinux role. this must be called at beginning of process to adjust proper roles for selinux. it will re-execute the process with same arguments. This has similar effect of: # chcon -t rpm_exec_t executable.py We must do this dynamic as this class is to be used at bootstrap stage, so we cannot put any persistent selinux policy changes, and have no clue if filesystem where we put scripts supports extended attributes, or if we have proper role for chcon. """ try: import selinux except ImportError: package_name = None if sys.version_info.major == 2: package_name = 'libselinux-python' elif sys.version_info.major == 3: package_name = 'libselinux-python3' else: # Unknown python version, do nothing for now pass if package_name is not None: package_installed = False with self.transaction(): self.install([package_name]) if self.buildTransaction(): self.processTransaction() package_installed = True # # on fedora-18 for example # the selinux core is updated # so we fail resolving symbols # solution is re-execute the process # after installation. # if package_installed: self._sink.reexec() os.execv(sys.executable, [sys.executable] + sys.argv) os._exit(1) if selinux.is_selinux_enabled(): rc, ctx = selinux.getcon() if rc != 0: raise Exception(_('Cannot get selinux context')) ctx1 = selinux.context_new(ctx) if not ctx1: raise Exception(_('Cannot create selinux context')) if selinux.context_role_get(ctx1) != 'system_r': if selinux.context_role_set(ctx1, 'system_r') != 0: raise Exception( _('Cannot set role within selinux context')) if selinux.setexeccon(selinux.context_str(ctx1)) != 0: raise Exception(_('Cannot set selinux exec context')) self._sink.reexec() os.execv(sys.executable, [sys.executable] + sys.argv) os._exit(1)
then verify we have returned to the proper hub. Since most spokes are off the summary hub, that's the default. If we are not back on the hub, the current test case will be failed. """ button = self.find("_Done", "push button", node=node) self.assertIsNotNone(button, msg="Done button not found") button.click() doDelay(5) self.check_window_displayed(hubName) @unittest.skipIf(os.geteuid() != 0, "GUI tests must be run as root") @unittest.skipIf( os.environ.get("DISPLAY", "") == "", "DISPLAY must be defined") @unittest.skipIf( selinux.is_selinux_enabled() and selinux.security_getenforce() == 1, "SELinux must be disabled or in Permissive mode, see rhbz#1276376") @unittest.skipIf(not isA11yEnabled(), "Assistive Technologies are disabled") class DogtailTestCase(unittest.TestCase): """A subclass that defines all the parameters for starting a local copy of anaconda, inspecting results, and managing temporary data! Most subclasses will only need to define the following four attributes: drives -- A list of tuples describing disk images to create. Each tuple is the name of the drive and its size as a blivet.Size. environ -- A dictionary of environment variables that should be added to the environment the test suite will run under. name -- A unique string that names the test. This name will be used in creating the results directory (and perhaps other places in the future) so make sure it doesn't
def __init__(self): self._log = logging.getLogger("%s.StorageServer" % __name__) self._log.addFilter(log_filter.get_intermittent_filter()) self._config = config.Config(logger=self._log) self._cli = util.connect_vdsm_json_rpc( logger=self._log, timeout=constants.VDSCLI_SSL_TIMEOUT ) self._type = self._config.get(config.ENGINE, const.DOMAIN_TYPE) self._spUUID = self._config.get(config.ENGINE, const.SP_UUID) self._sdUUID = self._config.get(config.ENGINE, const.SD_UUID) self._storage = self._config.get(config.ENGINE, const.STORAGE) self._HEVMID = self._config.get(config.ENGINE, const.HEVMID) self._host_id = int(self._config.get(config.ENGINE, const.HOST_ID)) self._fake_sd_size = '2G' self._vfstype = 'ext3' self._vm_img_uuid = self._config.get( config.ENGINE, const.VM_DISK_IMG_ID ) vm_vol_uuid = None try: vm_vol_uuid = self._config.get( config.ENGINE, const.VM_DISK_VOL_ID ) except (KeyError, ValueError): try: vm_vol_uuid = self._cli.StorageDomain.getVolumes( imageID=self._vm_img_uuid, storagepoolID=self._spUUID, storagedomainID=self._sdUUID, )[0] except ServerError: # Ignore error pass self._vm_vol_uuid = vm_vol_uuid self._conf_imgUUID = None self._conf_volUUID = None self._metadata_imgUUID = self._config.get( config.ENGINE, const.METADATA_IMAGE_UUID, ) self._metadata_volUUID = self._config.get( config.ENGINE, const.METADATA_VOLUME_UUID, ) self._lockspace_imgUUID = self._config.get( config.ENGINE, const.LOCKSPACE_IMAGE_UUID, ) self._lockspace_volUUID = self._config.get( config.ENGINE, const.LOCKSPACE_VOLUME_UUID, ) self._fake_SD_path = None self._fake_file = None self._fake_mastersd_uuid = str(uuid.uuid4()) self._selinux_enabled = selinux.is_selinux_enabled() self._fake_master_connection_uuid = str(uuid.uuid4())
def test_default_container_context(self): exp = ('system_u:object_r:svirt_sandbox_file_t:s0' if selinux.is_selinux_enabled() else '') self.assertEqual(exp, util.default_container_context())
def run(self, dbo, product, version, release, variant="", bugurl="", isfinal=False, workdir=None, outputdir=None, buildarch=None, volid=None, domacboot=True, doupgrade=True, remove_temp=False, installpkgs=None, excludepkgs=None, size=2, add_templates=None, add_template_vars=None, add_arch_templates=None, add_arch_template_vars=None, verify=True): assert self._configured installpkgs = installpkgs or [] excludepkgs = excludepkgs or [] # get lorax version try: import pylorax.version except ImportError: vernum = "devel" else: vernum = pylorax.version.num if domacboot: try: runcmd(["rpm", "-q", "hfsplus-tools"]) except CalledProcessError: logger.critical( "you need to install hfsplus-tools to create mac images") sys.exit(1) # set up work directory self.workdir = workdir or tempfile.mkdtemp(prefix="pylorax.work.") if not os.path.isdir(self.workdir): os.makedirs(self.workdir) # set up log directory logdir = self.conf.get("lorax", "logdir") if not os.path.isdir(logdir): os.makedirs(logdir) self.init_stream_logging() self.init_file_logging(logdir) logger.debug("version is %s", vernum) logger.debug("using work directory %s", self.workdir) logger.debug("using log directory %s", logdir) # set up output directory self.outputdir = outputdir or tempfile.mkdtemp(prefix="pylorax.out.") if not os.path.isdir(self.outputdir): os.makedirs(self.outputdir) logger.debug("using output directory %s", self.outputdir) # do we have root privileges? logger.info("checking for root privileges") if not os.geteuid() == 0: logger.critical("no root privileges") sys.exit(1) # is selinux disabled? # With selinux in enforcing mode the rpcbind package required for # dracut nfs module, which is in turn required by anaconda module, # will not get installed, because it's preinstall scriptlet fails, # resulting in an incomplete initial ramdisk image. # The reason is that the scriptlet runs tools from the shadow-utils # package in chroot, particularly groupadd and useradd to add the # required rpc group and rpc user. This operation fails, because # the selinux context on files in the chroot, that the shadow-utils # tools need to access (/etc/group, /etc/passwd, /etc/shadow etc.), # is wrong and selinux therefore disallows access to these files. logger.info("checking the selinux mode") if selinux.is_selinux_enabled() and selinux.security_getenforce(): logger.critical("selinux must be disabled or in Permissive mode") sys.exit(1) # do we have a proper dnf base object? logger.info("checking dnf base object") if not isinstance(dbo, dnf.Base): logger.critical("no dnf base object") sys.exit(1) self.inroot = dbo.conf.installroot logger.debug("using install root: %s", self.inroot) if not buildarch: buildarch = get_buildarch(dbo) logger.info("setting up build architecture") self.arch = ArchData(buildarch) for attr in ('buildarch', 'basearch', 'libdir'): logger.debug("self.arch.%s = %s", attr, getattr(self.arch, attr)) logger.info("setting up build parameters") self.product = DataHolder(name=product, version=version, release=release, variant=variant, bugurl=bugurl, isfinal=isfinal) logger.debug("product data: %s", self.product) # NOTE: if you change isolabel, you need to change pungi to match, or # the pungi images won't boot. isolabel = volid or "%s-%s-%s" % ( self.product.name, self.product.version, self.arch.basearch) if len(isolabel) > 32: logger.fatal("the volume id cannot be longer than 32 characters") sys.exit(1) # NOTE: rb.root = dbo.conf.installroot (== self.inroot) rb = RuntimeBuilder(product=self.product, arch=self.arch, dbo=dbo, templatedir=self.templatedir, installpkgs=installpkgs, excludepkgs=excludepkgs, add_templates=add_templates, add_template_vars=add_template_vars) logger.info("installing runtime packages") rb.install() # write .buildstamp buildstamp = BuildStamp(self.product.name, self.product.version, self.product.bugurl, self.product.isfinal, self.arch.buildarch) buildstamp.write(joinpaths(self.inroot, ".buildstamp")) if self.debug: rb.writepkglists(joinpaths(logdir, "pkglists")) rb.writepkgsizes(joinpaths(logdir, "original-pkgsizes.txt")) logger.info("doing post-install configuration") rb.postinstall() # write .discinfo discinfo = DiscInfo(self.product.release, self.arch.basearch) discinfo.write(joinpaths(self.outputdir, ".discinfo")) logger.info("backing up installroot") installroot = joinpaths(self.workdir, "installroot") linktree(self.inroot, installroot) logger.info("generating kernel module metadata") rb.generate_module_data() logger.info("cleaning unneeded files") rb.cleanup() if verify: logger.info("verifying the installroot") if not rb.verify(): sys.exit(1) else: logger.info("Skipping verify") if self.debug: rb.writepkgsizes(joinpaths(logdir, "final-pkgsizes.txt")) logger.info("creating the runtime image") runtime = "images/install.img" compression = self.conf.get("compression", "type") compressargs = self.conf.get("compression", "args").split() # pylint: disable=no-member if self.conf.getboolean("compression", "bcj"): if self.arch.bcj: compressargs += ["-Xbcj", self.arch.bcj] else: logger.info("no BCJ filter for arch %s", self.arch.basearch) rb.create_runtime(joinpaths(installroot, runtime), compression=compression, compressargs=compressargs, size=size) rb.finished() logger.info("preparing to build output tree and boot images") treebuilder = TreeBuilder(product=self.product, arch=self.arch, inroot=installroot, outroot=self.outputdir, runtime=runtime, isolabel=isolabel, domacboot=domacboot, doupgrade=doupgrade, templatedir=self.templatedir, add_templates=add_arch_templates, add_template_vars=add_arch_template_vars, workdir=self.workdir) logger.info("rebuilding initramfs images") dracut_args = [ "--xz", "--install", "/.buildstamp", "--no-early-microcode" ] anaconda_args = dracut_args + [ "--add", "anaconda pollcdrom qemu qemu-net" ] # ppc64 cannot boot an initrd > 32MiB so remove some drivers if self.arch.basearch in ("ppc64", "ppc64le"): dracut_args.extend(["--omit-drivers", REMOVE_PPC64_DRIVERS]) # Only omit dracut modules from the initrd so that they're kept for # upgrade.img anaconda_args.extend(["--omit", REMOVE_PPC64_MODULES]) treebuilder.rebuild_initrds(add_args=anaconda_args) logger.info("populating output tree and building boot images") treebuilder.build() # write .treeinfo file and we're done treeinfo = TreeInfo(self.product.name, self.product.version, self.product.variant, self.arch.basearch) for section, data in treebuilder.treeinfo_data.items(): treeinfo.add_section(section, data) treeinfo.write(joinpaths(self.outputdir, ".treeinfo")) # cleanup if remove_temp: remove(self.workdir)
def createBrick(brickName, mountPoint, devNameList, fsType=DEFAULT_FS_TYPE, raidParams={}): def _getDeviceList(devNameList): return [ blivetEnv.devicetree.getDeviceByName(devName.split("/")[-1]) for devName in devNameList ] def _createPV(deviceList, alignment): for dev in deviceList: # bz#1178705: Blivet always creates pv with 1MB dataalignment # Workaround: Till blivet fixes the issue, we use lvm pvcreate rc, out, err = commands.execCmd([ _pvCreateCommandPath.cmd, '--dataalignment', '%sk' % alignment, dev.path ]) if rc: raise ge.GlusterHostStorageDevicePVCreateFailedException( dev.path, alignment, rc, out, err) _reset_blivet(blivetEnv) return _getDeviceList([dev.name for dev in deviceList]) def _createVG(vgName, deviceList, stripeSize): # bz#1198568: Blivet always creates vg with 1MB stripe size # Workaround: Till blivet fixes the issue, use vgcreate command devices = ','.join([device.path for device in deviceList]) rc, out, err = commands.execCmd([ _vgCreateCommandPath.cmd, '-s', '%sk' % stripeSize, vgName, devices ]) if rc: raise ge.GlusterHostStorageDeviceVGCreateFailedException( vgName, devices, stripeSize, rc, out, err) blivetEnv.reset() return blivetEnv.devicetree.getDeviceByName(vgName) def _createThinPool(poolName, vg, alignment, poolMetaDataSize, poolDataSize): metaName = "meta-%s" % poolName vgPoolName = "%s/%s" % (vg.name, poolName) metaLv = LVMLogicalVolumeDevice(metaName, parents=[vg], size=blivet.size.Size( '%d KiB' % poolMetaDataSize)) poolLv = LVMLogicalVolumeDevice(poolName, parents=[vg], size=blivet.size.Size('%d KiB' % poolDataSize)) blivetEnv.createDevice(metaLv) blivetEnv.createDevice(poolLv) blivetEnv.doIt() # bz#1100514: LVM2 currently only supports physical extent sizes # that are a power of 2. Till that support is available we need # to use lvconvert to achive that. # bz#1179826: blivet doesn't support lvconvert functionality. # Workaround: Till the bz gets fixed, lvconvert command is used rc, out, err = commands.execCmd([ _lvconvertCommandPath.cmd, '--chunksize', '%sK' % alignment, '--thinpool', vgPoolName, '--poolmetadata', "%s/%s" % (vg.name, metaName), '--poolmetadataspar', 'n', '-y' ]) if rc: raise ge.GlusterHostStorageDeviceLVConvertFailedException( vg.path, alignment, rc, out, err) rc, out, err = commands.execCmd( [_lvchangeCommandPath.cmd, '--zero', 'n', vgPoolName]) if rc: raise ge.GlusterHostStorageDeviceLVChangeFailedException( vgPoolName, rc, out, err) _reset_blivet(blivetEnv) return blivetEnv.devicetree.getDeviceByName(poolLv.name) if os.path.ismount(mountPoint): raise ge.GlusterHostStorageMountPointInUseException(mountPoint) vgName = "vg-" + brickName poolName = "pool-" + brickName poolDataSize = 0 count = 0 raidType = raidParams.get('type') metaDataSizeKib = DEFAULT_METADATA_SIZE_KB if raidType == '6': count = raidParams['pdCount'] - 2 alignment = raidParams['stripeSize'] * count chunkSize = alignment elif raidType == '10': count = raidParams['pdCount'] // 2 alignment = raidParams['stripeSize'] * count chunkSize = DEFAULT_CHUNK_SIZE_KB else: # Device type is JBOD alignment = DEFAULT_CHUNK_SIZE_KB chunkSize = DEFAULT_CHUNK_SIZE_KB blivetEnv = blivet.Blivet() _reset_blivet(blivetEnv) # get the devices list from the device name deviceList = _getDeviceList(devNameList) # raise an error when any device not actually found in the given list notFoundList = set(devNameList).difference( set([dev.name for dev in deviceList])) if notFoundList: raise ge.GlusterHostStorageDeviceNotFoundException(notFoundList) # raise an error when any device is used already in the given list inUseList = set(devNameList).difference( set([not _canCreateBrick(dev) or dev.name for dev in deviceList])) if inUseList: raise ge.GlusterHostStorageDeviceInUseException(inUseList) pvDeviceList = _createPV(deviceList, alignment) vg = _createVG(vgName, pvDeviceList, alignment) # The following calculation is based on the redhat storage performance doc # http://docbuilder.usersys.redhat.com/22522 # /#chap-Configuring_Red_Hat_Storage_for_Enhancing_Performance # create ~16GB metadata LV (metaDataSizeKib) that has a size which is # a multiple of RAID stripe width if it is > minimum vg size # otherwise allocate a minimum of 0.5% of the data device size # and create data LV (poolDataSize) that has a size which is # a multiple of stripe width. vgSizeKib = int(_getDeviceSize(vg, 'KiB')) if _getDeviceSize(vg) < MIN_VG_SIZE: metaDataSizeKib = vgSizeKib * MIN_METADATA_PERCENT poolDataSize = vgSizeKib - metaDataSizeKib metaDataSizeKib = (metaDataSizeKib - (metaDataSizeKib % alignment)) poolDataSize = (poolDataSize - (poolDataSize % alignment)) # Creating a thin pool from the data LV and the metadata LV # lvconvert --chunksize alignment --thinpool VOLGROUP/thin_pool # --poolmetadata VOLGROUP/metadata_device_name pool = _createThinPool(poolName, vg, chunkSize, metaDataSizeKib, poolDataSize) # Size of the thin LV should be same as the size of Thinpool to avoid # over allocation. Refer bz#1412455 for more info. thinlv = LVMThinLogicalVolumeDevice(brickName, parents=[pool], size=blivet.size.Size('%d KiB' % poolDataSize), grow=True) blivetEnv.createDevice(thinlv) blivetEnv.doIt() if fsType != DEFAULT_FS_TYPE: log.error("fstype %s is currently unsupported" % fsType) raise ge.GlusterHostStorageDeviceMkfsFailedException(fsType) format = blivet.formats.getFormat(DEFAULT_FS_TYPE, device=thinlv.path, mountopts=DEFAULT_MOUNT_OPTIONS) format._defaultFormatOptions = ["-f", "-i", "size=512", "-n", "size=8192"] if raidParams.get('type') == '6': format._defaultFormatOptions += [ "-d", "sw=%s,su=%sk" % (count, raidParams.get('stripeSize')) ] blivetEnv.formatDevice(thinlv, format) blivetEnv.doIt() try: os.makedirs(mountPoint) except OSError as e: if errno.EEXIST != e.errno: errMsg = "[Errno %s] %s: '%s'" % (e.errno, e.strerror, e.filename) raise ge.GlusterHostStorageDeviceMakeDirsFailedException( err=[errMsg]) thinlv.format.setup(mountpoint=mountPoint) blivetEnv.doIt() # bz#1230495: lvm devices are invisible and appears only after vgscan # Workaround: Till the bz gets fixed, We use vgscan to refresh LVM devices rc, out, err = commands.execCmd([_vgscanCommandPath.cmd]) if rc: raise ge.GlusterHostStorageDeviceVGScanFailedException(rc, out, err) fstab.FsTab().add(thinlv.path, mountPoint, DEFAULT_FS_TYPE, mntOpts=[DEFAULT_MOUNT_OPTIONS]) # If selinux is enabled, set correct selinux labels on the brick. if selinux.is_selinux_enabled(): rc, out, err = commands.execCmd([ _semanageCommandPath.cmd, 'fcontext', '-a', '-t', 'glusterd_brick_t', mountPoint ]) if rc: raise ge.GlusterHostFailedToSetSelinuxContext( mountPoint, rc, out, err) try: # mountPoint can be of 'unicode' type when its passed through # jsonrpc. restorecon calls into a C API that needs a char *. # Thus, it is necessary to encode unicode to a utf-8 string. selinux.restorecon(mountPoint.encode('utf-8'), recursive=True) except OSError as e: errMsg = "[Errno %s] %s: '%s'" % (e.errno, e.strerror, e.filename) raise ge.GlusterHostFailedToRunRestorecon(mountPoint, err=errMsg) return _getDeviceDict(thinlv)
def main(): module = AnsibleModule(argument_spec=dict( policy=dict(required=False), state=dict(choices=['enforcing', 'permissive', 'disabled'], required=True), configfile=dict(aliases=['conf', 'file'], default='/etc/selinux/config')), supports_check_mode=True) if not HAS_SELINUX: module.fail_json(msg='libselinux-python required for this module') # global vars changed = False msgs = [] configfile = module.params['configfile'] policy = module.params['policy'] state = module.params['state'] runtime_enabled = selinux.is_selinux_enabled() runtime_policy = selinux.selinux_getpolicytype()[1] runtime_state = 'disabled' reboot_required = False if runtime_enabled: # enabled means 'enforcing' or 'permissive' if selinux.security_getenforce(): runtime_state = 'enforcing' else: runtime_state = 'permissive' if not os.path.isfile(configfile): module.fail_json(msg="Unable to find file {0}".format(configfile), details="Please install SELinux-policy package, " "if this package is not installed previously.") config_policy = get_config_policy(configfile) config_state = get_config_state(configfile) # check to see if policy is set if state is not 'disabled' if state != 'disabled': if not policy: module.fail_json( msg='Policy is required if state is not \'disabled\'') else: if not policy: policy = config_policy # check changed values and run changes if policy != runtime_policy: if module.check_mode: module.exit_json(changed=True) # cannot change runtime policy msgs.append('Running SELinux policy changed from \'%s\' to \'%s\'' % (runtime_policy, policy)) changed = True if policy != config_policy: if module.check_mode: module.exit_json(changed=True) set_config_policy(module, policy, configfile) msgs.append( 'SELinux policy configuration in \'%s\' changed from \'%s\' to \'%s\'' % (configfile, config_policy, policy)) changed = True if state != runtime_state: if runtime_enabled: if state == 'disabled': if runtime_state != 'permissive': # Temporarily set state to permissive if not module.check_mode: set_state(module, 'permissive') module.warn( 'SELinux state temporarily changed from \'%s\' to \'permissive\'. State change will take effect next reboot.' % (runtime_state)) changed = True else: module.warn( 'SELinux state change will take effect next reboot') reboot_required = True else: if not module.check_mode: set_state(module, state) msgs.append('SELinux state changed from \'%s\' to \'%s\'' % (runtime_state, state)) # Only report changes if the file is changed. # This prevents the task from reporting changes every time the task is run. changed = True else: module.warn("Reboot is required to set SELinux state to %s" % state) reboot_required = True if state != config_state: if not module.check_mode: set_config_state(module, state, configfile) msgs.append('Config SELinux state changed from \'%s\' to \'%s\'' % (config_state, state)) changed = True module.exit_json(changed=changed, msg=', '.join(msgs), configfile=configfile, policy=policy, state=state, reboot_required=reboot_required)
def __init__(self): # # mode of operation # self.testing = False self.debug = False # # minor modes # self.uevents = False # # enable/disable functionality # self.selinux = selinux.is_selinux_enabled() self.multipath = True self.dmraid = True self.ibft = True self.noiswmd = False self.gfs2 = True self.jfs = True self.reiserfs = True # for this flag to take effect, # blockdev.mpath.set_friendly_names(flags.multipath_friendly_names) must # be called prior to calling Blivet.reset() or DeviceTree.populate() self.multipath_friendly_names = True # set to False since automatic updates of a device's information # or state should not be necessary by default self.auto_dev_updates = False # set to False by default since a forced reset for file contexts # is ordinary not necessary self.selinux_reset_fcon = False # set to True since we want to keep these around by default self.keep_empty_ext_partitions = True # set to False to suppress the default LVM behavior of saving # backup metadata in /etc/lvm/{archive,backup} self.lvm_metadata_backup = True # whether to include nodev filesystems in the devicetree self.include_nodev = False # whether to enable discard for newly created devices # (so far only for LUKS) self.discard_new = False self.boot_cmdline = {} self.update_from_boot_cmdline() self.allow_imperfect_devices = True # compression option for btrfs filesystems self.btrfs_compression = None self.debug_threads = False