Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

start of work to add private remotes #585

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this check here as well ? _update_cache already checks this:

def _update_cache(self, force=False):
"""
Update local cache from a registry.
"""
if self._cache and not force:
return

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes absolutely! I responded in your PR - I really like your idea of making the protocol more general (perhaps a regular expression with a named group to match at the start, and then saving to the remote for later use) if you are up for that! We'd want to make sure that change still works with your ssh registry.

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 = "vsoch@users.noreply.github.com"
NAME = "singularity-hpc"
Expand Down