def hint_configure(container, cfg): print("[hint] Configuring hint") docker_util.exec_safely(container, ["mkdir", "-p", "/etc/hint/token_key"]) config = { "application_url": cfg.proxy_url, # drop (start) "email_server": "smtp.cc.ic.ac.uk", "email_port": 587, "email_username": "******", "email_sender": "*****@*****.**", # drop (end) "email_mode": cfg.hint_email_mode, "email_password": cfg.hint_email_password, "upload_dir": "/uploads", "hintr_url": "http://hintr:8888", "db_url": "jdbc:postgresql://db/hint", "db_password": "******", "issue_report_url": cfg.hint_issue_report_url } if cfg.hint_adr_url is not None: config["adr_url"] = cfg.hint_adr_url config_str = "".join("{}={}\n".format(k, v) for k, v in config.items()) docker_util.string_into_container(config_str, container, "/etc/hint/config.properties") print("[hint] Waiting for hint to become responsive") wait(lambda: requests.get("http://localhost:8080").status_code == 200, "Hint did not become responsive in time")
def db_configure(container, cfg): print("[db] Waiting for db to come up") docker_util.exec_safely(container, ["wait-for-db"]) print("[db] Migrating the database") migrate = constellation.ImageReference("mrcide", "hint-db-migrate", cfg.db_tag) args = ["-url=jdbc:postgresql://{}/hint".format(container.name)] container.client.containers.run(str(migrate), args, network=cfg.network, auto_remove=True, detach=False)
def proxy_configure(container, cfg): print("[proxy] Configuring proxy") if cfg.proxy_ssl_certificate and cfg.proxy_ssl_key: print("Copying ssl certificate and key into proxy") docker_util.string_into_container(cfg.proxy_ssl_certificate, container, "/run/proxy/certificate.pem") docker_util.string_into_container(cfg.proxy_ssl_key, container, "/run/proxy/key.pem") else: print("Generating self-signed certificates for proxy") args = [ "self-signed-certificate", "/run/proxy", "GB", "London", "IC", "reside", cfg.proxy_host ] docker_util.exec_safely(container, args)
def test_configure_proxy(): cfg = hint_deploy.HintConfig("config", "staging") cl = docker.client.from_env() args = ["localhost:80", "localhost", "80", "443"] container = cl.containers.run("reside/proxy-nginx:master", args, detach=True, auto_remove=False) args = [ "self-signed-certificate", "/tmp", "GB", "London", "IC", "reside", cfg.proxy_host ] docker_util.exec_safely(container, args) cert = docker_util.string_from_container(container, "/tmp/certificate.pem") key = docker_util.string_from_container(container, "/tmp/key.pem") cfg.proxy_ssl_certificate = cert cfg.proxy_ssl_key = key hint_deploy.proxy_configure(container, cfg) assert docker_util.string_from_container( container, "/run/proxy/certificate.pem") == cert assert docker_util.string_from_container(container, "/run/proxy/key.pem") == key container.kill()
def redis_configure(container, cfg): print("[redis] Waiting for redis to come up") docker_util.file_into_container("scripts/wait_for_redis", container, ".", "wait_for_redis") docker_util.exec_safely(container, ["bash", "/wait_for_redis"])
def test_start_hint(): cfg = hint_deploy.HintConfig("config") obj = hint_deploy.hint_constellation(cfg) obj.status() obj.start() res = requests.get("http://localhost:8080") assert res.status_code == 200 assert "Naomi" in res.content.decode("UTF-8") res = requests.get("http://localhost:8888") assert res.status_code == 200 assert docker_util.network_exists("hint_nw") assert docker_util.volume_exists("hint_db_data") assert docker_util.volume_exists("hint_uploads") assert docker_util.volume_exists("hint_results") assert docker_util.volume_exists("hint_prerun") assert docker_util.container_exists("hint_db") assert docker_util.container_exists("hint_redis") assert docker_util.container_exists("hint_hintr") assert docker_util.container_exists("hint_hint") assert len(docker_util.containers_matching("hint_worker_", False)) == 2 assert len(docker_util.containers_matching("hint_calibrate_worker_", False)) == 1 # Some basic user management user = "******" f = io.StringIO() with redirect_stdout(f): hint_deploy.hint_user(cfg, "add-user", user, True, "password") p = f.getvalue() assert "Adding user {}".format(user) in p assert p.strip().split("\n")[-1] == "OK" f = io.StringIO() with redirect_stdout(f): hint_deploy.hint_user(cfg, "user-exists", user, False) assert f.getvalue() == "Checking if user exists: {}\ntrue\n".format(user) f = io.StringIO() with redirect_stdout(f): hint_deploy.hint_user(cfg, "add-user", user, True, "password") p = f.getvalue() assert "Not adding user {} as they already exist".format(user) in p f = io.StringIO() with redirect_stdout(f): hint_deploy.hint_user(cfg, "remove-user", user, False) assert f.getvalue() == "Removing user {}\nOK\n".format(user) # Confirm we have brought up exactly two workers (none in the # hintr container itself) script = 'message(httr::content(httr::GET(' + \ '"http://localhost:8888/hintr/worker/status"),' + \ '"text", encoding="UTF-8"))' args = ["Rscript", "-e", script] hintr = obj.containers.get("hintr", obj.prefix) result = docker_util.exec_safely(hintr, args).output logs = result.decode("UTF-8") data = json.loads(logs)["data"] assert len(data.keys()) == 3 obj.destroy() assert not docker_util.network_exists("hint_nw") assert not docker_util.volume_exists("hint_db_data") assert not docker_util.volume_exists("hint_uploads") assert not docker_util.volume_exists("hint_results") assert not docker_util.volume_exists("hint_prerun") assert not docker_util.container_exists("hint_db") assert not docker_util.container_exists("hint_redis") assert not docker_util.container_exists("hint_hintr") assert not docker_util.container_exists("hint_hint") assert len(docker_util.containers_matching("hint_worker_", False)) == 0 assert len(docker_util.containers_matching("hint_calibrate_worker_", False)) == 0
def test_update_hintr_and_all(): hint_cli.main(["start"]) f = io.StringIO() with redirect_stdout(f): hint_cli.main(["upgrade", "hintr"]) p = f.getvalue() assert "Pulling docker image hintr" in p assert "Pulling docker image db-migrate" not in p assert "Stopping previous hintr and workers" in p assert "Starting hintr" in p assert "Starting *service* calibrate_worker" in p assert "Starting *service* worker" in p assert docker_util.network_exists("hint_nw") assert docker_util.volume_exists("hint_db_data") assert docker_util.volume_exists("hint_uploads") assert docker_util.volume_exists("hint_results") assert docker_util.volume_exists("hint_prerun") assert docker_util.container_exists("hint_db") assert docker_util.container_exists("hint_redis") assert docker_util.container_exists("hint_hintr") assert docker_util.container_exists("hint_hint") assert len(docker_util.containers_matching("hint_worker_", False)) == 2 assert len(docker_util.containers_matching("hint_worker_", True)) == 4 assert len(docker_util.containers_matching("hint_calibrate_worker", False)) == 1 assert len(docker_util.containers_matching("hint_calibrate_worker", True)) == 2 # We are going to write some data into redis here and later check # that it survived the upgrade. cfg = hint_deploy.HintConfig("config") obj = hint_deploy.hint_constellation(cfg) args_set = ["redis-cli", "SET", "data_persists", "yes"] redis = obj.containers.get("redis", obj.prefix) docker_util.exec_safely(redis, args_set) f = io.StringIO() with redirect_stdout(f): hint_cli.main(["upgrade", "all"]) p = f.getvalue() assert "Pulling docker image db" in p assert "Pulling docker image db-migrate" in p assert "Stop 'redis'" in p assert "Removing 'redis'" in p assert "Starting redis" in p assert "[redis] Waiting for redis to come up" in p assert docker_util.network_exists("hint_nw") assert docker_util.volume_exists("hint_db_data") assert docker_util.volume_exists("hint_uploads") assert docker_util.volume_exists("hint_results") assert docker_util.volume_exists("hint_prerun") assert docker_util.container_exists("hint_db") assert docker_util.container_exists("hint_redis") assert docker_util.container_exists("hint_hintr") assert docker_util.container_exists("hint_hint") assert len(docker_util.containers_matching("hint_worker_", False)) == 2 assert len(docker_util.containers_matching("hint_calibrate_worker_", False)) == 1 redis = obj.containers.get("redis", obj.prefix) args_get = ["redis-cli", "GET", "data_persists"] result = docker_util.exec_safely(redis, args_get).output.decode("UTF-8") assert "yes" in result obj.destroy()