def update_charm_status():
    tag = config.get('image-tag')

    ctx = get_context()

    for image in IMAGES:
        try:
            docker_utils.pull(image, tag)
        except Exception as e:
            log("Can't load image {}".format(e))
            status_set('blocked',
                       'Image could not be pulled: {}:{}'.format(image, tag))
            return

    deployer_image = "contrail-command-deployer"
    deploy_ccd_code(deployer_image, tag)

    if not ctx.get("cloud_orchestrator"):
        status_set('blocked', 'Missing cloud orchestrator info in relations.')
        return

    changed = common_utils.render_and_log('cluster_config.yml.j2',
                                          '/cluster_config.yml', ctx)

    if changed or not config.get("command_deployed"):
        dst = '/' + deployer_image + '/docker/deploy_contrail_command'
        check_call('./files/deploy_contrail_command.sh ' + dst, shell=True)
        config["command_deployed"] = True

    update_status()

    version = docker_utils.get_contrail_version("contrail-command", tag)
    application_version_set(version)
Example #2
0
def update_services_status(module, services):
    try:
        output = check_output(
            "export CONTRAIL_STATUS_CONTAINER_NAME=contrail-status-{} ; contrail-status"
            .format(module),
            shell=True).decode('UTF-8')
    except Exception as e:
        log("Container is not ready to get contrail-status: " + str(e))
        status_set("waiting", "Waiting services to run in container")
        return False

    statuses = dict()
    group = None
    for line in output.splitlines()[1:]:
        words = line.split()
        if len(words) == 4 and words[0] == "==" and words[3] == "==":
            group = words[2]
            continue
        if len(words) == 0:
            group = None
            continue
        if group and len(words) >= 2 and group in services:
            srv = words[0].split(":")[0]
            statuses.setdefault(group,
                                dict())[srv] = (words[1], " ".join(words[2:]))

    for group in services:
        if group not in statuses:
            status_set("waiting",
                       "POD " + group + " is absent in the contrail-status")
            return False
        for srv in services[group]:
            if srv not in statuses[group]:
                status_set("waiting",
                           srv + " is absent in the contrail-status")
                return False
            status, desc = statuses[group].get(srv)
            if status not in ["active", "backup"]:
                workload = "waiting" if status == "initializing" else "blocked"
                status_set(
                    workload, "{} is not ready. Reason: {}".format(
                        srv, desc if desc else status))
                return False

    status_set("active", "Unit is ready")
    try:
        tag = config.get('image-tag')
        docker_utils.pull("contrail-base", tag)
        version = docker_utils.get_contrail_version("contrail-base", tag)
        application_version_set(version)
    except CalledProcessError as e:
        log("Couldn't detect installed application version: " + str(e))
    return True
Example #3
0
def check_run_prerequisites(name, config_name, update_config_func, services):
    if is_container_launched(name):
        # already launched. just sync config if needed.
        check = True
        if update_config_func and update_config_func():
            check = apply_config_in_container(name, config_name)
        if check:
            update_services_status(name, services)
        return False

    if is_container_present(name):
        status_set(
            "blocked",
            "Container is present but is not running. Run or remove it.")
        return False

    image_name = config.get("image-name")
    image_tag = config.get("image-tag")
    if not image_name or not image_tag:
        image_name, image_tag = load_docker_image(name)
        if not image_name or not image_tag:
            status_set(
                "blocked", "No image is available. Resourse is not "
                "attached and there are no image-name/image-tag "
                "defined in charm configuration.")
            return False
        config["image-name"] = image_name
        config["image-tag"] = image_tag
        config.save()

    if "version" not in config:
        # current jinja2 doesn't support version_compare filter.
        # so build version variable as: a.b.c.d => a*1e4 + b*1e2 + c and then
        # compare it with integers like: 40002, 40100
        # 4.0.0 => 40000
        # 4.0.1 => 40001
        # 4.0.2 => 40002
        # 4.1.0 => 40100
        version = get_contrail_version()
        application_version_set(version)
        config["version_with_build"] = version
        version = version.split('-')[0].split('.')
        m = int(version[0])
        r = int(version[1]) if len(version) > 1 else 0
        a = int(version[2]) if len(version) > 2 else 0
        config["version"] = (m * 1e4) + (r * 1e2) + a
        config.save()

    return True
Example #4
0
def update_services_status(module, services):
    contrail_version = get_contrail_version()

    if contrail_version > 1912:
        statuses = get_contrail_status_json(module, services)
    else:
        statuses = get_contrail_status_txt(module, services)

    if not statuses:
        return False

    for group in services:
        if group not in statuses:
            status_set("waiting",
                       "POD " + group + " is absent in the contrail-status")
            return False
        # expected services
        for srv in services[group]:
            # actual statuses
            # actual service name can be present as a several workers like 'api-0', 'api-1', ...
            stats = [
                statuses[group][x] for x in statuses[group]
                if x == srv or x.startswith(srv + '-')
            ]
            if not stats:
                status_set("waiting",
                           srv + " is absent in the contrail-status")
                return False
            for status in stats:
                if status not in ["active", "backup"]:
                    workload = "waiting" if status == "initializing" else "blocked"
                    status_set(
                        workload,
                        "{} is not ready. Reason: {}".format(srv, status))
                    return False

    status_set("active", "Unit is ready")
    try:
        tag = config.get('image-tag')
        docker_utils.pull("contrail-node-init", tag)
        version = docker_utils.get_contrail_version("contrail-node-init", tag)
        application_version_set(version)
    except CalledProcessError as e:
        log("Couldn't detect installed application version: " + str(e))
    return True
def deploy_openstack_code(image, component, env_dict=None):
    tag = config.get('image-tag')
    docker_utils.pull(image, tag)

    # remove previous attempt
    docker_utils.remove_container_by_image(image)

    path = get_component_sys_paths(component)
    files = PLUGIN_FILES[component]
    name = docker_utils.create(image, tag)
    try:
        for item in files:
            dst = item.format(python_path=path)
            try:
                src = files[item]
                if isinstance(src, tuple):
                    src = src[0]
                tmp_folder = os.path.join('/tmp', str(uuid.uuid4()))
                # docker copies content of src folder if dst folder is not present
                # and directory itself if dst is present
                # therefore we copy content from container into tmp and then content of tmp into dst
                docker_utils.cp(name, src, tmp_folder)
                copy_tree(tmp_folder, dst)
                shutil.rmtree(tmp_folder, ignore_errors=True)
            except Exception:
                if not isinstance(files[item], tuple):
                    raise
                for folder in files[item][1]:
                    try:
                        docker_utils.cp(name, folder, dst)
                    except Exception:
                        pass
    finally:
        docker_utils.remove_container_by_image(image)

    try:
        version = docker_utils.get_contrail_version(image, tag)
        application_version_set(version)
    except CalledProcessError as e:
        log("Couldn't detect installed application version: " + str(e))
Example #6
0
def update_services_status(module, services):
    tag = config.get('image-tag')
    contrail_version = get_contrail_version()

    if contrail_version > 1912:
        statuses = get_contrail_status_json(module, services)
    else:
        statuses = get_contrail_status_txt(module, services)

    if not statuses:
        return False

    for group in services:
        if group not in statuses:
            status_set("waiting",
                       "POD " + group + " is absent in the contrail-status")
            return False
        for srv in services[group]:
            if not any(srv in key for key in statuses[group]):
                status_set("waiting",
                           srv + " is absent in the contrail-status")
                return False
            status = next(stat[srv] for stat in statuses[group] if srv in stat)
            if status not in ["active", "backup"]:
                workload = "waiting" if status == "initializing" else "blocked"
                status_set(workload,
                           "{} is not ready. Reason: {}".format(srv, status))
                return False

    status_set("active", "Unit is ready")
    try:
        tag = config.get('image-tag')
        docker_utils.pull("contrail-node-init", tag)
        version = docker_utils.get_contrail_version("contrail-node-init", tag)
        application_version_set(version)
    except CalledProcessError as e:
        log("Couldn't detect installed application version: " + str(e))
    return True
Example #7
0
def update_charm_status():
    tag = config.get('image-tag')
    ctx = get_context()

    deployer_image = "contrail-command-deployer"
    deploy_ccd_code(deployer_image, tag)

    if not ctx.get("cloud_orchestrator"):
        status_set('blocked', 'Missing cloud orchestrator info in relations.')
        return

    changed = common_utils.render_and_log('cluster_config.yml.j2',
                                          '/cluster_config.yml', ctx)

    if changed or not config.get("command_deployed"):
        dst = '/' + deployer_image + '/docker/deploy_contrail_command'
        check_call('./files/deploy_contrail_command.sh ' + dst, shell=True)
        config["command_deployed"] = True

    update_status()

    version = docker_utils.get_contrail_version("contrail-command", tag)
    application_version_set(version)