1# -*- coding: utf-8 -*-
2
3# ==============================================================================
4# COPYRIGHT (C) 1991 - 2015  EDF R&D                  WWW.CODE-ASTER.ORG
5# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8# (AT YOUR OPTION) ANY LATER VERSION.
9#
10# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
14#
15# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
18# ==============================================================================
19
20"""
21This module defines the old server types :
22    - RSH to execute commands on a remote server,
23    - RCP to copy files to and from a remote server.
24
25Note that these servers types are deprecated and are present only
26for backward compatibility.
27"""
28
29
30import os.path as osp
31
32from asrun.common.i18n import _
33from asrun.core        import magic
34from asrun.core.server import ( ExecServer, CopyFromServer, CopyToServer,
35                                local_shell )
36
37
38class RSHServer(ExecServer):
39    """Definition of a RSH server."""
40
41    def __init__(self, host, user, **kwargs):
42        """Initialization"""
43        magic.log.debug("RSHServer init")
44        super(RSHServer, self).__init__(host, user, **kwargs)
45
46    def support_display_forwarding(self):
47        """Tell if the protocol supports display forwarding."""
48        return True
49
50    def _exec_command(self, command, display_forwarding=False, **opts):
51        """Execute a command line on the server."""
52        cmd = [ "rsh",
53                "-n",
54                "-l", self.user,
55                self.host ]
56        #XXX append command as string and enclosed by ' or " (escape ' or " in command)
57        if type(command) not in (list, tuple):
58            command = [command, ]
59        cmd.extend(command)
60        res = local_shell(cmd)
61        return res
62
63
64class RCPServer(RSHServer, CopyToServer, CopyFromServer):
65    """Definition of a RCP server."""
66
67    def _create_dir(self, directory):
68        """Create a directory on the server."""
69        dico = { 'dir' : directory }
70        magic.log.info(_("create remote directory %(dir)s...") % dico)
71        cmd = "mkdir -p %(dir)s" % dico
72        res = self._exec_command(cmd)
73        cmd = "chmod 0700 %(dir)s" % dico
74        res = self._exec_command(cmd)
75        magic.log.info(_("returns %s"), res[0])
76        return res
77
78    def delete_proxy_dir(self):
79        """Erase the proxy_dir directory on the server."""
80        cmd = "rm -rf %s" % self.proxy_dir
81        magic.log.info(_("delete remote directory %s..."), self.proxy_dir)
82        res = self._exec_command(cmd)
83        magic.log.info(_("returns %s"), res[0])
84        return res
85
86    def _copyoneto(self, src, convert=None):
87        """Copy the file `srcto a server.
88        Return 0 or >0 if it failed.
89        `convert` is the function used to compute basename = f(convert).
90        """
91        bname = osp.basename(src)
92        if convert is not None:
93            bname = convert(src)
94        dst = osp.join(self.proxy_dir, bname)
95        dst = self.user + "@" +  self.host + ":" + dst
96        cmd = [ "rcp", "-r", src, dst]
97        magic.log.info(_("copy %s to %s"), src, dst)
98        res = local_shell(cmd)
99        magic.log.info(_("returns %s"), res[0])
100        if res[2]:
101            magic.log.error(res[2])
102        return res[0]
103
104    def _copyonefrom(self, dst, convert=None):
105        """Copy the file `dstfrom a server.
106        Return 0 or >0 if it failed.
107        `convert` is the function used to compute basename = f(convert).
108        Example : dst=/home/user/dir/fname
109            => rcp -r log@mach:`self.proxy_dir`/fname /home/user/fname
110
111        Warning: to avoid to create /home/user/dir/fname/fname when
112        fname is a directory, we execute:
113            => rcp -r log@mach:`self.proxy_dir`/fname /home/user/dir/
114        """
115        bname = osp.basename(dst)
116        if convert is not None:
117            bname = convert(dst)
118        src = osp.join(self.proxy_dir, bname)
119        fsrc = self.user + "@" +  self.host + ":" + src
120        cmd = [ "rcp", "-r", fsrc, dst]
121        magic.log.info(_("copy %s to %s"), fsrc, dst)
122        res = local_shell(cmd)
123        magic.log.info(_("returns %s"), res[0])
124        if res[2]:
125            magic.log.error(res[2])
126        return res[0]
127