Files
dj/integration-work/docker_worker_ops.py
T

33 lines
1.9 KiB
Python

"""Docker clone helpers: retain existing security and networks, publish no new ports."""
import copy,http.client,json,socket,subprocess,pathlib
class UnixHTTP(http.client.HTTPConnection):
def __init__(self): super().__init__('localhost',timeout=40)
def connect(self):
self.sock=socket.socket(socket.AF_UNIX,socket.SOCK_STREAM);self.sock.settimeout(self.timeout);self.sock.connect('/var/run/docker.sock')
def api(method,path,body=None):
c=UnixHTTP();raw=None if body is None else json.dumps(body).encode()
c.request(method,path,body=raw,headers={'Content-Type':'application/json'});r=c.getresponse();data=r.read();c.close()
if r.status>=300:raise RuntimeError(f'Docker {method} {path} failed: {r.status} '+data.decode()[:300])
return json.loads(data) if data else None
def inspect(name):return api('GET','/containers/'+name+'/json')
def clone(d,name):
cfg=copy.deepcopy(d['Config']);cfg['Hostname']=name;cfg['Image']=d['Image']
cfg['Labels']={k:v for k,v in cfg.get('Labels',{}).items() if not k.startswith('com.docker.compose.')}
cfg['Labels']['huobao.local.worker']=name
cfg['HostConfig']=copy.deepcopy(d['HostConfig'])
for k in ('ContainerIDFile','PidMode','IpcMode'):
if k=='ContainerIDFile':cfg['HostConfig'][k]=''
cfg['HostConfig']['AutoRemove']=False
return cfg
def set_env(cfg,key,value):
cfg['Env']=[x for x in cfg.get('Env',[]) if not x.startswith(key+'=')]+[key+'='+value]
cfg['Cmd']=[key+'='+value if x.startswith(key+'=') else x for x in cfg.get('Cmd',[])]
def replace_bind(cfg,destination,source):
binds=cfg['HostConfig'].get('Binds') or []
found=[x for x in binds if x.split(':')[1]==destination]
assert len(found)==1,(destination,found)
parts=found[0].split(':');parts[0]=str(source)
cfg['HostConfig']['Binds']=[(':'.join(parts) if x==found[0] else x) for x in binds]
def write_json(path,value):
path=pathlib.Path(path);path.write_text(json.dumps(value,ensure_ascii=False));path.chmod(0o600)