export-docker-startup-command.py
程序支持将选择单个容器,将容器的启动命令打印到console,或导出所有容器的启动命令到以时间戳命名的 txt 文件中
#!/usr/bin/python3 import argparse import datetime import json import os import sys containerIds=[] containerNames=[] containerImages=[] selectContainerIndex=None programTitle = "================= 本程序负责批量或选定Docker容器导出其启动命令 Powered by 王睿 =================" def welcome(): supportArgs = ["-d", "-P", "-p", "-v", "-e", "--name", "--restart", "--entrypoint", "--privileged", "--memory"] print("\n" + programTitle) print("支持导出的启动参数如下:") #for arg in supportArgs: print(supportArgs) print("================================================================================================") def exec(command): return os.popen(command).read().strip() # 获取容器列表数据 def getContainerListData(): global containerIds global containerNames global containerImages # 容器id集合 containerIds = exec("docker ps -a --format '{{.ID}}'").split("\n") # 容器名称集合 containerNames = exec("docker ps -a --format '{{.Names}}'").split("\n") # 容器镜像集合 containerImages = exec("docker ps -a --format '{{.Image}}'").split("\n") colume1 = "INDEX" colume2 = "CONTAINER ID" colume3 = "NAMES" colume4 = "IMAGE" # 每列之间间隔的字符串,默认是三个空格 columeIntervalString = " " maxNameLen = 0 for i in range(len(containerNames)): if (maxNameLen < len(containerNames[i])): maxNameLen = len(containerNames[i]) tableTitle1 = colume1 + columeIntervalString + colume2 + columeIntervalString + colume3 for i in range(maxNameLen): if (i >= len(colume3)): tableTitle1 += " " tableTitle1 += columeIntervalString tableTitle = tableTitle1 + colume4 print(tableTitle) for i in range(len(containerIds)): item = str(i+1) for j in range(len(tableTitle1)): if (j > len(item) and j <= len(colume1) + len(columeIntervalString)): item += " " item += containerIds[i] for j in range(len(tableTitle1)): if (j > len(item) and j <= len(colume1) + len(colume2) + len(columeIntervalString)*2): item += " " item += containerNames[i] for j in range(len(tableTitle1) + 1): if (j > len(item) and j <= len(tableTitle1)): item += " " item += containerImages[i] print(item) # 选择容器序号 def selectContainer(): global containerIds global containerNames global containerImages global selectContainerIndex print("\n请输入导出的容器序号、容器ID或容器名称:", end = "") try: inputText = input() except KeyboardInterrupt: print("\n\n操作取消,程序退出\n") exit(0) selectContainerIndex = getContainerIndex(inputText) if selectContainerIndex == None: print("未选中任何任何容器,请重新选择") selectContainer() else: print("\n当前选中的容器名称为:" + containerNames[selectContainerIndex]) # 根据用户的输入获取容器索引 def getContainerIndex(text): try: intVal = int(text) - 1 if intVal >= 0 and intVal < len(containerIds): return intVal except: print() for i in range(len(containerIds)): if containerIds[i] == text: return i for i in range(len(containerNames)): if containerNames[i] == text: return i for i in range(len(containerIds)): if containerIds[i].startswith(text): return i for i in range(len(containerNames)): if containerNames[i].startswith(text): return i return None # 组织容器参数 def getCommandByContainerIndex(containerIndex): command = "docker run -d" imageInspect = json.loads(exec("docker image inspect {}".format(containerImages[containerIndex]))) containerInspect = json.loads(exec("docker container inspect {}".format(containerIds[containerIndex]))) imageConfig = imageInspect[0]['Config'] containerConfig = containerInspect[0]['Config'] containerHostConfig = containerInspect[0]['HostConfig'] if (containerHostConfig['PublishAllPorts'] == True): command += "P" command += " \\\n --name " + containerInspect[0]['Name'][1:] command += " \\\n --restart " + containerHostConfig['RestartPolicy']['Name'] imageEntrypoints = imageConfig['Entrypoint'] containerEntrypoints = containerConfig['Entrypoint'] if(containerEntrypoints != None and containerEntrypoints != imageEntrypoints): command += " \\\n --entrypoint " + containerEntrypoints[0] if (containerHostConfig['Privileged'] == True): command += " \\\n --privileged " containerBinds = containerHostConfig['Binds'] if (containerBinds != None): for bind in containerBinds: command += " \\\n -v " + bind imageEnvs = imageConfig['Env'] containerEnvs = containerConfig['Env'] for containerEnv in containerEnvs: if(containerEnv not in imageEnvs): command += " \\\n -e \"" + containerEnv + "\"" containerPortBindings = containerHostConfig['PortBindings'] for containerPort in containerPortBindings: hostPortArr = containerPortBindings[containerPort] for hostPortObj in hostPortArr: command += " \\\n -p " + hostPortObj['HostPort'] + ":" + containerPort if containerHostConfig['Memory'] > 0: command += " \\\n --memory " + str(containerHostConfig['Memory']) command += " \\\n " + containerImages[containerIndex] imageCmd = imageConfig['Cmd'] containerCmd = containerConfig['Cmd'] if(containerCmd != None and containerCmd != imageCmd): for cmd in containerCmd: command += " \\\n " + cmd return command def parse_args(): parser = argparse.ArgumentParser(description = programTitle) parser.add_argument('--export-all', type=bool, default = False, help = "是否将所有容器的启动命令导出到文件,默认值: false") args = parser.parse_args() return args if __name__ == '__main__': args = parse_args() localDir = os.path.split(os.path.realpath(__file__))[0] welcome() getContainerListData() command = "" if args.export_all: fileName = localDir + "/" + "docker-startup-all-" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + ".txt" for i in range(len(containerIds)): command += getCommandByContainerIndex(i) + "\n\n\n" with open(fileName, "w") as f: f.write(command) print("\n所有容器的启动命令已导出到文件:" + fileName + "\n") else: selectContainer() command = getCommandByContainerIndex(selectContainerIndex) print("\n" + command + "\n")