From ccfda4c054c806fb74c99586b36c3c14fb46113a Mon Sep 17 00:00:00 2001 From: Ivan Kara Date: Mon, 9 Mar 2026 00:53:17 +0700 Subject: [PATCH] Adjust uploaded files permission --- src/lib/server/docker.ts | 22 +++++++++------ .../containers/[id]/files/upload/+server.ts | 27 ++++++++++++++++++- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/lib/server/docker.ts b/src/lib/server/docker.ts index 96c3dd7..fc83290 100644 --- a/src/lib/server/docker.ts +++ b/src/lib/server/docker.ts @@ -3844,19 +3844,25 @@ export async function getContainerTop(id: string, envId?: number | null): Promis export async function execInContainer( containerId: string, cmd: string[], - envId?: number | null + envId?: number | null, + user?: string | null ): Promise { - // Create exec instance + const execBody: any = { + Cmd: cmd, + AttachStdout: true, + AttachStderr: true, + Tty: false + }; + + if (user) { + execBody.User = user; + } + const execCreate = await dockerJsonRequest<{ Id: string }>( `/containers/${containerId}/exec`, { method: 'POST', - body: JSON.stringify({ - Cmd: cmd, - AttachStdout: true, - AttachStderr: true, - Tty: false - }) + body: JSON.stringify(execBody) }, envId ); diff --git a/src/routes/api/containers/[id]/files/upload/+server.ts b/src/routes/api/containers/[id]/files/upload/+server.ts index 91819c6..497fafb 100644 --- a/src/routes/api/containers/[id]/files/upload/+server.ts +++ b/src/routes/api/containers/[id]/files/upload/+server.ts @@ -1,5 +1,5 @@ import { json } from '@sveltejs/kit'; -import { putContainerArchive } from '$lib/server/docker'; +import { putContainerArchive, inspectContainer, execInContainer } from '$lib/server/docker'; import { authorize } from '$lib/server/authorize'; import { validateDockerIdParam } from '$lib/server/docker-validation'; import type { RequestHandler } from './$types'; @@ -111,6 +111,15 @@ export const POST: RequestHandler = async ({ params, url, request, cookies }) => return json({ error: 'No files provided' }, { status: 400 }); } + // We'll inspect the container once to determine its default user + let defaultUser: string | undefined; + try { + const inspectData = await inspectContainer(params.id, envIdNum); + defaultUser = inspectData.Config.User || undefined; + } catch (e) { + console.warn('Failed to inspect container for user info', e); + } + // For simplicity, we'll upload files one at a time // A more sophisticated implementation could pack multiple files into one tar const uploaded: string[] = []; @@ -128,6 +137,22 @@ export const POST: RequestHandler = async ({ params, url, request, cookies }) => envId ? parseInt(envId) : undefined ); + // chown the uploaded file + if (defaultUser) { + const targetPath = path.endsWith('/') ? `${path}${file.name}` : `${path}/${file.name}`; + const ownerGroup = defaultUser.includes(':') ? defaultUser : `${defaultUser}:${defaultUser}`; + try { + await execInContainer( + params.id, + ['chown', '-R', ownerGroup, targetPath], + envId ? parseInt(envId) : undefined, + 'root' + ); + } catch (e) { + console.warn('Failed to set ownership on', targetPath, e); + } + } + uploaded.push(file.name); } catch (err: any) { errors.push(`${file.name}: ${err.message}`);