Example #1
0
    def test_retry_on_shutdown_raise(self):
        os.rmdir(self.path)

        with self.assertRaises((WindowsError, OSError, IOError)):
            remove_directory(
                self.path, ignored_errnos=(), retry_on_exit=True, raise_=True)

        self.assertEqual(atexit._exithandlers, self.atexit_signature)
Example #2
0
    def _remove_directories(self, directories, retry_on_exit=True):
        """
        Removes multiple multiple directories at once, retrying on exit
        for each failure.
        """
        assert isinstance(directories, (list, tuple, set))

        for directory in directories:
            remove_directory(directory, raise_=False, retry_on_exit=retry_on_exit)
Example #3
0
    def test_retry_only_once(self):
        os.rmdir(self.path)

        # If remove_file is wrapped in a while loop and is being
        # passed the same arguments, it should only be one call for atexit.
        remove_directory(
            self.path, ignored_errnos=(), retry_on_exit=True, raise_=False)
        remove_directory(
            self.path, ignored_errnos=(), retry_on_exit=True, raise_=False)
        self.assertEqual(atexit._exithandlers, self.atexit_signature)
 def tearDown(self):
     super(TestTaskLogs, self).tearDown()
     remove_directory(
         config["jobtype_task_logs"], retry_on_exit=True, raise_=False)
Example #5
0
 def test_retry_on_shutdown_no_raise(self):
     os.rmdir(self.path)
     remove_directory(
         self.path, ignored_errnos=(), retry_on_exit=True, raise_=False)
     self.assertEqual(atexit._exithandlers, self.atexit_signature)
Example #6
0
 def test_ignored_error(self):
     os.rmdir(self.path)
     remove_directory(self.path, ignored_errnos=(ENOENT, ), raise_=True)
     self.assertFalse(isdir(self.path))
Example #7
0
 def test_removes_directory(self):
     remove_directory(self.path)
     self.assertFalse(isdir(self.path))
Example #8
0
def supervisor():
    logger.debug("Supervisor called with: %r", sys.argv)
    supervisor_args = []
    agent_args = []
    in_agent_args = False
    tmp_argv = list(sys.argv)
    del tmp_argv[0]
    for arg in tmp_argv:
        if not in_agent_args and arg != "--":
            supervisor_args.append(arg)
        elif not in_agent_args and arg == "--":
            in_agent_args = True
        else:
            agent_args.append(arg)

    logger.debug("supervisor_args: %s", supervisor_args)

    parser = AgentArgumentParser(
        description="Start and monitor the agent process")
    parser.add_argument("--updates-drop-dir",
                        config="agent_updates_dir",
                        type=isdir, type_kwargs=dict(create=True),
                        help="Where to look for agent updates")
    parser.add_argument("--agent-package-dir",
                        type=isdir, type_kwargs=dict(create=True),
                        help="Path to the actual agent code")
    parser.add_argument("--pidfile", config="supervisor_lock_file",
                        help="The file to store the process id in. "
                             "[default: %(default)s]")
    parser.add_argument("-n", "--no-daemon", default=False, action="store_true",
                        config=False,
                        help="If provided then do not run the process in the "
                             "background.")
    parser.add_argument("--chdir", config="agent_chdir", type=isdir,
                        help="The directory to chdir to upon launch.")
    parser.add_argument("--uid", type=int,
                        help="The user id to run the supervisor as.  "
                             "*This setting is ignored on Windows.*")
    parser.add_argument("--gid", type=int,
                        help="The group id to run the supervisor as.  "
                             "*This setting is ignored on Windows.*")
    args = parser.parse_args(supervisor_args)

    if not args.no_daemon and fork is not NotImplemented:
        logger.info("sending supervisor log output to %s" %
                    config["supervisor_log"])
        daemon_start_return_code = start_daemon_posix(
            args.log, args.chdir, args.uid, args.gid)

        if isinstance(daemon_start_return_code, INTEGER_TYPES):
            return daemon_start_return_code

    elif not args.no_daemon and fork is NotImplemented:
        logger.warning(
            "`fork` is not implemented on %s, starting in "
            "foreground" % OS.title())
    else:
        logger.debug("Not forking to background")

    pid = os.getpid()
    # Write the PID file
    try:
        with open(config["supervisor_lock_file"], "w") as pidfile:
            pidfile.write(str(os.getpid()))
    except OSError as e:
        logger.error(
            "Failed to write PID file %s: %s",
            config["supervisor_lock_file"], e)
        return 1
    else:
        logger.debug("Wrote PID to %s", config["supervisor_lock_file"])

    logger.info("supervisor pid: %s" % pid)

    if getuid is not NotImplemented:
        logger.info("uid: %s" % getuid())

    if getgid is not NotImplemented:
        logger.info("gid: %s" % getgid())

    def terminate_handler(*_):
        subprocess.call(["pyfarm-agent"] + agent_args + ["stop"])
        sys.exit(0)

    def restart_handler(*_):
        subprocess.call(["pyfarm-agent"] + agent_args + ["stop"])

    logger.debug("Setting signal handlers")

    signal.signal(signal.SIGTERM, terminate_handler)
    signal.signal(signal.SIGINT, terminate_handler)
    signal.signal(signal.SIGHUP, restart_handler)

    update_file_path = join(config["agent_updates_dir"], "pyfarm-agent.zip")
    run_control_file = config["run_control_file_by_platform"]\
        [operating_system()]
    loop_interval = config["supervisor_interval"]

    while True:
        if subprocess.call(["pyfarm-agent", "status"]) != 0:
            if not isfile(run_control_file):
                logger.info("pyfarm_agent is not running, but run control file "
                            "%s does not exist. Not restarting the agent",
                            run_control_file)
            logger.info("pyfarm-agent is not running")
            if (os.path.isfile(update_file_path) and
                zipfile.is_zipfile(update_file_path)):
                logger.info("Found an upgrade to pyfarm-agent")
                try:
                    remove_directory(args.agent_package_dir, raise_=True)
                    os.makedirs(args.agent_package_dir)
                    with zipfile.ZipFile(update_file_path, "r") as archive:
                        archive.extractall(args.agent_package_dir)

                    remove_file(
                        update_file_path, retry_on_exit=True, raise_=False)
                except Exception as e:
                    logger.error(
                        "Caught exception trying to update agent: %r", e)

            logger.info("starting pyfarm-agent now")
            if subprocess.call(["pyfarm-agent"] + agent_args + ["start"]) != 0:
                logger.error("Could not start pyfarm-agent")
                sys.exit(1)

        time.sleep(loop_interval)