aboutsummaryrefslogtreecommitdiff
blob: a5e4f8630b6f61f5bf066771e5826918cf40878d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# vim: set sw=4 sts=4 et :
# Copyright: 2008 Gentoo Foundation
# Author(s): Nirbheek Chauhan <nirbheek.chauhan@gmail.com>
# License: GPL-2
#
# Immortal lh!
#

import subprocess
from .. import config

class Spawn(object):
    """
    Spawn a daemonized sub-process in a shell
    The sub-process must respond to the 'ping\n'
    sent to stdin with a 'pong\n'
    """

    def __init__(self, chroot, jobtagedir, workdir, command, logfile=config.LOGFILE):
        """
        @param chroot: The path to the chroot in which 
                       the command will be run
        @type chroot: string

        @param command: The (properly quoted) command to be run in the shell
                        It should listen on stdin and send replies to fd 3
        @type command: string
        """
        self.logfile = logfile
        self.jobtagedir = jobtagedir
        self.workdir = workdir
        # Messages goto 3 and then to /dev/tty1
        # stderr goes to stdout
        # stdout goes to self.logfile
        if chroot:
            self.command = 'chroot \"%s\" /bin/bash -c \'%s\' 3>&2 2>&1 | tee -a \"%s\"' % (chroot, command, self.logfile)
        else:
            self.command = '/bin/bash -c \'%s\' 3>&2 2>&1 | tee -a \"%s\"' % (command, self.logfile)
        self.process = self._init()

    def _init(self):
        process = subprocess.Popen(self.command, shell=True, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
        process.stdin.write('ping\n')
        response = process.stderr.readline()
        if not response == 'pong\n':
            # FIXME: Custom exceptions
            raise 'Communication error: received %s when expecting "pong"' % response
        process.stdin.write(self.workdir+'\n')
        process.stdin.write(self.jobtagedir+'\n')
        return process