source: fedd/federation/proxy_segment.py @ 4e00f7c

axis_examplecompt_changesinfo-opsversion-3.01version-3.02
Last change on this file since 4e00f7c was d3c8759, checked in by Ted Faber <faber@…>, 15 years ago

Wholesale change of IOError to EnvironmentError? for file operations. Lots of
uncaught EnvironmentErrors? were causing spurious error conditions, e.g. on disk
full.

  • Property mode set to 100644
File size: 2.5 KB
Line 
1#!/usr/local/bin/python
2
3import sys, os
4import re
5
6import tempfile
7import subprocess
8import logging 
9import time
10import signal
11
12from service_error import service_error
13
14class proxy_segment:
15    class ssh_cmd_timeout(RuntimeError): pass
16
17    def __init__(self, log=None, keyfile=None, debug=False):
18        self.log = log or logging.getLogger(\
19                'fedd.access.proxy_segment')
20        self.ssh_privkey_file = keyfile
21        self.debug = debug
22        self.ssh_exec="/usr/bin/ssh"
23        self.scp_exec = "/usr/bin/scp"
24        self.ssh_cmd_timeout = proxy_segment.ssh_cmd_timeout
25
26    def scp_file(self, file, user, host, dest=""):
27        """
28        scp a file to the remote host.  If debug is set the action is only
29        logged.
30        """
31
32        scp_cmd = [self.scp_exec, '-o', 'IdentitiesOnly yes', 
33                '-o', 'StrictHostKeyChecking no', '-o', 'ForwardX11 no','-i', 
34                self.ssh_privkey_file, file, 
35                "%s@%s:%s" % (user, host, dest)]
36        rv = 0
37
38        try:
39            dnull = open("/dev/null", "w")
40        except EnvironmentError:
41            self.log.debug("[ssh_file]: failed to open " + \
42                    "/dev/null for redirect")
43            dnull = Null
44
45        self.log.debug("[scp_file]: %s" % " ".join(scp_cmd))
46        if not self.debug:
47            rv = subprocess.call(scp_cmd, stdout=dnull, 
48                    stderr=dnull, close_fds=True)
49
50        return rv == 0
51
52    def ssh_cmd(self, user, host, cmd, wname=None, timeout=None):
53        """
54        Run a remote command on host as user.  If debug is set, the action
55        is only logged.  Commands are run without stdin, to avoid stray
56        SIGTTINs.
57        """
58        sh_str = ("%s -n -o 'IdentitiesOnly yes' -o " + \
59                "'StrictHostKeyChecking no' -o 'ForwardX11 no' " +
60                "-i %s %s@%s %s") % \
61                (self.ssh_exec, self.ssh_privkey_file, 
62                        user, host, cmd)
63
64        try:
65            dnull = open("/dev/null", "w")
66        except EnvironmentError:
67            self.log.debug("[ssh_cmd]: failed to open /dev/null " + \
68                    "for redirect")
69            dnull = Null
70
71        self.log.debug("[ssh_cmd]: %s" % sh_str)
72        if not self.debug:
73            if dnull:
74                sub = subprocess.Popen(sh_str, shell=True, stdout=dnull,
75                        stderr=dnull, close_fds=True)
76            else:
77                sub = subprocess.Popen(sh_str, shell=True, close_fds=True)
78            if timeout:
79                i = 0
80                rv = sub.poll()
81                while i < timeout:
82                    if rv is not None: break
83                    else:
84                        time.sleep(1)
85                        rv = sub.poll()
86                        i += 1
87                else:
88                    self.log.debug("Process exceeded runtime: %s" % sh_str)
89                    os.kill(sub.pid, signal.SIGKILL)
90                    raise self.ssh_cmd_timeout();
91                return rv == 0
92            else:
93                return sub.wait() == 0
94        else:
95            if timeout == 0:
96                self.log.debug("debug timeout raised on %s " % sh_str)
97                raise self.ssh_cmd_timeout()
98            else:
99                return True
100
Note: See TracBrowser for help on using the repository browser.