def listRegistry(registry): ''' listRegistry(registry) retrieve image and tag data from a registry Parameters ---------- registry: str the address of the registry ''' curl_cmd = f'curl -s -X GET https://{registry}/v2/_catalog' data = json.loads( evalOrDie( curl_cmd, "There was an error getting the images. \nPlease make sure you are connected to the network" )[0]) print("\nREPOSITORY \t\t\t\t\t TAGS") for repo in data['repositories']: tag_cmd = f'curl -s -X GET https://{registry}/v2/{repo}/tags/list' res = json.loads( evalOrDie(tag_cmd, "There was en error getting the tags")[0]) tags = [str(tag) for tag in res['tags']] print(f"{repo} \t {tags}") print( f"\nUse {registry}/<repo>:<tag> as your environment in the `locker run` cmd.\n" ) print(f"EXAMPLE:\n\t`locker run --env {registry}/{repo}:{tags[0]}")
def execute(container, cmd, flags=''): # print(f"EXECUTING: {cmd}") docker_exec_cmd = ("docker exec " f"{'-' + flags if flags != '' else ''} " f"{container.id[:3]} " f"{cmd}") evalOrDie(docker_exec_cmd)
def pullImage(image): ''' pullImage(image) Pull image using docker pull Parameters ---------- image: str name of docker image to run ''' pull_cmd = f"docker pull {image}" print(f"Attempting to pull image [{image}] from the registry") evalOrDie( pull_cmd, f"Failed to pull {image}. \nPlease make sure you are connected to the network. \nMake sure that you have your HTTP_PROXY set if you are pulling from DockerHub. \n" )
def listImages(): ''' listImages() print all the images on the machine ''' image_cmd = 'docker images' print(evalOrDie(image_cmd)[0])
def ps(all): ''' ps(all) run "docker ps" cmd to print containers Parameters ---------- all: bool stopped containers too? ''' docker_ps_cmd = f"docker ps {' -a ' if all else ''}" print( evalOrDie(docker_ps_cmd, "There was an error getting the containers")[0])
def searchDockerHub(name, limit='15'): ''' searchDockerHub(name, limit='15') print docker search results Parameters ---------- name: str the name of the image to search for limit: str number of images to print ''' search_cmd = f'docker search {name} --limit {limit}' print( evalOrDie(search_cmd)[0], "Error getting images...\nPlease make sure you are connected to the network" )
def getPorts(cid): #print(f"CID: {cid}") docker_port_cmd = f'docker port {cid}' ports = evalOrDie(docker_port_cmd, "There was an error getting the ports")[0] port_dict = {} port_lines = ports.split('\n') #print(port_lines) for line in port_lines: if line != '': port = line.split('->') #print(port) #print(port) c_port = port[0].rstrip() #print(c_port) l_port = port[1][9:] #print(l_port) port_dict[c_port] = int(l_port) #print(port_dict) return port_dict
def cpFrom(container, file_path, dest): docker_cp_cmd = ("docker cp " f"{container.id[:3]}:{file_path} " f"{dest}") evalOrDie(docker_cp_cmd)
def createAndRun(user, image, ports, mode, keypath, label, cap_add, devices): ''' createAndRun(user, image, ports, mode, keypath, label, cap_add, devices) Create and run a docker container with specified parameters Parameters ---------- user: str user running container image: str name of docker image to run ports: dict port mappings mode: str run interactive or detached keypath: str path to .ssh/ label: dict labels to be added to the container cap_add: list linux capabilities for the container devices: list devices to add to the container ''' container = None # global container obj # check to see if the image is local if testImagePresence(image): print("You have this image on your machine") # test to see if they already have a container running if isImageRunning(image): print( f"You already have a container running with the image [{color(image, fg='cyan')}]" ) if not yes_or_no( "Do you want to create another container with the same image?" ): # if "no" sys.exit() ## CHECK & CHANGE PORTS ## print("You will need to change the ports ...") ports = checkPorts(usedPorts(), ports) ## CHECK EXPOSED PORTS ## ports = exposedPortsHelp(image, ports) else: # no running containers of the image print( "No running containers of this image found. \nStarting new container" ) # make sure the images exposed ports are allocated ports = exposedPortsHelp(image, ports) ## START CONTAINER ## if mode == 'ti' and label[ 'registry'] == 'docker': ## If it is a non-BMS image and the user is running -ti #print(ports) ports_str = " -p ".join([ f"{ports[inside]}:{inside[:len(inside)-4]}" for inside in ports.keys() ]) #print(ports_str) devices = [device.replace('/', '\/') for device in devices] cmd = ( f"docker run -ti " f"{' -p ' + ports_str if len(ports) >0 else ''} " f" {'--cap-add=' + ' --cap-add='.join(cap_add) if len(cap_add)> 0 else ''} " #f" {'--device=' + ' --device='.join(devices) if len(devices)> 0 else ''} " f" --entrypoint bin/bash {image} ") # print(cmd) evalOrDie(cmd) #detectTTY(res) sys.exit() # regular run container = docker.containers.run(image=image, ports=ports, cap_add=cap_add, devices=devices, labels=label, detach=True) print(f"Your container is now running with ID: {container.id}") if label[ 'registry'] == 'docker.rdcloud.bms.com:443': ## RUN BMS SPECIFIC SETUP if yes_or_no("Do you have SSH keys to mount stash?"): ## COPY KEYS TO CONTAINER ## copyKeys(container, keypath, user) ## EXECUTE SETUP ## print("Trying to set up stash") try: setupStash(container, user) except: print( "Could not mount /stash/. \nMake sure you're connected to the BMS network." ) if yes_or_no("Do you want to clean-up the container?"): return container.remove() ## INSTRUCTIONS ## print( f"Access {color('Rstudio', fg='cyan')} at http://localhost:{ports['8787/tcp']}" ) print( f"Access {color('ssh', fg='yellow')} at http://localhost:{ports['22/tcp']}" ) if mode == 'ti': # EXEC IN execute(container, 'bin/bash', 'ti') else: # image is not present locally ## PULL ## # TODO: Test connection before pulling pullImage(image) createAndRun(user=user, image=image, ports=ports, mode=mode, keypath=keypath, cap_add=cap_add, devices=devices, label=label)