source: fedd/federation/local_segment.py @ 1553d27

version-3.02
Last change on this file since 1553d27 was 5bf359d, checked in by Ted Faber <faber@…>, 15 years ago

More refactoring. Neaten up the code for creating segments in emulab and make the local and proxy class structures parallel. The code is more readable this way, I hope.

  • Property mode set to 100644
File size: 2.2 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
12import util
13
14class local_segment:
15    """
16    Base class for starting a segments on a local testbed accessed directly
17    through commands rather than ssh connections.  Code repository for
18    executing commands with timeouts and other utility functions.
19    """
20    class cmd_timeout(RuntimeError): pass
21
22    def __init__(self, log=None, keyfile=None, debug=False):
23        """
24        Parameters are a logger to use for updates, an unused key file, and a
25        flag indicating that commands should not actually be carried out.
26        """
27        self.log = log or logging.getLogger(\
28                'fedd.access.proxy_emulab_segment')
29        self.certfile = keyfile
30        self.debug = debug
31        self.cmd_timeout = local_segment.cmd_timeout
32
33    def copy_file(self, src, dest, size=1024):
34        """
35        Exceedingly simple file copy.
36        """
37        if not self.debug:
38            util.copy_file(src, dest, size)
39        else:
40            self.log.debug("Copy %s to %s" % (src, dest))
41
42    def cmd_with_timeout(self, cmd, wname=None, timeout=None):
43        """
44        Run a command.  If debug is set, the action
45        is only logged.  Commands are run without stdin, to avoid stray
46        SIGTTINs. If timeout is given and the command runs longer, a
47        cmd_timeout exception is thrown.
48        """
49
50        try:
51            dnull = open("/dev/null", "w")
52        except EnvironmentError:
53            self.log.debug("[cmd_with_timeout]: failed to open /dev/null " + \
54                    "for redirect")
55            dnull = Null
56
57        self.log.debug("[cmd_with_timeout]: %s" % cmd)
58        if not self.debug:
59            if dnull:
60                sub = subprocess.Popen(cmd, shell=True, stdout=dnull,
61                        stderr=dnull, close_fds=True)
62            else:
63                sub = subprocess.Popen(cmd, shell=True, close_fds=True)
64            if timeout:
65                i = 0
66                rv = sub.poll()
67                while i < timeout:
68                    if rv is not None: break
69                    else:
70                        time.sleep(1)
71                        rv = sub.poll()
72                        i += 1
73                else:
74                    self.log.debug("Process exceeded runtime: %s" % cmd)
75                    os.kill(sub.pid, signal.SIGKILL)
76                    raise self.cmd_timeout();
77                return rv == 0
78            else:
79                return sub.wait() == 0
80        else:
81            if timeout == 0:
82                self.log.debug("debug timeout raised on %s " % cmd)
83                raise self.cmd_timeout()
84            else:
85                return True
86
Note: See TracBrowser for help on using the repository browser.