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")
Exemple #3
0
    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)
Exemple #4
0
 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]])
Exemple #5
0
    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
Exemple #7
0
# 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)