Ejemplo n.º 1
0
def start_core_instances(core_extracted_dir, bind_addrs, conductr_roles,
                         features, log_level):
    """
    Starts the ConductR core process.

    Each instance is allocated an address to be bound based on the address range. For example:
    - Given 3 required core instances
    - Given the address range input of 192.168.128.0/24
    - The instances will be allocated these addresses: 192.168.128.1, 192.168.128.2, 192.168.128.3

    :param core_extracted_dir: the directory containing the files expanded from core's binary .tgz
    :param bind_addrs: a list of addresses which the core instances will bind to.
                       If there are 3 instances of core required, there will be 3 addresses supplied.
    :param conductr_roles: list of roles specified by the end user.
    :param features: list of features which needs to be started.
                     This method won't start the feature, but will ensure arguments from the feature flags will be
                     passed to the process accordingly
    :param log_level: the log level of the ConductR core process.
    :return: the pids of the core instances.
    """
    log = logging.getLogger(__name__)
    pids = []

    feature_conductr_roles = flatten(
        [feature.conductr_roles() for feature in features])
    # Role matching is enabled if there's role present for any of the ConductR agent instances.
    # We will check the first instance of the ConductR agent since it's where the bundles from feature flags
    # will be executing from.
    roles_enabled = len(
        sandbox_common.resolve_conductr_roles_by_instance(
            conductr_roles, feature_conductr_roles, 0)) > 0

    core_args = flatten([feature.conductr_args() for feature in features])

    for idx, bind_addr in enumerate(bind_addrs):
        commands = [
            '{}/bin/conductr'.format(core_extracted_dir),
            '-Dakka.loglevel={}'.format(log_level),
            '-Dconductr.ip={}'.format(bind_addr),
            '-Dconductr.resource-provider.match-offer-roles={}'.format(
                'on' if roles_enabled else 'off')
        ]
        if core_args:
            commands.extend(core_args)
        if idx > 0:
            commands.extend([
                '--seed', '{}:{}'.format(bind_addrs[0],
                                         CONDUCTR_AKKA_REMOTING_PORT)
            ])

        log.info('Starting ConductR core instance {} on {}..'.format(
            idx, bind_addr))
        pid = subprocess.Popen(commands,
                               cwd=core_extracted_dir,
                               start_new_session=True,
                               stdout=subprocess.DEVNULL,
                               stdin=subprocess.DEVNULL,
                               stderr=subprocess.DEVNULL).pid
        pids.append(pid)
    return pids
Ejemplo n.º 2
0
def start_agent_instances(agent_extracted_dir, bind_addrs, core_addrs,
                          conductr_roles, features, log_level):
    """
    Starts the ConductR agent process.

    Each instance is allocated an address to be bound based on the address range. For example:
    - Given 3 required agent instances
    - Given the address range input of 192.168.128.0/24
    - The instances will be allocated these addresses: 192.168.128.1, 192.168.128.2, 192.168.128.3

    :param agent_extracted_dir: the directory containing the files expanded from agent's binary .tgz
    :param bind_addrs: a list of addresses which the core instances will bind to.
                       If there are 3 instances of core required, there will be 3 addresses supplied.
    :param conductr_roles: list of roles specified by the end user.
    :param features: list of features which needs to be started.
                     This method won't start the feature, but if the roles is enabled (i.e. specified by the end user)
                     the agent must have correct roles assigned in order for features to be started correctly.
                     This method will also ensure extra arguments from the features are being passed into the agent
                     process.
    :param log_level: the log level of the ConductR agent process
    :return: the pids of the agent instances.
    """
    log = logging.getLogger(__name__)
    pids = []
    feature_conductr_roles = flatten(
        [feature.conductr_roles() for feature in features])
    agent_args = flatten([feature.conductr_args() for feature in features])
    for idx, bind_addr in enumerate(bind_addrs):
        core_addr = core_addrs[idx] if len(core_addrs) > idx else core_addrs[0]
        agent_roles = sandbox_common.resolve_conductr_roles_by_instance(
            conductr_roles, feature_conductr_roles, idx)

        commands = [
            '{}/bin/conductr-agent'.format(agent_extracted_dir),
            '-Dakka.loglevel={}'.format(log_level),
            '-Dconductr.agent.ip={}'.format(bind_addr), '--core-node',
            '{}:{}'.format(core_addr, CONDUCTR_AKKA_REMOTING_PORT)
        ] + [
            '-Dconductr.agent.roles.{}={}'.format(j, role)
            for j, role in enumerate(agent_roles)
        ] + agent_args
        log.info('Starting ConductR agent instance {} on {}..'.format(
            idx, bind_addr))
        pid = subprocess.Popen(commands,
                               cwd=agent_extracted_dir,
                               start_new_session=True,
                               stdout=subprocess.DEVNULL,
                               stdin=subprocess.DEVNULL,
                               stderr=subprocess.DEVNULL).pid
        pids.append(pid)
    return pids
Ejemplo n.º 3
0
def start_nodes(args, nr_of_containers, features):
    container_names = []
    log = logging.getLogger(__name__)
    log.info(h1('Starting ConductR'))
    ports = collect_ports(args, features)
    conductr_args = flatten([feature.conductr_args() for feature in features])
    conductr_features = flatten(
        [feature.conductr_feature_envs() for feature in features])
    feature_conductr_roles = flatten(
        [feature.conductr_roles() for feature in features])
    for i in range(nr_of_containers):
        container_name = '{prefix}{nr}'.format(prefix=CONDUCTR_NAME_PREFIX,
                                               nr=i)
        container_names.append(container_name)
        # Display the ports on the command line. Only if the user specifies a certain feature, then
        # the corresponding port will be displayed when running 'sandbox run' or 'sandbox debug'
        if ports:
            host_ip = host.DOCKER_IP
            ports_desc = ' exposing ' + ', '.join([
                '{}:{}'.format(host_ip, map_port(i, port))
                for port in sorted(ports)
            ])
        else:
            ports_desc = ''
        log.info('Starting container {container}{port_desc}..'.format(
            container=container_name, port_desc=ports_desc))
        cond0_ip = inspect_cond0_ip() if i > 0 else None
        conductr_container_roles = sandbox_common.resolve_conductr_roles_by_instance(
            args.conductr_roles, feature_conductr_roles, i)
        run_conductr_cmd(
            i, nr_of_containers, container_name, cond0_ip, args.envs,
            '{image}:{version}'.format(image=args.image,
                                       version=args.image_version),
            args.log_level, ports, args.bundle_http_port, conductr_features,
            conductr_container_roles, conductr_args)
    return container_names
Ejemplo n.º 4
0
def collect_ports(args, features):
    """Return a Set of ports based on the ports of each enabled feature and the ports specified by the user"""

    feature_ports = flatten([feature.ports for feature in features])
    return set(args.ports + feature_ports)