feat: deploy support
This commit is contained in:
parent
87d5506085
commit
1365e54aec
8
.dockerignore
Normal file
8
.dockerignore
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# top
|
||||||
|
/woj
|
||||||
|
|
||||||
|
# runner
|
||||||
|
resource/runner/.mark.container
|
||||||
|
resource/runner/problem/*
|
||||||
|
resource/runner/tmp/*
|
||||||
|
resource/runner/user/*
|
25
.idea/jsonSchemas.xml
Normal file
25
.idea/jsonSchemas.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JsonSchemaMappingsProjectConfiguration">
|
||||||
|
<state>
|
||||||
|
<map>
|
||||||
|
<entry key="docker-compose.yml">
|
||||||
|
<value>
|
||||||
|
<SchemaInfo>
|
||||||
|
<option name="name" value="docker-compose.yml" />
|
||||||
|
<option name="relativePathToSchema" value="https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json" />
|
||||||
|
<option name="applicationDefined" value="true" />
|
||||||
|
<option name="patterns">
|
||||||
|
<list>
|
||||||
|
<Item>
|
||||||
|
<option name="path" value="docker-compose.yml" />
|
||||||
|
</Item>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</SchemaInfo>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
|
</project>
|
13
Makefile
13
Makefile
@ -1,8 +1,12 @@
|
|||||||
GO := go
|
GO := go
|
||||||
|
|
||||||
LDFLAGS += -X cmd.BuildTime=$(shell date -u '+%Y-%m-%d-%I-%M-%S')
|
PKG_BASE := $(shell head -n 1 go.mod | awk '{print $$2}')
|
||||||
LDFLAGS += -X cmd.Version=$(shell cat VERSION)+$(shell git rev-parse --short HEAD)
|
BUILD_TIME := $(shell date -u '+%Y%m%d-%I%M%S')
|
||||||
LDFLAGS += -X cmd.SentryDSN=$(shell cat dsn.txt)
|
VERSION := $(shell cat VERSION)+$(shell git rev-parse --short HEAD)
|
||||||
|
|
||||||
|
LDFLAGS += -X $(PKG_BASE)/cmd.BuildTime=$(BUILD_TIME)
|
||||||
|
LDFLAGS += -X $(PKG_BASE)/cmd.Version=$(VERSION)
|
||||||
|
LDFLAGS += -X $(PKG_BASE)/cmd.SentryDSN=$(shell cat dsn.txt)
|
||||||
LDFLAGS += -s -w
|
LDFLAGS += -s -w
|
||||||
|
|
||||||
GOBUILD := $(GO) build -ldflags '$(LDFLAGS)'
|
GOBUILD := $(GO) build -ldflags '$(LDFLAGS)'
|
||||||
@ -18,8 +22,7 @@ build: swagger dep
|
|||||||
$(GOBUILD) -o woj ./cmd/woj
|
$(GOBUILD) -o woj ./cmd/woj
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f runner
|
rm -f woj
|
||||||
rm -f server
|
|
||||||
|
|
||||||
dep:
|
dep:
|
||||||
go mod download
|
go mod download
|
||||||
|
35
Runner.Dockerfile
Normal file
35
Runner.Dockerfile
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# builder
|
||||||
|
FROM docker.io/library/golang:alpine AS builder
|
||||||
|
|
||||||
|
ENV GOPROXY=https://goproxy.cn
|
||||||
|
WORKDIR /builder
|
||||||
|
|
||||||
|
RUN apk add --no-cache git make
|
||||||
|
RUN go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
|
|
||||||
|
COPY go.mod /builder/go.mod
|
||||||
|
COPY go.sum /builder/go.sum
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
COPY . /builder
|
||||||
|
RUN make build
|
||||||
|
|
||||||
|
|
||||||
|
# main image
|
||||||
|
FROM quay.io/podman/stable
|
||||||
|
|
||||||
|
# pkill
|
||||||
|
RUN yum -y install jq procps-ng && yum -y clean all && rm -rf /var/cache
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# prepare images
|
||||||
|
COPY --from=builder /builder/resource/runner /app/resource/runner
|
||||||
|
RUN bash -c "cd /app/resource/runner/scripts && ./prepare_images.sh save"
|
||||||
|
|
||||||
|
# sources
|
||||||
|
COPY --from=builder /builder/config.docker.yaml /app
|
||||||
|
COPY --from=builder /builder/docker-entrypoint.sh /app
|
||||||
|
COPY --from=builder /builder/woj /app
|
||||||
|
|
||||||
|
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|
@ -1,5 +1,5 @@
|
|||||||
# builder
|
# builder
|
||||||
FROM golang:alpine AS builder
|
FROM docker.io/library/golang:alpine AS builder
|
||||||
|
|
||||||
ENV GOPROXY=https://goproxy.cn
|
ENV GOPROXY=https://goproxy.cn
|
||||||
WORKDIR /builder
|
WORKDIR /builder
|
||||||
@ -16,16 +16,14 @@ RUN make build
|
|||||||
|
|
||||||
|
|
||||||
# main image
|
# main image
|
||||||
FROM alpine:latest
|
FROM docker.io/library/alpine
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN apk --no-cache add tzdata ca-certificates libc6-compat
|
RUN apk --no-cache add tzdata ca-certificates libc6-compat bash
|
||||||
|
|
||||||
COPY --from=builder /builder/config.docker.yaml /app
|
COPY --from=builder /builder/config.docker.yaml /app
|
||||||
COPY --from=builder /builder/docker-entrypoint.sh /app
|
COPY --from=builder /builder/docker-entrypoint.sh /app
|
||||||
COPY --from=builder /builder/resource/frontend /app/resource/frontend
|
COPY --from=builder /builder/resource/frontend /app/resource/frontend
|
||||||
COPY --from=builder /builder/resource/runner /app/resource/runner
|
|
||||||
|
|
||||||
COPY --from=builder /builder/woj /app
|
COPY --from=builder /builder/woj /app
|
||||||
|
|
||||||
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|
57
build_image.sh
Executable file
57
build_image.sh
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
. resource/runner/scripts/common.sh
|
||||||
|
|
||||||
|
# version
|
||||||
|
VERSION="$(cat VERSION)"
|
||||||
|
log_info "VERSION: $VERSION"
|
||||||
|
|
||||||
|
function build_base() {
|
||||||
|
log_info "[+] Building Base Images"
|
||||||
|
pushd resource/runner/scripts || exit 1
|
||||||
|
$DOCKER build -t git.0x7f.app/woj/ubuntu-full:latest -f scripts/ubuntu-full.Dockerfile . ||
|
||||||
|
(log_error "Build Full Image failed" && exit 1)
|
||||||
|
$DOCKER build -t git.0x7f.app/woj/ubuntu-run:latest -f scripts/ubuntu-run.Dockerfile . ||
|
||||||
|
(log_error "Build Tiny Image failed" && exit 1)
|
||||||
|
popd
|
||||||
|
}
|
||||||
|
|
||||||
|
function push_base() {
|
||||||
|
log_info "[+] Pushing Base Images"
|
||||||
|
$DOCKER push "git.0x7f.app/woj/ubuntu-full:latest"
|
||||||
|
$DOCKER push "git.0x7f.app/woj/ubuntu-run:latest"
|
||||||
|
}
|
||||||
|
|
||||||
|
function build_server() {
|
||||||
|
log_info "[+] Building Server"
|
||||||
|
$DOCKER build -t "git.0x7f.app/woj/woj-server:$VERSION" -f Server.Dockerfile . ||
|
||||||
|
(log_error "[!] Failed to build Server" && exit 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
function build_runner() {
|
||||||
|
log_info "[+] Building Runner"
|
||||||
|
$DOCKER build \
|
||||||
|
--cap-add=sys_admin,mknod \
|
||||||
|
--device=/dev/fuse \
|
||||||
|
--security-opt label=disable \
|
||||||
|
-t "git.0x7f.app/woj/woj-runner:$VERSION" \
|
||||||
|
-f Runner.Dockerfile . ||
|
||||||
|
(log_error "[!] Failed to build Runner" && exit 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
function push_server() {
|
||||||
|
log_info "[+] Pushing Server Images"
|
||||||
|
$DOCKER push "git.0x7f.app/woj/woj-server:$VERSION"
|
||||||
|
}
|
||||||
|
|
||||||
|
function push_runner() {
|
||||||
|
log_info "[+] Pushing Runner Images"
|
||||||
|
$DOCKER push "git.0x7f.app/woj/woj-runner:$VERSION"
|
||||||
|
}
|
||||||
|
|
||||||
|
# build_base
|
||||||
|
# push_base
|
||||||
|
build_server
|
||||||
|
push_server
|
||||||
|
build_runner
|
||||||
|
push_runner
|
@ -59,7 +59,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getBuildTime() time.Time {
|
func getBuildTime() time.Time {
|
||||||
build, err := time.Parse("2006-01-02-15-04-05", BuildTime)
|
build, err := time.Parse("20060102-150405", BuildTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("failed to parse build time: %v", err)
|
log.Printf("failed to parse build time: %v", err)
|
||||||
build = time.Now()
|
build = time.Now()
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
version: "3"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
server:
|
server:
|
||||||
build: .
|
image: git.0x7f.app/woj/woj-server:1.1.0
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "wget", "-q", "http://127.0.0.1:8000/health" ]
|
test: [ "CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:8000/health" ]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
command: web
|
command: web
|
||||||
environment:
|
environment:
|
||||||
@ -14,7 +12,7 @@ services:
|
|||||||
- DATABASE_USER=dev
|
- DATABASE_USER=dev
|
||||||
- DATABASE_PASSWORD=password
|
- DATABASE_PASSWORD=password
|
||||||
- DATABASE_NAME=dev
|
- DATABASE_NAME=dev
|
||||||
- STORAGE_ENDPOINT=minio:9000
|
- STORAGE_ENDPOINT=storage:9000
|
||||||
- STORAGE_ACCESS_KEY=access_key
|
- STORAGE_ACCESS_KEY=access_key
|
||||||
- STORAGE_SECRET_KEY=secret_key
|
- STORAGE_SECRET_KEY=secret_key
|
||||||
- STORAGE_BUCKET=woj
|
- STORAGE_BUCKET=woj
|
||||||
@ -23,6 +21,8 @@ services:
|
|||||||
- /etc/timezone:/etc/timezone:ro
|
- /etc/timezone:/etc/timezone:ro
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
depends_on:
|
depends_on:
|
||||||
|
runner:
|
||||||
|
condition: service_started
|
||||||
storage:
|
storage:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
cache:
|
cache:
|
||||||
@ -32,22 +32,36 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
|
|
||||||
#runner:
|
runner:
|
||||||
# build: .
|
image: git.0x7f.app/woj/woj-runner:1.1.0
|
||||||
# restart: unless-stopped
|
restart: unless-stopped
|
||||||
# command: runner
|
command: runner
|
||||||
# environment:
|
security_opt:
|
||||||
# - REDIS_ADDRESS_PORT=cache:6379
|
- "label=disable"
|
||||||
# - DEVELOPMENT=true
|
cap_add:
|
||||||
# volumes:
|
- SYS_ADMIN
|
||||||
# - runner:/app/resource/runner/user
|
- MKNOD
|
||||||
# - /etc/timezone:/etc/timezone:ro
|
devices:
|
||||||
# - /etc/localtime:/etc/localtime:ro
|
- "/dev/fuse"
|
||||||
# depends_on:
|
environment:
|
||||||
# - cache
|
- REDIS_ADDRESS_PORT=cache:6379
|
||||||
|
- STORAGE_ENDPOINT=storage:9000
|
||||||
|
- STORAGE_ACCESS_KEY=access_key
|
||||||
|
- STORAGE_SECRET_KEY=secret_key
|
||||||
|
- STORAGE_BUCKET=woj
|
||||||
|
- DEVELOPMENT=true
|
||||||
|
volumes:
|
||||||
|
- runner:/app/resource/runner/user
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
depends_on:
|
||||||
|
storage:
|
||||||
|
condition: service_healthy
|
||||||
|
cache:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
storage:
|
storage:
|
||||||
image: minio/minio:latest
|
image: quay.io/minio/minio:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live" ]
|
test: [ "CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live" ]
|
||||||
@ -55,13 +69,13 @@ services:
|
|||||||
entrypoint: sh
|
entrypoint: sh
|
||||||
command: -c 'mkdir -p /data/woj && minio server /data'
|
command: -c 'mkdir -p /data/woj && minio server /data'
|
||||||
environment:
|
environment:
|
||||||
MINIO_ACCESS_KEY: "access_key"
|
MINIO_ROOT_USER: "access_key"
|
||||||
MINIO_SECRET_KEY: "secret_key"
|
MINIO_ROOT_PASSWORD: "secret_key"
|
||||||
volumes:
|
volumes:
|
||||||
- storage:/data
|
- storage:/data
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
image: redis:alpine
|
image: docker.io/library/redis:alpine
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "redis-cli", "ping" ]
|
test: [ "CMD", "redis-cli", "ping" ]
|
||||||
@ -70,7 +84,7 @@ services:
|
|||||||
- cache:/data
|
- cache:/data
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: postgres:alpine
|
image: docker.io/library/postgres:alpine
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "pg_isready", "-U", "dev" ]
|
test: [ "CMD", "pg_isready", "-U", "dev" ]
|
||||||
@ -86,4 +100,4 @@ volumes:
|
|||||||
runner:
|
runner:
|
||||||
storage:
|
storage:
|
||||||
cache:
|
cache:
|
||||||
db:
|
db:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/bin/ash
|
#!/bin/bash
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
COLOR_RED="\e[0;31m"
|
COLOR_RED="\e[0;31m"
|
||||||
|
@ -18,7 +18,7 @@ func (s *service) EnsureDeps(force bool) e.Status {
|
|||||||
return e.Success
|
return e.Success
|
||||||
}
|
}
|
||||||
|
|
||||||
script := filepath.Join(ScriptsDir, "prepare_container.sh")
|
script := filepath.Join(ScriptsDir, "prepare_images.sh")
|
||||||
cmd := exec.Command(script)
|
cmd := exec.Command(script)
|
||||||
cmd.Dir = ScriptsDir
|
cmd.Dir = ScriptsDir
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
|
3
resource/runner/.gitignore
vendored
3
resource/runner/.gitignore
vendored
@ -1,7 +1,4 @@
|
|||||||
# docker image mark
|
# docker image mark
|
||||||
.mark.*
|
.mark.*
|
||||||
# tmp dockerfile
|
|
||||||
ubuntu-full.Dockerfile
|
|
||||||
ubuntu-run.Dockerfile
|
|
||||||
# other tmp files
|
# other tmp files
|
||||||
*.zip
|
*.zip
|
||||||
|
@ -10,5 +10,8 @@ function log_warn() { echo -e "${COLOR_YELLOW}$*${COLOR_NONE}" 1>&2; }
|
|||||||
function log_error() { echo -e "${COLOR_RED}$*${COLOR_NONE}" 1>&2; }
|
function log_error() { echo -e "${COLOR_RED}$*${COLOR_NONE}" 1>&2; }
|
||||||
|
|
||||||
# Docker or Podman
|
# Docker or Podman
|
||||||
DOCKER="docker"
|
DOCKER="podman"
|
||||||
if [ "$USE_PODMAN" ]; then DOCKER="podman"; fi
|
if [ "$USE_DOCKER" ]; then
|
||||||
|
log_error "docker is deprecated"
|
||||||
|
log_info "Use podman instead"
|
||||||
|
fi
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
. common.sh
|
|
||||||
|
|
||||||
cd "$(dirname "$0")"/../ || exit 1
|
|
||||||
|
|
||||||
# Check Mark
|
|
||||||
if [ -f ./.mark.container ]; then
|
|
||||||
log_warn "Docker containers already prepared"
|
|
||||||
log_warn "If you want to re-prepare the containers, please remove the file $(pwd)/.mark.container"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_info "Preparing container..."
|
|
||||||
log_info "Using $DOCKER - $($DOCKER --version)"
|
|
||||||
|
|
||||||
# Full
|
|
||||||
log_info "Building Full Image"
|
|
||||||
cat <<EOF >ubuntu-full.Dockerfile
|
|
||||||
FROM docker.io/library/ubuntu:22.04
|
|
||||||
WORKDIR /woj/
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN apt-get update && apt-get upgrade -y && apt-get install -y gcc g++ clang make cmake autoconf m4 libtool gperf git parallel python3 && apt-get clean && rm -rf /var/lib/apt/lists
|
|
||||||
|
|
||||||
# Copy source code
|
|
||||||
RUN mkdir -p /woj/framework && mkdir -p /woj/problem
|
|
||||||
COPY framework /woj/framework
|
|
||||||
|
|
||||||
# Build
|
|
||||||
RUN cd /woj/framework/template && ./setup.sh
|
|
||||||
RUN cd /woj/framework/scripts && ./setup.sh
|
|
||||||
|
|
||||||
# Environment
|
|
||||||
ENV WOJ_LAUNCHER=/woj/framework/scripts/woj_launcher
|
|
||||||
ENV WOJ_SANDBOX=/woj/framework/scripts/libwoj_sandbox.so
|
|
||||||
ENV TEMPLATE=/woj/framework/template
|
|
||||||
ENV TESTLIB=/woj/framework/template/testlib
|
|
||||||
ENV PREFIX=/woj/problem
|
|
||||||
EOF
|
|
||||||
$DOCKER build -t woj/ubuntu-full -f ubuntu-full.Dockerfile . || exit 1
|
|
||||||
rm ubuntu-full.Dockerfile
|
|
||||||
|
|
||||||
# Tiny
|
|
||||||
log_info "Building Tiny Image"
|
|
||||||
cat <<EOF >ubuntu-run.Dockerfile
|
|
||||||
FROM woj/ubuntu-full:latest AS builder
|
|
||||||
FROM docker.io/library/ubuntu:22.04
|
|
||||||
WORKDIR /woj/problem
|
|
||||||
RUN mkdir -p /woj/framework/scripts
|
|
||||||
COPY --from=builder /woj/framework/scripts/libwoj_sandbox.so /woj/framework/scripts/
|
|
||||||
COPY --from=builder /woj/framework/scripts/woj_launcher /woj/framework/scripts/
|
|
||||||
EOF
|
|
||||||
$DOCKER build -t woj/ubuntu-run -f ubuntu-run.Dockerfile . || exit 1
|
|
||||||
rm ubuntu-run.Dockerfile
|
|
||||||
|
|
||||||
touch ./.mark.container
|
|
||||||
|
|
||||||
log_info "Done"
|
|
52
resource/runner/scripts/prepare_images.sh
Executable file
52
resource/runner/scripts/prepare_images.sh
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
. common.sh
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"/../ || exit 1
|
||||||
|
|
||||||
|
# Check Mark
|
||||||
|
if [ -f ./.mark.image ]; then
|
||||||
|
log_warn "Docker images already prepared"
|
||||||
|
log_warn "If you want to re-prepare the images, please remove the file $(pwd)/.mark.image"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Preparing image..."
|
||||||
|
log_info "Checking $DOCKER - $($DOCKER --version)"
|
||||||
|
|
||||||
|
# Full
|
||||||
|
if [ -f ./tmp/ubuntu-full.tar.gz ]; then
|
||||||
|
log_info "Importing Full Image"
|
||||||
|
gzip -d -c ./tmp/ubuntu-full.tar.gz | $DOCKER load || (log_error "Import Full Image failed" && exit 1)
|
||||||
|
else
|
||||||
|
log_info "Pulling Full Image"
|
||||||
|
if ! $DOCKER pull git.0x7f.app/woj/ubuntu-full:latest; then
|
||||||
|
log_warn "Pull failed, building from scratch"
|
||||||
|
log_info "Building Full Image"
|
||||||
|
$DOCKER build -t git.0x7f.app/woj/ubuntu-full:latest -f scripts/ubuntu-full.Dockerfile . || (log_error "Build Full Image failed" && exit 1)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tiny
|
||||||
|
if [ -f ./tmp/ubuntu-tiny.tar.gz ]; then
|
||||||
|
log_info "Importing Tiny Image"
|
||||||
|
gzip -d -c ./tmp/ubuntu-tiny.tar.gz | $DOCKER load || (log_error "Import Tiny Image failed" && exit 1)
|
||||||
|
else
|
||||||
|
log_info "Pulling Tiny Image"
|
||||||
|
if ! $DOCKER pull git.0x7f.app/woj/ubuntu-run:latest; then
|
||||||
|
log_warn "Pull failed, building from scratch"
|
||||||
|
log_info "Building Tiny Image"
|
||||||
|
$DOCKER build -t git.0x7f.app/woj/ubuntu-run:latest -f scripts/ubuntu-run.Dockerfile . || (log_error "Build Tiny Image failed" && exit 1)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Mark
|
||||||
|
if [ "$1" == "save" ]; then
|
||||||
|
log_info "Saving Images"
|
||||||
|
$DOCKER save git.0x7f.app/woj/ubuntu-full:latest | gzip -9 >./tmp/ubuntu-full.tar.gz
|
||||||
|
$DOCKER save git.0x7f.app/woj/ubuntu-run:latest | gzip -9 >./tmp/ubuntu-tiny.tar.gz
|
||||||
|
else
|
||||||
|
touch ./.mark.image
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Done"
|
@ -9,67 +9,67 @@
|
|||||||
# $3: language
|
# $3: language
|
||||||
# exports: Info_Script, Info_Cmp, Info_Num, Info_Limit_Time, Info_Limit_Memory, Info_Limit_NProc
|
# exports: Info_Script, Info_Cmp, Info_Num, Info_Limit_Time, Info_Limit_Memory, Info_Limit_NProc
|
||||||
function get_problem_info() {
|
function get_problem_info() {
|
||||||
local err
|
local err
|
||||||
|
|
||||||
if [ ! -f "$1/problem/$2/config.json" ]; then
|
if [ ! -f "$1/problem/$2/config.json" ]; then
|
||||||
log_error "problem $2 not found"
|
log_error "problem $2 not found"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
parse_language_info "$1" "$2" "$3"
|
parse_language_info "$1" "$2" "$3"
|
||||||
err=$?
|
err=$?
|
||||||
if [ "$err" -ne 0 ]; then
|
if [ "$err" -ne 0 ]; then
|
||||||
return "$err"
|
return "$err"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
parse_limits "$1" "$2"
|
parse_limits "$1" "$2"
|
||||||
err=$?
|
err=$?
|
||||||
if [ "$err" -ne 0 ]; then
|
if [ "$err" -ne 0 ]; then
|
||||||
return "$err"
|
return "$err"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_language_info() {
|
function parse_language_info() {
|
||||||
export Info_Script
|
export Info_Script
|
||||||
export Info_Cmp
|
export Info_Cmp
|
||||||
|
|
||||||
local lang_config
|
local lang_config
|
||||||
local lang_type
|
local lang_type
|
||||||
local lang_script
|
local lang_script
|
||||||
|
|
||||||
lang_config=$(jq ".Languages[] | select(.Lang == \"$3\")" "$1/problem/$2/config.json")
|
lang_config=$(jq ".Languages[] | select(.Lang == \"$3\")" "$1/problem/$2/config.json")
|
||||||
if [ -z "$lang_config" ]; then
|
if [ -z "$lang_config" ]; then
|
||||||
log_error "language $3 is not supported"
|
log_error "language $3 is not supported"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
Info_Cmp=$(echo "$lang_config" | jq -r ".Cmp")
|
Info_Cmp=$(echo "$lang_config" | jq -r ".Cmp")
|
||||||
|
|
||||||
lang_type=$(echo "$lang_config" | jq -r ".Type")
|
lang_type=$(echo "$lang_config" | jq -r ".Type")
|
||||||
lang_script=$(echo "$lang_config" | jq -r ".Script")
|
lang_script=$(echo "$lang_config" | jq -r ".Script")
|
||||||
|
|
||||||
if [ "$lang_type" == "custom" ]; then
|
if [ "$lang_type" == "custom" ]; then
|
||||||
Info_Script="/woj/problem/judge/$lang_script"
|
Info_Script="/woj/problem/judge/$lang_script"
|
||||||
elif [ "$lang_type" == "default" ]; then
|
elif [ "$lang_type" == "default" ]; then
|
||||||
Info_Script="/woj/framework/template/default/$3.Makefile"
|
Info_Script="/woj/framework/template/default/$3.Makefile"
|
||||||
else
|
else
|
||||||
log_warn "Config file might be corrupted!"
|
log_warn "Config file might be corrupted!"
|
||||||
log_error "Unknown language type: $lang_type"
|
log_error "Unknown language type: $lang_type"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_limits() {
|
function parse_limits() {
|
||||||
export Info_Limit_Time
|
export Info_Limit_Time
|
||||||
export Info_Limit_Memory
|
export Info_Limit_Memory
|
||||||
export Info_Limit_NProc
|
export Info_Limit_NProc
|
||||||
export Info_Num
|
export Info_Num
|
||||||
|
|
||||||
local cfg
|
local cfg
|
||||||
cfg="$1/problem/$2/config.json"
|
cfg="$1/problem/$2/config.json"
|
||||||
|
|
||||||
Info_Limit_Time=$(jq ".Runtime.TimeLimit" "$cfg")
|
Info_Limit_Time=$(jq ".Runtime.TimeLimit" "$cfg")
|
||||||
Info_Limit_Memory=$(jq ".Runtime.MemoryLimit" "$cfg")
|
Info_Limit_Memory=$(jq ".Runtime.MemoryLimit" "$cfg")
|
||||||
Info_Limit_NProc=$(jq ".Runtime.NProcLimit" "$cfg")
|
Info_Limit_NProc=$(jq ".Runtime.NProcLimit" "$cfg")
|
||||||
Info_Num=$(jq ".Tasks | length" "$1/problem/$2/config.json")
|
Info_Num=$(jq ".Tasks | length" "$1/problem/$2/config.json")
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
|||||||
. "$WORKSPACE"/scripts/problem.sh
|
. "$WORKSPACE"/scripts/problem.sh
|
||||||
|
|
||||||
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
||||||
log_warn "Usage: $0 <problem> <user_dir> <language> <timeout>"
|
log_warn "Usage: $0 <problem> <user_dir> <language> <timeout>"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
get_problem_info "$WORKSPACE" "$1" "$3"
|
get_problem_info "$WORKSPACE" "$1" "$3"
|
||||||
@ -20,11 +20,11 @@ rm -f "$EXE_FILE" && touch "$EXE_FILE"
|
|||||||
|
|
||||||
export TIMEOUT=${4:-60}
|
export TIMEOUT=${4:-60}
|
||||||
docker_run \
|
docker_run \
|
||||||
-v "$WORKSPACE"/problem/"$1"/judge:/woj/problem/judge:ro \
|
-v "$WORKSPACE"/problem/"$1"/judge:/woj/problem/judge:ro \
|
||||||
-v "$SRC_FILE":/woj/problem/user/"$2"."$3":ro \
|
-v "$SRC_FILE":/woj/problem/user/"$2"."$3":ro \
|
||||||
-v "$EXE_FILE":/woj/problem/user/"$2".out \
|
-v "$EXE_FILE":/woj/problem/user/"$2".out \
|
||||||
-e USER_PROG="$2" \
|
-e USER_PROG="$2" \
|
||||||
-e LANG="$3" \
|
-e LANG="$3" \
|
||||||
woj/ubuntu-full \
|
git.0x7f.app/woj/ubuntu-full \
|
||||||
sh -c \
|
sh -c \
|
||||||
"cd /woj/problem/user && make -f $Info_Script compile"
|
"cd /woj/problem/user && make -f $Info_Script compile"
|
||||||
|
@ -6,35 +6,35 @@ WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
|||||||
. "$WORKSPACE"/scripts/problem.sh
|
. "$WORKSPACE"/scripts/problem.sh
|
||||||
|
|
||||||
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
||||||
log_warn "Usage: $0 <problem> <user_dir> <language> <timeout>"
|
log_warn "Usage: $0 <problem> <user_dir> <language> <timeout>"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
get_problem_info "$WORKSPACE" "$1" "$3"
|
get_problem_info "$WORKSPACE" "$1" "$3"
|
||||||
|
|
||||||
export TIMEOUT=${4:-60}
|
export TIMEOUT=${4:-60}
|
||||||
for test_num in $(seq "$Info_Num"); do
|
for test_num in $(seq "$Info_Num"); do
|
||||||
std_file="$WORKSPACE/problem/$1/data/output/$test_num.output"
|
std_file="$WORKSPACE/problem/$1/data/output/$test_num.output"
|
||||||
ans_file="$WORKSPACE/user/$2/$test_num.out.usr"
|
ans_file="$WORKSPACE/user/$2/$test_num.out.usr"
|
||||||
jdg_file="$WORKSPACE/user/$2/$test_num.judge"
|
jdg_file="$WORKSPACE/user/$2/$test_num.judge"
|
||||||
|
|
||||||
if [ ! -f "$std_file" ] || [ ! -f "$ans_file" ]; then
|
if [ ! -f "$std_file" ] || [ ! -f "$ans_file" ]; then
|
||||||
log_error "Missing test case $test_num"
|
log_error "Missing test case $test_num"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_info "Judging test case $test_num"
|
log_info "Judging test case $test_num"
|
||||||
|
|
||||||
touch "$jdg_file"
|
touch "$jdg_file"
|
||||||
|
|
||||||
docker_run \
|
docker_run \
|
||||||
-v "$WORKSPACE"/problem/"$1"/judge:/woj/problem/judge:ro \
|
-v "$WORKSPACE"/problem/"$1"/judge:/woj/problem/judge:ro \
|
||||||
-v "$WORKSPACE"/problem/"$1"/data:/woj/problem/data:ro \
|
-v "$WORKSPACE"/problem/"$1"/data:/woj/problem/data:ro \
|
||||||
-v "$ans_file":/woj/problem/user/"$test_num".out.usr \
|
-v "$ans_file":/woj/problem/user/"$test_num".out.usr \
|
||||||
-v "$jdg_file":/woj/problem/user/"$test_num".judge \
|
-v "$jdg_file":/woj/problem/user/"$test_num".judge \
|
||||||
-e TEST_NUM="$test_num" \
|
-e TEST_NUM="$test_num" \
|
||||||
-e CMP="$Info_Cmp" \
|
-e CMP="$Info_Cmp" \
|
||||||
woj/ubuntu-full \
|
git.0x7f.app/woj/ubuntu-full \
|
||||||
sh -c \
|
sh -c \
|
||||||
"cd /woj/problem/user && make -f $Info_Script judge"
|
"cd /woj/problem/user && make -f $Info_Script judge"
|
||||||
done
|
done
|
||||||
|
@ -5,28 +5,28 @@ WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
|||||||
. "$WORKSPACE"/scripts/common.sh
|
. "$WORKSPACE"/scripts/common.sh
|
||||||
|
|
||||||
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ]; then
|
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ]; then
|
||||||
log_warn "Usage: $0 <problem> <timeout>"
|
log_warn "Usage: $0 <problem> <timeout>"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "$WORKSPACE/problem/$1/.mark.prebuild" ]; then
|
if [ -f "$WORKSPACE/problem/$1/.mark.prebuild" ]; then
|
||||||
log_warn "Problem $1 already prebuilt"
|
log_warn "Problem $1 already prebuilt"
|
||||||
log_warn "If you want to re-prebuild the problem, please remove the file $WORKSPACE/problem/$1/.mark.prebuild"
|
log_warn "If you want to re-prebuild the problem, please remove the file $WORKSPACE/problem/$1/.mark.prebuild"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "$WORKSPACE/problem/$1/judge/prebuild.Makefile" ]; then
|
if [ ! -f "$WORKSPACE/problem/$1/judge/prebuild.Makefile" ]; then
|
||||||
log_warn "Problem $1 does not have prebuild scripts"
|
log_warn "Problem $1 does not have prebuild scripts"
|
||||||
log_warn "$WORKSPACE/problem/$1/.mark.prebuild"
|
log_warn "$WORKSPACE/problem/$1/.mark.prebuild"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export TIMEOUT=${2:-300}
|
export TIMEOUT=${2:-300}
|
||||||
docker_run \
|
docker_run \
|
||||||
-v "$WORKSPACE/problem/$1/data":/woj/problem/data \
|
-v "$WORKSPACE/problem/$1/data":/woj/problem/data \
|
||||||
-v "$WORKSPACE/problem/$1/judge":/woj/problem/judge \
|
-v "$WORKSPACE/problem/$1/judge":/woj/problem/judge \
|
||||||
-e PREFIX=/woj/problem \
|
-e PREFIX=/woj/problem \
|
||||||
woj/ubuntu-full \
|
git.0x7f.app/woj/ubuntu-full \
|
||||||
sh -c "cd /woj/problem/judge && make -f prebuild.Makefile prebuild && touch .mark.prebuild"
|
sh -c "cd /woj/problem/judge && make -f prebuild.Makefile prebuild && touch .mark.prebuild"
|
||||||
|
|
||||||
mv "$WORKSPACE/problem/$1/judge/.mark.prebuild" "$WORKSPACE/problem/$1/.mark.prebuild" || exit 1
|
mv "$WORKSPACE/problem/$1/judge/.mark.prebuild" "$WORKSPACE/problem/$1/.mark.prebuild" || exit 1
|
||||||
|
@ -6,20 +6,20 @@ WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
|
|||||||
. "$WORKSPACE"/scripts/problem.sh
|
. "$WORKSPACE"/scripts/problem.sh
|
||||||
|
|
||||||
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
|
||||||
log_warn "Usage: $0 <problem> <user_dir> <language>"
|
log_warn "Usage: $0 <problem> <user_dir> <language>"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "$WORKSPACE/problem/$1/.mark.prebuild" ]; then
|
if [ ! -f "$WORKSPACE/problem/$1/.mark.prebuild" ]; then
|
||||||
log_warn "Problem $1 has not been prebuilt"
|
log_warn "Problem $1 has not been prebuilt"
|
||||||
log_warn "Please run 'problem_prebuild.sh $1' first"
|
log_warn "Please run 'problem_prebuild.sh $1' first"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "$WORKSPACE/user/$2/$2.out" ]; then
|
if [ ! -f "$WORKSPACE/user/$2/$2.out" ]; then
|
||||||
log_warn "User $2 has not been compiled"
|
log_warn "User $2 has not been compiled"
|
||||||
log_warn "Please run 'problem_compile.sh ...' first"
|
log_warn "Please run 'problem_compile.sh ...' first"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
parse_limits "$WORKSPACE" "$1"
|
parse_limits "$WORKSPACE" "$1"
|
||||||
@ -35,37 +35,37 @@ TIMEOUT=$(((LIMIT_TIME + 1000) / 1000 + 4))
|
|||||||
log_info "Timeout: $TIMEOUT"
|
log_info "Timeout: $TIMEOUT"
|
||||||
|
|
||||||
for test_num in $(seq "$Info_Num"); do
|
for test_num in $(seq "$Info_Num"); do
|
||||||
test_case="$WORKSPACE/problem/$1/data/input/$test_num.input"
|
test_case="$WORKSPACE/problem/$1/data/input/$test_num.input"
|
||||||
exe_file="$WORKSPACE/user/$2/$2.out"
|
exe_file="$WORKSPACE/user/$2/$2.out"
|
||||||
ans_file="$WORKSPACE/user/$2/$test_num.out.usr"
|
ans_file="$WORKSPACE/user/$2/$test_num.out.usr"
|
||||||
ifo_file="$WORKSPACE/user/$2/$test_num.info"
|
ifo_file="$WORKSPACE/user/$2/$test_num.info"
|
||||||
|
|
||||||
if [ ! -f "$test_case" ]; then
|
if [ ! -f "$test_case" ]; then
|
||||||
log_error "Test case $test_num does not exist"
|
log_error "Test case $test_num does not exist"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_info "Running test case $test_num"
|
log_info "Running test case $test_num"
|
||||||
rm -f "$ans_file" && touch "$ans_file"
|
rm -f "$ans_file" && touch "$ans_file"
|
||||||
rm -f "$ifo_file" && touch "$ifo_file"
|
rm -f "$ifo_file" && touch "$ifo_file"
|
||||||
docker_run \
|
docker_run \
|
||||||
--cpus 1 \
|
--cpus 1 \
|
||||||
--network none \
|
--network none \
|
||||||
-v "$test_case":/woj/problem/data/input/"$test_num".input:ro \
|
-v "$test_case":/woj/problem/data/input/"$test_num".input:ro \
|
||||||
-v "$exe_file":/woj/user/"$2".out:ro \
|
-v "$exe_file":/woj/user/"$2".out:ro \
|
||||||
-v "$ans_file":/woj/user/"$test_num".out.usr \
|
-v "$ans_file":/woj/user/"$test_num".out.usr \
|
||||||
-v "$ifo_file":/woj/user/"$test_num".info \
|
-v "$ifo_file":/woj/user/"$test_num".info \
|
||||||
woj/ubuntu-run \
|
git.0x7f.app/woj/ubuntu-run \
|
||||||
sh -c \
|
sh -c \
|
||||||
"cd /woj/user && /woj/framework/scripts/woj_launcher \
|
"cd /woj/user && /woj/framework/scripts/woj_launcher \
|
||||||
--memory_limit=$Info_Limit_Memory \
|
--memory_limit=$Info_Limit_Memory \
|
||||||
--nproc_limit=$Info_Limit_NProc \
|
--nproc_limit=$Info_Limit_NProc \
|
||||||
--time_limit=$Info_Limit_Time \
|
--time_limit=$Info_Limit_Time \
|
||||||
--sandbox_path=/woj/framework/scripts/libwoj_sandbox.so \
|
--sandbox_path=/woj/framework/scripts/libwoj_sandbox.so \
|
||||||
--sandbox_template=$3 \
|
--sandbox_template=$3 \
|
||||||
--sandbox_action=nothing \
|
--sandbox_action=nothing \
|
||||||
--file_input=/woj/problem/data/input/$test_num.input \
|
--file_input=/woj/problem/data/input/$test_num.input \
|
||||||
--file_output=/woj/user/$test_num.out.usr \
|
--file_output=/woj/user/$test_num.out.usr \
|
||||||
--file_info=/woj/user/$test_num.info \
|
--file_info=/woj/user/$test_num.info \
|
||||||
--program=/woj/user/$2.out"
|
--program=/woj/user/$2.out"
|
||||||
done
|
done
|
||||||
|
@ -3,17 +3,17 @@
|
|||||||
. common.sh
|
. common.sh
|
||||||
|
|
||||||
function docker_run() {
|
function docker_run() {
|
||||||
local timeout=${TIMEOUT:-10}
|
local timeout=${TIMEOUT:-10}
|
||||||
local log_file=${LOG_FILE:-"/dev/stderr"}
|
local log_file=${LOG_FILE:-"/dev/stderr"}
|
||||||
local log_limit=${LOG_LIMIT:-4K}
|
local log_limit=${LOG_LIMIT:-4K}
|
||||||
log_info "$DOCKER run with timeout $timeout"
|
log_info "$DOCKER run with timeout $timeout"
|
||||||
CONTAINER_NAME=$(uuidgen)
|
CONTAINER_NAME=$(uuidgen)
|
||||||
(
|
(
|
||||||
sleep "$timeout"
|
sleep "$timeout"
|
||||||
$DOCKER kill "$CONTAINER_NAME"
|
$DOCKER kill "$CONTAINER_NAME"
|
||||||
) &
|
) &
|
||||||
$DOCKER run --rm --name "$CONTAINER_NAME" "$@" 2>&1 | head -c "$log_limit" >"$log_file"
|
$DOCKER run --rm --name "$CONTAINER_NAME" "$@" 2>&1 | head -c "$log_limit" >"$log_file"
|
||||||
pkill -P $$
|
pkill -P $$
|
||||||
$DOCKER kill "$CONTAINER_NAME" >/dev/null 2>&1
|
$DOCKER kill "$CONTAINER_NAME" >/dev/null 2>&1
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
20
resource/runner/scripts/ubuntu-full.Dockerfile
Normal file
20
resource/runner/scripts/ubuntu-full.Dockerfile
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
FROM docker.io/library/ubuntu:22.04
|
||||||
|
WORKDIR /woj/
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN apt-get update && apt-get upgrade -y && apt-get install -y gcc g++ clang make cmake autoconf m4 libtool gperf git parallel python3 && apt-get clean && rm -rf /var/lib/apt/lists
|
||||||
|
|
||||||
|
# Copy source code
|
||||||
|
RUN mkdir -p /woj/framework && mkdir -p /woj/problem
|
||||||
|
COPY framework /woj/framework
|
||||||
|
|
||||||
|
# Build
|
||||||
|
RUN cd /woj/framework/template && ./setup.sh
|
||||||
|
RUN cd /woj/framework/scripts && ./setup.sh
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
ENV WOJ_LAUNCHER=/woj/framework/scripts/woj_launcher
|
||||||
|
ENV WOJ_SANDBOX=/woj/framework/scripts/libwoj_sandbox.so
|
||||||
|
ENV TEMPLATE=/woj/framework/template
|
||||||
|
ENV TESTLIB=/woj/framework/template/testlib
|
||||||
|
ENV PREFIX=/woj/problem
|
8
resource/runner/scripts/ubuntu-run.Dockerfile
Normal file
8
resource/runner/scripts/ubuntu-run.Dockerfile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
FROM woj/ubuntu-full:latest AS builder
|
||||||
|
FROM docker.io/library/ubuntu:22.04
|
||||||
|
|
||||||
|
WORKDIR /woj/problem
|
||||||
|
RUN mkdir -p /woj/framework/scripts
|
||||||
|
|
||||||
|
COPY --from=builder /woj/framework/scripts/libwoj_sandbox.so /woj/framework/scripts/
|
||||||
|
COPY --from=builder /woj/framework/scripts/woj_launcher /woj/framework/scripts/
|
Loading…
Reference in New Issue
Block a user