예제 #1
0
    def helper_resolve_linked_datasets(labbook, info):
        submodules = labbook.git.list_submodules()
        datasets = list()
        for submodule in submodules:
            try:
                namespace, dataset_name = submodule['name'].split("&")
                submodule_dir = os.path.join(labbook.root_dir, '.gigantum', 'datasets', namespace, dataset_name)
                ds = InventoryManager().load_dataset_from_directory(submodule_dir, author=get_logged_in_author())
                ds.namespace = namespace
                info.context.dataset_loader.prime(f"{get_logged_in_username()}&{namespace}&{dataset_name}", ds)

                datasets.append(Dataset(owner=namespace, name=dataset_name))
            except InventoryException:
                continue

        return datasets
예제 #2
0
    def mutate_and_get_payload(cls,
                               root,
                               info,
                               dataset_owner,
                               dataset_name,
                               keys,
                               client_mutation_id=None):
        logged_in_username = get_logged_in_username()
        ds = InventoryManager().load_dataset(logged_in_username,
                                             dataset_owner,
                                             dataset_name,
                                             author=get_logged_in_author())
        ds.namespace = dataset_owner
        m = Manifest(ds, logged_in_username)

        with ds.lock():
            m.delete(keys)

        return DeleteDatasetFiles(success=True)
예제 #3
0
    def mutate_and_get_payload(cls,
                               root,
                               info,
                               dataset_owner,
                               dataset_name,
                               src_path,
                               dst_path,
                               client_mutation_id=None):
        logged_in_username = get_logged_in_username()
        ds = InventoryManager().load_dataset(logged_in_username,
                                             dataset_owner,
                                             dataset_name,
                                             author=get_logged_in_author())
        ds.namespace = dataset_owner
        m = Manifest(ds, logged_in_username)

        with ds.lock():
            edge_data = m.move(src_path, dst_path)

        file_edges = list()
        for edge_dict in edge_data:
            file_edges.append(
                DatasetFile(owner=dataset_owner,
                            name=dataset_name,
                            key=edge_dict['key'],
                            is_dir=edge_dict['is_dir'],
                            is_favorite=edge_dict['is_favorite'],
                            modified_at=edge_dict['modified_at'],
                            is_local=edge_dict['is_local'],
                            size=str(edge_dict['size'])))

        cursors = [
            base64.b64encode("{}".format(cnt).encode("UTF-8")).decode("UTF-8")
            for cnt, x in enumerate(file_edges)
        ]

        edge_objs = [
            DatasetFileConnection.Edge(node=e, cursor=c)
            for e, c in zip(file_edges, cursors)
        ]
        return MoveDatasetFile(updated_edges=edge_objs)
예제 #4
0
    def mutate_and_get_payload(cls,
                               root,
                               info,
                               dataset_owner,
                               dataset_name,
                               key,
                               client_mutation_id=None):
        logged_in_username = get_logged_in_username()
        ds = InventoryManager().load_dataset(logged_in_username,
                                             dataset_owner,
                                             dataset_name,
                                             author=get_logged_in_author())
        ds.namespace = dataset_owner
        m = Manifest(ds, logged_in_username)

        if key[-1] != '/':
            raise ValueError(
                "Provided relative path must end in `/` to indicate it is a directory"
            )

        with ds.lock():
            file_info = m.create_directory(key)

        create_data = {
            'owner': dataset_owner,
            'name': dataset_name,
            'key': file_info['key'],
            '_file_info': file_info
        }

        # TODO: Fix cursor implementation, this currently doesn't make sense
        cursor = base64.b64encode(f"{0}".encode('utf-8'))

        return MakeDatasetDirectory(
            new_dataset_file_edge=DatasetFileConnection.Edge(
                node=DatasetFile(**create_data), cursor=cursor))
예제 #5
0
def start_labbook_container(labbook_root: str,
                            config_path: str,
                            username: str,
                            override_image_id: Optional[str] = None) -> str:
    """ Start a Docker container from a given image_name.

    Args:
        labbook_root: Root dir of labbook
        config_path: Path to LabBook configuration file.
        override_image_id: Optional explicit docker image id (do not infer).
        username: Username of active user. Do not use with override_image_id.

    Returns:
        Tuple containing docker container id, dict mapping of exposed ports.

    Raises:
    """
    if username and override_image_id:
        raise ValueError(
            'Argument username and override_image_id cannot both be set')

    lb = InventoryManager(
        config_file=config_path).load_labbook_from_directory(labbook_root)
    if not override_image_id:
        owner = InventoryManager().query_owner(lb)
        tag = infer_docker_image_name(lb.name, owner, username)
    else:
        tag = override_image_id

    mnt_point = labbook_root.replace('/mnt/gigantum',
                                     os.environ['HOST_WORK_DIR'])
    volumes_dict = {
        mnt_point: {
            'bind': '/mnt/labbook',
            'mode': 'cached'
        },
        'labmanager_share_vol': {
            'bind': '/mnt/share',
            'mode': 'rw'
        }
    }

    # Set up additional bind mounts for datasets if needed.
    submodules = lb.git.list_submodules()
    for submodule in submodules:
        try:
            namespace, dataset_name = submodule['name'].split("&")
            submodule_dir = os.path.join(lb.root_dir, '.gigantum', 'datasets',
                                         namespace, dataset_name)
            ds = InventoryManager().load_dataset_from_directory(submodule_dir)
            ds.namespace = namespace

            cm_class = get_cache_manager_class(ds.client_config)
            cm = cm_class(ds, username)
            ds_cache_dir = cm.current_revision_dir.replace(
                '/mnt/gigantum', os.environ['HOST_WORK_DIR'])
            volumes_dict[ds_cache_dir] = {
                'bind': f'/mnt/labbook/input/{ds.name}',
                'mode': 'ro'
            }
        except InventoryException:
            continue

    # If re-mapping permissions, be sure to configure the container
    if 'LOCAL_USER_ID' in os.environ:
        env_var = [f"LOCAL_USER_ID={os.environ['LOCAL_USER_ID']}"]
    else:
        env_var = ["WINDOWS_HOST=1"]

    # Get resource limits
    resource_args = dict()
    memory_limit = lb.client_config.config['container']['memory']
    cpu_limit = lb.client_config.config['container']['cpu']
    gpu_shared_mem = lb.client_config.config['container']['gpu_shared_mem']
    if memory_limit:
        # If memory_limit not None, pass to Docker to limit memory allocation to container
        resource_args["mem_limit"] = memory_limit
    if cpu_limit:
        # If cpu_limit not None, pass to Docker to limit CPU allocation to container
        # "nano_cpus" is an integer in factional parts of a CPU
        resource_args["nano_cpus"] = round(cpu_limit * 1e9)

    docker_client = get_docker_client()

    # run with nvidia-docker if we have GPU support on the Host compatible with the project
    should_run_nvidia, reason = should_launch_with_cuda_support(
        lb.cuda_version)
    if should_run_nvidia:
        logger.info(f"Launching container with GPU support:{reason}")
        if gpu_shared_mem:
            resource_args["shm_size"] = gpu_shared_mem

        container_id = docker_client.containers.run(tag,
                                                    detach=True,
                                                    init=True,
                                                    name=tag,
                                                    environment=env_var,
                                                    volumes=volumes_dict,
                                                    runtime='nvidia',
                                                    **resource_args).id
    else:
        logger.info(f"Launching container without GPU support. {reason}")
        container_id = docker_client.containers.run(tag,
                                                    detach=True,
                                                    init=True,
                                                    name=tag,
                                                    environment=env_var,
                                                    volumes=volumes_dict,
                                                    **resource_args).id

    labmanager_ip = ""
    try:
        labmanager_ip = get_labmanager_ip() or ""
    except IndexError:
        logger.warning("Cannot find labmanager IP")

    labmanager_ip = labmanager_ip.strip()
    cmd = f"echo {labmanager_ip} > /home/giguser/labmanager_ip"
    for timeout in range(20):
        time.sleep(0.5)
        if docker_client.containers.get(container_id).status == 'running':
            r = docker_client.containers.get(container_id).exec_run(
                f'sh -c "{cmd}"')
            logger.info(f"Response to write labmanager_ip in {tag}: {r}")
            break
    else:
        logger.error(
            "After 10 seconds could not write IP to labmanager container."
            f" Container status = {docker_client.containers.get(container_id).status}"
        )
    return container_id