Skip to content

Commit 6c4b571

Browse files
committed
feat: Update GQL user mutation to allow set uid/gid
1 parent 7d5e7eb commit 6c4b571

File tree

4 files changed

+119
-0
lines changed

4 files changed

+119
-0
lines changed

changes/3352.feature.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Enable per-user UID/GID set for containers via user creation and update GraphQL APIs

docs/manager/graphql-reference/schema.graphql

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,21 @@ type UserNode implements Node {
732732
totp_activated: Boolean
733733
totp_activated_at: DateTime
734734
sudo_session_enabled: Boolean
735+
736+
"""
737+
Added in 25.2.0. The user ID (UID) assigned to processes running inside the container.
738+
"""
739+
container_uid: Int
740+
741+
"""
742+
Added in 25.2.0. The primary group ID (GID) assigned to processes running inside the container.
743+
"""
744+
container_main_gid: Int
745+
746+
"""
747+
Added in 25.2.0. Supplementary group IDs assigned to processes running inside the container.
748+
"""
749+
container_gids: [Int]
735750
}
736751

737752
"""Added in 24.03.0"""
@@ -835,6 +850,21 @@ type User implements Item {
835850
Added in 24.03.0. Used as the default authentication credential for password-based logins and sets the user's total resource usage limit. User's main_access_key cannot be deleted, and only super-admin can replace main_access_key.
836851
"""
837852
main_access_key: String
853+
854+
"""
855+
Added in 25.2.0. The user ID (UID) assigned to processes running inside the container.
856+
"""
857+
container_uid: Int
858+
859+
"""
860+
Added in 25.2.0. The primary group ID (GID) assigned to processes running inside the container.
861+
"""
862+
container_main_gid: Int
863+
864+
"""
865+
Added in 25.2.0. Supplementary group IDs assigned to processes running inside the container.
866+
"""
867+
container_gids: [Int]
838868
groups: [UserGroup]
839869
}
840870

@@ -2131,6 +2161,21 @@ input UserInput {
21312161
totp_activated: Boolean = false
21322162
resource_policy: String = "default"
21332163
sudo_session_enabled: Boolean = false
2164+
2165+
"""
2166+
Added in 25.2.0. The user ID (UID) assigned to processes running inside the container.
2167+
"""
2168+
container_uid: Int
2169+
2170+
"""
2171+
Added in 25.2.0. The primary group ID (GID) assigned to processes running inside the container.
2172+
"""
2173+
container_main_gid: Int
2174+
2175+
"""
2176+
Added in 25.2.0. Supplementary group IDs assigned to processes running inside the container.
2177+
"""
2178+
container_gids: [Int]
21342179
}
21352180

21362181
type ModifyUser {
@@ -2155,6 +2200,21 @@ input ModifyUserInput {
21552200
resource_policy: String
21562201
sudo_session_enabled: Boolean
21572202
main_access_key: String
2203+
2204+
"""
2205+
Added in 25.2.0. The user ID (UID) assigned to processes running inside the container.
2206+
"""
2207+
container_uid: Int
2208+
2209+
"""
2210+
Added in 25.2.0. The primary group ID (GID) assigned to processes running inside the container.
2211+
"""
2212+
container_main_gid: Int
2213+
2214+
"""
2215+
Added in 25.2.0. Supplementary group IDs assigned to processes running inside the container.
2216+
"""
2217+
container_gids: [Int]
21582218
}
21592219

21602220
"""

src/ai/backend/manager/models/gql_models/user.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ class Meta:
5252
totp_activated = graphene.Boolean()
5353
totp_activated_at = GQLDateTime()
5454
sudo_session_enabled = graphene.Boolean()
55+
container_uid = graphene.Int(
56+
description="Added in 25.2.0. The user ID (UID) assigned to processes running inside the container."
57+
)
58+
container_main_gid = graphene.Int(
59+
description="Added in 25.2.0. The primary group ID (GID) assigned to processes running inside the container."
60+
)
61+
container_gids = graphene.List(
62+
lambda: graphene.Int,
63+
description="Added in 25.2.0. Supplementary group IDs assigned to processes running inside the container.",
64+
)
5565

5666
@classmethod
5767
def from_row(cls, ctx: GraphQueryContext, row: UserRow) -> Self:
@@ -74,6 +84,9 @@ def from_row(cls, ctx: GraphQueryContext, row: UserRow) -> Self:
7484
totp_activated=row.totp_activated,
7585
totp_activated_at=row.totp_activated_at,
7686
sudo_session_enabled=row.sudo_session_enabled,
87+
container_uid=row.container_uid,
88+
container_main_gid=row.container_main_gid,
89+
container_gids=row.container_gids,
7790
)
7891

7992
@classmethod

src/ai/backend/manager/models/user.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,16 @@ class Meta:
256256
" be deleted, and only super-admin can replace main_access_key."
257257
)
258258
)
259+
container_uid = graphene.Int(
260+
description="Added in 25.2.0. The user ID (UID) assigned to processes running inside the container."
261+
)
262+
container_main_gid = graphene.Int(
263+
description="Added in 25.2.0. The primary group ID (GID) assigned to processes running inside the container."
264+
)
265+
container_gids = graphene.List(
266+
lambda: graphene.Int,
267+
description="Added in 25.2.0. Supplementary group IDs assigned to processes running inside the container.",
268+
)
259269

260270
groups = graphene.List(lambda: UserGroup)
261271

@@ -295,6 +305,9 @@ def from_row(
295305
totp_activated_at=row["totp_activated_at"],
296306
sudo_session_enabled=row["sudo_session_enabled"],
297307
main_access_key=row["main_access_key"],
308+
container_uid=row["container_uid"],
309+
container_main_gid=row["container_main_gid"],
310+
container_gids=row["container_gids"],
298311
)
299312

300313
@classmethod
@@ -557,6 +570,19 @@ class UserInput(graphene.InputObjectType):
557570
totp_activated = graphene.Boolean(required=False, default_value=False)
558571
resource_policy = graphene.String(required=False, default_value="default")
559572
sudo_session_enabled = graphene.Boolean(required=False, default_value=False)
573+
container_uid = graphene.Int(
574+
required=False,
575+
description="Added in 25.2.0. The user ID (UID) assigned to processes running inside the container.",
576+
)
577+
container_main_gid = graphene.Int(
578+
required=False,
579+
description="Added in 25.2.0. The primary group ID (GID) assigned to processes running inside the container.",
580+
)
581+
container_gids = graphene.List(
582+
lambda: graphene.Int,
583+
required=False,
584+
description="Added in 25.2.0. Supplementary group IDs assigned to processes running inside the container.",
585+
)
560586
# When creating, you MUST set all fields.
561587
# When modifying, set the field to "None" to skip setting the value.
562588

@@ -577,6 +603,19 @@ class ModifyUserInput(graphene.InputObjectType):
577603
resource_policy = graphene.String(required=False)
578604
sudo_session_enabled = graphene.Boolean(required=False, default=False)
579605
main_access_key = graphene.String(required=False)
606+
container_uid = graphene.Int(
607+
required=False,
608+
description="Added in 25.2.0. The user ID (UID) assigned to processes running inside the container.",
609+
)
610+
container_main_gid = graphene.Int(
611+
required=False,
612+
description="Added in 25.2.0. The primary group ID (GID) assigned to processes running inside the container.",
613+
)
614+
container_gids = graphene.List(
615+
lambda: graphene.Int,
616+
required=False,
617+
description="Added in 25.2.0. Supplementary group IDs assigned to processes running inside the container.",
618+
)
580619

581620

582621
class PurgeUserInput(graphene.InputObjectType):
@@ -626,6 +665,9 @@ async def mutate(
626665
"resource_policy": props.resource_policy,
627666
"sudo_session_enabled": props.sudo_session_enabled,
628667
}
668+
set_if_set(props, user_data, "container_uid")
669+
set_if_set(props, user_data, "container_main_gid")
670+
set_if_set(props, user_data, "container_gids")
629671
user_insert_query = sa.insert(users).values(user_data)
630672

631673
async def _post_func(conn: SAConnection, result: Result) -> Row:
@@ -737,6 +779,9 @@ async def mutate(
737779
set_if_set(props, data, "sudo_session_enabled")
738780
set_if_set(props, data, "main_access_key")
739781
set_if_set(props, data, "is_active")
782+
set_if_set(props, data, "container_uid")
783+
set_if_set(props, data, "container_main_gid")
784+
set_if_set(props, data, "container_gids")
740785
if data.get("password") is None:
741786
data.pop("password", None)
742787
if not data and not props.group_ids:

0 commit comments

Comments
 (0)