コード例 #1
0
def zap():
    if not hookenv.action_get('i-really-mean-it'):
        hookenv.action_fail('i-really-mean-it is a required parameter')
        return

    failed_devices = []
    not_block_devices = []
    lvm_devices = []
    try:
        devices = get_devices()
    except ZapDiskError as error:
        hookenv.action_fail("Failed due to: {}".format(error))
        return

    for device in devices:
        if is_lvm_physical_volume(device):
            lvm_devices.append(device)
        if not is_block_device(device):
            not_block_devices.append(device)
        if (is_device_mounted(device) or is_active_bluestore_device(device)
                or is_mapped_luks_device(device)):
            failed_devices.append(device)

    if lvm_devices or failed_devices or not_block_devices:
        message = ""
        if lvm_devices:
            log('Cannot zap a device used by lvm')
            message = "{} devices are lvm devices: {}".format(
                len(lvm_devices), ", ".join(lvm_devices))
        if failed_devices:
            message += "{} devices are mounted: {}".format(
                len(failed_devices), ", ".join(failed_devices))
        if not_block_devices:
            if len(message):
                message += "\n\n"
            message += "{} devices are not block devices: {}".format(
                len(not_block_devices), ", ".join(not_block_devices))
        hookenv.action_fail(message)
        return
    db = kv()
    used_devices = db.get('osd-devices', [])
    for device in devices:
        zap_disk(device)
        if device in used_devices:
            used_devices.remove(device)
    db.set('osd-devices', used_devices)
    db.flush()
    hookenv.action_set({
        'message':
        "{} disk(s) have been zapped, to use them as OSDs, run: \n"
        "juju run-action {} add-disk osd-devices=\"{}\"".format(
            len(devices), hookenv.local_unit(), " ".join(devices))
    })
コード例 #2
0
def zap():
    if not hookenv.action_get('i-really-mean-it'):
        hookenv.action_fail('i-really-mean-it is a required parameter')
        return

    failed_devices = []
    not_block_devices = []
    devices = get_devices()
    for device in devices:
        if not is_block_device(device):
            not_block_devices.append(device)
        if (is_device_mounted(device) or
                is_active_bluestore_device(device) or
                is_mapped_luks_device(device)):
            failed_devices.append(device)

    if failed_devices or not_block_devices:
        message = ""
        if failed_devices:
            message = "{} devices are mounted: {}".format(
                len(failed_devices),
                ", ".join(failed_devices))
        if not_block_devices:
            if len(message):
                message += "\n\n"
            message += "{} devices are not block devices: {}".format(
                len(not_block_devices),
                ", ".join(not_block_devices))
        hookenv.action_fail(message)
        return
    db = kv()
    used_devices = db.get('osd-devices', [])
    for device in devices:
        zap_disk(device)
        if device in used_devices:
            used_devices.remove(device)
    db.set('osd-devices', used_devices)
    db.flush()
    hookenv.action_set({
        'message': "{} disk(s) have been zapped, to use them as OSDs, run: \n"
                   "juju run-action {} add-disk osd-devices=\"{}\"".format(
                       len(devices),
                       hookenv.local_unit(),
                       " ".join(devices))
    })
コード例 #3
0
def assess_status():
    """Assess status of current unit"""
    # check to see if the unit is paused.
    application_version_set(get_upstream_version(VERSION_PACKAGE))
    if is_unit_upgrading_set():
        status_set(
            "blocked", "Ready for do-release-upgrade and reboot. "
            "Set complete when finished.")
        return
    if is_unit_paused_set():
        status_set('maintenance',
                   "Paused. Use 'resume' action to resume normal service.")
        return
    # Check for mon relation
    if len(relation_ids('mon')) < 1:
        status_set('blocked', 'Missing relation: monitor')
        return

    # Check for monitors with presented addresses
    # Check for bootstrap key presentation
    monitors = get_mon_hosts()
    if len(monitors) < 1 or not get_conf('osd_bootstrap_key'):
        status_set('waiting', 'Incomplete relation: monitor')
        return

    # Check for vault
    if use_vaultlocker():
        if not relation_ids('secrets-storage'):
            status_set('blocked', 'Missing relation: vault')
            return
        try:
            if not vaultlocker.vault_relation_complete():
                status_set('waiting', 'Incomplete relation: vault')
                return
        except Exception as e:
            status_set('blocked', "Warning: couldn't verify vault relation")
            log("Exception when verifying vault relation - maybe it was "
                "offline?:\n{}".format(str(e)))
            log("Traceback: {}".format(traceback.format_exc()))

    # Check for OSD device creation parity i.e. at least some devices
    # must have been presented and used for this charm to be operational
    (prev_status, prev_message) = status_get()
    running_osds = ceph.get_running_osds()
    if not prev_message.startswith('Non-pristine'):
        if not running_osds:
            status_set(
                'blocked',
                'No block devices detected using current configuration')
        else:
            status_set('active',
                       'Unit is ready ({} OSD)'.format(len(running_osds)))
    else:
        pristine = True
        osd_journals = get_journal_devices()
        for dev in list(set(ceph.unmounted_disks()) - set(osd_journals)):
            if (not ceph.is_active_bluestore_device(dev)
                    and not ceph.is_pristine_disk(dev)):
                pristine = False
                break
        if pristine:
            status_set('active',
                       'Unit is ready ({} OSD)'.format(len(running_osds)))

    try:
        get_bdev_enable_discard()
    except ValueError as ex:
        status_set('blocked', str(ex))

    try:
        bluestore_compression = ch_context.CephBlueStoreCompressionContext()
        bluestore_compression.validate()
    except ValueError as e:
        status_set('blocked', 'Invalid configuration: {}'.format(str(e)))
コード例 #4
0
def prepare_disks_and_activate():
    if use_vaultlocker():
        # NOTE: vault/vaultlocker preflight check
        vault_kv = vaultlocker.VaultKVContext(vaultlocker.VAULTLOCKER_BACKEND)
        context = vault_kv()
        if not vault_kv.complete:
            log('Deferring OSD preparation as vault not ready', level=DEBUG)
            return
        else:
            log('Vault ready, writing vaultlocker configuration', level=DEBUG)
            vaultlocker.write_vaultlocker_conf(context)

    osd_journal = get_journal_devices()
    if not osd_journal.isdisjoint(set(get_devices())):
        raise ValueError('`osd-journal` and `osd-devices` options must not'
                         'overlap.')
    log("got journal devs: {}".format(osd_journal), level=DEBUG)

    # pre-flight check of eligible device pristinity
    devices = get_devices()

    # if a device has been previously touched we need to consider it as
    # non-pristine. If it needs to be re-processed it has to be zapped
    # via the respective action which also clears the unitdata entry.
    db = kv()
    touched_devices = db.get('osd-devices', [])
    devices = [dev for dev in devices if dev not in touched_devices]
    log('Skipping osd devices previously processed by this unit: {}'.format(
        touched_devices))
    # filter osd-devices that are file system paths
    devices = [dev for dev in devices if dev.startswith('/dev')]
    # filter osd-devices that does not exist on this unit
    devices = [dev for dev in devices if os.path.exists(dev)]
    # filter osd-devices that are already mounted
    devices = [dev for dev in devices if not is_device_mounted(dev)]
    # filter osd-devices that are active bluestore devices
    devices = [
        dev for dev in devices if not ceph.is_active_bluestore_device(dev)
    ]

    log('Checking for pristine devices: "{}"'.format(devices), level=DEBUG)
    if not all(ceph.is_pristine_disk(dev) for dev in devices):
        status_set(
            'blocked', 'Non-pristine devices detected, consult '
            '`list-disks`, `zap-disk` and `blacklist-*` actions.')
        return

    if is_osd_bootstrap_ready():
        log('ceph bootstrapped, rescanning disks')
        emit_cephconf()
        bluestore = use_bluestore()
        ceph.udevadm_settle()
        for dev in get_devices():
            ceph.osdize(dev, config('osd-format'), osd_journal,
                        config('ignore-device-errors'), config('osd-encrypt'),
                        bluestore, config('osd-encrypt-keymanager'))
            # Make it fast!
            if config('autotune'):
                log(
                    'The autotune config is deprecated and planned '
                    'for removal in the next release.',
                    level=WARNING)
                ceph.tune_dev(dev)
        ceph.start_osds(get_devices())

    # Notify MON cluster as to how many OSD's this unit bootstrapped
    # into the cluster
    for r_id in relation_ids('mon'):
        relation_set(relation_id=r_id,
                     relation_settings={
                         'bootstrapped-osds':
                         len(db.get('osd-devices', [])),
                         'ceph_release':
                         ceph.resolve_ceph_version(
                             hookenv.config('source') or 'distro')
                     })