示例#1
0
 def copy_flash(self):
     """Copy output/error to the flash directory. Return the filenames."""
     prof = self.prof
     cfg = self._host_config
     flashcoll = prof.get_type('flash')
     assert len(flashcoll) > 0
     flash = flashcoll[0]
     self.run.MkDir(flash.repr(), niverr='SILENT', verbose=True)
     df = {}
     for typ in ('output', 'error', 'export'):
         fname = FileName(self.flash(typ))
         if not is_localhost2(self.host):
             fname.user = prof['username'][0]
             fname.host = prof['serveur'][0]
         else:
             fname.path = osp.join(get_home_directory(), fname.path)
         df[typ] = fname
     if cfg['result_on_client']:
         lf = [fname.repr() for fname in df.values()]
         self.run.Copy(flash.path, niverr='<A>_ALARM', *lf)
     else:
         cmd = 'mv -f %s %s'
         for fname in df.values():
             self.run.Shell(cmd % (fname.path, flash.path),
                            mach=self.prof['serveur'][0],
                            user=prof['username'][0])
     return df
示例#2
0
 def __init__(self, host, user, **kwargs):
     """Initialization"""
     self.host = host or local_host
     self.user = user or local_user
     self._is_localhost = is_localhost2(self.host, self.user)
     magic.log.info("BaseServer init  host=%s   user=%s", self.host,
                    self.user)
示例#3
0
 def Ping(self, mach='', timeout=2):
     """Return True if 'mach' is responding.
     """
     if is_localhost2(mach):
         return True
     iret, output = self.Shell(command['ping'] % {
         'host': mach,
         'timeout': timeout
     })
     return iret == 0
示例#4
0
    def Shell(self, cmd, mach='', user='', **opts):
        """Execute a command shell on local or remote machine.
        Options : see local_shell
        """
        #TODO use list type
        if type(cmd) in (list, tuple):
            cmd = ' '.join(cmd)
        iret = 1
        # valeurs par défaut
        kargs = {
            'verbose': self.verbose,
            'bg': False,
            'interact': False,
            'follow_output': False,
            'alt_comment': cmd,
            'timeout': None,
            'display_forwarding': False,
        }
        # surcharge par opts
        kargs.update(opts)

        proto = self.param['remote_shell_protocol']

        # distant ?
        user = user or local_user
        distant = not is_localhost2(mach, user=user)
        self._dbg('remote command (%s <> %s and %s <> %s) ? %s' %
                  (mach, local_host, user, local_user, distant))

        if not distant:
            result = self.local_shell(cmd, **kargs)
        else:
            action = ''
            # pour recuperer correctement l'output, il faut des " et non des ' autour des
            # commandes sous "sh -c" et sous "xterm -e"
            if cmd.find('"') != -1:
                cmd = cmd.replace('"', '\\"')
            cmd = '"%s"' % cmd
            if proto == 'RSH':
                action = 'rsh -n -l ' + user + ' ' + mach + ' ' + cmd
            #elif proto == 'SSH': is the default
            else:
                options = "-n -o StrictHostKeyChecking=no -o BatchMode=yes"
                if kargs['timeout']:
                    options += " -o 'ConnectTimeout=%s'" % kargs["timeout"]
                if kargs['display_forwarding']:
                    options += " -X"
                action = "ssh %(options)s -l %(user)s %(host)s %(command)s" % {
                    "user": user,
                    "host": mach,
                    "command": cmd,
                    "options": options,
                }
            result = self.local_shell(action, **kargs)
        return result
示例#5
0
def build_server(classname, host, user, **kwargs):
    """Build a server calling the specified protocol class.
    the argument type is necessary to choose a LocalServer variant.
    """
    path = classname.split('.')
    if is_localhost2(host, user=user) and kwargs.get('type') is not None:
        magic.log.info("'%s' is the local host", host)
        if kwargs['type'] in (TYPES.COPY_TO, TYPES.COPY_FROM):
            sclass = LocalCopyServer
        else:
            sclass = LocalExecServer
    elif globals().get(path[-1]):
        sclass = globals()[path[-1]]
    else:
        # external server type
        sclass = get_plugin(classname)
    magic.log.debug("create %s with %s, %s, %s", sclass, host, user, kwargs)
    return sclass(host, user, **kwargs)
示例#6
0
def Del(run, *args, **kwargs):
    """Kill a job and delete related files.
    """
    if len(args) < 3:
        run.parser.error(_(u"'--%s' takes at least %d arguments (%d given)") % \
            (run.current_action, 3, len(args)))
    elif len(args) > 4:
        run.parser.error(_(u"'--%s' takes at most %d arguments (%d given)") % \
            (run.current_action, 4, len(args)))

    # 0. arguments
    njob, nomjob, mode = args[:3]
    if len(args) > 3:
        node = args[3]
    else:
        node = ''
    sent_signal = run['signal']
    if kwargs.get('signal'):
        sent_signal = kwargs['signal']
    delete_files = sent_signal == 'KILL'

    use_batch_cmd = False
    scheduler = None
    if mode == 'batch':
        scheduler = BatchSystemFactory(run)
        use_batch_cmd = sent_signal == 'KILL' or scheduler.supports_signal()

    # 1. retrieve the job status
    etat, diag, node, tcpu, wrk, queue = Func_actu(run, njob, nomjob, mode)
    run.DBG(u"actu returns : etat/diag/node/tcpu/wrk/queue",
            (etat, diag, node, tcpu, wrk, queue))

    # 2. send the signal
    if etat in ('RUN', 'SUSPENDED', 'PEND'):
        if use_batch_cmd:
            iret = scheduler.signal_job(njob, sent_signal)
            if iret != 0:
                run.Sortie(4)
        else:
            numpr, psout = '', ''
            # get process id
            if node == '_':
                # try on localhost
                node = ''
            if node != '_':
                jret, psout = run.Shell(run['ps_pid'], mach=node)
                exp = re.compile('^ *([0-9]+) +(.*)\-\-num_job=%s.*\-\-mode=%s' \
                        % (njob, mode), re.MULTILINE)
                res = exp.findall(psout)
                res.reverse()  # the relevant process should be the last one
                run.DBG(u"processes :", res)
                for numj, cmd in res:
                    # "sh -c" is automatically added by os.system
                    if cmd.find(shell_cmd) < 0 and cmd.find("sh -c") < 0:
                        numpr = int(numj)
                        run.DBG(u"Signal will be sent to process : %s" % numpr)
                        break
                if numpr == '':
                    # try to kill its as_run parent (but USR1 will not stop as_run)
                    sent_signal = 'KILL'
                    exp = re.compile('^ *([0-9]+) +(.*as_run.*\-\-num_job=+%s.*)' \
                            % njob, re.M)
                    res = exp.findall(psout)
                    res.reverse(
                    )  # the relevant process should be the last one
                    run.DBG(u"as_run processes :", res)
                    for numj, cmd in res:
                        # python run by bin/as_run
                        if cmd.find('python') > -1:
                            numpr = int(numj)
                            run.DBG(u"Signal will be sent to process : %s" %
                                    numpr)
                            break
            if numpr != '':
                if is_localhost2(node):
                    os.kill(numpr, getattr(signal, 'SIG%s' % sent_signal))
                else:
                    iret, psout = run.Shell('kill -%s %s' %
                                            (sent_signal, numpr),
                                            mach=node)
            else:
                run.DBG(u'<job.Del> process not found :',
                        psout,
                        u'node = %s' % node,
                        all=True)

    # 3. delete files
    if delete_files:
        l_fich = glob.glob(osp.join(run['flasheur'],
                                    '%s.?%s' % (nomjob, njob)))
        for f in l_fich:
            run.Delete(f)
示例#7
0
 def IsRemote(self, path):
     """Return True if 'path' seems to be on a remote host.
     NB : we suppose that host and host.domain are identical.
     """
     dico = self.filename2dict(path)
     return not is_localhost2(dico["mach"])
示例#8
0
    def soumbtc_interactif(self, fbtc):
        """Run btc in interactive mode.
        """
        self.jobid = self.pid
        # commandes
        cmd_batch = '%(fbtc)s 1> %(output)s 2> %(error)s'
        cmd_interactif = '%(fbtc)s 2> %(error)s | tee %(output)s'

        node = self.dict_info['node']
        dico = {
            'fbtc': fbtc,
            'output': self.flash('output'),
            'error': self.flash('error'),
        }
        # follow output or not
        xterm = ''
        if self.prof['follow_output'][0] in YES_VALUES:
            xterm = self.run['terminal']

        if self.prof['depart'][0] != '' or xterm == '':
            cmd = cmd_batch % dico
        else:
            cmd = cmd_interactif % dico

        # delayed start
        if self.prof['depart'][0] != '':
            cmd = "echo '%s' | at %s" % (cmd, self.prof['depart'][0])
        elif xterm != '':
            if re.search('@E', xterm) == None:
                xterm = xterm + ' -e @E'
            cmd = xterm.replace('@E', '%s "%s"' % (shell_cmd, cmd))

        # run on another node
        distant = not is_localhost2(node)

        if not distant:
            # check xterm command
            if xterm != '':
                term = xterm.split()[0]
                if not os.access(term, os.X_OK):
                    print3(_(u"Not an executable : %s") % term)
                    return 7, '', 'unknown'
        else:
            # check node connection
            iret, output = self.run.Shell('echo hello', mach=node)
            if output.find('hello') < 0:
                print3(output)
                print3(
                    _(u"Connection failure to %s (from %s)") %
                    (node, self.prof['serveur'][0]))
                return 6, '', 'unknown'

        # background is not possible if display forwarding is required
        # (the connection must stay alive)
        need_display = xterm != ''
        background = (not need_display) \
            or same_hosts2(self.prof['mclient'][0], node,
                           self.prof['uclient'][0], self.prof['username'][0])
        kret, output = self.run.Shell(cmd,
                                      mach=node,
                                      bg=background,
                                      display_forwarding=need_display)

        return 0, self.jobid, 'interactif'