Last active
March 29, 2017 12:02
-
-
Save filipposc5/fd123fb269e55f49b3363876c47943ab to your computer and use it in GitHub Desktop.
Docker Save - export docker image, calculate md5 / sha 256 on the fly and write to disk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Small util to avoid hammering the disk by reading and writing files | |
| # all the time. Attempts to export the docker container, calculate md5 | |
| # and sha256 sums on the fly, compress, gpg encrypt and write it to disk | |
| # | |
| # Some credit to some Stack Overflow posts is due! | |
| import hashlib | |
| import os | |
| import resource | |
| import subprocess | |
| import shlex | |
| import sys | |
| import time | |
| def report_usage(): | |
| print "pid: ", os.getpid() | |
| print "Max RSS used = {}".format( | |
| resource.getrusage(resource.RUSAGE_SELF).ru_maxrss) | |
| def report_status(c, from_time, to_time): | |
| print "wrote {} bytes ({:.2f} MB/s)".format(c, long(c)/(to_time-from_time)/1024.0/1024.0) | |
| def check_args(): | |
| if len(sys.argv) != 3: | |
| print "Usage: {} <container name> <tag>".format(sys.argv[0]) | |
| sys.exit(1) | |
| # From here on this code could be converted to a class eg Packager/Exporter | |
| # buffer size | |
| bufsz = 4096 * 10 | |
| # counter | |
| c = 0 | |
| now = time.time() | |
| report_usage() | |
| md5sum = hashlib.md5() | |
| sha256 = hashlib.sha256() | |
| check_args() | |
| (container, tag) = sys.argv[1:] | |
| dockercmd = 'docker save "{}:{}"'.format(container, tag) | |
| print dockercmd | |
| proc = subprocess.Popen(shlex.split(dockercmd), stdout=subprocess.PIPE) | |
| output = proc.stdout | |
| file_out = open("output.tar", "wb") | |
| #gz_cmd = "gzip -c - " | |
| #gz_proc = subprocess.Popen(shlex.split(gz_cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE) | |
| gpg_stdin_pass = True | |
| if gpg_stdin_pass: | |
| gpg_cmd = "gpg --passphrase-fd 0 -c -" | |
| else: | |
| gpg_cmd = "gpg --passphrase PASSPHRASE -c -" | |
| gpg_proc = subprocess.Popen(shlex.split(gpg_cmd), stdin=subprocess.PIPE, stdout=file_out) | |
| #f = open("foo", "wb") | |
| #gpg_proc = subprocess.Popen(shlex.split(gpg_cmd), stdin=subprocess.PIPE, stdout=subprocess.PIPE) | |
| if gpg_stdin_pass: | |
| gpg_proc.stdin.write("PASSPHRASE\n") | |
| gpg_proc.stdin.flush() | |
| #f = open("foo", "wb") | |
| begin = time.time() | |
| for chunk in iter(lambda: output.read(bufsz), b''): | |
| # count the bytes | |
| c += len(chunk) | |
| # calculate the sum | |
| md5sum.update(chunk) | |
| sha256.update(chunk) | |
| # write to gpg | |
| gpg_proc.stdin.write(chunk) | |
| # write to disk | |
| #f.write(chunk) | |
| if (time.time() - now) > 6: | |
| now = time.time() | |
| report_status(c, begin, now) | |
| # report status if all done | |
| report_status(c, begin, time.time()) | |
| # Ensure buffer is flushed | |
| gpg_proc.stdin.flush() | |
| #f.close() | |
| manifest = { | |
| "md5": md5sum.hexdigest(), | |
| "sha256": sha256.hexdigest(), | |
| "container": container, | |
| "tag": tag, | |
| "c_size": c | |
| } | |
| print manifest | |
| report_usage() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
new output: