mirror of
				https://git.launchpad.net/~ubuntu-release/britney/+git/britney2-ubuntu
				synced 2025-11-04 10:34:05 +00:00 
			
		
		
		
	Add present-and-installable constraints support
Solves first half of GH#5. Signed-off-by: Niels Thykier <niels@thykier.net>
This commit is contained in:
		
							parent
							
								
									e92bbf386f
								
							
						
					
					
						commit
						f3e37faf7e
					
				@ -13,6 +13,10 @@ EXCUSES_YAML_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/excuses
 | 
			
		||||
UPGRADE_OUTPUT    = /srv/release.debian.org/britney/var/data-b2/output/output.txt
 | 
			
		||||
HEIDI_OUTPUT      = /srv/release.debian.org/britney/var/data-b2/output/HeidiResult
 | 
			
		||||
 | 
			
		||||
# External policy/constraints/faux-packages information that
 | 
			
		||||
# (presumably) rarely changes.  Examples include "constraints".
 | 
			
		||||
STATIC_INPUT_DIR = /srv/release.debian.org/britney/input
 | 
			
		||||
 | 
			
		||||
# Directory for input files that Britney will update herself
 | 
			
		||||
# (e.g. aging information) or will need regular updates
 | 
			
		||||
# (e.g. urgency information).
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										97
									
								
								britney.py
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								britney.py
									
									
									
									
									
								
							@ -317,6 +317,21 @@ class Britney(object):
 | 
			
		||||
            # unstable
 | 
			
		||||
            self.binaries['testing'][arch] = self.read_binaries(self.options.testing, "testing", arch)
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            constraints_file = os.path.join(self.options.static_input_dir, 'constraints')
 | 
			
		||||
        except AttributeError:
 | 
			
		||||
            self.log("The static_input_dir option is not set", type='I')
 | 
			
		||||
            constraints_file = None
 | 
			
		||||
        if constraints_file is not None and os.path.exists(constraints_file):
 | 
			
		||||
            self.log("Loading constraints from %s" % constraints_file, type='I')
 | 
			
		||||
            self.constraints = self._load_constraints(constraints_file)
 | 
			
		||||
        else:
 | 
			
		||||
            if constraints_file is not None:
 | 
			
		||||
                self.log("No constraints as %s does not exist" % constraints_file, type='I')
 | 
			
		||||
            self.constraints = {
 | 
			
		||||
                'keep-installable': [],
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        self.log("Compiling Installability tester", type="I")
 | 
			
		||||
        self._build_installability_tester(self.options.architectures)
 | 
			
		||||
 | 
			
		||||
@ -476,6 +491,88 @@ class Britney(object):
 | 
			
		||||
        if self.options.verbose or type in ("E", "W"):
 | 
			
		||||
            print("%s: [%s] - %s" % (type, time.asctime(), msg))
 | 
			
		||||
 | 
			
		||||
    def _load_constraints(self, constraints_file):
 | 
			
		||||
        """Loads configurable constraints
 | 
			
		||||
 | 
			
		||||
        The constraints file can contain extra rules that Britney should attempt
 | 
			
		||||
        to satisfy.  Examples can be "keep package X in testing and ensure it is
 | 
			
		||||
        installable".
 | 
			
		||||
 | 
			
		||||
        :param constraints_file: Path to the file containing the constraints
 | 
			
		||||
        """
 | 
			
		||||
        tag_file = apt_pkg.TagFile(constraints_file)
 | 
			
		||||
        get_field = tag_file.section.get
 | 
			
		||||
        step = tag_file.step
 | 
			
		||||
        no = 0
 | 
			
		||||
        faux_version = sys.intern('1')
 | 
			
		||||
        faux_section = sys.intern('faux')
 | 
			
		||||
 | 
			
		||||
        while step():
 | 
			
		||||
            no += 1
 | 
			
		||||
            pkg_name = get_field('Fake-Package-Name', None)
 | 
			
		||||
            if pkg_name is None:
 | 
			
		||||
                raise ValueError("Missing Fake-Package-Name field in paragraph %d (file %s)" % (no, constraints_file))
 | 
			
		||||
            pkg_name = sys.intern(pkg_name)
 | 
			
		||||
 | 
			
		||||
            def mandatory_field(x):
 | 
			
		||||
                v = get_field(x, None)
 | 
			
		||||
                if v is None:
 | 
			
		||||
                    raise ValueError("Missing %s field for %s (file %s)" % (x, pkg_name, constraints_file))
 | 
			
		||||
                return v
 | 
			
		||||
 | 
			
		||||
            constraint = mandatory_field('Constraint')
 | 
			
		||||
            if constraint not in {'present-and-installable'}:
 | 
			
		||||
                raise ValueError("Unsupported constraint %s for %s (file %s)" % (constraint, pkg_name, constraints_file))
 | 
			
		||||
 | 
			
		||||
            self.log(" - constraint %s" % pkg_name, type='I')
 | 
			
		||||
 | 
			
		||||
            pkg_list = [x.strip() for x in mandatory_field('Package-List').split("\n") if x.strip() != '']
 | 
			
		||||
            src_data = [faux_version,
 | 
			
		||||
                        faux_section,
 | 
			
		||||
                        [],
 | 
			
		||||
                        None,
 | 
			
		||||
                        True,
 | 
			
		||||
                        ]
 | 
			
		||||
            self.sources['testing'][pkg_name] = src_data
 | 
			
		||||
            self.sources['unstable'][pkg_name] = src_data
 | 
			
		||||
            for arch in self.options.architectures:
 | 
			
		||||
                deps = []
 | 
			
		||||
                for pkg_spec in pkg_list:
 | 
			
		||||
                    s = pkg_spec.split(None, 2)
 | 
			
		||||
                    if len(s) == 1:
 | 
			
		||||
                        deps.append(s[0])
 | 
			
		||||
                    else:
 | 
			
		||||
                        pkg, arch_res = s
 | 
			
		||||
                        if not (arch_res.startswith('[') and arch_res.endswith(']')):
 | 
			
		||||
                            raise ValueError("Invalid arch-restriction on %s - should be [arch1 arch2] (for %s file %s)"
 | 
			
		||||
                                             % (pkg, pkg_name, constraints_file))
 | 
			
		||||
                        arch_res = arch_res[1:-1].split()
 | 
			
		||||
                        if not arch_res:
 | 
			
		||||
                            msg = "Empty arch-restriction for %s: Uses comma or negation (for %s file %s)"
 | 
			
		||||
                            raise ValueError(msg % (pkg, pkg_name, constraints_file))
 | 
			
		||||
                        for a in arch_res:
 | 
			
		||||
                            if a == arch:
 | 
			
		||||
                                deps.append(pkg)
 | 
			
		||||
                            elif ',' in a or '!' in a:
 | 
			
		||||
                                msg = "Invalid arch-restriction for %s: Uses comma or negation (for %s file %s)"
 | 
			
		||||
                                raise ValueError(msg % (pkg, pkg_name, constraints_file))
 | 
			
		||||
                pkg_id = (pkg_name, faux_version, arch)
 | 
			
		||||
                bin_data = BinaryPackage(faux_version,
 | 
			
		||||
                                         faux_section,
 | 
			
		||||
                                         pkg_name,
 | 
			
		||||
                                         faux_version,
 | 
			
		||||
                                         arch,
 | 
			
		||||
                                         'no',
 | 
			
		||||
                                         ', '.join(deps),
 | 
			
		||||
                                         None,
 | 
			
		||||
                                         [],
 | 
			
		||||
                                         False,
 | 
			
		||||
                                         )
 | 
			
		||||
                src_data[BINARIES].append(pkg_id)
 | 
			
		||||
                self.binaries['testing'][arch][0][pkg_name] = bin_data
 | 
			
		||||
                self.binaries['unstable'][arch][0][pkg_name] = bin_data
 | 
			
		||||
                self.all_binaries[pkg_id] = bin_data
 | 
			
		||||
 | 
			
		||||
    def _build_installability_tester(self, archs):
 | 
			
		||||
        """Create the installability tester"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user