Skip to content

Commit

Permalink
chore: resolve changes from conflict resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
olevski committed Aug 28, 2024
1 parent e74a04c commit f4455bc
Show file tree
Hide file tree
Showing 26 changed files with 438 additions and 152 deletions.
48 changes: 1 addition & 47 deletions .github/workflows/test_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,53 +63,6 @@ jobs:
${{ steps.docker_image.outputs.image_repository }}:${{ steps.docker_image.outputs.image_tag }}
${{ steps.docker_image.outputs.image_repository }}:${{ env.DEVCONTAINER_IMAGE_TAG_MAIN }}
style-checks:
runs-on: ubuntu-latest
needs:
- build-devcontainer
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Docker image metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DEVCONTAINER_REGISTRY }}/${{ env.DEVCONTAINER_IMAGE_NAME }}
tags: |
type=ref,event=pr,prefix=cache-pr-,priority=600
type=ref,event=branch,prefix=cache-,priority=500
type=ref,event=tag,prefix=cache-,priority=500
flavor: |
latest=false
- name: Extract Docker image name
id: docker_image
env:
IMAGE_TAGS: ${{ steps.meta.outputs.tags }}
run: |
IMAGE=$(echo "$IMAGE_TAGS" | cut -d" " -f1)
IMAGE_REPOSITORY=$(echo "$IMAGE" | cut -d":" -f1)
IMAGE_TAG=$(echo "$IMAGE" | cut -d":" -f2)
echo "image=$IMAGE" >> "$GITHUB_OUTPUT"
echo "image_repository=$IMAGE_REPOSITORY" >> "$GITHUB_OUTPUT"
echo "image_tag=$IMAGE_TAG" >> "$GITHUB_OUTPUT"
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Pre-build devcontainer
uses: devcontainers/ci@v0.3
continue-on-error: true
with:
push: always
skipContainerUserIdUpdate: false
imageName: ${{ steps.docker_image.outputs.image_repository }}
imageTag: ${{ steps.docker_image.outputs.image_tag }}
cacheFrom: |
${{ steps.docker_image.outputs.image_repository }}:${{ steps.docker_image.outputs.image_tag }}
${{ steps.docker_image.outputs.image_repository }}:${{ env.DEVCONTAINER_IMAGE_TAG_MAIN }}
style-checks:
runs-on: ubuntu-latest
needs:
Expand Down Expand Up @@ -142,6 +95,7 @@ jobs:
push: never
skipContainerUserIdUpdate: false
cacheFrom: ${{ needs.build-devcontainer.outputs.image_repository }}:${{ needs.build-devcontainer.outputs.image_tag }}

test-main:
runs-on: ubuntu-latest
needs:
Expand Down
3 changes: 1 addition & 2 deletions components/renku_data_services/crc/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@
from functools import wraps
from typing import Any, Concatenate, Optional, ParamSpec, TypeVar, cast

from sqlalchemy import NullPool, create_engine, delete, select, true
from sqlalchemy import NullPool, create_engine, delete, false, select, true
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Session, selectinload, sessionmaker
from sqlalchemy.sql import Select, and_, not_, or_
from sqlalchemy.sql.expression import false, true

import renku_data_services.base_models as base_models
from renku_data_services import errors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# NOTE: If these are directly imported then you get circular imports.
from renku_data_services.notebooks.api.classes.server import UserServer


async def git_clone_container_v2(server: "UserServer") -> dict[str, Any] | None:
"""Returns the specification for the container that clones the user's repositories for new operator."""
amalthea_session_work_volume: str = "amalthea-volume"
Expand Down Expand Up @@ -104,7 +105,6 @@ async def git_clone_container_v2(server: "UserServer") -> dict[str, Any] | None:
},
)


# Set up git repositories
for idx, repo in enumerate(repositories):
obj_env = f"{prefix}REPOSITORIES_{idx}_"
Expand Down Expand Up @@ -153,6 +153,7 @@ async def git_clone_container_v2(server: "UserServer") -> dict[str, Any] | None:
"env": env,
}


async def git_clone_container(server: "UserServer") -> dict[str, Any] | None:
"""Returns the specification for the container that clones the user's repositories."""
repositories = await server.repositories()
Expand Down Expand Up @@ -241,7 +242,6 @@ async def git_clone_container(server: "UserServer") -> dict[str, Any] | None:
},
)


# Set up git repositories
for idx, repo in enumerate(repositories):
obj_env = f"{prefix}REPOSITORIES_{idx}_"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

from marshmallow import Schema, fields

from renku_data_services.crc.models import ResourceClass
from renku_data_services.notebooks.api.schemas.custom_fields import ByteSizeField, CpuField, GpuField
from renku_data_services.notebooks.config.dynamic import CPUEnforcement
from renku_data_services.notebooks.errors.programming import ProgrammingError
from renku_data_services.crc.models import ResourceClass


@dataclass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from enum import Enum
from typing import Any, Union, cast

from kubernetes.utils.quantity import parse_quantity
from marshmallow import EXCLUDE, Schema, fields, pre_load, validate

from renku_data_services.notebooks.api.classes.server_manifest import UserServerManifest
Expand Down Expand Up @@ -403,9 +402,7 @@ def get_status(server: UserServerManifest, started: datetime) -> dict[str, dict[

hibernation_date_str = annotations.get("renku.io/hibernationDate")

hibernated_seconds_threshold = (
server.manifest.spec.culling.hibernatedSecondsThreshold
)
hibernated_seconds_threshold = server.manifest.spec.culling.hibernatedSecondsThreshold

if hibernation_date_str and hibernated_seconds_threshold > 0 and not is_user_anonymous(server):
hibernation_date = datetime.fromisoformat(hibernation_date_str)
Expand Down
31 changes: 1 addition & 30 deletions components/renku_data_services/notebooks/apispec.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# generated by datamodel-codegen:
# filename: api.spec.yaml
# timestamp: 2024-08-28T09:26:11+00:00
# timestamp: 2024-08-28T11:41:22+00:00

from __future__ import annotations

Expand Down Expand Up @@ -341,35 +341,6 @@ class ServerStatus(BaseAPISpec):
warnings: Optional[List[ServerStatusWarning]] = None


class SessionPostRequest(BaseAPISpec):
project_id: str = Field(
...,
description="ULID identifier",
max_length=26,
min_length=26,
pattern="^[A-Z0-9]{26}$",
)
launcher_id: str = Field(
...,
description="ULID identifier",
max_length=26,
min_length=26,
pattern="^[A-Z0-9]{26}$",
)
storage: int = Field(
1, description="The size of disk storage for the session, in gigabytes"
)
resource_class_id: Optional[int] = None


class SessionStatus(BaseAPISpec):
details: Optional[List[SessionStatusDetail]] = None
message: Optional[str] = None
state: State3
will_hibernate_at: Optional[datetime] = None
will_delete_at: Optional[datetime] = None


class SessionResources(BaseAPISpec):
requests: Optional[SessionResourcesRequests] = None

Expand Down
18 changes: 9 additions & 9 deletions components/renku_data_services/notebooks/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import base64
import json as json_lib
import logging
from math import floor
import os
from dataclasses import dataclass
from datetime import UTC, datetime
from math import floor
from pathlib import Path
from typing import Any
from urllib.parse import urljoin, urlparse
Expand Down Expand Up @@ -784,23 +784,23 @@ async def _handler(
internal_gitlab_user: APIUser,
body: apispec.SessionPostRequest,
) -> JSONResponse:
# gitlab_client = NotebooksGitlabClient(self.nb_config.git.url, internal_gitlab_user.access_token)
launcher = await self.session_repo.get_launcher(user, ULID.from_str(body.launcher_id))
project = await self.project_repo.get_project(user=user, project_id=launcher.project_id)
server_name = renku_2_make_server_name(
safe_username=user.id, project_id=body.project_id, launcher_id=body.launcher_id
safe_username=user.id, project_id=str(launcher.project_id), launcher_id=body.launcher_id
)
existing_session = await self.nb_config.k8s_v2_client.get_server(server_name, user.id)
if existing_session is not None and existing_session.spec is not None:
return json(existing_session.as_apispec().model_dump(exclude_none=True, mode="json"))
gitlab_client = NotebooksGitlabClient(self.nb_config.git.url, internal_gitlab_user.access_token)
project = await self.project_repo.get_project(user=user, project_id=ULID.from_str(body.project_id))
launcher = await self.session_repo.get_launcher(user, ULID.from_str(body.launcher_id))
environment = launcher.environment
image = environment.container_image
default_resource_class = await self.rp_repo.get_default_resource_class()
if default_resource_class.id is None:
raise errors.ProgrammingError(message="The default reosurce class has to have an ID", quiet=True)
resource_class_id = body.resource_class_id or default_resource_class.id
parsed_server_options = await self.nb_config.crc_validator.validate_class_storage(
user, resource_class_id, body.storage
user, resource_class_id, body.disk_storage
)
work_dir = Path("/home/jovyan/work")
user_secrets: K8sUserSecrets | None = None
Expand All @@ -816,7 +816,7 @@ async def _handler(
server = Renku2UserServer(
user=user,
image=image,
project_id=body.project_id,
project_id=str(launcher.project_id),
launcher_id=body.launcher_id,
server_name=server_name,
server_options=parsed_server_options,
Expand Down Expand Up @@ -857,7 +857,7 @@ async def _handler(

parsed_server_url = urlparse(server.server_url)
annotations: dict[str, str] = {
"renku.io/project_id": body.project_id,
"renku.io/project_id": str(launcher.project_id),
"renku.io/launcher_id": body.launcher_id,
"renku.io/resource_class_id": str(body.resource_class_id or default_resource_class.id),
}
Expand All @@ -874,7 +874,7 @@ async def _handler(
port=environment.port,
storage=Storage(
className=self.nb_config.sessions.storage.pvs_storage_class,
size=str(body.storage) + "Gi",
size=str(body.disk_storage) + "G",
mountPath=environment.mount_directory.as_posix(),
),
workingDir=environment.working_directory.as_posix(),
Expand Down
5 changes: 3 additions & 2 deletions components/renku_data_services/notebooks/config/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

latest_version: str = "1.25.3"


def _parse_str_as_bool(val: Union[str, bool]) -> bool:
if isinstance(val, str):
return val.lower() == "true"
Expand Down Expand Up @@ -409,14 +410,14 @@ def from_env(cls) -> Self:
def _for_testing(cls) -> Self:
return cls(
culling=_SessionCullingConfig.from_env(),
git_proxy=_GitProxyConfig(renku_client_secret="not-defined"),
git_proxy=_GitProxyConfig(renku_client_secret="not-defined"), # nosec B106
git_rpc_server=_GitRpcServerConfig.from_env(),
git_clone=_GitCloneConfig.from_env(),
ingress=_SessionIngress(host="localhost"),
ca_certs=_CustomCaCertsConfig.from_env(),
oidc=_SessionOidcConfig(
client_id="not-defined",
client_secret="not-defined",
client_secret="not-defined", # nosec B106
token_url="http://not.defined",
auth_url="http://not.defined",
issuer_url="http://not.defined",
Expand Down
5 changes: 1 addition & 4 deletions components/renku_data_services/notebooks/cr_base.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"""Base models for K8s CRD specifications."""

from pydantic import BaseModel, Field


from pydantic import BaseModel


class BaseCRD(BaseModel):
Expand All @@ -12,4 +10,3 @@ class Config:
"""Do not exclude unknown properties."""

extra = "allow"

11 changes: 10 additions & 1 deletion components/renku_data_services/notebooks/crs.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ def as_apispec(self) -> apispec.SessionResponse:
url = urljoin(f"{scheme}://{self.spec.ingress.host}", self.spec.session.urlPath)
else:
url = self.status.url
ready_containers = 0
total_containers = 0
if self.status.initContainerCounts is not None:
ready_containers += self.status.initContainerCounts.ready or 0
total_containers += self.status.initContainerCounts.total or 0
if self.status.containerCounts is not None:
ready_containers += self.status.containerCounts.ready or 0
total_containers += self.status.containerCounts.total or 0
return apispec.SessionResponse(
image=self.spec.session.image,
name=self.metadata.name,
Expand All @@ -183,8 +191,9 @@ def as_apispec(self) -> apispec.SessionResponse:
),
started=self.metadata.creationTimestamp,
status=apispec.SessionStatus(
details=[],
state=apispec.State3.running,
ready_containers=ready_containers,
total_containers=total_containers,
),
url=url,
project_id=str(self.project_id),
Expand Down
8 changes: 8 additions & 0 deletions components/renku_data_services/notebooks/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@

@dataclass
class SessionEnvVar:
"""Environment variables for an amalthea session."""

name: str
value: str


@dataclass
class SessionUserSecrets:
"""User secret mounted in an amalthea session."""

mount_path: Path
user_secret_ids: list[str]

Expand Down Expand Up @@ -45,6 +49,8 @@ class Config:


class AmaltheaSessionManifest:
"""The manifest for an amalthea session."""

def __init__(self, manifest: AmaltheaSessionV1Alpha1) -> None:
self._manifest = manifest
self._metadata = _MetadataValidation.model_validate(self._manifest.metadata)
Expand All @@ -54,6 +60,7 @@ def __repr__(self) -> str:

@property
def env_vars(self) -> dict[str, SessionEnvVar]:
"""Extract the environment variables from a manifest."""
output: dict[str, SessionEnvVar] = {}
assert self._manifest.spec
for env in self._manifest.spec.session.env or []:
Expand All @@ -64,5 +71,6 @@ def env_vars(self) -> dict[str, SessionEnvVar]:

@property
def requested_env_vars(self) -> dict[str, SessionEnvVar]:
"""The environment variables requested."""
requested_names = self._metadata.annotations.env_variable_names
return {ikey: ival for ikey, ival in self.env_vars.items() if ikey in requested_names}
4 changes: 2 additions & 2 deletions components/renku_data_services/notebooks/util/kubernetes_.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@

from __future__ import annotations

from dataclasses import dataclass
from enum import StrEnum
from hashlib import md5
from typing import Any, Self, TypeAlias, cast
from typing import Any, TypeAlias, cast

import escapism
from kubernetes.client import V1Container

from renku_data_services.notebooks.crs import Patch, PatchType


Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Repository utilities."""

import requests
from typing import Any, Optional, cast

import requests
Expand Down
4 changes: 2 additions & 2 deletions components/renku_data_services/repositories/db.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Adapters for repositories database classes."""

from collections.abc import Callable, Coroutine
from typing import Any, Literal
from collections.abc import Callable
from typing import Literal
from urllib.parse import urlparse

from httpx import AsyncClient as HttpClient
Expand Down
2 changes: 1 addition & 1 deletion components/renku_data_services/session/apispec_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ def convert_path_to_string(cls, val: str | PurePosixPath) -> str:
"""Converts the python path to a regular string when pydantic deserializes."""
if isinstance(val, PurePosixPath):
return val.as_posix()
return val
return val
Loading

0 comments on commit f4455bc

Please sign in to comment.