|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +''' |
| 4 | +docker.py: an example of converting a docker to a singularity image using |
| 5 | +singularity-python. This is now dated and not the recommended standard. The recommended way |
| 6 | +is to use singularity natively, see: |
| 7 | +
|
| 8 | +http://singularity.lbl.gov/docs-docker |
| 9 | +
|
| 10 | +''' |
| 11 | + |
| 12 | +from singularity.utils import check_install, getsudo, run_command |
| 13 | +from singularity.package import get_image_hash |
| 14 | +from singularity.cli import Singularity |
| 15 | +import tempfile |
| 16 | +import tarfile |
| 17 | +import requests |
| 18 | +import shutil |
| 19 | +import os |
| 20 | + |
| 21 | +dockerhub = "" |
| 22 | + |
| 23 | +def docker2singularity(docker_image,output_folder=None): |
| 24 | + '''docker2singulrity is a wrapper for the Singularity.docker2singularity |
| 25 | + client function. Does not currently include runscript (/singularity) in image, |
| 26 | + but does export full docker image spec under /singularity.json |
| 27 | + :param docker_image: the full docker repo/image,eg "ubuntu:latest" |
| 28 | + :param output_folder: the output folder to create the image in. If not |
| 29 | + specified, will use pwd. |
| 30 | + ''' |
| 31 | + |
| 32 | + S = Singularity() |
| 33 | + docker_image = S.docker2singularity(docker_image=docker_image, |
| 34 | + output_dir=output_folder) |
| 35 | + return docker_image |
| 36 | + |
| 37 | + |
| 38 | +def get_docker_guts(docker_image,sudopw=None): |
| 39 | + '''get_docker_guts will get the files and folders within a docker image by converting to tar first. |
| 40 | + :param docker_image: the name of the docker image, doesn't have to be on local machine (eg, ubuntu:latest) |
| 41 | + :param sudopw: sudopw to use in function. |
| 42 | + ''' |
| 43 | + if check_install('docker') == True: |
| 44 | + |
| 45 | + # get sudopwd once to send to all following commands |
| 46 | + if sudopw == None: |
| 47 | + print("\nYOU MUST ENTER PASSWORD TO CONTINUE AND USE DOCKER:") |
| 48 | + sudopw = getsudo() |
| 49 | + |
| 50 | + cmd = ['docker','run','-d',docker_image,'tail','-f','/dev/null'] |
| 51 | + runningid = run_command(cmd=cmd,sudopw=sudopw) |
| 52 | + # sha256:d59bdb51bb5c4fb7b2c8d90ae445e0720c169c553bcf553f67cb9dd208a4ec15 |
| 53 | + |
| 54 | + # Take the first 12 characters to get id of container |
| 55 | + container_id=runningid[0:12] |
| 56 | + |
| 57 | + # Get image name |
| 58 | + cmd = ['docker','inspect','--format="{{.Config.Image}}"',container_id] |
| 59 | + image_name = run_command(cmd=cmd,sudopw=sudopw) |
| 60 | + |
| 61 | + # Export tar to get files and folders |
| 62 | + print("Extracting filesystem from %s, please wait..." %(docker_image)) |
| 63 | + tmpdir = tempfile.mkdtemp() |
| 64 | + tmptar = "%s/%s.tar" %(tmpdir,container_id) |
| 65 | + cmd = ['docker','export',container_id,'>',tmptar] |
| 66 | + run_command(cmd=cmd,sudopw=sudopw,suppress=True) |
| 67 | + |
| 68 | + # Give the list a VERSION based on the tarfile |
| 69 | + version = get_image_hash(tmptar) |
| 70 | + dockerstuffs = {"VERSION": version, |
| 71 | + "image":image_name} |
| 72 | + |
| 73 | + # Read in files and folders from the tar! |
| 74 | + tar = tarfile.open(tmptar) |
| 75 | + members = tar.getmembers() |
| 76 | + files = [x.path for x in members if x.isfile()] |
| 77 | + folders = [x.path for x in members if x.isdir()] |
| 78 | + dockerstuffs["files.txt"] = files |
| 79 | + dockerstuffs["folders.txt"] = folders |
| 80 | + |
| 81 | + # Finally,stop the container |
| 82 | + print("Stopping container... please wait!") |
| 83 | + run_command(cmd=['docker','stop',container_id],sudopw=sudopw) |
| 84 | + |
| 85 | + # clean up the temporary directory |
| 86 | + shutil.rmtree(tmpdir) |
| 87 | + |
| 88 | + return dockerstuffs |
0 commit comments