diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..976fbbc
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,8 @@
+# top
+/woj
+
+# runner
+resource/runner/.mark.container
+resource/runner/problem/*
+resource/runner/tmp/*
+resource/runner/user/*
diff --git a/.idea/jsonSchemas.xml b/.idea/jsonSchemas.xml
new file mode 100644
index 0000000..3120128
--- /dev/null
+++ b/.idea/jsonSchemas.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Makefile b/Makefile
index f8da8e8..45de93c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,12 @@
GO := go
-LDFLAGS += -X cmd.BuildTime=$(shell date -u '+%Y-%m-%d-%I-%M-%S')
-LDFLAGS += -X cmd.Version=$(shell cat VERSION)+$(shell git rev-parse --short HEAD)
-LDFLAGS += -X cmd.SentryDSN=$(shell cat dsn.txt)
+PKG_BASE := $(shell head -n 1 go.mod | awk '{print $$2}')
+BUILD_TIME := $(shell date -u '+%Y%m%d-%I%M%S')
+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
GOBUILD := $(GO) build -ldflags '$(LDFLAGS)'
@@ -18,8 +22,7 @@ build: swagger dep
$(GOBUILD) -o woj ./cmd/woj
clean:
- rm -f runner
- rm -f server
+ rm -f woj
dep:
go mod download
diff --git a/Runner.Dockerfile b/Runner.Dockerfile
new file mode 100644
index 0000000..b58e46a
--- /dev/null
+++ b/Runner.Dockerfile
@@ -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"]
diff --git a/Dockerfile b/Server.Dockerfile
similarity index 75%
rename from Dockerfile
rename to Server.Dockerfile
index 71692e5..e82eeae 100644
--- a/Dockerfile
+++ b/Server.Dockerfile
@@ -1,5 +1,5 @@
# builder
-FROM golang:alpine AS builder
+FROM docker.io/library/golang:alpine AS builder
ENV GOPROXY=https://goproxy.cn
WORKDIR /builder
@@ -16,16 +16,14 @@ RUN make build
# main image
-FROM alpine:latest
+FROM docker.io/library/alpine
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/docker-entrypoint.sh /app
COPY --from=builder /builder/resource/frontend /app/resource/frontend
-COPY --from=builder /builder/resource/runner /app/resource/runner
-
COPY --from=builder /builder/woj /app
ENTRYPOINT ["/app/docker-entrypoint.sh"]
diff --git a/build_image.sh b/build_image.sh
new file mode 100755
index 0000000..d522837
--- /dev/null
+++ b/build_image.sh
@@ -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
diff --git a/cmd/common.go b/cmd/common.go
index a0b8f8e..dc74753 100644
--- a/cmd/common.go
+++ b/cmd/common.go
@@ -59,7 +59,7 @@ func init() {
}
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 {
log.Printf("failed to parse build time: %v", err)
build = time.Now()
diff --git a/docker-compose.yml b/docker-compose.yml
index ac68d45..98b43dc 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,11 +1,9 @@
-version: "3"
-
services:
server:
- build: .
+ image: git.0x7f.app/woj/woj-server:1.1.0
restart: unless-stopped
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
command: web
environment:
@@ -14,7 +12,7 @@ services:
- DATABASE_USER=dev
- DATABASE_PASSWORD=password
- DATABASE_NAME=dev
- - STORAGE_ENDPOINT=minio:9000
+ - STORAGE_ENDPOINT=storage:9000
- STORAGE_ACCESS_KEY=access_key
- STORAGE_SECRET_KEY=secret_key
- STORAGE_BUCKET=woj
@@ -23,6 +21,8 @@ services:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
depends_on:
+ runner:
+ condition: service_started
storage:
condition: service_healthy
cache:
@@ -32,22 +32,36 @@ services:
ports:
- "8000:8000"
- #runner:
- # build: .
- # restart: unless-stopped
- # command: runner
- # environment:
- # - REDIS_ADDRESS_PORT=cache:6379
- # - DEVELOPMENT=true
- # volumes:
- # - runner:/app/resource/runner/user
- # - /etc/timezone:/etc/timezone:ro
- # - /etc/localtime:/etc/localtime:ro
- # depends_on:
- # - cache
+ runner:
+ image: git.0x7f.app/woj/woj-runner:1.1.0
+ restart: unless-stopped
+ command: runner
+ security_opt:
+ - "label=disable"
+ cap_add:
+ - SYS_ADMIN
+ - MKNOD
+ devices:
+ - "/dev/fuse"
+ environment:
+ - 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:
- image: minio/minio:latest
+ image: quay.io/minio/minio:latest
restart: unless-stopped
healthcheck:
test: [ "CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live" ]
@@ -55,13 +69,13 @@ services:
entrypoint: sh
command: -c 'mkdir -p /data/woj && minio server /data'
environment:
- MINIO_ACCESS_KEY: "access_key"
- MINIO_SECRET_KEY: "secret_key"
+ MINIO_ROOT_USER: "access_key"
+ MINIO_ROOT_PASSWORD: "secret_key"
volumes:
- storage:/data
cache:
- image: redis:alpine
+ image: docker.io/library/redis:alpine
restart: unless-stopped
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
@@ -70,7 +84,7 @@ services:
- cache:/data
db:
- image: postgres:alpine
+ image: docker.io/library/postgres:alpine
restart: unless-stopped
healthcheck:
test: [ "CMD", "pg_isready", "-U", "dev" ]
@@ -86,4 +100,4 @@ volumes:
runner:
storage:
cache:
- db:
\ No newline at end of file
+ db:
diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh
index 4728bdd..e950e71 100755
--- a/docker-entrypoint.sh
+++ b/docker-entrypoint.sh
@@ -1,4 +1,4 @@
-#!/bin/ash
+#!/bin/bash
set -eo pipefail
COLOR_RED="\e[0;31m"
diff --git a/internal/service/runner/deps.go b/internal/service/runner/deps.go
index c968ec0..1aee7f9 100644
--- a/internal/service/runner/deps.go
+++ b/internal/service/runner/deps.go
@@ -18,7 +18,7 @@ func (s *service) EnsureDeps(force bool) e.Status {
return e.Success
}
- script := filepath.Join(ScriptsDir, "prepare_container.sh")
+ script := filepath.Join(ScriptsDir, "prepare_images.sh")
cmd := exec.Command(script)
cmd.Dir = ScriptsDir
err := cmd.Run()
diff --git a/resource/runner/.gitignore b/resource/runner/.gitignore
index 8a603d9..0f3e631 100644
--- a/resource/runner/.gitignore
+++ b/resource/runner/.gitignore
@@ -1,7 +1,4 @@
# docker image mark
.mark.*
-# tmp dockerfile
-ubuntu-full.Dockerfile
-ubuntu-run.Dockerfile
# other tmp files
*.zip
diff --git a/resource/runner/scripts/common.sh b/resource/runner/scripts/common.sh
index 72dd11c..408ed96 100755
--- a/resource/runner/scripts/common.sh
+++ b/resource/runner/scripts/common.sh
@@ -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; }
# Docker or Podman
-DOCKER="docker"
-if [ "$USE_PODMAN" ]; then DOCKER="podman"; fi
+DOCKER="podman"
+if [ "$USE_DOCKER" ]; then
+ log_error "docker is deprecated"
+ log_info "Use podman instead"
+fi
diff --git a/resource/runner/scripts/prepare_container.sh b/resource/runner/scripts/prepare_container.sh
deleted file mode 100755
index 0987ee4..0000000
--- a/resource/runner/scripts/prepare_container.sh
+++ /dev/null
@@ -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 <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 <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"
diff --git a/resource/runner/scripts/prepare_images.sh b/resource/runner/scripts/prepare_images.sh
new file mode 100755
index 0000000..f03c696
--- /dev/null
+++ b/resource/runner/scripts/prepare_images.sh
@@ -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"
diff --git a/resource/runner/scripts/problem.sh b/resource/runner/scripts/problem.sh
index ef407a2..a9f2754 100755
--- a/resource/runner/scripts/problem.sh
+++ b/resource/runner/scripts/problem.sh
@@ -9,67 +9,67 @@
# $3: language
# exports: Info_Script, Info_Cmp, Info_Num, Info_Limit_Time, Info_Limit_Memory, Info_Limit_NProc
function get_problem_info() {
- local err
+ local err
- if [ ! -f "$1/problem/$2/config.json" ]; then
- log_error "problem $2 not found"
- return 1
- fi
+ if [ ! -f "$1/problem/$2/config.json" ]; then
+ log_error "problem $2 not found"
+ return 1
+ fi
- parse_language_info "$1" "$2" "$3"
- err=$?
- if [ "$err" -ne 0 ]; then
- return "$err"
- fi
+ parse_language_info "$1" "$2" "$3"
+ err=$?
+ if [ "$err" -ne 0 ]; then
+ return "$err"
+ fi
- parse_limits "$1" "$2"
- err=$?
- if [ "$err" -ne 0 ]; then
- return "$err"
- fi
+ parse_limits "$1" "$2"
+ err=$?
+ if [ "$err" -ne 0 ]; then
+ return "$err"
+ fi
}
function parse_language_info() {
- export Info_Script
- export Info_Cmp
+ export Info_Script
+ export Info_Cmp
- local lang_config
- local lang_type
- local lang_script
+ local lang_config
+ local lang_type
+ local lang_script
- lang_config=$(jq ".Languages[] | select(.Lang == \"$3\")" "$1/problem/$2/config.json")
- if [ -z "$lang_config" ]; then
- log_error "language $3 is not supported"
- return 1
- fi
+ lang_config=$(jq ".Languages[] | select(.Lang == \"$3\")" "$1/problem/$2/config.json")
+ if [ -z "$lang_config" ]; then
+ log_error "language $3 is not supported"
+ return 1
+ 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_script=$(echo "$lang_config" | jq -r ".Script")
+ lang_type=$(echo "$lang_config" | jq -r ".Type")
+ lang_script=$(echo "$lang_config" | jq -r ".Script")
- if [ "$lang_type" == "custom" ]; then
- Info_Script="/woj/problem/judge/$lang_script"
- elif [ "$lang_type" == "default" ]; then
- Info_Script="/woj/framework/template/default/$3.Makefile"
- else
- log_warn "Config file might be corrupted!"
- log_error "Unknown language type: $lang_type"
- return 1
- fi
+ if [ "$lang_type" == "custom" ]; then
+ Info_Script="/woj/problem/judge/$lang_script"
+ elif [ "$lang_type" == "default" ]; then
+ Info_Script="/woj/framework/template/default/$3.Makefile"
+ else
+ log_warn "Config file might be corrupted!"
+ log_error "Unknown language type: $lang_type"
+ return 1
+ fi
}
function parse_limits() {
- export Info_Limit_Time
- export Info_Limit_Memory
- export Info_Limit_NProc
- export Info_Num
+ export Info_Limit_Time
+ export Info_Limit_Memory
+ export Info_Limit_NProc
+ export Info_Num
- local cfg
- cfg="$1/problem/$2/config.json"
+ local cfg
+ cfg="$1/problem/$2/config.json"
- Info_Limit_Time=$(jq ".Runtime.TimeLimit" "$cfg")
- Info_Limit_Memory=$(jq ".Runtime.MemoryLimit" "$cfg")
- Info_Limit_NProc=$(jq ".Runtime.NProcLimit" "$cfg")
- Info_Num=$(jq ".Tasks | length" "$1/problem/$2/config.json")
+ Info_Limit_Time=$(jq ".Runtime.TimeLimit" "$cfg")
+ Info_Limit_Memory=$(jq ".Runtime.MemoryLimit" "$cfg")
+ Info_Limit_NProc=$(jq ".Runtime.NProcLimit" "$cfg")
+ Info_Num=$(jq ".Tasks | length" "$1/problem/$2/config.json")
}
diff --git a/resource/runner/scripts/problem_compile.sh b/resource/runner/scripts/problem_compile.sh
index 8f35ac6..a25ccfc 100755
--- a/resource/runner/scripts/problem_compile.sh
+++ b/resource/runner/scripts/problem_compile.sh
@@ -6,8 +6,8 @@ WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
. "$WORKSPACE"/scripts/problem.sh
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
- log_warn "Usage: $0 "
- exit 1
+ log_warn "Usage: $0 "
+ exit 1
fi
get_problem_info "$WORKSPACE" "$1" "$3"
@@ -20,11 +20,11 @@ rm -f "$EXE_FILE" && touch "$EXE_FILE"
export TIMEOUT=${4:-60}
docker_run \
- -v "$WORKSPACE"/problem/"$1"/judge:/woj/problem/judge:ro \
- -v "$SRC_FILE":/woj/problem/user/"$2"."$3":ro \
- -v "$EXE_FILE":/woj/problem/user/"$2".out \
- -e USER_PROG="$2" \
- -e LANG="$3" \
- woj/ubuntu-full \
- sh -c \
- "cd /woj/problem/user && make -f $Info_Script compile"
+ -v "$WORKSPACE"/problem/"$1"/judge:/woj/problem/judge:ro \
+ -v "$SRC_FILE":/woj/problem/user/"$2"."$3":ro \
+ -v "$EXE_FILE":/woj/problem/user/"$2".out \
+ -e USER_PROG="$2" \
+ -e LANG="$3" \
+ git.0x7f.app/woj/ubuntu-full \
+ sh -c \
+ "cd /woj/problem/user && make -f $Info_Script compile"
diff --git a/resource/runner/scripts/problem_judge.sh b/resource/runner/scripts/problem_judge.sh
index 0142ee2..b262d6f 100755
--- a/resource/runner/scripts/problem_judge.sh
+++ b/resource/runner/scripts/problem_judge.sh
@@ -6,35 +6,35 @@ WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
. "$WORKSPACE"/scripts/problem.sh
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
- log_warn "Usage: $0 "
- exit 1
+ log_warn "Usage: $0 "
+ exit 1
fi
get_problem_info "$WORKSPACE" "$1" "$3"
export TIMEOUT=${4:-60}
for test_num in $(seq "$Info_Num"); do
- std_file="$WORKSPACE/problem/$1/data/output/$test_num.output"
- ans_file="$WORKSPACE/user/$2/$test_num.out.usr"
- jdg_file="$WORKSPACE/user/$2/$test_num.judge"
+ std_file="$WORKSPACE/problem/$1/data/output/$test_num.output"
+ ans_file="$WORKSPACE/user/$2/$test_num.out.usr"
+ jdg_file="$WORKSPACE/user/$2/$test_num.judge"
- if [ ! -f "$std_file" ] || [ ! -f "$ans_file" ]; then
- log_error "Missing test case $test_num"
- exit 1
- fi
+ if [ ! -f "$std_file" ] || [ ! -f "$ans_file" ]; then
+ log_error "Missing test case $test_num"
+ exit 1
+ fi
- log_info "Judging test case $test_num"
+ log_info "Judging test case $test_num"
- touch "$jdg_file"
+ touch "$jdg_file"
- docker_run \
- -v "$WORKSPACE"/problem/"$1"/judge:/woj/problem/judge:ro \
- -v "$WORKSPACE"/problem/"$1"/data:/woj/problem/data:ro \
- -v "$ans_file":/woj/problem/user/"$test_num".out.usr \
- -v "$jdg_file":/woj/problem/user/"$test_num".judge \
- -e TEST_NUM="$test_num" \
- -e CMP="$Info_Cmp" \
- woj/ubuntu-full \
- sh -c \
- "cd /woj/problem/user && make -f $Info_Script judge"
+ docker_run \
+ -v "$WORKSPACE"/problem/"$1"/judge:/woj/problem/judge:ro \
+ -v "$WORKSPACE"/problem/"$1"/data:/woj/problem/data:ro \
+ -v "$ans_file":/woj/problem/user/"$test_num".out.usr \
+ -v "$jdg_file":/woj/problem/user/"$test_num".judge \
+ -e TEST_NUM="$test_num" \
+ -e CMP="$Info_Cmp" \
+ git.0x7f.app/woj/ubuntu-full \
+ sh -c \
+ "cd /woj/problem/user && make -f $Info_Script judge"
done
diff --git a/resource/runner/scripts/problem_prebuild.sh b/resource/runner/scripts/problem_prebuild.sh
index 3b97164..e054688 100755
--- a/resource/runner/scripts/problem_prebuild.sh
+++ b/resource/runner/scripts/problem_prebuild.sh
@@ -5,28 +5,28 @@ WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
. "$WORKSPACE"/scripts/common.sh
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ]; then
- log_warn "Usage: $0 "
- exit 1
+ log_warn "Usage: $0 "
+ exit 1
fi
if [ -f "$WORKSPACE/problem/$1/.mark.prebuild" ]; then
- 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"
- exit 0
+ 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"
+ exit 0
fi
if [ ! -f "$WORKSPACE/problem/$1/judge/prebuild.Makefile" ]; then
- log_warn "Problem $1 does not have prebuild scripts"
- log_warn "$WORKSPACE/problem/$1/.mark.prebuild"
- exit 0
+ log_warn "Problem $1 does not have prebuild scripts"
+ log_warn "$WORKSPACE/problem/$1/.mark.prebuild"
+ exit 0
fi
export TIMEOUT=${2:-300}
docker_run \
- -v "$WORKSPACE/problem/$1/data":/woj/problem/data \
- -v "$WORKSPACE/problem/$1/judge":/woj/problem/judge \
- -e PREFIX=/woj/problem \
- woj/ubuntu-full \
- sh -c "cd /woj/problem/judge && make -f prebuild.Makefile prebuild && touch .mark.prebuild"
+ -v "$WORKSPACE/problem/$1/data":/woj/problem/data \
+ -v "$WORKSPACE/problem/$1/judge":/woj/problem/judge \
+ -e PREFIX=/woj/problem \
+ git.0x7f.app/woj/ubuntu-full \
+ 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
diff --git a/resource/runner/scripts/problem_run.sh b/resource/runner/scripts/problem_run.sh
index 3fb4ae3..03da64d 100755
--- a/resource/runner/scripts/problem_run.sh
+++ b/resource/runner/scripts/problem_run.sh
@@ -6,20 +6,20 @@ WORKSPACE=$(cd "$(dirname "$0")"/.. && pwd)
. "$WORKSPACE"/scripts/problem.sh
if [ "$1" == "" ] || [ ! -d "$WORKSPACE/problem/$1" ] || [ "$2" == "" ] || [ ! -d "$WORKSPACE/user/$2" ] || [ -z "$3" ]; then
- log_warn "Usage: $0 "
- exit 1
+ log_warn "Usage: $0 "
+ exit 1
fi
if [ ! -f "$WORKSPACE/problem/$1/.mark.prebuild" ]; then
- log_warn "Problem $1 has not been prebuilt"
- log_warn "Please run 'problem_prebuild.sh $1' first"
- exit 1
+ log_warn "Problem $1 has not been prebuilt"
+ log_warn "Please run 'problem_prebuild.sh $1' first"
+ exit 1
fi
if [ ! -f "$WORKSPACE/user/$2/$2.out" ]; then
- log_warn "User $2 has not been compiled"
- log_warn "Please run 'problem_compile.sh ...' first"
- exit 1
+ log_warn "User $2 has not been compiled"
+ log_warn "Please run 'problem_compile.sh ...' first"
+ exit 1
fi
parse_limits "$WORKSPACE" "$1"
@@ -35,37 +35,37 @@ TIMEOUT=$(((LIMIT_TIME + 1000) / 1000 + 4))
log_info "Timeout: $TIMEOUT"
for test_num in $(seq "$Info_Num"); do
- test_case="$WORKSPACE/problem/$1/data/input/$test_num.input"
- exe_file="$WORKSPACE/user/$2/$2.out"
- ans_file="$WORKSPACE/user/$2/$test_num.out.usr"
- ifo_file="$WORKSPACE/user/$2/$test_num.info"
+ test_case="$WORKSPACE/problem/$1/data/input/$test_num.input"
+ exe_file="$WORKSPACE/user/$2/$2.out"
+ ans_file="$WORKSPACE/user/$2/$test_num.out.usr"
+ ifo_file="$WORKSPACE/user/$2/$test_num.info"
- if [ ! -f "$test_case" ]; then
- log_error "Test case $test_num does not exist"
- exit 1
- fi
+ if [ ! -f "$test_case" ]; then
+ log_error "Test case $test_num does not exist"
+ exit 1
+ fi
- log_info "Running test case $test_num"
- rm -f "$ans_file" && touch "$ans_file"
- rm -f "$ifo_file" && touch "$ifo_file"
- docker_run \
- --cpus 1 \
- --network none \
- -v "$test_case":/woj/problem/data/input/"$test_num".input:ro \
- -v "$exe_file":/woj/user/"$2".out:ro \
- -v "$ans_file":/woj/user/"$test_num".out.usr \
- -v "$ifo_file":/woj/user/"$test_num".info \
- woj/ubuntu-run \
- sh -c \
- "cd /woj/user && /woj/framework/scripts/woj_launcher \
- --memory_limit=$Info_Limit_Memory \
- --nproc_limit=$Info_Limit_NProc \
- --time_limit=$Info_Limit_Time \
- --sandbox_path=/woj/framework/scripts/libwoj_sandbox.so \
- --sandbox_template=$3 \
- --sandbox_action=nothing \
- --file_input=/woj/problem/data/input/$test_num.input \
- --file_output=/woj/user/$test_num.out.usr \
- --file_info=/woj/user/$test_num.info \
- --program=/woj/user/$2.out"
+ log_info "Running test case $test_num"
+ rm -f "$ans_file" && touch "$ans_file"
+ rm -f "$ifo_file" && touch "$ifo_file"
+ docker_run \
+ --cpus 1 \
+ --network none \
+ -v "$test_case":/woj/problem/data/input/"$test_num".input:ro \
+ -v "$exe_file":/woj/user/"$2".out:ro \
+ -v "$ans_file":/woj/user/"$test_num".out.usr \
+ -v "$ifo_file":/woj/user/"$test_num".info \
+ git.0x7f.app/woj/ubuntu-run \
+ sh -c \
+ "cd /woj/user && /woj/framework/scripts/woj_launcher \
+ --memory_limit=$Info_Limit_Memory \
+ --nproc_limit=$Info_Limit_NProc \
+ --time_limit=$Info_Limit_Time \
+ --sandbox_path=/woj/framework/scripts/libwoj_sandbox.so \
+ --sandbox_template=$3 \
+ --sandbox_action=nothing \
+ --file_input=/woj/problem/data/input/$test_num.input \
+ --file_output=/woj/user/$test_num.out.usr \
+ --file_info=/woj/user/$test_num.info \
+ --program=/woj/user/$2.out"
done
diff --git a/resource/runner/scripts/run_timeout.sh b/resource/runner/scripts/run_timeout.sh
index 1f48957..20b64f2 100755
--- a/resource/runner/scripts/run_timeout.sh
+++ b/resource/runner/scripts/run_timeout.sh
@@ -3,17 +3,17 @@
. common.sh
function docker_run() {
- local timeout=${TIMEOUT:-10}
- local log_file=${LOG_FILE:-"/dev/stderr"}
- local log_limit=${LOG_LIMIT:-4K}
- log_info "$DOCKER run with timeout $timeout"
- CONTAINER_NAME=$(uuidgen)
- (
- sleep "$timeout"
- $DOCKER kill "$CONTAINER_NAME"
- ) &
- $DOCKER run --rm --name "$CONTAINER_NAME" "$@" 2>&1 | head -c "$log_limit" >"$log_file"
- pkill -P $$
- $DOCKER kill "$CONTAINER_NAME" >/dev/null 2>&1
- return 0
+ local timeout=${TIMEOUT:-10}
+ local log_file=${LOG_FILE:-"/dev/stderr"}
+ local log_limit=${LOG_LIMIT:-4K}
+ log_info "$DOCKER run with timeout $timeout"
+ CONTAINER_NAME=$(uuidgen)
+ (
+ sleep "$timeout"
+ $DOCKER kill "$CONTAINER_NAME"
+ ) &
+ $DOCKER run --rm --name "$CONTAINER_NAME" "$@" 2>&1 | head -c "$log_limit" >"$log_file"
+ pkill -P $$
+ $DOCKER kill "$CONTAINER_NAME" >/dev/null 2>&1
+ return 0
}
diff --git a/resource/runner/scripts/ubuntu-full.Dockerfile b/resource/runner/scripts/ubuntu-full.Dockerfile
new file mode 100644
index 0000000..a7391da
--- /dev/null
+++ b/resource/runner/scripts/ubuntu-full.Dockerfile
@@ -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
diff --git a/resource/runner/scripts/ubuntu-run.Dockerfile b/resource/runner/scripts/ubuntu-run.Dockerfile
new file mode 100644
index 0000000..44839ba
--- /dev/null
+++ b/resource/runner/scripts/ubuntu-run.Dockerfile
@@ -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/