def get_jupyter_token(container): """Check docker logs for a container.""" result = bash('docker logs %s'%container,scroll=False) matched = re.findall(r':(\d+)/\?token=(.*?)\s',result['stdout']) if len(matched)==1: raise Exception('cannot locate the token') port,token = int(matched[-1][0]),matched[-1][1] print('status notebook is available at http://localhost:%d/?token=%s'%(port,token))
def get_jupyter_token(container): """Check docker logs for a container.""" result = bash('docker logs %s' % container, scroll=False) matched = re.findall(r':(\d+)/\?token=(.*?)\s', result['stdout']) if len(matched) == 1: raise Exception('cannot locate the token') port, token = int(matched[-1][0]), matched[-1][1] print('status notebook is available at http://localhost:%d/?token=%s' % (port, token))
def docker_compose(self,compose,dockerfile,site, command,script=None,persist=True,rebuild=True, prelim=None,identity=None,indirect=False,cname=None): """ Prepare a docker-compose folder and run a command in the docker. """ # the identity key is hook-able, but right now we do not set a proper # hook and instead have it hard-coded below, where we add the user # key to docker compose services lists when running on linux. note # that the linux check and modification of docker compose file can # later be moved to a real hook if desired if indirect: raise Exception('you cannot run this! (indirect: true)') is_linux = False try: check_linux = bash('uname -a',scroll=False) if re.match('^Linux',check_linux['stdout']): is_linux = True except: pass if is_linux: user_uid = os.getuid() user_gid = os.getgid() requires_python_check('yaml') import yaml if prelim: result = read_config(hook=prelim).get(prelim,prelim) #! do something with result? right now this is just a do hook dfm = DockerFileMaker(meta=self.meta,**dockerfile) spot = SpotLocal(site=site,persist=persist) with open(os.path.join(spot.path,'Dockerfile'),'w') as fp: fp.write(dfm.dockerfile) # add the user to all docker-compose.yml services on Linux if is_linux: for key in compose.get('services',{}): compose['services'][key]['user'] = '******'%(user_uid,user_gid) # the cname flag gets container name from the command line # and adds it to all of the compose recipes at start time because # if we add it to the recipe by default it turns off some features #! this feature does not work with docker exec for some reason if cname: for service in compose['services']: if 'container_name' in compose['services']: raise Exception(('received cname from the command line but ' 'the service "%s" already has a container named %s and we ' 'refuse to override this')%(service, compose['services']['container_name'])) else: compose['services'][service]['container_name'] = cname with open(os.path.join(spot.path,'docker-compose.yml'),'w') as fp: fp.write(yaml.dump(compose)) # script is optional. it only runs if you run a docker command below # which also depends on it via an entrypoint if script: with open(os.path.join(spot.path,'script.sh'),'w') as fp: fp.write(script) if rebuild: cmd = 'docker-compose build' print('status from %s running command %s'%(spot.path,cmd)) bash_basic('docker-compose build',cwd=spot.path) # no need to log this since it manipulates a presumably # persistent set of files print('status running command %s'%command) #! note that we could use docker_compose just for building if we #! made the rebuild True when no script or command. this might be #! somewhat more elegant? this could be done with another method #! for clarity bash_basic(command,cwd=spot.path)
def bash(self,call): """Run a bash call.""" bash(call)
def docker_compose(self, compose, dockerfile, site, command, script=None, persist=True, rebuild=True, cleanup=True, prelim=None, identity=None, indirect=False, cname=None, notes=None): """ Prepare a docker-compose folder and run a command in the docker. """ # the identity key is hook-able, but right now we do not set a proper # hook and instead have it hard-coded below, where we add the user # key to docker compose services lists when running on linux. note # that the linux check and modification of docker compose file can # later be moved to a real hook if desired if indirect: raise Exception('you cannot run this! (indirect: true)') is_linux = False try: check_linux = bash('uname -a', scroll=False) if re.match('^Linux', check_linux['stdout']): is_linux = True except: pass if is_linux: user_uid = os.getuid() user_gid = os.getgid() requires_python_check('yaml') import yaml if prelim: result = read_config(hook=prelim).get(prelim, prelim) #! do something with result? right now this is just a do hook spot = SpotLocal(site=site, persist=persist) # added a switch in case no dockerfile build is happening if dockerfile: dfm = DockerFileMaker(meta=self.meta, **dockerfile) dockerfile_fn = os.path.join(spot.path, 'Dockerfile') with open(dockerfile_fn, 'w') as fp: fp.write(dfm.dockerfile) # add the user to all docker-compose.yml services on Linux if is_linux: for key in compose.get('services', {}): compose['services'][key]['user'] = '******' % (user_uid, user_gid) # the cname flag gets container name from the command line # and adds it to all of the compose recipes at start time because # if we add it to the recipe by default it turns off some features #! this feature does not work with docker exec for some reason if cname: for service in compose['services']: if 'container_name' in compose['services']: raise Exception(( 'received cname from the command line but ' 'the service "%s" already has a container named %s and we ' 'refuse to override this') % (service, compose['services']['container_name'])) else: compose['services'][service]['container_name'] = cname compose_fn = os.path.join(spot.path, 'docker-compose.yml') with open(compose_fn, 'w') as fp: fp.write(yaml.dump(compose)) # script is optional. it only runs if you run a docker command below # which also depends on it via an entrypoint if script: script_fn = os.path.join(spot.path, 'script.sh') with open(script_fn, 'w') as fp: fp.write(script) # added a switch in case no dockerfile build is happening if dockerfile and rebuild: cmd = 'docker-compose build' print('status from %s running command %s' % (spot.path, cmd)) bash_basic('docker-compose build', cwd=spot.path) # no need to log this since it manipulates a presumably # persistent set of files print('status running command %s' % command) #! note that we could use docker_compose just for building if we #! made the rebuild True when no script or command. this might be #! somewhat more elegant? this could be done with another method #! for clarity #! failures during rebuild still deposit you in the previous container #! and since this is mildly useful sometimes, we allow it anyway bash_basic(command, cwd=spot.path) # clean up #! note that this is a design choice if cleanup: if script: os.remove(script_fn) try: os.remove(dockerfile_fn) except: pass try: os.remove(compose_fn) except: pass
def bash(self, call): """Run a bash call.""" bash(call)