Ejemplo n.º 1
0
 def __init__(self):
     try:
         self.docker_cli = docker.from_env(version='auto')
         self.container_name = 'splash-detectem'
     except docker.errors.DockerException:
         raise DockerStartError("Could not connect to Docker daemon. "
                                "Please ensure Docker is running.")
Ejemplo n.º 2
0
 def start_container(self):
     container = self._get_container()
     if container.status != 'running':
         try:
             container.start()
             self._wait_container()
         except docker.errors.APIError as e:
             raise DockerStartError(
                 "There was an error running Splash container: {}".format(
                     e.explanation))
Ejemplo n.º 3
0
 def start_container(self):
     container = self._get_container()
     if container.status != "running":
         try:
             container.start()
             self._wait_container()
         except docker.errors.APIError as e:
             raise DockerStartError(
                 f"There was an error running Splash container: {e.explanation}"
             )
Ejemplo n.º 4
0
    def setup(self, n_instances: int):
        """Fill ``self._instances`` with created containers.

        ``n_instances`` could be equal to NUMBER_OF_SPLASH_INSTANCES or lower
        since it's also determined by the number of URLs to analyze.

        It also checks that the target docker image exists
        and there weren't any issues creating the containers.

        """
        # Check base image
        try:
            self.docker_cli.images.get(DOCKER_SPLASH_IMAGE)
        except docker.errors.ImageNotFound:
            raise DockerStartError(
                f"Docker image {DOCKER_SPLASH_IMAGE} not found."
                f"Please install it or set an image using DOCKER_SPLASH_IMAGE environment variable."
            )

        for container_index in range(n_instances):
            container_name = f"splash-detectem-{container_index}"
            port = 8050 + container_index

            self._instances[container_name] = {
                "url": f"http://localhost:{port}",
                "in_use": False,
                "errors": 0,
            }

            try:
                container: Container = self.docker_cli.containers.get(container_name)
            except docker.errors.NotFound:
                # If not found, create it
                container: Container = self.docker_cli.containers.create(
                    name=container_name,
                    image=DOCKER_SPLASH_IMAGE,
                    ports={
                        "8050/tcp": ("127.0.0.1", port),
                    },
                    command=f"--max-timeout {SPLASH_MAX_TIMEOUT}",
                )

            if container.status != "running":
                container.start()

                try:
                    self._wait_container(container_name)
                except DockerStartError:
                    # If the container didn't start it's probable to be a unrecuperable error
                    # We stop it and delete the container to be recreated next run
                    container.stop()
                    container.remove()
                    # Also it's not available to send work to
                    del self._instances[container_name]
                    continue
Ejemplo n.º 5
0
 def _wait_container(self):
     for t in [1, 2, 4, 6, 8, 10]:
         try:
             requests.get('{}/_ping'.format(SPLASH_URL))
             break
         except requests.exceptions.RequestException:
             time.sleep(t)
     else:
         raise DockerStartError(
             "Could not connect to started Splash container. "
             "See 'docker logs splash-detectem' for more details, "
             "or remove the container to try again.")
Ejemplo n.º 6
0
    def _wait_container(self, container_name):
        """ Wait until Splash HTTP service is ready to receive requests """
        url = self._instances[container_name]["url"]

        for t in [1, 2, 4, 6, 8, 10]:
            try:
                requests.get(f"{url}/_ping")
                break
            except requests.exceptions.RequestException:
                time.sleep(t)
        else:
            raise DockerStartError(
                f"Could not connect to started Splash container. "
                f"See 'docker logs {container_name}' for more details."
            )
Ejemplo n.º 7
0
    def docker_cli(self) -> DockerClient:
        """Return a docker client instance

        Raises:
            - DockerError
        """
        if not self._docker_cli:
            try:
                self._docker_cli: DockerClient = docker.from_env(version="auto")
            except docker.errors.DockerException:
                raise DockerStartError(
                    "Could not connect to Docker daemon. "
                    "Please ensure Docker is running and your user has access."
                )

        return self._docker_cli
Ejemplo n.º 8
0
 def _get_container(self):
     try:
         return self.docker_cli.containers.get(self.container_name)
     except docker.errors.NotFound:
         try:
             return self.docker_cli.containers.create(
                 name=self.container_name,
                 image=DOCKER_SPLASH_IMAGE,
                 ports={
                     '5023/tcp': 5023,
                     '8050/tcp': 8050,
                     '8051/tcp': 8051,
                 },
                 command=self._get_splash_args(),
             )
         except docker.errors.ImageNotFound:
             raise DockerStartError(
                 "Docker image {} not found. Please install it or set an image "
                 "using DOCKER_SPLASH_IMAGE environment variable.".format(
                     DOCKER_SPLASH_IMAGE))
Ejemplo n.º 9
0
 def _get_container(self):
     try:
         return self.docker_cli.containers.get(self.container_name)
     except docker.errors.NotFound:
         try:
             return self.docker_cli.containers.create(
                 name=self.container_name,
                 image=DOCKER_SPLASH_IMAGE,
                 ports={
                     "5023/tcp": ("127.0.0.1", 5023),
                     "8050/tcp": ("127.0.0.1", 8050),
                     "8051/tcp": ("127.0.0.1", 8051),
                 },
                 command=self._get_splash_args(),
             )
         except docker.errors.ImageNotFound:
             raise DockerStartError(
                 f"Docker image {DOCKER_SPLASH_IMAGE} not found."
                 f"Please install it or set an image "
                 f"using DOCKER_SPLASH_IMAGE environment variable.")
Ejemplo n.º 10
0
 def run_method(self=None):
     try:
         method(self)
     except docker.errors.DockerException as e:
         raise DockerStartError("Docker error: {}".format(e))
Ejemplo n.º 11
0
 def run_method(self=None):
     try:
         method(self)
     except docker.errors.DockerException as e:
         raise DockerStartError(f"Docker error: {e}")
Ejemplo n.º 12
0
 def run_method(*args, **kwargs):
     try:
         method(*args, **kwargs)
     except docker.errors.DockerException as e:
         raise DockerStartError(f"Docker error: {e}")
Ejemplo n.º 13
0
 def _conditional_mock(*args, **kwargs):
     # Raise exception for only one container
     if args[0] == "splash-detectem-0":
         raise DockerStartError()