def cmd_seal(args): ''' Subcommand seal: Mark the bundle as ReadOnly and change a suite's tag from 'staging' to 'deploy'. ''' bundle = setupContext(args, require_own_suite=True) sourcesInReprepro = set([ list(p.getData())[0] for p in bundle.queryBinaryPackages(packageFields="C") ]) if len(sourcesInReprepro) == 0: raise BundleError( "Sorry, the bundle {} is empty and you can't seal an empty bundle!" .format(bundle)) (applied, not_applied) = bundle.getApplicationStatus() applied_diff = sourcesInReprepro.symmetric_difference(applied) if len(applied_diff) > 0 or len(not_applied) > 0: raise BundleError( "Sorry, the sources_control.list is not (yet?) fully applied to the reprepro-repository! Differences found for " + ", ".join(sorted(applied_diff | not_applied))) with choose_commit_context(bundle, args, "SEALED bundle '{bundleName}'") as (bundle, git_add, cwd): infofile = edit_meta(bundle, CANCEL_REMARK.format(action="seal")) if not infofile: return git_add.append(infofile) git_add.append(bundle.updateInfofile(rollout=True)) git_add.append(create_reprepro_config(bundle, readOnly=True)) git_add.append(updateReposConfig(cwd=cwd)) sealedHook = reprepro_bundle.getHooksConfig(cwd=cwd).get( 'bundle_sealed', None) if sealedHook: info = bundle.getInfo() target = "{}".format(info.get("Target", "no-target")) subject = info.get("Releasenotes", "--no-subject--").split("\n")[0] cmd = [ arg.format(bundleName=bundle.bundleName, bundleSuiteName=bundle.getOwnSuiteName(), subject=subject, target=target) for arg in sealedHook.split() ] logger.info("Calling bundle_sealed hook '{}'".format(" ".join(cmd))) try: subprocess.check_call(cmd, cwd=cwd) except Exception as e: logger.warning("Hook execution failed in folder {}: {}".format( cwd, e))
def __init__(self, suiteName, packages): suites = sorted(apt_repos.getSuites([suiteName])) if len(suites) != 1: raise BundleError( "Can't create UpdateRule for suite selector '{}' since it doesn't select exactly one suite." .format(suiteName)) self.suite = suites[0] self.packages = packages
def setOwnSuite(self, ownSuiteStr): ''' Sets the bundles `ownSuite` to a apt_repos.RepoSuite object derived from `ownSuiteStr`. `ownSuiteStr` could be a template string that after filling in the templates should describe the apt-repos suite identifier of the (typically server side) apt-repository representing the bundle's content. ''' selector = ownSuiteStr if ownSuiteStr: (suites, selector) = self.parseSuitesStr(ownSuiteStr) if len(suites) > 0: self._ownSuite = sorted(suites)[0] if not self._ownSuite: raise BundleError( "Could not connect bundle '{}' to it's own apt-repos suite '{}'." .format(self.bundleName, selector))
def __init__(self, bundleName, basedir): ''' Parses `bundleName` which could be in the form [repo/bundle/]<distribution>[/<bundleID>] and either uses the specified bundleID or creates a new bundleID (after scanning the already exising bundles for <distribution>). ''' regex = re.compile(r"^(repo/bundle/)?([\w\.]+)(/(\d+))?$") m = regex.match(bundleName) if not m: raise BundleError( "bundleName '{}' doesn't match the pattern '{}'".format( bundleName, regex.pattern)) else: (_, distribution, _, number) = m.groups() if not number: # create a new one highest = 0 mydir = os.path.join(basedir, "repo", "bundle", distribution) if os.path.isdir(mydir): for f in os.listdir(mydir): f = os.path.join(distribution, f) m = regex.match(f) if m: number = int(m.group(4)) if number > highest: highest = number number = highest + 1 self.basedir = basedir self.distribution = distribution self.bundleName = "{}/{:04d}".format(distribution, int(number)) self.__confDir = os.path.join(self.basedir, "repo", "bundle", self.bundleName, "conf") self.scl = os.path.join(self.__confDir, "sources_control.list") self._blacklist = "FilterList-blacklisted-binary-packages" self._infofile = "info" self._updatesfile = "updates" self._ownSuite = None self._templateEnv = Environment( loader=FileSystemLoader(self.getTemplateDir()))