Skip to content

Commit

Permalink
feat(portal): 提交作业和提交交互式应用时显示可用分区 (#977)
Browse files Browse the repository at this point in the history
### 做了什么

修改提交作业和提交交互式应用时账户及分区获取逻辑
修改为选择的账户为用户可以使用的正常未封锁账户(账户状态未封锁,用户在账户下状态未封锁)
选择账户时获取该账户的可用分区并短暂保存
当切换集群或刷新账户或刷新分区的时候会重新发起请求获取新的数据

### 修改后提交作业页面

1.不使用模板值时
账户,分区,QOS为可选列表的第一项

![image](https://github.com/PKUHPC/SCOW/assets/43978285/1e646071-14eb-4655-9019-4f6b13a651e8)
集群,账户,分区发生变更时,重置下级关联项为可选列表第一项

![image](https://github.com/PKUHPC/SCOW/assets/43978285/8ade113c-78ec-433b-adac-60ecb2a511d6)

![image](https://github.com/PKUHPC/SCOW/assets/43978285/9b809d95-e596-47b0-ad6a-0696450018c9)
2.使用模板值时无论是否仍为当前可选列表中的值都可以直接填入

![image](https://github.com/PKUHPC/SCOW/assets/43978285/e2d6006e-54f9-4776-abc7-735b15ee5c15)
集群出现错误时会在页面直接报错

![image](https://github.com/PKUHPC/SCOW/assets/43978285/66c35b6f-ba57-44fe-9167-3d9e7511bb5f)
账户出现错误时当前为允许提交但是作业无法正常运行
分区等信息出现错误时会直接报错

![image](https://github.com/PKUHPC/SCOW/assets/43978285/f9c40a09-48e3-47b7-8969-c42a03e6ac61)
使用模板值时,集群,账户,分区任意值发生变化时,下级关联项目将重置为可选列表的第一项,
节点数gpu卡数等内容正常开始校验


### 修改后创建交互式应用页面

1. 没有上一次提交记录时
打开页面账户,分区,qos分别为可选列表的第一项

![image](https://github.com/PKUHPC/SCOW/assets/43978285/9d7cd8ae-6181-43bb-9687-4224dc67da6a)
适当选择填入不同值

![image](https://github.com/PKUHPC/SCOW/assets/43978285/c4ed7a76-0aef-46ca-b128-c902c381bf4c)
上一级条件发生变更时下一级条件重置为可选列表第一项,gpu卡数或节点数更新为默认值1

![image](https://github.com/PKUHPC/SCOW/assets/43978285/a84710fd-117d-4108-863e-07436d00f464)

2.当上一次提交记录存在
如果仍然为当前可选列表值则打开页面后正常填入
如果不可选则自动更新为可选列表的第一项
之后动作与1相同
  • Loading branch information
piccaSun authored Jun 19, 2024
1 parent 7285809 commit 0a43348
Show file tree
Hide file tree
Showing 23 changed files with 779 additions and 187 deletions.
8 changes: 8 additions & 0 deletions .changeset/four-timers-protect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@scow/portal-server": patch
"@scow/mis-server": patch
"@scow/portal-web": patch
"@scow/mis-web": patch
---

修改门户系统下提交作业或交互式应用时可以选择的账号为用户维度未封锁账号,分区为该用户在该集群下对应账号的可用分区;修改从模板提交作业时模板值可以直接提交
5 changes: 5 additions & 0 deletions .changeset/wise-boats-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@scow/grpc-api": minor
---

在 common/config 下新增 getAvailablePartitionsForCluster 作为门户/管理系统共用 proto,管理系统下原 proto 标记为已过时;在 listAccounts 下新增可选 AccountStatusFilter 查询参数
21 changes: 20 additions & 1 deletion apps/mis-server/src/services/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ import { status } from "@grpc/grpc-js";
import { getClusterConfigs } from "@scow/config/build/cluster";
import { convertClusterConfigsToServerProtoType, NO_CLUSTERS } from "@scow/lib-server";
import { scowErrorMetadata } from "@scow/lib-server/build/error";
import { libCheckActivatedClusters } from "@scow/lib-server/build/misCommon/clustersActivation";
import { ConfigServiceServer, ConfigServiceService } from "@scow/protos/build/common/config";
import { updateCluster } from "src/bl/clustersUtils";
import { getActivatedClusters, updateCluster } from "src/bl/clustersUtils";

export const configServiceServer = plugin((server) => {
server.addService<ConfigServiceServer>(ConfigServiceService, {
Expand All @@ -36,6 +37,24 @@ export const configServiceServer = plugin((server) => {
return [reply];
},

getAvailablePartitionsForCluster: async ({ request, em, logger }) => {

const { cluster, accountName, userId } = request;

// check cluster activation
const currentActivatedClusters = await getActivatedClusters(em, logger);
libCheckActivatedClusters({ clusterIds: cluster, activatedClusters: currentActivatedClusters, logger });

const reply = await server.ext.clusters.callOnOne(
cluster,
logger,
async (client) => await asyncClientCall(client.config, "getAvailablePartitions", {
accountName, userId,
}),
);
return [reply];

},

getClusterConfigFiles: async ({ em, logger }) => {

Expand Down
6 changes: 6 additions & 0 deletions apps/mis-server/src/services/misConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import { ClusterRuntimeInfo_LastActivationOperation,
import { getActivatedClusters, getClustersRuntimeInfo } from "src/bl/clustersUtils";
import { Cluster, ClusterActivationStatus } from "src/entities/Cluster";

/**
* @deprecated Use the new API function GetAvailablePartitionsForCluster From configServiceServer instead.
*/
export const misConfigServiceServer = plugin((server) => {
server.addService<ConfigServiceServer>(ConfigServiceService, {

Expand Down Expand Up @@ -47,6 +50,9 @@ export const misConfigServiceServer = plugin((server) => {
},


/**
* @deprecated Use the new API function GetAvailablePartitionsForCluster from ./config/configServiceServer instead.
*/
getAvailablePartitionsForCluster: async ({ request, logger }) => {

const { cluster, accountName, userId } = request;
Expand Down
4 changes: 2 additions & 2 deletions apps/mis-web/src/pages/api/job/getAvailableBillingTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import { typeboxRouteSchema } from "@ddadaal/next-typed-api-routes-runtime";
import { asyncClientCall } from "@ddadaal/tsgrpc-client";
import { ConfigServiceClient as MisConfigServerClient } from "@scow/protos/build/server/config";
import { ConfigServiceClient } from "@scow/protos/build/server/config";
import { JobBillingItem } from "@scow/protos/build/server/job";
import { UserStatus } from "@scow/protos/build/server/user";
import { Static, Type } from "@sinclair/typebox";
Expand Down Expand Up @@ -80,7 +80,7 @@ export const GetAvailableBillingTableSchema = typeboxRouteSchema({
export async function getAvailablePartitionForItems(
cluster: string, userId: string, tenantName: string): Promise<Partition[]> {

const client = getClient(MisConfigServerClient);
const client = getClient(ConfigServiceClient);

const statuses = await getUserStatus(userId, tenantName);

Expand Down
27 changes: 26 additions & 1 deletion apps/portal-server/src/services/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { status } from "@grpc/grpc-js";
import { getClusterConfigs } from "@scow/config/build/cluster";
import { checkSchedulerApiVersion, convertClusterConfigsToServerProtoType, NO_CLUSTERS } from "@scow/lib-server";
import { scowErrorMetadata } from "@scow/lib-server/build/error";
import { ConfigServiceServer, ConfigServiceService } from "@scow/protos/build/common/config";
import { ConfigServiceServer, ConfigServiceService, Partition } from "@scow/protos/build/common/config";
import { ConfigServiceServer as runTimeConfigServiceServer, ConfigServiceService as runTimeConfigServiceService }
from "@scow/protos/build/portal/config";
import { ApiVersion } from "@scow/utils/build/version";
Expand All @@ -39,6 +39,31 @@ export const staticConfigServiceServer = plugin((server) => {
return [reply];
},

getAvailablePartitionsForCluster: async ({ request, logger }) => {

const { cluster, accountName, userId } = request;
let availablePartitions: Partition[];

await checkActivatedClusters({ clusterIds: cluster });

try {
const resp = await callOnOne(
cluster,
logger,
async (client) => await asyncClientCall(client.config, "getAvailablePartitions", {
accountName, userId,
}),
);
availablePartitions = resp.partitions;
} catch (error) {
logger.error(`Error occured when query the available partitions of ${userId} in ${accountName}.`);
availablePartitions = [];
}

return [ { partitions: availablePartitions } ];
},


getClusterConfigFiles: async ({ logger }) => {

const clusterConfigs = getClusterConfigs(undefined, logger, ["hpc"]);
Expand Down
63 changes: 59 additions & 4 deletions apps/portal-server/src/services/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { Status } from "@grpc/grpc-js/build/src/constants";
import { jobInfoToPortalJobInfo, jobInfoToRunningjob } from "@scow/lib-scheduler-adapter";
import { checkSchedulerApiVersion } from "@scow/lib-server";
import { createDirectoriesRecursively, sftpReadFile, sftpStat, sftpWriteFile } from "@scow/lib-ssh";
import { JobServiceServer, JobServiceService } from "@scow/protos/build/portal/job";
import { AccountStatusFilter, JobServiceServer, JobServiceService } from "@scow/protos/build/portal/job";
import { parseErrorDetails } from "@scow/rich-error-model";
import { ApiVersion } from "@scow/utils/build/version";
import path, { join } from "path";
Expand Down Expand Up @@ -49,7 +49,7 @@ export const jobServiceServer = plugin((server) => {
},

listAccounts: async ({ request, logger }) => {
const { cluster, userId } = request;
const { cluster, userId, statusFilter } = request;
await checkActivatedClusters({ clusterIds: cluster });

const reply = await callOnOne(
Expand All @@ -60,7 +60,63 @@ export const jobServiceServer = plugin((server) => {
}),
);

return [{ accounts: reply.accounts }];
const accounts = reply.accounts;

if ((statusFilter === undefined) || statusFilter === AccountStatusFilter.ALL) {
return [{ accounts: accounts }];
}

const filteredUnblockedAccounts: string[] = [];
const filteredBlockedAccounts: string[] = [];
const filteredUnblockedUserAccounts: string[] = [];
const filteredBlockedUserAccounts: string[] = [];

const filterAccountPromise = Promise.allSettled(accounts.map(async (account) => {
try {
const resp = await callOnOne(
cluster,
logger,
async (client) => await asyncClientCall(client.account, "queryAccountBlockStatus", {
accountName: account,
}),
);
if (resp.blocked) {
filteredBlockedAccounts.push(account);
} else {
filteredUnblockedAccounts.push(account);
}
} catch (error) {
logger.error(`Error occured when query the block status of ${account}.`, error);
}
}));

const filterUserStatusPromise = Promise.allSettled(accounts.map(async (account) => {
try {
const resp = await callOnOne(
cluster,
logger,
async (client) => await asyncClientCall(client.user, "queryUserInAccountBlockStatus", {
accountName: account, userId,
}),
);
if (resp.blocked) {
filteredBlockedUserAccounts.push(account);
} else {
filteredUnblockedUserAccounts.push(account);
}
} catch (error) {
logger.error(`Error occured when query the block status of ${userId} in ${account}.`, error);
}
}));

await Promise.allSettled([filterAccountPromise, filterUserStatusPromise]);

const unblockAccounts =
filteredUnblockedAccounts.filter((account) => filteredUnblockedUserAccounts.includes(account));
const blockedAccounts = Array.from(new Set(filteredBlockedAccounts.concat(filteredBlockedUserAccounts)));

return [{ accounts:
statusFilter === AccountStatusFilter.BLOCKED_ONLY ? blockedAccounts : unblockAccounts }];
},

getJobTemplate: async ({ request, logger }) => {
Expand Down Expand Up @@ -324,7 +380,6 @@ export const jobServiceServer = plugin((server) => {
return [{ jobId: reply.jobId }];
},


});

});
3 changes: 3 additions & 0 deletions apps/portal-web/src/apis/api.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ export const mockApi: MockApi<typeof api> = {
terminateFileTransfer: null,
checkTransferKey: null,

getAvailablePartitionsForCluster: async () => ({ partitions: []}),
getClusterConfigFiles: async () => ({ clusterConfigs: {
hpc01: {
displayName: "hpc01Name",
Expand All @@ -300,3 +301,5 @@ export const mockApi: MockApi<typeof api> = {

};



2 changes: 2 additions & 0 deletions apps/portal-web/src/apis/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import type { CancelJobSchema } from "src/pages/api/job/cancelJob";
import type { DeleteJobTemplateSchema } from "src/pages/api/job/deleteJobTemplate";
import type { GetAccountsSchema } from "src/pages/api/job/getAccounts";
import type { GetAllJobsSchema } from "src/pages/api/job/getAllJobs";
import type { GetAvailablePartitionsForClusterSchema } from "src/pages/api/job/getAvailablePartitionsForCluster";
import type { GetJobTemplateSchema } from "src/pages/api/job/getJobTemplate";
import type { GetRunningJobsSchema } from "src/pages/api/job/getRunningJobs";
import type { ListJobTemplatesSchema } from "src/pages/api/job/listJobTemplates";
Expand Down Expand Up @@ -108,6 +109,7 @@ export const api = {
deleteJobTemplate: apiClient.fromTypeboxRoute<typeof DeleteJobTemplateSchema>("DELETE", "/api/job/deleteJobTemplate"),
getAccounts: apiClient.fromTypeboxRoute<typeof GetAccountsSchema>("GET", "/api/job/getAccounts"),
getAllJobs: apiClient.fromTypeboxRoute<typeof GetAllJobsSchema>("GET", "/api/job/getAllJobs"),
getAvailablePartitionsForCluster: apiClient.fromTypeboxRoute<typeof GetAvailablePartitionsForClusterSchema>("GET", "/api/job/getAvailablePartitionsForCluster"),
getJobTemplate: apiClient.fromTypeboxRoute<typeof GetJobTemplateSchema>("GET", "/api/job/getJobTemplate"),
getRunningJobs: apiClient.fromTypeboxRoute<typeof GetRunningJobsSchema>("GET", "/api/job/getRunningJobs"),
listJobTemplates: apiClient.fromTypeboxRoute<typeof ListJobTemplatesSchema>("GET", "/api/job/listJobTemplates"),
Expand Down
4 changes: 4 additions & 0 deletions apps/portal-web/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ export default {
selectAccountPlaceholder: "Select Account",
refreshAccountList: "Refresh Account List",
},
partitionSelector: {
selectPartitionPlaceholder: "Select Partition",
refreshPartitionList: "Refresh Partition List",
},
allJobsTable: {
searchForm: {
clusterLabel: "Cluster",
Expand Down
6 changes: 5 additions & 1 deletion apps/portal-web/src/i18n/zh_cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ export default {
selectAccountPlaceholder: "请选择账户",
refreshAccountList: "刷新账户列表",
},
partitionSelector: {
selectPartitionPlaceholder: "请选择分区",
refreshPartitionList: "刷新分区列表",
},
allJobsTable: {
searchForm: {
clusterLabel: "集群",
Expand Down Expand Up @@ -185,7 +189,7 @@ export default {

wdTooltip2: "2. 填写目录不可访问或者不可操作时,提交作业或者作业运行将失败;",

wdTooltip3: "2.该文件用于保存适配器返回的脚本,默认值参考输出文件。",
wdTooltip3: "该文件用于保存适配器返回的脚本,默认值参考输出文件。",

output: "标准输出文件",
errorOutput: "错误输出文件",
Expand Down
5 changes: 5 additions & 0 deletions apps/portal-web/src/models/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,9 @@ export function formatTime(milliseconds: number) {
return text;
}

export enum AccountStatusFilter {
ALL = 0,
BLOCKED_ONLY = 1,
UNBLOCKED_ONLY = 2,
};

Loading

0 comments on commit 0a43348

Please sign in to comment.