123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- """
- dever-manage tools
- name:docker.py
- author:rabin
- """
- from core import *
- class Docker(object):
- path = 'src/docker/'
- default = 'shemic'
- @classmethod
- def init(self):
- self.conf = {}
- self.core = Config.core(self.path)
- self.store = Env.store()
- self.storeHost = self.core['store'][self.store] + '/'
- action = ('uprun', 'run', 'rm', 'rmb', 'stop', 'create', 'call', 'save', 'load', 'show', 'reset', 'logs', 'restart', 'inspect', 'test')
- method = Core.getMethod(Docker_Action, Args.action)
- if Args.name and Args.action in action:
- self.load(method)
- else:
- method()
- @classmethod
- def load(self, method):
- self.config()
- Container.network(self.conf['base'])
- self.rely(self.conf['base'], Args.action)
- one = False
- if Args.index in self.conf['config']:
- self.handle(method, self.conf['config'][Args.index], Args.index, Args.action)
- else:
- for item in self.conf['server']:
- if self.check(Args.index, item) == True:
- self.handle(method, self.conf['config'][item], item, Args.action)
- @classmethod
- def config(self):
- if not self.conf:
- self.conf = Config.read(self.path)
- @classmethod
- def check(self, name, item):
- if '#' in item:
- return False
- elif name == '':
- return True
- elif name + '-' in item:
- return True
- else:
- return False
- @classmethod
- def handle(self, method, config, item, action='run'):
- self.rely(config, action)
- if 'num' not in config:
- config['num'] = 1
- num = int(config['num'])
- i = 1;
- while (i <= num):
- name = self.name(item, i)
- if 'image' not in config:
- config['image'] = item
- if self.store == 'private' and config['image'] in self.core['images']:
- config['image'] = self.core['images'][config['image']]
- method(config=config, name=name, item=item, index=i, action=action)
- if action in ('stop', 'restart', 'rm', 'rmb', 'reset', 'run', 'create'):
- self.slave(method, config, item, action)
- i = i + 1
- @classmethod
- def name(self, name, i):
- name = Args.name + '-' + name
- if i > 1:
- self.conf['base']['i'] = '' + str(i)
- i = i - 1;
- self.conf['base']['num'] = '' + str(i)
- return name + self.conf['base']['num'];
- self.conf['base']['num'] = ''
- self.conf['base']['i'] = '1'
- return name;
- @classmethod
- def param(self, config, item, prefix, name):
- result = ''
- concat = ' '
- if item in config:
- if '#' not in item:
- result = config[item]
- if '[' in config[item]:
- search = re.search(r'\[(.*?)\]', result, re.M|re.I)
- temp = search.group(1)
- if temp:
- result = Core.replace('['+str(temp)+']', self.name(temp, 1), result)
- result = Core.replace('{num}', self.conf['base']['num'], result)
- result = Core.replace('{i}', self.conf['base']['i'], result)
- result = Core.replace('{path}', self.conf['base']['path'], result)
- result = Core.replace('{container}', self.conf['base']['path'] + 'container/', result)
- result = Core.replace('{name}', name, result)
- result = self.parse(result)
- result = Core.replace(',', ' ' + prefix + ' ', result)
- if item == 'hostname':
- name = result
- elif item == 'network' and 'network' in self.conf['base']:
- result = self.conf['base']['network']
- if result != '':
- if '=' in prefix:
- concat = ''
- result = prefix + concat + result
- return result
- @classmethod
- def parse(self, result):
- if '{$' in result:
- param = {}
- if Args.param != '':
- if 'http://' not in Args.param:
- Args.param = 'http://shemic.com/?' + Args.param;
- if '^' in Args.param:
- Args.param = Core.replace('^', '&', Args.param)
- parse = urlparse.urlparse(Args.param)
- param = urlparse.parse_qs(parse.query,True)
- search = re.compile(r'\{\$(.*?)\}')
- search = search.findall(result)
- for key in search:
- value = ''
- index = key
- if ':' in key:
- arr = key.split(':');
- index = arr[0]
- value = arr[1]
- if index in param:
- value = param[index][0]
- if value == '':
- print 'please set param value:' + index
- sys.exit()
- else:
- result = Core.replace('{$'+key+'}', value, result)
- return result
- @classmethod
- def rely(self, config, action):
- if 'rely' in config:
- if ',' in config['rely']:
- rely = config['rely'].split(',');
- for i in rely:
- Core.popen('Core ' + action + ' ' + i, True)
- else:
- Core.popen('Core ' + action + ' ' + config['rely'], True)
- @classmethod
- def hook(self, type, config, name):
- key = 'hook.'+type
- if key in config:
- Core.shell('hook.' + config[key] + ' ' + name + ' ' + Core.path, bg=True)
- @classmethod
- def slave(self, method, config, name, action):
- if 'slave' in config:
- num = int(config['slave'])
- key = ['slave', 'command', 'alias', 'port', 'hook.start', 'hook.end']
- for k in key:
- if k in config:
- del config[k]
- config['num'] = num
- self.handle(method, config, name + '-slave', action)
- @classmethod
- def tar(self, name):
- path = Core.path + 'data/backup/' + name + '/'
- File.mkdir(path)
- backup = 'backup/' + name
- tar = path + name + '.tar'
- return tar,backup
- class Docker_Action(object):
- @staticmethod
- def build():
- if Args.name and Args.name in Docker.core['images']:
- Args.name = Docker.core['images'][Args.name]
- Image.build(Docker.storeHost, Args.name)
- Container.delete()
- Image.delete()
- print 'docker build '+Args.name+':yes'
- @classmethod
- def push(self):
- package = self.package()
- if Args.name != '':
- if Args.name in package:
- Image.push(package[Args.name])
- else:
- print 'error ' + Args.name
- sys.exit()
- for key in package:
- Image.push(package[key])
- @classmethod
- def login(self):
- if Args.name and Args.name in Docker.core['store']:
- Core.shell('docker.login ' + Docker.core['store'][Args.name], True)
- else:
- for key,value in Docker.core['store'].items():
- Core.shell('docker.login ' + value, True)
- @staticmethod
- def package():
- stores = Docker.core['store']
- result = {}
- del stores[Docker.store]
- for key,value in Docker.core['images'].items():
- if Docker.store == 'private':
- index = Docker.storeHost + value
- else:
- index = Docker.storeHost + key
- result[key] = []
- result[key].append(index)
- for k,v in stores.items():
- if k == 'private':
- host = v + '/' + value
- else:
- host = v + '/' + key
- if host != index:
- result[key].append(host)
- if Args.name and Args.name in result:
- value = Args.name + ' [' + ",".join(result[Args.name ]) + ']'
- print value
- else:
- i = 1
- for key in result:
- value = key + ' [' + ",".join(result[key]) + ']'
- print str(i) + ':' + value
- i = i + 1
- return result
- @staticmethod
- def showi():
- Image.show()
- @staticmethod
- def rmi():
- Image.delete()
- print 'rm image:yes'
- @staticmethod
- def drop():
- Container.drop()
- print 'drop container:yes'
- @staticmethod
- def dropi():
- Image.drop(Args.name)
- print 'drop image:yes'
- @staticmethod
- def show(**param):
- name = ''
- if param:
- name = param['name']
- Container.show(name)
- @staticmethod
- def logs(**param):
- Container.logs(param['name'])
- @staticmethod
- def restart(**param):
- print 'reloading ' + param['name'] + ', please wait...'
- Container.restart(param['name'])
- @staticmethod
- def inspect(**param):
- Container.inspect(param['name'])
- @staticmethod
- def stop(**param):
- Container.stop(param['name'])
- @staticmethod
- def save(**param):
- tar,backup = Docker.tar(param['name'])
- Container.save(tar, param['name'], backup)
- @classmethod
- def load(self, **param):
- tar,backup = Docker.tar(param['name'])
- Container.load(tar, param['name'])
- Docker.storeHost = ''
- param['config']['image'] = backup
- self.run(**param)
- @classmethod
- def uprun(self, **param):
- Image.install(Docker.storeHost, param['config']['image'])
- param['action'] = 'run'
- self.run(**param)
- @staticmethod
- def rm(**param):
- if param and 'name' in param:
- Container.delete(param['name'])
- Alias.delete(param['config'], param['name'])
- else:
- Container.delete()
- print 'rm container:yes'
- @staticmethod
- def rmb(**param):
- if param and 'name' in param:
- Container.delete(param['name'], bg=True)
- Alias.delete(param['config'], param['name'])
- else:
- Container.delete()
- print 'rm container:yes'
- @classmethod
- def reset(self, **param):
- self.rm(**param)
- self.up(**param)
- @classmethod
- def test(self, **param):
- param['test'] = True
- print self.run(**param)
- @classmethod
- def create(self, **param):
- self.run(**param)
- @classmethod
- def call(self, **param):
- self.run(**param)
- @classmethod
- def run(self, **param):
- command = ''
- daemon = '-d'
- restart = '--restart=always'
- if 'daemon' in param['config']:
- daemon = param['config']['daemon']
- if daemon == 'false':
- daemon = ''
- restart = ''
- if 'image' not in param['config']:
- param['config']['image'] = ''
- if 'restart' in param['config']:
- restart = ''
- if param['action'] == 'call':
- runCommand = Docker.param(param['config'], 'call', '', param['name'])
- command = Docker.param(param['config'], 'param', '', param['name'])
- restart = '--entrypoint' + runCommand
- daemon = '--rm'
- param['action'] = 'run'
- state = Container.check(param['name'])
- if state == 0:
- Docker.hook('start', param['config'], param['name'])
- run = ['-it', '--name='+param['name'], '--hostname='+param['name'], restart, daemon, '-v '+Core.path+'container/share:/share -v /etc/hosts:/etc/hosts.main']
- args = Container.args()
- for key in args:
- if args[key] != '':
- value = Docker.param(param['config'], key, args[key], param['name'])
- if value != '':
- run.append(value)
- run.append(Docker.storeHost + param['config']['image'])
- if command == '' and 'command' in args:
- value = Docker.param(param['config'], 'command', args['command'], param['name'])
- command = value
- if command != '':
- run.append(command)
- command = ' '.join(run)
- if 'test' in param:
- return 'docker run ' + command
- print 'setuping ' + param['name'] + ', please wait...'
- method = Core.getMethod(Container, param['action'])
- method(command)
- Alias.add(param['config'], param['name'], 'docker run ' + command, param['action'])
- Docker.hook('end', param['config'], param['name'])
- else:
- self.restart(**param)
- class Container(object):
- @staticmethod
- def run(command):
- #command = 'container.run ' + command
- #Core.shell(command, True, bg=False)
- command = 'docker run ' + command
- Core.popen(command, True, bg=False)
- return command
- @staticmethod
- def show(name=''):
- print Core.shell('container.show ' + name)
- @staticmethod
- def args():
- return {
- 'port' : '-p'
- ,'volumes' : '-v'
- ,'environment' : '-e'
- ,'link' : '--link'
- ,'volumes_from' : '--volumes-from'
- ,'command' : ''
- ,'entrypoint' : '--entrypoint'
- ,'network' : '--net='
- ,'host' : '--add-host'
- ,'root' : '--privileged='
- ,'memory' : '--memory='
- ,'expose' : '--expose',
- }
- @staticmethod
- def drop():
- Core.shell('container.drop', bg=True)
- @staticmethod
- def stop(name):
- Core.shell('container.stop ' + name)
- @staticmethod
- def logs(name):
- Core.shell('container.logs ' + name, True)
- @staticmethod
- def inspect(name):
- Core.shell('container.inspect ' + name, True)
- @staticmethod
- def restart(name):
- Core.shell('container.restart ' + name)
- @classmethod
- def delete(self, name='', bg=False):
- if name != '':
- print 'rm ' + name + ', please wait...'
- if self.check(name) == 1:
- Core.shell('container.rm ' + name, False, bg=bg)
- else:
- Core.shell('container.rm', False)
-
- @staticmethod
- def check(name):
- result = int(Core.popen('docker ps -a | grep '+name+' | wc -l'))
- if result != 0:
- return 1
- else:
- return 0
- @staticmethod
- def network(config):
- if 'network' in config:
- result = int(Core.popen('docker network ls | grep ' + config['network'] + ' | wc -l'))
- if result == 0:
- Core.shell('container.network ' + config['network'], True)
- @staticmethod
- def save(tar, name, backup):
- if File.exists(tar) == True:
- now = time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))
- old = replace('.tar', '.' + now + '.tar', tar)
- File.rename(tar, old)
- Core.popen('docker commit -p ' + name + ' ' + backup)
- Core.popen('docker save ' + backup + ' > ' + tar, True)
- @classmethod
- def load(self, tar, name):
- Core.popen('docker load < ' + tar, True)
- self.delete(name)
- class Image(object):
- @classmethod
- def push(self, stores):
- store = stores[0]
- if self.check(store) == 1:
- del stores[0]
- Core.shell('image.push ' + store, bg=True)
- for value in stores:
- #print store + ' ' + value
- Core.shell('image.push ' + store + ' ' + value, bg=True)
- @staticmethod
- def show():
- print Core.shell('image.show')
- @staticmethod
- def drop(name=''):
- Core.shell('image.drop ' + name, bg=True)
- @staticmethod
- def delete():
- Core.shell('image.rm', bg=True)
- @staticmethod
- def build(path, name):
- file = Core.path + Docker.path + 'build/' + name + '/'
- name = path + name
- Core.shell('image.build ' + name + ' ' + file, True)
- @staticmethod
- def check(name):
- result = int(Core.popen('docker images | grep '+name+' | wc -l'))
- if result != 0:
- return 1
- else:
- return 0
- @staticmethod
- def install(library, key):
- pull = 'docker pull';
- command = pull + ' ' + library + key
- Core.popen(command, True)
- print 'finished'
|