From 84f14ce93ca0b1bc44ed09f0579391c0cc91fdf1 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Mon, 26 Jan 2026 10:21:48 +0900 Subject: [PATCH 1/9] docs: Reserve BEP-1038 for ImageV2 GQL Implementation --- proposals/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/README.md b/proposals/README.md index 1e05362e4d8..6b02fc38caa 100644 --- a/proposals/README.md +++ b/proposals/README.md @@ -126,7 +126,6 @@ BEP numbers start from 1000. | [1036](BEP-1036-artifact-storage-quota.md) | Artifact Storage Usage Tracking and Quota Enforcement | Gyubong Lee | Rejected | | [1037](BEP-1037-storage-proxy-health-monitoring.md) | Volume Host Availability Check | Gyubong Lee | Draft | | [1038](BEP-1038-image-v2-gql-implementation.md) | ImageV2 GQL Implementation | Gyubong Lee | Draft | -| [1039](BEP-1039-image-id-based-service-logic-migration.md) | Image ID Based Service Logic Migration | Gyubong Lee | Draft | | _next_ | _(reserve your number here)_ | | | ## File Structure From bd9b135800a434ad05e438aa6ffaa34926f0f40b Mon Sep 17 00:00:00 2001 From: Gyubong Date: Mon, 26 Jan 2026 11:30:54 +0900 Subject: [PATCH 2/9] docs: Reserve BEP-1039 for Image ID Based Service Logic Migration --- proposals/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/README.md b/proposals/README.md index 6b02fc38caa..1e05362e4d8 100644 --- a/proposals/README.md +++ b/proposals/README.md @@ -126,6 +126,7 @@ BEP numbers start from 1000. | [1036](BEP-1036-artifact-storage-quota.md) | Artifact Storage Usage Tracking and Quota Enforcement | Gyubong Lee | Rejected | | [1037](BEP-1037-storage-proxy-health-monitoring.md) | Volume Host Availability Check | Gyubong Lee | Draft | | [1038](BEP-1038-image-v2-gql-implementation.md) | ImageV2 GQL Implementation | Gyubong Lee | Draft | +| [1039](BEP-1039-image-id-based-service-logic-migration.md) | Image ID Based Service Logic Migration | Gyubong Lee | Draft | | _next_ | _(reserve your number here)_ | | | ## File Structure From 8c090004c9e8059a89f87dc83f25c00b290cc713 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Mon, 26 Jan 2026 13:13:06 +0900 Subject: [PATCH 3/9] doc: Add BEP-1038 for ImageV2 GQL Implementation --- .../BEP-1038-image-v2-gql-implementation.md | 109 ++++++++++++++++ proposals/BEP-1038/types-to-defer.md | 48 +++++++ proposals/BEP-1038/types-to-include.md | 121 ++++++++++++++++++ proposals/BEP-1038/types-to-skip.md | 30 +++++ 4 files changed, 308 insertions(+) create mode 100644 proposals/BEP-1038-image-v2-gql-implementation.md create mode 100644 proposals/BEP-1038/types-to-defer.md create mode 100644 proposals/BEP-1038/types-to-include.md create mode 100644 proposals/BEP-1038/types-to-skip.md 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..7b95eeecc2a --- /dev/null +++ b/proposals/BEP-1038-image-v2-gql-implementation.md @@ -0,0 +1,109 @@ +--- +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 Skip** - Types replaced by other designs or deprecated +3. **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-skip.md](BEP-1038/types-to-skip.md) | Types replaced by other designs | +| [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 Skip (Do Not Implement) + +| Type | Reason | +|------|--------| +| `Image` (legacy) | Replaced by `ImageV2GQL` with improved structure | + +### 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 # 이미지 식별 정보 +│ ├── canonical_name +│ ├── namespace +│ ├── architecture +│ └── aliases +│ +├── metadata: ImageMetadataInfoGQL # 메타데이터 정보 +│ ├── tags +│ ├── labels +│ ├── digest +│ ├── size_bytes +│ ├── status +│ └── created_at +│ +├── requirements: ImageRequirementsInfoGQL # 실행 요구사항 +│ ├── resource_limits +│ └── supported_accelerators +│ +├── permission: ImagePermissionInfoGQL # RBAC 권한 +│ └── permissions +│ +├── registry_id: UUID # 레지스트리 ID (직접 쿼리용) +└── registry: ContainerRegistryNode # (deferred) +``` + +## Implementation Checklist + +### PR Scope + +- [ ] Implement all types listed in "Types to Include" +- [ ] Skip all types listed in "Types to Skip" +- [ ] Implement `from_row()` factory method for `ImageV2GQL` +- [ ] 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..a601050282f --- /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="ImageNode") +class ImageV2GQL(Node): + registry: str # Keep as string for now + +# Future implementation (after ContainerRegistryNode PR) +@strawberry.type(name="ImageNode") +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..390257ec385 --- /dev/null +++ b/proposals/BEP-1038/types-to-include.md @@ -0,0 +1,121 @@ +# 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="ImageNode") +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: str # TODO: Replace with ContainerRegistryNode connection + + @classmethod + def from_row( + cls, + row: ImageRow, + *, + permissions: list[ImagePermission] | None = None, + ) -> Self: + ... +``` + +### ImageEdgeGQL +```python +ImageEdgeGQL = Edge[ImageV2GQL] +``` + +### ImageConnectionV2GQL +```python +@strawberry.type(name="ImageConnection") +class ImageConnectionV2GQL(Connection[ImageV2GQL]): + count: int +``` diff --git a/proposals/BEP-1038/types-to-skip.md b/proposals/BEP-1038/types-to-skip.md new file mode 100644 index 00000000000..30eff576678 --- /dev/null +++ b/proposals/BEP-1038/types-to-skip.md @@ -0,0 +1,30 @@ +# ImageV2 GQL - Types to Skip + +These types are **not to be implemented**. They have been decided to be replaced by other designs or are deprecated. + +--- + +## Summary + +| Type | Location | Reason | +|------|----------|--------| +| `Image` (legacy ObjectType) | `gql_legacy/image.py` | Replaced by `ImageV2GQL` with improved structure | + +--- + +## Legacy Image Type + +### Image (graphene.ObjectType) + +**Action**: Do not implement. Replaced by `ImageV2GQL` with better structure. + +**Reason**: The legacy `Image` type has several issues: +1. Flat structure without proper grouping of related fields +2. Missing proper RBAC permission field handling +3. Inconsistent naming (`name` vs `namespace`) +4. Legacy `hash` field that duplicates `digest` + +The new `ImageV2GQL` type addresses these issues with: +- Proper field naming conventions +- RBAC permission integration +- Cleaner separation of concerns From 8d406f70d9bd57146ee11db48c1d8c3e8d6cc755 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Mon, 26 Jan 2026 13:27:48 +0900 Subject: [PATCH 4/9] docs: Add news fragment --- changes/8292.doc.md | 1 + proposals/BEP-1038/types-to-include.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 changes/8292.doc.md diff --git a/changes/8292.doc.md b/changes/8292.doc.md new file mode 100644 index 00000000000..c5f0c43bf5b --- /dev/null +++ b/changes/8292.doc.md @@ -0,0 +1 @@ +Add BEP-1038 for ImageV2 GQL Implementation diff --git a/proposals/BEP-1038/types-to-include.md b/proposals/BEP-1038/types-to-include.md index 390257ec385..95c2880ffcf 100644 --- a/proposals/BEP-1038/types-to-include.md +++ b/proposals/BEP-1038/types-to-include.md @@ -84,7 +84,7 @@ class ImagePermissionInfoGQL: ### ImageV2GQL ```python -@strawberry.type(name="ImageNode") +@strawberry.type(name="ImageV2") class ImageV2GQL(Node): id: NodeID[UUID] @@ -115,7 +115,7 @@ ImageEdgeGQL = Edge[ImageV2GQL] ### ImageConnectionV2GQL ```python -@strawberry.type(name="ImageConnection") +@strawberry.type(name="ImageConnectionV2") class ImageConnectionV2GQL(Connection[ImageV2GQL]): count: int ``` From 8f755de71311963cef3f509d8d64d7c90e725651 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Mon, 26 Jan 2026 13:30:58 +0900 Subject: [PATCH 5/9] doc: Update --- .../BEP-1038-image-v2-gql-implementation.md | 21 ++++--------- proposals/BEP-1038/types-to-skip.md | 30 ------------------- 2 files changed, 6 insertions(+), 45 deletions(-) delete mode 100644 proposals/BEP-1038/types-to-skip.md diff --git a/proposals/BEP-1038-image-v2-gql-implementation.md b/proposals/BEP-1038-image-v2-gql-implementation.md index 7b95eeecc2a..c0fe52a9aab 100644 --- a/proposals/BEP-1038-image-v2-gql-implementation.md +++ b/proposals/BEP-1038-image-v2-gql-implementation.md @@ -14,8 +14,7 @@ Implemented-Version: 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 Skip** - Types replaced by other designs or deprecated -3. **Types to Defer** - Types requiring Node connections (implement later) +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. @@ -24,7 +23,6 @@ This document defines the implementation plan for `ImageV2GQL` types as part of | Document | Description | |----------|-------------| | [types-to-include.md](BEP-1038/types-to-include.md) | Detailed specifications of types to implement | -| [types-to-skip.md](BEP-1038/types-to-skip.md) | Types replaced by other designs | | [types-to-defer.md](BEP-1038/types-to-defer.md) | Types requiring Node connections | ## Summary @@ -47,12 +45,6 @@ This document defines the implementation plan for `ImageV2GQL` types as part of - `ImageEdgeGQL` - Edge type - `ImageConnectionV2GQL` - Connection type -### Types to Skip (Do Not Implement) - -| Type | Reason | -|------|--------| -| `Image` (legacy) | Replaced by `ImageV2GQL` with improved structure | - ### Types to Defer (Node Connections) | Type/Field | Future Node | Action | @@ -65,13 +57,13 @@ This document defines the implementation plan for `ImageV2GQL` types as part of ImageV2GQL ├── id: NodeID[UUID] │ -├── identity: ImageIdentityInfoGQL # 이미지 식별 정보 +├── identity: ImageIdentityInfoGQL # Image identity information │ ├── canonical_name │ ├── namespace │ ├── architecture │ └── aliases │ -├── metadata: ImageMetadataInfoGQL # 메타데이터 정보 +├── metadata: ImageMetadataInfoGQL # Metadata information │ ├── tags │ ├── labels │ ├── digest @@ -79,14 +71,14 @@ ImageV2GQL │ ├── status │ └── created_at │ -├── requirements: ImageRequirementsInfoGQL # 실행 요구사항 +├── requirements: ImageRequirementsInfoGQL # Runtime requirements │ ├── resource_limits │ └── supported_accelerators │ -├── permission: ImagePermissionInfoGQL # RBAC 권한 +├── permission: ImagePermissionInfoGQL # RBAC permissions │ └── permissions │ -├── registry_id: UUID # 레지스트리 ID (직접 쿼리용) +├── registry_id: UUID # Registry ID (for direct query) └── registry: ContainerRegistryNode # (deferred) ``` @@ -95,7 +87,6 @@ ImageV2GQL ### PR Scope - [ ] Implement all types listed in "Types to Include" -- [ ] Skip all types listed in "Types to Skip" - [ ] Implement `from_row()` factory method for `ImageV2GQL` - [ ] Implement connection resolver with pagination diff --git a/proposals/BEP-1038/types-to-skip.md b/proposals/BEP-1038/types-to-skip.md deleted file mode 100644 index 30eff576678..00000000000 --- a/proposals/BEP-1038/types-to-skip.md +++ /dev/null @@ -1,30 +0,0 @@ -# ImageV2 GQL - Types to Skip - -These types are **not to be implemented**. They have been decided to be replaced by other designs or are deprecated. - ---- - -## Summary - -| Type | Location | Reason | -|------|----------|--------| -| `Image` (legacy ObjectType) | `gql_legacy/image.py` | Replaced by `ImageV2GQL` with improved structure | - ---- - -## Legacy Image Type - -### Image (graphene.ObjectType) - -**Action**: Do not implement. Replaced by `ImageV2GQL` with better structure. - -**Reason**: The legacy `Image` type has several issues: -1. Flat structure without proper grouping of related fields -2. Missing proper RBAC permission field handling -3. Inconsistent naming (`name` vs `namespace`) -4. Legacy `hash` field that duplicates `digest` - -The new `ImageV2GQL` type addresses these issues with: -- Proper field naming conventions -- RBAC permission integration -- Cleaner separation of concerns From 3e8641a9f9a44d22afb5b9a760d460a918579c61 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Mon, 26 Jan 2026 14:33:20 +0900 Subject: [PATCH 6/9] doc: Update --- changes/8292.doc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changes/8292.doc.md b/changes/8292.doc.md index c5f0c43bf5b..80cfcb1de56 100644 --- a/changes/8292.doc.md +++ b/changes/8292.doc.md @@ -1 +1 @@ -Add BEP-1038 for ImageV2 GQL Implementation +Add BEP-1038 for `ImageV2` GQL Implementation From 7a7d7e56ca1999904afc908c55614cb096e9a325 Mon Sep 17 00:00:00 2001 From: jopemachine Date: Tue, 27 Jan 2026 01:54:43 +0000 Subject: [PATCH 7/9] doc: Update --- proposals/BEP-1038/types-to-defer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/BEP-1038/types-to-defer.md b/proposals/BEP-1038/types-to-defer.md index a601050282f..d866958ec0e 100644 --- a/proposals/BEP-1038/types-to-defer.md +++ b/proposals/BEP-1038/types-to-defer.md @@ -26,12 +26,12 @@ The `ContainerRegistryNode` will include: ```python # Current implementation -@strawberry.type(name="ImageNode") +@strawberry.type(name="ImageV2") class ImageV2GQL(Node): registry: str # Keep as string for now # Future implementation (after ContainerRegistryNode PR) -@strawberry.type(name="ImageNode") +@strawberry.type(name="ImageV2") class ImageV2GQL(Node): @strawberry.field async def registry(self, info: strawberry.Info) -> ContainerRegistryNode | None: From 796ea551e578b335611a96a6dec48d9cbe476997 Mon Sep 17 00:00:00 2001 From: jopemachine Date: Tue, 27 Jan 2026 03:30:31 +0000 Subject: [PATCH 8/9] doc: Update --- proposals/BEP-1038-image-v2-gql-implementation.md | 1 - proposals/BEP-1038/types-to-include.md | 9 --------- 2 files changed, 10 deletions(-) diff --git a/proposals/BEP-1038-image-v2-gql-implementation.md b/proposals/BEP-1038-image-v2-gql-implementation.md index c0fe52a9aab..ed3fcd1eaec 100644 --- a/proposals/BEP-1038-image-v2-gql-implementation.md +++ b/proposals/BEP-1038-image-v2-gql-implementation.md @@ -87,7 +87,6 @@ ImageV2GQL ### PR Scope - [ ] Implement all types listed in "Types to Include" -- [ ] Implement `from_row()` factory method for `ImageV2GQL` - [ ] Implement connection resolver with pagination ### Future PRs diff --git a/proposals/BEP-1038/types-to-include.md b/proposals/BEP-1038/types-to-include.md index 95c2880ffcf..85e44a4f31f 100644 --- a/proposals/BEP-1038/types-to-include.md +++ b/proposals/BEP-1038/types-to-include.md @@ -97,15 +97,6 @@ class ImageV2GQL(Node): # Registry registry_id: UUID # For direct query without loading full registry node registry: str # TODO: Replace with ContainerRegistryNode connection - - @classmethod - def from_row( - cls, - row: ImageRow, - *, - permissions: list[ImagePermission] | None = None, - ) -> Self: - ... ``` ### ImageEdgeGQL From 449c9ba238ccbc2af7f2ba2fd4c08012cb8a9dcf Mon Sep 17 00:00:00 2001 From: jopemachine Date: Tue, 27 Jan 2026 03:32:31 +0000 Subject: [PATCH 9/9] doc: Update --- proposals/BEP-1038/types-to-include.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/BEP-1038/types-to-include.md b/proposals/BEP-1038/types-to-include.md index 85e44a4f31f..3c0e36890d2 100644 --- a/proposals/BEP-1038/types-to-include.md +++ b/proposals/BEP-1038/types-to-include.md @@ -96,7 +96,7 @@ class ImageV2GQL(Node): # Registry registry_id: UUID # For direct query without loading full registry node - registry: str # TODO: Replace with ContainerRegistryNode connection + # registry: ContainerRegistryNode connection to be added later ``` ### ImageEdgeGQL