Hello community, here is the log from the commit of package diskimage-builder for openSUSE:Factory checked in at 2017-05-27 13:19:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/diskimage-builder (Old) and /work/SRC/openSUSE:Factory/.diskimage-builder.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "diskimage-builder" Sat May 27 13:19:33 2017 rev:7 rq:498609 version:2.4.1 Changes: -------- --- /work/SRC/openSUSE:Factory/diskimage-builder/diskimage-builder.changes 2017-05-18 20:51:43.022497402 +0200 +++ /work/SRC/openSUSE:Factory/.diskimage-builder.new/diskimage-builder.changes 2017-05-27 13:20:47.970854763 +0200 @@ -1,0 +2,15 @@ +Thu May 25 07:59:42 UTC 2017 - [email protected] + +- Version bump to 2.4.1 + * Set manifest permissions in the image + * Move parts of Partition creation into object + * Split partition into it's own file + * Move exception to it's own file (again) + * Add weights to digraph + * Switch debian to deb.debian.org + * Add dracut-regenerate elements + * Set manifests to mode 600 and owner root + * Only unmount directories that are mounted + * Apply setfiles on all mountpoints + +------------------------------------------------------------------- Old: ---- diskimage-builder-2.4.0.tar.gz New: ---- diskimage-builder-2.4.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ diskimage-builder.spec ++++++ --- /var/tmp/diff_new_pack.gxjTLg/_old 2017-05-27 13:20:49.014707191 +0200 +++ /var/tmp/diff_new_pack.gxjTLg/_new 2017-05-27 13:20:49.018706626 +0200 @@ -21,7 +21,7 @@ %global __requires_exclude_from ^%{python_sitelib}/diskimage_builder/elements/.*$ Name: diskimage-builder -Version: 2.4.0 +Version: 2.4.1 Release: 0 Summary: Image Building Tools for OpenStack License: Apache-2.0 ++++++ diskimage-builder-2.4.0.tar.gz -> diskimage-builder-2.4.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/ChangeLog new/diskimage-builder-2.4.1/ChangeLog --- old/diskimage-builder-2.4.0/ChangeLog 2017-05-15 02:47:19.000000000 +0200 +++ new/diskimage-builder-2.4.1/ChangeLog 2017-05-25 01:23:56.000000000 +0200 @@ -1,6 +1,25 @@ CHANGES ======= +2.4.1 +----- + +* Set manifest permissions in the image +* Move parts of Partition creation into object +* Split partition into it's own file +* Move exception to it's own file (again) +* Add weights to digraph +* Switch debian to deb.debian.org +* Add dracut-regenerate elements +* Remove \_config\_error thrower +* Set manifests to mode 600 and owner root +* Use fakelogger in test\_blockdevice\_mbr +* Remove PluginBase/NodePluginBase class +* Only unmount directories that are mounted +* Updated from global requirements +* Apply setfiles on all mountpoints +* Updated from global requirements + 2.4.0 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/PKG-INFO new/diskimage-builder-2.4.1/PKG-INFO --- old/diskimage-builder-2.4.0/PKG-INFO 2017-05-15 02:47:20.000000000 +0200 +++ new/diskimage-builder-2.4.1/PKG-INFO 2017-05-25 01:23:57.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: diskimage-builder -Version: 2.4.0 +Version: 2.4.1 Summary: Golden Disk Image builder. Home-page: http://docs.openstack.org/developer/diskimage-builder/ Author: OpenStack diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/block_device/blockdevice.py new/diskimage-builder-2.4.1/diskimage_builder/block_device/blockdevice.py --- old/diskimage-builder-2.4.0/diskimage_builder/block_device/blockdevice.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/block_device/blockdevice.py 2017-05-25 01:23:24.000000000 +0200 @@ -22,6 +22,8 @@ from stevedore import extension +from diskimage_builder.block_device.exception import \ + BlockDeviceSetupException from diskimage_builder.block_device.utils import exec_sudo from diskimage_builder.graph.digraph import Digraph @@ -29,10 +31,6 @@ logger = logging.getLogger(__name__) -class BlockDeviceSetupException(Exception): - pass - - class BlockDevice(object): """Handles block devices. @@ -298,7 +296,10 @@ return 0 if symbol == 'mount-points': mount_points = self._config_get_all_mount_points() - print("%s" % " ".join(mount_points)) + # we return the mountpoints joined by a pipe, because it is not + # a valid char in directories, so it is a safe separator for the + # mountpoints list + print("%s" % "|".join(mount_points)) return 0 if symbol == 'image-block-partition': # If there is no partition needed, pass back directly the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/block_device/exception.py new/diskimage-builder-2.4.1/diskimage_builder/block_device/exception.py --- old/diskimage-builder-2.4.0/diskimage_builder/block_device/exception.py 1970-01-01 01:00:00.000000000 +0100 +++ new/diskimage-builder-2.4.1/diskimage_builder/block_device/exception.py 2017-05-25 01:23:24.000000000 +0200 @@ -0,0 +1,15 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# 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. + + +class BlockDeviceSetupException(Exception): + """Generic exception""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/block_device/level0/localloop.py new/diskimage-builder-2.4.1/diskimage_builder/block_device/level0/localloop.py --- old/diskimage-builder-2.4.0/diskimage_builder/block_device/level0/localloop.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/block_device/level0/localloop.py 2017-05-25 01:23:24.000000000 +0200 @@ -16,9 +16,8 @@ import os import subprocess -from diskimage_builder.block_device.blockdevice import \ +from diskimage_builder.block_device.exception import \ BlockDeviceSetupException -from diskimage_builder.block_device.plugin_base import NodePluginBase from diskimage_builder.block_device.tree_config import TreeConfig from diskimage_builder.block_device.utils import parse_abs_size_spec from diskimage_builder.graph.digraph import Digraph @@ -27,7 +26,7 @@ logger = logging.getLogger(__name__) -class LocalLoop(NodePluginBase): +class LocalLoop(Digraph.Node): """Level0: Local loop image device handling. This class handles local loop devices that can be used @@ -56,6 +55,10 @@ """Because this is created without base, there are no edges.""" pass + def insert_nodes(self, dg): + """Adds self as a node to the given digraph""" + dg.add_node(self) + @staticmethod def image_create(filename, size): logger.info("Create image file [%s]" % filename) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/block_device/level1/partition.py new/diskimage-builder-2.4.1/diskimage_builder/block_device/level1/partition.py --- old/diskimage-builder-2.4.0/diskimage_builder/block_device/level1/partition.py 1970-01-01 01:00:00.000000000 +0100 +++ new/diskimage-builder-2.4.1/diskimage_builder/block_device/level1/partition.py 2017-05-25 01:23:24.000000000 +0200 @@ -0,0 +1,125 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# 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.tree_config import TreeConfig +from diskimage_builder.graph.digraph import Digraph + + +logger = logging.getLogger(__name__) + + +class PartitionTreeConfig(object): + + @staticmethod + def config_tree_to_digraph(config_key, config_value, pconfig, dconfig, + base_name, plugin_manager): + logger.debug("called [%s] [%s] [%s]" + % (config_key, config_value, base_name)) + assert config_key == Partition.type_string + + for partition in config_value: + name = partition['name'] + nconfig = { + 'name': name, + 'base': base_name + } + for k, v in partition.items(): + if k not in plugin_manager: + nconfig[k] = v + else: + plugin_manager[k].plugin \ + .tree_config.config_tree_to_digraph( + k, v, dconfig, name, plugin_manager) + pconfig.append(nconfig) + + logger.debug("finished [%s] [%s]" % (nconfig, dconfig)) + + +class Partition(Digraph.Node): + + type_string = "partitions" + tree_config = TreeConfig("partitions") + + flag_boot = 1 + flag_primary = 2 + + def __init__(self, config, parent, prev_partition): + if 'name' not in config: + raise BlockDeviceSetupException( + "Missing 'name' in partition config: %s" % config) + self.name = config['name'] + + Digraph.Node.__init__(self, self.name) + + self.base = config['base'] + self.partitioning = parent + self.prev_partition = prev_partition + + self.flags = set() + if 'flags' in config: + for f in config['flags']: + if f == 'boot': + self.flags.add(self.flag_boot) + elif f == 'primary': + self.flags.add(self.flag_primary) + else: + raise BlockDeviceSetupException("Unknown flag: %s" % f) + + if 'size' not in config: + raise BlockDeviceSetupException("No size in partition" % self.name) + self.size = config['size'] + + self.ptype = int(config['type'], 16) if 'type' in config else 0x83 + + def __repr__(self): + return "<Partition [%s] on [%s] size [%s] prev [%s]>" \ + % (self.name, self.base, self.size, + self.prev_partition.name if self.prev_partition else "UNSET") + + def get_flags(self): + return self.flags + + def get_size(self): + return self.size + + def get_type(self): + return self.ptype + + def get_name(self): + return self.name + + def insert_edges(self, dg): + bnode = dg.find(self.base) + assert bnode is not None + dg.create_edge(bnode, self) + if self.prev_partition is not None: + logger.debug("Insert edge [%s]" % self) + dg.create_edge(self.prev_partition, self) + + def create(self, result, rollback): + self.partitioning.create(result, rollback) + + def umount(self, state): + """Partition does not need any umount task.""" + pass + + def cleanup(self, state): + """Partition does not need any cleanup.""" + pass + + def delete(self, state): + """Partition does not need any cleanup.""" + pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/block_device/level1/partitioning.py new/diskimage-builder-2.4.1/diskimage_builder/block_device/level1/partitioning.py --- old/diskimage-builder-2.4.0/diskimage_builder/block_device/level1/partitioning.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/block_device/level1/partitioning.py 2017-05-25 01:23:24.000000000 +0200 @@ -17,11 +17,13 @@ from subprocess import CalledProcessError -from diskimage_builder.block_device.blockdevice import \ +from diskimage_builder.block_device.exception import \ BlockDeviceSetupException from diskimage_builder.block_device.level1.mbr import MBR -from diskimage_builder.block_device.plugin_base import PluginBase -from diskimage_builder.block_device.tree_config import TreeConfig +from diskimage_builder.block_device.level1.partition import \ + Partition +from diskimage_builder.block_device.level1.partition import \ + PartitionTreeConfig 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 parse_rel_size_spec @@ -31,87 +33,6 @@ logger = logging.getLogger(__name__) -class PartitionTreeConfig(object): - - @staticmethod - def config_tree_to_digraph(config_key, config_value, pconfig, dconfig, - base_name, plugin_manager): - logger.debug("called [%s] [%s] [%s]" - % (config_key, config_value, base_name)) - assert config_key == Partition.type_string - - for partition in config_value: - name = partition['name'] - nconfig = {'name': name} - for k, v in partition.items(): - if k not in plugin_manager: - nconfig[k] = v - else: - plugin_manager[k].plugin \ - .tree_config.config_tree_to_digraph( - k, v, dconfig, name, plugin_manager) - pconfig.append(nconfig) - - logger.debug("finished [%s] [%s]" % (nconfig, dconfig)) - - -class Partition(Digraph.Node): - - type_string = "partitions" - tree_config = TreeConfig("partitions") - - def __init__(self, name, flags, size, ptype, base, partitioning, - prev_partition): - Digraph.Node.__init__(self, name) - self.name = name - self.flags = flags - self.size = size - self.ptype = ptype - self.base = base - self.partitioning = partitioning - self.prev_partition = prev_partition - - def __repr__(self): - return "<Partition [%s] on [%s] size [%s] prev [%s]>" \ - % (self.name, self.base, self.size, - self.prev_partition.name if self.prev_partition else "UNSET") - - def get_flags(self): - return self.flags - - def get_size(self): - return self.size - - def get_type(self): - return self.ptype - - def get_name(self): - return self.name - - def insert_edges(self, dg): - bnode = dg.find(self.base) - assert bnode is not None - dg.create_edge(bnode, self) - if self.prev_partition is not None: - logger.debug("Insert edge [%s]" % self) - dg.create_edge(self.prev_partition, self) - - def create(self, result, rollback): - self.partitioning.create(result, rollback) - - def umount(self, state): - """Partitioning does not need any umount task.""" - pass - - def cleanup(self, state): - """Partitioning does not need any cleanup.""" - pass - - def delete(self, state): - """Partitioning does not need any cleanup.""" - pass - - class PartitioningTreeConfig(object): @staticmethod @@ -136,13 +57,10 @@ logger.debug("finished new [%s] complete [%s]" % (nconfig, dconfig)) -class Partitioning(PluginBase): +class Partitioning(Digraph.Node): tree_config = PartitioningTreeConfig() - flag_boot = 1 - flag_primary = 2 - def __init__(self, config, default_config): logger.debug("Creating Partitioning object; config [%s]" % config) # Because using multiple partitions of one base is done @@ -152,14 +70,19 @@ # Parameter check if 'base' not in config: - self._config_error("Partitioning config needs 'base'") + 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: - self._config_error("Partitioning config needs 'label'") + raise BlockDeviceSetupException( + "Partitioning config needs 'label'") self.label = config['label'] if self.label not in ("mbr", ): - self._config_error("Label must be '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. @@ -176,44 +99,13 @@ 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 = [] prev_partition = None 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 - - np = Partition(part_name, flags, size, ptype, self.base, self, - prev_partition) + np = Partition(part_cfg, self, prev_partition) self.partitions.append(np) prev_partition = np - logger.debug(part_cfg) - - def _config_error(self, msg): - logger.error(msg) - raise BlockDeviceSetupException(msg) def _size_of_block_dev(self, dev): with open(dev, "r") as fd: @@ -280,9 +172,9 @@ with MBR(image_path, disk_size, self.align) as part_impl: for part_cfg in self.partitions: part_name = part_cfg.get_name() - part_bootflag = Partitioning.flag_boot \ + part_bootflag = Partition.flag_boot \ in part_cfg.get_flags() - part_primary = Partitioning.flag_primary \ + part_primary = Partition.flag_primary \ in part_cfg.get_flags() part_size = part_cfg.get_size() part_free = part_impl.free() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/block_device/level2/mkfs.py new/diskimage-builder-2.4.1/diskimage_builder/block_device/level2/mkfs.py --- old/diskimage-builder-2.4.0/diskimage_builder/block_device/level2/mkfs.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/block_device/level2/mkfs.py 2017-05-25 01:23:24.000000000 +0200 @@ -15,7 +15,7 @@ import logging import uuid -from diskimage_builder.block_device.blockdevice \ +from diskimage_builder.block_device.exception \ import BlockDeviceSetupException from diskimage_builder.block_device.tree_config import TreeConfig from diskimage_builder.block_device.utils import exec_sudo @@ -43,16 +43,13 @@ class Filesystem(Digraph.Node): - def _config_error(self, msg): - logger.error(msg) - raise BlockDeviceSetupException(msg) - def __init__(self, config): logger.debug("Create filesystem object; config [%s]" % config) # Parameter check (mandatory) for pname in ['base', 'name', 'type']: if pname not in config: - self._config_error("Mkfs config needs [%s]" % pname) + raise BlockDeviceSetupException( + "Mkfs config needs [%s]" % pname) setattr(self, pname, config[pname]) # Parameter check (optional) @@ -71,20 +68,19 @@ self.label = "img-rootfs" if self.label in file_system_labels: - self._config_error( - "File system label [%s] used more than once" % - self.label) + raise BlockDeviceSetupException( + "File system label [%s] used more than once" % self.label) file_system_labels.add(self.label) if self.type in file_system_max_label_length: - if file_system_max_label_length[self.type] < \ - len(self.label): - self._config_error( - "Label [%s] too long for filesystem [%s]: " - "maximum length [%d] provided length [%d]" % - (self.label, self.type, - file_system_max_label_length[self.type], - len(self.label))) + if file_system_max_label_length[self.type] < len(self.label): + raise BlockDeviceSetupException( + "Label [{label}] too long for filesystem [{type}]: " + " [{len}] > [{max_len}]".format({ + 'label': self.label, + 'type': self.type, + 'len': len(self.label), + 'max': file_system_max_label_length[self.type]})) else: logger.warning("Length of label [%s] cannot be checked for " "filesystem [%s]: unknown max length" % diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/block_device/level3/mount.py new/diskimage-builder-2.4.1/diskimage_builder/block_device/level3/mount.py --- old/diskimage-builder-2.4.0/diskimage_builder/block_device/level3/mount.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/block_device/level3/mount.py 2017-05-25 01:23:24.000000000 +0200 @@ -15,7 +15,7 @@ import logging import os -from diskimage_builder.block_device.blockdevice \ +from diskimage_builder.block_device.exception \ import BlockDeviceSetupException from diskimage_builder.block_device.tree_config import TreeConfig from diskimage_builder.block_device.utils import exec_sudo @@ -35,17 +35,13 @@ class MountPoint(Digraph.Node): - @staticmethod - def _config_error(msg): - logger.error(msg) - raise BlockDeviceSetupException(msg) - def __init__(self, mount_base, config): # Parameter check self.mount_base = mount_base for pname in ['base', 'name', 'mount_point']: if pname not in config: - self._config_error("MountPoint config needs [%s]" % pname) + raise BlockDeviceSetupException( + "MountPoint config needs [%s]" % pname) setattr(self, pname, config[pname]) Digraph.Node.__init__(self, self.name) logger.debug("MountPoint created [%s]" % self) @@ -57,8 +53,9 @@ def insert_node(self, dg): global mount_points if self.mount_point in mount_points: - self._config_error("Mount point [%s] specified more than once" - % self.mount_point) + raise BlockDeviceSetupException( + "Mount point [%s] specified more than once" + % self.mount_point) logger.debug("Insert node [%s]" % self) mount_points[self.mount_point] = self dg.add_node(self) @@ -136,17 +133,14 @@ type_string = "mount" tree_config = TreeConfig("mount") - def _config_error(self, msg): - logger.error(msg) - raise BlockDeviceSetupException(msg) - def __init__(self, config, params): logger.debug("Mounting object; config [%s]" % config) self.config = config self.params = params if 'mount-base' not in self.params: - MountPoint._config_error("Mount default config needs 'mount-base'") + raise BlockDeviceSetupException( + "Mount default config needs 'mount-base'") self.mount_base = self.params['mount-base'] self.mount_points = {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/block_device/level4/fstab.py new/diskimage-builder-2.4.1/diskimage_builder/block_device/level4/fstab.py --- old/diskimage-builder-2.4.0/diskimage_builder/block_device/level4/fstab.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/block_device/level4/fstab.py 2017-05-25 01:23:24.000000000 +0200 @@ -14,8 +14,6 @@ import logging -from diskimage_builder.block_device.blockdevice \ - import BlockDeviceSetupException from diskimage_builder.block_device.tree_config import TreeConfig from diskimage_builder.graph.digraph import Digraph @@ -28,10 +26,6 @@ type_string = "fstab" tree_config = TreeConfig("fstab") - def _config_error(self, msg): - logger.error(msg) - raise BlockDeviceSetupException(msg) - def __init__(self, config, params): logger.debug("Fstab object; config [%s]" % config) self.config = config diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/block_device/plugin_base.py new/diskimage-builder-2.4.1/diskimage_builder/block_device/plugin_base.py --- old/diskimage-builder-2.4.0/diskimage_builder/block_device/plugin_base.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/block_device/plugin_base.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,52 +0,0 @@ -# Copyright 2017 Andreas Florath ([email protected]) -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# 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 abc -import six - -from diskimage_builder.graph.digraph import Digraph - - [email protected]_metaclass(abc.ABCMeta) -class PluginBase(object): - """Abstract base class for block device plugins""" - - def __init__(self, name): - """All plugins must have a name""" - self.name = name - - @abc.abstractmethod - def create(self, state, rollback): - """Create the block device plugin - - :param state: a dictionary to store results for this plugin. - These are used in two scenarios: other plugins - can use this to get information about the - result of the plugin and it can be used in - later runs of dib-block-device for cleaning up. - :type state: dict(str:?) - - :param rollback: a list of python functions that will be - called in reversed order to cleanup if there - occurs an error later within the same - dib-block-device run. - :type rollback: list(function) - """ - - -class NodePluginBase(PluginBase, Digraph.Node): - - def insert_nodes(self, dg): - """Adds self as a node to the given digraph""" - dg.add_node(self) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/elements/debian-minimal/environment.d/10-debian-minimal.bash new/diskimage-builder-2.4.1/diskimage_builder/elements/debian-minimal/environment.d/10-debian-minimal.bash --- old/diskimage-builder-2.4.0/diskimage_builder/elements/debian-minimal/environment.d/10-debian-minimal.bash 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/elements/debian-minimal/environment.d/10-debian-minimal.bash 2017-05-25 01:23:24.000000000 +0200 @@ -4,7 +4,7 @@ if [ -n "${DIB_DEBIAN_DISTRIBUTION_MIRROR:-}" ]; then DIB_DISTRIBUTION_MIRROR=$DIB_DEBIAN_DISTRIBUTION_MIRROR fi -export DIB_DISTRIBUTION_MIRROR=${DIB_DISTRIBUTION_MIRROR:-http://ftp.us.debian.org/debian} +export DIB_DISTRIBUTION_MIRROR=${DIB_DISTRIBUTION_MIRROR:-http://deb.debian.org/debian} export DIB_DEBIAN_COMPONENTS=${DIB_DEBIAN_COMPONENTS:-main} export DIB_DEBIAN_COMPONENTS_WS=${DIB_DEBIAN_COMPONENTS//,/ } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/elements/debootstrap/README.rst new/diskimage-builder-2.4.1/diskimage_builder/elements/debootstrap/README.rst --- old/diskimage-builder-2.4.0/diskimage_builder/elements/debootstrap/README.rst 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/elements/debootstrap/README.rst 2017-05-25 01:23:24.000000000 +0200 @@ -14,16 +14,11 @@ overwrite the two environment variables to adapt the behavior: * ``DIB_DISTRIBUTION_MIRROR``: the mirror to use (default: - `<http://ftp.us.debian.org/debian>`__) + `<http://deb.debian.org/debian>`__) * ``DIB_DEBIAN_COMPONENTS``: (default: ``main``) a comma separated list of components. For Debian this can be e.g. ``main,contrib,non-free``. - Note it is not recommended to use - `<http://httpredir.debian.org/>`__ for ``DIB_DISTRIBUTION_MIRROR`` - due to how unreliable it is. Be sure to select a mirror from the - official mirror list at `<https://www.debian.org/mirror/list>`__ - By default only the ``main`` component is used. If ``DIB_DEBIAN_COMPONENTS`` (comma separated) from the ``debootstrap`` element has been set, that list of components will diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/elements/dracut-regenerate/README.rst new/diskimage-builder-2.4.1/diskimage_builder/elements/dracut-regenerate/README.rst --- old/diskimage-builder-2.4.0/diskimage_builder/elements/dracut-regenerate/README.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/diskimage-builder-2.4.1/diskimage_builder/elements/dracut-regenerate/README.rst 2017-05-25 01:23:24.000000000 +0200 @@ -0,0 +1,18 @@ +================= +dracut-regenerate +================= +Adds the possibility of regenerating dracut on image build time, giving the +possibility to load extra modules. +It relies on the ``DIB_DRACUT_ENABLED_MODULES`` setting, that will accept +a yaml blob with the following format:: + + - name: <module1> + packages: + - <package1> + - <package2> + - name: <module2> + packages: + - <package3> + - <package4> + +By default, this element will bring lvm and crypt modules. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/elements/dracut-regenerate/element-deps new/diskimage-builder-2.4.1/diskimage_builder/elements/dracut-regenerate/element-deps --- old/diskimage-builder-2.4.0/diskimage_builder/elements/dracut-regenerate/element-deps 1970-01-01 01:00:00.000000000 +0100 +++ new/diskimage-builder-2.4.1/diskimage_builder/elements/dracut-regenerate/element-deps 2017-05-25 01:23:24.000000000 +0200 @@ -0,0 +1,3 @@ +package-installs +select-boot-kernel-initrd + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/elements/dracut-regenerate/environment.d/10-dracut-regenerate new/diskimage-builder-2.4.1/diskimage_builder/elements/dracut-regenerate/environment.d/10-dracut-regenerate --- old/diskimage-builder-2.4.0/diskimage_builder/elements/dracut-regenerate/environment.d/10-dracut-regenerate 1970-01-01 01:00:00.000000000 +0100 +++ new/diskimage-builder-2.4.1/diskimage_builder/elements/dracut-regenerate/environment.d/10-dracut-regenerate 2017-05-25 01:23:24.000000000 +0200 @@ -0,0 +1,11 @@ +export DIB_DRACUT_ENABLED_MODULES_DEFAULT_CONFIG=" +- name: crypt + packages: + - cryptsetup +- name: lvm + packages: + - lvm2 +" + +DIB_DRACUT_ENABLED_MODULES=${DIB_DRACUT_ENABLED_MODULES:-${DIB_DRACUT_ENABLED_MODULES_DEFAULT_CONFIG}} +export DIB_DRACUT_ENABLED_MODULES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/elements/dracut-regenerate/finalise.d/98-dracut-regenerate new/diskimage-builder-2.4.1/diskimage_builder/elements/dracut-regenerate/finalise.d/98-dracut-regenerate --- old/diskimage-builder-2.4.0/diskimage_builder/elements/dracut-regenerate/finalise.d/98-dracut-regenerate 1970-01-01 01:00:00.000000000 +0100 +++ new/diskimage-builder-2.4.1/diskimage_builder/elements/dracut-regenerate/finalise.d/98-dracut-regenerate 2017-05-25 01:23:24.000000000 +0200 @@ -0,0 +1,67 @@ +#!/usr/local/bin/dib-python + +# Copyright 2017 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# 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 os +import re +import subprocess +import yaml + + +def main(): + dracut_env = os.getenv('DIB_DRACUT_ENABLED_MODULES') + dracut_objects = yaml.safe_load(dracut_env) + + modules_to_boot = [] + for dracut_object in dracut_objects: + # first, install dependent packages + packages = dracut_object.get('packages', []) + for package in packages: + cmdline = ["install-packages", package] + subp = subprocess.Popen(cmdline, stdout=subprocess.PIPE) + out = subp.communicate()[0] + if subp.returncode: + e = subprocess.CalledProcessError(subp.returncode, cmdline) + e.output = out + raise e + + # second, compose the list of modules to boot + modules_to_boot.append(dracut_object.get('name', None)) + + # regenerate dracut with the list of installed modules + if len(modules_to_boot) > 0: + cmdline = ["select-boot-kernel-initrd"] + subp = subprocess.Popen(cmdline, stdout=subprocess.PIPE) + out, err = subp.communicate() + + if subp.returncode: + e = subprocess.CalledProcessError(subp.returncode, cmdline) + e.output = out + raise e + + kernel_set = out.split(':') + kernel_search = re.match("vmlinuz-(.*)", kernel_set[0]) + kernel_version = "%s" % kernel_search.groups(1) + ramdisk_path = "/boot/%s" % kernel_set[1].strip() + modules_to_boot = ' ' .join(modules_to_boot) + + subp = subprocess.Popen(['dracut', '--force', '--add', modules_to_boot, + '-f', ramdisk_path, kernel_version], + stdout=subprocess.PIPE) + subp.wait() + + +if __name__ == '__main__': + main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/elements/manifests/cleanup.d/01-copy-manifests-dir new/diskimage-builder-2.4.1/diskimage_builder/elements/manifests/cleanup.d/01-copy-manifests-dir --- old/diskimage-builder-2.4.0/diskimage_builder/elements/manifests/cleanup.d/01-copy-manifests-dir 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/elements/manifests/cleanup.d/01-copy-manifests-dir 2017-05-25 01:23:24.000000000 +0200 @@ -32,5 +32,12 @@ echo "$DIB_ENV" | sudo dd of=${MANIFEST_IMAGE_PATH}/dib_environment # dib-lint: safe_sudo echo "$DIB_ARGS" | sudo dd of=${MANIFEST_IMAGE_PATH}/dib_arguments # dib-lint: safe_sudo +# Save the manifests locally to the save dir mkdir -p ${DIB_MANIFEST_SAVE_DIR} cp --no-preserve=ownership -rv ${MANIFEST_IMAGE_PATH} ${DIB_MANIFEST_SAVE_DIR} + +# Lock down permissions on the manifest files inside the image to +# root. We don't want regular users being able to see what might +# contain a password, etc. +find ${MANIFEST_IMAGE_PATH} -type f | xargs sudo chown root:root # dib-lint: safe_sudo +find ${MANIFEST_IMAGE_PATH} -type f | xargs sudo chmod 600 # dib-lint: safe_sudo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/elements/rpm-distro/finalise.d/90-selinux-fixfiles-restore new/diskimage-builder-2.4.1/diskimage_builder/elements/rpm-distro/finalise.d/90-selinux-fixfiles-restore --- old/diskimage-builder-2.4.0/diskimage_builder/elements/rpm-distro/finalise.d/90-selinux-fixfiles-restore 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/elements/rpm-distro/finalise.d/90-selinux-fixfiles-restore 2017-05-25 01:23:24.000000000 +0200 @@ -5,14 +5,22 @@ fi set -eu set -o pipefail + SETFILES=$(which setfiles || true) if [ -e /etc/selinux/targeted/contexts/files/file_contexts -a -x "${SETFILES}" ]; then - # Without fixing selinux file labels, sshd will run in the kernel_t domain - # instead of the sshd_t domain, making ssh connections fail with - # "Unable to get valid context for <user>" error message - setfiles /etc/selinux/targeted/contexts/files/file_contexts / + # get all mounpoints in the system + IFS='|' read -ra SPLIT_MOUNTS <<< "$DIB_MOUNTPOINTS" + for MOUNTPOINT in "${SPLIT_MOUNTS[@]}"; do + # Without fixing selinux file labels, sshd will run in the kernel_t domain + # instead of the sshd_t domain, making ssh connections fail with + # "Unable to get valid context for <user>" error message + if [ "${MOUNTPOINT}" != "/tmp/in_target.d" ] && [ "${MOUNTPOINT}" != "/dev" ]; then + $SETFILES /etc/selinux/targeted/contexts/files/file_contexts ${MOUNTPOINT} + fi + done else echo "Skipping SELinux relabel, since setfiles is not available." echo "Touching /.autorelabel to schedule a relabel when the image boots." touch /.autorelabel fi + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/graph/digraph.py new/diskimage-builder-2.4.1/diskimage_builder/graph/digraph.py --- old/diskimage-builder-2.4.0/diskimage_builder/graph/digraph.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/graph/digraph.py 2017-05-25 01:23:24.000000000 +0200 @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. # +import bisect class Digraph(object): @@ -20,6 +21,32 @@ Each node of the digraph must have a unique name. """ + class Edge(object): + """Directed graph edge. + + The digraph has weighted edges. This class holds the weight and + a reference to the node. + """ + + def __init__(self, node, weight): + self.__node = node + self.__weight = weight + + def __eq__(self, other): + return self.__weight == other.get_weight() \ + and self.__node == other.get_node() + + def __lt__(self, other): + return self.__weight < other.get_weight() + + def get_node(self): + """Return the (pointed to) node""" + return self.__node + + def get_weight(self): + """Return the edge's weight""" + return self.__weight + class Node(object): """Directed graph node. @@ -35,33 +62,38 @@ computed. """ self.__name = name - self.__incoming = set() - self.__outgoing = set() + self.__incoming = [] + self.__outgoing = [] + + def __repr__(self): + return "<Node [%s]>" % self.__name def get_name(self): """Returns the name of the node.""" return self.__name - def add_incoming(self, node): + def add_incoming(self, node, weight): """Add node to the incoming list.""" + bisect.insort(self.__incoming, Digraph.Edge(node, weight)) - self.__incoming.add(node) - - def add_outgoing(self, node): - """Add node to the incoming list.""" - - self.__outgoing.add(node) + def add_outgoing(self, node, weight): + """Add node to the outgoing list.""" + bisect.insort(self.__outgoing, Digraph.Edge(node, weight)) def get_iter_outgoing(self): """Return an iterator over the outgoing nodes.""" - return iter(self.__outgoing) + return iter([x.get_node() for x in self.__outgoing]) + + def has_incoming(self): + """Returns True if the node has incoming edges""" + return self.__incoming @staticmethod def __as_named_list(inlist): """Return given list as list of names.""" - return map(lambda x: x.get_name(), inlist) + return [x.get_node().get_name() for x in inlist] def get_outgoing_as_named_list(self): """Return the names of all outgoing nodes as a list.""" @@ -105,7 +137,7 @@ "exists" % node.get_name()) self._named_nodes[anode.get_name()] = anode - def create_edge(self, anode, bnode): + def create_edge(self, anode, bnode, weight=0): """Creates an edge from a to b - both must be nodes.""" assert issubclass(anode.__class__, Digraph.Node) @@ -114,8 +146,8 @@ assert anode == self._named_nodes[anode.get_name()] assert bnode.get_name() in self._named_nodes.keys() assert bnode == self._named_nodes[bnode.get_name()] - anode.add_outgoing(bnode) - bnode.add_incoming(anode) + anode.add_outgoing(bnode, weight) + bnode.add_incoming(anode, weight) def get_iter_nodes_values(self): """Returns the nodes dict to the values. @@ -144,7 +176,7 @@ rval[node.get_name()] = node.get_outgoing_as_named_list() return rval - def topological_sort(dg): + def topological_sort(self): """Digraph topological search. This algorithm is based upon a depth first search with @@ -169,7 +201,9 @@ tsort.insert(0, node) # The 'main' function of the topological sort - for node in dg.get_iter_nodes_values(): + for node in self.get_iter_nodes_values(): + if node.has_incoming(): + continue visit(node) return tsort @@ -189,6 +223,6 @@ """Converts a node list into a list of the corresponding node names.""" node_name_list = [] - for n in node_list: - node_name_list.append(n.get_name()) + for node in node_list: + node_name_list.append(node.get_name()) return node_name_list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/lib/common-functions new/diskimage-builder-2.4.1/diskimage_builder/lib/common-functions --- old/diskimage-builder-2.4.0/diskimage_builder/lib/common-functions 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/lib/common-functions 2017-05-25 01:23:24.000000000 +0200 @@ -343,6 +343,8 @@ local dir="$1" local real_dir local mnts + local split_mounts + local found_mountpoint if [ ! -d $dir ]; then echo "*** $dir is not a directory" @@ -353,12 +355,30 @@ # /proc/mounts is the real path real_dir=$(readlink -e $dir) + # populate the exported mountpoints + IFS='|' read -ra split_mounts <<< "$DIB_MOUNTPOINTS" + + # note the "/" on real_dir ... we are just looking for things # mounted *underneath* this directory. mnts=$(awk '{print $2}' < /proc/mounts | grep "^$real_dir/" | sort -r) for m in $mnts; do - echo "Unmount $m" - sudo umount -fl $m || true + # check if suffix is in array + found_mountpoint=false + for mountpoint in "${split_mounts[@]}"; do + if [[ "$mountpoint" != "/" ]]; then + if [[ "$m" == *$mountpoint ]]; then + echo "Mountpoint $m managed by block device; skipping" + found_mountpoint=true + break + fi + fi + done + if [ $found_mountpoint == false ]; then + # unmount the directory as it is not managed by block device + echo "Unmount $m" + sudo umount -fl $m || true + fi done } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/lib/disk-image-create new/diskimage-builder-2.4.1/diskimage_builder/lib/disk-image-create --- old/diskimage-builder-2.4.0/diskimage_builder/lib/disk-image-create 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/lib/disk-image-create 2017-05-25 01:23:24.000000000 +0200 @@ -290,6 +290,10 @@ DIB_ROOT_FSTYPE=$(dib-block-device getval root-fstype) export DIB_ROOT_FSTYPE +# retrieve mount points so we can reuse in elements +DIB_MOUNTPOINTS=$(dib-block-device getval mount-points) +export DIB_MOUNTPOINTS + create_base # This variable needs to be propagated into the chroot mkdir -p $TMP_HOOKS_PATH/environment.d diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/lib/ramdisk-image-create new/diskimage-builder-2.4.1/diskimage_builder/lib/ramdisk-image-create --- old/diskimage-builder-2.4.0/diskimage_builder/lib/ramdisk-image-create 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/lib/ramdisk-image-create 2017-05-25 01:23:24.000000000 +0200 @@ -290,6 +290,10 @@ DIB_ROOT_FSTYPE=$(dib-block-device getval root-fstype) export DIB_ROOT_FSTYPE +# retrieve mount points so we can reuse in elements +DIB_MOUNTPOINTS=$(dib-block-device getval mount-points) +export DIB_MOUNTPOINTS + create_base # This variable needs to be propagated into the chroot mkdir -p $TMP_HOOKS_PATH/environment.d diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/tests/functional/test_blockdevice_mbr.py new/diskimage-builder-2.4.1/diskimage_builder/tests/functional/test_blockdevice_mbr.py --- old/diskimage-builder-2.4.0/diskimage_builder/tests/functional/test_blockdevice_mbr.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/tests/functional/test_blockdevice_mbr.py 2017-05-25 01:23:24.000000000 +0200 @@ -11,9 +11,7 @@ # under the License. import copy -from diskimage_builder.block_device.level0.localloop import LocalLoop -from diskimage_builder.block_device.level1.mbr import MBR -from diskimage_builder.logging_config import setup +import fixtures import logging import os import shutil @@ -21,6 +19,12 @@ import tempfile import testtools +from diskimage_builder.block_device.level0.localloop import LocalLoop +from diskimage_builder.block_device.level1.mbr import MBR + + +logger = logging.getLogger(__name__) + class TestMBR(testtools.TestCase): @@ -48,7 +52,10 @@ def setUp(self): super(TestMBR, self).setUp() - setup() + fs = '%(asctime)s %(levelname)s [%(name)s] %(message)s' + self.log_fixture = self.useFixture( + fixtures.FakeLogger(level=logging.DEBUG, + format=fs)) def _create_image(self): tmp_dir = tempfile.mkdtemp(prefix="dib-bd-mbr-") @@ -61,7 +68,7 @@ partx_path = self._get_path_for_partx() largs.insert(0, partx_path) largs.append(image_path) - logging.info("Running command [%s]", largs) + logger.info("Running command [%s]", largs) return subprocess.check_output(largs).decode("ascii") def test_one_ext_partition(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/tests/functional/test_graph.py new/diskimage-builder-2.4.1/diskimage_builder/tests/functional/test_graph.py --- old/diskimage-builder-2.4.0/diskimage_builder/tests/functional/test_graph.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/tests/functional/test_graph.py 2017-05-25 01:23:24.000000000 +0200 @@ -121,3 +121,23 @@ self.assertTrue(False) except RuntimeError: pass + + def test_iter_outgoing_weight_01(self): + """Tests iter_outgoing in a graph with weights""" + + digraph = Digraph() + node0 = Digraph.Node("R") + digraph.add_node(node0) + node1 = Digraph.Node("A") + digraph.add_node(node1) + node2 = Digraph.Node("B") + digraph.add_node(node2) + node3 = Digraph.Node("C") + digraph.add_node(node3) + + digraph.create_edge(node0, node1, 1) + digraph.create_edge(node0, node2, 2) + digraph.create_edge(node0, node3, 3) + + self.assertEqual([node1, node2, node3], + list(node0.get_iter_outgoing())) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder/tests/functional/test_graph_toposort.py new/diskimage-builder-2.4.1/diskimage_builder/tests/functional/test_graph_toposort.py --- old/diskimage-builder-2.4.0/diskimage_builder/tests/functional/test_graph_toposort.py 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder/tests/functional/test_graph_toposort.py 2017-05-25 01:23:24.000000000 +0200 @@ -12,9 +12,11 @@ # License for the specific language governing permissions and limitations # under the License. +import testtools + +from diskimage_builder.graph.digraph import Digraph from diskimage_builder.graph.digraph import digraph_create_from_dict from diskimage_builder.graph.digraph import node_list_to_node_name_list -import testtools class TestTopologicalSearch(testtools.TestCase): @@ -67,3 +69,48 @@ self.assertTrue(tnames.index('A') < tnames.index('B')) self.assertTrue(tnames.index('B') < tnames.index('C')) self.assertTrue(tnames.index('D') < tnames.index('E')) + + def test_tsort_006(self): + """Complex digraph with weights""" + + digraph = Digraph() + node0 = Digraph.Node("R") + digraph.add_node(node0) + node1 = Digraph.Node("A") + digraph.add_node(node1) + node2 = Digraph.Node("B") + digraph.add_node(node2) + node3 = Digraph.Node("C") + digraph.add_node(node3) + node4 = Digraph.Node("B1") + digraph.add_node(node4) + node5 = Digraph.Node("B2") + digraph.add_node(node5) + node6 = Digraph.Node("B3") + digraph.add_node(node6) + + digraph.create_edge(node0, node1, 1) + digraph.create_edge(node0, node2, 2) + digraph.create_edge(node0, node3, 3) + + digraph.create_edge(node2, node4, 7) + digraph.create_edge(node2, node5, 14) + digraph.create_edge(node2, node6, 21) + + tsort = digraph.topological_sort() + tnames = node_list_to_node_name_list(tsort) + + # Also here: many possible solutions + self.assertTrue(tnames.index('R') < tnames.index('A')) + self.assertTrue(tnames.index('R') < tnames.index('B')) + self.assertTrue(tnames.index('R') < tnames.index('C')) + self.assertTrue(tnames.index('B') < tnames.index('B1')) + self.assertTrue(tnames.index('B') < tnames.index('B2')) + self.assertTrue(tnames.index('B') < tnames.index('B3')) + + # In addition in the weighted graph the following + # must also hold: + self.assertTrue(tnames.index('B') < tnames.index('A')) + self.assertTrue(tnames.index('C') < tnames.index('B')) + self.assertTrue(tnames.index('B2') < tnames.index('B1')) + self.assertTrue(tnames.index('B3') < tnames.index('B2')) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder.egg-info/PKG-INFO new/diskimage-builder-2.4.1/diskimage_builder.egg-info/PKG-INFO --- old/diskimage-builder-2.4.0/diskimage_builder.egg-info/PKG-INFO 2017-05-15 02:47:20.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder.egg-info/PKG-INFO 2017-05-25 01:23:56.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: diskimage-builder -Version: 2.4.0 +Version: 2.4.1 Summary: Golden Disk Image builder. Home-page: http://docs.openstack.org/developer/diskimage-builder/ Author: OpenStack diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder.egg-info/SOURCES.txt new/diskimage-builder-2.4.1/diskimage_builder.egg-info/SOURCES.txt --- old/diskimage-builder-2.4.0/diskimage_builder.egg-info/SOURCES.txt 2017-05-15 02:47:20.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder.egg-info/SOURCES.txt 2017-05-25 01:23:57.000000000 +0200 @@ -28,13 +28,14 @@ diskimage_builder/block_device/__init__.py diskimage_builder/block_device/blockdevice.py diskimage_builder/block_device/cmd.py -diskimage_builder/block_device/plugin_base.py +diskimage_builder/block_device/exception.py diskimage_builder/block_device/tree_config.py diskimage_builder/block_device/utils.py diskimage_builder/block_device/level0/__init__.py diskimage_builder/block_device/level0/localloop.py diskimage_builder/block_device/level1/__init__.py diskimage_builder/block_device/level1/mbr.py +diskimage_builder/block_device/level1/partition.py diskimage_builder/block_device/level1/partitioning.py diskimage_builder/block_device/level2/__init__.py diskimage_builder/block_device/level2/mkfs.py @@ -254,6 +255,10 @@ diskimage_builder/elements/dracut-ramdisk/install.d/20-install-dracut-deps diskimage_builder/elements/dracut-ramdisk/post-install.d/01-ensure-drivers diskimage_builder/elements/dracut-ramdisk/post-install.d/99-build-dracut-ramdisk +diskimage_builder/elements/dracut-regenerate/README.rst +diskimage_builder/elements/dracut-regenerate/element-deps +diskimage_builder/elements/dracut-regenerate/environment.d/10-dracut-regenerate +diskimage_builder/elements/dracut-regenerate/finalise.d/98-dracut-regenerate diskimage_builder/elements/dynamic-login/README.rst diskimage_builder/elements/dynamic-login/element-deps diskimage_builder/elements/dynamic-login/init-scripts/systemd/dynamic-login.service diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/diskimage_builder.egg-info/pbr.json new/diskimage-builder-2.4.1/diskimage_builder.egg-info/pbr.json --- old/diskimage-builder-2.4.0/diskimage_builder.egg-info/pbr.json 2017-05-15 02:47:20.000000000 +0200 +++ new/diskimage-builder-2.4.1/diskimage_builder.egg-info/pbr.json 2017-05-25 01:23:56.000000000 +0200 @@ -1 +1 @@ -{"git_version": "e4e2389", "is_release": true} \ No newline at end of file +{"git_version": "0208f83", "is_release": true} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/diskimage-builder-2.4.0/test-requirements.txt new/diskimage-builder-2.4.1/test-requirements.txt --- old/diskimage-builder-2.4.0/test-requirements.txt 2017-05-15 02:46:47.000000000 +0200 +++ new/diskimage-builder-2.4.1/test-requirements.txt 2017-05-25 01:23:24.000000000 +0200 @@ -7,10 +7,10 @@ testrepository>=0.0.18 # Apache-2.0/BSD # Doc requirements -sphinx>=1.5.1 # BSD +sphinx!=1.6.1,>=1.5.1 # BSD oslosphinx>=4.7.0 # Apache-2.0 # releasenotes reno>=1.8.0 # Apache-2.0 -coverage>=4.0 # Apache-2.0 +coverage!=4.4,>=4.0 # Apache-2.0
