示例#1
0
def deactivate(ns, setting, device=None):
    '''
    Deactivate network setting.

    :param LMI_IPAssignmentSettingData setting: Setting to deactivate.
    :param device: Device to deactivate the setting on
    :type device: LMI_IPNetworkConnection or None
    '''
    service = ns.LMI_IPConfigurationService.first_instance()
    if device is not None:
        LOG().debug('Deactivating setting %s on device %s', setting.Caption,
                    device.ElementName)
        result = service.SyncApplySettingToIPNetworkConnection(
            SettingData=setting,
            IPNetworkConnection=device,
            Mode=service.ApplySettingToIPNetworkConnection.ModeValues.Mode32769
        )
        if result.errorstr:
            raise LmiFailed("Unable to deactivate setting: %s" %
                            result.errorstr)
    else:
        result = service.SyncApplySettingToIPNetworkConnection(
            SettingData=setting,
            Mode=service.ApplySettingToIPNetworkConnection.ModeValues.Mode32769
        )
        if result.errorstr:
            raise LmiFailed("Unable to deactivate setting: %s" %
                            result.errorstr)
    return 0
示例#2
0
def add_luks_passphrase(ns, fmt, passphrase, new_passphrase):
    """
    Adds new password to LUKS format. Each format can have up to 8 separate
    passwords and any of them can be used to open(decrypt) the format.

    Any existing passphrase must be provided to add a new one. This proves
    the caller is authorized to add new passphrase (because it already knows
    one) and also this 'old' passphrase is used to retrieve encryption keys.
    This 'old' passphrase is not removed nor replaced when adding new
    passphrase!

    :type fmt: LMIInstance/LMI_EncryptionFormat or string
    :param fmt: The LUKS format to modify.
    :type passphrase: string
    :param passphrase: Existing LUKS passphrase.
    :type new_passphrase: string
    :param new_passphrase: New passphrase to add to the format.
    """
    fmt = fs.str2format(ns, fmt)
    service = ns.LMI_ExtentEncryptionConfigurationService.first_instance()
    (ret, outparams, err) = service.AddPassphrase(Format=fmt,
                                                  Passphrase=passphrase,
                                                  NewPassphrase=new_passphrase)
    if ret != 0:
        if err:
            raise LmiFailed("Cannot add new passphrase: %s." % err)
        values = service.AddPassphrase.AddPassphraseValues
        raise LmiFailed("Cannot add new passphrase: %s." %
                        (values.value_name(ret), ))
示例#3
0
def open_luks(ns, fmt, name, passphrase):
    """
    Open encrypted LUKS format and expose it as a clear-text block device.

    :type fmt: LMIInstance/LMI_EncryptionFormat or string
    :param fmt: The LUKS format to open.
    :type name: string
    :param name: Requested name of the clear-text block device. It will be
            available as /dev/mapper/<name>.
    :type passphrase: string
    :param passphrase: Password to open the encrypted data.
    :rtype: LMIInstance/LMI_LUKSStorageExtent
    :returns: The block device with clear-text data.
    """
    fmt = fs.str2format(ns, fmt)
    service = ns.LMI_ExtentEncryptionConfigurationService.first_instance()
    (ret, outparams,
     err) = service.SyncOpenEncryptionFormat(Format=fmt,
                                             ElementName=name,
                                             Passphrase=passphrase)
    if ret != 0:
        if err:
            raise LmiFailed("Cannot open LUKS format: %s." % err)
        values = service.OpenEncryptionFormat.OpenEncryptionFormatValues
        raise LmiFailed("Cannot open LUKS format: %s." %
                        (values.value_name(ret), ))
    return outparams['Extent']
示例#4
0
def mount_delete(ns, target):
    """
    Unmount filesystem.

    :type target: string
    :param target: device path or mountpoint
    """
    # Try to convert device name to full device path
    try:
        device_inst = common.str2device(ns, target)
        if device_inst:
            target = device_inst.Name
    except LmiFailed:
        # we did not find CIM_StorageExtent for the device, it must be non
        # device filesystem specification
        pass

    mnt = ns.LMI_MountedFileSystem.first_instance({'FileSystemSpec':target}) or \
          ns.LMI_MountedFileSystem.first_instance({'MountPointPath':target})
    if mnt is None:
        raise LmiFailed('Target is not mounted: %s.' % target)

    service = ns.LMI_MountConfigurationService.first_instance()
    # TODO for now
    # Mode 32769 == only unmount (don't remove any persistent info)
    (ret, _outparams, _err) = service.SyncDeleteMount(Mount=mnt, Mode=32769)
    if ret != 0:
        raise LmiFailed('Cannot delete mount: %s.' % target)

    LOG().info('Successfully deleted mount: %s', target)
示例#5
0
def str2device(ns, device):
    """
    Convert string with name of device to LMIInstance of the device.
    If LMIInstance is provided, nothing is done and the instance is just
    returned. If string is given, appropriate LMIInstance is looked up and
    returned.
    This functions throws an error when the device cannot be found.

    The main purpose of this function is to convert parameters in functions,
    where both string and LMIInstance is allowed.

    :type device: LMIInstance/CIM_StorageExtent or string with name of device
    :param device: Device to convert.
    :rtype: LMIInstance/CIM_StorageExtent
    """
    if isinstance(device, LMIInstance):
        return device
    if not isinstance(device, str):
        raise TypeError("string or LMIInstance expected, got %s" %
                        device.__class__.__name__)
    query = 'SELECT * FROM CIM_StorageExtent WHERE ' \
                'DeviceID="%(device)s" ' \
                'OR Name="%(device)s" ' \
                'OR ElementName="%(device)s"' % {'device': escape_cql(device)}
    devices = ns.wql(query)
    if not devices:
        raise LmiFailed("Device '%s' not found" % (device, ))
    if len(devices) > 1:
        raise LmiFailed("Too many devices with name '%s' found" % (device, ))

    LOG().debug("String %s translated to device '%s'.", device,
                devices[0].DeviceID)
    return devices[0]
示例#6
0
def lf_list(ns, directory, depth=None):
    """
    List all files in a directory.

    If depth is positive, directory is walked recursively up to the given depth.

    :type directory: string
    :param directory: Full path to the directory.
    :type depth: integer
    :param depth: Maximum depth to be recursed to.
    """
    if directory != '/':
        directory = directory.rstrip('/')
    try:
        d = get_directory_instance(ns, directory)
    except:
        raise LmiFailed("Can't list directory: %s" % directory)
    if depth:
        try:
            depth = int(depth)
        except ValueError:
            raise LmiFailed("Depth must be integer.")
    else:
        depth = 0

    for (f, lvl) in walk_cim_directory(d, depth):
        rwx = ''
        rwx += 'r' if f.Readable else '-'
        rwx += 'w' if f.Writeable else '-'
        rwx += 'x' if f.Executable else '-'
        prefix = '  ' * (depth - lvl)
        ident = f.associators(AssocClass='LMI_FileIdentity')[0]
        yield (get_file_identification(f), prefix + f.Name, rwx,
               ident.SELinuxCurrentContext)
示例#7
0
def create_raid(ns, devices, level, name=None):
    """
    Create new MD RAID device.

    :type devices: list of LMIInstance/CIM_StorageExtent or list of strings
    :param device: Devices to add to the RAID.
    :type level: int
    :param level: RAID level.
    :type name: string
    :param name: RAID name.
    :rtype: LMIInstance/LMI_MDRAIDStorageExtent
    """
    devs = [common.str2device(ns, device) for device in devices]
    args = {'InExtents': devs, 'Level': level}
    if name:
        args['ElementName'] = name
    service = ns.LMI_StorageConfigurationService.first_instance()
    (ret, outparams, err) = service.SyncCreateOrModifyMDRAID(**args)
    if ret != 0:
        if err:
            raise LmiFailed("Cannot create the MD RAID: %s." % err)
        values = service.CreateOrModifyMDRAID.CreateOrModifyMDRAIDValues
        raise LmiFailed("Cannot create the MD RAID: %s." %
                        (values.value_name(ret), ))

    raid = outparams['TheElement'].to_instance()
    LOG().info("Created MD RAID %s", raid.Name)
    return raid
示例#8
0
def str2vg(ns, vg):
    """
    Convert string with name of volume group to LMIInstance of the
    LMI_VGStoragePool.

    If LMIInstance is provided, nothing is done and the instance is just
    returned. If string is provided, appropriate LMIInstance is looked up and
    returned.

    This functions throws an error when the device cannot be found.

    The main purpose of this function is to convert parameters in functions,
    where both string and LMIInstance is allowed.

    :type vg: LMIInstance/LMI_VGStoragePool or string
    :param vg: VG to retrieve.
    :rtype: LMIInstance/LMI_VGStoragePool

    """
    if isinstance(vg, LMIInstance):
        return vg
    if not isinstance(vg, str):
        raise TypeError("string or LMIInstance expected, got %s" %
                        vg.__class__.__name__)
    query = 'SELECT * FROM LMI_VGStoragePool WHERE ElementName="%(vg)s"' \
            % {'vg': escape_cql(vg)}
    vgs = ns.wql(query)
    if not vgs:
        raise LmiFailed("Volume Group '%s' not found" % (vg, ))
    if len(vgs) > 1:
        raise LmiFailed("Too many volume groups with name '%s' found" % (vg, ))

    LOG().debug("String %s translated to Volume Group '%s'", vg,
                vgs[0].InstanceID)
    return vgs[0]
示例#9
0
def create_vg(ns, devices, name, extent_size=None):
    """
    Create new Volume Group from given devices.

    :type devices: list of LMIInstance/CIM_StorageExtent or list of strings
    :param device: Devices to add to the Volume Group.
    :type name: string
    :param name: Name of the Volume gGoup.
    :type extent_size: int
    :param extent_size: Extent size in bytes.
    :rtype: LMIInstance/LMI_VGStoragePool
    """
    devs = [common.str2device(ns, device) for device in devices]
    args = {'InExtents': devs, 'ElementName': name}
    goal = None

    try:
        if extent_size:
            # create (and use) VGStorageSetting
            caps = ns.LMI_VGStorageCapabilities.first_instance()
            (ret, outparams, err) = caps.CreateVGStorageSetting(InExtents=devs)
            if ret != 0:
                if err:
                    raise LmiFailed("Cannot create setting for the volume " \
                            "group: %s." % err)
                vals = caps.CreateVGStorageSetting.CreateVGStorageSettingValues
                raise LmiFailed("Cannot create setting for the volume group:" \
                        " %s." % (vals.value_name(ret),))
            goal = outparams['Setting']
            goal = goal.to_instance()
            goal.ExtentSize = extent_size
            (ret, outparams, err) = goal.push()
            if ret != 0:
                if err:
                    raise LmiFailed("Cannot modify setting for the volume " \
                            "group: %s." % err)
                raise LmiFailed("Cannot modify setting for the volume group:" \
                        " %d." % ret)
            args['Goal'] = goal

        service = ns.LMI_StorageConfigurationService.first_instance()
        (ret, outparams, err) = service.SyncCreateOrModifyVG(**args)
        if ret != 0:
            values = service.CreateOrModifyVG.CreateOrModifyVGValues
            raise LmiFailed("Cannot create the volume group: %s." %
                            (values.value_name(ret), ))
    finally:
        if goal:
            goal.delete()

    pool = outparams['Pool'].to_instance()
    LOG().info("Created volume group %s", pool.Name)
    return pool
示例#10
0
def get_setting_from_opts(ns, options, other_options):
    """
    Create a setting instance from option strings.

    :type options: string of comma-separated options
    :type other_options: string of comma-separated options
    :rtype: an instance of LMI_MountedFileSystemSetting
    """
    cap = ns.LMI_MountedFileSystemCapabilities.first_instance()

    (ret, outparams, _err) = cap.CreateSetting()
    if ret != 0:
        raise LmiFailed('Could not create setting')

    setting = outparams['setting'].to_instance()

    if other_options is not None:
        setting.OtherOptions = other_options.split(',')

    if options is None:
        return setting

    for opt_pair in options.split(','):
        opts = map(lambda o: o.strip(), opt_pair.split(':'))
        # bail out if the option is not in 'Option:Value' format
        # or if the Option is not in supported options
        if len(opts) != 2 or opts[0] not in _OPTS:
            raise LmiFailed('Invalid option: %s' % opt_pair)
        # ignore OtherOptions, there is a separate cmdline option for it
        if opts[0] == 'OtherOptions':
            continue
        # insist on using a number with FileSystemCheckOrder
        if opts[0] == 'FileSystemCheckOrder':
            if not opts[1].isdigit():
                raise LmiFailed(
                    'Value of FileSystemCheckOrder must be a number')
            opts[1] = int(opts[1])
        else:
            # otherwise check for true/false possibilities
            opts[1] = opts[1].lower()

            if opts[1] not in ['t', 'true', 'f', 'false']:
                raise LmiFailed('Invalid option value: %s' % opts[1])

            # sanitize the boolean option values
            if opts[1] in ['t', 'true']:
                opts[1] = True
            else:
                opts[1] = False

        setattr(setting, opts[0], opts[1])

    return setting
示例#11
0
def list_messages(ns, reverse=False, tail=False):
    """
    List messages from the journal.

    :param boolean reverse: List messages from newest to oldest.
    :param boolean tail: List only the last 50 messages
    """

    inst = ns.LMI_JournalMessageLog.first_instance()
    if not inst:
        raise LmiFailed(
            "Cannot initialize Journald provider. (hint: check if it's installed)"
        )

    if reverse or tail:
        r = inst.PositionToLastRecord()
    else:
        r = inst.PositionToFirstRecord()
    if not 'IterationIdentifier' in r.rparams:
        raise LmiFailed(
            "Cannot initialize Journald iteration. (hint: check SELinux AVCs)")
    iter_id = r.rparams['IterationIdentifier']

    if tail:
        r = inst.PositionAtRecord(IterationIdentifier=iter_id,
                                  MoveAbsolute=False,
                                  RecordNumber=-NUM_TAIL)
        iter_id = r.rparams['IterationIdentifier']

    try:
        while True:
            r = inst.GetRecord(IterationIdentifier=iter_id,
                               PositionToNext=(not reverse))
            if r.rval != 0:
                break
            iter_id = r.rparams['IterationIdentifier']

            if reverse:
                x = inst.PositionAtRecord(IterationIdentifier=iter_id,
                                          MoveAbsolute=False,
                                          RecordNumber=-1)
                iter_id = x.rparams['IterationIdentifier']

            print "".join(map(chr, r.rparams['RecordData']))
    except KeyboardInterrupt:
        pass

    inst.CancelIteration(IterationIdentifier=iter_id)

    return 0
示例#12
0
def get_service(ns, service):
    """
    Return :py:class:`lmi.shell.LMIInstance` object matching the given
    service name.

    :param string service: Service name.
    """
    try:
        if isinstance(service, basestring):
            if not service.endswith('.service'):
                service += '.service'
            cs = get_computer_system(ns)
            iname = ns.LMI_Service.new_instance_name({
                "Name":
                service,
                "CreationClassName":
                "LMI_Service",
                "SystemName":
                cs.Name,
                "SystemCreationClassName":
                cs.CreationClassName
            })
            inst = iname.to_instance()

        elif isinstance(service, (LMIInstance, LMIInstanceName)):
            try:
                inst = service
                service = inst.Name
                if isinstance(inst, LMIInstanceName):
                    inst = inst.to_instance()
            except AttributeError:
                raise ValueError('Invalid service instance name. It\'s missing'
                                 ' Name property.')

        else:
            raise TypeError(
                "service must be either string or ``LMIInstanceName``")

    except wbem.CIMError as err:
        if err.args[0] == wbem.CIM_ERR_NOT_FOUND:
            raise LmiFailed('No such service "%s".' % service)
        else:
            raise LmiFailed('Failed to get service "%s": %s' %
                            (service, err.args[1]))

    if inst is None:
        raise LmiFailed('No such service "%s".' % service)

    return inst
示例#13
0
def mount_create(ns, device, mountpoint, fs_type=None, options=None):
    """
    Create a mounted filesystem.

    :type device: string or LMIInstance/CIM_StorageExtent
    :param device: Device to mount or a mount specifier (like '//server/share' for CIFS).
    :type mountpoint: string
    :param mountpoint: path where device should be mounted
    :type fs_type: string
    :param fs_type: filesystem type
    :type options: string
    :param options: comma-separated string of mount options
    """
    # Try to convert device name to full device path
    try:
        device_inst = common.str2device(ns, device)
        if device_inst:
            device = device_inst.Name
    except LmiFailed:
        # we did not find CIM_StorageExtent for the device, it must be non
        # device filesystem specification
        pass

    fs_setting = ns.LMI_FileSystemSetting.first_instance(
        {'InstanceID': 'LMI:LMI_FileSystemSetting:' + device})
    if fs_setting is None:
        raise LmiFailed('Wrong device: %s' % device)
    filesystem = fs_setting.associators()[0]
    if fs_type is None:
        fs_type = filesystem.FileSystemType
    service = ns.LMI_MountConfigurationService.first_instance()

    setting = get_setting_from_opts(ns, options)
    setting.push()

    # TODO for now
    # Mode 32768 == only mount (don't create any persistent info)
    (ret, _outparams,
     _err) = service.SyncCreateMount(Goal=setting.path,
                                     FileSystemType=fs_type,
                                     Mode=32768,
                                     FileSystem=filesystem.path,
                                     MountPoint=mountpoint,
                                     FileSystemSpec=device)
    msg = '%s on %s' % (device, mountpoint)
    if ret != 0:
        raise LmiFailed('Cannot create mount: %s: %s' % (msg, _err))

    LOG().info('Successfully created mount: %s', msg)
示例#14
0
def delete_vg(ns, vg):
    """
    Destroy given Volume Group.

    :type vg: LMIInstance/LMI_VGStoragePool or string
    :param vg: Volume Group to delete.
    """
    vg = common.str2vg(ns, vg)
    service = ns.LMI_StorageConfigurationService.first_instance()
    (ret, _outparams, err) = service.SyncDeleteVG(Pool=vg)
    if ret != 0:
        if err:
            raise LmiFailed("Cannot delete the VG: %s." % err)
        raise LmiFailed("Cannot delete the VG: %s." %
                        (service.DeleteVG.DeleteVGValues.value_name(ret), ))
示例#15
0
def remove_from_group(ns, group, users):
    group_inst = ns.LMI_Group.first_instance({"Name": group})
    if group_inst is None:
        raise LmiFailed('No such group "%s"' % group)

    for user in users:
        user_inst = ns.LMI_Account.first_instance({"Name": user})
        if user_inst is None:
            raise LmiFailed('No such user "%s"' % user)
        # get identity
        identity = user_inst.first_associator(ResultClass="LMI_Identity")
        # get MemberOfGroup
        for mog in identity.references(ResultClass="LMI_MemberOfGroup"):
            if mog.Collection.Name == group:
                mog.delete()
示例#16
0
def delete_lv(ns, lv):
    """
    Destroy given Logical Volume.

    :type lv: LMIInstance/LMI_LVStorageExtent or string
    :param lv: Logical Volume to destroy.
    """
    lv = common.str2device(ns, lv)
    service = ns.LMI_StorageConfigurationService.first_instance()
    (ret, _outparams, err) = service.SyncDeleteLV(TheElement=lv)
    if ret != 0:
        if err:
            raise LmiFailed("Cannot delete the LV: %s." % err)
        raise LmiFailed("Cannot delete the LV: %s." %
                        (service.DeleteLV.DeleteLVValues.value_name(ret), ))
示例#17
0
def set_boolean(ns, target, value, default):
    """
    Set a new value of an SELinux boolean.

    :param target: An SELinux boolean to change.
    :param value: New value.
    :param bool default: If True, makes the new state persistent.
    """
    service = get_service(ns)
    id = "LMI:LMI_SELinuxBoolean:" + target
    tg = ns.LMI_SELinuxBoolean.new_instance_name({"InstanceID": id})

    try:
        (rval, _, errorstr) = service.SyncSetBoolean(
            Target=tg,
            Value=proc_bool(value),
            MakeDefault=default,
        )
    except LMIExceptions.CIMError as err:
        msg = 'Failed to set SELinux boolean'
        if err[1]:
            msg += err[1][err[1].index(':'):]
        raise LmiFailed(msg)
    else:
        LOG().info('SELinux boolean "%s" changed to "%s"%s.', target,
                   proc_bool(value), ' (persistently)' if default else '')
示例#18
0
def delete_raid(ns, raid):
    """
    Destroy given RAID device

    :type raid: LMIInstance/LMI_MDRAIDStorageExtent
    :param raid: MD RAID to destroy.
    """
    raid = common.str2device(ns, raid)
    service = ns.LMI_StorageConfigurationService.first_instance()
    (ret, _outparams, err) = service.SyncDeleteMDRAID(TheElement=raid)
    if ret != 0:
        if err:
            raise LmiFailed("Cannot create the partition: %s." % err)
        raise LmiFailed(
            "Cannot delete the raid: %s." %
            (service.DeleteMDRAID.DeleteMDRAIDValues.value_name(ret), ))
示例#19
0
def get_service(ns, service):
    """
    Return :py:class:`lmi.shell.LMIInstance` object matching the given
    service name.

    :param string service: Service name.
    """
    if isinstance(service, basestring):
        cs = ns.Linux_ComputerSystem.first_instance_name()
        iname = ns.LMI_Service.new_instance_name({
            "Name":
            service,
            "CreationClassName":
            "LMI_Service",
            "SystemName":
            cs.path['Name'],
            "SystemCreationClassName":
            cs.path['CreationClassName']
        })
        inst = iname.to_instance()
        if inst is None:
            raise LmiFailed('No such service "%s"' % service)
    elif isinstance(service, (LMIInstance, LMIInstanceName)):
        inst = service
        service = inst.Name
        if isinstance(inst, LMIInstanceName):
            inst = inst.to_instance()
    else:
        raise TypeError("service must be either string or ``LMIInstanceName``")

    return inst
示例#20
0
def close_luks(ns, fmt):
    """
    Closes clear-text block device previously opened by open_luks().

    :type fmt: LMIInstance/LMI_EncryptionFormat or string
    :param fmt: The LUKS format to close.
    """
    fmt = fs.str2format(ns, fmt)
    service = ns.LMI_ExtentEncryptionConfigurationService.first_instance()
    (ret, outparams, err) = service.SyncCloseEncryptionFormat(Format=fmt)
    if ret != 0:
        if err:
            raise LmiFailed("Cannot close LUKS format: %s." % err)
        values = service.CloseEncryptionFormat.CloseEncryptionFormatValues
        raise LmiFailed("Cannot close LUKS format: %s." %
                        (values.value_name(ret), ))
示例#21
0
def set_autoconnect(ns, setting, device=None, state=True):
    '''
    Enable/disable automatical activation of the setting.

    :param LMI_IPAssignmentSettingData setting: Setting that will be affected
    :param bool state: `True` for autoconnection activation, `False` for deactivation
    '''
    if device is None:
        LOG().info("%s autoconnect on setting %s",
                   "Enabling" if state else "Disabling", setting.Caption)
    else:
        LOG().info("%s autoconnect on setting %s on device %s",
                   "Enabling" if state else "Disabling", setting.Caption,
                   device.ElementName)

    service = ns.LMI_IPConfigurationService.first_instance()
    if state:
        # Set IsNext = 1 (Is Next), don't change IsCurrent
        mode = service.ApplySettingToIPNetworkConnection.ModeValues.Mode2
    else:
        # Set IsNext = 2 (Is Not Next), don't change IsCurrent
        mode = service.ApplySettingToIPNetworkConnection.ModeValues.Mode5

    if device is None:
        result = service.SyncApplySettingToIPNetworkConnection(
            SettingData=setting, Mode=mode)
    else:
        result = service.SyncApplySettingToIPNetworkConnection(
            SettingData=setting, IPNetworkConnection=device, Mode=mode)
    if result.errorstr:
        raise LmiFailed("Unable to change setting autoconnect: %s" %
                        result.errorstr)
    return result.rval
示例#22
0
def remove_package(ns, package):
    """
    Uninstall given package from system.

    :raises: :py:exc:`LmiFailed`` will be raised on failure.
    :param package:  Instance or instance name of
        ``LMI_SoftwareIdentity`` representing package to remove.
    :type package: :py:class:`lmi.shell.LMIInstance`
        or :py:class:`lmi.shell.LMIInstanceName`
    """
    if not isinstance(package, (LMIInstance, LMIInstanceName)):
        raise TypeError("package must be an LMIInstance or LMIInstanceName")
    try:
        if isinstance(package, LMIInstanceName):
            package = package.to_instance()
    except LmiFailed:
        package = None
    else:
        installed_assocs = package.reference_names(
            Role="InstalledSoftware",
            ResultClass="LMI_InstalledSoftwareIdentity")

    if not package or len(installed_assocs) < 1:
        raise LmiFailed('Given package "%s" is not installed!' %
                        get_package_nevra(package))

    for assoc in installed_assocs:
        nevra = get_package_nevra(assoc.InstalledSoftware)
        assoc.to_instance().delete()
        LOG().info('Removed package %s.', nevra)
示例#23
0
def get_largest_partition_size(ns, device):
    """
    Returns size of the largest free region (in blocks), which can accommodate
    a partition on given device.
    There must be partition table present on this device.

    :type device: LMIInstance/CIM_StorageExtent or string
    :param device:  Device which should be examined.
    :rtype: int
    """
    device = common.str2device(ns, device)
    # find the partition table (=LMI_DiskPartitionConfigurationCapabilities)
    cap = device.first_associator(
        ResultClass="LMI_DiskPartitionConfigurationCapabilities")
    if not cap:
        raise LmiFailed("Cannot find partition table on %s" % device.name)
    (ret, outparams, err) = cap.FindPartitionLocation(Extent=device)

    if ret == cap.FindPartitionLocation.FindPartitionLocationValues\
                 .NotEnoughFreeSpace:
        return 0

    if ret != 0:
        if err:
            LOG().warning("Cannot find largest partition size: %s." % err)
        else:
            LOG().warning("Cannot find largest partition size: %d." % ret)
        return 0
    blocks = outparams['EndingAddress'] - outparams['StartingAddress']
    size = blocks * device.BlockSize
    return size
示例#24
0
def set_repository_enabled(ns, repository, enable=True):
    """
    Enable or disable repository.

    :param repository: Instance of ``LMI_SoftwareIdentityResource``.
    :type repository: :py:class:`lmi.shell.LMIInstance`
        or :py:class:`lmi.shell.LMIInstanceName`
    :param boolean enable: New value of ``EnabledState`` property.
    :returns: Previous value of repository's ``EnabledState``.
    :rtype: boolean
    """
    if not isinstance(repository, (LMIInstance, LMIInstanceName)):
        raise TypeError("repository must be an LMIInstance")
    cls = ns.LMI_SoftwareIdentityResource
    if not LMIUtil.lmi_isinstance(repository, cls):
        raise ValueError("repository must be an instance of"
                         " LMI_SoftwareIdentityResource")
    requested_state = cls.EnabledStateValues.Enabled if enable else \
            cls.EnabledStateValues.Disabled
    if repository.EnabledState != requested_state:
        results = repository.RequestStateChange(RequestedState=requested_state)
        if results.rval != 0:
            msg = 'Failed to enable repository "%s" (rval=%d).' % (
                repository.Name, results.rval)
            if results.errorstr:
                msg += ': ' + results.errorstr
            raise LmiFailed(msg)
        LOG().info('Repository "%s" %s.', repository.Name,
                   "enabled" if enable else "disabled")
    else:
        LOG().info('Repository "%s" is already %s.', repository.Name,
                   "enabled" if enable else "disabled")
    return repository.EnabledState
示例#25
0
def install_from_uri(ns, uri, force=False, update=False):
    """
    Install package from *URI* on remote system.

    :param string uri: Identifier of *RPM* package available via http, https,
        or ftp service.
    :param boolean force: Whether the installation shall be done even if
        installing the same (reinstalling) or older version than already
        installed.
    :param boolean update: Whether this is an update. Update fails if
        package is not already installed on system.
    """
    if not isinstance(uri, basestring):
        raise TypeError("uri must be a string")
    service = ns.LMI_SoftwareInstallationService.first_instance()
    options = [4 if not update else 5]  # Install (4) or Update (5)
    if force:
        options.append(3)  # Force Installation
    results = service.SyncInstallFromURI(URI=uri,
                                         Target=get_computer_system(ns).path,
                                         InstallOptions=options)
    if results.rval != 0:
        msg = 'Failed to %s package from uri (rval=%d).' % (
            'update' if update else 'install', results.rval)
        if results.errorstr:
            msg += ': ' + results.errorstr
        raise LmiFailed(msg)
    else:
        LOG().info('Installed package from uri %s.', uri)
示例#26
0
def watch(ns):
    """
    Sets up a new indication listener and waits for events.
    """

    indication_port = random.randint(12000, 13000)
    listener = LMIIndicationListener("0.0.0.0", indication_port)
    uniquename = listener.add_handler("lmiscript_journald_watch-XXXXXXXX",
                                      ind_handler)
    listener.start()

    ret = ns.connection.subscribe_indication(
        Name=uniquename,
        Query=
        "SELECT * FROM LMI_JournalLogRecordInstanceCreationIndication WHERE SOURCEINSTANCE ISA LMI_JournalLogRecord",
        Destination="http://%s:%d" % (socket.gethostname(), indication_port))
    if not ret or not ret.rval:
        raise LmiFailed("Failed to register indication: %s\n" %
                        retval.errorstr)

    try:
        LOG().info("Watching journal, press Ctrl+C to abort\n")
        while True:
            time.sleep(1)
            pass

    except KeyboardInterrupt:
        pass

    ns.connection.unsubscribe_indication(uniquename)

    return 0
示例#27
0
def restore(ns, target, action, recursively):
    """
    Restore default SELinux security contexts on files.

    :param target: SELinux file to change.
    :param action: Action to take on mislabeled files.
    :param recursively: Restore labels recursively in case Target is a directory.
    """
    uf_name = get_uf_name(ns, target)
    service = get_service(ns)

    try:
        (rval, params, errorstr) = service.SyncRestoreLabels(
            Target=uf_name,
            Action=action,
            Recursively=recursively,
        )
    except LMIExceptions.CIMError as err:
        msg = 'Failed to restore default SELinux security context'
        if err[1]:
            if err[0] == 4:
                msg += err[1][err[1].index(':'):]
            else:
                msg += ": " + err[1]
        raise LmiFailed(msg)
    else:
        LOG().info('SELinux security contexts on "%s" restored.', target)
示例#28
0
def set_port(ns, target, protocol, port_range):
    """
    Set label on an SELinux port.

    :param target: An SELinux port to change.
    :param protocol: Network protocol (TCP/UDP).
    :param port_range: Network ports to change. Single port or a range, for example 1024-2048'.
    """
    service = get_service(ns)
    id = "LMI:LMI_SELinuxPort:" + protocol.upper() + ":" + target
    tg = ns.LMI_SELinuxBoolean.new_instance_name({"InstanceID": id})

    try:
        (rval, _, errorstr) = service.SyncSetPortLabel(
            Target=tg,
            PortRange=port_range,
        )
    except LMIExceptions.CIMError as err:
        msg = 'Failed to set SELinux port'
        if err[1]:
            if err[0] == 4:
                msg += err[1][err[1].index(':'):]
            else:
                msg += ": " + err[1]
        raise LmiFailed(msg)
    else:
        LOG().info('SELinux port "%s" changed to "%s" (%s)', target,
                   port_range, protocol.upper())
示例#29
0
def set_state(ns, new_state, default):
    """
    Set SELinux state.

    :param new_state: New state value.
    :param bool default: If set to True, makes the new state persistent.
    """
    service = get_service(ns)

    try:
        (rval, _, errorstr) = service.SyncSetSELinuxState(
            NewState=proc_state(new_state),
            MakeDefault=default,
        )
    except LMIExceptions.CIMError as err:
        msg = 'Failed to set SELinux state'
        if err[1]:
            msg += err[1][err[1].index(':'):]
        raise LmiFailed(msg)
    else:
        if default:
            LOG().info('SELinux default state changed to "%s".',
                       state2str(proc_state(new_state)))
        else:
            LOG().info('SELinux state changed to "%s".',
                       state2str(proc_state(new_state)))
示例#30
0
def verify_package(ns, package):
    """
    Returns the instances of ``LMI_SoftwareIdentityFileCheck`` representing
    files, that did not pass the verification.

    :param package: Instance or instance name of
        ``LMI_SoftwareIdentity`` representing package to verify.
    :type package: :py:class:`lmi.shell.LMIInstance`
        or :py:class:`lmi.shell.LMIInstanceName`
    :returns: List of instances of ``LMI_SoftwareIdentityFileCheck``
        with non-empty ``FailedFlags`` property.
    :rtype: list
    """
    if not isinstance(package, (LMIInstance, LMIInstanceName)):
        raise TypeError("package must be an LMIInstance or LMIInstanceName")
    # we can not use synchronous invocation because the reference to a job is
    # needed - for enumerating of affected software identities
    service = ns.LMI_SoftwareInstallationService.first_instance()
    results = service.VerifyInstalledIdentity(
        Source=package.path if isinstance(package, LMIInstance) else package,
        Target=get_computer_system(ns).path)
    nevra = get_package_nevra(package)
    if results.rval != 4096:
        msg = 'Failed to verify package "%s (rval=%d)".' % (nevra,
                                                            results.rval)
        if results.errorstr:
            msg += ': ' + results.errorstr
        raise LmiFailed(msg)

    job = results.rparams['Job'].to_instance()
    _wait_for_job_finished(job)
    if not LMIJob.lmi_is_job_completed(job):
        msg = 'Failed to verify package "%s".' % nevra
        if job.ErrorDescription:
            msg += ': ' + job.ErrorDescription
        raise LmiFailed(msg)
    LOG().debug('Verified package "%s" on remote host "%s".', nevra,
                ns.connection.uri)

    failed = job.associators(Role='AffectingElement',
                             ResultRole='AffectedElement',
                             AssocClass="LMI_AffectedSoftwareJobElement",
                             ResultClass='LMI_SoftwareIdentityFileCheck')
    LOG().debug('Verified package "%s" on remote host "%s" with %d failures.',
                nevra, ns.connection.uri, len(failed))

    return failed