def get_container_config(self, entity, key=None): """ Retrieve Config dictionary for a container. If key is specified, only return the key within the Config dictionary. Args: entity: Service or Container or service id or service name or container id or container name key: desired config key Returns: dict """ if not entity: raise NotFoundError('No entity provided') # first, try if entity is a container try: wait_on_container_status(self, entity) c = self._docker.containers.get(entity) except docker.errors.NotFound: # second, try if entity is a service try: c = self.get_containers_for_service(entity)[0] except NotFoundError: raise NotFoundError('Could not find service {}'.format(entity)) if key: return c.attrs['Config'].get(key, None) else: return c.attrs['Config']
def put_file(self, entity, file_to_transfer='', destination='/', filename=None): """ Copy a file onto a running container. Args: entity: docker.models.containers.Container file_to_transfer: local file object destination: path to the destination filename: destination file name Returns: None """ if not os.path.isfile(file_to_transfer): raise NotFoundError('File {} not found'.format(file_to_transfer)) if isinstance(entity, Container): entity = entity.name filename = filename or os.path.basename(file_to_transfer) BuiltIn().log('Putting file {} on {}'.format(filename, entity), level='INFO', console=Settings.to_console) with open(file_to_transfer, 'r') as f: content = f.read() self._send_file(content, destination, entity, filename)
def run_busybox(self, **kwargs): """ Helper method for conftest.py to create a running dummy container. Args: **kwargs: any argument that a Container object takes except for image, command, name and detach Returns: Container """ try: name = namesgenerator.get_random_name() command = kwargs.pop( 'command', 'sh -c "while true; do $(echo date "GET / HTTP/1.1"); sleep 1; done"' ) self._docker.containers.run('busybox', command=command, name=name, detach=True, **kwargs) return self._docker.containers.get(name) except docker.errors.NotFound as exc: raise NotFoundError(exc) except docker.errors.APIError as exc: raise DeploymentError(exc)
def get_container_logs(self, container): try: if not isinstance(container, Container): container = self.get_container(container) return {'res': container.logs(), 'code': 0} except docker.errors.APIError as exc: raise NotFoundError('get_container_logs failed: {}'.format(exc))
def _check_sut_availability(self, temp_sut): """ Helper method to determine if an SUT is available. Makes use of the Orchestrator instance. Args: temp_sut: namedtuple Returns: temp_sut: namedtuple """ try: if temp_sut.target_type == 'network': self.orchestrator.controller.get_network(temp_sut.service_id) elif temp_sut.target_type == 'service': self.orchestrator.controller.get_service(temp_sut.service_id) self.orchestrator.controller.get_containers_for_service( temp_sut.service_id) elif temp_sut.target_type == 'container': self.orchestrator.controller.get_containers( filters={'name': temp_sut.service_id}, all=True) else: raise NotFoundError( '_check_sut_availability: target_type {} is invalid'. format(temp_sut.target_type)) return temp_sut except NotFoundError as exc: raise exc
def _get_record_by_pk(self, pk, pk_val) -> dict: """ Obtain record by given primary key :param pk: primary key name :param pk_val: primary key value :return: record dict """ data = self._impl_object.get(self.__class__, pk, pk_val) # type: dict if not data: raise NotFoundError("Cannot find record with {}='{}'".format( pk, pk_val)) return data
def get_network(self, name): """ Retrieves a network by name Args: name: str Returns: docker.models.networks.Network """ try: return self._docker.networks.get(name) except docker.errors.NotFound as exc: raise NotFoundError(exc)
def get_container(self, container): """ Retrieves a container by its name or id. Args: container: container name or container id Returns: docker.models.containers.Container """ try: return self._docker.containers.get(container) except (docker.errors.NotFound, docker.errors.APIError) as exc: raise NotFoundError(exc)
def get_containers(self, **kwargs): """ Retrieve containers that match the filters specified by **kwargs. Refer to the Docker help for available filters. Args: **kwargs: filters Returns: [Container] """ try: return self._docker.containers.list(**kwargs) except docker.errors.APIError as exc: raise NotFoundError('get_containers failed: {}'.format(exc))
def get_service(self, service): """ Wait for service replication and retrieve a service. Args: service: Service or service id or service name Returns: docker.models.services.Service """ try: wait_on_service_replication(self._docker, service) return self._docker.services.get(service) except docker.errors.NotFound as exc: raise NotFoundError('Cannot find service {}: {}'.format( service, exc))
def get_or_pull_image(self, image): """ Retrieves an image from hub.docker.com. Args: image: str - image name Returns: None """ try: self._docker.images.get(image) except docker.errors.ImageNotFound: try: logger.console('Fetching sidecar image...') self._docker.images.pull(image) except docker.errors.ImageNotFound as exc: raise NotFoundError('Image {} not found: {}'.format( image, exc))
def get_containers_for_service(self, service, state='running'): """ For the given service, wait until a timeout occurs or at least one container is in the specified state. Args: service: Service or service name or service id state: expected state of service Returns: [Container] """ service = service.name if isinstance(service, Service) else service assert isinstance(service, basestring) try: wait_on_service_replication(self._docker, service) wait_on_service_container_status(self, service) res = self._docker.containers.list( all=True, filters={ 'label': 'com.docker.swarm.service.name={}'.format(service), 'status': lower(state) }) # BuiltIn().log('Get containers for services {}: {}'.format( # service, [c.name for c in res ] if res else 'None'), level='DEBUG', console=Settings.to_console) if res: return res else: BuiltIn().log( 'No containers found for service {}'.format(service), level='INFO', console=True) raise NotFoundError except NotFoundError: raise except docker.errors.NotFound as exc: raise NotFoundError(exc)
def update_sut(self, **kwargs): """ Update the sut object with the values provided in **kwargs. Before the update takes place, we check if the updated SUT is available. Args: **kwargs: target_type, target, service_id Returns: None """ # create a new namedtuple and use the old values if no new value is available # noinspection PyProtectedMember temp_sut = self.sut._replace( target_type=kwargs.get('target_type', self.sut.target_type), target=kwargs.get('target', self.sut.target), service_id=kwargs.get('service_id', self.sut.service_id), ) try: # set_breakpoint() self.sut = self._check_sut_availability(temp_sut) BuiltIn().log( '\nUpdating context: target_type={}, service_id={}, target={}'. format( self.sut.target_type if self.sut.target_type else 'Not set', self.sut.service_id if self.sut.service_id else 'Not set', self.sut.target if self.sut.target else 'Not set'), level='INFO', console=Settings.to_console) except NotFoundError as exc: raise NotFoundError( 'update_sut: Fatal error: {} "{}" not found in deployment "{}".' .format(temp_sut.target_type, temp_sut.target, self.deployment_name))
def execute(self, entity=None, command=None): """ Executes a command within a Docker container. Args: entity: Container object or container name or container id command: str or list - command to execute in the container Returns: dict: { 'code': int, 'rest': str } """ target = entity if isinstance(entity, Container) else None if not target: try: target = self.get_container(entity) except (NotFoundError, TypeError): try: target = self.get_containers_for_service(entity)[0] except (NotFoundError, TypeError): raise NotFoundError( 'Could not find entity (service or container) {}'. format(entity if entity else '<None>')) BuiltIn().log('Running "{}" in {}'.format(command, target.name), level='INFO', console=Settings.to_console) container_status = target.status if 'created' in container_status: return self.run_sidecar(sidecar=target) else: return self._run_in_container(container=target, command=command)