From 850931573cba9c3b310750d64a699cbc823df387 Mon Sep 17 00:00:00 2001 From: LuisBlanche Date: Fri, 6 Nov 2020 15:41:06 +0100 Subject: [PATCH] feat: update to python 3 --- .travis.yml | 4 +- docker_push_ssh/cli.py | 323 ++++++++++++++++++++++++------------- docker_push_ssh/command.py | 2 +- 3 files changed, 210 insertions(+), 119 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d3e7f2..65327d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,8 @@ sudo: required language: python python: - - "2.7" + - "3.7" script: - bash ./test.sh services: - - docker \ No newline at end of file + - docker diff --git a/docker_push_ssh/cli.py b/docker_push_ssh/cli.py index 0a88f57..f0714f2 100644 --- a/docker_push_ssh/cli.py +++ b/docker_push_ssh/cli.py @@ -16,20 +16,22 @@ import socket import sys import time -import urllib2 -import httplib +from http import client +from urllib import request +from urllib.error import URLError -from command import Command +from .command import Command def getLocalIp(): import socket + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) localIp = s.getsockname()[0] s.close() - print("[Local IP] " + localIp) + print(("[Local IP] " + localIp)) return localIp @@ -39,8 +41,8 @@ def waitForSshTunnelInit(retries=20, delay=1.0): time.sleep(delay) try: - response = urllib2.urlopen("http://localhost:5000/v2/", timeout=5) - except (socket.error, urllib2.URLError, httplib.BadStatusLine): + response = request.urlopen("http://localhost:5000/v2/", timeout=5) + except (socket.error, URLError, client.BadStatusLine): continue if response.getcode() == 200: @@ -52,46 +54,71 @@ def waitForSshTunnelInit(retries=20, delay=1.0): def pushImage(dockerImageTagList, sshHost, sshIdentityFile, sshPort, primeImages, registryPort): # Setup remote docker registry print("Setting up secure private registry... ") - registryCommandResult = Command("ssh", [ - "-i", sshIdentityFile, - "-p", sshPort, - "-o", "StrictHostKeyChecking=no", - "-o", "UserKnownHostsFile=/dev/null", - sshHost, - "sh -l -c \"docker run -d -v /etc/docker-push-ssh/registry:/var/lib/registry " + - "--name docker-push-ssh-registry -p 127.0.0.1:{0}:5000 registry\"".format(registryPort) - ]).execute() + registryCommandResult = Command( + "ssh", + [ + "-i", + sshIdentityFile, + "-p", + sshPort, + "-o", + "StrictHostKeyChecking=no", + "-o", + "UserKnownHostsFile=/dev/null", + sshHost, + 'sh -l -c "docker run -d -v /etc/docker-push-ssh/registry:/var/lib/registry ' + + '--name docker-push-ssh-registry -p 127.0.0.1:{0}:5000 registry"'.format( + registryPort + ), + ], + ).execute() if registryCommandResult.failed(): print("ERROR") - print(registryCommandResult.stdout) - print(registryCommandResult.stderr) + print((registryCommandResult.stdout)) + print((registryCommandResult.stderr)) return False try: # Establish ssh tunnel print("Establishing SSH Tunnel...") - sshTunnelCommandResult = Command("docker", [ - "run", "-d", - "--name", "docker-push-ssh-tunnel", - "-p", "127.0.0.1:5000:5000", - "-v", "{0}:/etc/ssh_key_file".format(sshIdentityFile), - "brthornbury/docker-alpine-ssh", - "ssh", - "-N", - "-L", "*:5000:localhost:{0}".format(registryPort), - "-i", "/etc/ssh_key_file", - "-o", "StrictHostKeyChecking=no", - "-o", "UserKnownHostsFile=/dev/null", - "-p", sshPort, - sshHost - ]).environment_dict(os.environ).execute() + sshTunnelCommandResult = ( + Command( + "docker", + [ + "run", + "-d", + "--name", + "docker-push-ssh-tunnel", + "-p", + "127.0.0.1:5000:5000", + "-v", + "{0}:/etc/ssh_key_file".format(sshIdentityFile), + "brthornbury/docker-alpine-ssh", + "ssh", + "-N", + "-L", + "*:5000:localhost:{0}".format(registryPort), + "-i", + "/etc/ssh_key_file", + "-o", + "StrictHostKeyChecking=no", + "-o", + "UserKnownHostsFile=/dev/null", + "-p", + sshPort, + sshHost, + ], + ) + .environment_dict(os.environ) + .execute() + ) if sshTunnelCommandResult.failed(): print("ERROR") - print(sshTunnelCommandResult.stdout) - print(sshTunnelCommandResult.stderr) + print((sshTunnelCommandResult.stdout)) + print((sshTunnelCommandResult.stderr)) return False print("Waiting for SSH Tunnel Initialization...") @@ -100,146 +127,210 @@ def pushImage(dockerImageTagList, sshHost, sshIdentityFile, sshPort, primeImages print("ERROR") print("SSH Tunnel failed to initialize.") - logsCmd = Command("docker", ["logs", "docker-push-ssh-tunnel"]).environment_dict(os.environ).execute() - print(logsCmd.stdout, logsCmd.stderr) + logsCmd = ( + Command("docker", ["logs", "docker-push-ssh-tunnel"]) + .environment_dict(os.environ) + .execute() + ) + print((logsCmd.stdout, logsCmd.stderr)) return False if sshTunnelCommandResult.failed(): print("ERROR") - print(sshTunnelCommandResult.stdout) - print(sshTunnelCommandResult.stderr) + print((sshTunnelCommandResult.stdout)) + print((sshTunnelCommandResult.stderr)) return False print("Priming Registry with base images...") - for primeImage in (primeImages or []): - - print("Priming base image ({0})".format(primeImage)) - - primingCommand = Command("ssh", [ - "-i", sshIdentityFile, - "-p", sshPort, - "-o", "StrictHostKeyChecking=no", - "-o", "UserKnownHostsFile=/dev/null", - sshHost, - "sh -l -c \"docker pull {0}".format(primeImage) + - " && docker tag {0} localhost:{1}/{0} && docker push localhost:{1}/{0}\"".format(primeImage, registryPort) - ]).execute() + for primeImage in primeImages or []: + + print(("Priming base image ({0})".format(primeImage))) + + primingCommand = Command( + "ssh", + [ + "-i", + sshIdentityFile, + "-p", + sshPort, + "-o", + "StrictHostKeyChecking=no", + "-o", + "UserKnownHostsFile=/dev/null", + sshHost, + 'sh -l -c "docker pull {0}'.format(primeImage) + + ' && docker tag {0} localhost:{1}/{0} && docker push localhost:{1}/{0}"'.format( + primeImage, registryPort + ), + ], + ).execute() if primingCommand.failed(): print("ERROR") - print(primingCommand.stdout) - print(primingCommand.stderr) + print((primingCommand.stdout)) + print((primingCommand.stderr)) return False print("Tagging image(s) for push...") for dockerImageTag in dockerImageTagList: - tagCommandResult = Command("docker", [ - "tag", - dockerImageTag, - "localhost:5000/{0}".format(dockerImageTag) - ]).environment_dict(os.environ).execute() + tagCommandResult = ( + Command( + "docker", ["tag", dockerImageTag, "localhost:5000/{0}".format(dockerImageTag)] + ) + .environment_dict(os.environ) + .execute() + ) if tagCommandResult.failed(): print("ERROR") - print(tagCommandResult.stdout) - print(tagCommandResult.stderr) + print((tagCommandResult.stdout)) + print((tagCommandResult.stderr)) return False print("Pushing Image(s) from local host...") for dockerImageTag in dockerImageTagList: - pushDockerImageCommandResult = Command("docker", [ - "push", - "localhost:5000/{0}".format(dockerImageTag) - ]).environment_dict(os.environ).execute() + pushDockerImageCommandResult = ( + Command("docker", ["push", "localhost:5000/{0}".format(dockerImageTag)]) + .environment_dict(os.environ) + .execute() + ) if pushDockerImageCommandResult.failed(): print("ERROR") - print(pushDockerImageCommandResult.stdout) - print(pushDockerImageCommandResult.stderr) + print((pushDockerImageCommandResult.stdout)) + print((pushDockerImageCommandResult.stderr)) - print("Error Pushing Image: Ensure localhost:5000 is added to your insecure registries.") - print("More Details (OS X): " - "https://stackoverflow.com/questions/32808215/where-to-set-the-insecure-registry-flag-on-mac-os") + print( + "Error Pushing Image: Ensure localhost:5000 is added to your insecure registries." + ) + print( + "More Details (OS X): " + "https://stackoverflow.com/questions/32808215/where-to-set-the-insecure-registry-flag-on-mac-os" + ) return False - print("Pushed Image {0} Successfully...".format(dockerImageTag)) + print(("Pushed Image {0} Successfully...".format(dockerImageTag))) print("Pulling and Retagging Image on remote host...") for dockerImageTag in dockerImageTagList: - pullDockerImageCommandResult = Command("ssh", [ - "-i", sshIdentityFile, - "-p", sshPort, - "-o", "StrictHostKeyChecking=no", - "-o", "UserKnownHostsFile=/dev/null", - sshHost, - "sh -l -c \"docker pull " + "localhost:{1}/{0}".format(dockerImageTag, registryPort) + - " && docker tag localhost:{1}/{0} {0}\"".format(dockerImageTag, registryPort) - ]).execute() + pullDockerImageCommandResult = Command( + "ssh", + [ + "-i", + sshIdentityFile, + "-p", + sshPort, + "-o", + "StrictHostKeyChecking=no", + "-o", + "UserKnownHostsFile=/dev/null", + sshHost, + 'sh -l -c "docker pull ' + + "localhost:{1}/{0}".format(dockerImageTag, registryPort) + + ' && docker tag localhost:{1}/{0} {0}"'.format(dockerImageTag, registryPort), + ], + ).execute() if pullDockerImageCommandResult.failed(): print("ERROR") - print(pullDockerImageCommandResult.stdout) - print(pullDockerImageCommandResult.stderr) + print((pullDockerImageCommandResult.stdout)) + print((pullDockerImageCommandResult.stderr)) return False - print("Pulled Image {0} Successfully...".format(dockerImageTag)) + print(("Pulled Image {0} Successfully...".format(dockerImageTag))) finally: print("Cleaning up...") - Command("ssh", [ - "-i", sshIdentityFile, - "-p", sshPort, - "-o", "StrictHostKeyChecking=no", - "-o", "UserKnownHostsFile=/dev/null", - sshHost, - "sh -l -c \"docker rm -f docker-push-ssh-registry\"" - ]).execute() + Command( + "ssh", + [ + "-i", + sshIdentityFile, + "-p", + sshPort, + "-o", + "StrictHostKeyChecking=no", + "-o", + "UserKnownHostsFile=/dev/null", + sshHost, + 'sh -l -c "docker rm -f docker-push-ssh-registry"', + ], + ).execute() - Command("docker", [ - "rm", "-f", "docker-push-ssh-tunnel" - ]).environment_dict(os.environ).execute() + Command("docker", ["rm", "-f", "docker-push-ssh-tunnel"]).environment_dict( + os.environ + ).execute() for dockerImageTag in dockerImageTagList: - Command("docker", [ - "image", "rm", - "localhost:5000/{0}".format(dockerImageTag) - ]).environment_dict(os.environ).execute() + Command( + "docker", ["image", "rm", "localhost:5000/{0}".format(dockerImageTag)] + ).environment_dict(os.environ).execute() return True def main(): - parser = argparse.ArgumentParser(description="A utility to securely push a docker image from your local host to a " - "remote host over ssh without using docker save/load or needing to " - "setup a private registry.") + parser = argparse.ArgumentParser( + description="A utility to securely push a docker image from your local host to a " + "remote host over ssh without using docker save/load or needing to " + "setup a private registry." + ) parser.add_argument("ssh_host", help="Host to push docker image to. (ex. username@myhost.com)") - parser.add_argument("docker_image", nargs='+', - help="Docker image tag(s) to push. Specify one or more separated by spaces.") - - parser.add_argument("-i", "--ssh-identity-file", type=str, - help="[required] Path to the ssh identity file on your local host. " - "Required, password auth not supported. (ex. ~/.ssh/id_rsa)") - - parser.add_argument("-p", "--ssh-port", type=str, help="[optional] Port on ssh host to connect to. (Default is 22)", default="22") - - parser.add_argument("-r", "--registry-port", type=str, - help="[optional] Remote registry port on ssh host to forward to. (Default is 5000)", default="5000") - - parser.add_argument("--prime-image", help="[optional] [list] Base images with which to prime the registry from the remote host. Docker pull is performed on the remote host.", action="append") + parser.add_argument( + "docker_image", + nargs="+", + help="Docker image tag(s) to push. Specify one or more separated by spaces.", + ) + + parser.add_argument( + "-i", + "--ssh-identity-file", + type=str, + help="[required] Path to the ssh identity file on your local host. " + "Required, password auth not supported. (ex. ~/.ssh/id_rsa)", + ) + + parser.add_argument( + "-p", + "--ssh-port", + type=str, + help="[optional] Port on ssh host to connect to. (Default is 22)", + default="22", + ) + + parser.add_argument( + "-r", + "--registry-port", + type=str, + help="[optional] Remote registry port on ssh host to forward to. (Default is 5000)", + default="5000", + ) + + parser.add_argument( + "--prime-image", + help="[optional] [list] Base images with which to prime the registry from the remote host. Docker pull is performed on the remote host.", + action="append", + ) args = parser.parse_args() - assert args.ssh_identity_file is not None + # assert args.ssh_identity_file is not None sshIdentityFileAbsolutePath = os.path.abspath(os.path.expanduser(args.ssh_identity_file)) print("[REQUIRED] Ensure localhost:5000 is added to your insecure registries.") - success = pushImage(args.docker_image, args.ssh_host, sshIdentityFileAbsolutePath, - args.ssh_port, args.prime_image, args.registry_port) + success = pushImage( + args.docker_image, + args.ssh_host, + sshIdentityFileAbsolutePath, + args.ssh_port, + args.prime_image, + args.registry_port, + ) if not success: sys.exit(1) diff --git a/docker_push_ssh/command.py b/docker_push_ssh/command.py index 743969f..b5ab6d3 100644 --- a/docker_push_ssh/command.py +++ b/docker_push_ssh/command.py @@ -38,7 +38,7 @@ def environment(self, key, value): return self def environment_dict(self, env_dict): - for key, value in env_dict.iteritems(): + for key, value in env_dict.items(): self.environment_variables[key] = value return self