Example #1
0
 def _run(command: Union[str, List[str]], container: ContainerisedIrodsServer) -> str:
     """
     Run the given commend on the containerised server.
     :param command: the command to run
     :param container: the containerised server to run the command in
     """
     container_id = container.native_object["Id"]
     docker_client = create_client()
     id = docker_client.exec_create(container_id, cmd=command)
     chunks = []
     for chunk in docker_client.exec_start(id, stream=True):
         logging.debug(chunk)
         chunks.append(chunk.decode("utf-8"))
     return "".join(chunks)
Example #2
0
 def test_baton_can_connect_to_irods_with_setting_parameters(self):
     irods_server = type(self).get_irods_server(self._irods_version)
     host_config = create_client().create_host_config(links={
         irods_server.host: irods_server.host
     })
     user = irods_server.users[0]
     response = self._run(command="ils", environment={
         "IRODS_HOST": irods_server.host,
         "IRODS_PORT": irods_server.port,
         "IRODS_USERNAME": user.username,
         "IRODS_ZONE": user.zone,
         "IRODS_PASSWORD": user.password
     }, host_config=host_config)
     self.assertEqual(response, "/%s/home/%s:" % (user.zone, user.username))
Example #3
0
 def _run(command: Union[str, List[str]],
          service: IrodsDockerisedService) -> str:
     """
     Run the given commend on the containerised server.
     :param command: the command to run
     :param service: the containerised service managing the iCAT
     """
     container_id = service.container["Id"]
     docker_client = create_client()
     id = docker_client.exec_create(container_id, cmd=command)
     chunks = []
     for chunk in docker_client.exec_start(id, stream=True):
         logging.debug(chunk)
         chunks.append(chunk.decode("utf-8"))
     return "".join(chunks)
Example #4
0
 def _run(self, stderr: bool=True, **kwargs) -> str:
     """
     Run the containerised baton image that is been tested.
     :param stderr: whether content written to stderr should be included in the return
     :param kwargs: named arguments that are binded to corresponding parameters in docker-py's `create_container`
     method
     :return: what the command put onto stdout and stderr (if applicable)
     """
     client = create_client()
     tag = self._top_level_image[1][0]
     container = client.create_container(tag, **kwargs)
     id = container.get("Id")
     client.start(id)
     client.wait(id)
     responses = client.logs(id, stderr=stderr).decode("utf-8")
     return "".join(responses).strip()
Example #5
0
    def _build_image(top_level_image: Tuple[Optional[Tuple], Tuple[str, str]]):
        """
        Builds images bottom up, building the top level image last.
        :param top_level_image: representation of the top level image
        """
        image = top_level_image
        images = []     # type: List[Tuple[str, str]]
        while image is not None:
            images.insert(0, image[1])
            image = image[0]

        docker_client = create_client()
        for image in images:
            tag = image[0]
            directory = "%s/%s" % (_PROJECT_ROOT, image[1])
            for line in docker_client.build(tag=tag, path=directory):
                logging.debug(line)
Example #6
0
    def _build_image(top_level_image: Tuple[Optional[Tuple], Tuple[str, str]]):
        """
        Builds images bottom up, building the top level image last.
        :param top_level_image: representation of the top level image
        """
        image = top_level_image
        images = []  # type: List[Tuple[str, str]]
        while image is not None:
            images.insert(0, image[1])
            image = image[0]

        docker_client = create_client()
        for image in images:
            tag = image[0]
            directory = "%s/%s" % (_PROJECT_ROOT, image[1])
            for line in docker_client.build(tag=tag, path=directory):
                logging.debug(line)
Example #7
0
def setup_influxdb_in_docker(repository: str, tag: str) -> Tuple[str, int, Callable]:
    """
    Setup an InfluxDB instance in docker using the given Docker Hub repository and tag.
    :param repository: the Docker Hub repository URL
    :param tag: the Docker Hub repository tag
    :return: tuple where the first element is the location of the database, the second is the port the HTTP API runs on
    and the third is a method to tear down the database
    """
    docker_client = create_client()

    response = docker_client.pull(repository, tag)
    logging.debug(response)

    http_api_port = get_open_port()

    container = docker_client.create_container(
        name="influxdb-%s" % uuid4(),
        image="%s:%s" % (repository, tag),
        ports=[http_api_port],
        host_config=docker_client.create_host_config(
            port_bindings={
                8086: http_api_port
            }
        )
    )

    # Ensure that, no matter what, the container gets killed
    def tear_down():
        docker_client.kill(container)
        atexit.unregister(tear_down)

    atexit.register(tear_down)

    docker_client.start(container)
    logging.info("Waiting for InfluxDB server to setup")
    for line in docker_client.logs(container, stream=True):
        logging.debug(line)
        if "Listening for signals" in str(line):
            break

    url = urlparse(docker_client.base_url)
    host = url.hostname if url.scheme in ["http", "https"] else "localhost"

    return host, http_api_port, tear_down
Example #8
0
    def test_baton_can_connect_to_irods_with_settings_file(self):
        irods_server = type(self).get_irods_server(self._irods_version)

        settings_directory = create_temp_docker_mountable_directory()
        IrodsController = get_static_irods_server_controller(self._irods_version)
        # XXX: This is rather hacky - it should be possible to get the name from the iRODS controller
        if self._irods_version == IrodsVersion.v3_3_1:
            IrodsController.write_connection_settings("%s/.irodsEnv" % settings_directory, irods_server)
        else:
            IrodsController.write_connection_settings("%s/irods_environment.json" % settings_directory, irods_server)
        host_config = create_client().create_host_config(binds={
            settings_directory: {
                "bind": "/root/.irods",
                "mode": "rw"
            }
        }, links={
            irods_server.host: irods_server.host
        })

        user = irods_server.users[0]
        response = self._run(command="ils", environment={"IRODS_PASSWORD": user.password}, host_config=host_config)
        self.assertEqual(response, "/%s/home/%s:" % (user.zone, user.username))
Example #9
0
    def setup(self):
        """
        Sets up the setup: builds the baton Docker image, starts the iRODS test server (if required) and creates the
        proxies.
        """
        if self._state != TestWithBaton._SetupState.INIT:
            raise RuntimeError("Already been setup")
        self._state = TestWithBaton._SetupState.RUNNING

        docker_client = create_client()
        if self._baton_docker_build.docker_file is not None:
            # baton Docker image is to be built from a local Dockerfile
            logging.debug("Building baton Docker")
            build_baton_docker(docker_client, self._baton_docker_build)
        else:
            # Ensuring Docker image is pulled - not waiting until `docker run` to prevent Docker from polluting the
            # stderr
            if ":" in self._baton_docker_build.tag:
                repository, tag = self._baton_docker_build.tag.split(":")
            else:
                repository = self._baton_docker_build.tag
                tag = ""

            docker_image = docker_client.images("%s:%s" % (repository, tag), quiet=True)
            if len(docker_image) == 0:
                # Docker image doesn't exist locally: getting from DockerHub
                docker_client.pull(repository, tag)

        if self._irods_version_to_start:
            logging.debug("Starting iRODS test server")
            self.irods_server = get_static_irods_server_controller(self._irods_version_to_start).start_server()
            logging.debug("iRODS test server has started")
        else:
            logging.debug("Using pre-existing iRODS server")

        self._setup_proxies()

        logging.debug("Setup complete")
Example #10
0
    def __init__(self):
        """ Build and start the containerised instance """
        self._client = client = create_client()
        self._url = url = urlparse(self._client.base_url)

        self._host = url.hostname if url.scheme in ['http', 'https'] else 'localhost'
        self._port = get_open_port()

        # Exposed interface for CouchDB
        self.couchdb_fqdn = 'http://{host}:{port}'.format(host=self._host, port=self._port)

        # Build image
        # n.b., This will take a while, the first time through
        logging.info('Building CouchDB image...')
        logging.debug([
            line for line in client.build(
                path = _DOCKERFILE_PATH,
                tag  = _COUCHDB_IMAGE
            )
        ])

        # Create container
        self.container = client.create_container(
            image       = _COUCHDB_IMAGE,
            ports       = [self._port],
            host_config = client.create_host_config(
                port_bindings = {5984: self._port}
            )
        )

        # Start container
        logging.info('Starting CouchDB container {Id}...'.format(**self.container))
        logging.debug('Warnings: {Warnings}'.format(**self.container))
        atexit.register(self.tear_down)
        client.start(self.container['Id'])

        # Block 'til 200 OK response received (or timeout)
        test_connection = HTTPConnection(self._host, self._port)
        start_time = finish_time = datetime.now()
        couchdb_started = False
        while finish_time - start_time < timedelta(minutes=1):
            response = None

            try:
                test_connection.request('HEAD', '/')
                response = test_connection.getresponse()

            except:
                sleep(0.1)

            finally:
                test_connection.close()
                finish_time = datetime.now()

            if isinstance(response, HTTPResponse) and response.status == 200:
                couchdb_started = True
                break

        if not couchdb_started:
            self.tear_down()
            raise ConnectionError('Couldn\'t start CouchDB in a reasonable amount of time')

        logging.info('CouchDB container available on {fqdn}'.format(fqdn=self.couchdb_fqdn))