Skip to content

Commit

Permalink
feat: PrivilegedContainer for challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Sep 18, 2022
1 parent 566d8b2 commit ae172e4
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 1,158 deletions.
1,365 changes: 227 additions & 1,138 deletions GZCTF/ClientApp/src/Api.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion GZCTF/ClientApp/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { useLocalStorage } from '@mantine/hooks'
import { ModalsProvider } from '@mantine/modals'
import { NotificationsProvider } from '@mantine/notifications'
import { ThemeOverride } from '@Utils/ThemeOverride'
import { fetcher } from "@Api";
import { fetcher } from '@Api'

export const App: FC = () => {
const [colorScheme, setColorScheme] = useLocalStorage<ColorScheme>({
Expand Down
6 changes: 3 additions & 3 deletions GZCTF/ClientApp/src/components/admin/FlagEditPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import {
SimpleGrid,
Input,
} from '@mantine/core'
import { useClipboard } from '@mantine/hooks'
import { showNotification } from '@mantine/notifications'
import { mdiCheck, mdiDeleteOutline } from '@mdi/js'
import { Icon } from '@mdi/react'
import { Attachment, FlagInfoModel } from '@Api'
import { useClipboard } from '@mantine/hooks'
import { showNotification } from '@mantine/notifications'

interface FlagCardProps {
flag: FlagInfoModel
Expand Down Expand Up @@ -50,7 +50,7 @@ const FlagCard: FC<FlagCardProps> = ({ flag, onDelete, unifiedAttachment }) => {
},
wrapper: {
width: '100%',
}
},
}}
/>
<Text color="dimmed" size="sm" style={{ fontFamily: theme.fontFamilyMonospace }}>
Expand Down
2 changes: 1 addition & 1 deletion GZCTF/ClientApp/src/pages/account/Confirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Confirm: FC = () => {
const sp = new URLSearchParams(location.search)
const token = sp.get('token')
const email = sp.get('email')
const runOnce = useRef(false);
const runOnce = useRef(false)

usePageTitle('邮箱验证')

Expand Down
7 changes: 4 additions & 3 deletions GZCTF/ClientApp/src/pages/account/Verify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ const Verify: FC = () => {
const token = sp.get('token')
const email = sp.get('email')
const navigate = useNavigate()
const runOnce = useRef(false);
const runOnce = useRef(false)

usePageTitle('账户验证')

useEffect(() => {
if (token && email && !runOnce.current ) {
if (token && email && !runOnce.current) {
runOnce.current = true
api.account
.accountVerify({ token, email })
Expand All @@ -40,7 +40,8 @@ const Verify: FC = () => {
icon: <Icon path={mdiClose} size={1} />,
disallowClose: true,
})
}).finally(() => {
})
.finally(() => {
navigate('/account/login')
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
TextInput,
Grid,
Code,
Switch,
} from '@mantine/core'
import { useClipboard } from '@mantine/hooks'
import { useModals } from '@mantine/modals'
Expand All @@ -28,6 +29,7 @@ import {
import { Icon } from '@mdi/react'
import HintList from '@Components/HintList'
import ScoreFunc from '@Components/admin/ScoreFunc'
import { SwitchLabel } from '@Components/admin/SwitchLabel'
import WithGameEditTab from '@Components/admin/WithGameEditTab'
import { showErrorNotification } from '@Utils/ApiErrorHandler'
import {
Expand Down Expand Up @@ -139,7 +141,10 @@ const GameChallengeEdit: FC = () => {
if (!challenge?.testContainer) {
if (
challenge.containerImage !== challengeInfo.containerImage ||
challenge.containerExposePort !== challengeInfo.containerExposePort
challenge.containerExposePort !== challengeInfo.containerExposePort ||
challenge.memoryLimit !== challengeInfo.memoryLimit ||
challenge.cpuCount !== challengeInfo.cpuCount ||
challenge.privilegedContainer !== challengeInfo.privilegedContainer
)
onUpdate(challengeInfo)?.then(onCreateTestContainer)
else onCreateTestContainer()
Expand Down Expand Up @@ -353,8 +358,8 @@ const GameChallengeEdit: FC = () => {
/>
)}
{(type === ChallengeType.StaticContainer || type === ChallengeType.DynamicContainer) && (
<Grid>
<Grid.Col span={8}>
<Grid columns={9}>
<Grid.Col span={6}>
<TextInput
label="容器镜像"
disabled={disabled}
Expand All @@ -375,14 +380,14 @@ const GameChallengeEdit: FC = () => {
}
/>
</Grid.Col>
<Grid.Col span={4}>
<Grid.Col span={3}>
<Group spacing={0} align="center" pt={22} style={{ height: '100%' }}>
{challenge?.testContainer ? (
<Code
sx={(theme) => ({
backgroundColor: 'transparent',
fontSize: theme.fontSizes.sm,
fontWeight: 'bold'
fontWeight: 'bold',
})}
onClick={() => clipBoard.copy(challenge?.testContainer?.entry ?? '')}
>
Expand All @@ -395,7 +400,7 @@ const GameChallengeEdit: FC = () => {
)}
</Group>
</Grid.Col>
<Grid.Col span={4}>
<Grid.Col span={2}>
<NumberInput
label="服务端口"
min={1}
Expand All @@ -408,7 +413,7 @@ const GameChallengeEdit: FC = () => {
onChange={(e) => setChallengeInfo({ ...challengeInfo, containerExposePort: e })}
/>
</Grid.Col>
<Grid.Col span={4}>
<Grid.Col span={2}>
<NumberInput
label="CPU 数量限制"
min={1}
Expand All @@ -421,7 +426,7 @@ const GameChallengeEdit: FC = () => {
onChange={(e) => setChallengeInfo({ ...challengeInfo, cpuCount: e })}
/>
</Grid.Col>
<Grid.Col span={4}>
<Grid.Col span={2}>
<NumberInput
label="内存限制 (MB)"
min={64}
Expand All @@ -434,6 +439,17 @@ const GameChallengeEdit: FC = () => {
onChange={(e) => setChallengeInfo({ ...challengeInfo, memoryLimit: e })}
/>
</Grid.Col>
<Grid.Col span={3}>
<Switch
style={{ marginTop: '1rem' }}
disabled={disabled}
checked={challengeInfo.privilegedContainer ?? false}
label={SwitchLabel('特权容器', '以特权模式运行容器,Swarm 不受支持')}
onChange={(e) =>
setChallengeInfo({ ...challengeInfo, privilegedContainer: e.target.checked })
}
/>
</Grid.Col>
</Grid>
)}
</Stack>
Expand Down
2 changes: 1 addition & 1 deletion GZCTF/ClientApp/src/pages/games/[id]/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ const GameDetail: FC = () => {
你已经以队伍 "{game?.teamName}" 成员身份成功报名,请耐心等待比赛开始。
</Alert>
)}
<MarkdownRender source={game?.content ?? ''} style={{ marginBottom: 100 }}/>
<MarkdownRender source={game?.content ?? ''} style={{ marginBottom: 100 }} />
</Stack>
<GameJoinModal
title="补全报名信息"
Expand Down
5 changes: 5 additions & 0 deletions GZCTF/Models/Internal/ContainerConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public class ContainerConfig
/// </summary>
public string? Flag { get; set; } = string.Empty;

/// <summary>
/// 是否为特权容器
/// </summary>
public bool PrivilegedContainer { get; set; } = false;

/// <summary>
/// 内存限制(MB)
/// </summary>
Expand Down
3 changes: 2 additions & 1 deletion GZCTF/Repositories/InstanceRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,13 @@ public async Task<TaskResult<Container>> CreateContainer(Instance instance, Team
await context.Entry(instance).Reference(e => e.FlagContext).LoadAsync(token);
var container = await service.CreateContainer(new ContainerConfig()
{
CPUCount = instance.Challenge.CPUCount ?? 1,
TeamId = team.Id.ToString(),
UserId = userId,
Flag = instance.FlagContext?.Flag, // static challenge has no specific flag
Image = instance.Challenge.ContainerImage,
CPUCount = instance.Challenge.CPUCount ?? 1,
MemoryLimit = instance.Challenge.MemoryLimit ?? 64,
PrivilegedContainer = instance.Challenge.PrivilegedContainer ?? false,
ExposedPort = instance.Challenge.ContainerExposePort ?? throw new ArgumentException("创建容器时遇到无效的端口"),
}, token);

Expand Down
5 changes: 3 additions & 2 deletions GZCTF/Services/DockerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ private CreateContainerParameters GetCreateContainerParameters(ContainerConfig c
{
PublishAllPorts = true,
Memory = config.MemoryLimit * 1024 * 1024,
CPUCount = 1
CPUCount = 1,
Privileged = config.PrivilegedContainer
}
};

Expand Down Expand Up @@ -128,7 +129,7 @@ private ServiceCreateParameters GetServiceCreateParameters(ContainerConfig confi
{
MemoryBytes = config.MemoryLimit * 1024 * 1024,
NanoCPUs = config.CPUCount * 10_0000_0000,
}
},
},
}
}
Expand Down
4 changes: 4 additions & 0 deletions GZCTF/Services/K8sService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ public K8sService(IOptions<RegistryConfig> _registry, ILogger<K8sService> logger
Name = name,
Image = config.Image,
ImagePullPolicy = "Always",
SecurityContext = new()
{
Privileged = config.PrivilegedContainer
},
Env = config.Flag is null ? new List<V1EnvVar>() : new[]
{
new V1EnvVar("GZCTF_FLAG", config.Flag)
Expand Down

0 comments on commit ae172e4

Please sign in to comment.