def check_integrity(self, check_duplicates=True):
        """
        Checks the integrity of the container map. This means, that
        * every shared container (instance name) and attached volume should only exist once (can be deactivated);
        * every container declared as `used` needs to have at least a shared volume or a host bind;
        * every host bind declared under `binds` needs to be shared from the host;
        * every volume alias used in `attached` and `binds` needs to be associated with a path in `volumes`;
        * every container referred to in `links` needs to be defined;
        * every container named in `extended` is available.

        :param check_duplicates: Check for duplicate attached volumes.
        :type check_duplicates: bool
        """
        def _get_instance_names(c_name, instances):
            if instances:
                return ['{0}.{1}'.format(c_name, instance) for instance in instances]
            return [c_name]

        def _get_container_items(c_name, c_config):
            instance_names = _get_instance_names(c_name, c_config.instances)
            group_ref_names = instance_names[:]
            if c_config.instances:
                group_ref_names.append(c_name)
            shared = instance_names[:] if c_config.shares or c_config.binds or c_config.uses else []
            bind = [b.name for b in c_config.binds if isinstance(b, SharedVolume)]
            link = [l.container for l in c_config.links]
            uses = [u.name for u in c_config.uses]
            networks = [n.network_name for n in c_config.networks if n.network_name not in DEFAULT_PRESET_NETWORKS]
            network_mode = c_config.network_mode
            if isinstance(network_mode, tuple):
                if network_mode[1]:
                    net_containers = ['{0[0]}.{0[1]}'.format(network_mode)]
                else:
                    net_containers = [network_mode[0]]
            else:
                net_containers = []
            if self.use_attached_parent_name:
                attaches = [(c_name, a.name) for a in c_config.attaches]
            else:
                attaches = [a.name for a in c_config.attaches]
            attaches_with_path = [a.name for a in c_config.attaches
                                  if isinstance(a, UsedVolume)]
            return (instance_names, group_ref_names, uses, attaches, attaches_with_path, shared, bind, link, networks,
                    net_containers)

        self.clean()
        (all_instances, all_grouprefs, all_used, all_attached, all_attached_default, all_shared, all_binds, all_links,
         all_networks, all_net_containers) = zip(*[
            _get_container_items(k, v) for k, v in self.get_extended_map()
         ])
        if self.use_attached_parent_name:
            all_attached_names = tuple('{0}.{1}'.format(c_name, a)
                                       for c_name, a in itertools.chain.from_iterable(all_attached))
        else:
            all_attached_names = tuple(itertools.chain.from_iterable(all_attached))

        ref_set = set(itertools.chain.from_iterable(all_grouprefs))
        group_set = set(self.groups.keys())
        ambiguous_names = group_set & ref_set
        if ambiguous_names:
            ambiguous_str = ', '.join(ambiguous_names)
            raise MapIntegrityError("Names are used both for container configurations (or instances) and for container "
                                    "groups: {0}.".format(ambiguous_str))
        group_referenced = set(itertools.chain.from_iterable(self.groups.values()))
        missing_refs = group_referenced - ref_set
        if missing_refs:
            missing_ref_str = ', '.join(missing_refs)
            raise MapIntegrityError("Container configurations or certain instances are referenced by groups, but are "
                                    "not defined: {0}.".format(missing_ref_str))
        volume_shared = tuple(itertools.chain.from_iterable(all_shared)) + all_attached_names
        if check_duplicates:
            duplicated = [name for name, count in six.iteritems(Counter(volume_shared)) if count > 1]
            if duplicated:
                dup_str = ', '.join(duplicated)
                raise MapIntegrityError("Duplicated attached volumes found with name(s): {0}.".format(dup_str))
        used_set = set(itertools.chain.from_iterable(all_used))
        shared_set = set(volume_shared)
        missing_shares = used_set - shared_set
        if missing_shares:
            missing_share_str = ', '.join(missing_shares)
            raise MapIntegrityError("No shared or attached volumes found for used volume(s): "
                                    "{0}.".format(missing_share_str))
        binds_set = set(itertools.chain.from_iterable(all_binds))
        host_set = set(self.host.keys())
        missing_binds = binds_set - host_set
        if missing_binds:
            missing_mapped_str = ', '.join(missing_binds)
            raise MapIntegrityError("No host share found for mapped volume(s): {0}.".format(missing_mapped_str))
        if self.use_attached_parent_name:
            volume_set = binds_set.union(a[1] for a in itertools.chain.from_iterable(all_attached))
        else:
            volume_set = binds_set.union(all_attached_names)
        named_set = set(self.volumes.keys()).union(itertools.chain.from_iterable(all_attached_default))
        missing_names = volume_set - named_set
        if missing_names:
            missing_names_str = ', '.join(missing_names)
            raise MapIntegrityError("No volume name-path-assignments found for volume(s): "
                                    "{0}.".format(missing_names_str))
        instance_set = set(itertools.chain.from_iterable(all_instances))
        linked_set = set(itertools.chain.from_iterable(all_links))
        missing_links = linked_set - instance_set
        if missing_links:
            missing_links_str = ', '.join(missing_links)
            raise MapIntegrityError("No container instance found for link(s): {0}.".format(missing_links_str))
        used_network_set = set(itertools.chain.from_iterable(all_networks))
        used_net_container_set = set(itertools.chain.from_iterable(all_net_containers))
        available_network_set = set(self.networks.keys())
        missing_networks = used_network_set - available_network_set
        if missing_networks:
            missing_networks_str = ', '.join(missing_networks)
            raise MapIntegrityError("No network configuration found for the following network reference(s): "
                                    "{0}".format(missing_networks_str))
        missing_net_containers = used_net_container_set - instance_set
        if missing_net_containers:
            missing_net_cnt_str = ', '.join(missing_net_containers)
            raise MapIntegrityError("No container instance found for the following network mode reference(s): "
                                    "{0}".format(missing_net_cnt_str))
def check_integrity ( self , check_duplicates = True ) : def _get_instance_names ( c_name , instances ) : if instances : return [ '{0}.{1}' . format ( c_name , instance ) for instance in instances ] return [ c_name ] def _get_container_items ( c_name , c_config ) : instance_names = _get_instance_names ( c_name , c_config . instances ) group_ref_names = instance_names [ : ] if c_config . instances : group_ref_names . append ( c_name ) shared = instance_names [ : ] if c_config . shares or c_config . binds or c_config . uses else [ ] bind = [ b . name for b in c_config . binds if isinstance ( b , SharedVolume ) ] link = [ l . container for l in c_config . links ] uses = [ u . name for u in c_config . uses ] networks = [ n . network_name for n in c_config . networks if n . network_name not in DEFAULT_PRESET_NETWORKS ] network_mode = c_config . network_mode if isinstance ( network_mode , tuple ) : if network_mode [ 1 ] : net_containers = [ '{0[0]}.{0[1]}' . format ( network_mode ) ] else : net_containers = [ network_mode [ 0 ] ] else : net_containers = [ ] if self . use_attached_parent_name : attaches = [ ( c_name , a . name ) for a in c_config . attaches ] else : attaches = [ a . name for a in c_config . attaches ] attaches_with_path = [ a . name for a in c_config . attaches if isinstance ( a , UsedVolume ) ] return ( instance_names , group_ref_names , uses , attaches , attaches_with_path , shared , bind , link , networks , net_containers ) self . clean ( ) ( all_instances , all_grouprefs , all_used , all_attached , all_attached_default , all_shared , all_binds , all_links , all_networks , all_net_containers ) = zip ( * [ _get_container_items ( k , v ) for k , v in self . get_extended_map ( ) ] ) if self . use_attached_parent_name : all_attached_names = tuple ( '{0}.{1}' . format ( c_name , a ) for c_name , a in itertools . chain . from_iterable ( all_attached ) ) else : all_attached_names = tuple ( itertools . chain . from_iterable ( all_attached ) ) ref_set = set ( itertools . chain . from_iterable ( all_grouprefs ) ) group_set = set ( self . groups . keys ( ) ) ambiguous_names = group_set & ref_set if ambiguous_names : ambiguous_str = ', ' . join ( ambiguous_names ) raise MapIntegrityError ( "Names are used both for container configurations (or instances) and for container " "groups: {0}." . format ( ambiguous_str ) ) group_referenced = set ( itertools . chain . from_iterable ( self . groups . values ( ) ) ) missing_refs = group_referenced - ref_set if missing_refs : missing_ref_str = ', ' . join ( missing_refs ) raise MapIntegrityError ( "Container configurations or certain instances are referenced by groups, but are " "not defined: {0}." . format ( missing_ref_str ) ) volume_shared = tuple ( itertools . chain . from_iterable ( all_shared ) ) + all_attached_names if check_duplicates : duplicated = [ name for name , count in six . iteritems ( Counter ( volume_shared ) ) if count > 1 ] if duplicated : dup_str = ', ' . join ( duplicated ) raise MapIntegrityError ( "Duplicated attached volumes found with name(s): {0}." . format ( dup_str ) ) used_set = set ( itertools . chain . from_iterable ( all_used ) ) shared_set = set ( volume_shared ) missing_shares = used_set - shared_set if missing_shares : missing_share_str = ', ' . join ( missing_shares ) raise MapIntegrityError ( "No shared or attached volumes found for used volume(s): " "{0}." . format ( missing_share_str ) ) binds_set = set ( itertools . chain . from_iterable ( all_binds ) ) host_set = set ( self . host . keys ( ) ) missing_binds = binds_set - host_set if missing_binds : missing_mapped_str = ', ' . join ( missing_binds ) raise MapIntegrityError ( "No host share found for mapped volume(s): {0}." . format ( missing_mapped_str ) ) if self . use_attached_parent_name : volume_set = binds_set . union ( a [ 1 ] for a in itertools . chain . from_iterable ( all_attached ) ) else : volume_set = binds_set . union ( all_attached_names ) named_set = set ( self . volumes . keys ( ) ) . union ( itertools . chain . from_iterable ( all_attached_default ) ) missing_names = volume_set - named_set if missing_names : missing_names_str = ', ' . join ( missing_names ) raise MapIntegrityError ( "No volume name-path-assignments found for volume(s): " "{0}." . format ( missing_names_str ) ) instance_set = set ( itertools . chain . from_iterable ( all_instances ) ) linked_set = set ( itertools . chain . from_iterable ( all_links ) ) missing_links = linked_set - instance_set if missing_links : missing_links_str = ', ' . join ( missing_links ) raise MapIntegrityError ( "No container instance found for link(s): {0}." . format ( missing_links_str ) ) used_network_set = set ( itertools . chain . from_iterable ( all_networks ) ) used_net_container_set = set ( itertools . chain . from_iterable ( all_net_containers ) ) available_network_set = set ( self . networks . keys ( ) ) missing_networks = used_network_set - available_network_set if missing_networks : missing_networks_str = ', ' . join ( missing_networks ) raise MapIntegrityError ( "No network configuration found for the following network reference(s): " "{0}" . format ( missing_networks_str ) ) missing_net_containers = used_net_container_set - instance_set if missing_net_containers : missing_net_cnt_str = ', ' . join ( missing_net_containers ) raise MapIntegrityError ( "No container instance found for the following network mode reference(s): " "{0}" . format ( missing_net_cnt_str ) )
Checks the integrity of the container map. This means, that
        * every shared container (instance name) and attached volume should only exist once (can be deactivated);
        * every container declared as `used` needs to have at least a shared volume or a host bind;
        * every host bind declared under `binds` needs to be shared from the host;
        * every volume alias used in `attached` and `binds` needs to be associated with a path in `volumes`;
        * every container referred to in `links` needs to be defined;
        * every container named in `extended` is available.

        :param check_duplicates: Check for duplicate attached volumes.
        :type check_duplicates: bool