调用方式
data = {
"base_url": "tcp://ip:port",
"sign": "api",
"apiversion": ""
}
tt = DockerManage(**data)
data = {
"base_url": "ssh://username:password@ip:port",
"sign": "ssh",
"apiversion": "1.23"
}
tt = DockerManage(**data)
tt.ContainerList()
tt.Images()
tt.pullimage(tag="镜像id或者镜像名称:镜像")
脚本内容
from io import BytesIO
import os
import docker
from docker import transport, DockerClient
from config import MIN_DOCKER_API, DEFAULT_NUM_POOLS, DEFAULT_MAX_POOL_SIZE
MIN_DOCKER_API = "1.21"
DEFAULT_NUM_POOLS = 25
DEFAULT_MAX_POOL_SIZE = 30
class SSHHTTPAdapter(transport.SSHHTTPAdapter):
def __init__(self, ssh_params, timeout=60, pool_connections=DEFAULT_NUM_POOLS,
max_pool_size=DEFAULT_MAX_POOL_SIZE, shell_out=False):
self.ssh_params = ssh_params
del ssh_params['scheme']
super(SSHHTTPAdapter, self).__init__('', timeout, pool_connections, max_pool_size, shell_out)
def _create_paramiko_client(self, _):
self.ssh_client = paramiko.SSHClient()
ssh_config_file = os.path.expanduser("~/.ssh/config")
if os.path.exists(ssh_config_file):
conf = paramiko.SSHConfig()
with open(ssh_config_file) as f:
conf.parse(f)
host_config = conf.lookup(self.ssh_params['hostname'])
self.ssh_conf = host_config
if 'proxycommand' in host_config:
self.ssh_params["sock"] = paramiko.ProxyCommand(
self.ssh_conf['proxycommand']
)
if 'hostname' in host_config:
self.ssh_params['hostname'] = host_config['hostname']
if self.ssh_params['port'] is None and 'port' in host_config:
self.ssh_params['port'] = self.ssh_conf['port']
if self.ssh_params['username'] is None and 'user' in host_config:
self.ssh_params['username'] = self.ssh_conf['user']
self.ssh_client.load_system_host_keys()
self.ssh_client.set_missing_host_key_policy(paramiko.WarningPolicy())
class SSHDockerClient(DockerClient):
def __init__(self, *args, **kwargs):
base_url = kwargs.get('base_url')
ssh_params = docker_urlparse(base_url)
adapter = SSHHTTPAdapter(ssh_params)
kwargs['base_url'] = ''
kwargs['version'] = kwargs.get('version')
super(SSHDockerClient, self).__init__(*args, **kwargs)
self.api.mount('http+docker://ssh', adapter)
self.api.base_url = 'http+docker://ssh'
def docker_urlparse(url):
mark = '_a5s7m3_'
r = urlparse(url.replace('#', mark))
hostname = r.hostname.replace(mark, '#')
username = r.username.replace(mark, '#')
password = r.password.replace(mark, '#')
port = r.port
scheme = r.scheme
return {
'hostname': hostname,
'port': port,
'username': username,
'password': decrypt(password[2:-1]),
'scheme': scheme
}
class DockerManage:
def __init__(self, *args, **kwargs) -> None:
self.base_url = kwargs.get("base_url")
self.sign = kwargs.get("sign")
self.apiversion = kwargs.get("apiversion")
self.success_code = 200
self.fail_code = 400
def Client(self):
if self.sign == "api":
docker_clinet = docker.DockerClient(base_url=self.base_url)
return docker_clinet
elif self.sign == "ssh":
docker_clinet = SSHDockerClient(base_url=self.base_url,version=self.apiversion)
return docker_clinet
def ContainerList(self):
try:
client = self.Client()
container_list = client.api.containers(all=True)
client.close()
containers = []
if container_list:
for container in container_list:
id = container["Id"]
names = container["Names"][0].split("/")[1]
image = container["Image"]
if container["Ports"]:
ports = []
for ptp in container["Ports"]:
if "PublicPort" in ptp.keys():
pstr = ptp["IP"] + ":" + str(ptp["PublicPort"]) + "->" + str(ptp["PrivatePort"])
ports.append(pstr)
else:
ports = container["Ports"]
status = container["State"]
created = TimeTool(container["Created"])
if container["Mounts"]:
mount = []
for mtp in container["Mounts"]:
if mtp["Source"]:
mtp_str = mtp["Source"] + ":" + mtp["Destination"]
mount.append(mtp_str)
else:
mount = container["Mounts"]
container_dict = {"id": id, "name": names, "image": image, "ports": ports, "status": status, "mount": mount, "created": created}
containers.append(container_dict)
return {"code": self.success_code, "msg": "获取成功","data": containers}
except Exception as e:
return {"code": self.fail_code, "msg": "获取失败 %s" % str(e),"data": []}
def Images(self):
try:
client = self.Client()
images = client.api.images(all=True)
client.close()
imagesRes = []
for image in images:
created = TimeTool(image["Created"])
size = HumConvert(image["Size"])
for tag in image["RepoTags"]:
imagesRes.append({"tag": tag, "size": size, "created": created})
return {"code": self.success_code, "msg": "获取成功", "data": imagesRes}
except Exception as e:
return {"code": self.fail_code, "msg": "获取失败 %s" % str(e),"data": []}
def pullimage(self, tag):
try:
client = self.Client()
client.images.pull(repository=tag)
client.close()
return {"code": self.success_code, "msg": "拉取成功", "data": ""}
except Exception as e:
return {"code": self.fail_code, "msg": "拉取失败: " ,"data": [e]}
def DelImage(self,tag):
try:
client = self.Client()
client.images.remove(image=tag)
client.close()
return {"code": self.success_code, "msg": "删除成功", "data": []}
except Exception as e:
return {"code": self.fail_code, "msg": "删除失败: %s" % str(e),"data": []}
def SearchImg(self,tag):
try:
client = self.Client()
res = client.images.search(tag)
client.close()
return {"code": self.success_code, "msg": "查询成功", "data": res}
except Exception as e:
return {"code": self.fail_code, "msg": "查询失败: %s" % str(e),"data": []}
def historyImg(self,tag):
try:
client = self.Client()
res = client.api.history(tag)
client.close()
return {"code": self.success_code, "msg": "查询成功", "data": res}
except Exception as e:
return {"code": self.fail_code, "msg": "查询失败: %s" % str(e),"data": []}
def pushImg(self, repository):
try:
client = self.Client()
res = client.api.push(repository=repository)
client.close()
return {"code": self.success_code, "msg": "提交成功", "data": res}
except Exception as e:
return {"code": self.fail_code, "msg": "提交失败: %s" % str(e),"data": []}
def tagImg(self, image, repository):
try:
client = self.Client()
res = client.api.tag(image=image, repository=repository)
client.close()
return {"code": self.success_code, "msg": "提交成功", "data": res}
except Exception as e:
return {"code": self.fail_code, "msg": "提交失败: %s" % str(e),"data": []}
def extPush(self, image, repository):
try:
client = self.Client()
res = client.api.tag(image=image, repository=repository)
if res:
pres = client.api.push(repository=repository)
client.close()
return {"code": self.success_code, "msg": "提交成功", "data": pres}
else:
return {"code": self.fail_code, "msg": "提交失败: %s" % str(res),"data": []}
except Exception as e:
return {"code": self.fail_code, "msg": "提交失败: %s" % str(e),"data": []}
def RenameContainers(self, oldname, newname):
try:
client = self.Client()
client.api.rename(oldname, newname)
client.close()
return {"code": self.success_code, "msg": "重命名成功", "data": []}
except Exception as e:
return {"code": self.fail_code, "msg": "重命名失败: %s" % str(e),"data": []}
def RestartContainers(self, id):
try:
client = self.Client()
client.api.restart(id)
client.close()
return {"code": self.success_code, "msg": "重启成功", "data": []}
except Exception as e:
return {"code": self.fail_code, "msg": "重启失败: %s" % str(e),"data": []}
def StartContainers(self, id):
try:
client = self.Client()
client.api.start(id)
client.close()
return {"code": self.success_code, "msg": "启动成功", "data": []}
except Exception as e:
return {"code": self.fail_code, "msg": "启动失败: %s" % str(e),"data": []}
def StopContainers(self, id):
try:
client = self.Client()
client.api.stop(id)
client.close()
return {"code": self.success_code, "msg": "停止成功", "data": []}
except Exception as e:
return {"code": self.fail_code, "msg": "停止失败: %s" % str(e),"data": []}
def RemoveContainers(self, id):
try:
stopRes = self.StopContainers(id)
if stopRes["code"] == 200:
client = self.Client()
client.api.remove_container(id)
client.close()
return {"code": self.success_code, "msg": "删除成功", "data": []}
else:
return {"code": self.fail_code, "msg": "删除失败: %s" % stopRes['msg'],"data": []}
except Exception as e:
return {"code": self.fail_code, "msg": "删除失败: %s" % str(e),"data": []}
def RunContainers(self, data):
try:
client = self.Client()
if ";" in data["binds"]:
volumes = data["binds"].split(";")
elif ":" in [data["binds"]]:
volumes = [data["binds"]]
else:
volumes = []
prots = {}
if ";" in data["port_bindings"]:
portLst = data["port_bindings"].split(";")
prots = {}
for port in portLst:
key = port.split(":")[1]
value = port.split(":")[0]
prots[key] = value
elif data["port_bindings"]:
key = data["port_bindings"].split(":")[1]
value = data["port_bindings"].split(":")[0]
prots[key] = value
if data["nano_cpus"]:
nano_cpus = int(data["nano_cpus"]) * 1000000000
else:
nano_cpus = ""
if ";" in data["environment"]:
environment = data["environment"].split(";")
elif ":" in data["environment"]:
environment = [data["environment"]]
else:
environment = []
container = client.containers.create(
image=data["image"],
environment=environment,
hostname=data["hostname"],
name=data["name"],
nano_cpus=nano_cpus,
mem_limit=data["mem_limit"],
network=data["network"],
volumes=volumes,
ports=prots,
detach=True,
network_mode=data["network_mode"],
restart_policy=data["restart_policy"],
shm_size=data["shmsize"]
)
container.start()
client.close()
return {"code": self.success_code, "msg": "创建成功: %s" % container.id,"data": []}
except Exception as e:
return {"code": self.fail_code, "msg": "创建失败: %s" % str(e),"data": []}
def build(self, dockerfile, tag):
try:
client = self.Client()
f = BytesIO(dockerfile.encode('utf-8'))
response = [line for line in client.api.build(fileobj=f, rm=True, tag=tag, nocache=True)]
res_data = eval(response[-1])
client.close()
if "Successfully tagged" in str(res_data):
return {"code": self.success_code, "msg": "build成功", "data": [res_data]}
else:
return {"code": self.fail_code, "msg": "build失败" ,"data": [res_data]}
except Exception as e:
return {"code": self.fail_code, "msg": "build失败: %s" % str(e),"data": []}