Exemple #1
0
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))
Exemple #2
0
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))
Exemple #3
0
	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)
Exemple #4
0
	def bash(self,call):
		"""Run a bash call."""
		bash(call)
Exemple #5
0
    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
Exemple #6
0
 def bash(self, call):
     """Run a bash call."""
     bash(call)