def pull(self, image): self._ensure_singularity() if image in self.pulled_images: return if image.startswith('instance://'): return image image_file = self._image_file(image) if os.path.exists(image_file): env.logger.debug( f'Using existing singularity image {image_file.replace(os.path.expanduser("~"), "~")}' ) return if '://' not in image: raise ValueError( f'Cannot locate or pull singularity image {image}') # ask controller while True: res = request_answer_from_controller( ['resource', 'singularity_image', 'request', image]) if res == 'pending': time.sleep(0.5) elif res == 'available': return elif res == 'unavailable': raise RuntimeError(f'Docker image {image} is unavailable') elif res == 'help yourself': break else: raise ValueError(f'Unrecognized request from controller {res}') # if image is specified, check if it is available locally. If not, pull it try: print( f'HINT: Pulling singularity image {image} to {image_file.replace(os.path.expanduser("~"), "~")}' ) subprocess.check_output('singularity pull {} {}'.format( image_file, image), stderr=subprocess.STDOUT, shell=True, universal_newlines=True) self.pulled_images.add(image) except subprocess.CalledProcessError as exc: send_message_to_controller( ['resource', 'singularity_image', 'unavailable', image]) env.logger.warning(f'Failed to pull {image}: {exc.output}') if not path(image_file).exists(): raise ValueError( f'Image {image_file} does not exist after pulling {image}.') else: print(f'HINT: Singularity image {image} is now up to date') send_message_to_controller( ['resource', 'singularity_image', 'available', image])
def pull(self, image): if not self.client: raise RuntimeError( 'Cannot connect to the Docker daemon. Is the docker daemon running on this host?' ) if image in self.pulled_images: return # ask controller while True: res = request_answer_from_controller( ['resource', 'docker_image', 'request', image]) if res == 'pending': time.sleep(0.5) elif res == 'available': return elif res == 'unavailable': raise RuntimeError(f'Docker image {image} is unavailable') elif res == 'help yourself': break else: raise ValueError(f'Unrecognized request from controller {res}') # if image is specified, check if it is available locally. If not, pull it err_msg = '' try: print(f'HINT: Pulling docker image {image}') subprocess.check_output('docker pull {}'.format(image), stderr=subprocess.STDOUT, shell=True, universal_newlines=True) except subprocess.CalledProcessError as exc: err_msg = exc.output if not self._is_image_avail(image): send_message_to_controller( ['resource', 'docker_image', 'unavailable', image]) raise RuntimeError( f'Failed to pull docker image {image}:\n {err_msg}') else: print(f'HINT: Docker image {image} is now up to date') send_message_to_controller( ['resource', 'docker_image', 'available', image]) self.pulled_images.add(image)