Skip to content

Commit

Permalink
start of work to add private remotes
Browse files Browse the repository at this point in the history
Signed-off-by: vsoch <[email protected]>
  • Loading branch information
vsoch committed Aug 31, 2022
1 parent ec85590 commit c035442
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and **Merged pull requests**. Critical items to know are:
The versions coincide with releases on pip. Only major versions will be released as tags on Github.

## [0.0.x](https://github.com/singularityhub/singularity-hpc/tree/main) (0.0.x)
- Support for remotes that do not expose library.json (0.0.12)
- Update add to return container yaml (0.1.11)
- Fixing bug with writing package file in update (0.1.1)
- Add support for remote registry and sync commands --all (0.1.0)
Expand Down
3 changes: 2 additions & 1 deletion shpc/client/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
__copyright__ = "Copyright 2021-2022, Vanessa Sochat"
__license__ = "MPL 2.0"

import os

import shpc.logger as logger
import shpc.utils
import os


def sync_registry(args, parser, extra, subparser):
Expand Down
16 changes: 4 additions & 12 deletions shpc/main/modules/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import shpc.main.modules.template as templatectl
import shpc.main.modules.versions as versionfile
import shpc.main.modules.views as views
import shpc.main.registry as registry
import shpc.main.registry
import shpc.utils as utils
from shpc.logger import logger
from shpc.main.client import Client as BaseClient
Expand Down Expand Up @@ -198,7 +198,7 @@ def add(self, image, module_name=None, **kwargs):

# Load config (but don't validate yet!)
config = container.ContainerConfig(
registry.FilesystemResult(module_name, template), validate=False
shpc.main.registry.FilesystemResult(module_name, template), validate=False
)
return self.container.add(
module_name, image, config, container_yaml=dest, **kwargs
Expand Down Expand Up @@ -236,16 +236,8 @@ def docgen(self, module_name, registry=None, out=None, branch="main"):
template = self.template.load("docs.md")
registry = registry or defaults.github_url
github_url = "%s/blob/%s/%s/container.yaml" % (registry, branch, module_name)
registry_bare = registry.split(".com")[-1]
raw = (
"https://gitlab.com/%s/-/raw/%s/%s/container.yaml"
if "gitlab" in registry
else "https://raw.githubusercontent.com/%s/%s/%s/container.yaml"
)
raw_github_url = raw % (
registry_bare,
branch,
module_name,
raw_github_url = shpc.main.registry.get_module_config_url(
registry, module_name, branch
)

# Currently one doc is rendered for all containers
Expand Down
2 changes: 1 addition & 1 deletion shpc/main/registry/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from shpc.main.settings import SettingsBase

from .filesystem import Filesystem, FilesystemResult
from .remote import GitHub, GitLab
from .remote import GitHub, GitLab, get_module_config_url


def update_container_module(module, from_path, existing_path):
Expand Down
50 changes: 44 additions & 6 deletions shpc/main/registry/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

import os
import re
import shutil
import subprocess as sp
import sys

import requests

Expand All @@ -16,6 +16,23 @@
from .provider import Provider, Result


def get_module_config_url(registry, module_name, branch="main"):
"""
Get the raw address of the config (container.yaml)
"""
registry_bare = registry.split(".com")[-1]
raw = (
"https://gitlab.com/%s/-/raw/%s/%s/container.yaml"
if "gitlab" in registry
else "https://raw.githubusercontent.com/%s/%s/%s/container.yaml"
)
return raw % (
registry_bare,
branch,
module_name,
)


class RemoteResult(Result):
"""
A remote result provides courtesy functions for interacting with
Expand Down Expand Up @@ -117,6 +134,9 @@ def exists(self, name):
"""
Determine if a module exists in the registry.
"""
name = name.split(":")[0]
if self._cache and name in self._cache:
return True
dirname = self.source
if self.subdir:
dirname = os.path.join(dirname, self.subdir)
Expand Down Expand Up @@ -158,7 +178,8 @@ def find(self, name):
"""
Find a particular entry in a registry
"""
self._update_cache()
if not self._cache:
self._update_cache()
if name in self._cache:
return RemoteResult(name, self._cache[name])

Expand All @@ -172,12 +193,29 @@ def _update_cache(self, force=False):
# Check for exposed library API on GitHub or GitLab pages
response = requests.get(self.web_url)
if response.status_code != 200:
sys.exit(
"Remote %s is not deploying a Registry API (%s). Open a GitHub issue to ask for help."
% (self.source, self.web_url)
)
return self._update_clone_cache()
self._cache = response.json()

def _update_clone_cache(self):
"""
Given a remote that does not expose a library.json, handle via clone.
"""
logger.warning(
"Remote %s is not deploying a Registry API, falling back to clone."
% self.source
)
tmpdir = self.clone()
for dirname, module in self.iter_modules():
# Minimum amount of metadata to function here
config_url = get_module_config_url(self.source, module)
self._cache[module] = {
"config": shpc.utils.read_yaml(
os.path.join(dirname, module, "container.yaml")
),
"config_url": config_url,
}
shutil.rmtree(tmpdir)

def iter_registry(self, filter_string=None):
"""
Yield metadata about containers in a remote registry.
Expand Down
29 changes: 29 additions & 0 deletions shpc/tests/test_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ def test_sync_from_file(tmp_path):
[
"https://github.com/singularityhub/shpc-registry",
"https://gitlab.com/singularityhub/shpc-registry",
# This registry does not expose a web UI
"https://github.com/researchapps/shpc-test-registry",
],
)
def test_remote_upgrade(tmp_path, remote):
Expand Down Expand Up @@ -133,3 +135,30 @@ def test_remote_upgrade(tmp_path, remote):

client.registry.sync(sync_registry=remote)
assert list(client.registry.iter_modules())


@pytest.mark.parametrize(
"remote",
[
"https://github.com/singularityhub/shpc-registry",
"https://gitlab.com/singularityhub/shpc-registry",
# This registry does not expose a web UI
"https://github.com/researchapps/shpc-test-registry",
],
)
def test_registry_interaction(tmp_path, remote):
"""
Test interactions with registries of different types
"""
client = init_client(str(tmp_path), "lmod", "singularity")
reg = client.registry.get_registry(remote)

assert not reg.is_filesystem_registry

# This will hit the underlying logic to list/show
mods = list(reg.iter_registry())
assert mods

# Should use the cache
assert reg.exists("vanessa/salad")
assert reg.find("vanessa/salad") is not None
2 changes: 1 addition & 1 deletion shpc/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
__copyright__ = "Copyright 2021-2022, Vanessa Sochat"
__license__ = "MPL 2.0"

__version__ = "0.1.11"
__version__ = "0.1.12"
AUTHOR = "Vanessa Sochat"
EMAIL = "[email protected]"
NAME = "singularity-hpc"
Expand Down

0 comments on commit c035442

Please sign in to comment.