def pytest_configure(config):
    if config.option.use_sprout:
        # Using sprout
        try:
            sprout_client = SproutClient.from_config()
            logger().info(
                "Requesting {} appliances from Sprout at {}\n".format(
                    config.option.sprout_appliances, sprout_client.api_entry))
            pool_id = sprout_client.request_appliances(
                config.option.sprout_group,
                count=config.option.sprout_appliances,
                lease_time=config.option.sprout_timeout,
                version=config.option.sprout_version,
                cpu=config.option.sprout_override_cpu or None,
                ram=config.option.sprout_override_ram or None,
            )
            wait_for = partial(wait_for_mod)
            logger().info("Pool {}. Waiting for fulfillment ...\n".format(pool_id))
            sprout_pool = pool_id
            at_exit(sprout_client.destroy_pool, sprout_pool)
            if config.option.sprout_desc is not None:
                sprout_client.set_pool_description(
                    pool_id, str(config.option.sprout_desc))
            try:
                result = wait_for(
                    lambda: sprout_client.request_check(sprout_pool)["fulfilled"],
                    num_sec=3600,
                    delay=5,
                    message="requesting appliances was fulfilled"
                )
            except:
                logger().info("Destroying the pool on error.\n")
                sprout_client.destroy_pool(pool_id)
                raise
            logger().info("Provisioning took {0:.1f} seconds\n".format(result.duration))
            request = sprout_client.request_check(sprout_pool)
            # Push an appliance to the stack to have proper reference for test collection
            perf_data['appliance']['ip_address'] = request["appliances"][0]["ip_address"]
            perf_data['appliance']['appliance_name'] = 'CFME-R0000-SPROUT-LATEST'
            logger().info("Sprout Appliances provisioning completed\n")
        except Exception as e:
            logger().error(e)
            logger().error("Exception occured while provisioning from sprout")
    if config.option.appliance:
        perf_data['appliance']['ip_address'] = config.option.appliance
    if config.option.appliance_name:
        perf_data['appliance']['appliance_name'] = config.option.appliance_name
    logger().info('Appliance IP is {}'.format(perf_data['appliance']['ip_address']))
    logger().info('Appliance name is {}'.format(perf_data['appliance']['appliance_name']))
    if config.option.replication_master_ip:
        perf_data['replication_master']['ip_address'] = config.option.replication_master_ip
        logger().info('Replication Master IP is {}'.format(
            perf_data['replication_master']['ip_address']))
    if config.option.replication_master_name:
        perf_data['replication_master']['appliance_name'] = config.option.replication_master_name
        logger().info('Replication Master appliance name is {}'.format(
            perf_data['replication_master']['appliance_name']))
    if config.option.use_collectd and config.option.use_sprout:
        collectd.setup_collectd(perf_data)
def pytest_configure(config):
    global appliance
    global pool_id
    global sprout
    if not config.option.appliances and (config.option.use_sprout and
                                         config.option.sprout_appliances == 1):
        terminal = reporter()
        sprout = SproutClient.from_config()
        terminal.write("Requesting a single appliance from sprout...\n")
        pool_id = sprout.request_appliances(
            config.option.sprout_group,
            count=config.option.sprout_appliances,
            version=config.option.sprout_version,
            date=config.option.sprout_date,
            lease_time=config.option.sprout_timeout)
        terminal.write(
            "Appliance pool {}. Waiting for fulfillment ...\n".format(pool_id))
        at_exit(destroy_the_pool)
        if config.option.sprout_desc is not None:
            sprout.set_pool_description(pool_id,
                                        str(config.option.sprout_desc))
        try:
            result = wait_for(
                lambda: sprout.request_check(pool_id)["fulfilled"],
                num_sec=config.option.sprout_provision_timeout * 60,
                delay=5,
                message="requesting appliance was fulfilled")
        except:
            pool = sprout.request_check(pool_id)
            dump_pool_info(lambda x: terminal.write("{}\n".format(x)), pool)
            terminal.write("Destroying the pool on error.\n")
            sprout.destroy_pool(pool_id)
            raise
        terminal.write("Provisioning took {0:.1f} seconds\n".format(
            result.duration))
        request = sprout.request_check(pool_id)
        ip_address = request["appliances"][0]["ip_address"]
        terminal.write(
            "Appliance requested at address {} ...\n".format(ip_address))
        reset_timer(sprout, pool_id, config.option.sprout_timeout)
        terminal.write("Appliance lease timer is running ...\n")
        appliance = IPAppliance(address=ip_address)
        appliance.push()
        # Retrieve and print the template_name for Jenkins to pick up
        template_name = request["appliances"][0]["template_name"]
        conf.runtime["cfme_data"]["basic_info"][
            "appliance_template"] = template_name
        terminal.write("appliance_template=\"{}\";\n".format(template_name))
        with project_path.join('.appliance_template').open(
                'w') as template_file:
            template_file.write(
                'export appliance_template="{}"'.format(template_name))
        terminal.write("Single appliance Sprout setup finished.\n")
        # And set also the appliances_provider
        provider = request["appliances"][0]["provider"]
        terminal.write("appliance_provider=\"{}\";\n".format(provider))
        conf.runtime["cfme_data"]["basic_info"][
            "appliances_provider"] = provider
    yield
Ejemplo n.º 3
0
def main():
    host = env.get("sprout", {}).get("hostname", "localhost")
    port = env.get("sprout", {}).get("port", 8000)

    command_args = sys.argv[1:]

    try:
        method = command_args.pop(0)
    except IndexError:
        raise Exception("You have to specify the method!")

    args = []
    while command_args and "=" not in command_args[
            0] and ":" not in command_args[0]:
        value = command_args.pop(0)
        try:
            value = int(value)
        except ValueError:
            pass
        args.append(value)

    kwargs = {}
    while command_args and "=" in command_args[0] and ":" not in command_args[
            0]:
        param, value = command_args.pop(0).split("=", 1)
        try:
            value = int(value)
        except ValueError:
            pass
        kwargs[param] = value
    additional_kwargs = {}
    if command_args and ":" in command_args[0]:
        additional_kwargs["auth"] = [
            x.strip() for x in command_args[0].split(":", 1)
        ]
    elif "SPROUT_USER" in os.environ and "SPROUT_PASSWORD" in os.environ:
        additional_kwargs["auth"] = os.environ["SPROUT_USER"], os.environ[
            "SPROUT_PASSWORD"]
    elif "SPROUT_PASSWORD" in os.environ:
        additional_kwargs["auth"] = os.environ["USER"], os.environ[
            "SPROUT_PASSWORD"]
    client = SproutClient(host=host, port=port, **additional_kwargs)
    print json.dumps(client.call_method(method, *args, **kwargs))
def pytest_configure(config):
    global appliance
    global pool_id
    global sprout
    yield
    if not config.option.appliances and (config.option.use_sprout
            and config.option.sprout_appliances == 1):
        terminal = reporter()
        sprout = SproutClient.from_config()
        terminal.write("Requesting single appliance from sprout...\n")
        pool_id = sprout.request_appliances(
            config.option.sprout_group,
            count=config.option.sprout_appliances,
            version=config.option.sprout_version,
            date=config.option.sprout_date,
            lease_time=config.option.sprout_timeout
        )
        terminal.write("Appliance pool {}. Waiting for fulfillment ...\n".format(pool_id))
        at_exit(destroy_the_pool)
        if config.option.sprout_desc is not None:
            sprout.set_pool_description(pool_id, str(config.option.sprout_desc))
        try:
            result = wait_for(
                lambda: sprout.request_check(pool_id)["fulfilled"],
                num_sec=config.option.sprout_provision_timeout * 60,
                delay=5,
                message="requesting appliance was fulfilled"
            )
        except:
            pool = sprout.request_check(pool_id)
            dump_pool_info(lambda x: terminal.write("{}\n".format(x)), pool)
            terminal.write("Destroying the pool on error.\n")
            sprout.destroy_pool(pool_id)
            raise
        terminal.write("Provisioning took {0:.1f} seconds\n".format(result.duration))
        request = sprout.request_check(pool_id)
        ip_address = request["appliances"][0]["ip_address"]
        terminal.write("Appliance requested at address {} ...\n".format(ip_address))
        reset_timer(sprout, pool_id, config.option.sprout_timeout)
        terminal.write("Appliance lease timer is running ...\n")
        appliance = IPAppliance(address=ip_address)
        # Retrieve and print the template_name for Jenkins to pick up
        template_name = request["appliances"][0]["template_name"]
        conf.runtime["cfme_data"]["basic_info"]["appliance_template"] = template_name
        terminal.write("appliance_template=\"{}\";\n".format(template_name))
        with project_path.join('.appliance_template').open('w') as template_file:
            template_file.write('export appliance_template="{}"'.format(template_name))
        terminal.write("Single appliance Sprout setup finished.\n")
        # And set also the appliances_provider
        provider = request["appliances"][0]["provider"]
        terminal.write("appliance_provider=\"{}\";\n".format(provider))
        conf.runtime["cfme_data"]["basic_info"]["appliances_provider"] = provider
Ejemplo n.º 5
0
def main():
    host = env.get("sprout", {}).get("hostname", "localhost")
    port = env.get("sprout", {}).get("port", 8000)

    command_args = sys.argv[1:]

    try:
        method = command_args.pop(0)
    except IndexError:
        raise Exception("You have to specify the method!")

    args = []
    while command_args and "=" not in command_args[0] and ":" not in command_args[0]:
        value = command_args.pop(0)
        try:
            value = int(value)
        except ValueError:
            pass
        args.append(value)

    kwargs = {}
    while command_args and "=" in command_args[0] and ":" not in command_args[0]:
        param, value = command_args.pop(0).split("=", 1)
        try:
            value = int(value)
        except ValueError:
            pass
        kwargs[param] = value
    additional_kwargs = {}
    if command_args and ":" in command_args[0]:
        additional_kwargs["auth"] = [x.strip() for x in command_args[0].split(":", 1)]
    elif "SPROUT_USER" in os.environ and "SPROUT_PASSWORD" in os.environ:
        additional_kwargs["auth"] = os.environ["SPROUT_USER"], os.environ["SPROUT_PASSWORD"]
    elif "SPROUT_PASSWORD" in os.environ:
        additional_kwargs["auth"] = os.environ["USER"], os.environ["SPROUT_PASSWORD"]
    client = SproutClient(host=host, port=port, **additional_kwargs)
    print(json.dumps(client.call_method(method, *args, **kwargs)))
Ejemplo n.º 6
0
def pytest_configure(config):
    if config.option.use_sprout:
        # Using sprout
        try:
            sprout_client = SproutClient.from_config()
            logger().info(
                "Requesting {} appliances from Sprout at {}\n".format(
                    config.option.sprout_appliances, sprout_client.api_entry))
            pool_id = sprout_client.request_appliances(
                config.option.sprout_group,
                count=config.option.sprout_appliances,
                lease_time=config.option.sprout_timeout
            )
            wait_for = partial(wait_for_mod)
            logger().info("Pool {}. Waiting for fulfillment ...\n".format(pool_id))
            sprout_pool = pool_id
            at_exit(sprout_client.destroy_pool, sprout_pool)
            if config.option.sprout_desc is not None:
                sprout_client.set_pool_description(
                    pool_id, str(config.option.sprout_desc))
            try:
                result = wait_for(
                    lambda: sprout_client.request_check(sprout_pool)["fulfilled"],
                    num_sec=3600,
                    delay=5,
                    message="requesting appliances was fulfilled"
                )
            except:
                logger().info("Destroying the pool on error.\n")
                sprout_client.destroy_pool(pool_id)
                raise
            logger().info("Provisioning took {0:.1f} seconds\n".format(result.duration))
            request = sprout_client.request_check(sprout_pool)
            # Push an appliance to the stack to have proper reference for test collection
            perf_data['appliance']['ip_address'] = request["appliances"][0]["ip_address"]
            perf_data['appliance']['appliance_name'] = 'CFME-R0000-SPROUT-LATEST'
            logger().info("Sprout Appliances provisioning completed\n")
        except Exception as e:
            logger().error(e)
            logger().error("Exception occured while provisioning from sprout")
    if config.option.appliance:
        perf_data['appliance']['ip_address'] = config.option.appliance
    if config.option.appliance_name:
        perf_data['appliance']['appliance_name'] = config.option.appliance_name
    logger().info('Appliance IP is {}'.format(perf_data['appliance']['ip_address']))
    logger().info('Appliance name is {}'.format(perf_data['appliance']['appliance_name']))
Ejemplo n.º 7
0
    def __init__(self, config):
        self.config = config
        self.session = None
        self.session_finished = False
        self.countfailures = 0
        self.collection = OrderedDict()
        self.sent_tests = 0
        self.log = create_sublogger('master')
        self.maxfail = config.getvalue("maxfail")
        self._failed_collection_errors = {}
        self.terminal = store.terminalreporter
        self.trdist = None
        self.slaves = SlaveDict()
        self.slave_urls = SlaveDict()
        self.slave_tests = defaultdict(set)
        self.test_groups = self._test_item_generator()
        self.failed_slave_test_groups = deque()
        self.slave_spawn_count = 0
        self.sprout_client = None
        self.sprout_timer = None
        self.sprout_pool = None
        if not self.config.option.use_sprout:
            # Without Sprout
            self.appliances = self.config.option.appliances
        else:
            # Using sprout
            self.sprout_client = SproutClient.from_config()
            self.terminal.write(
                "Requesting {} appliances from Sprout at {}\n".format(
                    self.config.option.sprout_appliances,
                    self.sprout_client.api_entry))
            pool_id = self.sprout_client.request_appliances(
                self.config.option.sprout_group,
                count=self.config.option.sprout_appliances,
                version=self.config.option.sprout_version,
                date=self.config.option.sprout_date,
                lease_time=self.config.option.sprout_timeout)
            self.terminal.write(
                "Pool {}. Waiting for fulfillment ...\n".format(pool_id))
            self.sprout_pool = pool_id
            at_exit(self.sprout_client.destroy_pool, self.sprout_pool)
            if self.config.option.sprout_desc is not None:
                self.sprout_client.set_pool_description(
                    pool_id, str(self.config.option.sprout_desc))
            try:
                result = wait_for(
                    lambda: self.sprout_client.request_check(self.sprout_pool)[
                        "fulfilled"],
                    num_sec=self.config.option.sprout_provision_timeout * 60,
                    delay=5,
                    message="requesting appliances was fulfilled")
            except:
                pool = self.sprout_client.request_check(self.sprout_pool)
                dump_pool_info(lambda x: self.terminal.write("{}\n".format(x)),
                               pool)
                self.terminal.write("Destroying the pool on error.\n")
                self.sprout_client.destroy_pool(pool_id)
                raise
            else:
                pool = self.sprout_client.request_check(self.sprout_pool)
                dump_pool_info(lambda x: self.terminal.write("{}\n".format(x)),
                               pool)
            self.terminal.write("Provisioning took {0:.1f} seconds\n".format(
                result.duration))
            request = self.sprout_client.request_check(self.sprout_pool)
            self.appliances = []
            # Push an appliance to the stack to have proper reference for test collection
            IPAppliance(address=request["appliances"][0]["ip_address"]).push()
            self.terminal.write("Appliances were provided:\n")
            for appliance in request["appliances"]:
                url = "https://{}/".format(appliance["ip_address"])
                self.appliances.append(url)
                self.terminal.write("- {} is {}\n".format(
                    url, appliance['name']))
            map(lambda a: "https://{}/".format(a["ip_address"]),
                request["appliances"])
            self._reset_timer()
            # Set the base_url for collection purposes on the first appliance
            conf.runtime["env"]["base_url"] = self.appliances[0]
            # Retrieve and print the template_name for Jenkins to pick up
            template_name = request["appliances"][0]["template_name"]
            conf.runtime["cfme_data"]["basic_info"][
                "appliance_template"] = template_name
            self.terminal.write(
                "appliance_template=\"{}\";\n".format(template_name))
            with project_path.join('.appliance_template').open(
                    'w') as template_file:
                template_file.write(
                    'export appliance_template="{}"'.format(template_name))
            self.terminal.write("Parallelized Sprout setup finished.\n")
            self.slave_appliances_data = {}
            for appliance in request["appliances"]:
                self.slave_appliances_data[appliance["ip_address"]] = (
                    appliance["template_name"], appliance["provider"])

        # set up the ipc socket
        zmq_endpoint = 'tcp://127.0.0.1:{}'.format(random_port())
        ctx = zmq.Context.instance()
        self.sock = ctx.socket(zmq.ROUTER)
        self.sock.bind('%s' % zmq_endpoint)

        # clean out old slave config if it exists
        slave_config = conf_path.join('slave_config.yaml')
        slave_config.check() and slave_config.remove()

        # write out the slave config
        conf.runtime['slave_config'] = {
            'args':
            self.config.args,
            'options':
            self.config.option.__dict__,
            'zmq_endpoint':
            zmq_endpoint,
            'sprout':
            self.sprout_client is not None and self.sprout_pool is not None,
        }
        if hasattr(self, "slave_appliances_data"):
            conf.runtime['slave_config'][
                "appliance_data"] = self.slave_appliances_data
        conf.runtime['slave_config']['options'][
            'use_sprout'] = False  # Slaves don't use sprout
        conf.save('slave_config')

        for i, base_url in enumerate(self.appliances):
            self.slave_urls.add(base_url)

        for slave in sorted(self.slave_urls):
            self.print_message("using appliance {}".format(
                self.slave_urls[slave]),
                               slave,
                               green=True)

        # Start the recv queue
        self._recv_queue = deque()
        recv_queuer = Thread(target=_recv_queue, args=(self, ))
        recv_queuer.daemon = True
        recv_queuer.start()
Ejemplo n.º 8
0
    def __init__(self, config):
        self.config = config
        self.session = None
        self.session_finished = False
        self.countfailures = 0
        self.collection = OrderedDict()
        self.sent_tests = 0
        self.log = create_sublogger('master')
        self.maxfail = config.getvalue("maxfail")
        self._failed_collection_errors = {}
        self.terminal = store.terminalreporter
        self.trdist = None
        self.slaves = SlaveDict()
        self.slave_urls = SlaveDict()
        self.slave_tests = defaultdict(set)
        self.test_groups = self._test_item_generator()

        self._pool = []
        self.pool_lock = Lock()
        from utils.conf import cfme_data
        self.provs = sorted(set(cfme_data['management_systems'].keys()),
                            key=len, reverse=True)
        self.slave_allocation = collections.defaultdict(list)
        self.used_prov = set()

        self.failed_slave_test_groups = deque()
        self.slave_spawn_count = 0
        self.sprout_client = None
        self.sprout_timer = None
        self.sprout_pool = None
        if not self.config.option.use_sprout:
            # Without Sprout
            self.appliances = self.config.option.appliances
        else:
            # Using sprout
            self.sprout_client = SproutClient.from_config()
            try:
                if self.config.option.sprout_desc is not None:
                    jenkins_job = re.findall(r"Jenkins.*[^\d+$]", self.config.option.sprout_desc)
                    if jenkins_job:
                        self.terminal.write(
                            "Check if pool already exists for this '{}' Jenkins job\n".format(
                                jenkins_job[0]))
                        jenkins_job_pools = self.sprout_client.find_pools_by_description(
                            jenkins_job[0], partial=True)
                        for pool in jenkins_job_pools:
                            self.terminal.write("Destroying the old pool {} for '{}' job.\n".format(
                                pool, jenkins_job[0]))
                            self.sprout_client.destroy_pool(pool)
            except Exception as e:
                self.terminal.write(
                    "Exception occurred during old pool deletion, this can be ignored"
                    "proceeding to Request new pool")
                self.terminal.write("> The exception was: {}".format(str(e)))

            self.terminal.write(
                "Requesting {} appliances from Sprout at {}\n".format(
                    self.config.option.sprout_appliances, self.sprout_client.api_entry))
            pool_id = self.sprout_client.request_appliances(
                self.config.option.sprout_group,
                count=self.config.option.sprout_appliances,
                version=self.config.option.sprout_version,
                date=self.config.option.sprout_date,
                lease_time=self.config.option.sprout_timeout
            )
            self.println("Pool {}. Waiting for fulfillment ...".format(pool_id))
            self.sprout_pool = pool_id
            at_exit(self.sprout_client.destroy_pool, self.sprout_pool)
            if self.config.option.sprout_desc is not None:
                self.sprout_client.set_pool_description(
                    pool_id, str(self.config.option.sprout_desc))

            def detailed_check():
                try:
                    result = self.sprout_client.request_check(self.sprout_pool)
                except SproutException as e:
                    # TODO: ensure we only exit this way on sprout usage
                    try:
                        self.sprout_client.destroy_pool(pool_id)
                    except Exception:
                        pass
                    self.println(
                        "sprout pool could not be fulfilled\n{}".format(e))
                    pytest.exit(1)

                self.println("[{now:%H:%M}] fulfilled at {progress:2}%".format(
                    now=datetime.now(),
                    progress=result['progress']
                ))
                return result["fulfilled"]
            try:
                result = wait_for(
                    detailed_check,
                    num_sec=self.config.option.sprout_provision_timeout * 60,
                    delay=5,
                    message="requesting appliances was fulfilled"
                )
            except Exception:
                pool = self.sprout_client.request_check(self.sprout_pool)
                dump_pool_info(self.println, pool)
                self.println("Destroying the pool on error.")
                self.sprout_client.destroy_pool(pool_id)
                raise
            else:
                pool = self.sprout_client.request_check(self.sprout_pool)
                dump_pool_info(self.println, pool)
            self.println("Provisioning took {0:.1f} seconds".format(result.duration))
            request = self.sprout_client.request_check(self.sprout_pool)
            self.appliances = []
            # Push an appliance to the stack to have proper reference for test collection
            # FIXME: this is a bad hack based on the need for controll of collection partitioning
            appliance_stack.push(
                IPAppliance(address=request["appliances"][0]["ip_address"]))
            self.println("Appliances were provided:")
            for appliance in request["appliances"]:
                url = "https://{}/".format(appliance["ip_address"])
                self.appliances.append(url)
                self.println("- {} is {}".format(url, appliance['name']))
            map(lambda a: "https://{}/".format(a["ip_address"]), request["appliances"])
            self._reset_timer()
            # Set the base_url for collection purposes on the first appliance
            conf.runtime["env"]["base_url"] = self.appliances[0]
            # Retrieve and print the template_name for Jenkins to pick up
            template_name = request["appliances"][0]["template_name"]
            conf.runtime["cfme_data"]["basic_info"]["appliance_template"] = template_name
            self.terminal.write("appliance_template=\"{}\";\n".format(template_name))
            with project_path.join('.appliance_template').open('w') as template_file:
                template_file.write('export appliance_template="{}"'.format(template_name))
            self.println("Parallelized Sprout setup finished.")
            self.slave_appliances_data = {}
            for appliance in request["appliances"]:
                self.slave_appliances_data[appliance["ip_address"]] = (
                    appliance["template_name"], appliance["provider"]
                )

        # set up the ipc socket
        zmq_endpoint = 'tcp://127.0.0.1:{}'.format(random_port())
        ctx = zmq.Context.instance()
        self.sock = ctx.socket(zmq.ROUTER)
        self.sock.bind('{}'.format(zmq_endpoint))

        # clean out old slave config if it exists
        slave_config = conf_path.join('slave_config.yaml')
        slave_config.check() and slave_config.remove()

        # write out the slave config
        conf.runtime['slave_config'] = {
            'args': self.config.args,
            'options': self.config.option.__dict__,
            'zmq_endpoint': zmq_endpoint,
            'sprout': self.sprout_client is not None and self.sprout_pool is not None,
        }
        if hasattr(self, "slave_appliances_data"):
            conf.runtime['slave_config']["appliance_data"] = self.slave_appliances_data
        conf.runtime['slave_config']['options']['use_sprout'] = False  # Slaves don't use sprout
        conf.save('slave_config')

        for i, base_url in enumerate(self.appliances):
            self.slave_urls.add(base_url)

        for slave in sorted(self.slave_urls):
            self.print_message("using appliance {}".format(self.slave_urls[slave]),
                slave, green=True)

        # Start the recv queue
        self._recv_queue = deque()
        recv_queuer = Thread(target=_recv_queue, args=(self,))
        recv_queuer.daemon = True
        recv_queuer.start()
Ejemplo n.º 9
0
    def __init__(self, config):
        self.config = config
        self.session = None
        self.session_finished = False
        self.countfailures = 0
        self.collection = OrderedDict()
        self.sent_tests = 0
        self.log = create_sublogger('master')
        self.maxfail = config.getvalue("maxfail")
        self._failed_collection_errors = {}
        self.terminal = store.terminalreporter
        self.trdist = None
        self.slaves = SlaveDict()
        self.slave_urls = SlaveDict()
        self.slave_tests = defaultdict(set)
        self.test_groups = self._test_item_generator()
        self.failed_slave_test_groups = deque()
        self.slave_spawn_count = 0
        self.sprout_client = None
        self.sprout_timer = None
        self.sprout_pool = None
        if not self.config.option.use_sprout:
            # Without Sprout
            self.appliances = self.config.option.appliances
        else:
            # Using sprout
            self.sprout_client = SproutClient.from_config()
            self.terminal.write(
                "Requesting {} appliances from Sprout at {}\n".format(
                    self.config.option.sprout_appliances, self.sprout_client.api_entry))
            pool_id = self.sprout_client.request_appliances(
                self.config.option.sprout_group,
                count=self.config.option.sprout_appliances,
                version=self.config.option.sprout_version,
                date=self.config.option.sprout_date,
                lease_time=self.config.option.sprout_timeout
            )
            self.terminal.write("Pool {}. Waiting for fulfillment ...\n".format(pool_id))
            self.sprout_pool = pool_id
            at_exit(self.sprout_client.destroy_pool, self.sprout_pool)
            if self.config.option.sprout_desc is not None:
                self.sprout_client.set_pool_description(
                    pool_id, str(self.config.option.sprout_desc))
            try:
                result = wait_for(
                    lambda: self.sprout_client.request_check(self.sprout_pool)["fulfilled"],
                    num_sec=self.config.option.sprout_provision_timeout * 60,
                    delay=5,
                    message="requesting appliances was fulfilled"
                )
            except:
                pool = self.sprout_client.request_check(self.sprout_pool)
                dump_pool_info(lambda x: self.terminal.write("{}\n".format(x)), pool)
                self.terminal.write("Destroying the pool on error.\n")
                self.sprout_client.destroy_pool(pool_id)
                raise
            else:
                pool = self.sprout_client.request_check(self.sprout_pool)
                dump_pool_info(lambda x: self.terminal.write("{}\n".format(x)), pool)
            self.terminal.write("Provisioning took {0:.1f} seconds\n".format(result.duration))
            request = self.sprout_client.request_check(self.sprout_pool)
            self.appliances = []
            # Push an appliance to the stack to have proper reference for test collection
            IPAppliance(address=request["appliances"][0]["ip_address"]).push()
            self.terminal.write("Appliances were provided:\n")
            for appliance in request["appliances"]:
                url = "https://{}/".format(appliance["ip_address"])
                self.appliances.append(url)
                self.terminal.write("- {} is {}\n".format(url, appliance['name']))
            map(lambda a: "https://{}/".format(a["ip_address"]), request["appliances"])
            self._reset_timer()
            # Set the base_url for collection purposes on the first appliance
            conf.runtime["env"]["base_url"] = self.appliances[0]
            # Retrieve and print the template_name for Jenkins to pick up
            template_name = request["appliances"][0]["template_name"]
            conf.runtime["cfme_data"]["basic_info"]["appliance_template"] = template_name
            self.terminal.write("appliance_template=\"{}\";\n".format(template_name))
            with project_path.join('.appliance_template').open('w') as template_file:
                template_file.write('export appliance_template="{}"'.format(template_name))
            self.terminal.write("Parallelized Sprout setup finished.\n")
            self.slave_appliances_data = {}
            for appliance in request["appliances"]:
                self.slave_appliances_data[appliance["ip_address"]] = (
                    appliance["template_name"], appliance["provider"]
                )

        # set up the ipc socket
        zmq_endpoint = 'tcp://127.0.0.1:{}'.format(random_port())
        ctx = zmq.Context.instance()
        self.sock = ctx.socket(zmq.ROUTER)
        self.sock.bind('%s' % zmq_endpoint)

        # clean out old slave config if it exists
        slave_config = conf_path.join('slave_config.yaml')
        slave_config.check() and slave_config.remove()

        # write out the slave config
        conf.runtime['slave_config'] = {
            'args': self.config.args,
            'options': self.config.option.__dict__,
            'zmq_endpoint': zmq_endpoint,
            'sprout': self.sprout_client is not None and self.sprout_pool is not None,
        }
        if hasattr(self, "slave_appliances_data"):
            conf.runtime['slave_config']["appliance_data"] = self.slave_appliances_data
        conf.runtime['slave_config']['options']['use_sprout'] = False  # Slaves don't use sprout
        conf.save('slave_config')

        for i, base_url in enumerate(self.appliances):
            self.slave_urls.add(base_url)
        # Fire up the workers
        self._slave_audit()

        # Start the recv queue
        self._recv_queue = deque()
        recv_queuer = Thread(target=_recv_queue, args=(self,))
        recv_queuer.daemon = True
        recv_queuer.start()