Skip to content

Commit

Permalink
Feat runtime (#5280)
Browse files Browse the repository at this point in the history
* add-runtime

feat:devbox template

* fix:devbox template merge

* fix:devbox style & add migrations

* feat: add version manage

* fix(devbox):fix network update

* fix(devbox):show cname error

* chore(devbox): add postinstall for prisma

* fix(devbox): image build error

* chore(devbox):remove comment
  • Loading branch information
xudaotutou authored Dec 24, 2024
1 parent f365048 commit dade357
Show file tree
Hide file tree
Showing 137 changed files with 7,687 additions and 2,134 deletions.
12 changes: 11 additions & 1 deletion frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions frontend/providers/devbox/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ DEVBOX_AFFINITY_ENABLE=
SQUASH_ENABLE=
NODE_TLS_REJECT_UNAUTHORIZED=
ROOT_RUNTIME_NAMESPACE=
DATABASE_URL=
RETAG_SVC_URL=
PRIVACY_URL=
2 changes: 2 additions & 0 deletions frontend/providers/devbox/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

prisma/generated
49 changes: 28 additions & 21 deletions frontend/providers/devbox/api/devbox.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
import { V1Deployment, V1Pod, V1StatefulSet } from '@kubernetes/client-node'

import { DELETE, GET, POST } from '@/services/request'
import { GetDevboxByNameReturn } from '@/types/adapt'
import {
DevboxEditType,
DevboxListItemType,
DevboxEditTypeV2,
DevboxListItemTypeV2,
DevboxPatchPropsType,
DevboxVersionListItemType,
runtimeNamespaceMapType
DevboxVersionListItemType
} from '@/types/devbox'
import { KBDevboxReleaseType, KBDevboxTypeV2 } from '@/types/k8s'
import { MonitorDataResult, MonitorQueryKey } from '@/types/monitor'
import {
adaptAppListItem,
adaptDevboxDetail,
adaptDevboxListItem,
adaptDevboxDetailV2,
adaptDevboxListItemV2,
adaptDevboxVersionListItem,
adaptPod
} from '@/utils/adapt'
import { GET, POST, DELETE } from '@/services/request'
import { KBDevboxType, KBDevboxReleaseType } from '@/types/k8s'
import { MonitorDataResult, MonitorQueryKey } from '@/types/monitor'

export const getMyDevboxList = () =>
GET<KBDevboxType[]>('/api/getDevboxList').then((data): DevboxListItemType[] =>
data.map(adaptDevboxListItem).sort((a, b) => {
GET<[KBDevboxTypeV2, {
templateRepository: {
iconId: string | null;
};
uid: string;
}][]>('/api/getDevboxList').then((data): DevboxListItemTypeV2[] =>
data.map(adaptDevboxListItemV2).sort((a, b) => {
return new Date(b.createTime).getTime() - new Date(a.createTime).getTime()
})
)
export const getDevboxByName = (devboxName: string) =>
GET<KBDevboxType & { portInfos: any[] }>('/api/getDevboxByName', { devboxName }).then((data) =>
adaptDevboxDetail(data)
)
GET<GetDevboxByNameReturn>('/api/getDevboxByName', { devboxName }).then(adaptDevboxDetailV2)

export const applyYamlList = (yamlList: string[], type: 'create' | 'replace' | 'update') =>
POST('/api/applyYamlList', { yamlList, type })

export const createDevbox = (payload: {
devboxForm: DevboxEditType
runtimeNamespaceMap: runtimeNamespaceMapType
devboxForm: DevboxEditTypeV2
}) => POST(`/api/createDevbox`, payload)

export const updateDevbox = (payload: { patch: DevboxPatchPropsType; devboxName: string }) =>
Expand Down Expand Up @@ -69,8 +71,16 @@ export const editDevboxVersion = (data: { name: string; releaseDes: string }) =>
export const delDevboxVersionByName = (versionName: string) =>
DELETE('/api/delDevboxVersionByName', { versionName })

export const getSSHConnectionInfo = (data: { devboxName: string; runtimeName: string }) =>
GET('/api/getSSHConnectionInfo', data)
export const getSSHConnectionInfo = (data: { devboxName: string }) =>
GET<{
base64PublicKey: string;
base64PrivateKey: string;
token: string;
userName: string;
workingDir: string;
releaseCommand: string;
releaseArgs: string;
}>('/api/getSSHConnectionInfo', data)

export const getDevboxPodsByDevboxName = (name: string) =>
GET<V1Pod[]>('/api/getDevboxPodsByDevboxName', { name }).then((item) => item.map(adaptPod))
Expand All @@ -81,9 +91,6 @@ export const getDevboxMonitorData = (payload: {
step: string
}) => GET<MonitorDataResult[]>(`/api/monitor/getMonitorData`, payload)

export const getSSHRuntimeInfo = (runtimeName: string) =>
GET('/api/getSSHRuntimeInfo', { runtimeName })

export const getAppsByDevboxId = (devboxId: string) =>
GET<V1Deployment & V1StatefulSet[]>('/api/getAppsByDevboxId', { devboxId }).then((res) =>
res.map(adaptAppListItem)
Expand Down
132 changes: 132 additions & 0 deletions frontend/providers/devbox/api/template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { Tag, TemplateRepositoryKind } from "@/prisma/generated/client";
import { DELETE, GET, POST } from "@/services/request";
import { CreateTemplateRepositoryType, UpdateTemplateRepositoryType, UpdateTemplateType } from "@/utils/vaildate";

export const listOfficialTemplateRepository = () => GET<{
templateRepositoryList: {
uid: string;
name: string;
kind: TemplateRepositoryKind;
iconId: string;
description: string | null;
}[]
}>(`/api/templateRepository/listOfficial`)
export const listTemplateRepository = (page: {
page: number,
pageSize: number,
}, tags?: string[], search?: string) => {
const searchParams = new URLSearchParams()
if (tags && tags.length > 0) {
tags.forEach((tag) => {
searchParams.append('tags', tag)
})
}
searchParams.append('page', page.page.toString())
searchParams.append('pageSize', page.pageSize.toString())
if (search) searchParams.append('search', search)
return GET<{
templateRepositoryList: {
uid: string;
name: string;
description: string | null;
iconId: string | null;
templates: {
uid: string;
name: string;
}[];
templateRepositoryTags: {
tag: Tag;
}[];
}[],
page: {
page: number,
pageSize: number,
totalItems: number,
totalPage: number,
}
}>(`/api/templateRepository/list?${searchParams.toString()}`)

}
export const listPrivateTemplateRepository = ({
search,
page,
pageSize,
}: {
search?: string,
page?: number,
pageSize?: number,
} = {}) => {
const searchParams = new URLSearchParams()

if (search) searchParams.append('search', search)
if (page) searchParams.append('page', page.toString())
if (pageSize) searchParams.append('pageSize', pageSize.toString())
return GET<{
templateRepositoryList: {
uid: string;
name: string;
description: string | null;
iconId: string | null;
templates: {
uid: string;
name: string;
}[];
isPublic: boolean;
templateRepositoryTags: {
tag: Tag;
}[];
}[],
page: {
page: number,
pageSize: number,
totalItems: number,
totalPage: number,
}
}>(`/api/templateRepository/listPrivate?${searchParams.toString()}`)
}

export const getTemplateRepository = (uid: string) => GET<{
templateRepository: {
templates: {
name: string;
uid: string;
}[];
uid: string;
isPublic: true;
name: string;
description: string | null;
iconId: string | null;
templateRepositoryTags: {
tag: Tag;
}[];
}
}>(`/api/templateRepository/get?uid=${uid}`)
export const getTemplateConfig = (uid: string) => GET<{
template: {
name: string;
uid: string;
config: string;
}
}>(`/api/templateRepository/template/getConfig?uid=${uid}`)
export const listTemplate = (templateRepositoryUid: string) => GET<{
templateList: {
uid: string;
name: string;
config: string;
image: string;
createAt: Date;
updateAt: Date;
}[]
}>(`/api/templateRepository/template/list?templateRepositoryUid=${templateRepositoryUid}`)
export const listTag = () => GET<{
tagList: Tag[]
}>(`/api/templateRepository/tag/list`)

export const createTemplateReposistory = (data: CreateTemplateRepositoryType) => POST(`/api/templateRepository/withTemplate/create`, data)
export const initUser = () => POST<string>(`/api/auth/init`)

export const deleteTemplateRepository = (templateRepositoryUid: string) => DELETE(`/api/templateRepository/delete?templateRepositoryUid=${templateRepositoryUid}`)

export const updateTemplateReposistory = (data: UpdateTemplateRepositoryType) => POST(`/api/templateRepository/update`, data)
export const updateTemplate = (data: UpdateTemplateType) => POST(`/api/templateRepository/withTemplate/update`, data)
export const deleteTemplate = (templateUid: string) => DELETE(`/api/templateRepository/template/delete?uid=${templateUid}`)
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import MyIcon from "@/components/Icon";
import { TemplateState } from "@/constants/template";
import { usePathname, useRouter } from "@/i18n";
import { useTemplateStore } from "@/stores/template";
import { Box, Button, Center, Flex, Text, useTheme } from "@chakra-ui/react";
import { useTranslations } from "next-intl";
import { useEffect } from "react";

export default function DevboxHeader({ listLength }: { listLength: number }) {
const { openTemplateModal, config, updateTemplateModalConfig } = useTemplateStore()
const theme = useTheme()
const router = useRouter()
const t = useTranslations()
const pathname = usePathname()
const lastRoute = '/?openTemplate=publicTemplate'
useEffect(() => {
const refreshLastRoute = '/'
if (config.lastRoute.includes('openTemplate')) {
openTemplateModal({
...config,
lastRoute: refreshLastRoute
})
} else {
updateTemplateModalConfig({
...config,
lastRoute: refreshLastRoute
})
}
}, [])
return <Flex h={'90px'} alignItems={'center'}>
<Center
mr={'16px'}
width={'46px'}
bg={'#FFF'}
height={'46px'}
border={theme.borders.base}
borderRadius={'md'}>
<MyIcon name="logo" w={'30px'} h={'30px'} />
</Center>
<Box fontSize={'xl'} color={'grayModern.900'} fontWeight={'bold'}>
{t('devbox_list')}
</Box>
<Box ml={'8px'} fontSize={'md'} fontWeight={'bold'} color={'grayModern.500'}>
( {listLength} )
</Box>
<Flex
alignItems="center"
justifyContent="center"
height="18px"
borderRadius="6px"
gap="4px"
mr={'20px'}
ml={'auto'}
cursor="pointer"
onClick={() => {
// setLastRoute(pathname)
openTemplateModal({
'templateState': TemplateState.publicTemplate,
lastRoute,
})
}}
>
<MyIcon
name={'templateTitle'}
width="18px"
height="18px"
color='brightBlue.600'
fill={"currentColor"}
/>
<Text
fontFamily="PingFang SC"
fontSize="12px"
fontWeight="500"
lineHeight="16px"
letterSpacing="0.5px"
color='brightBlue.600'
>
{t("scan_templates")}
</Text>
</Flex>
<Button
minW={'156px'}
h={'40px'}
variant={'solid'}
leftIcon={<MyIcon name={'plus'} w={'20px'} fill={'#ffffff'} />}
onClick={() => router.push('/devbox/create')}>
{t('create_devbox')}
</Button>
</Flex>;
}
Loading

0 comments on commit dade357

Please sign in to comment.