def setup_docker_vol():
    """Fixture to create a Build instance with a test image name that does not exist and cleanup after"""
    client = get_docker_client()
    vol = client.volumes.create(name='test-labmanager-volume')

    yield 'test-labmanager-volume', client

    # Remove image post test if it still exists
    vol.remove()
def cleanup_docker_vol():
    """Fixture to create a Build instance with a test image name that does not exist and cleanup after"""
    yield 'test-labmanager-volume'

    # Remove image post test if it still exists
    client = get_docker_client()
    try:
        vol = client.volumes.get('test-labmanager-volume')
        vol.remove()
    except NotFound:
        pass
예제 #3
0
    def attach(self) -> None:
        """Method to attach to a running dev container for debugging or interaction with the sw

        Returns:
            None
        """
        client = get_docker_client()

        containers = client.containers.list()

        container_id = None
        for container in containers:
            if "_labmanager_" in container.name:
                container_id = container.id

        if not container_id:
            print("  \nNo Client dev container running. Did you run `gtm dev start` first?\n")
            sys.exit(1)

        if self._docker_compose_exists():
            override_command = '/bin/bash -c \"cd /opt/project; echo \'-- Run /opt/setup.sh to switch to giguser context\'; /bin/bash"'
            command = 'docker exec -it {} {}'.format(container_id, override_command)
            os.system(command)
예제 #4
0
 def __init__(self, image_name: str):
     """Constructor"""
     self.image_name = image_name
     self._container_name = None
     self.docker_client = get_docker_client()
예제 #5
0
    def build_image(self,
                    no_cache: bool = False,
                    build_args: dict = None,
                    docker_args: dict = None) -> None:
        """Method to build the Gigantum Client Docker Image

        Args:
            no_cache(bool): Flag indicating if the docker cache should be ignored
            build_args(dict): Variables to prepare files for build
            docker_args(dict): Variables passed to docker during the build process

        build_args items:
            supervisor_file: The path to the target supervisor file to move into build dir
            config_override_file: The path to the target config file override file

        docker_args items:
            CLIENT_CONFIG_FILE: The client config file
            NGINX_UI_CONFIG: Nginx config file for the UI
            NGINX_API_CONFIG: Nginx config file for the API
            SUPERVISOR_CONFIG: Supervisord config file
            ENTRYPOINT_FILE: Entrypoint file
        """
        # Check if *nix or windows
        # Doing this at the top of the function so it's clear this variable is
        # available
        if platform.system() == 'Windows':
            is_windows = True
        else:
            is_windows = False

        self.docker_client = get_docker_client()
        client_root_dir = get_client_root()
        build_dir = os.path.join(client_root_dir, build_args['build_dir'])
        if os.path.exists(build_dir) is False:
            os.makedirs(build_dir)

        named_image = "{}:{}".format(self.image_name, self.get_image_tag())
        if self.image_exists(named_image):
            # Image found. Make sure container isn't running.
            self.prune_container(named_image)

        # Write updated config file
        base_config_file = os.path.join(client_root_dir, "packages", 'gtmcore',
                                        'gtmcore', 'configuration', 'config',
                                        'labmanager.yaml.default')
        final_config_file = docker_args['CLIENT_CONFIG_FILE']

        with open(base_config_file, "rt") as cf:
            base_data = yaml.load(cf)
        with open(
                os.path.join(client_root_dir,
                             build_args['config_override_file']), "rt") as cf:
            overwrite_data = yaml.load(cf)

        # Merge sub-sections together
        for key in base_data:
            if key in overwrite_data:
                base_data[key].update(overwrite_data[key])

        # Add Build Info
        build_date = datetime.datetime.utcnow().strftime('%Y-%m-%d')
        short_hash = get_current_commit_hash()[:8]
        base_data[
            'build_info'] = f"Gigantum Client :: {build_date} :: {short_hash}"

        # Write out updated config file
        with open(os.path.join(client_root_dir, final_config_file),
                  "wt") as cf:
            cf.write(yaml.dump(base_data, default_flow_style=False))

        # Write final supervisor file to set CHP parameters
        base_supervisor = os.path.join(client_root_dir,
                                       build_args['supervisor_file'])
        final_supervisor = os.path.join(client_root_dir,
                                        docker_args['SUPERVISOR_CONFIG'])

        with open(base_supervisor, 'rt') as source:
            with open(final_supervisor, 'wt') as dest:
                supervisor_data = source.read()

                ext_proxy_port = base_data['proxy']["external_proxy_port"]
                api_port = base_data['proxy']['api_port']

                dest.write(f"""{supervisor_data}\n\n
[program:chp]
command=configurable-http-proxy --ip=0.0.0.0 --port={ext_proxy_port} --api-port={api_port} --default-target='http://*****:*****@gigantum.com'
        }

        # Delete .pyc files in case dev tools used on something not ubuntu before building
        self._remove_pyc(os.path.join(client_root_dir, "packages"))

        # Build image
        dockerfile_path = os.path.join(client_root_dir, 'resources', 'docker',
                                       'Dockerfile')
        print(
            "\n\n*** Building Gigantum Client image `{}`, please wait...\n\n".
            format(self.image_name))

        if is_windows:
            dockerfile_path = dockerize_windows_path(
                os.path.relpath(dockerfile_path, client_root_dir))
            client_root_dir = dockerize_windows_path(client_root_dir)
            for path_var in ['CLIENT_CONFIG_FILE', 'SUPERVISOR_CONFIG']:
                docker_args[path_var] = dockerize_windows_path(
                    docker_args[path_var])

        [
            print(ln[list(ln.keys())[0]], end='')
            for ln in self.docker_client.api.build(path=client_root_dir,
                                                   dockerfile=dockerfile_path,
                                                   tag=named_image,
                                                   labels=labels,
                                                   nocache=no_cache,
                                                   pull=True,
                                                   rm=True,
                                                   decode=True,
                                                   buildargs=docker_args)
        ]

        # Tag with `latest` for auto-detection of image on launch
        # TODO: Rename container to gigantum/client
        self.docker_client.api.tag(named_image, self.image_name, 'latest')