Пример #1
0
 def __init__(self, tagSection, repoSuite=None):
     self.__repoSuite = repoSuite
     if tagSection:
         self.__tagSection = tagSection
         self.__id = tagSection['ID']
         self.__status = BundleStatus.getByName(tagSection['Status'])
         self.__target = tagSection['Target']
         self.__trac = tagSection.get('Trac', None)
         self.__ignores = str(tagSection.get('Ignores') or "").split(" ")
     elif repoSuite:
         self.__id = repoSuite.getSuiteName()
         self.__tagSection = apt_pkg.TagSection("ID: {}\n".format(self.__id))
         self.__status = BundleStatus.getByTags(repoSuite.getTags())
         self.__target = self.getInfo().get("Target", "unknown")
         self.__trac = None
         self.__ignores = []
def createTargetRepreproConfigs(bundles):
    """
        Creates reprepro config files for targets in all known stages
    """
    dist_template = templateEnv.get_template("target_distributions.skel")
    bundle_update_template = templateEnv.get_template("bundle_updates.skel")
    bundle_base_update_template = templateEnv.get_template(
        "bundle-base_updates.skel")

    updateUrls = set()
    for stage in sorted(BundleStatus.getAvailableStages()):
        targets = getTargetRepoSuites(stage)
        logger.info("Found {} targets for stage '{}'".format(
            len(targets), stage))
        for _, target in sorted(targets.items()):
            logger.debug("Adding target {} with Url {}".format(
                target, target.getRepoUrl()))
            updateUrls.add(target.getRepoUrl())

    for url in sorted(updateUrls):
        p = urlparse(url)
        repoConfDir = None
        if p.scheme == "file":
            urlFilepath = p.path.replace("%20", " ")
            repoConfDir = os.path.join(urlFilepath, 'conf')
            if not os.path.isdir(repoConfDir):
                os.makedirs(repoConfDir)
        else:
            urlFilepath = re.sub("[^a-zA-z0-9]", "_", url)
            repoConfDir = os.path.join(PROJECT_DIR, 'repo', urlFilepath,
                                       'conf')
            if not os.path.isdir(repoConfDir):
                # we expect 'conf' to be a preconfigured symlink in this case,
                # so use "mkdir" instead of "mkdirs"
                os.mkdir(repoConfDir)

        distributionsDir = os.path.join(repoConfDir, 'distributions')
        if os.path.isfile(distributionsDir):
            # allows to migrate from versions in which this was a file
            os.rename(distributionsDir,
                      os.path.join(repoConfDir, 'distributions.bak'))
        if not os.path.isdir(distributionsDir):
            os.mkdir(distributionsDir)

        updatesDir = os.path.join(repoConfDir, 'updates')
        if os.path.isfile(updatesDir):
            # allows to migrate from versions in which this was a file
            os.rename(updatesDir, os.path.join(repoConfDir, 'updates.bak'))
        if not os.path.isdir(updatesDir):
            os.mkdir(updatesDir)

        repoTargets = list()
        for _, target in sorted(getTargetRepoSuites().items()):
            if target.getRepoUrl() == url:
                repoTargets.append(target)
        createTargetRepreproConfigForRepository(bundles, repoTargets,
                                                repoConfDir,
                                                bundle_update_template,
                                                bundle_base_update_template,
                                                dist_template)
def cmd_stage(args):
    '''
        Marks specified bundles to be put into a particular stage.
    '''
    stageStatus = BundleStatus.getByStage(args.stage[0])
    bundles = parseBundles(getBundleRepoSuites())
    ids = set()
    if args.bundleName:
        ids = ids.union(args.bundleName)
    if args.candidates:
        candidates = filterBundles(bundles, stageStatus.getCandidates())
        ids = ids.union([bundle.getID() for bundle in candidates])
    markBundlesForStatus(bundles, ids, stageStatus, args.force)
Пример #4
0
def updateBundles(tracApi=None, parentTicketsField=None, cwd=PROJECT_DIR):
    preUpdateHook = getHooksConfig(cwd=cwd).get('pre_update_bundles', None)
    if preUpdateHook:
        cmd = preUpdateHook.split()
        logger.info("Calling pre_update_bundles hook '{}'".format(
            " ".join(cmd)))
        try:
            subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            logger.warning(
                "Hook execution failed with return code {}:\n{}".format(
                    e.returncode, e.output.decode('utf-8')))

    repo_suites = getBundleRepoSuites(cwd=cwd)
    managed_bundles = parseBundles(cwd=cwd)
    ids = set(repo_suites.keys()).union(managed_bundles.keys())

    for id in sorted(ids):
        logger.debug("Updating {}".format(id))
        bundle = managed_bundles.get(id)
        suite = repo_suites.get(id)
        if not bundle and suite:
            bundle = ManagedBundle(None, suite)
            managed_bundles[id] = bundle
            logger.info("Added {} with status '{}'".format(
                bundle, bundle.getStatus()))
        elif bundle and not suite:
            if bundle.getStatus() != BundleStatus.DROPPED:
                logger.warn(
                    "Could not find an apt-repos suite for bundle {} - Please check!"
                    .format(bundle))
        else:
            bundle.setRepoSuite(suite)
            if not bundle.ignoresTargetFromInfoFile():
                info = bundle.getInfo()
                if info.get("Target") != bundle.getTarget():
                    logger.warn(
                        "Target-Fields of {} and it's info file dont't match ('{}' vs. '{}') - Please check!"
                        .format(bundle, bundle.getTarget(),
                                info.get("Target")))
            suiteStatus = BundleStatus.getByTags(suite.getTags())
            if bundle.getStatus() < suiteStatus:
                if bundle.getStatus().allowsOverride():
                    bundle.setStatus(suiteStatus)
                    logger.info("Updated {} to status '{}'".format(
                        bundle, suiteStatus))
                else:
                    logger.warn(
                        "Status of {} doesn't match it's apt-repos tag-status ('{}' vs. '{}') - Please check!"
                        .format(bundle, bundle.getStatus(), suiteStatus))
        if tracApi:
            if not bundle.getTrac():
                if bundle.getStatus(
                ) > BundleStatus.STAGING and bundle.getStatus(
                ) < BundleStatus.DROPPED:
                    tid = createTracTicketForBundle(
                        tracApi,
                        bundle,
                        parentTicketsField=parentTicketsField,
                        cwd=cwd)
                    bundle.setTrac(tid)
                    logger.info(
                        "Created Trac-Ticket #{} of {} - Don't forget to publish this change!"
                        .format(bundle.getTrac(), bundle))
                else:
                    continue
            ticket = tracApi.getTicketValues(bundle.getTrac())
            fetchedTracStatus = BundleStatus.getByTracStatus(
                ticket['status'], ticket.get('resolution'))
            if bundle.getStatus() < fetchedTracStatus:
                if bundle.getStatus().allowsOverride():
                    bundle.setStatus(fetchedTracStatus)
                    logger.info("Updated {} to status '{}'".format(
                        bundle, fetchedTracStatus))
                else:
                    logger.warn(
                        "Status of {} doesn't match it's Trac-Ticket status ('{}' vs. '{}') - Please check!"
                        .format(bundle, bundle.getStatus(), fetchedTracStatus))
                    continue
            pushTracStatus = bundle.getStatus().getTracStatus()
            pushTracResolution = bundle.getStatus().getTracResolution()
            if pushTracStatus and ticket['status'] != pushTracStatus:
                tracApi.updateTicket(
                    bundle.getTrac(),
                    "Automatically updated by bundle-compose", {
                        'status':
                        pushTracStatus,
                        'resolution':
                        pushTracResolution if pushTracResolution else "",
                    })
                logger.info(
                    "Updated Trac-Ticket #{} of {} to Status '{}'".format(
                        bundle.getTrac(), bundle,
                        (pushTracStatus + " as " + pushTracResolution)
                        if pushTracResolution else pushTracStatus))
            pushTarget = bundle.getTarget()
            if pushTarget and ticket['bereitstellung'] != pushTarget:
                tracApi.updateTicket(
                    bundle.getTrac(),
                    "Automatically updated by bundle-compose",
                    {'bereitstellung': pushTarget})
                logger.info(
                    "Updated Trac-Ticket #{} of {} to Target '{}'".format(
                        bundle.getTrac(), bundle, pushTarget))

    storeBundles(managed_bundles, cwd=cwd)
def main():
    """
        Main entry point for this script
    """
    # fixup to get help-messages for subcommands that require positional argmuments
    # so that "apt-repos -h <subcommand>" prints a help-message and not an error
    for subcmd in ['mark-for-stage', 'stage', 'mark']:
        if ("-h" in sys.argv or "--help" in sys.argv) and subcmd in sys.argv:
            sys.argv.append("drop")

    parser = argparse.ArgumentParser(description=__doc__,
                                     prog=progname,
                                     add_help=False)
    parser.add_argument("-h",
                        "--help",
                        action="store_true",
                        help="""
                        Show a (subcommand specific) help message""")
    parser.add_argument("-d",
                        "--debug",
                        action="store_true",
                        default=False,
                        help="Show debug messages.")
    subparsers = parser.add_subparsers(help='choose one of these subcommands')
    parser.set_defaults(debug=False)

    # subcommand parsers
    parse_ub = subparsers.add_parser("update-bundles",
                                     help=cmd_update_bundles.__doc__,
                                     description=cmd_update_bundles.__doc__,
                                     aliases=['ub'])
    parse_stage = subparsers.add_parser("mark-for-stage",
                                        help=cmd_stage.__doc__,
                                        description=cmd_stage.__doc__,
                                        aliases=['stage', 'mark'])
    parse_list = subparsers.add_parser("list",
                                       help=cmd_list.__doc__,
                                       description=cmd_list.__doc__,
                                       aliases=['ls', 'lsb'])
    parse_apply = subparsers.add_parser("apply",
                                        help=cmd_apply.__doc__,
                                        description=cmd_apply.__doc__)
    parse_jsondump = subparsers.add_parser("jsondump",
                                           help=cmd_jsondump.__doc__,
                                           description=cmd_jsondump.__doc__)
    parse_jsondeps = subparsers.add_parser("jsondeps",
                                           help=cmd_jsondeps.__doc__,
                                           description=cmd_jsondeps.__doc__)

    parse_ub.set_defaults(sub_function=cmd_update_bundles, sub_parser=parse_ub)
    parse_stage.set_defaults(sub_function=cmd_stage, sub_parser=parse_stage)
    parse_list.set_defaults(sub_function=cmd_list, sub_parser=parse_list)
    parse_apply.set_defaults(sub_function=cmd_apply, sub_parser=parse_apply)
    parse_jsondump.set_defaults(sub_function=cmd_jsondump,
                                sub_parser=parse_jsondump)
    parse_jsondeps.set_defaults(sub_function=cmd_jsondeps,
                                sub_parser=parse_jsondeps)

    for p in [parse_ub]:
        p.add_argument("--no-trac",
                       action="store_true",
                       help="""
                        Don't sync against trac.""")

    for p in [parse_jsondump, parse_jsondeps]:
        p.add_argument('outputFilename',
                       nargs=1,
                       help="""
                        Name of the ouptFile for the json-dump.""")

    for p in [parse_list]:
        p.add_argument("-s",
                       "--stage",
                       default=None,
                       choices=sorted(BundleStatus.getAvailableStages()),
                       help="""
                        Select only bundles in the provided stage.""")
        p.add_argument("-c",
                       "--candidates",
                       action="store_true",
                       help="""
                        Print the list of candidates for each (selected) status."""
                       )

    for p in [parse_stage]:
        p.add_argument("-c",
                       "--candidates",
                       action="store_true",
                       help="""
                        Automatically add all candiates for this stage. Available candidates can be viewed with '{} list -c'."""
                       .format(progname))
        p.add_argument("-f",
                       "--force",
                       action="store_true",
                       help="""
                        Don't check if a bundle is ready for being put into the new stage."""
                       )
        p.add_argument('stage',
                       nargs=1,
                       choices=sorted(BundleStatus.getAvailableStages()),
                       help="""
                        The stage bundles should be marked for.""")
        p.add_argument('bundleName',
                       nargs='*',
                       help="""
                        Identifier of a bundle (as listed in the first column of '{} list')."""
                       .format(progname))

    parser.set_defaults()
    args = parser.parse_args()
    setupLogging(logging.DEBUG if args.debug else logging.INFO)
    apt_repos.setAptReposBaseDir(os.path.join(PROJECT_DIR, ".apt-repos"))

    if "sub_function" in args.__dict__:
        if args.help:
            args.sub_parser.print_help()
            sys.exit(0)
        else:
            args.sub_function(args)
            sys.exit(0)
    else:
        if args.help:
            parser.print_help()
            sys.exit(0)
        else:
            parser.print_usage()
            sys.exit(1)