|
Packit Service |
76cb02 |
import os
|
|
Packit Service |
76cb02 |
from subprocess import Popen, PIPE
|
|
Packit Service |
cd7d79 |
from io import open
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
class Command:
|
|
Packit Service |
76cb02 |
"""Contains the needed data to run a command"""
|
|
Packit Service |
76cb02 |
def __init__(self, args, stdin=None, stdout=None, shell=False):
|
|
Packit Service |
76cb02 |
self.arguments = args
|
|
Packit Service |
76cb02 |
self.stdin = stdin
|
|
Packit Service |
76cb02 |
self.stdout = stdout
|
|
Packit Service |
76cb02 |
self.shell = shell
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
class CommandRunner:
|
|
Packit Service |
76cb02 |
"""
|
|
Packit Service |
76cb02 |
Execute the differents registered commands in the specified order,
|
|
Packit Service |
76cb02 |
either independantly or as a pipe process chain if required
|
|
Packit Service |
76cb02 |
"""
|
|
Packit Service |
76cb02 |
def __init__(self, module_name="", log=None):
|
|
Packit Service |
76cb02 |
self.module_name = module_name
|
|
Packit Service |
76cb02 |
self.commands = []
|
|
Packit Service |
76cb02 |
self.processes = []
|
|
Packit Service |
76cb02 |
self.log = log
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
def info(self, text):
|
|
Packit Service |
76cb02 |
if self.log: self.log.info(text)
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
def set_name(self, module_name):
|
|
Packit Service |
76cb02 |
self.module_name = module_name
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
def add_command(self, args, stdin=None, stdout=None, shell=False):
|
|
Packit Service |
76cb02 |
command = Command(args, stdin, stdout, shell)
|
|
Packit Service |
76cb02 |
self.commands.append(command)
|
|
Packit Service |
76cb02 |
return command
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
def shcmd(self, args):
|
|
Packit Service |
76cb02 |
nargs = []
|
|
Packit Service |
76cb02 |
for arg in args:
|
|
Packit Service |
76cb02 |
if len(arg.split()) > 1: arg = '"%s"' % arg
|
|
Packit Service |
76cb02 |
nargs.append(arg)
|
|
Packit Service |
76cb02 |
return " ".join(nargs)
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
def run(self, kw=None):
|
|
Packit Service |
76cb02 |
if not(self.commands):
|
|
Packit Service |
76cb02 |
return
|
|
Packit Service |
76cb02 |
if not(kw): kw = {}
|
|
Packit Service |
76cb02 |
pipe_top = False
|
|
Packit Service |
76cb02 |
rc = 0
|
|
Packit Service |
76cb02 |
for cmd in self.commands:
|
|
Packit Service |
76cb02 |
if rc != 0:
|
|
Packit Service |
76cb02 |
break
|
|
Packit Service |
76cb02 |
stdin, stdout = None, None
|
|
Packit Service |
76cb02 |
prev_pipe = None
|
|
Packit Service |
76cb02 |
if cmd.stdin == "PIPE":
|
|
Packit Service |
76cb02 |
if self.processes:
|
|
Packit Service |
76cb02 |
prev_pipe = self.processes[-1]
|
|
Packit Service |
76cb02 |
stdin = prev_pipe.stdout
|
|
Packit Service |
76cb02 |
else:
|
|
Packit Service |
76cb02 |
pipe_top = True
|
|
Packit Service |
76cb02 |
stdin = PIPE
|
|
Packit Service |
76cb02 |
if cmd.stdout == "PIPE":
|
|
Packit Service |
76cb02 |
stdout = PIPE
|
|
Packit Service |
76cb02 |
elif cmd.stdout:
|
|
Packit Service |
cd7d79 |
stdout = open(cmd.stdout % kw, "wb")
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
if kw: args = [a % kw for a in cmd.arguments]
|
|
Packit Service |
76cb02 |
else: args = cmd.arguments
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
self.info(" ".join(args))
|
|
Packit Service |
76cb02 |
# Some commands work only in shell env (e.g. links), so take care
|
|
Packit Service |
76cb02 |
if cmd.shell:
|
|
Packit Service |
76cb02 |
p = Popen(self.shcmd(args), stdin=stdin, stdout=stdout,
|
|
Packit Service |
76cb02 |
shell=True)
|
|
Packit Service |
76cb02 |
else:
|
|
Packit Service |
76cb02 |
p = Popen(args, stdin=stdin, stdout=stdout)
|
|
Packit Service |
76cb02 |
self.processes.append(p)
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
if stdin and prev_pipe:
|
|
Packit Service |
76cb02 |
# Close stdout to allow <prev_pipe> receiving SIGPIPE
|
|
Packit Service |
76cb02 |
prev_pipe.stdout.close()
|
|
Packit Service |
76cb02 |
if stdout != PIPE:
|
|
Packit Service |
76cb02 |
# Wait until the process is finished if not in a pipe chain
|
|
Packit Service |
76cb02 |
rc = p.wait()
|
|
Packit Service |
76cb02 |
if stdout: stdout.close()
|
|
Packit Service |
76cb02 |
|
|
Packit Service |
76cb02 |
return rc
|
|
Packit Service |
76cb02 |
|