Exemplo n.º 1
0
    def remote_scp(self, files, target):
        logger.debug("Running remote_scp function from %s" %
                     self.parent_module)
        scp_command = self.scp_command(files, target)
        pipe = subprocess.Popen(scp_command,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                env=self.get_env())

        signal.alarm(SSH_CONNECT_TIMEOUT)
        err = ''
        try:
            _, err = pipe.communicate()
        except IOError as exc:
            #pipe.terminate() # only in python 2.6 allowed
            os.kill(pipe.pid, signal.SIGTERM)
            signal.alarm(0)  # disable alarm
            logger.warning("%s (under %s): %s" %
                           (' '.join(scp_command), self.username, str(exc)))
        signal.alarm(0)  # disable alarm
        returncode = pipe.returncode
        if returncode != 0:  # ssh client error
            logger.warning("%s (under %s): %s" %
                           (' '.join(scp_command), self.username, err.strip()))
        logger.debug("Ending remote_scp function from %s" % self.parent_module)
Exemplo n.º 2
0
Arquivo: ssh.py Projeto: cofinoa/DRM4G
 def close(self):
     try:
         if self._trans:
             self._trans.close()
     except Exception as err:
         logger.warning("Could not close the SSH connection to '%s': %s" %
                        (self.frontend, str(err)))
Exemplo n.º 3
0
    def scp_command(self, files, target, debug=False):
        """
        Build the command string to transfer the files identified by filenames.
        Include target(s) if specified. Internal function
        """
        logger.debug("Running scp_command function from %s" %
                     self.parent_module)
        cmd = ['scp', debug and '-vvvv' or '-q', '-r']

        if self.username:
            remotename = '%s@%s' % (self.username, self.frontend)
        else:
            remotename = self.frontend
        if self.configfile:
            cmd += ['-F', self.configfile]
        if self.private_key:
            cmd += ['-i', self.private_key]
        if self.port:
            cmd += ['-P', str(self.port)]

        if not isinstance(files, list):
            logger.warning(
                '"files" argument has to be an iterable (list or tuple)')
        if len(files) < 1:
            logger.warning('You should name at least one file to copy')

        for f in files:
            cmd.append('%s:%s' % (remotename, f))
        cmd.append(target)
        logger.debug("The command is " + str(cmd))
        logger.debug("Ending scp_command function from %s" %
                     self.parent_module)
        return cmd
Exemplo n.º 4
0
 def copy(self, source_url, destination_url, execution_mode=''):
     try:
         logger.debug("Running copy function from %s" % self.parent_module)
         if not self.conn:
             self.connect()
         with self._sem:
             if 'file://' in source_url:
                 from_dir = urlparse(source_url).path
                 to_dir = self._set_dir(urlparse(destination_url).path)
                 self.conn.scp([from_dir], target=to_dir)
                 if execution_mode == 'X':
                     stdout, stderr = self.execCommand("chmod +x %s" %
                                                       to_dir)
                     if stderr:
                         logger.warning(
                             "Could not change access permissions of %s file: %s"
                             % (to_dir, stderr))
             else:
                 from_dir = self._set_dir(urlparse(source_url).path)
                 to_dir = urlparse(destination_url).path
                 self.remote_scp([from_dir], target=to_dir)
         logger.debug("Ending copy function from %s" % self.parent_module)
     except Exception as excep:
         if "disabling multiplexing" in str(excep):
             logger.debug(
                 "Mux isn't working from the copy function. Eliminating " +
                 self.parent_module + "'s socket file.")
             self._delete_socket()
             self.copy(source_url, destination_url)
         else:
             logger.warning(str(excep))
Exemplo n.º 5
0
    def createConfFiles(self):
        logger.debug("Running createConfFiles function from %s" %
                     self.parent_module)
        #the maximum length of the path of a unix domain socket is 108 on Linux, 104 on Mac OS X
        conf_text = ("Host *\n"
                     "    ControlMaster auto\n"
                     "    ControlPath %s/%s-%s\n"
                     "    ControlPersist 10m\n"
                     "    StrictHostKeyChecking no")

        for manager in ['im', 'tm', 'em', 'rocci']:
            with io.FileIO(join(DRM4G_DIR, 'etc', 'openssh_%s.conf' % manager),
                           'w') as conf_file:
                conf_file.write(conf_text %
                                (Communicator.socket_dir, manager, '%r@%h:%p'))
        try:
            if not exists(Communicator.socket_dir):
                logger.debug("Creating socket directory in %s" %
                             Communicator.socket_dir)
                os.makedirs(Communicator.socket_dir)
        except OSError as excep:
            if "File exists" in str(excep):
                logger.warning("The directory %s already exists" %
                               Communicator.socket_dir)
            else:
                logger.error("An unexpected exception ocurred:\n" + str(excep))
        logger.debug("Ending createConfFiles function from %s" %
                     self.parent_module)
Exemplo n.º 6
0
                def first_ssh():
                    try:
                        logger.debug(
                            "Running first_ssh function\n    - Creating first connection for %s"
                            % self.parent_module)
                        #this is here because the threads are created at the same time, so the moment one creates the conection, the rest are going to cause an UnboundLocalError exception
                        #(which probably shouldn't be ocurring since ControlMaster is set to auto - only if they execute this at the same time)
                        if not exists(
                                join(
                                    Communicator.socket_dir, '%s-%s@%s:%s' %
                                    (self.parent_module, self.username,
                                     self.frontend, self.port))):
                            command = 'ssh -F %s -i %s -p %s -T %s@%s' % (
                                self.configfile, self.private_key,
                                str(self.port), self.username, self.frontend)
                        pipe = subprocess.Popen(command.split(),
                                                stdin=subprocess.PIPE,
                                                stdout=subprocess.PIPE,
                                                stderr=subprocess.PIPE)
                        out, err = pipe.communicate()

                        if err:
                            if "too long for Unix domain socket" in str(
                                    err) or "ControlPath too long" in str(err):
                                logger.debug(
                                    "Socket path was too long for Unix domain socket.\n    Creating sockets in ~/.ssh/dmr4g.\n    Exception captured in first_ssh."
                                )
                                self._change_socket_dir()
                                logger.debug(
                                    "Calling first_ssh once again, but with a new socket_dir"
                                )
                                first_ssh()
                            elif "disabling multiplexing" in str(err):
                                logger.debug(
                                    "connect function: The multiplexing of connections isn't working. Eliminating "
                                    + self.parent_module + "'s socket file.")
                                self._delete_socket()
                                first_ssh()
                            elif "bind: No such file or directory" in str(
                                    err) or "cannot bind to path" in str(err):
                                logger.debug(
                                    "The connection through the socket %s-%s@%s:%s wasn't established since the socket directory %s hasn't been created yet."
                                    % (self.parent_module, self.username,
                                       self.frontend, self.port,
                                       Communicator.socket_dir))
                                self.createConfFiles()
                                first_ssh()
                            else:
                                logger.debug(
                                    "Unexpected error occured while running first_ssh:\n"
                                    + str(err))
                                logger.warning(str(err))
                    except UnboundLocalError as err:
                        logger.warning(
                            "Local variable referenced before assignment")
                        logger.debug(str(err))
Exemplo n.º 7
0
Arquivo: ssh.py Projeto: cofinoa/DRM4G
 def copy(self, source_url, destination_url, execution_mode=''):
     with self._sem:
         self.connect()
         scp = SCPClient(self._trans)
         if 'file://' in source_url:
             from_dir = urlparse(source_url).path
             to_dir = self._set_dir(urlparse(destination_url).path)
             scp.put(from_dir, to_dir)
             if execution_mode == 'X':
                 stdout, stderr = self.execCommand("chmod +x %s" % to_dir)
         else:
             from_dir = self._set_dir(urlparse(source_url).path)
             to_dir = urlparse(destination_url).path
             logger.warning("%s , %s" % (from_dir, to_dir))
             scp.get(from_dir, to_dir)
Exemplo n.º 8
0
 def _change_socket_dir(self):
     logger.debug("Running _change_socket_dir function from %s" %
                  self.parent_module)
     try:
         if exists(Communicator.socket_dir):
             os.rmdir(Communicator.socket_dir)
     except OSError as excep:
         if "No such file or directory" in str(excep):
             logger.debug(
                 "The old socket directory %s has already been deleted" %
                 Communicator.socket_dir)
         else:
             logger.warning(str(excep))
     Communicator.socket_dir = join(expanduser('~'), '.ssh/drm4g')
     self.createConfFiles()
     logger.debug("Ending _change_socket_dir function from %s" %
                  self.parent_module)
Exemplo n.º 9
0
 def _delete_socket(self):
     try:
         logger.debug("Running _delete_socket function from %s" %
                      self.parent_module)
         os.remove("%s/%s-%s@%s:%s" %
                   (Communicator.socket_dir, self.parent_module,
                    self.username, self.frontend, str(self.port)))
         logger.debug("Ending _delete_socket function from %s" %
                      self.parent_module)
     except OSError as excep:
         if "No such file or directory" in str(excep):
             logger.debug("The socket %s/%s-%s@%s:%s does not exist" %
                          (Communicator.socket_dir, self.parent_module,
                           self.username, self.frontend, str(self.port)))
             logger.debug("Ending _delete_socket function from %s" %
                          self.parent_module)
         else:
             logger.warning(str(excep))
Exemplo n.º 10
0
 def rmDirectory(self, url):
     try:
         logger.debug("Running rmDirectory function from %s" %
                      self.parent_module)
         to_dir = self._set_dir(urlparse(url).path)
         stdout, stderr = self.execCommand("rm -rf %s" % to_dir)
         if stderr:
             logger.warning("Could not remove %s directory: %s" %
                            (to_dir, stderr))
         logger.debug("Ending rmDirectory function from %s" %
                      self.parent_module)
     except Exception as excep:
         if "disabling multiplexing" in str(excep):
             logger.debug(
                 "Mux isn't working from the rmDirectory function. Eliminating "
                 + self.parent_module + "'s socket file.")
             self._delete_socket()
             self.rmDirectory(url)
         else:
             logger.warning(str(excep))
Exemplo n.º 11
0
    def execCommand(self, command, input=None):
        try:
            logger.debug("Running execCommand function from " +
                         self.parent_module +
                         "\n    - Trying to execute command " + str(command))

            if not self.conn:
                logger.debug(
                    "Going to run connect function.\n    - That should already have been done, so it shouldn't do anything."
                )
                self.connect()

            ret = self.conn.run(command)
            logger.debug("Ending execCommand function.")
            return ret.stdout, ret.stderr
        except Exception as excep:
            if "disabling multiplexing" in str(excep):
                logger.debug(
                    "Mux isn't working from the execCommand function. Eliminating "
                    + self.parent_module + "'s socket file.")
                self._delete_socket()
                self.execCommand(command, input)
            else:
                logger.warning(str(excep))
Exemplo n.º 12
0
Arquivo: ssh.py Projeto: cofinoa/DRM4G
    def connect(self):
        try:
            with self._lock:
                if not self._trans or not self._trans.is_authenticated():
                    logger.debug("Opening ssh connection ... ")
                    keys = None
                    logger.debug("Trying ssh-agent ... ")
                    drm4g_agent = drm4g.commands.Agent()
                    drm4g_agent.start()
                    drm4g_agent.update_agent_env()
                    # paramiko agent
                    agent = Agent()
                    keys = agent.get_keys()
                    if not keys:
                        logger.debug("Error trying to connect to '%s'" %
                                     self.frontend)
                        logger.debug(
                            "Impossible to load '%s' key from the ssh-agent" %
                            self.private_key)
                        try:
                            status_ssh_agent = agent._conn
                        except Exception as err:
                            logger.warning(
                                "Probably you are using paramiko version <= 1.7.7.2 : %s "
                                % err)
                            status_ssh_agent = agent.conn
                        if not status_ssh_agent:
                            logger.warning("'ssh-agent' is not running")
                        else:
                            if agent.get_keys():
                                logger.warning(
                                    "ssh-agent is running but none of the keys have been accepted"
                                    "by remote frontend %s." % self.frontend)
                            else:
                                logger.debug(
                                    "'ssh-agent' is running but without any keys"
                                )
                    if self.private_key:
                        logger.debug("Trying '%s' key ... " % self.private_key)
                        private_key_path = expanduser(self.private_key)
                        if (not exists(private_key_path)) and (
                                not 'PRIVATE KEY' in self.private_key):
                            output = "'%s'key does not exist" % private_key_path
                            raise ComException(output)
                        for pkey_class in (RSAKey, DSSKey):
                            try:
                                if 'PRIVATE KEY' in self.private_key:
                                    import StringIO
                                    key = pkey_class.from_private_key(
                                        StringIO.StringIO(
                                            self.private_key.strip("'")))
                                else:
                                    key = pkey_class.from_private_key_file(
                                        private_key_path)
                                keys = keys + (key, )
                            except Exception:
                                pass
                    if not keys:
                        output = "Impossible to load any keys"
                        logger.error(output)
                        raise ComException(output)

                    for key in keys:
                        try:
                            sock = socket.socket()
                            try:
                                sock.settimeout(SSH_CONNECT_TIMEOUT)
                            except:
                                output = "Timeout trying to connect to '%s'" % self.frontend
                                raise ComException(output)
                            logger.debug(
                                "Connecting to '%s' as user '%s' port  '%s' ..."
                                % (self.frontend, self.username, self.port))
                            if ':' in self.frontend:
                                self.frontend, self.port = self.frontend.split(
                                    ':')
                            sock.connect((self.frontend, self.port))
                            self._trans = Transport(sock)
                            self._trans.connect(username=self.username,
                                                pkey=key)
                            if self._trans.is_authenticated():
                                break
                        except socket.gaierror:
                            output = "Could not resolve hostname '%s' " % self.frontend
                            raise ComException(output)
                        except Exception as err:
                            logger.warning("Error connecting '%s': %s" %
                                           (self.frontend, str(err)))
                if not self._trans:
                    output = "Authentication failed for '%s'. Try to execute `ssh -vvv -p %d %s@%s` and see the response." % (
                        self.frontend, self.port, self.username, self.frontend)
                    raise ComException(output)
        except ComException:
            raise
        except Exception as err:
            if "No handlers could be found for logger" in str(err):
                raise Exception(
                    "The connect function is the one causing problems : %s" %
                    str(err))
            else:
                raise