From 1512a6835a6984d4cb2090c6ba9e096b8d7755a1 Mon Sep 17 00:00:00 2001 From: Gladys Nalvarte Date: Fri, 20 Jul 2018 11:45:01 +0200 Subject: [PATCH 1/4] Explicit hostname supplied to the container --- repo2docker/app.py | 10 +++++++ tests/test_connect_url.py | 55 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 tests/test_connect_url.py diff --git a/repo2docker/app.py b/repo2docker/app.py index d98b9226..3ddf11ee 100644 --- a/repo2docker/app.py +++ b/repo2docker/app.py @@ -18,6 +18,7 @@ import tempfile import time import docker +from urllib.parse import urlparse from docker.utils import kwargs_from_env from docker.errors import DockerException import escapism @@ -517,6 +518,14 @@ class Repo2Docker(Application): ports = {} # store ports on self so they can be retrieved in tests self.ports = ports + + docker_host = os.environ.get('DOCKER_HOST') + if docker_host: + host_name = urlparse(docker_host).host_name + else: + host_name = '127.0.0.1' + self.hostname = host_name + container_volumes = {} if self.volumes: api_client = docker.APIClient( @@ -536,6 +545,7 @@ class Repo2Docker(Application): self.output_image_spec, publish_all_ports=self.all_ports, ports=ports, + hostname=host_name, detach=True, command=run_cmd, volumes=container_volumes, diff --git a/tests/test_connect_url.py b/tests/test_connect_url.py new file mode 100644 index 00000000..91c73266 --- /dev/null +++ b/tests/test_connect_url.py @@ -0,0 +1,55 @@ +""" +Test if the environment.yml is empty or it constains other data structure than a dictionary +""" +import os +import sys +import pytest +import requests +import time +from repo2docker.app import Repo2Docker + +def test_env_yml(tmpdir): + tmpdir.chdir() + #q = tmpdir.join("environment.yml") + #q.write("dependencies:\n" + # " - notebook==5.6.0rc1") + p = tmpdir.join("requirements.txt") + p.write("notebook==5.6.0rc1") + + app = Repo2Docker() + argv = [str(tmpdir), ] + app.initialize(argv) + app.run = False + app.start() # This just build the image and does not run it. + detect = app.build + print("app.build",detect) + container = app.start_container() + port = app.port + print("port in test", port) + hostname = app.hostname + # wait a bit for the container to be ready + container_url = 'http://{}:{}/api'.format(hostname, port) + print("print container url",container_url) + # wait a bit for the container to be ready + # give the container a chance to start + time.sleep(1) + try: + # try a few times to connect + success = False + for i in range(1, 4): + container.reload() + assert container.status == 'running' + try: + info = requests.get(container_url).json() + except Exception as e: + print("Error: %s" % e) + time.sleep(i * 3) + else: + print(info) + success = True + break + assert success, "Notebook never started in %s" % container + finally: + # stop the container + container.stop() + app.wait_for_container(container) From e0b92796a45dea66ff9970323011bd4cd8986ce6 Mon Sep 17 00:00:00 2001 From: Gladys Nalvarte Date: Fri, 20 Jul 2018 13:19:15 +0200 Subject: [PATCH 2/4] Updates the test_connect_url description and deletes print statements --- tests/test_connect_url.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/test_connect_url.py b/tests/test_connect_url.py index 91c73266..6d21525c 100644 --- a/tests/test_connect_url.py +++ b/tests/test_connect_url.py @@ -1,5 +1,5 @@ """ -Test if the environment.yml is empty or it constains other data structure than a dictionary +Test if the explict hostname is supplied correctly to the container """ import os import sys @@ -21,15 +21,11 @@ def test_env_yml(tmpdir): app.initialize(argv) app.run = False app.start() # This just build the image and does not run it. - detect = app.build - print("app.build",detect) container = app.start_container() port = app.port - print("port in test", port) hostname = app.hostname # wait a bit for the container to be ready container_url = 'http://{}:{}/api'.format(hostname, port) - print("print container url",container_url) # wait a bit for the container to be ready # give the container a chance to start time.sleep(1) From 4c0cb69b8093dd5494669c56f36d6805ab3fd282 Mon Sep 17 00:00:00 2001 From: Gladys Nalvarte Date: Tue, 31 Jul 2018 11:28:20 +0200 Subject: [PATCH 3/4] Uses jupyter/notebook option to pass explicit hostname --- repo2docker/app.py | 27 +++++++++++++++++---------- tests/test_connect_url.py | 19 ++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/repo2docker/app.py b/repo2docker/app.py index 3ddf11ee..1e0c7853 100644 --- a/repo2docker/app.py +++ b/repo2docker/app.py @@ -503,11 +503,26 @@ class Repo2Docker(Application): Returns running container """ client = docker.from_env(version='auto') + + docker_host = os.environ.get('DOCKER_HOST') + if docker_host: + host_name = urlparse(docker_host).hostname + else: + host_name = '127.0.0.1' + self.hostname = host_name + if not self.run_cmd: port = str(self._get_free_port()) self.port = port - run_cmd = ['jupyter', 'notebook', '--ip', '0.0.0.0', - '--port', port] + # To use the option --NotebookApp.custom_display_url + # make sure the base-notebook image is updated: + # docker pull jupyter/base-notebook + run_cmd = [ + 'jupyter', 'notebook', + '--ip', '0.0.0.0', + '--port', port, + "--NotebookApp.custom_display_url=http://{}:{}".format(host_name, port), + ] ports = {'%s/tcp' % port: port} else: # run_cmd given by user, if port is also given then pass it on @@ -519,13 +534,6 @@ class Repo2Docker(Application): # store ports on self so they can be retrieved in tests self.ports = ports - docker_host = os.environ.get('DOCKER_HOST') - if docker_host: - host_name = urlparse(docker_host).host_name - else: - host_name = '127.0.0.1' - self.hostname = host_name - container_volumes = {} if self.volumes: api_client = docker.APIClient( @@ -545,7 +553,6 @@ class Repo2Docker(Application): self.output_image_spec, publish_all_ports=self.all_ports, ports=ports, - hostname=host_name, detach=True, command=run_cmd, volumes=container_volumes, diff --git a/tests/test_connect_url.py b/tests/test_connect_url.py index 6d21525c..14ddb8c6 100644 --- a/tests/test_connect_url.py +++ b/tests/test_connect_url.py @@ -6,35 +6,40 @@ import sys import pytest import requests import time +import urllib.parse from repo2docker.app import Repo2Docker -def test_env_yml(tmpdir): +def test_connect_url(tmpdir): tmpdir.chdir() #q = tmpdir.join("environment.yml") #q.write("dependencies:\n" - # " - notebook==5.6.0rc1") + # " - notebook==5.6.0") p = tmpdir.join("requirements.txt") - p.write("notebook==5.6.0rc1") + p.write("notebook==5.6.0") app = Repo2Docker() argv = [str(tmpdir), ] app.initialize(argv) + app.debug = True app.run = False app.start() # This just build the image and does not run it. container = app.start_container() - port = app.port - hostname = app.hostname - # wait a bit for the container to be ready - container_url = 'http://{}:{}/api'.format(hostname, port) + container_url = 'http://{}:{}/api'.format(app.hostname, app.port) + expected_url = 'http://{}:{}'.format(app.hostname, app.port) + # wait a bit for the container to be ready # give the container a chance to start time.sleep(1) + try: # try a few times to connect success = False for i in range(1, 4): container.reload() assert container.status == 'running' + if expected_url not in container.logs().decode("utf8"): + time.sleep(i * 3) + continue try: info = requests.get(container_url).json() except Exception as e: From 4587702119dcced33d20ac4c8ec8a2c4573345cc Mon Sep 17 00:00:00 2001 From: Gladys Nalvarte Date: Wed, 1 Aug 2018 14:21:15 +0200 Subject: [PATCH 4/4] Include corrections in app and test_connect_url files --- repo2docker/app.py | 4 ++-- tests/test_connect_url.py | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/repo2docker/app.py b/repo2docker/app.py index 1e0c7853..19228cc0 100644 --- a/repo2docker/app.py +++ b/repo2docker/app.py @@ -203,7 +203,7 @@ class Repo2Docker(Application): Raises: ArgumentTypeError: if image_name contains characters that do not meet the logic that container names must start - with an alphanumeric character and can then + with an alphanumeric character and can then use _ . or - in addition to alphanumeric. [a-zA-Z0-9][a-zA-Z0-9_.-]+ """ @@ -515,7 +515,7 @@ class Repo2Docker(Application): port = str(self._get_free_port()) self.port = port # To use the option --NotebookApp.custom_display_url - # make sure the base-notebook image is updated: + # make sure the base-notebook image is updated: # docker pull jupyter/base-notebook run_cmd = [ 'jupyter', 'notebook', diff --git a/tests/test_connect_url.py b/tests/test_connect_url.py index 14ddb8c6..5c5e1acf 100644 --- a/tests/test_connect_url.py +++ b/tests/test_connect_url.py @@ -1,12 +1,8 @@ """ Test if the explict hostname is supplied correctly to the container """ -import os -import sys -import pytest import requests import time -import urllib.parse from repo2docker.app import Repo2Docker def test_connect_url(tmpdir):