def test_is_realpath_dev_mounted_at_destination(self, fake_proc, monkeypatch): monkeypatch.setattr(system.os.path, 'realpath', lambda x: '/dev/sda1' if 'foo' in x else x) result = system.device_is_mounted( '/dev/maper/foo', destination='/far/lib/ceph/osd/ceph-0') assert result is True
def zap_partition(self, device): """ Device example: /dev/sda1 Requirements: Must be a partition """ if device.is_encrypted: # find the holder holders = [ '/dev/%s' % holder for holder in device.sys_api.get('holders', []) ] for mapper_uuid in os.listdir('/dev/mapper'): mapper_path = os.path.join('/dev/mapper', mapper_uuid) if os.path.realpath(mapper_path) in holders: self.dmcrypt_close(mapper_uuid) if system.device_is_mounted(device.abspath): mlogger.info("Unmounting %s", device.abspath) system.unmount(device.abspath) wipefs(device.abspath) zap_data(device.abspath) if self.args.destroy: mlogger.info("Destroying partition since --destroy was used: %s" % device.abspath) disk.remove_partition(device)
def scan(self, args): osd_metadata = {'cluster_name': conf.cluster} device_mounts = system.get_mounts(devices=True) osd_path = None logger.info('detecting if argument is a device or a directory: %s', args.osd_path) if os.path.isdir(args.osd_path): logger.info('will scan directly, path is a directory') osd_path = args.osd_path else: # assume this is a device, check if it is mounted and use that path logger.info('path is not a directory, will check if mounted') if system.device_is_mounted(args.osd_path): logger.info('argument is a device, which is mounted') mounted_osd_paths = device_mounts.get(args.osd_path) osd_path = mounted_osd_paths[0] if len(mounted_osd_paths) else None # argument is not a directory, and it is not a device that is mounted # somewhere so temporarily mount it to poke inside, otherwise, scan # directly if not osd_path: logger.info('device is not mounted, will mount it temporarily to scan') with system.tmp_mount(args.osd_path) as osd_path: osd_metadata = self.scan_directory(osd_path) else: logger.info('will scan OSD directory at path: %s', osd_path) osd_metadata = self.scan_directory(osd_path) osd_id = osd_metadata['whoami'] osd_fsid = osd_metadata['fsid'] filename = '%s-%s.json' % (osd_id, osd_fsid) json_path = os.path.join(self.etc_path, filename) if os.path.exists(json_path) and not args.stdout: if not args.force: raise RuntimeError( '--force was not used and OSD metadata file exists: %s' % json_path ) if args.stdout: print(json.dumps(osd_metadata, indent=4, sort_keys=True, ensure_ascii=False)) else: with open(json_path, 'w') as fp: json.dump(osd_metadata, fp, indent=4, sort_keys=True, ensure_ascii=False) terminal.success( 'OSD %s got scanned and metadata persisted to file: %s' % ( osd_id, json_path ) ) terminal.success( 'To take over managment of this scanned OSD, and disable ceph-disk and udev, run:' ) terminal.success(' ceph-volume simple activate %s %s' % (osd_id, osd_fsid)) if not osd_metadata.get('data'): msg = 'Unable to determine device mounted on %s' % args.osd_path logger.warning(msg) terminal.warning(msg) terminal.warning('OSD will not be able to start without this information:') terminal.warning(' "data": "/path/to/device",') logger.warning('Unable to determine device mounted on %s' % args.osd_path)
def zap_partition(self, device): """ Device example: /dev/sda1 Requirements: Must be a partition """ if device.is_encrypted: # find the holder holders = [ '/dev/%s' % holder for holder in device.sys_api.get('holders', []) ] for mapper_uuid in os.listdir('/dev/mapper'): mapper_path = os.path.join('/dev/mapper', mapper_uuid) if os.path.realpath(mapper_path) in holders: self.dmcrypt_close(mapper_uuid) if system.device_is_mounted(device.abspath): mlogger.info("Unmounting %s", device.abspath) system.unmount(device.abspath) wipefs(device.abspath) zap_data(device.abspath) if self.args.destroy: mlogger.info("Destroying partition since --destroy was used: %s" % device.abspath) disk.remove_partition(device)
def activate_filestore(lvs): # find the osd osd_lv = lvs.get(lv_tags={'ceph.type': 'data'}) if not osd_lv: raise RuntimeError('Unable to find a data LV for filestore activation') is_encrypted = osd_lv.tags.get('ceph.encrypted', '0') == '1' osd_id = osd_lv.tags['ceph.osd_id'] conf.cluster = osd_lv.tags['ceph.cluster_name'] # it may have a volume with a journal osd_journal_lv = lvs.get(lv_tags={'ceph.type': 'journal'}) # TODO: add sensible error reporting if this is ever the case # blow up with a KeyError if this doesn't exist osd_fsid = osd_lv.tags['ceph.osd_fsid'] if not osd_journal_lv: # must be a disk partition, by quering blkid by the uuid we are ensuring that the # device path is always correct journal_uuid = osd_lv.tags['ceph.journal_uuid'] osd_journal = disk.get_device_from_partuuid(journal_uuid) else: journal_uuid = osd_journal_lv.lv_uuid osd_journal = osd_lv.tags['ceph.journal_device'] if not osd_journal: raise RuntimeError('unable to detect an lv or device journal for OSD %s' % osd_id) # this is done here, so that previous checks that ensure path availability # and correctness can still be enforced, and report if any issues are found if is_encrypted: lockbox_secret = osd_lv.tags['ceph.cephx_lockbox_secret'] # this keyring writing is idempotent encryption_utils.write_lockbox_keyring(osd_id, osd_fsid, lockbox_secret) dmcrypt_secret = encryption_utils.get_dmcrypt_key(osd_id, osd_fsid) encryption_utils.luks_open(dmcrypt_secret, osd_lv.lv_path, osd_lv.lv_uuid) encryption_utils.luks_open(dmcrypt_secret, osd_journal, journal_uuid) osd_journal = '/dev/mapper/%s' % journal_uuid source = '/dev/mapper/%s' % osd_lv.lv_uuid else: source = osd_lv.lv_path # mount the osd destination = '/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id) if not system.device_is_mounted(source, destination=destination): process.run(['mount', '-v', source, destination]) # always re-do the symlink regardless if it exists, so that the journal # device path that may have changed can be mapped correctly every time destination = '/var/lib/ceph/osd/%s-%s/journal' % (conf.cluster, osd_id) process.run(['ln', '-snf', osd_journal, destination]) # make sure that the journal has proper permissions system.chown(osd_journal) # enable the ceph-volume unit for this OSD systemctl.enable_volume(osd_id, osd_fsid, 'lvm') # start the OSD systemctl.start_osd(osd_id) terminal.success("ceph-volume lvm activate successful for osd ID: %s" % osd_id)
def activate_filestore(lvs): # find the osd osd_lv = lvs.get(lv_tags={'ceph.type': 'data'}) if not osd_lv: raise RuntimeError('Unable to find a data LV for filestore activation') is_encrypted = osd_lv.tags.get('ceph.encrypted', '0') == '1' osd_id = osd_lv.tags['ceph.osd_id'] conf.cluster = osd_lv.tags['ceph.cluster_name'] # it may have a volume with a journal osd_journal_lv = lvs.get(lv_tags={'ceph.type': 'journal'}) # TODO: add sensible error reporting if this is ever the case # blow up with a KeyError if this doesn't exist osd_fsid = osd_lv.tags['ceph.osd_fsid'] if not osd_journal_lv: # must be a disk partition, by quering blkid by the uuid we are ensuring that the # device path is always correct journal_uuid = osd_lv.tags['ceph.journal_uuid'] osd_journal = disk.get_device_from_partuuid(journal_uuid) else: journal_uuid = osd_journal_lv.lv_uuid osd_journal = osd_lv.tags['ceph.journal_device'] if not osd_journal: raise RuntimeError('unable to detect an lv or device journal for OSD %s' % osd_id) # this is done here, so that previous checks that ensure path availability # and correctness can still be enforced, and report if any issues are found if is_encrypted: lockbox_secret = osd_lv.tags['ceph.cephx_lockbox_secret'] # this keyring writing is idempotent encryption_utils.write_lockbox_keyring(osd_id, osd_fsid, lockbox_secret) dmcrypt_secret = encryption_utils.get_dmcrypt_key(osd_id, osd_fsid) encryption_utils.luks_open(dmcrypt_secret, osd_lv.lv_path, osd_lv.lv_uuid) encryption_utils.luks_open(dmcrypt_secret, osd_journal, journal_uuid) osd_journal = '/dev/mapper/%s' % journal_uuid source = '/dev/mapper/%s' % osd_lv.lv_uuid else: source = osd_lv.lv_path # mount the osd destination = '/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id) if not system.device_is_mounted(source, destination=destination): process.run(['mount', '-v', source, destination]) # always re-do the symlink regardless if it exists, so that the journal # device path that may have changed can be mapped correctly every time destination = '/var/lib/ceph/osd/%s-%s/journal' % (conf.cluster, osd_id) process.run(['ln', '-snf', osd_journal, destination]) # make sure that the journal has proper permissions system.chown(osd_journal) # enable the ceph-volume unit for this OSD systemctl.enable_volume(osd_id, osd_fsid, 'lvm') # start the OSD systemctl.start_osd(osd_id) terminal.success("ceph-volume lvm activate successful for osd ID: %s" % osd_id)
def activate_filestore(lvs): # find the osd osd_lv = lvs.get(lv_tags={'ceph.type': 'data'}) if not osd_lv: raise RuntimeError('Unable to find a data LV for filestore activation') osd_id = osd_lv.tags['ceph.osd_id'] conf.cluster = osd_lv.tags['ceph.cluster_name'] # it may have a volume with a journal osd_journal_lv = lvs.get(lv_tags={'ceph.type': 'journal'}) # TODO: add sensible error reporting if this is ever the case # blow up with a KeyError if this doesn't exist osd_fsid = osd_lv.tags['ceph.osd_fsid'] if not osd_journal_lv: # must be a disk partition, by quering blkid by the uuid we are ensuring that the # device path is always correct osd_journal = disk.get_device_from_partuuid( osd_lv.tags['ceph.journal_uuid']) else: osd_journal = osd_lv.tags['ceph.journal_device'] if not osd_journal: raise RuntimeError( 'unable to detect an lv or device journal for OSD %s' % osd_id) # mount the osd source = osd_lv.lv_path destination = '/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id) if not system.device_is_mounted(source, destination=destination): process.run(['mount', '-v', source, destination]) # always re-do the symlink regardless if it exists, so that the journal # device path that may have changed can be mapped correctly every time destination = '/var/lib/ceph/osd/%s-%s/journal' % (conf.cluster, osd_id) process.run(['ln', '-snf', osd_journal, destination]) # make sure that the journal has proper permissions system.chown(osd_journal) # enable the ceph-volume unit for this OSD systemctl.enable_volume(osd_id, osd_fsid, 'lvm') # start the OSD systemctl.start_osd(osd_id) terminal.success("ceph-volume lvm activate successful for osd ID: %s" % osd_id)
def activate_filestore(lvs): # find the osd osd_lv = lvs.get(lv_tags={'ceph.type': 'data'}) if not osd_lv: raise RuntimeError('Unable to find a data LV for filestore activation') osd_id = osd_lv.tags['ceph.osd_id'] conf.cluster = osd_lv.tags['ceph.cluster_name'] # it may have a volume with a journal osd_journal_lv = lvs.get(lv_tags={'ceph.type': 'journal'}) # TODO: add sensible error reporting if this is ever the case # blow up with a KeyError if this doesn't exist osd_fsid = osd_lv.tags['ceph.osd_fsid'] if not osd_journal_lv: # must be a disk partition, by quering blkid by the uuid we are ensuring that the # device path is always correct osd_journal = disk.get_device_from_partuuid(osd_lv.tags['ceph.journal_uuid']) else: osd_journal = osd_lv.tags['ceph.journal_device'] if not osd_journal: raise RuntimeError('unable to detect an lv or device journal for OSD %s' % osd_id) # mount the osd source = osd_lv.lv_path destination = '/var/lib/ceph/osd/%s-%s' % (conf.cluster, osd_id) if not system.device_is_mounted(source, destination=destination): process.run(['mount', '-v', source, destination]) # always re-do the symlink regardless if it exists, so that the journal # device path that may have changed can be mapped correctly every time destination = '/var/lib/ceph/osd/%s-%s/journal' % (conf.cluster, osd_id) process.run(['ln', '-snf', osd_journal, destination]) # make sure that the journal has proper permissions system.chown(osd_journal) # enable the ceph-volume unit for this OSD systemctl.enable_volume(osd_id, osd_fsid, 'lvm') # start the OSD systemctl.start_osd(osd_id) terminal.success("ceph-volume lvm activate successful for osd ID: %s" % osd_id)
def test_is_mounted_at_destination(self, fake_proc): assert system.device_is_mounted( '/dev/sda1', destination='/far/lib/ceph/osd/ceph-7') is False
def test_path_is_not_device(self, fake_proc): assert system.device_is_mounted('/far/lib/ceph/osd/ceph-7') is False
def test_is_mounted(self, fake_proc): assert system.device_is_mounted('/dev/sda1') is True
def activate(self, args): with open(args.json_config, 'r') as fp: osd_metadata = json.load(fp) osd_id = osd_metadata.get('whoami', args.osd_id) osd_fsid = osd_metadata.get('fsid', args.osd_fsid) cluster_name = osd_metadata.get('cluster_name', 'ceph') osd_dir = '/var/lib/ceph/osd/%s-%s' % (cluster_name, osd_id) data_uuid = osd_metadata.get('data', {}).get('uuid') if not data_uuid: raise RuntimeError( 'Unable to activate OSD %s - no "uuid" key found for data' % args.osd_id ) data_device = disk.get_device_from_partuuid(data_uuid) journal_device = disk.get_device_from_partuuid(osd_metadata.get('journal', {}).get('uuid')) block_device = disk.get_device_from_partuuid(osd_metadata.get('block', {}).get('uuid')) block_db_device = disk.get_device_from_partuuid(osd_metadata.get('block.db', {}).get('uuid')) block_wal_device = disk.get_device_from_partuuid( osd_metadata.get('block.wal', {}).get('uuid') ) if not system.device_is_mounted(data_device, destination=osd_dir): process.run(['sudo', 'mount', '-v', data_device, osd_dir]) device_map = { 'journal': journal_device, 'block': block_device, 'block.db': block_db_device, 'block.wal': block_wal_device } for name, device in device_map.items(): if not device: continue # always re-do the symlink regardless if it exists, so that the journal # device path that may have changed can be mapped correctly every time destination = os.path.join(osd_dir, name) process.run(['sudo', 'ln', '-snf', device, destination]) # make sure that the journal has proper permissions system.chown(device) if not self.systemd: # enable the ceph-volume unit for this OSD systemctl.enable_volume(osd_id, osd_fsid, 'simple') # disable any/all ceph-disk units systemctl.mask_ceph_disk() # enable the OSD systemctl.enable_osd(osd_id) # start the OSD systemctl.start_osd(osd_id) if not self.systemd: terminal.success('Successfully activated OSD %s with FSID %s' % (osd_id, osd_fsid)) terminal.warning( ('All ceph-disk systemd units have been disabled to ' 'prevent OSDs getting triggered by UDEV events') )
def test_is_realpath_path_mounted_at_destination(self, fake_proc, monkeypatch): monkeypatch.setattr( system.os.path, 'realpath', lambda x: '/far/lib/ceph/osd/ceph-0' if 'symlink' in x else x) result = system.device_is_mounted('/dev/sda1', destination='/symlink/lib/ceph/osd/ceph-0') assert result is True
def activate(self, args): with open(args.json_config, 'r') as fp: osd_metadata = json.load(fp) # Make sure that required devices are configured self.validate_devices(osd_metadata) osd_id = osd_metadata.get('whoami', args.osd_id) osd_fsid = osd_metadata.get('fsid', args.osd_fsid) data_uuid = osd_metadata.get('data', {}).get('uuid') conf.cluster = osd_metadata.get('cluster_name', 'ceph') if not data_uuid: raise RuntimeError( 'Unable to activate OSD %s - no "uuid" key found for data' % args.osd_id ) # Encryption detection, and capturing of the keys to decrypt self.is_encrypted = osd_metadata.get('encrypted', False) self.encryption_type = osd_metadata.get('encryption_type') if self.is_encrypted: lockbox_secret = osd_metadata.get('lockbox.keyring') # write the keyring always so that we can unlock encryption_utils.write_lockbox_keyring(osd_id, osd_fsid, lockbox_secret) # Store the secret around so that the decrypt method can reuse raw_dmcrypt_secret = encryption_utils.get_dmcrypt_key(osd_id, osd_fsid) # Note how both these calls need b64decode. For some reason, the # way ceph-disk creates these keys, it stores them in the monitor # *undecoded*, requiring this decode call again. The lvm side of # encryption doesn't need it, so we are assuming here that anything # that `simple` scans, will come from ceph-disk and will need this # extra decode call here self.dmcrypt_secret = base64.b64decode(raw_dmcrypt_secret) cluster_name = osd_metadata.get('cluster_name', 'ceph') osd_dir = '/var/lib/ceph/osd/%s-%s' % (cluster_name, osd_id) # XXX there is no support for LVM here data_device = self.get_device(data_uuid) journal_device = self.get_device(osd_metadata.get('journal', {}).get('uuid')) block_device = self.get_device(osd_metadata.get('block', {}).get('uuid')) block_db_device = self.get_device(osd_metadata.get('block.db', {}).get('uuid')) block_wal_device = self.get_device(osd_metadata.get('block.wal', {}).get('uuid')) if not system.device_is_mounted(data_device, destination=osd_dir): process.run(['mount', '-v', data_device, osd_dir]) device_map = { 'journal': journal_device, 'block': block_device, 'block.db': block_db_device, 'block.wal': block_wal_device } for name, device in device_map.items(): if not device: continue # always re-do the symlink regardless if it exists, so that the journal # device path that may have changed can be mapped correctly every time destination = os.path.join(osd_dir, name) process.run(['ln', '-snf', device, destination]) # make sure that the journal has proper permissions system.chown(device) self.enable_systemd_units(osd_id, osd_fsid) terminal.success('Successfully activated OSD %s with FSID %s' % (osd_id, osd_fsid))
def scan(self, args): osd_metadata = {'cluster_name': conf.cluster} osd_path = None logger.info('detecting if argument is a device or a directory: %s', args.osd_path) if os.path.isdir(args.osd_path): logger.info('will scan directly, path is a directory') osd_path = args.osd_path else: # assume this is a device, check if it is mounted and use that path logger.info('path is not a directory, will check if mounted') if system.device_is_mounted(args.osd_path): logger.info('argument is a device, which is mounted') mounted_osd_paths = self.device_mounts.get(args.osd_path) osd_path = mounted_osd_paths[0] if len(mounted_osd_paths) else None # argument is not a directory, and it is not a device that is mounted # somewhere so temporarily mount it to poke inside, otherwise, scan # directly if not osd_path: # check if we have an encrypted device first, so that we can poke at # the lockbox instead if self.is_encrypted: if not self.encryption_metadata.get('lockbox'): raise RuntimeError( 'Lockbox partition was not found for device: %s' % args.osd_path ) osd_metadata = self.scan_encrypted() else: logger.info('device is not mounted, will mount it temporarily to scan') with system.tmp_mount(args.osd_path) as osd_path: osd_metadata = self.scan_directory(osd_path) else: if self.is_encrypted: logger.info('will scan encrypted OSD directory at path: %s', osd_path) osd_metadata = self.scan_encrypted(osd_path) else: logger.info('will scan OSD directory at path: %s', osd_path) osd_metadata = self.scan_directory(osd_path) osd_id = osd_metadata['whoami'] osd_fsid = osd_metadata['fsid'] filename = '%s-%s.json' % (osd_id, osd_fsid) json_path = os.path.join(self.etc_path, filename) if os.path.exists(json_path) and not args.stdout: if not args.force: raise RuntimeError( '--force was not used and OSD metadata file exists: %s' % json_path ) if args.stdout: print(json.dumps(osd_metadata, indent=4, sort_keys=True, ensure_ascii=False)) else: with open(json_path, 'w') as fp: json.dump(osd_metadata, fp, indent=4, sort_keys=True, ensure_ascii=False) fp.write(os.linesep) terminal.success( 'OSD %s got scanned and metadata persisted to file: %s' % ( osd_id, json_path ) ) terminal.success( 'To take over management of this scanned OSD, and disable ceph-disk and udev, run:' ) terminal.success(' ceph-volume simple activate %s %s' % (osd_id, osd_fsid)) if not osd_metadata.get('data'): msg = 'Unable to determine device mounted on %s' % args.osd_path logger.warning(msg) terminal.warning(msg) terminal.warning('OSD will not be able to start without this information:') terminal.warning(' "data": "/path/to/device",') logger.warning('Unable to determine device mounted on %s' % args.osd_path)
def available_lvm_batch(self): if self.sys_api.get("partitions"): return False if system.device_is_mounted(self.path): return False return self.is_device or self.is_lv
def test_is_mounted(self, fake_proc): assert system.device_is_mounted('/dev/sda1') is True
def test_path_is_not_device(self, fake_proc): assert system.device_is_mounted('/far/lib/ceph/osd/ceph-7') is False
def test_is_not_mounted_at_destination(self, fake_proc): assert system.device_is_mounted('/dev/sda1', destination='/far/lib/ceph/osd/test-1') is False
def activate(self, args): with open(args.json_config, 'r') as fp: osd_metadata = json.load(fp) # Make sure that required devices are configured self.validate_devices(osd_metadata) osd_id = osd_metadata.get('whoami', args.osd_id) osd_fsid = osd_metadata.get('fsid', args.osd_fsid) data_uuid = osd_metadata.get('data', {}).get('uuid') conf.cluster = osd_metadata.get('cluster_name', 'ceph') if not data_uuid: raise RuntimeError( 'Unable to activate OSD %s - no "uuid" key found for data' % args.osd_id) # Encryption detection, and capturing of the keys to decrypt self.is_encrypted = osd_metadata.get('encrypted', False) self.encryption_type = osd_metadata.get('encryption_type') if self.is_encrypted: lockbox_secret = osd_metadata.get('lockbox.keyring') # write the keyring always so that we can unlock encryption_utils.write_lockbox_keyring(osd_id, osd_fsid, lockbox_secret) # Store the secret around so that the decrypt method can reuse raw_dmcrypt_secret = encryption_utils.get_dmcrypt_key( osd_id, osd_fsid) # Note how both these calls need b64decode. For some reason, the # way ceph-disk creates these keys, it stores them in the monitor # *undecoded*, requiring this decode call again. The lvm side of # encryption doesn't need it, so we are assuming here that anything # that `simple` scans, will come from ceph-disk and will need this # extra decode call here self.dmcrypt_secret = base64.b64decode(raw_dmcrypt_secret) cluster_name = osd_metadata.get('cluster_name', 'ceph') osd_dir = '/var/lib/ceph/osd/%s-%s' % (cluster_name, osd_id) # XXX there is no support for LVM here data_device = self.get_device(data_uuid) if not data_device: raise RuntimeError("osd fsid {} doesn't exist, this file will " "be skipped, consider cleaning legacy " "json file {}".format(osd_metadata['fsid'], args.json_config)) journal_device = self.get_device( osd_metadata.get('journal', {}).get('uuid')) block_device = self.get_device( osd_metadata.get('block', {}).get('uuid')) block_db_device = self.get_device( osd_metadata.get('block.db', {}).get('uuid')) block_wal_device = self.get_device( osd_metadata.get('block.wal', {}).get('uuid')) if not system.device_is_mounted(data_device, destination=osd_dir): if osd_metadata.get('type') == 'filestore': prepare_utils.mount_osd(data_device, osd_id) else: process.run(['mount', '-v', data_device, osd_dir]) device_map = { 'journal': journal_device, 'block': block_device, 'block.db': block_db_device, 'block.wal': block_wal_device } for name, device in device_map.items(): if not device: continue # always re-do the symlink regardless if it exists, so that the journal # device path that may have changed can be mapped correctly every time destination = os.path.join(osd_dir, name) process.run(['ln', '-snf', device, destination]) # make sure that the journal has proper permissions system.chown(device) self.enable_systemd_units(osd_id, osd_fsid) terminal.success('Successfully activated OSD %s with FSID %s' % (osd_id, osd_fsid))
def activate(self, args): with open(args.json_config, 'r') as fp: osd_metadata = json.load(fp) osd_id = osd_metadata.get('whoami', args.osd_id) osd_fsid = osd_metadata.get('fsid', args.osd_fsid) cluster_name = osd_metadata.get('cluster_name', 'ceph') osd_dir = '/var/lib/ceph/osd/%s-%s' % (cluster_name, osd_id) data_uuid = osd_metadata.get('data', {}).get('uuid') if not data_uuid: raise RuntimeError( 'Unable to activate OSD %s - no "uuid" key found for data' % args.osd_id ) data_device = disk.get_device_from_partuuid(data_uuid) journal_device = disk.get_device_from_partuuid(osd_metadata.get('journal', {}).get('uuid')) block_device = disk.get_device_from_partuuid(osd_metadata.get('block', {}).get('uuid')) block_db_device = disk.get_device_from_partuuid(osd_metadata.get('block.db', {}).get('uuid')) block_wal_device = disk.get_device_from_partuuid( osd_metadata.get('block.wal', {}).get('uuid') ) if not system.device_is_mounted(data_device, destination=osd_dir): process.run(['mount', '-v', data_device, osd_dir]) device_map = { 'journal': journal_device, 'block': block_device, 'block.db': block_db_device, 'block.wal': block_wal_device } for name, device in device_map.items(): if not device: continue # always re-do the symlink regardless if it exists, so that the journal # device path that may have changed can be mapped correctly every time destination = os.path.join(osd_dir, name) process.run(['ln', '-snf', device, destination]) # make sure that the journal has proper permissions system.chown(device) if not self.systemd: # enable the ceph-volume unit for this OSD systemctl.enable_volume(osd_id, osd_fsid, 'simple') # disable any/all ceph-disk units systemctl.mask_ceph_disk() # enable the OSD systemctl.enable_osd(osd_id) # start the OSD systemctl.start_osd(osd_id) terminal.success('Successfully activated OSD %s with FSID %s' % (osd_id, osd_fsid)) terminal.warning( ('All ceph-disk systemd units have been disabled to ' 'prevent OSDs getting triggered by UDEV events') )