Beispiel #1
0
    def run_job(self, file, jobid, timeout=None, env={}):
        try:
            jobs_dir = ".cstar/remote-jobs/" + jobid
            self.run(("mkdir", "-p", jobs_dir))
            self.put_command(file, "%s/job" % (jobs_dir, ))

            # Manually insert environment into script, since passing env into exec_command leads to it being
            # ignored on most ssh servers. :-(

            for key in env:
                if _alnum_re.search(key):
                    raise BadEnvironmentVariable(key)

            env_str = " ".join(key + "=" + self.escape(value)
                               for key, value in env.items())
            remote_script = resource_string('cstar.resources',
                                            'scripts/remote_job.sh')
            wrapper = remote_script.decode("utf-8") % (env_str, )
            self.write_command(wrapper, "%s/wrapper" % (jobs_dir, ))
            cmd_cd = "cd %s" % (self.escape(jobs_dir), )
            cmd_wrapper = "nohup ./wrapper"
            self.exec_command(cmd_cd + ";" + cmd_wrapper)
            out, err_output, status = self.read_channel()
            real_output = self.read_file(jobs_dir + "/stdout")
            real_error = self.read_file(jobs_dir + "/stderr")
            real_status = int(self.read_file(jobs_dir + "/status"))
            return ExecutionResult(cmd_wrapper, real_status, real_output,
                                   real_error)
        except:
            err("Command failed : ", sys.exc_info()[0])
            raise BadSSHHost("SSH connection to host %s was reset" %
                             (self.hostname, ))
Beispiel #2
0
    def run_job(self, file, jobid, timeout=None, env={}):
        try:
            self._connect()

            transport = self.client.get_transport()
            session = transport.open_session()
            paramiko.agent.AgentRequestHandler(session)

            dir = ".cstar/remote-jobs/" + jobid

            self.run(("mkdir", "-p", dir))

            self.put_command(file, "%s/job" % (dir, ))

            # Manually insert environment into script, since passing env into exec_command leads to it being
            # ignored on most ssh servers. :-(

            for key in env:
                if _alnum_re.search(key):
                    raise BadEnvironmentVariable(key)

            env_str = " ".join(key + "=" + self.escape(value)
                               for key, value in env.items())
            wrapper = r"""#! /bin/sh

    if test -f pid; then
        # We can't wait for things that aren't our children. Loop and sleep. :-(
        while ! test -f status; do
            sleep 10s
        done
        exit
    fi

    %s ./job >stdout 2>stderr &
    echo $! >pid
    wait $!
    echo $? >status
    """ % (env_str, )
            self.write_command(wrapper, "%s/wrapper" % (dir, ))

            cmd = """
    cd %s
    nohup ./wrapper
    """ % (self.escape(dir), )

            stdin, stdout, stderr = self.client.exec_command(cmd,
                                                             timeout=timeout)
            stdout.channel.recv_exit_status()
            real_output = self.read_file(dir + "/stdout")
            real_error = self.read_file(dir + "/stderr")
            real_status = int(self.read_file(dir + "/status"))
            return ExecutionResult(cmd, real_status, real_output, real_error)
        except (ConnectionResetError, paramiko.ssh_exception.SSHException):
            raise BadSSHHost("SSH connection to host %s was reset" %
                             (self.hostname, ))
Beispiel #3
0
 def run(self, argv):
     try:
         cmd = " ".join(self.escape(s) for s in argv)
         self.exec_command(cmd)
         out, error, status = self.read_channel()
         if status != 0:
             err("Command %s failed with status %d on host %s" %
                 (cmd, status, self.hostname))
         else:
             debug("Command %s succeeded on host %s, output was %s and %s" %
                   (cmd, self.hostname, out, error))
         return ExecutionResult(cmd, status, out, error)
     except:
         self.client = None
         raise BadSSHHost("SSH connection to host %s was reset" %
                          (self.hostname, ))
Beispiel #4
0
    def run_job(self, file, jobid, timeout=None, env={}):
        try:
            self._connect()

            transport = self.client.get_transport()
            session = transport.open_session()
            paramiko.agent.AgentRequestHandler(session)

            dir = ".cstar/remote-jobs/" + jobid

            self.run(("mkdir", "-p", dir))

            self.put_command(file, "%s/job" % (dir, ))

            # Manually insert environment into script, since passing env into exec_command leads to it being
            # ignored on most ssh servers. :-(

            for key in env:
                if _alnum_re.search(key):
                    raise BadEnvironmentVariable(key)

            # substitute host variables in the command
            env_str = self._substitute_host_variables(" ".join(
                key + "=" + self.escape(value) for key, value in env.items()))

            remote_script = resource_string('cstar.resources',
                                            'scripts/remote_job.sh')
            wrapper = remote_script.decode("utf-8") % (env_str, )
            self.write_command(wrapper, "%s/wrapper" % (dir, ))

            cmd = """
                cd %s
                nohup ./wrapper
                """ % (self.escape(dir), )

            stdin, stdout, stderr = self.client.exec_command(cmd,
                                                             timeout=timeout)
            _, _, _ = self._read_results(stdin, stdout, stderr, timeout)

            real_output = self.read_file(dir + "/stdout")
            real_error = self.read_file(dir + "/stderr")
            real_status = int(self.read_file(dir + "/status"))
            return ExecutionResult(cmd, real_status, real_output, real_error)
        except (ConnectionResetError, paramiko.ssh_exception.SSHException):
            raise BadSSHHost("SSH connection to host %s was reset" %
                             (self.hostname, ))
Beispiel #5
0
    def run(self, argv):
        try:
            self._connect()
            cmd = " ".join(self.escape(s) for s in argv)

            stdin, stdout, stderr = self.client.exec_command(cmd)
            status = stdout.channel.recv_exit_status()
            out = stdout.read()
            error = stderr.read()
            if status != 0:
                err("Command %s failed with status %d on host %s" % (cmd, status, self.hostname))
            else:
                debug("Command %s succeeded on host %s, output was %s and %s" %
                      (cmd, self.hostname, str(out, 'utf-8'), str(error, 'utf-8')))
            return ExecutionResult(cmd, status, str(out, 'utf-8'), str(error, 'utf-8'))
        except (ConnectionResetError, paramiko.ssh_exception.SSHException):
            self.client = None
            raise BadSSHHost("SSH connection to host %s was reset" % (self.hostname,))
Beispiel #6
0
    def __call__(self):
        replaced = self.job.command.replace("{}", self.host.ip)

        # Use subprocess.Popen because subprocess.run is not available in Python 3.4 used by Ubuntu Trusty
        proc = subprocess.Popen(shlex.split(replaced),
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        try:
            outs, errs = proc.communicate()
        except subprocess.TimeoutExpired:
            # The child process is not killed in case of timeout
            proc.kill()
            outs, errs = proc.communicate()
        result = ExecutionResult(replaced, proc.returncode, str(outs, 'utf-8'),
                                 str(errs, 'utf-8'))

        save_output(self.job, self.host, result)
        self.job.results.put((self.host, result))
        return result