diff --git a/changes/8292.doc.md b/changes/8292.doc.md new file mode 100644 index 00000000000..80cfcb1de56 --- /dev/null +++ b/changes/8292.doc.md @@ -0,0 +1 @@ +Add BEP-1038 for `ImageV2` GQL Implementation diff --git a/proposals/BEP-1038-image-v2-gql-implementation.md b/proposals/BEP-1038-image-v2-gql-implementation.md new file mode 100644 index 00000000000..ed3fcd1eaec --- /dev/null +++ b/proposals/BEP-1038-image-v2-gql-implementation.md @@ -0,0 +1,99 @@ +--- +Author: Gyubong Lee (gbl@lablup.com) +Status: Draft +Created: 2026-01-26 +Created-Version: 26.2.0 +Target-Version: 26.2.0 +Implemented-Version: +--- + +# BEP-1038: ImageV2 GQL Implementation + +## Overview + +This document defines the implementation plan for `ImageV2GQL` types as part of the Strawberry GraphQL migration (BEP-1010). It specifies: + +1. **Types to Include** - Types that will be implemented +2. **Types to Defer** - Types requiring Node connections (implement later) + +> **Note**: Enums are directly exposed from existing definitions. Mutations, Filters, and OrderBy types are out of scope for this BEP. + +## Document Structure + +| Document | Description | +|----------|-------------| +| [types-to-include.md](BEP-1038/types-to-include.md) | Detailed specifications of types to implement | +| [types-to-defer.md](BEP-1038/types-to-defer.md) | Types requiring Node connections | + +## Summary + +### Types to Include + +#### Sub-Info Types (Leaf) +- `ImageTagEntryGQL` - Tag key-value pair +- `ImageLabelEntryGQL` - Label key-value pair +- `ImageResourceLimitGQL` - Resource limit info + +#### Info Types (Grouped) +- `ImageIdentityInfoGQL` - Identity info (canonical_name, namespace, architecture, aliases) +- `ImageMetadataInfoGQL` - Metadata info (tags, labels, digest, size_bytes, status, created_at) +- `ImageRequirementsInfoGQL` - Requirements info (resource_limits, supported_accelerators) +- `ImagePermissionInfoGQL` - Permission info (permissions) + +#### Main Types +- `ImageV2GQL` - Main image node type +- `ImageEdgeGQL` - Edge type +- `ImageConnectionV2GQL` - Connection type + +### Types to Defer (Node Connections) + +| Type/Field | Future Node | Action | +|------------|-------------|--------| +| `ImageV2GQL.registry` | `ContainerRegistryNode` | Return primitive string for now | + +## Type Structure + +``` +ImageV2GQL +├── id: NodeID[UUID] +│ +├── identity: ImageIdentityInfoGQL # Image identity information +│ ├── canonical_name +│ ├── namespace +│ ├── architecture +│ └── aliases +│ +├── metadata: ImageMetadataInfoGQL # Metadata information +│ ├── tags +│ ├── labels +│ ├── digest +│ ├── size_bytes +│ ├── status +│ └── created_at +│ +├── requirements: ImageRequirementsInfoGQL # Runtime requirements +│ ├── resource_limits +│ └── supported_accelerators +│ +├── permission: ImagePermissionInfoGQL # RBAC permissions +│ └── permissions +│ +├── registry_id: UUID # Registry ID (for direct query) +└── registry: ContainerRegistryNode # (deferred) +``` + +## Implementation Checklist + +### PR Scope + +- [ ] Implement all types listed in "Types to Include" +- [ ] Implement connection resolver with pagination + +### Future PRs + +- [ ] ContainerRegistryNode PR: Replace `registry` string with connection + +## References + +- [BEP-1010: GraphQL API Migration to Strawberry](BEP-1010-new-gql.md) +- [BEP-1034: KernelV2 GQL Implementation](BEP-1034-kernel-v2-gql-implementation.md) diff --git a/proposals/BEP-1038/types-to-defer.md b/proposals/BEP-1038/types-to-defer.md new file mode 100644 index 00000000000..d866958ec0e --- /dev/null +++ b/proposals/BEP-1038/types-to-defer.md @@ -0,0 +1,48 @@ +# ImageV2 GQL - Types to Defer + +These types reference entities that should be represented as proper Relay Node connections. Since the corresponding Node types are not yet implemented, these fields/types should be **omitted** or use primitive types and added later. + +--- + +## Summary + +| Type/Field | Future Node | Current Action | +|------------|-------------|----------------| +| `ImageV2GQL.registry` | `ContainerRegistryNode` | Keep as string, replace later | + +--- + +## Registry Types (Defer to ContainerRegistryNode) + +### ImageV2GQL.registry field + +**Current Action**: Keep as primitive `str` type. + +**Future**: Replace with `ContainerRegistryNode` connection. + +The `ContainerRegistryNode` will include: +- `is_local`: Whether the registry is local +- `project`: Project/namespace in the registry + +```python +# Current implementation +@strawberry.type(name="ImageV2") +class ImageV2GQL(Node): + registry: str # Keep as string for now + +# Future implementation (after ContainerRegistryNode PR) +@strawberry.type(name="ImageV2") +class ImageV2GQL(Node): + @strawberry.field + async def registry(self, info: strawberry.Info) -> ContainerRegistryNode | None: + # Load via dataloader + ... +``` + +--- + +## Future Implementation PRs + +| PR | Fields to Add/Modify | +|----|---------------------| +| ContainerRegistryNode PR | Replace `registry: str` with `registry: ContainerRegistryNode` connection | diff --git a/proposals/BEP-1038/types-to-include.md b/proposals/BEP-1038/types-to-include.md new file mode 100644 index 00000000000..3c0e36890d2 --- /dev/null +++ b/proposals/BEP-1038/types-to-include.md @@ -0,0 +1,112 @@ +# ImageV2 GQL - Types to Include + +This document lists all types to be implemented with their fields. + +> **Note**: Enums (`ImageStatusGQL`, `ImagePermissionGQL`) are directly exposed from existing definitions. Mutations, Filters, and OrderBy types are out of scope for this BEP. + +--- + +## Sub-Info Types + +### ImageTagEntryGQL +```python +@strawberry.type(name="ImageTagEntry") +class ImageTagEntryGQL: + key: str + value: str +``` + +### ImageLabelEntryGQL +```python +@strawberry.type(name="ImageLabelEntry") +class ImageLabelEntryGQL: + key: str + value: str +``` + +### ImageResourceLimitGQL +```python +@strawberry.type(name="ImageResourceLimit") +class ImageResourceLimitGQL: + key: str + min: str + max: str | None +``` + +--- + +## Info Types + +### ImageIdentityInfoGQL +```python +@strawberry.type(name="ImageIdentityInfo") +class ImageIdentityInfoGQL: + canonical_name: str # Full canonical name (e.g., cr.backend.ai/stable/python:3.9) + namespace: str # Base image namespace (e.g., python) + architecture: str # CPU architecture (e.g., x86_64, aarch64) + aliases: list[str] # Image aliases +``` + +### ImageMetadataInfoGQL +```python +@strawberry.type(name="ImageMetadataInfo") +class ImageMetadataInfoGQL: + # Manifest info + tags: list[ImageTagEntryGQL] # Parsed tag components (e.g., 3.9, ubuntu20.04) + labels: list[ImageLabelEntryGQL] # Docker labels + digest: str | None # Config digest (image hash) + size_bytes: int # Image size in bytes + + # Lifecycle info + status: ImageStatusGQL # ALIVE, DELETED + created_at: datetime | None +``` + +### ImageRequirementsInfoGQL +```python +@strawberry.type(name="ImageRequirementsInfo") +class ImageRequirementsInfoGQL: + resource_limits: list[ImageResourceLimitGQL] + supported_accelerators: list[str] +``` + +### ImagePermissionInfoGQL +```python +@strawberry.type(name="ImagePermissionInfo") +class ImagePermissionInfoGQL: + permissions: list[ImagePermissionGQL] +``` + +--- + +## Main Types + +### ImageV2GQL + +```python +@strawberry.type(name="ImageV2") +class ImageV2GQL(Node): + id: NodeID[UUID] + + # Sub-info types + identity: ImageIdentityInfoGQL + metadata: ImageMetadataInfoGQL + requirements: ImageRequirementsInfoGQL + permission: ImagePermissionInfoGQL | None + + # Registry + registry_id: UUID # For direct query without loading full registry node + # registry: ContainerRegistryNode connection to be added later +``` + +### ImageEdgeGQL +```python +ImageEdgeGQL = Edge[ImageV2GQL] +``` + +### ImageConnectionV2GQL +```python +@strawberry.type(name="ImageConnectionV2") +class ImageConnectionV2GQL(Connection[ImageV2GQL]): + count: int +```