Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ on:

jobs:
docker:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ on:

jobs:
build-n-publish:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
Expand Down Expand Up @@ -62,7 +62,7 @@ jobs:
password: ${{ secrets.PYPI_PASSWORD }}

publish-docker:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
env:
DEFAULT_REGISTRY: quay.io
IMAGE_NAME: jupyterhub/repo2docker
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ubuntu_version: ["22.04"]
ubuntu_version: ["24.04"]
python_version: ["3.10"]
repo_type:
- base
Expand Down
2 changes: 0 additions & 2 deletions repo2docker/contentproviders/rdm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,9 @@ async def _fetch_binder(
for binder_output_dir in binder_output_dirs:
provisioner.save_provision_script(
os.path.join(binder_output_dir, "provision.sh"),
project.id,
)
provisioner.save_prepare_mnt_script(
os.path.join(binder_output_dir, "prepare_mnt.sh"),
project.id,
)

async def _fetch_all(
Expand Down
22 changes: 15 additions & 7 deletions repo2docker/contentproviders/rdm/provisioner.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,19 @@ async def add_link_mapping(self, path_mapping: PathMapping):
source = await self._resolve_source(path_mapping)
self._link_mappings.append((path_mapping, source))

def save_provision_script(self, script_path: str, project_id: str, source_mount_dir='/mnt/rdm/'):
def save_provision_script(self, script_path: str, source_mount_dir='/mnt/rdm/'):
"""Save the provision script to the specified path."""
with open(script_path, "w") as f:
f.write("#!/bin/bash\n")
f.write("set -e\n\n")
f.write("set -xe\n\n")
f.write("PROVISION_LOG=\"/tmp/provision.log\"\n\n")
f.write("# Extract project_id from BINDER_REPO_URL\n")
f.write("_path=\"${BINDER_REPO_URL#*://}\"\n")
f.write("_path=\"${_path#*/}\"\n")
f.write("PROJECT_ID=\"${_path%%/*}\"\n\n")
f.write("# Ensure /mnt/rdm exists or create symlink to project-specific directory\n")
f.write("if [ ! -e /mnt/rdm ]; then\n")
f.write(f" PROJECT_DIR=/mnt/rdms/{shlex.quote(project_id)}\n")
f.write(" PROJECT_DIR=/mnt/rdms/$PROJECT_ID\n")
f.write(" for i in 1 2 4; do\n")
f.write(" if [ -d \"$PROJECT_DIR\" ]; then\n")
f.write(" ln -s \"$PROJECT_DIR\" /mnt/rdm 2>> \"$PROVISION_LOG\" || echo \"[provision] Warning: Failed to create symlink /mnt/rdm\" >&2\n")
Expand Down Expand Up @@ -128,15 +132,19 @@ def save_provision_script(self, script_path: str, project_id: str, source_mount_
f.write(" exec \"$@\"\n")
f.write("fi\n")

def save_prepare_mnt_script(self, script_path: str, project_id: str):
def save_prepare_mnt_script(self, script_path: str):
"""Save the prepare_mnt script to the specified path."""
with open(script_path, "w") as f:
f.write("#!/bin/bash\n")
f.write("set -e\n\n")
f.write("set -xe\n\n")
f.write("# Extract project_id from BINDER_REPO_URL\n")
f.write("_path=\"${BINDER_REPO_URL#*://}\"\n")
f.write("_path=\"${_path#*/}\"\n")
f.write("PROJECT_ID=\"${_path%%/*}\"\n\n")
f.write("# Ensure /mnt/rdm exists or create symlink to project-specific directory\n")
f.write("if [ ! -e /mnt/rdm ]; then\n")
f.write(f" PROJECT_DIR=/mnt/rdms/{shlex.quote(project_id)}\n")
f.write(f" ln -s \"$PROJECT_DIR\" /mnt/rdm\n")
f.write(" PROJECT_DIR=/mnt/rdms/$PROJECT_ID\n")
f.write(" ln -s \"$PROJECT_DIR\" /mnt/rdm\n")
f.write("fi\n")

async def _resolve_source(self, path_mapping: PathMapping):
Expand Down
28 changes: 20 additions & 8 deletions tests/unit/contentproviders/test_rdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,10 +470,13 @@ async def mock_resolve_source(self, path_mapping):

# Verify script content
assert "#!/bin/bash" in script_content
assert "set -e" in script_content
assert "set -xe" in script_content
# Verify project_id extraction from BINDER_REPO_URL
assert '_path="${BINDER_REPO_URL#*://}"' in script_content
assert 'PROJECT_ID="${_path%%/*}"' in script_content
# Verify /mnt/rdm symlink creation with retry logic for project-specific directory
assert "if [ ! -e /mnt/rdm ]; then" in script_content
assert "PROJECT_DIR=/mnt/rdms/x1234" in script_content
assert "PROJECT_DIR=/mnt/rdms/$PROJECT_ID" in script_content
assert "for i in 1 2 4; do" in script_content
assert 'ln -s "$PROJECT_DIR" /mnt/rdm' in script_content
assert "Waiting for $PROJECT_DIR to be available" in script_content
Expand All @@ -494,9 +497,12 @@ async def mock_resolve_source(self, path_mapping):

# Verify prepare_mnt.sh content
assert "#!/bin/bash" in prepare_mnt_content
assert "set -e" in prepare_mnt_content
assert "set -xe" in prepare_mnt_content
# Verify project_id extraction from BINDER_REPO_URL
assert '_path="${BINDER_REPO_URL#*://}"' in prepare_mnt_content
assert 'PROJECT_ID="${_path%%/*}"' in prepare_mnt_content
assert "if [ ! -e /mnt/rdm ]; then" in prepare_mnt_content
assert "PROJECT_DIR=/mnt/rdms/x1234" in prepare_mnt_content
assert "PROJECT_DIR=/mnt/rdms/$PROJECT_ID" in prepare_mnt_content
assert 'ln -s "$PROJECT_DIR" /mnt/rdm' in prepare_mnt_content


Expand Down Expand Up @@ -556,9 +562,12 @@ async def mock_resolve_source(self, path_mapping):

# Verify default mapping is added (copy entire storage to current directory)
assert "#!/bin/bash" in script_content
assert "set -e" in script_content
assert "set -xe" in script_content
# Verify project_id extraction from BINDER_REPO_URL
assert '_path="${BINDER_REPO_URL#*://}"' in script_content
assert 'PROJECT_ID="${_path%%/*}"' in script_content
# Verify /mnt/rdm symlink creation with retry logic
assert "PROJECT_DIR=/mnt/rdms/x1234" in script_content
assert "PROJECT_DIR=/mnt/rdms/$PROJECT_ID" in script_content
assert 'ln -s "$PROJECT_DIR" /mnt/rdm' in script_content
assert "cp -fr /mnt/rdm/osfstorage/* ." in script_content
# Should not have any user-defined link commands in the background block
Expand Down Expand Up @@ -627,9 +636,12 @@ async def mock_resolve_source(self, path_mapping):

# Verify script structure without user-defined copy or link commands
assert "#!/bin/bash" in script_content
assert "set -e" in script_content
assert "set -xe" in script_content
# Verify project_id extraction from BINDER_REPO_URL
assert '_path="${BINDER_REPO_URL#*://}"' in script_content
assert 'PROJECT_ID="${_path%%/*}"' in script_content
# Verify /mnt/rdm symlink creation with retry logic
assert "PROJECT_DIR=/mnt/rdms/x1234" in script_content
assert "PROJECT_DIR=/mnt/rdms/$PROJECT_ID" in script_content
assert 'ln -s "$PROJECT_DIR" /mnt/rdm' in script_content
# Should not have any copy commands
assert "cp -fr" not in script_content
Expand Down