• 基于 docker inspect + Python 反向生成容器启动命令


    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")
  • 相关阅读:
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    C语言I博客作业02
    Django连接MySql数据库
    asyncio异步编程
    Django-rest framework框架
    Git版本管理工具详细教程
    MySQL的sql_mode模式说明及设置
  • 原文地址:https://www.cnblogs.com/nihaorz/p/16420235.html
Copyright © 2020-2023  润新知