Exemple #1
0
    def __init__(self):
        super(Communicator, self).__init__()
        #logger.debug("\n\nCREATING NEW COMMUNICATOR\n%s\n" % traceback.format_exc())
        self.conn = None
        self.parent_module = None
        self.configfile = None

        # module_dict = {'rocci.py':'rocci', 'im_mad.py':'im', 'tm_mad.py':'tm', 'em_mad.py':'em'}
        # #t=repr(traceback.format_stack())
        # trace = traceback.extract_stack()
        # for module_path in trace :
        #     module = basename(module_path[0])
        #     if module in module_dict :
        #         self.parent_module = module_dict[module]
        #         self.configfile = join(DRM4G_DIR, 'etc', 'openssh_%s.conf' % module_dict[module])
        #         break
        self.get_parent_module()

        with self._lock:
            self.agent = Agent()
            self.agent.start()
        self.agent_socket = self.agent.update_agent_env()['SSH_AUTH_SOCK']

        if not Communicator.socket_dir:
            Communicator.socket_dir = join(DRM4G_DIR, 'var', 'sockets')
Exemple #2
0
def run(arg):
    try:
        Daemon().stop()
        agent = Agent()
        if agent.is_alive():
            agent.stop()
    except Exception as err:
        console_logger.error(str(err))
Exemple #3
0
def run(arg):
    try:
        logging.basicConfig(
            format='%(message)s',
            level=logging.DEBUG if arg['--dbg'] else logging.INFO,
            stream=sys.stdout)
        Daemon().stop()
        Agent().stop()
    except KeyboardInterrupt:
        pass
    except Exception as err:
        logging.error(str(err))
Exemple #4
0
def run(arg):

    try:
        # El logger no funcionaba porque el import logging se hace varias veces y coge la primera. Hacemos un reload para que funcione
        # https://stackoverflow.com/questions/20240464/python-logging-file-is-not-working-when-using-logging-basicconfig
        from imp import reload
        reload(logging)
        logging.basicConfig(
            format='%(message)s',
            level=logging.DEBUG if arg['--dbg'] else logging.INFO,
            stream=sys.stdout)

        if not exists(WRF4G_DIR) or arg['--clear-conf']:
            from shutil import copytree, rmtree
            if exists(WRF4G_DIR):
                logging.debug("Removing WRF4G local configuration in '%s'" %
                              WRF4G_DIR)
                rmtree(WRF4G_DIR)
            logging.debug("Creating a WRF4G local configuration in '%s'" %
                          WRF4G_DIR)
            for directory in ['log', 'submission', 'acct']:
                abs_dir = join(WRF4G_DIR, 'var', directory)
                logging.debug("Creating '%s' directory" % abs_dir)
                os.makedirs(abs_dir)

            src = join(WRF4G_DEPLOYMENT_DIR, 'data')
            logging.debug("Coping from '%s' to '%s'" % (src, WRF4G_DIR))
            copy_tree(src, WRF4G_DIR)

            logging.debug('Downloading and extracting data repository')
            r = requests.get(
                'http://personales.gestion.unican.es/fernanqv/repository2.tar.gz'
            )
            open('repository.tar.gz', 'wb').write(r.content)
            tar = tarfile.open('repository.tar.gz')
            tar.extractall(path=WRF4G_DIR)
            tar.close()
            os.remove('repository.tar.gz')

        if arg['--disc-jobs']:
            Daemon().clear()
        else:
            Daemon().start()
        Agent().start()
        # Update database configuration
        with open(DB4G_CONF, 'w') as f:
            f.write(DEFAULT_DB_CONF % {"WRF4G_DIR": WRF4G_DIR})
    except KeyboardInterrupt:
        pass
    except Exception as err:
        logging.error(err)
Exemple #5
0
def run( arg ) :
    try:
        # El logger no funcionaba porque el import logging se hace varias veces y coge la primera. Hacemos un reload para que funcione
        # https://stackoverflow.com/questions/20240464/python-logging-file-is-not-working-when-using-logging-basicconfig
        from imp import reload
        reload(logging)
        logging.basicConfig( format = '%(message)s',
                         level  = logging.DEBUG if arg[ '--dbg' ] else logging.INFO,
                         stream = sys.stdout )
        Daemon().status()
        Agent().status()
    except KeyboardInterrupt :
        pass
    except Exception as err :
        logging.error( str( err ) )
Exemple #6
0
def run(arg):
    try:
        logging.basicConfig(
            format='%(message)s',
            level=logging.DEBUG if arg['--dbg'] else logging.INFO,
            stream=sys.stdout)
        if not exists(WRF4G_DIR) or arg['--clear-conf']:
            from shutil import copytree, rmtree
            if exists(WRF4G_DIR):
                logging.debug("Removing WRF4G local configuration in '%s'" %
                              WRF4G_DIR)
                rmtree(WRF4G_DIR)
            logging.debug("Creating a WRF4G local configuration in '%s'" %
                          WRF4G_DIR)
            for directory in ['log', 'submission', 'acct']:
                abs_dir = join(WRF4G_DIR, 'var', directory)
                logging.debug("Creating '%s' directory" % abs_dir)
                os.makedirs(abs_dir)
            if 'VIRTUAL_ENV' in os.environ.keys():
                deployment_dir = glob.glob(
                    join(WRF4G_DEPLOYMENT_DIR,
                         'lib/python*/site-packages/wrf4g'))[0]
            else:
                deployment_dir = glob.glob(
                    join(WRF4G_DEPLOYMENT_DIR,
                         'local/lib/python*/dist-packages/wrf4g'))[0]
            src = join(deployment_dir, 'etc')
            print src
            dest = join(WRF4G_DIR, 'etc')
            print dest
            logging.debug("Coping from '%s' to '%s'" % (src, dest))
            copytree(src, dest)
        if arg['--disc-jobs']:
            Daemon().clear()
        else:
            Daemon().start()
        Agent().start()
        # Update database configuration
        with open(DB4G_CONF, 'w') as f:
            f.write(DEFAULT_DB_CONF % {"WRF4G_DIR": WRF4G_DIR})
    except KeyboardInterrupt:
        pass
    except Exception as err:
        logging.error(err)
Exemple #7
0
def run(arg):
    try:
        daemon = Daemon()
        if not daemon.is_alive():
            raise Exception('DRM4G is stopped.')
        config = Configuration()
        config.load()
        if config.check():
            raise Exception("Review the configuration of '%s'." %
                            (arg['<resource_name>']))
        if arg['<resource_name>'] not in config.resources:
            raise Exception("'%s' is not a configured resource." %
                            (arg['<resource_name>']))
        lrms = config.resources.get(arg['<resource_name>'])['lrms']
        communicator = config.resources.get(
            arg['<resource_name>'])['communicator']
        if lrms != 'cream' and lrms != 'rocci' and communicator == 'local':
            raise Exception("'%s' does not have an identity to configure." %
                            (arg['<resource_name>']))
        if lrms == 'cream' or lrms == 'rocci':
            comm = config.make_communicators()[arg['<resource_name>']]
            if communicator == 'op_ssh':
                #paramiko will always be used to renew the grid certificate
                config.resources.get(
                    arg['<resource_name>'])['communicator'] = 'pk_ssh'
                comm = config.make_communicators()[arg['<resource_name>']]
            proxy = Proxy(config.resources[arg['<resource_name>']], comm)
            config.resources.get(
                arg['<resource_name>'])['communicator'] = communicator
            config.make_communicators()
        if communicator != 'local':
            agent = Agent(config.resources[arg['<resource_name>']])
        if arg['init']:
            if communicator != 'local':
                agent.start()
                agent.add_key(arg['--lifetime'])
                agent.copy_key()
            if lrms == 'cream' or lrms == 'rocci':
                proxy.configure()
                proxy.create(arg['--lifetime'])
        elif arg['delete']:
            if lrms == 'cream' or lrms == 'rocci':
                proxy.destroy()
            if communicator != 'local':
                agent.delete_key()
        else:
            if communicator != 'local':
                agent.list_key()
            if lrms == 'cream' or lrms == 'rocci':
                proxy.check()
    except Exception as err:
        logger.error(str(err))
Exemple #8
0
def run( arg ) :
    try:
        Daemon().stop()
        Agent().stop()
    except Exception as err :
        logger.error( str( err ) )
Exemple #9
0
def run(arg):
    logging.basicConfig(format='%(message)s',
                        level=logging.DEBUG if arg['--dbg'] else logging.INFO,
                        stream=sys.stdout)
    try:
        daemon = Daemon()
        if not daemon.is_alive():
            raise Exception('DRM4G is stopped.')
        config = Configuration()
        config.load()
        if config.check():
            raise Exception("Review the configuration of '%s'." %
                            (arg['<resource>']))
        if arg['<resource>'] not in config.resources:
            raise Exception("'%s' is not a configured resource." %
                            (arg['<resource>']))
        lrms = config.resources.get(arg['<resource>'])['lrms']
        communicator = config.resources.get(arg['<resource>'])['communicator']
        if lrms != 'cream' and communicator != 'ssh':
            raise Exception("'%s' does not have an identity to configure." %
                            (arg['<resource>']))
        if lrms == 'cream':
            proxy = Proxy(config.resources[arg['<resource>']],
                          config.make_communicators()[arg['<resource>']])
        if communicator == 'ssh':
            agent = Agent(config.resources[arg['<resource>']])
        if arg['init']:
            if communicator == 'ssh':
                agent.start()
                agent.add_key(arg['--lifetime'])
                agent.copy_key()
            if lrms == 'cream':
                proxy.configure()
                proxy.create(arg['--lifetime'])
        elif arg['delete']:
            if lrms == 'cream':
                proxy.destroy()
            if communicator == 'ssh':
                agent.delete_key()
        else:
            if communicator == 'ssh':
                agent.list_key()
            if lrms == 'cream':
                proxy.check()
    except KeyboardInterrupt:
        pass
    except Exception as err:
        logging.error(str(err))
Exemple #10
0
class Communicator(drm4g.communicators.Communicator):
    """
    Create a SSH session to remote resources.
    """
    _lock = __import__('threading').Lock()
    _sem = __import__('threading').Semaphore(SFTP_CONNECTIONS)
    _trans = None

    socket_dir = None

    def __init__(self):
        super(Communicator, self).__init__()
        #logger.debug("\n\nCREATING NEW COMMUNICATOR\n%s\n" % traceback.format_exc())
        self.conn = None
        self.parent_module = None
        self.configfile = None

        # module_dict = {'rocci.py':'rocci', 'im_mad.py':'im', 'tm_mad.py':'tm', 'em_mad.py':'em'}
        # #t=repr(traceback.format_stack())
        # trace = traceback.extract_stack()
        # for module_path in trace :
        #     module = basename(module_path[0])
        #     if module in module_dict :
        #         self.parent_module = module_dict[module]
        #         self.configfile = join(DRM4G_DIR, 'etc', 'openssh_%s.conf' % module_dict[module])
        #         break
        self.get_parent_module()

        with self._lock:
            self.agent = Agent()
            self.agent.start()
        self.agent_socket = self.agent.update_agent_env()['SSH_AUTH_SOCK']

        if not Communicator.socket_dir:
            Communicator.socket_dir = join(DRM4G_DIR, 'var', 'sockets')

    def get_parent_module(self):
        module_dict = {
            'rocci.py': 'rocci',
            'im_mad.py': 'im',
            'tm_mad.py': 'tm',
            'em_mad.py': 'em'
        }
        #t=repr(traceback.format_stack())
        trace = traceback.extract_stack()
        for module_path in trace:
            module = basename(module_path[0])
            if module in module_dict:
                self.parent_module = module_dict[module]
                self.configfile = join(DRM4G_DIR, 'etc',
                                       'openssh_%s.conf' % self.parent_module)
                break
            else:
                #if it's none of the other modules but it's still calling Configuration().make_communicators
                #it has to be from commands/__init__.py's check_frontends() being called from commands/resource.py
                #for which we had decided the 'im' socket would be used
                self.parent_module = 'im'
                self.configfile = join(DRM4G_DIR, 'etc',
                                       'openssh_%s.conf' % self.parent_module)

    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)

    def connect(self):
        """
        To establish the connection to resource.
        """
        try:
            p_module = sys._getframe().f_back.f_code.co_filename
            p_function = sys._getframe().f_back.f_code.co_name
            t = repr(traceback.format_stack())
            #for line in t:
            #    print line

            #logger.debug("Running connect function\n    - called from "+p_module+"\n    - by function "+p_function)
            logger.debug(
                "\n\nRunning connect function from %s\n    - called from %s\n    - by function %s\nTraceback :\n%s\n"
                % (self.parent_module, p_module, p_function, t))
            #logger.debug("\np_module = %s\np_function = %s\n" % (p_module, p_function))

            if not self.configfile:
                logger.debug("Variable 'self.configfile' is not defined")
                logger.error(
                    "OpenSHH configuration file's path is not defined")

            if not exists(self.configfile):
                self.createConfFiles()
            logger.debug("The socket " + join(
                Communicator.socket_dir, '%s-%s@%s:%s' %
                (self.parent_module, self.username, self.frontend,
                 self.port)) + " existance is " + str(
                     exists(
                         join(
                             Communicator.socket_dir, '%s-%s@%s:%s' %
                             (self.parent_module, self.username, self.frontend,
                              self.port)))))

            if not exists(
                    join(
                        Communicator.socket_dir, '%s-%s@%s:%s' %
                        (self.parent_module, self.username, self.frontend,
                         self.port))):
                logger.debug(
                    "No master conncection exists for %s so a new one will be created"
                    % self.parent_module)

                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))

                t = threading.Thread(target=first_ssh, args=())
                t.daemon = True
                logger.debug("Starting thread with first_ssh")
                t.start()
                time.sleep(
                    5
                )  #so that there's time to make the first connection in case there was an error

            if self.conn == None:
                logger.debug("No conn exists (conn == " + str(self.conn) +
                             ") for " + self.parent_module +
                             " so a new one will be created.")
                self.conn = SSHConnection(self.frontend,
                                          login=self.username,
                                          port=str(self.port),
                                          configfile=self.configfile,
                                          identity_file=self.private_key,
                                          ssh_agent_socket=self.agent_socket,
                                          timeout=SSH_CONNECT_TIMEOUT)

            logger.debug("Ending connect function from %s" %
                         self.parent_module)

        except Exception as excep:
            if "too long for Unix domain socket" in str(excep):
                logger.debug(
                    "Socket path was too long for Unix domain socket.\n    Creating sockets in ~/.ssh/dmr4g.\n    Exception captured in connect's except."
                )
                self._change_socket_dir()
                self.connect()
            else:
                logger.error(str(excep))
                raise

    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))

    def mkDirectory(self, url):
        try:
            logger.debug("Running mkDirectory function from %s" %
                         self.parent_module)
            to_dir = self._set_dir(urlparse(url).path)
            stdout, stderr = self.execCommand("mkdir -p %s" % to_dir)
            if stderr:
                logger.warning("Could not create %s directory: %s" %
                               (to_dir, stderr))
            logger.debug("Ending mkDirectory function from %s" %
                         self.parent_module)
        except Exception as excep:
            if "disabling multiplexing" in str(excep):
                logger.debug(
                    "Mux isn't working from the mkDirectory function. Eliminating "
                    + self.parent_module + "'s socket file.")
                self._delete_socket()
                self.mkDirectory(url)
            else:
                logger.warning(str(excep))

    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))

    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))

    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)

    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))

    #internal
    def _set_dir(self, path):
        logger.debug("Running _set_dir function from %s" % self.parent_module)
        work_directory = re.compile(r'^~').sub(self.work_directory, path)
        logger.debug("Ending _set_dir function from %s" % self.parent_module)
        return work_directory

    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)

    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

    def get_env(self):
        """
        Retrieve environment variables and replace SSH_AUTH_SOCK
        if ssh_agent_socket was specified on object creation.
        """
        logger.debug("Running get_env function from %s" % self.parent_module)
        env = os.environ.copy()
        if self.agent_socket:
            env['SSH_AUTH_SOCK'] = self.agent_socket
        logger.debug("Ending get_env function from %s" % self.parent_module)
        return env