Esempio n. 1
0
    def env(self):
        # strategy: create a tempfile, let python dump its full env in a subprocess. and load the
        # env file again afterwards
        script = self.script
        if script not in self._envs:
            with tmp_file() as tmp:
                tmp_path = os.path.realpath(tmp[1])

                cmd = "bash -l -c 'source \"{0}\"; python -c \"" \
                    "import os,pickle;pickle.dump(os.environ,open(\\\"{1}\\\",\\\"w\\\"))\"'"
                cmd = cmd.format(script, tmp_path)

                returncode, out, _ = interruptable_popen(
                    cmd,
                    shell=True,
                    executable="/bin/bash",
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT)
                if returncode != 0:
                    raise Exception("bash sandbox env loading failed: " +
                                    str(out))

                with open(tmp_path, "r") as f:
                    env = six.moves.cPickle.load(f)

            # add env variables defined in the config
            env.update(self.get_config_env())

            # add env variables defined by the task
            env.update(self.get_task_env())

            # cache
            self._envs[script] = env

        return self._envs[script]
Esempio n. 2
0
def renew_arc_proxy(password="", lifetime="8 days", proxy_file=None):
    """
    Renews the arc proxy using a password *password* and a default *lifetime* of 8 days, which is
    internally parsed by :py:func:`law.util.parse_duration` where the default input unit is hours.
    To ensure that the *password* it is not visible in any process listing, it is written to a
    temporary file first and piped into the ``arcproxy`` command. When *proxy_file* is *None*, it
    defaults to the result of :py:func:`get_arc_proxy_file`. Otherwise, when it evaluates to
    *False*, ``arcproxy`` is invoked without a custom proxy file.
    """
    # convert the lifetime to seconds
    lifetime_seconds = int(parse_duration(lifetime, input_unit="h", unit="s"))

    if proxy_file is None:
        proxy_file = get_arc_proxy_file()

    args = "--constraint=validityPeriod={}".format(lifetime_seconds)
    if proxy_file:
        proxy_file = os.path.expandvars(os.path.expanduser(proxy_file))
        args += " --proxy={}".format(proxy_file)

    with tmp_file() as (_, tmp):
        with open(tmp, "w") as f:
            f.write(password)

        cmd = "arcproxy --passwordsource=key=file:{} {}".format(tmp, args)
        code, out, _ = interruptable_popen(cmd,
                                           shell=True,
                                           executable="/bin/bash",
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.STDOUT)

        if code != 0:
            raise Exception("arcproxy failed: {}".format(out))
Esempio n. 3
0
    def env(self):
        # strategy: create a tempfile, forward it to a container, let python dump its full env,
        # close the container and load the env file
        if self.image not in self._envs:
            with tmp_file() as tmp:
                tmp_path = os.path.realpath(tmp[1])
                env_path = os.path.join("/tmp", str(hash(tmp_path))[-8:])

                cmd = "docker run --rm -v {1}:{2} {0} python -c \"" \
                    "import os,pickle;pickle.dump(os.environ,open('{2}','w'))\""
                cmd = cmd.format(self.image, tmp_path, env_path)

                returncode, out, _ = interruptable_popen(
                    cmd,
                    shell=True,
                    executable="/bin/bash",
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT)
                if returncode != 0:
                    raise Exception("docker sandbox env loading failed: " +
                                    str(out))

                with open(tmp_path, "r") as f:
                    env = six.moves.cPickle.load(f)

            # add env variables defined in the config
            env.update(self.get_config_env())

            # add env variables defined by the task
            env.update(self.get_task_env())

            # cache
            self._envs[self.image] = env

        return self._envs[self.image]
Esempio n. 4
0
File: bash.py Progetto: riga/law
    def env(self):
        # strategy: create a tempfile, let python dump its full env in a subprocess and load the
        # env file again afterwards
        script = self.script
        if script not in self._envs:
            with tmp_file() as tmp:
                tmp_path = os.path.realpath(tmp[1])

                # get the bash command
                bash_cmd = self._bash_cmd()

                # build commands to setup the environment
                setup_cmds = self._build_setup_cmds(self._get_env())

                # build the python command that dumps the environment
                py_cmd = "import os,pickle;" \
                    + "pickle.dump(dict(os.environ),open('{}','wb'),protocol=2)".format(tmp_path)

                # build the full command
                cmd = quote_cmd(bash_cmd + [
                    "-c",
                    "; ".join(
                        flatten("source \"{}\" \"\"".format(
                            self.script), setup_cmds,
                                quote_cmd(["python", "-c", py_cmd]))),
                ])

                # run it
                returncode = interruptable_popen(cmd,
                                                 shell=True,
                                                 executable="/bin/bash")[0]
                if returncode != 0:
                    raise Exception("bash sandbox env loading failed")

                # load the environment from the tmp file
                pickle_kwargs = {"encoding": "utf-8"} if six.PY3 else {}
                with open(tmp_path, "rb") as f:
                    env = collections.OrderedDict(
                        six.moves.cPickle.load(f, **pickle_kwargs))

            # cache it
            self._envs[script] = env

        return self._envs[script]
Esempio n. 5
0
File: sandbox.py Progetto: yrath/law
    def env(self):
        # strategy: create a tempfile, forward it to a container, let python dump its full env,
        # close the container and load the env file
        if self.image not in self._envs:
            with tmp_file() as tmp:
                tmp_path = os.path.realpath(tmp[1])
                env_path = os.path.join("/tmp", str(hash(tmp_path))[-8:])

                # build commands to setup the environment
                setup_cmds = self._build_setup_cmds(self._get_env())

                # arguments to configure the environment
                args = ["-v", "{}:{}".format(tmp_path, env_path)
                        ] + self.common_args()

                # build the command
                py_cmd = "import os,pickle;" \
                    + "pickle.dump(dict(os.environ),open('{}','wb'),protocol=2)".format(env_path)
                cmd = quote_cmd(["docker", "run"] + args + [
                    self.image,
                    "bash",
                    "-l",
                    "-c",
                    "; ".join(
                        flatten(setup_cmds, quote_cmd(["python", "-c", py_cmd
                                                       ]))),
                ])

                # run it
                returncode = interruptable_popen(cmd,
                                                 shell=True,
                                                 executable="/bin/bash")[0]
                if returncode != 0:
                    raise Exception("docker sandbox env loading failed")

                # load the environment from the tmp file
                with open(tmp_path, "rb") as f:
                    env = six.moves.cPickle.load(f)

            # cache
            self._envs[self.image] = env

        return self._envs[self.image]
Esempio n. 6
0
File: util.py Progetto: yrath/law
def renew_voms_proxy(passwd="", vo=None, lifetime="196:00"):
    """
    Renews the voms proxy using a password *passwd*, an optional virtual organization name *vo*, and
    a default *lifetime* of 8 days. The password is written to a temporary file first and piped into
    the renewal commad to ensure it is not visible in the process list.
    """
    with tmp_file() as (_, tmp):
        with open(tmp, "w") as f:
            f.write(passwd)

        cmd = "cat '{}' | voms-proxy-init --valid '{}'".format(tmp, lifetime)
        if vo:
            cmd += " -voms '{}'".format(vo)
        code, out, _ = interruptable_popen(cmd,
                                           shell=True,
                                           executable="/bin/bash",
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.STDOUT)
        if code != 0:
            raise Exception("proxy renewal failed: {}".format(out))
Esempio n. 7
0
File: util.py Progetto: riga/law
def renew_voms_proxy(password="", vo=None, lifetime="8 days", proxy_file=None):
    """
    Renews the voms proxy using a password *password*, an optional virtual organization name *vo*,
    and a default *lifetime* of 8 days, which is internally parsed by
    :py:func:`law.util.parse_duration` where the default input unit is hours. To ensure that the
    *password* is not visible in any process listing, it is written to a temporary file first and
    piped into the ``voms-proxy-init`` command. When *proxy_file* is *None*, it defaults to the
    result of :py:func:`get_voms_proxy_file`.
    """
    # parse and format the lifetime
    lifetime_seconds = max(parse_duration(lifetime, input_unit="h", unit="s"),
                           60.0)
    lifetime = human_duration(seconds=lifetime_seconds, colon_format="h")
    # cut the seconds part
    normalized = ":".join((2 - lifetime.count(":")) * ["00"] + [""]) + lifetime
    lifetime = ":".join(normalized.rsplit(":", 3)[-3:-1])

    # when proxy_file is None, get the default
    # when empty string, don't add a --out argument
    if proxy_file is None:
        proxy_file = get_voms_proxy_file()

    with tmp_file() as (_, tmp):
        with open(tmp, "w") as f:
            f.write(password)

        cmd = "cat '{}' | voms-proxy-init --valid '{}'".format(tmp, lifetime)
        if vo:
            cmd += " -voms '{}'".format(vo)
        if proxy_file:
            proxy_file = os.path.expandvars(os.path.expanduser(proxy_file))
            cmd += " --out '{}'".format(proxy_file)

        code, out, _ = interruptable_popen(cmd,
                                           shell=True,
                                           executable="/bin/bash",
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.STDOUT)

        if code != 0:
            raise Exception("voms-proxy-init failed: {}".format(out))