def wait_on_pod_ready(self): """Wait until job's pod initializes, pulls image, and starts running.""" self.log.info('Creating pod...') for i in range(POD_CHECK_RETRIES): pods = self.get_pods() if len(pods) < 1: time.sleep(POD_CHECK_DELAY_SECONDS) continue break if len(pods) < 1: self.cleanup() raise exceptions.AnsibleTestError( 'Could not create pod assocated with job') self.log.info('Scheduling pod and waiting until it is running...') for i in range(POD_CHECK_RETRIES): pods = self.get_pods() pod_phase = pods[0]['status']['phase'] if pod_phase != 'Pending': return time.sleep(POD_CHECK_DELAY_SECONDS) self.log.debug(pods[0]['status']) self.cleanup() raise exceptions.AnsibleTestError( 'Could not start pod assocated with job')
def _build_image_with_artifact(container_engine, dir): pkg_entrypoint = pkg_resources.resource_filename( "galaxy_importer", "ansible_test/container/entrypoint.sh") shutil.copyfile(pkg_entrypoint, os.path.join(dir, "entrypoint.sh")) cmd = [container_engine, "build", ".", "--quiet"] proc = Popen( cmd, cwd=dir, stdout=PIPE, stderr=STDOUT, encoding="utf-8", ) image_id = "" for line in proc.stdout: image_id = line.strip() return_code = proc.wait() if return_code != 0: raise exceptions.AnsibleTestError( "An exception occurred in {}, returncode={}".format( " ".join(cmd), return_code)) if container_engine == "docker": image_id = image_id.split(":")[-1] return image_id
def _wait_until_image_available(self): self.log.info('Waiting until image is available...') for i in range(API_CHECK_RETRIES): if self._get_image(): return time.sleep(API_CHECK_DELAY_SECONDS) raise exceptions.AnsibleTestError('Image was not available')
def _wait_until_build_created(self): self.log.info('Creating build...') for i in range(API_CHECK_RETRIES): build = self._get_build() if len(build['items']) > 0: return time.sleep(API_CHECK_DELAY_SECONDS) raise exceptions.AnsibleTestError('Could not create build')
def cleanup(self): self.log.info('Removing temporary files, image and container') self.working_dir.cleanup() cmd = [self.container_engine, 'image', 'rm', '-f', self.image] try: run(cmd) except CalledProcessError as e: raise exceptions.AnsibleTestError( 'An exception occurred in: {}, message={}'.format(' '.join(cmd), e.msg))
def _get_build(self): """Get build associated with buildconfig.""" params = {'labelSelector': f'buildconfig={self.name}'} r = requests.get(self.build_url, headers=self.auth_header, params=params, verify=self.ca_path) if r.status_code != requests.codes.ok: raise exceptions.AnsibleTestError(f'Could not access builds') return r.json()
def _wait_until_build_complete(self): self.log.info('Waiting until build is complete...') for i in range(API_CHECK_RETRIES): build = self._get_build() build_phase = build['items'][0]['status']['phase'] if build_phase == 'Complete': return time.sleep(API_CHECK_DELAY_SECONDS) raise exceptions.AnsibleTestError( 'Unable to build image within timeout')
def cleanup(self): self.log.info("Removing temporary files, image and container") self.working_dir.cleanup() cmd = [self.container_engine, "image", "rm", "-f", self.image] try: run(cmd) except CalledProcessError as e: raise exceptions.AnsibleTestError( "An exception occurred in: {}, message={}".format( " ".join(cmd), e.msg))
def _create_buildconfig(self): self.log.info(f'Creating buildconfig {self.name}') r = requests.post( self.buildconfig_url, headers=self.auth_header, json=yaml.safe_load(self.build_yaml), verify=self.ca_path, ) if r.status_code != requests.codes.created: raise exceptions.AnsibleTestError( f'Could not create buildconfig: {r.status_code} {r.reason} {r.text}' )
def get_pods(self): """Get pods associated with job.""" params = {'labelSelector': f'job-name={self.name}'} r = requests.get(self.pods_url, headers=self.auth_header, params=params, verify=self.ca_path) try: pods = r.json()['items'] except (KeyError, ValueError): raise exceptions.AnsibleTestError( 'Could not access pod assocated with job') return pods
def create(self): """Create the job.""" self.log.info(f'Creating job {self.name}') r = requests.post( self.jobs_url, headers=self.auth_header, json=yaml.safe_load(self.job_yaml), verify=self.ca_path, ) if r.status_code != requests.codes.created: raise exceptions.AnsibleTestError( f'Could not create job: {r.status_code} {r.reason} {r.text}')
def _run_image(self, image_id): cmd = ['docker', 'run', image_id] proc = Popen( cmd, stdout=PIPE, stderr=STDOUT, encoding='utf-8', ) for line in proc.stdout: self.log.info(line.strip()) return_code = proc.wait() if return_code != 0: raise exceptions.AnsibleTestError( 'An exception occurred in {}, returncode={}'.format( ' '.join(cmd), return_code))
def _run_image(self, image_id, container_engine): cmd = [container_engine, 'run', image_id, 'LOCAL_IMAGE_RUNNER'] proc = Popen( cmd, stdout=PIPE, stderr=STDOUT, encoding='utf-8', ) for line in proc.stdout: self.log.info(line.strip()) return_code = proc.wait() if return_code != 0: raise exceptions.AnsibleTestError( 'An exception occurred in {}, returncode={}'.format( ' '.join(cmd), return_code))
def _build_image_with_artifact(dir): cmd = ['docker', 'build', '.', '--quiet'] proc = Popen( cmd, cwd=dir, stdout=PIPE, stderr=STDOUT, encoding='utf-8', ) result = '' for line in proc.stdout: result = line.strip() return_code = proc.wait() if return_code != 0: raise exceptions.AnsibleTestError( 'An exception occurred in {}, returncode={}'.format( ' '.join(cmd), return_code)) return result.split(':')[-1]
def cleanup(self): """Deletes job and any pods associated to it.""" requests.delete(self.job_name_url, headers=self.auth_header, verify=self.ca_path) self.log.debug(f'Deleted job {self.name}') for pod in self.get_pods(): pod_name = self.get_pod_name(pod) requests.delete(f'{self.pods_url}/{pod_name}', headers=self.auth_header, verify=self.ca_path) self.log.debug(f'Deleted pod {pod_name}') status = pod['status']['phase'] if status == 'Failed': reason = pod['status']['containerStatuses'][0]['state'][ 'terminated']['reason'] raise exceptions.AnsibleTestError( f'Pod terminated with status: "{status}" and reason: "{reason}"' )
def _build_image_with_artifact(container_engine, dir): cmd = [container_engine, 'build', '.', '--quiet'] proc = Popen( cmd, cwd=dir, stdout=PIPE, stderr=STDOUT, encoding='utf-8', ) image_id = '' for line in proc.stdout: image_id = line.strip() return_code = proc.wait() if return_code != 0: raise exceptions.AnsibleTestError( 'An exception occurred in {}, returncode={}' .format(' '.join(cmd), return_code)) if container_engine == 'docker': image_id = image_id.split(':')[-1] return image_id
def cleanup(self): """Deletes job and any pods associated to it.""" requests.delete(self.job_name_url, headers=self.auth_header, verify=self.ca_path) self.log.debug(f"Deleted job {self.name}") for pod in self.get_pods(): pod_name = self.get_pod_name(pod) requests.delete( f"{self.pods_url}/{pod_name}", headers=self.auth_header, verify=self.ca_path, ) self.log.debug(f"Deleted pod {pod_name}") status = pod["status"]["phase"] if status == "Failed": reason = pod["status"]["containerStatuses"][0]["state"][ "terminated"]["reason"] raise exceptions.AnsibleTestError( f'Pod terminated with status: "{status}" and reason: "{reason}"' )