def prepare_disks_and_activate(): # NOTE: vault/vaultlocker preflight check vault_kv = vaultlocker.VaultKVContext(vaultlocker.VAULTLOCKER_BACKEND) context = vault_kv() if use_vaultlocker() and not vault_kv.complete: log('Deferring OSD preparation as vault not ready', level=DEBUG) return elif use_vaultlocker() and vault_kv.complete: 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 ceph.is_bootstrapped(): log('ceph bootstrapped, rescanning disks') emit_cephconf() for dev in get_devices(): ceph.osdize(dev, config('osd-format'), osd_journal, config('ignore-device-errors'), config('osd-encrypt'), config('bluestore'), config('osd-encrypt-keymanager')) # Make it fast! if config('autotune'): ceph.tune_dev(dev) ceph.start_osds(get_devices())
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 if not vaultlocker.vault_relation_complete(): status_set('waiting', 'Incomplete relation: vault') return # 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)))
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 message is not '': 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)) })
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 message is not '': 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)) })
def prepare_disks_and_activate(): # NOTE: vault/vaultlocker preflight check vault_kv = vaultlocker.VaultKVContext(vaultlocker.VAULTLOCKER_BACKEND) context = vault_kv() if use_vaultlocker() and not vault_kv.complete: log('Deferring OSD preparation as vault not ready', level=DEBUG) return elif use_vaultlocker() and vault_kv.complete: 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 ceph.is_bootstrapped(): 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'): 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', [])) } )
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 if not vaultlocker.vault_relation_complete(): status_set('waiting', 'Incomplete relation: vault') return # 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))