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

fix(cli): output proper session link and only check registry if logged in #3660

Merged
merged 4 commits into from
Jan 4, 2024
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
41 changes: 35 additions & 6 deletions renku/core/session/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import webbrowser
from datetime import datetime
from pathlib import Path
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Tuple, Union, cast
from typing import TYPE_CHECKING, Any, Dict, Iterator, List, Optional, Tuple, Union, cast
from uuid import uuid4

import docker
Expand All @@ -29,8 +29,11 @@
from renku.core import errors
from renku.core.config import get_value
from renku.core.constant import ProviderPriority
from renku.core.login import read_renku_token
from renku.core.plugin import hookimpl
from renku.core.session.utils import get_renku_url
from renku.core.util import communication
from renku.core.util.jwt import is_token_expired
from renku.domain_model.project_context import project_context
from renku.domain_model.session import ISessionProvider, Session, SessionStopStatus

Expand Down Expand Up @@ -67,11 +70,14 @@ def docker_client(self) -> docker.client.DockerClient:
return self._docker_client

@staticmethod
def _get_jupyter_urls(ports: Dict[str, Any], auth_token: str, jupyter_port: int = 8888) -> Iterable[str]:
def _get_jupyter_urls(ports: Dict[str, Any], auth_token: str, jupyter_port: int = 8888) -> Iterator[str]:
port_key = f"{jupyter_port}/tcp"
if port_key not in ports:
return list()
return map(lambda x: f"http://{x['HostIp']}:{x['HostPort']}/?token={auth_token}", ports[port_key])
return list() # type: ignore
default_url = get_value("interactive", "default_url")
if not default_url:
default_url = "/lab"
return map(lambda x: f"http://{x['HostIp']}:{x['HostPort']}{default_url}?token={auth_token}", ports[port_key])

def _get_docker_containers(self, project_name: str) -> List[docker.models.containers.Container]:
return self.docker_client().containers.list(filters={"label": f"renku_project={project_name}"})
Expand All @@ -92,9 +98,22 @@ def build_image(self, image_descriptor: Path, image_name: str, config: Optional[
def find_image(self, image_name: str, config: Optional[Dict[str, Any]]) -> bool:
"""Find the given container image."""
with communication.busy(msg=f"Checking for image {image_name}"):
renku_url = get_renku_url()

# only search remote image if a user is logged in
find_remote = True
if renku_url is None:
find_remote = False
else:
token = read_renku_token(endpoint=renku_url)
if not token or is_token_expired(token):
find_remote = False

try:
self.docker_client().images.get(image_name)
except docker.errors.ImageNotFound:
if not find_remote:
return False
try:
self.docker_client().images.get_registry_data(image_name)
except docker.errors.APIError:
Expand Down Expand Up @@ -454,13 +473,23 @@ def session_open(self, project_name: str, session_name: Optional[str], **kwargs)
def session_url(self, session_name: Optional[str]) -> Optional[str]:
"""Get the URL of the interactive session."""
sessions = self.docker_client().containers.list()
default_url = get_value("interactive", "default_url")
if not default_url:
default_url = "/lab"

for c in sessions:
if (
c.short_id == session_name or (not session_name and len(sessions) == 1)
) and f"{DockerSessionProvider.JUPYTER_PORT}/tcp" in c.ports:
host = c.ports[f"{DockerSessionProvider.JUPYTER_PORT}/tcp"][0]
return f'http://{host["HostIp"]}:{host["HostPort"]}/?token={c.labels["jupyter_token"]}'
url = next(
DockerSessionProvider._get_jupyter_urls(
c.ports, c.labels["jupyter_token"], DockerSessionProvider.JUPYTER_PORT
),
None,
)
if not url:
continue
return url
return None

def force_build_image(self, force_build: bool = False, **kwargs) -> bool:
Expand Down
6 changes: 6 additions & 0 deletions renku/core/session/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import urllib
from typing import Optional

from renku.core.login import read_renku_token
from renku.core.util.git import get_remote
from renku.core.util.jwt import is_token_expired
from renku.core.util.urls import parse_authentication_endpoint
from renku.domain_model.project_context import project_context

Expand Down Expand Up @@ -54,4 +56,8 @@ def get_image_repository_host() -> Optional[str]:
renku_url = get_renku_url()
if not renku_url:
return None
token = read_renku_token(endpoint=renku_url)
if not token or is_token_expired(token):
# only guess host if user is logged in
return None
return "registry." + urllib.parse.urlparse(renku_url).netloc