def readcmd(self, *args): ''' Open a pipe from the megacli command and yield lines from its output. ''' cmdargs = [self.megacli] + list(args) print("+", quotecmd(cmdargs), file=sys.stderr) P = Popen(cmdargs, stdout=PIPE, close_fds=True, encoding='ascii') for line in P.stdout: yield line P.wait()
def test_func(): with Pfx("main.test_func: shcmd=%r", test_shcmd): argv = ['sh', '-c', test_shcmd] if test_uid != uid: argv = ['su', test_username, 'exec ' + quotecmd(argv)] shcmd_ok = callproc(argv, stdin=DEVNULL) == 0 if not quiet: info("exit status != 0") return shcmd_ok
def docmd(self, *args): ''' Pretend to execute a megacli command as specified. This currently just echoes commands to stderr; I fear running the "new raid" stuff etc automatically. Return True if the exit code is 0, False otherwise. ''' cmdargs = [self.megacli] + list(args) print("#", quotecmd(cmdargs)) ## return call(cmdargs) == 0 return True
def sig_func(): argv = ['sh', ('-xc' if trace else '-c'), sig_shcmd] if test_uid != uid: su_shcmd = 'exec ' + quotecmd(argv) if trace: su_shcmd = 'set -x; ' + su_shcmd argv = ['su', test_username, '-c', su_shcmd] P = LockedPopen(argv, stdin=DEVNULL, stdout=PIPE) sig_text = P.stdout.read() returncode = P.wait() if returncode != 0: warning("returncode %s from %r", returncode, sig_shcmd) sig_text = None return sig_text
def main(argv=None): ''' Command line main programme. ''' if argv is None: argv = sys.argv cmd = basename(argv.pop(0)) usage = USAGE.format(cmd=cmd, TEST_RATE=TEST_RATE, VARRUN=VARRUN) setup_logging(cmd) badopts = False try: if not argv: raise GetoptError("missing arguments") arg0 = argv[0] if arg0 == 'disable': argv.pop(0) for name in argv: SvcD([], name=name).disable() return 0 if arg0 == 'enable': argv.pop(0) for name in argv: SvcD([], name=name).enable() return 0 if arg0 == 'restart': argv.pop(0) for name in argv: SvcD([], name=name).restart() return 0 if arg0 == 'stop': argv.pop(0) for name in argv: SvcD([], name=name).stop() return 0 once = False use_lock = False lock_name = None name = None svc_pidfile = None # pid file for the service process mypidfile = None # pid file for the svcd quiet = False sig_shcmd = None test_shcmd = None test_rate = TEST_RATE uid = os.geteuid() username = getpwuid(uid).pw_name run_uid = uid run_username = username test_uid = uid test_username = username test_flags = {} trace = sys.stderr.isatty() opts, argv = getopt(argv, '1lF:L:n:p:P:qs:t:T:u:U:x') for opt, value in opts: with Pfx(opt): if opt == '-1': once = True elif opt == '-l': use_lock = True elif opt == '-F': for flagname in value.split(','): with Pfx(flagname): truthiness = True if flagname.startswith('!'): truthiness = False flagname = flagname[1:] if not flagname: warning("invalid empty flag name") badopts = True else: test_flags[flagname] = truthiness elif opt == '-L': use_lock = True lock_name = value elif opt == '-n': name = value elif opt == '-p': svc_pidfile = value elif opt == '-P': mypidfile = value elif opt == '-q': quiet = True elif opt == '-s': sig_shcmd = value elif opt == '-t': test_shcmd = value elif opt == '-T': try: test_rate = int(value) except ValueError as e: raise GetoptError( "testrate should be a valid integer: %s" % (e, )) elif opt == '-u': run_username = value run_uid = getpwnam(run_username).pw_uid elif opt == '-U': test_username = value test_uid = getpwnam(test_username).pw_uid elif opt == '-x': trace = True else: raise RuntimeError("unhandled option") if use_lock and name is None: raise GetoptError("-l (lock) requires a name (-n)") if not argv: raise GetoptError("missing command") except GetoptError as e: warning("%s", e) badopts = True if badopts: print(usage, file=sys.stderr) return 2 if sig_shcmd is None: sig_func = None else: def sig_func(): argv = ['sh', ('-xc' if trace else '-c'), sig_shcmd] if test_uid != uid: su_shcmd = 'exec ' + quotecmd(argv) if trace: su_shcmd = 'set -x; ' + su_shcmd argv = ['su', test_username, '-c', su_shcmd] P = LockedPopen(argv, stdin=DEVNULL, stdout=PIPE) sig_text = P.stdout.read() returncode = P.wait() if returncode != 0: warning("returncode %s from %r", returncode, sig_shcmd) sig_text = None return sig_text if test_shcmd is None: test_func = None else: def test_func(): with Pfx("main.test_func: shcmd=%r", test_shcmd): argv = ['sh', '-c', test_shcmd] if test_uid != uid: argv = ['su', test_username, 'exec ' + quotecmd(argv)] shcmd_ok = callproc(argv, stdin=DEVNULL) == 0 if not quiet: info("exit status != 0") return shcmd_ok if run_uid != uid: argv = ['su', run_username, 'exec ' + quotecmd(argv)] if use_lock: argv = ['lock', '--', 'svcd-' + name] + argv S = SvcD(argv, name=name, pidfile=svc_pidfile, sig_func=sig_func, test_flags=test_flags, test_func=test_func, test_rate=test_rate, once=once, quiet=quiet, trace=trace) def signal_handler(*_): S.stop() S.wait() S.flag_stop = False sys.exit(1) signal(SIGHUP, signal_handler) signal(SIGINT, signal_handler) signal(SIGTERM, signal_handler) if S.pidfile or mypidfile: if mypidfile is None: pidfile_base, pidfile_ext = splitext(S.pidfile) mypidfile = pidfile_base + '-svcd' + pidfile_ext with PidFileManager(mypidfile): S.start() S.wait() else: S.start() S.wait()