Source code for train_lib.docker_util.docker_ops

import tarfile
from io import BytesIO
import os
import json

import docker


[docs]def extract_train_config(img: str, config_path: str = "/opt/train_config.json") -> dict: """ Extract the train configuration json from the specified image and return it as a dictionary :param img: docker image identifier :param config_path: path of the config file inside the image :return: dictionary containing the security values stored inside the train:config.json """ with extract_archive(img, config_path) as config_archive: config_file = config_archive.extractfile("train_config.json") data = config_file.read() train_config = json.loads(data) return train_config
[docs]def extract_query_json(img: str, query_file_path: str = "/opt/pht_train/query.json") -> dict: """ Extract query.json file from the specified image and return it as a dictionary :param img: docker image identifier :param query_file_path: path of the query file inside the image :return: dictionary containing the security values stored inside the train:config.json """ config_archive = extract_archive(img, query_file_path) query_file = config_archive.extractfile("query.json") data = query_file.read() query_dict = json.loads(data) return query_dict
[docs]def files_from_archive(tar_archive: tarfile.TarFile): """ Extracts only the actual files from the given tarfile :param tar_archive: the tar archive from which to extract the files :return: List of file object extracted from the tar archive """ file_members = [] # Find the actual files in the archive for member in tar_archive.getmembers(): if member.isreg(): # extract the actual files from the archive file_members.append(member) files = [] file_names = [] for file_member in file_members: files.append(tar_archive.extractfile(file_member)) # Extract the file names without the top level directory from the file members file_names.append("/".join(file_member.name.split("/")[1:])) return files, file_names
[docs]def result_files_from_archive(tar_archive: tarfile.TarFile): """ Extracts the result files from the given archive returning the files as well as the director structure contained in the tar archive for later reconstruction :param tar_archive: the tar archive from which to extract the files :return: List of file object extracted from the tar archive """ file_members = [] for member in tar_archive.getmembers(): if member.isreg(): # skip if the TarInfo is not files file_members.append(member) files = [] for file_member in file_members: files.append(tar_archive.extractfile(file_member)) return files, file_members, tar_archive.getmembers()
[docs]def extract_archive(img: str, extract_path: str) -> tarfile.TarFile: """ Extracts a file or folder at the given path from the given docker image :param img: identifier of the img to extract the file from :param extract_path: path of the file or directory to extract from the container :return: tar archive containing the the extracted path """ client = docker.from_env() data = client.containers.create(img) stream, stat = data.get_archive(extract_path) file_obj = BytesIO() for i in stream: file_obj.write(i) file_obj.seek(0) tar = tarfile.open(mode="r", fileobj=file_obj) return tar
[docs]def add_archive(img: str, archive: BytesIO, path: str): """ Adds a given tar archive to a given docker image at the specified path :param img: identifier of the image <repository>:<tag> :param archive: tar archive to be added to the image :param path: path at which the tar archive will be added inside the image :return: """ client = docker.from_env() data = client.containers.create(img) data.put_archive(path, archive) data.wait() # Get repository and tag for committing the container to an image repository, tag = img.split(":") data.commit(repository=repository, tag=tag) data.wait() data.remove()