def config_lvm(dev): if (is_lvm_physical_volume(dev) and list_lvm_volume_group(dev) == VG_NAME): log('Device already configured for LVM/LXD, skipping') return status_set('maintenance', 'Configuring LVM container storage') cmd = ['systemctl', 'enable', 'lvm2-lvmetad'] check_call(cmd) cmd = ['systemctl', 'start', 'lvm2-lvmetad'] check_call(cmd) if has_storage(): cmd = [ 'lxc', 'storage', 'create', LXD_POOL, 'lvm', 'source={}'.format(dev), 'lvm.vg_name={}'.format(VG_NAME) ] check_call(cmd) else: create_lvm_physical_volume(dev) create_lvm_volume_group(VG_NAME, dev) cmd = ['lxc', 'config', 'set', 'storage.lvm_vg_name', VG_NAME] check_call(cmd) # The LVM thinpool logical volume is lazily created, either on # image import or container creation. This will force LV creation. create_and_import_busybox_image()
def prepare_lvm_storage(block_device, volume_group): ''' Ensures block_device is initialized as a LVM PV and creates volume_group. Assumes block device is clean and will raise if storage is already initialized as a PV. :param block_device: str: Full path to block device to be prepared. :param volume_group: str: Name of volume group to be created with block_device as backing PV. :returns: None or raises CinderCharmError if storage is unclean. ''' e = None if is_lvm_physical_volume(block_device): juju_log('ERROR: Could not prepare LVM storage: %s is already ' 'initialized as LVM physical device.' % block_device) raise CinderCharmError try: create_lvm_physical_volume(block_device) create_lvm_volume_group(volume_group, block_device) except Exception as e: juju_log('Could not prepare LVM storage on %s.' % block_device) juju_log(e) raise CinderCharmError
def config_lvm(dev): if (is_lvm_physical_volume(dev) and list_lvm_volume_group(dev) == VG_NAME): log('Device already configured for LVM/LXD, skipping') return status_set('maintenance', 'Configuring LVM container storage') cmd = ['systemctl', 'enable', 'lvm2-lvmetad'] check_call(cmd) cmd = ['systemctl', 'start', 'lvm2-lvmetad'] check_call(cmd) if has_storage(): cmd = ['lxc', 'storage', 'create', LXD_POOL, 'lvm', 'source={}'.format(dev), 'lvm.vg_name={}'.format(VG_NAME)] check_call(cmd) else: create_lvm_physical_volume(dev) create_lvm_volume_group(VG_NAME, dev) cmd = ['lxc', 'config', 'set', 'storage.lvm_vg_name', VG_NAME] check_call(cmd) # The LVM thinpool logical volume is lazily created, either on # image import or container creation. This will force LV creation. create_and_import_busybox_image()
def manage_lvm(device, dirname): """Add the device to the VG corresponding to the dirname. In this case, logical volume name will be dirname with / replaced by _ symbols. If logical volume already exists, then, device is added as a new physical device and the entire logical volume is resized. If logical volume name does not exist, then prepare the physical device and add to the newly created volume. """ lv_name = "lvm" + dirname.replace("/", "_") vg_name = "vg" + dirname.replace("/", "_") pv = device try: if list_lvm_volume_group(device): # PV already used, raise this as an issue pv = None except subprocess.CalledProcessError: # Device does not exist in the list, continue pass if not pv: raise DiskMapHelperPVAlreadyTakenForLVM(device, lv_name) if not is_lvm_physical_volume(device): # This is not a PV yet, create one create_lvm_physical_volume(device) if lv_name not in list_logical_volumes(): # lv_name is always associated 1:1 with vg_name # If one does not exist, so we need to create both. create_lvm_volume_group(vg_name, pv) create_logical_volume(lv_name, vg_name) else: # Now extend the lv_name: extend_logical_volume_by_device(lv_name, pv) # TODO: find FS already present and resize it as well return "/dev/{}/{}".format(vg_name, lv_name)
def prepare_volume(device): juju_log("prepare_volume: {}".format(device)) clean_storage(device) create_lvm_physical_volume(device) juju_log("prepared volume: {}".format(device))
def test_pvcreate(self): '''It correctly calls pvcreate for a given block dev''' with patch(STORAGE_LINUX_LVM + '.check_call') as check_call: lvm.create_lvm_physical_volume('/dev/foo') check_call.assert_called_with(['pvcreate', '/dev/foo'])
def configure_lxd_block(): '''Configure a block device for use by LXD for containers''' log('Configuring LXD container storage') if filesystem_mounted('/var/lib/lxd'): log('/var/lib/lxd already configured, skipping') return lxd_block_devices = get_block_devices() if len(lxd_block_devices) < 1: log('block devices not provided - skipping') return if len(lxd_block_devices) > 1: raise NotImplementedError('Multiple block devices are not supported.') lxd_block_device = lxd_block_devices[0] dev = None if lxd_block_device.startswith('/dev/'): dev = lxd_block_device elif lxd_block_device.startswith('/'): log('Configuring loopback device for use with LXD') _bd = lxd_block_device.split('|') if len(_bd) == 2: dev, size = _bd else: dev = lxd_block_device size = DEFAULT_LOOPBACK_SIZE dev = ensure_loopback_device(dev, size) if not dev or not is_block_device(dev): log('Invalid block device provided: %s' % lxd_block_device) return # NOTE: check overwrite and ensure its only execute once. db = kv() if config('overwrite') and not db.get('scrubbed', False): clean_storage(dev) db.set('scrubbed', True) db.flush() if not os.path.exists('/var/lib/lxd'): mkdir('/var/lib/lxd') if config('storage-type') == 'btrfs': status_set('maintenance', 'Configuring btrfs container storage') lxd_stop() cmd = ['mkfs.btrfs', '-f', dev] check_call(cmd) mount(dev, '/var/lib/lxd', options='user_subvol_rm_allowed', persist=True, filesystem='btrfs') cmd = ['btrfs', 'quota', 'enable', '/var/lib/lxd'] check_call(cmd) lxd_start() elif config('storage-type') == 'lvm': if (is_lvm_physical_volume(dev) and list_lvm_volume_group(dev) == 'lxd_vg'): log('Device already configured for LVM/LXD, skipping') return status_set('maintenance', 'Configuring LVM container storage') # Enable and startup lvm2-lvmetad to avoid extra output # in lvm2 commands, which confused lxd. cmd = ['systemctl', 'enable', 'lvm2-lvmetad'] check_call(cmd) cmd = ['systemctl', 'start', 'lvm2-lvmetad'] check_call(cmd) create_lvm_physical_volume(dev) create_lvm_volume_group('lxd_vg', dev) cmd = ['lxc', 'config', 'set', 'storage.lvm_vg_name', 'lxd_vg'] check_call(cmd) # The LVM thinpool logical volume is lazily created, either on # image import or container creation. This will force LV creation. create_and_import_busybox_image() elif config('storage-type') == 'zfs': status_set('maintenance', 'Configuring zfs container storage') if ZFS_POOL_NAME in zpools(): log('ZFS pool already exist; skipping zfs configuration') return if config('overwrite'): cmd = ['zpool', 'create', '-f', ZFS_POOL_NAME, dev] else: cmd = ['zpool', 'create', ZFS_POOL_NAME, dev] check_call(cmd) cmd = ['lxc', 'config', 'set', 'storage.zfs_pool_name', ZFS_POOL_NAME] check_call(cmd)
def prepare_volume(device): clean_storage(device) create_lvm_physical_volume(device)
def configure_lxd_block(): '''Configure a block device for use by LXD for containers''' log('Configuring LXD container storage') if filesystem_mounted('/var/lib/lxd'): log('/var/lib/lxd already configured, skipping') return lxd_block_devices = get_block_devices() if len(lxd_block_devices) < 1: log('block devices not provided - skipping') return if len(lxd_block_devices) > 1: log("More than one block device is not supported yet, only" " using the first") lxd_block_device = lxd_block_devices[0] dev = None if lxd_block_device.startswith('/dev/'): dev = lxd_block_device elif lxd_block_device.startswith('/'): log('Configuring loopback device for use with LXD') _bd = lxd_block_device.split('|') if len(_bd) == 2: dev, size = _bd else: dev = lxd_block_device size = DEFAULT_LOOPBACK_SIZE dev = ensure_loopback_device(dev, size) if not dev or not is_block_device(dev): log('Invalid block device provided: %s' % lxd_block_device) return # NOTE: check overwrite and ensure its only execute once. db = kv() if config('overwrite') and not db.get('scrubbed', False): clean_storage(dev) db.set('scrubbed', True) db.flush() if not os.path.exists('/var/lib/lxd'): mkdir('/var/lib/lxd') if config('storage-type') == 'btrfs': status_set('maintenance', 'Configuring btrfs container storage') lxd_stop() cmd = ['mkfs.btrfs', '-f', dev] check_call(cmd) mount(dev, '/var/lib/lxd', options='user_subvol_rm_allowed', persist=True, filesystem='btrfs') cmd = ['btrfs', 'quota', 'enable', '/var/lib/lxd'] check_call(cmd) lxd_start() elif config('storage-type') == 'lvm': if (is_lvm_physical_volume(dev) and list_lvm_volume_group(dev) == 'lxd_vg'): log('Device already configured for LVM/LXD, skipping') return status_set('maintenance', 'Configuring LVM container storage') # Enable and startup lvm2-lvmetad to avoid extra output # in lvm2 commands, which confused lxd. cmd = ['systemctl', 'enable', 'lvm2-lvmetad'] check_call(cmd) cmd = ['systemctl', 'start', 'lvm2-lvmetad'] check_call(cmd) create_lvm_physical_volume(dev) create_lvm_volume_group('lxd_vg', dev) cmd = ['lxc', 'config', 'set', 'storage.lvm_vg_name', 'lxd_vg'] check_call(cmd) # The LVM thinpool logical volume is lazily created, either on # image import or container creation. This will force LV creation. create_and_import_busybox_image() elif config('storage-type') == 'zfs': status_set('maintenance', 'Configuring zfs container storage') if ZFS_POOL_NAME in zpools(): log('ZFS pool already exist; skipping zfs configuration') return if config('overwrite'): cmd = ['zpool', 'create', '-f', ZFS_POOL_NAME, dev] else: cmd = ['zpool', 'create', ZFS_POOL_NAME, dev] check_call(cmd) cmd = ['lxc', 'config', 'set', 'storage.zfs_pool_name', ZFS_POOL_NAME] check_call(cmd)