Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 接入 scowd #1193

Merged
merged 43 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
1c423b1
feat: 添加scowd proto 和 getClient 方法
Miracle575 Mar 18, 2024
646f1e6
feat: 部分文件操作重构
Miracle575 Mar 20, 2024
a1b146c
Merge branch 'master' into feat-scowd
Miracle575 Mar 20, 2024
04ae1db
feat: 添加日志
Miracle575 Apr 2, 2024
3166032
fix: bug
Miracle575 Apr 2, 2024
f22a418
fix: scowdUrl 配置改为可选
Miracle575 Apr 2, 2024
19caec9
feat: 添加环境变量选择加载 service
Miracle575 Apr 2, 2024
cb9856b
fix: bug
Miracle575 Apr 2, 2024
b0bb2f8
fix: build error
Miracle575 Apr 2, 2024
803d4a5
feat: 改造 scowd 上传下载
Miracle575 Apr 2, 2024
b66079c
feat: 修改文件上传下载逻辑
Miracle575 Apr 3, 2024
6576225
Merge branch 'master' into feat-scowd
Miracle575 Apr 7, 2024
034bb5c
feat: 初步添加 desktop 的 scowd 改造
Miracle575 Apr 7, 2024
472e3a6
Merge branch 'master' into feat-scowd
Miracle575 Apr 9, 2024
b46e5c3
feat: 完成桌面功能对接
Miracle575 Apr 9, 2024
40d4c4f
test: build
Miracle575 Apr 9, 2024
4ceba17
feat: 加入双向 tls 逻辑
Miracle575 Apr 12, 2024
a088887
fix: bug
Miracle575 Apr 12, 2024
4dc013d
fix: test bug
Miracle575 Apr 15, 2024
8aad4bf
fix: spelling mistake
Miracle575 Apr 16, 2024
7d31905
refactor: 修改 ssl 相关文件路径
Miracle575 Apr 17, 2024
02071f5
Merge branch 'master' into feat-scowd
Miracle575 Apr 17, 2024
53722c4
fix: pnpm version
Miracle575 Apr 17, 2024
1ae6917
Merge branch 'master' into feat-scowd
Miracle575 Apr 18, 2024
cf67cef
fix: build bug
Miracle575 Apr 18, 2024
10ff918
feat: 支持集群级别启动 scowd
Miracle575 Apr 25, 2024
3238977
Merge branch 'master' into feat-scowd
Miracle575 Apr 25, 2024
9bedb11
chore: 修改 changeset
Miracle575 Apr 25, 2024
beb797e
refactor: 重构代码,删除冗余
Miracle575 Apr 26, 2024
1347064
fix: bug
Miracle575 Apr 26, 2024
f79f883
fix: 配置文件路径问题
Miracle575 Apr 26, 2024
e3123a2
fix: http config error
Miracle575 Apr 28, 2024
8e44b3e
fix: 删除关于 rejectUnauthorized 配置
Miracle575 Apr 28, 2024
d362ae2
feat: 新增健康检查接口
Miracle575 Apr 30, 2024
d801af3
Merge branch 'master' into feat-scowd
Miracle575 Jun 5, 2024
1cce8b8
fix: fix the bugs after merging the master branch
Miracle575 Jun 5, 2024
0312420
fix: configClusters name changed bug
Miracle575 Jun 5, 2024
7703618
feat: trpc err to grpc err
Miracle575 Jun 6, 2024
1ff31ef
Merge branch 'master' into feat-scowd
Miracle575 Jun 11, 2024
0ffe1e2
chore: 更新本地 pnpm 版本
Miracle575 Jun 11, 2024
7cee0e6
Merge branch 'master' into feat-scowd
Miracle575 Jun 18, 2024
090cda6
chore: 删除冗余 changeset 文件
Miracle575 Jun 18, 2024
a0b276b
update changesets
ddadaal Jun 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/brown-boats-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@scow/portal-server": patch
"@scow/scowd-protos": patch
"@scow/config": patch
"@scow/lib-scowd": patch
"@scow/cli": patch
"@scow/grpc-api": patch
---

scowd 一期改造,完成 HPC 部分文件和桌面支持接入 scowd
9 changes: 9 additions & 0 deletions .changeset/silent-lemons-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@scow/portal-server": patch
"@scow/scowd-protos": patch
"@scow/config": patch
"@scow/lib-scowd": patch
"@scow/cli": patch
---

scowd 一期改造,完成 HPC 部分文件和桌面支持接入 scowd
17 changes: 15 additions & 2 deletions apps/cli/src/compose/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,28 @@ export const createComposeSpec = (config: InstallConfigSchema) => {
// PORTAL
if (config.portal) {

const configPath = "/etc/scow";

const portalBasePath = join(BASE_PATH, PORTAL_PATH);

const scowdSslCaCertPath = config.scowd?.ssl?.caCertPath ?
join(configPath, config.scowd.ssl.caCertPath) : "";
const scowdSslScowCertPath = config.scowd?.ssl?.scowCertPath ?
join(configPath, config.scowd.ssl.scowCertPath) : "";
const scowdSslScowPrivateKeyPath = config.scowd?.ssl?.scowPrivateKeyPath ?
join(configPath, config.scowd.ssl.scowPrivateKeyPath) : "";

composeSpec.volumes["portal_data"] = {};

addService("portal-server", {
image: scowImage,
environment: {
SCOW_LAUNCH_APP: "portal-server",
PORTAL_BASE_PATH: portalBasePath,
SCOWD_SSL_ENABLED: String(config.scowd?.ssl?.enabled ?? false),
SCOWD_SSL_CA_CERT_PATH: scowdSslCaCertPath,
SCOWD_SSL_SCOW_CERT_PATH: scowdSslScowCertPath,
SCOWD_SSL_SCOW_PRIVATE_KEY_PATH: scowdSslScowPrivateKeyPath,
MIS_DEPLOYED: config.mis ? "true" : "false",
MIS_SERVER_URL: config.mis ? "mis-server:5000" : "",
...serviceLogEnv,
Expand All @@ -258,7 +271,7 @@ export const createComposeSpec = (config: InstallConfigSchema) => {
ports: config.portal.portMappings?.portalServer ? { [config.portal.portMappings.portalServer]: 5000 } : {},
volumes: {
"/etc/hosts": "/etc/hosts",
"./config": "/etc/scow",
"./config": configPath,
"~/.ssh": "/root/.ssh",
"portal_data":"/var/lib/scow/portal",
},
Expand Down Expand Up @@ -286,7 +299,7 @@ export const createComposeSpec = (config: InstallConfigSchema) => {
ports: {},
volumes: {
"/etc/hosts": "/etc/hosts",
"./config": "/etc/scow",
"./config": configPath,
},
});

Expand Down
15 changes: 15 additions & 0 deletions apps/cli/src/config/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,21 @@ export const InstallConfigSchema = Type.Object({
image: Type.Optional(Type.String({ description: "镜像", default: "mirrors.pku.edu.cn/pkuhpc-icode/scow" })),
imageTag: Type.String({ description: "镜像tag", default: "master" }),

scowd: Type.Optional(Type.Object({
ssl: Type.Optional(Type.Object({
enabled: Type.Boolean({ description: "到 SCOWD 的连接是否启动SSL", default: false }),
caCertPath: Type.String({ description: "SCOWD CA根证书路径, 相对 config 的默认目录", default: "./scowd/certs/ca.crt" }),
scowCertPath: Type.String({
description: "SCOWD CA签名的 SCOW 证书路径, 相对 config 的默认目录",
default: "./scowd/certs/scow.crt",
}),
scowPrivateKeyPath: Type.String({
description: "SCOWD CA签名的 SCOW 私钥路径, 相对 config 的默认目录",
default: "./scowd/certs/scow.key",
}),
}, { description: "scowd 全局 ssl 相关配置" })),
}, { description: "全局 scowd 相关配置" })),

log: Type.Object({
level: Type.String({ description: "日志级别", default: "info" }),
pretty: Type.Boolean({ description: "日志格式", default: false }),
Expand Down
7 changes: 5 additions & 2 deletions apps/portal-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,22 @@
"license": "Mulan PSL v2",
"repository": "https://github.com/PKUHPC/SCOW",
"dependencies": {
"@connectrpc/connect": "1.4.0",
"@ddadaal/tsgrpc-common": "0.2.5",
"@ddadaal/tsgrpc-server": "0.19.5",
"@ddadaal/tsgrpc-client": "0.17.7",
"@grpc/grpc-js": "1.10.6",
"@scow/config": "workspace:*",
"@scow/lib-config": "workspace:*",
"@scow/lib-scheduler-adapter": "workspace:*",
"@scow/lib-scowd": "workspace:*",
"@scow/lib-server": "workspace:*",
"@scow/lib-ssh": "workspace:*",
"@scow/protos": "workspace:*",
"@scow/rich-error-model": "workspace:*",
"@scow/scheduler-adapter-protos": "workspace:*",
"@scow/lib-scheduler-adapter": "workspace:*",
"@scow/scowd-protos": "workspace:*",
"@scow/utils": "workspace:*",
"@scow/rich-error-model": "workspace:*",
"@sinclair/typebox": "0.32.20",
"dayjs": "1.11.10",
"dotenv": "16.4.5",
Expand Down
5 changes: 3 additions & 2 deletions apps/portal-server/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,14 @@ export async function createServer() {
}

await server.register(appServiceServer);
await server.register(desktopServiceServer);
await server.register(jobServiceServer);
await server.register(fileServiceServer);
await server.register(shellServiceServer);
await server.register(staticConfigServiceServer);
await server.register(runtimeConfigServiceServer);
await server.register(dashboardServiceServer);
await server.register(fileServiceServer);
await server.register(desktopServiceServer);


if (process.env.NODE_ENV === "production") {
await checkClustersRootUserLogin(server.logger);
Expand Down
70 changes: 70 additions & 0 deletions apps/portal-server/src/clusterops/api/desktop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy
* SCOW is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

import { Logger } from "ts-log";

export interface CreateDesktopRequest {
loginNode: string;
userId: string;
wm: string;
desktopName: string;
}

export interface CreateDesktopReply {
host: string;
port: number;
password: string;
}

export interface KillDesktopRequest {
loginNode: string;
userId: string;
displayId: number;
}

export interface KillDesktopReply {}

export interface ConnectToDesktopRequest {
loginNode: string;
userId: string;
displayId: number;
}

export interface ConnectToDesktopReply {
host: string;
port: number;
password: string;
}

export interface ListUserDesktopsRequest {
userId: string;
loginNode: string;
}

export interface Desktop {
displayId: number;
desktopName: string;
wm: string;
createTime?: string;
}

export interface ListUserDesktopsReply {
host: string;
desktops: Desktop[]
}

export interface DesktopOps {
createDesktop(req: CreateDesktopRequest, logger: Logger): Promise<CreateDesktopReply>;
killDesktop(req: KillDesktopRequest, logger: Logger): Promise<KillDesktopReply>;
connectToDesktop(req: ConnectToDesktopRequest, logger: Logger): Promise<ConnectToDesktopReply>;
listUserDesktops(req: ListUserDesktopsRequest, logger: Logger): Promise<ListUserDesktopsReply>;
}
162 changes: 162 additions & 0 deletions apps/portal-server/src/clusterops/api/file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/**
* Copyright (c) 2022 Peking University and Peking University Institute for Computing and Digital Economy
* SCOW is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

import { ReaderExtensions } from "@ddadaal/tsgrpc-common";
import { ObjectWritable } from "@grpc/grpc-js/build/src/object-stream";
import { Logger } from "ts-log";

export interface CopyRequest {
userId: string;
fromPath: string;
toPath: string;
}

export interface CopyReply {}

export interface MoveRequest {
userId: string;
fromPath: string;
toPath: string;
}

export interface MoveReply {}

export interface ExistsRequest {
userId: string;
path: string;
}

export interface ExistsReply {
exists: boolean;
}


export interface CreateFileRequest {
userId: string;
path: string;
}

export interface CreateFileReply {}

export interface DeleteDirectoryRequest {
userId: string;
path: string;
}

export interface DeleteDirectoryReply {}

export interface DeleteFileRequest {
userId: string;
path: string;
}

export interface DeleteFileReply {}

export interface ReadDirectoryRequest {
userId: string;
path: string;
updateAccessTime?: boolean
}

export interface FileInfo {
name: string;
type: FileInfo_FileType;
mtime: string;
mode: number;
size: number;
}

export enum FileInfo_FileType {
FILE = 0,
DIR = 1,
}

export interface ReadDirectoryReply {
results: FileInfo[];
}


export interface GetHomeDirectoryRequest {
userId: string;
}

export interface GetHomeDirectoryReply {
path: string;
}

export interface MakeDirectoryRequest {
userId: string;
path: string;
}

export interface MakeDirectoryReply {}

export interface DownloadRequest {
userId: string;
path: string;
call: ObjectWritable<{ chunk: Uint8Array }>
}

export interface DownloadReply {}

interface UploadRequest_Info {
userId: string;
path: string;
}

interface UploadRequest_ReadStream {
message?: { $case: "info"; info: UploadRequest_Info } | { $case: "chunk"; chunk: Uint8Array } | undefined
}

export interface UploadRequest {
userId: string;
path: string;
call: ReaderExtensions<UploadRequest_ReadStream>
}

export interface UploadReply {
writtenBytes: number;
}

export interface GetFileMetadataRequest {
userId: string;
path: string;
}

export interface GetFileMetadataReply {
size: number;
type: string;
}

export interface FileOps {
copy(req: CopyRequest, logger: Logger): Promise<CopyReply>;
move(req: MoveRequest, logger: Logger): Promise<MoveReply>;
exists(req: ExistsRequest, logger: Logger): Promise<ExistsReply>;

createFile(req: CreateFileRequest, logger: Logger): Promise<CreateFileReply>;
deleteFile(req: DeleteFileRequest, logger: Logger): Promise<DeleteFileReply>;

readDirectory(req: ReadDirectoryRequest, logger: Logger): Promise<ReadDirectoryReply>;
deleteDirectory(req: DeleteDirectoryRequest, logger: Logger): Promise<DeleteDirectoryReply>;
getHomeDirectory(req: GetHomeDirectoryRequest, logger: Logger): Promise<GetHomeDirectoryReply>;
makeDirectory(req: MakeDirectoryRequest, logger: Logger): Promise<MakeDirectoryReply>;

upload(req: UploadRequest, logger: Logger): Promise<UploadReply>;
download(req: DownloadRequest, logger: Logger): Promise<DownloadReply>;

getFileMetadata(req: GetFileMetadataRequest, logger: Logger): Promise<GetFileMetadataReply>;

// StartFileTransfer(req: StartFileTransferRequest, logger: Logger): Promise<StartFileTransferReply>;
// QueryFileTransfer(req: QueryFileTransferRequest, logger: Logger): Promise<QueryFileTransferReply>;
// TerminateFileTransfer(req: TerminateFileTransferRequest, logger: Logger): Promise<TerminateFileTransferReply>;
// CheckTransferKey(req: CheckTransferKeyRequest, logger: Logger): Promise<CheckTransferKeyReply>;
}
4 changes: 4 additions & 0 deletions apps/portal-server/src/clusterops/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@
*/

import { AppOps } from "src/clusterops/api/app";
import { DesktopOps } from "src/clusterops/api/desktop";
import { FileOps } from "src/clusterops/api/file";
import { JobOps } from "src/clusterops/api/job";

export interface ClusterOps {
app: AppOps;
job: JobOps;
desktop: DesktopOps;
file: FileOps;
}
Loading
Loading