Пример #1
0
def do_depend(builder, pkg_name, role_names, deps):
    """
    Make pkg_name in role_names depend on the contents of deps.

    deps is a list of 2-tuples (pkg_name, role_name)

    If the role name is None, we depend on the pkg name in the role we're
    currently using, so ``do_depend(a, ['b', 'c'], [ ('d', None) ])`` leads
    to ``a{b}`` depending on ``d{b}`` and ``a{c}`` depending on ``d{c}``.
    
    If role_names is a string, we will implicitly convert it into the 
    singleton list [ role_names ].
    """

    ruleset = builder.ruleset
    if isinstance(role_names, basestring):
        r = role_names
        role_names = [r]

    for role_name in role_names:
        for (pkg, role) in deps:
            if (role is None):
                role = role_name

            ruleset.add(
                depend.depend_one(
                    None,
                    depend.Label(utils.LabelType.Package, pkg_name, role_name,
                                 utils.LabelTag.PreConfig),
                    depend.Label(utils.LabelType.Package, pkg, role,
                                 utils.LabelTag.PostInstalled)))
Пример #2
0
def deploy_with_domains(builder, target_dir, name, role_domains):
    """
    Register a file deployment.

    'role_domains' is a sequence of (role, domain) pairs. The deployment will
    take the roles and domains specified, and build them into a deployment at
    deploy/[name].

    More specifically, a rule will be created for label:

      "deployment:<name>/deployed"

    which depends on "package:(<domain>)*{<role}/postinstalled" for each
    (<role>, <domain>) pair in 'role_domains'.

    In other words, the deployment called 'name' will depend on the given roles
    in the appropriate domains having been "finished" (postinstalled).

    An "instructions applied" label "deployment:<name>/instructionsapplied"
    will also be created.

    The deployment should eventually be located at 'target_dir'.
    """

    the_action = FileDeploymentBuilder(role_domains, target_dir)

    dep_label = depend.Label(utils.LabelType.Deployment, name, None,
                             utils.LabelTag.Deployed)

    iapp_label = depend.Label(utils.LabelType.Deployment,
                              name,
                              None,
                              utils.LabelTag.InstructionsApplied,
                              transient=True)

    # We depend on every postinstall for every package in the roles

    deployment_rule = depend.Rule(dep_label, the_action)

    for role, domain in role_domains:
        role_label = depend.Label(utils.LabelType.Package,
                                  "*",
                                  role,
                                  utils.LabelTag.PostInstalled,
                                  domain=domain)
        deployment_rule.add(role_label)

    # The instructionsapplied label is standalone ..
    app_rule = depend.Rule(iapp_label, the_action)

    # Now add 'em ..
    builder.ruleset.add(deployment_rule)
    builder.ruleset.add(app_rule)

    # .. and deal with cleanup, which is entirely generic
    deployment.register_cleanup(builder, name)

    # .. and set the environment
    the_action.attach_env(builder)
Пример #3
0
def deployment_depends_on_deployment(builder, what, depends_on, domain=None):
    """
    Inter-deployment dependencies. Aren't you glad we have a
    general purpose dependency solver?
    """
    tgt = depend.Label(utils.LabelType.Deployment, what, None,
                       utils.LabelTag.Deployed)
    rule = builder.ruleset.rule_for_target(tgt, createIfNotPresent=True)
    rule.add(
        depend.Label(utils.LabelType.Deployment,
                     depends_on,
                     None,
                     utils.LabelTag.Deployed,
                     domain=domain))
Пример #4
0
def depend_across_roles(ruleset, pkg_name, role_names, depends_on_pkgs,
                        depends_on_role):
    """
    Register that pkg_name{role_name}'s preconfig depends on
    depends_on_pkg{depends_on_role} having been postinstalled.
    """
    for pkg in depends_on_pkgs:
        for role_name in role_names:
            ruleset.add(
                depend.depend_one(
                    None,
                    depend.Label(utils.LabelType.Package, pkg_name, role_name,
                                 utils.LabelTag.PreConfig),
                    depend.Label(utils.LabelType.Package, pkg, depends_on_role,
                                 utils.LabelTag.PostInstalled)))
Пример #5
0
def depends_on_aptalt(builder, name, role, pkg, pkg_role):
    """
    Make a package dependant on a particular apt-builder.

    * pkg - The package we want to add a dependency to. '*' is a good thing to
      add here ..
    """

    tgt_label = depend.Label(LabelType.Package, pkg, pkg_role,
                             LabelTag.PreConfig)

    the_rule = builder.ruleset.rule_for_target(tgt_label,
                                               createIfNotPresent=True)
    the_rule.add(
        depend.Label(LabelType.Package, name, role, LabelTag.PostInstalled))
Пример #6
0
def role_depends_on_deployment(builder, role, deployment, domain=None):
    """
    Make every package in the given role depend on the given deployment
    """

    tgt = depend.Label(utils.LabelType.Package, "*", role,
                       utils.LabelTag.PreConfig)
    the_rule = depend.Rule(tgt, None)
    the_rule.add(
        depend.Label(utils.LabelType.Deployment,
                     deployment,
                     None,
                     utils.LabelTag.Deployed,
                     domain=domain))
    builder.ruleset.add(the_rule)
Пример #7
0
def deployment_depends_on_roles(builder, deployment, roles, domain=None):
    """
    Make the deployment of the deployment with the given name
    depend on the installation of every package in the given
    role
    """
    tgt = depend.Label(utils.LabelType.Deployment, deployment, None,
                       utils.LabelTag.Deployed)
    rule = builder.ruleset.rule_for_target(tgt, createIfNotPresent=True)
    for r in roles:
        lbl = depend.Label(utils.LabelType.Package,
                           "*",
                           r,
                           utils.LabelTag.PostInstalled,
                           domain=domain)
        rule.add(lbl)
Пример #8
0
    def apply_instructions(self, builder, label):

        for role, domain in self.roles:
            lbl = depend.Label(utils.LabelType.Package,
                               "*",
                               role,
                               "*",
                               domain=domain)
            deploy_dir = builder.deploy_path(label)
            instr_list = builder.load_instructions(lbl)
            for (lbl, fn, instrs) in instr_list:
                print "File deployment: Applying instructions for role %s, label %s .. " % (
                    role, lbl)
                for instr in instrs:
                    # Obey this instruction.
                    iname = instr.outer_elem_name()
                    print 'Instruction:', iname
                    if iname in self.app_dict:
                        self.app_dict[iname].apply(builder, instr, role,
                                                   deploy_dir)
                    else:
                        raise utils.GiveUp(
                            "File deployments don't know about instruction %s"
                            % iname + " found in label %s (filename %s)" %
                            (lbl, fn))
Пример #9
0
def create(builder,
           name,
           role,
           pkgs_and_roles,
           custom_depmod=None,
           subdir="/lib/modules"):
    """
    Create a depmod_merge . It will depend on each of the mentioned packages.

    pkgs is a list of (pkg, role) pairs.

    We return the depmod_merge we've created.
    """

    action = MergeDepModBuilder(name, role, custom_depmod)

    pkg.add_package_rules(builder.ruleset, name, role, action)
    pkg.do_depend(builder, name, [role], pkgs_and_roles)

    for (pname, role) in pkgs_and_roles:
        lbl = depend.Label(utils.LabelType.Package, pname, role,
                           utils.LabelTag.PostInstalled)
        action.add_label(lbl, subdir)

    return action
Пример #10
0
def attach_env(builder, role, env, name):
    """
    Attach suitable environment variables for the given input role
    to the given environment store.

    We set:

    * LD_LIBRARY_PATH   - Prepend $role_installl/lib
    * PATH              - Append $role_install/bin
    * PKG_CONFIG_PATH   - Prepend $role_install/lib/pkgconfig
    * $role_TOOLS_PATH  - Prepend $role_install/bin

    The PATH/TOOLS_PATH stuff is so you can still locate tools which were
    in the path even if they've been overridden with your built tools.
    """

    env.set_type("LD_LIBRARY_PATH", muddled.env_store.EnvType.Path)
    env.set_type("PATH", muddled.env_store.EnvType.Path)
    env.set_type("PKG_CONFIG_PATH", muddled.env_store.EnvType.Path)
    env.set_external("LD_LIBRARY_PATH")
    env.set_external("PATH")
    env.set_external("PKG_CONFIG_PATH")

    deploy_label = depend.Label(utils.LabelType.Deployment, name)
    deploy_base = builder.deploy_path(deploy_label)

    env.ensure_prepended("LD_LIBRARY_PATH", os.path.join(deploy_base, "lib"))
    env.ensure_prepended("PKG_CONFIG_PATH",
                         os.path.join(deploy_base, "lib", "pkgconfig"))
    env.ensure_appended("PATH", os.path.join(deploy_base, "bin"))
    env.set("%s_TOOLS_PATH" % (name.upper()), deploy_base)
Пример #11
0
def packages_use_role(builder, pkgs, in_role, use_role, domain=None):
    """
    Specifies that one role uses the results of another role; this
    is most often used to allow roles built for a target to use roles
    built for the host.

    We would normally want a role_uses_role(), but this tends to lead
    to undesirable excessive rebuilding of entire roles when the host
    tools change.
    """
    for p in pkgs:
        role_label = depend.Label(utils.LabelType.Package, "*", use_role,
                                  utils.LabelTag.PostInstalled)
        pkg.do_depend_label(builder, p, [in_role], role_label)

        role_path = builder.role_install_path(use_role, domain)
        pkg.prepend_env_for_package(builder,
                                    p, [in_role],
                                    "PATH",
                                    os.path.join(role_path, "bin"),
                                    domain=domain)
        pkg.prepend_env_for_package(builder,
                                    p, [in_role],
                                    "LD_LIBRARY_PATH",
                                    os.path.join(role_path, "lib"),
                                    domain=domain)
Пример #12
0
def set_env(builder, deployment, name, value):
    """
    Set NAME=VALUE in the environment for this deployment.
    """
    lbl = depend.Label(utils.LabelType.Deployment, deployment, None,
                       utils.LabelTag.Deployed)
    env = builder.get_environment_for(lbl)
    env.set(name, value)
Пример #13
0
def append_to_path(builder, roles, val):
    """
    Append the given value to the PATH for the given roles
    """
    for r in roles:
        lbl = depend.Label(utils.LabelType.Package, "*", r, "*")
        env = builder.get_environment_for(lbl)
        env.append("PATH", val)
Пример #14
0
def package_depends_on_packages(ruleset, pkg_name, role, tag_name, deps):
    """
    Make pkg_name depend on the list in deps.

    pkg_name's tag_name tag ends up depending on the deps having been installed -
    this can be PreConfig or Built, depending on whether you need that dependency
    to configure yourself or not.
    """
    target_label = depend.Label(utils.LabelType.Package, pkg_name, role,
                                tag_name)

    r = ruleset.rule_for_target(target_label, createIfNotPresent=True)

    for d in deps:
        dep_label = depend.Label(utils.LabelType.Package, d, role,
                                 utils.LabelTag.PostInstalled)
        r.add(dep_label)
Пример #15
0
def package_depends_on_checkout(ruleset,
                                pkg_name,
                                role_name,
                                co_name,
                                action=None):
    """
    Make the given package depend on the given checkout

    * ruleset   - The ruleset to use - builder.ruleset, for example.
    * pkg_name  - The package which depends.
    * role_name - The role which depends. Can be '*' for a wildcard.
    * co_name   - The checkout which this package and role depends on.
    * action    - If non-None, specifies an Action to be invoked to get from
      the checkout to the package preconfig. If you are a normal (outside
      muddle itself) caller, then you will normally leave this None unless you
      are doing something deeply weird.
    """

    checkout = depend.Label(utils.LabelType.Checkout, co_name, None,
                            utils.LabelTag.CheckedOut)

    preconfig = depend.Label(utils.LabelType.Package, pkg_name, role_name,
                             utils.LabelTag.PreConfig)

    new_rule = depend.Rule(preconfig, action)
    new_rule.add(checkout)
    ruleset.add(new_rule)

    # We can't clean or distclean a package until we've checked out its checkout
    # Both are transient, as we don't need to remember we've done them, and
    # indeed they should be doable more than once
    clean = depend.Label(utils.LabelType.Package,
                         pkg_name,
                         role_name,
                         utils.LabelTag.Clean,
                         transient=True)
    ruleset.add(depend.depend_one(action, clean, checkout))

    distclean = depend.Label(utils.LabelType.Package,
                             pkg_name,
                             role_name,
                             utils.LabelTag.DistClean,
                             transient=True)
    ruleset.add(depend.depend_one(action, distclean, checkout))
Пример #16
0
    def build_label(self, builder, label):
        """
        Install is the only one we care about ..
        """

        if (label.tag == utils.LabelTag.Installed):
            tmp = Label(utils.LabelType.Package, self.name, self.role, domain=label.domain)
            inst_dir = builder.package_install_path(tmp)

            tgt_dir = os.path.join(inst_dir, "bin")
            src_file = builder.resource_file_name("initscript.sh")

            utils.ensure_dir(tgt_dir)
            tgt_file = os.path.join(tgt_dir, self.script_name)
            print "> Writing %s .. "%(tgt_file)
            subst.subst_file(src_file, tgt_file, None, os.environ)
            os.chmod(tgt_file, 0755)

            # Write the setvars script
            env = get_effective_env(builder, self.name, self.role,
                                    domain = label.domain)
            effective_env = env.copy()
            env_store.add_install_dir_env(effective_env, "MUDDLE_TARGET_LOCATION")


            for d in self.deployments:
                # Merge in the relevant deployment environments.
                lbl = depend.Label(utils.LabelType.Deployment,
                                   d,
                                   None,
                                   utils.LabelTag.Deployed,
                                   domain = label.domain)
                effective_env.merge(builder.get_environment_for(
                        lbl))

            if (self.write_setvars_sh):
                setenv_file_name = os.path.join(tgt_dir, "setvars")
                sv_script  = effective_env.get_setvars_script(builder,
                                                              self.script_name,
                                                              env_store.EnvLanguage.Sh)

                out_f = open(setenv_file_name, "w")
                out_f.write(sv_script)
                out_f.close()

            if (self.write_setvars_py):
                # Now the python version ..
                setenv_file_name = os.path.join(tgt_dir, "setvars.py")
                sv_script = effective_env.get_setvars_script(builder,
                                                             self.script_name,
                                                   env_store.EnvLanguage.Python)
                out_f = open(setenv_file_name, "w")
                out_f.write(sv_script)
                out_f.close()
        else:
            pass
Пример #17
0
def set_global_package_env(builder, name, value, roles=["*"]):
    """
    Set an environment variable 'name = value' for all of the named roles.

    (The default sets the environment variable globally, i.e., for all roles.)
    """
    for r in roles:
        lbl = depend.Label(utils.LabelType.Package, "*", r, "*")
        env = builder.get_environment_for(lbl)
        env.set(name, value)
Пример #18
0
def inform_deployment_path(builder, name, deployment, roles, domain=None):
    """
    Sets an environment variable to tell the given roles about the
    location of the given deployment.

    Useful when e.g. some tools need to run other tools and therefore
    want to know where they are at build (rather than run)time.
    """

    for role in roles:
        lbl = depend.Label(utils.LabelType.Package,
                           "*",
                           role,
                           "*",
                           domain=domain)
        env = builder.get_environment_for(lbl)
        env.set_type(name, env_store.EnvType.SimpleValue)

        deployment_label = depend.Label(utils.LabelType.Deployment, deployment)
        env.set(name, builder.deploy_path(deployment_label))
Пример #19
0
def add_deps(builder, merger, deps, subdir="/lib/modules"):
    """
    Add a set of packages and roles to this merger as packages which create
    linux kernel modules. deps is a list of (pkg,role)
    """
    pkg.do_depend(builder, merger.name, [merger.role], deps)

    for (pname, role) in deps:
        lbl = depend.Label(utils.LabelType.Package, pname, role,
                           utils.LabelTag.PostInstalled)
        merger.add_label(lbl, subdir)
Пример #20
0
def get_effective_env(builder, name, role, domain = None):
    """
    Retrieve the effective runtime environment for this initscripts
    package. Note that setting variables here will have no effect.
    """
    return builder.effective_environment_for(
                depend.Label(
                    utils.LabelType.Package,
                    name, role,
                    utils.LabelTag.RuntimeEnv,
                    domain = domain))
Пример #21
0
def attach_env(builder, name, role, checkout, domain=None):
    """
    Write the environment which attaches MUDDLE_SRC to makefiles.

    We retrieve the environment for ``package:<name>{<role>}/*``, and
    set MUDDLE_SRC therein to the checkout path for 'checkout:<checkout>'.
    """
    env = builder.get_environment_for(
        depend.Label(utils.LabelType.Package, name, role, "*"))
    tmp = Label(utils.LabelType.Checkout, checkout, domain=domain)
    env.set("MUDDLE_SRC", builder.db.get_checkout_path(tmp))
Пример #22
0
def deploy(builder, name, rolesThatUseThis=[], rolesNeededForThis=[]):
    """
    Register a tools deployment.

    This is used to:

    1. Set the environment for each role in 'rolesThatUseThis' so that
       PATH, LD_LIBRARY_PATH and PKG_CONFIG_PATH include the 'name'
       deployment

    2. Make deployment:<name>/deployed depend upon the 'rolesNeededForThis'

    3. Register cleanup for this deployment

    The intent is that we have a "tools" deployment, which provides useful
    host tools (for instance, something to mangle a file in a particular
    manner). Those roles which need to use such tools in their builds
    (normally in a Makefile.muddle) then need to have the environment set
    appropriately to allow them to find the tools (and ideally, not system
    provided tools which mighth have the same name).
    """

    tgt = depend.Label(utils.LabelType.Deployment, name, None,
                       utils.LabelTag.Deployed)

    for role in rolesThatUseThis:
        for tag in (utils.LabelTag.PreConfig, utils.LabelTag.Configured,
                    utils.LabelTag.Built, utils.LabelTag.Installed,
                    utils.LabelTag.PostInstalled):
            lbl = depend.Label(utils.LabelType.Package, "*", role, tag)
            env = builder.get_environment_for(lbl)
            attach_env(builder, role, env, name)

        deployment.role_depends_on_deployment(builder, role, name)

    the_rule = depend.Rule(tgt, ToolsDeploymentBuilder(rolesNeededForThis))
    builder.ruleset.add(the_rule)

    deployment.deployment_depends_on_roles(builder, name, rolesNeededForThis)

    deployment.register_cleanup(builder, name)
Пример #23
0
def register_cleanup(builder, deployment):
    """
    Register the rule you need to clean a deployment.

    Cleaning a deployment basically means we remove the directory
    and its deployed tag.
    """

    target_lbl = depend.Label(utils.LabelType.Deployment, deployment, None,
                              utils.LabelTag.Clean)
    rule = depend.Rule(target_lbl, CleanDeploymentBuilder())
    builder.ruleset.add(rule)
Пример #24
0
def get_env(builder, name, role, domain = None):
    """
    Retrieve an environment to which you can make changes which will
    be reflected in the generated init scripts. The actual environment
    used will have extra values inserted from wildcarded environments -
    see get_effective_env() above.
    """
    return builder.get_environment_for(
        depend.Label(
            utils.LabelType.Package,
            name, role,
            utils.LabelTag.RuntimeEnv,
            domain = domain))
Пример #25
0
def pkg_depends_on_deployment(builder, pkg, roles, deployment, domain=None):
    """
    Make this package depend on the given deployment

    Specifically, given each role 'r' in 'roles', make the label
    "package:<pkg>{<r>}/preconfig" depend on the label
    "deployment:<deployment>/deployed".

    If 'domain' is given, this is (currently) just used for the deploymet
    label.
    """
    deployment_label = depend.Label(utils.LabelType.Deployment,
                                    deployment,
                                    None,
                                    utils.LabelTag.Deployed,
                                    domain=domain)
    for i in roles:
        tgt = depend.Label(utils.LabelType.Package, pkg, i,
                           utils.LabelTag.PreConfig)
        the_rule = depend.Rule(tgt, None)
        the_rule.add(deployment_label)
        builder.ruleset.add(the_rule)
Пример #26
0
def add_package_rules(ruleset, pkg_name, role_name, action):
    """
    Add the standard package rules to a ruleset.
    """

    depend.depend_chain(
        action,
        depend.Label(utils.LabelType.Package, pkg_name, role_name,
                     utils.LabelTag.PreConfig), [
                         utils.LabelTag.Configured, utils.LabelTag.Built,
                         utils.LabelTag.Installed, utils.LabelTag.PostInstalled
                     ], ruleset)

    # "clean" is transient, since we don't want/need to remember that it
    # has been done (doing "clean" more than once is rather requires to
    # be harmless)
    #
    # "clean" used to depend on "preconfig", but this sometimes had strange
    # results - for instance, if "preconfig" on A depended on "checked_out"
    # of B.
    #
    # Instead, we will make "clean" depend on "checked_out", and as such this
    # is done in package_depends_on_checkout, just as "distclean" always has
    # been
    if False:
        ruleset.add(
            depend.depend_one(
                action,
                depend.Label(utils.LabelType.Package,
                             pkg_name,
                             role_name,
                             utils.LabelTag.Clean,
                             transient=True),
                depend.Label(utils.LabelType.Package,
                             pkg_name,
                             role_name,
                             utils.LabelTag.CheckedOut,
                             transient=True)))
Пример #27
0
def build_role_on_architecture(builder, role, arch):
    """
    Wraps all the actions in a given role inside an ArchSpecificAction generator.

    This requires all the actions in that role ("package:*{<role>}/*") to
    be built on architecture <arch>.
    """
    lbl = depend.Label(utils.LabelType.Package,
                       "*",
                       role,
                       "*",
                       domain=builder.default_domain)
    gen = pkg.ArchSpecificAction(arch)
    builder.ruleset.wrap_actions(gen, lbl)
Пример #28
0
def deployment_rule_from_name(builder, name):
    """
    Return the rule for target label "deployment:<name>{}/deployed".

    Raises an exception if there is more than one such rule.
    """
    rules = builder.ruleset.rules_for_target(depend.Label(
        utils.LabelType.Deployment, name, None, utils.LabelTag.Deployed),
                                             useTags=True,
                                             useMatch=False)
    if (len(rules) != 1):
        raise utils.GiveUp(
            "Attempt to retrieve rule for deployment %s:" % name +
            " returned list had length %d ,not 1.. " % len(rules))

    for r in rules:
        return r
Пример #29
0
def do_depend_label(builder, pkg_name, role_names, label):
    """ 
    Make pkg_name in role_names depend on the given label
    
    If role_names is a string, we will implicitly convert it into the 
    singleton list [ role_names ].
    """
    ruleset = builder.ruleset
    if isinstance(role_names, basestring):
        r = role_names
        role_names = [r]

    for role_name in role_names:
        ruleset.add(
            depend.depend_one(
                None,
                depend.Label(utils.LabelType.Package, pkg_name, role_name,
                             utils.LabelTag.PreConfig), label))
Пример #30
0
    def attach_env(self, builder):
        """
        Attaches an environment containing:

          MUDDLE_TARGET_LOCATION - the location in the target filesystem where
          this deployment will end up.

        to every package label in this role.
        """

        for role, domain in self.roles:
            lbl = depend.Label(utils.LabelType.Package,
                               "*",
                               role,
                               "*",
                               domain=domain)
            env = builder.get_environment_for(lbl)
            env.set_type("MUDDLE_TARGET_LOCATION",
                         muddled.env_store.EnvType.SimpleValue)
            env.set("MUDDLE_TARGET_LOCATION", self.target_dir)