def __init__(self, config, default_config): logger.debug("Creating LocalLoop object; config [%s] " "default_config [%s]", config, default_config) super(LocalLoopNode, self).__init__(config['name']) if 'size' in config: self.size = parse_abs_size_spec(config['size']) logger.debug("Image size [%s]", self.size) else: self.size = parse_abs_size_spec(default_config['image-size']) logger.debug("Using default image size [%s]", self.size) if 'directory' in config: self.image_dir = config['directory'] else: self.image_dir = default_config['image-dir'] self.filename = os.path.join(self.image_dir, self.name + ".raw")
def __init__(self, config, default_config, state): logger.debug("Creating LocalLoop object; config [%s] " "default_config [%s]", config, default_config) super(LocalLoopNode, self).__init__(config['name'], state) if 'size' in config: self.size = parse_abs_size_spec(config['size']) logger.debug("Image size [%s]", self.size) else: self.size = parse_abs_size_spec(default_config['image-size']) logger.debug("Using default image size [%s]", self.size) if 'directory' in config: self.image_dir = config['directory'] else: self.image_dir = default_config['image-dir'] self.filename = os.path.join(self.image_dir, self.name + ".raw")
def _create(self): cmd = [ "lvcreate", ] cmd.extend(['--name', self.name]) if self.type: cmd.extend(['--type', self.type]) if self.thin_pool: cmd.extend(['--thin-pool', self.thin_pool]) if self.size: size = parse_abs_size_spec(self.size) # ensuire size aligns with physical extents size = size - size % PHYSICAL_EXTENT_BYTES size_arg = '-V' if self.type == 'thin' else '-L' cmd.extend([size_arg, '%dB' % size]) elif self.extents: cmd.extend(['-l', self.extents]) if self.options: cmd.extend(self.options) cmd.append(self.base) logger.debug("Creating lv command [%s]", cmd) exec_sudo(cmd) # save state device_name = '%s-%s' % (self.base, self.name) self.state['blockdev'][self.name] = { 'vgs': self.base, 'size': self.size, 'extents': self.extents, 'opts': self.options, 'device': '/dev/mapper/%s' % device_name } self.add_rollback(remove_device, device_name)
def test_parse_size_spec(self): map( lambda tspec: self.assertEqual(parse_abs_size_spec(tspec[0]), tspec[1]), [["20TiB", 20 * 1024**4], ["1024KiB", 1024 * 1024], ["1.2TB", 1.2 * 1000**4], ["2.4T", 2.4 * 1000**4], ["512B", 512], ["364", 364]])
def __init__(self, config, default_config, state): logger.debug("Creating Partitioning object; config [%s]", config) super(Partitioning, self).__init__() # Unlike other PluginBase we are somewhat persistent, as the # partition nodes call back to us (see create() below). We # need to keep this reference. self.state = state # Because using multiple partitions of one base is done # within one object, there is the need to store a flag if the # creation of the partitions was already done. self.already_created = False self.already_cleaned = False # Parameter check if 'base' not in config: raise BlockDeviceSetupException("Partitioning config needs 'base'") self.base = config['base'] if 'partitions' not in config: raise BlockDeviceSetupException( "Partitioning config needs 'partitions'") if 'label' not in config: raise BlockDeviceSetupException( "Partitioning config needs 'label'") self.label = config['label'] if self.label not in ("mbr", ): raise BlockDeviceSetupException("Label must be 'mbr'") # It is VERY important to get the alignment correct. If this # is not correct, the disk performance might be very poor. # Example: In some tests a 'off by one' leads to a write # performance of 30% compared to a correctly aligned # partition. # The problem for DIB is, that it cannot assume that the host # system uses the same IO sizes as the target system, # therefore here a fixed approach (as used in all modern # systems with large disks) is used. The partitions are # aligned to 1MiB (which are about 2048 times 512 bytes # blocks) self.align = 1024 * 1024 # 1MiB as default if 'align' in config: self.align = parse_abs_size_spec(config['align']) self.partitions = [] prev_partition = None for part_cfg in config['partitions']: np = PartitionNode(part_cfg, state, self, prev_partition) self.partitions.append(np) prev_partition = np
def __init__(self, config, default_config, state): logger.debug("Creating Partitioning object; config [%s]", config) super(Partitioning, self).__init__() # Unlike other PluginBase we are somewhat persistent, as the # partition nodes call back to us (see create() below). We # need to keep this reference. self.state = state # Because using multiple partitions of one base is done # within one object, there is the need to store a flag if the # creation of the partitions was already done. self.number_of_partitions = 0 # Parameter check if 'base' not in config: raise BlockDeviceSetupException("Partitioning config needs 'base'") self.base = config['base'] if 'partitions' not in config: raise BlockDeviceSetupException( "Partitioning config needs 'partitions'") if 'label' not in config: raise BlockDeviceSetupException( "Partitioning config needs 'label'") self.label = config['label'] if self.label not in ("mbr", "gpt"): raise BlockDeviceSetupException("Label must be 'mbr' or 'gpt'") # It is VERY important to get the alignment correct. If this # is not correct, the disk performance might be very poor. # Example: In some tests a 'off by one' leads to a write # performance of 30% compared to a correctly aligned # partition. # The problem for DIB is, that it cannot assume that the host # system uses the same IO sizes as the target system, # therefore here a fixed approach (as used in all modern # systems with large disks) is used. The partitions are # aligned to 1MiB (which are about 2048 times 512 bytes # blocks) self.align = 1024 * 1024 # 1MiB as default if 'align' in config: self.align = parse_abs_size_spec(config['align']) self.partitions = [] prev_partition = None for part_cfg in config['partitions']: np = PartitionNode(part_cfg, state, self, prev_partition) self.partitions.append(np) prev_partition = np
# distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import logging from diskimage_builder.block_device.exception \ import BlockDeviceSetupException from diskimage_builder.block_device.plugin import NodeBase from diskimage_builder.block_device.plugin import PluginBase from diskimage_builder.block_device.utils import exec_sudo from diskimage_builder.block_device.utils import parse_abs_size_spec from diskimage_builder.block_device.utils import remove_device PHYSICAL_EXTENT_BYTES = parse_abs_size_spec('4MiB') LVS_TYPES = ['thin', 'thin-pool'] logger = logging.getLogger(__name__) # # LVM # --- # # The LVM config has three required keys; pvs, vgs and lvs # # lvm: -> LVSNode # pvs: -> PvsNode # lvs: -> LvsNode # vgs: -> VgsNode #
def __init__(self, config, default_config): logger.debug("Creating Partitioning object; config [%s]" % config) # Because using multiple partitions of one base is done # within one object, there is the need to store a flag if the # creation of the partitions was already done. self.already_created = False # Parameter check if 'base' not in config: self._config_error("Partitioning config needs 'base'") self.base = config['base'] if 'label' not in config: self._config_error("Partitioning config needs 'label'") self.label = config['label'] if self.label not in ("mbr", ): self._config_error("Label must be 'mbr'") # It is VERY important to get the alignment correct. If this # is not correct, the disk performance might be very poor. # Example: In some tests a 'off by one' leads to a write # performance of 30% compared to a correctly aligned # partition. # The problem for DIB is, that it cannot assume that the host # system uses the same IO sizes as the target system, # therefore here a fixed approach (as used in all modern # systems with large disks) is used. The partitions are # aligned to 1MiB (which are about 2048 times 512 bytes # blocks) self.align = 1024 * 1024 # 1MiB as default if 'align' in config: self.align = parse_abs_size_spec(config['align']) if 'partitions' not in config: self._config_error("Partitioning config needs 'partitions'") self.partitions = collections.OrderedDict() for part_cfg in config['partitions']: if 'name' not in part_cfg: self.config_error("Missing 'name' in partition config") part_name = part_cfg['name'] flags = set() if 'flags' in part_cfg: for f in part_cfg['flags']: if f == 'boot': flags.add(Partitioning.flag_boot) elif f == 'primary': flags.add(Partitioning.flag_primary) else: self._config_error("Unknown flag [%s] in " "partitioning for [%s]" % (f, part_name)) if 'size' not in part_cfg: self._config_error("No 'size' in partition [%s]" % part_name) size = part_cfg['size'] ptype = int(part_cfg['type'], 16) if 'type' in part_cfg else 0x83 self.partitions[part_name] \ = Partition(part_name, flags, size, ptype, self.base, self) logger.debug(part_cfg)
def test_parse_abs_size_without_spec(self): """Call parse_abs_size_spec without spec""" size = parse_abs_size_spec("198") self.assertEqual(198, size)