2018-10-30 20:08:47 -07:00
|
|
|
"""
|
2018-10-31 11:21:09 -07:00
|
|
|
Test running bootstrap script in different circumstances
|
2018-10-30 20:08:47 -07:00
|
|
|
"""
|
2020-08-18 23:56:37 +03:00
|
|
|
import concurrent.futures
|
2020-08-21 18:03:57 +03:00
|
|
|
import os
|
2018-10-30 20:08:47 -07:00
|
|
|
import subprocess
|
2023-05-16 21:07:20 +02:00
|
|
|
import sys
|
2020-08-18 23:56:37 +03:00
|
|
|
import time
|
2018-10-30 20:08:47 -07:00
|
|
|
|
2023-03-21 10:15:22 +01:00
|
|
|
BASE_IMAGE = os.getenv("BASE_IMAGE", "ubuntu:20.04")
|
|
|
|
|
|
2020-08-21 18:03:57 +03:00
|
|
|
|
|
|
|
|
def install_pkgs(container_name, show_progress_page):
|
2018-10-30 20:08:47 -07:00
|
|
|
# Install python3 inside the ubuntu container
|
|
|
|
|
# There is no trusted Ubuntu+Python3 container we can use
|
2020-08-21 18:03:57 +03:00
|
|
|
pkgs = ["python3"]
|
|
|
|
|
if show_progress_page:
|
2020-08-24 13:01:54 +03:00
|
|
|
pkgs += ["systemd", "git", "curl"]
|
2023-03-21 10:15:22 +01:00
|
|
|
# Create the sudoers dir, so that the installer successfully gets to the
|
2020-08-21 18:03:57 +03:00
|
|
|
# point of starting jupyterhub and stopping the progress page server.
|
|
|
|
|
subprocess.check_output(
|
|
|
|
|
["docker", "exec", container_name, "mkdir", "-p", "etc/sudoers.d"]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
subprocess.check_output(["docker", "exec", container_name, "apt-get", "update"])
|
|
|
|
|
subprocess.check_output(
|
|
|
|
|
["docker", "exec", container_name, "apt-get", "install", "--yes"] + pkgs
|
2020-08-18 23:56:37 +03:00
|
|
|
)
|
2020-08-21 18:03:57 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_bootstrap_script_location(container_name, show_progress_page):
|
|
|
|
|
# Copy only the bootstrap script to container when progress page not enabled, to be faster
|
|
|
|
|
source_path = "bootstrap/"
|
|
|
|
|
bootstrap_script = "/srv/src/bootstrap.py"
|
|
|
|
|
if show_progress_page:
|
|
|
|
|
source_path = os.path.abspath(
|
|
|
|
|
os.path.join(os.path.dirname(__file__), os.pardir)
|
|
|
|
|
)
|
|
|
|
|
bootstrap_script = "/srv/src/bootstrap/bootstrap.py"
|
|
|
|
|
|
|
|
|
|
subprocess.check_call(["docker", "cp", source_path, f"{container_name}:/srv/src"])
|
|
|
|
|
return bootstrap_script
|
|
|
|
|
|
2021-11-01 09:42:45 +01:00
|
|
|
|
2021-10-17 20:23:31 +02:00
|
|
|
# FIXME: Refactor this function to easier to understand using the following
|
|
|
|
|
# parameters
|
|
|
|
|
#
|
|
|
|
|
# - param: container_apt_packages
|
|
|
|
|
# - param: bootstrap_tljh_source
|
|
|
|
|
# - local: copies local tljh repo to container and configures bootstrap to
|
|
|
|
|
# install tljh from copied repo
|
|
|
|
|
# - github: configures bootstrap to install tljh from the official github repo
|
|
|
|
|
# - <pip spec>: configures bootstrap to install tljh from any given remote location
|
|
|
|
|
# - param: bootstrap_flags
|
2021-10-20 11:21:34 +02:00
|
|
|
#
|
|
|
|
|
# FIXME: Consider stripping logic in this file to only testing if the bootstrap
|
|
|
|
|
# script successfully detects the too old Ubuntu version and the lack of
|
|
|
|
|
# systemd. The remaining test named test_progress_page could rely on
|
|
|
|
|
# running against the systemd container that cab be built by
|
|
|
|
|
# integration-test.py.
|
|
|
|
|
#
|
2021-11-01 09:42:45 +01:00
|
|
|
def run_bootstrap_after_preparing_container(
|
|
|
|
|
container_name, image, show_progress_page=False
|
|
|
|
|
):
|
2021-10-17 20:23:31 +02:00
|
|
|
"""
|
|
|
|
|
1. Stops old container
|
|
|
|
|
2. Starts --detached container
|
|
|
|
|
3. Installs apt packages in container
|
|
|
|
|
4. Two situations
|
|
|
|
|
|
|
|
|
|
A) limited test (--show-progress-page=false)
|
|
|
|
|
- Copies ./bootstrap/ folder content to container /srv/src
|
|
|
|
|
- Runs copied bootstrap/bootstrap.py without flags
|
|
|
|
|
|
|
|
|
|
B) full test (--show-progress-page=true)
|
|
|
|
|
- Copies ./ folder content to the container /srv/src
|
|
|
|
|
- Runs copied bootstrap/bootstrap.py with environment variables
|
|
|
|
|
- TLJH_BOOTSTRAP_DEV=yes
|
|
|
|
|
This makes --editable be used when installing the tljh package
|
|
|
|
|
- TLJH_BOOTSTRAP_PIP_SPEC=/srv/src
|
|
|
|
|
This makes us install tljh from the given location instead of from
|
|
|
|
|
github.com/jupyterhub/the-littlest-jupyterhub
|
|
|
|
|
"""
|
2020-08-21 18:03:57 +03:00
|
|
|
# stop container if it is already running
|
|
|
|
|
subprocess.run(["docker", "rm", "-f", container_name])
|
|
|
|
|
|
2020-08-24 13:01:54 +03:00
|
|
|
# Start a detached container
|
|
|
|
|
subprocess.check_call(
|
|
|
|
|
[
|
|
|
|
|
"docker",
|
|
|
|
|
"run",
|
2021-10-19 15:18:02 +02:00
|
|
|
"--env=DEBIAN_FRONTEND=noninteractive",
|
2020-08-24 13:01:54 +03:00
|
|
|
"--detach",
|
2021-10-17 20:23:31 +02:00
|
|
|
f"--name={container_name}",
|
2020-08-24 13:01:54 +03:00
|
|
|
image,
|
|
|
|
|
"/bin/bash",
|
|
|
|
|
"-c",
|
|
|
|
|
"sleep 1000s",
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
|
2020-08-21 18:03:57 +03:00
|
|
|
install_pkgs(container_name, show_progress_page)
|
|
|
|
|
|
|
|
|
|
bootstrap_script = get_bootstrap_script_location(container_name, show_progress_page)
|
|
|
|
|
|
2022-11-27 19:03:48 +00:00
|
|
|
exec_flags = [
|
|
|
|
|
"-i",
|
|
|
|
|
container_name,
|
|
|
|
|
"python3",
|
|
|
|
|
bootstrap_script,
|
|
|
|
|
"--version",
|
|
|
|
|
"main",
|
|
|
|
|
]
|
2020-08-21 18:03:57 +03:00
|
|
|
if show_progress_page:
|
|
|
|
|
exec_flags = (
|
2020-08-22 15:57:40 +03:00
|
|
|
["-e", "TLJH_BOOTSTRAP_DEV=yes", "-e", "TLJH_BOOTSTRAP_PIP_SPEC=/srv/src"]
|
2020-08-21 18:03:57 +03:00
|
|
|
+ exec_flags
|
|
|
|
|
+ ["--show-progress-page"]
|
|
|
|
|
)
|
2018-10-30 20:08:47 -07:00
|
|
|
|
2019-05-19 23:00:43 -07:00
|
|
|
# Run bootstrap script, return the output
|
2020-08-21 18:03:57 +03:00
|
|
|
return subprocess.run(
|
|
|
|
|
["docker", "exec"] + exec_flags,
|
|
|
|
|
check=False,
|
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
|
encoding="utf-8",
|
|
|
|
|
)
|
|
|
|
|
|
2019-05-19 23:00:43 -07:00
|
|
|
|
|
|
|
|
def test_ubuntu_too_old():
|
|
|
|
|
"""
|
|
|
|
|
Error with a useful message when running in older Ubuntu
|
|
|
|
|
"""
|
2023-03-21 10:15:22 +01:00
|
|
|
output = run_bootstrap_after_preparing_container("old-distro-test", "ubuntu:18.04")
|
|
|
|
|
assert output.stdout == "The Littlest JupyterHub requires Ubuntu 20.04 or higher\n"
|
2019-05-19 23:00:43 -07:00
|
|
|
assert output.returncode == 1
|
|
|
|
|
|
|
|
|
|
|
2019-05-20 09:52:50 -07:00
|
|
|
def test_inside_no_systemd_docker():
|
2021-10-20 11:20:19 +02:00
|
|
|
output = run_bootstrap_after_preparing_container(
|
|
|
|
|
"plain-docker-test",
|
2023-03-21 10:15:22 +01:00
|
|
|
BASE_IMAGE,
|
2021-10-20 11:20:19 +02:00
|
|
|
)
|
2021-10-17 19:43:13 +02:00
|
|
|
assert "Systemd is required to run TLJH" in output.stdout
|
2019-05-19 23:00:43 -07:00
|
|
|
assert output.returncode == 1
|
2020-08-18 23:56:37 +03:00
|
|
|
|
|
|
|
|
|
2020-08-19 02:33:17 +03:00
|
|
|
def verify_progress_page(expected_status_code, timeout):
|
2020-08-18 23:56:37 +03:00
|
|
|
progress_page_status = False
|
2020-08-19 02:33:17 +03:00
|
|
|
start = time.time()
|
|
|
|
|
while not progress_page_status and (time.time() - start < timeout):
|
2020-08-18 23:56:37 +03:00
|
|
|
try:
|
2020-08-24 13:01:54 +03:00
|
|
|
resp = subprocess.check_output(
|
|
|
|
|
[
|
|
|
|
|
"docker",
|
|
|
|
|
"exec",
|
|
|
|
|
"progress-page",
|
|
|
|
|
"curl",
|
|
|
|
|
"-i",
|
|
|
|
|
"http://localhost/index.html",
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
if b"HTTP/1.0 200 OK" in resp:
|
2020-08-18 23:56:37 +03:00
|
|
|
progress_page_status = True
|
2020-08-21 18:03:57 +03:00
|
|
|
break
|
2023-05-16 21:07:20 +02:00
|
|
|
else:
|
|
|
|
|
print(
|
|
|
|
|
f"Unexpected progress page response: {resp[:100]}", file=sys.stderr
|
|
|
|
|
)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"Error getting progress page: {e}", file=sys.stderr)
|
|
|
|
|
time.sleep(1)
|
2020-08-21 18:03:57 +03:00
|
|
|
continue
|
2020-08-18 23:56:37 +03:00
|
|
|
|
|
|
|
|
return progress_page_status
|
|
|
|
|
|
2020-08-21 18:03:57 +03:00
|
|
|
|
2020-08-18 23:56:37 +03:00
|
|
|
def test_progress_page():
|
|
|
|
|
with concurrent.futures.ThreadPoolExecutor() as executor:
|
2020-08-21 18:03:57 +03:00
|
|
|
installer = executor.submit(
|
2021-10-20 11:20:19 +02:00
|
|
|
run_bootstrap_after_preparing_container,
|
|
|
|
|
"progress-page",
|
2023-03-21 10:15:22 +01:00
|
|
|
BASE_IMAGE,
|
2021-11-01 09:42:45 +01:00
|
|
|
True,
|
2020-08-21 18:03:57 +03:00
|
|
|
)
|
2020-08-18 23:56:37 +03:00
|
|
|
|
|
|
|
|
# Check if progress page started
|
2023-05-16 21:10:44 +02:00
|
|
|
started = verify_progress_page(expected_status_code=200, timeout=180)
|
2020-08-18 23:56:37 +03:00
|
|
|
assert started
|
|
|
|
|
|
2020-08-21 18:03:57 +03:00
|
|
|
# This will fail start tljh but should successfully get to the point
|
|
|
|
|
# Where it stops the progress page server.
|
|
|
|
|
output = installer.result()
|
2020-08-19 02:33:17 +03:00
|
|
|
|
|
|
|
|
# Check if progress page stopped
|
2020-08-21 18:03:57 +03:00
|
|
|
assert "Progress page server stopped successfully." in output.stdout
|