Skip to content

Commit

Permalink
feat: ✨ rebuild rlua-54 plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Eason0729 committed May 17, 2024
1 parent 96ef9b5 commit 2811cd3
Show file tree
Hide file tree
Showing 26 changed files with 342 additions and 81 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"backend/migration",
"grpc",
]
exclude = ["judger/plugins/rlua-54"]

[workspace.dependencies]
prost = "0.12.3"
Expand Down
2 changes: 1 addition & 1 deletion judger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cgroups-rs = "0.3.2"
cgroups-rs = "0.3.4"
env_logger = "0.10.1"
futures-core = "0.3.30"
log = "0.4.17"
Expand Down
2 changes: 0 additions & 2 deletions judger/plugins/.dockerignore

This file was deleted.

1 change: 1 addition & 0 deletions judger/plugins/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/*.lang
16 changes: 4 additions & 12 deletions judger/plugins/rlua-54/spec.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
# memory in byte, time in microsecond
fs_limit = 3145728
file = "/src/code.txt"
info = "A lightweight Lua 5.4 runtime build for both secure sandboxing and modj-sandbox test"
extension = "lua" # same extension means same language
name = "rlua-54" # must be same as dictionary name
uid = "1c41598f-e253-4f81-9ef5-d50bf1e4e74f" # be sure it's unique
name = "rlua-54"
id = "1c41598f-e253-4f81-9ef5-d50bf1e4e74f" # be sure it's unique

[compile]
command = ["/rlua-54","compile"]
kernel_mem = 67108864
user_mem = 268435456
rt_time = 1000000
cpu_time = 10000000
total_time = 10000000

[judge]
command = ["/rlua-54","execute"]
kernel_mem = 67108864
memory_multiplier = 6 # user_mem
rt_time = 1000000
cpu_multiplier = 3 # cpu_time
3 changes: 0 additions & 3 deletions judger/plugins/rlua-54/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,5 @@ use std::{
};

pub fn compile() {
let mut buf = Vec::new();
stdin().read_to_end(&mut buf).unwrap();

fs::write(crate::LUA_SRC, buf).unwrap();
}
34 changes: 29 additions & 5 deletions judger/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ use serde::{Deserialize, Serialize};

#[cfg(not(test))]
use std::path::PathBuf;
use std::{
net::{SocketAddr, SocketAddrV4},
str::FromStr,
};

#[cfg(not(test))]
fn try_load_config() -> Result<Config, Box<dyn std::error::Error>> {
Expand Down Expand Up @@ -36,19 +40,19 @@ pub enum Accounting {
Cpu,
}

fn default_ratio_cpu() -> f32 {
fn default_ratio_cpu() -> f64 {
1.0
}
fn default_ratio_memory() -> f32 {
fn default_ratio_memory() -> f64 {
1.0
}

#[derive(Serialize, Deserialize, Default)]
pub struct Ratio {
#[serde(default = "default_ratio_cpu")]
pub cpu: f32,
pub cpu: f64,
#[serde(default = "default_ratio_memory")]
pub memory: f32,
pub memory: f64,
}

fn default_log() -> u8 {
Expand All @@ -66,7 +70,11 @@ fn default_memory() -> u64 {
1024 * 1024 * 1024
}

#[derive(Serialize, Deserialize, Default)]
fn default_addr() -> SocketAddr {
SocketAddr::from_str("0.0.0.0:8081").unwrap()
}

#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Config {
#[serde(default)]
Expand All @@ -81,4 +89,20 @@ pub struct Config {
pub secret: Option<String>,
#[serde(default = "default_memory")]
pub memory: u64,
#[serde(default = "default_addr")]
pub address: SocketAddr,
}

impl Default for Config {
fn default() -> Self {
Self {
accounting: Default::default(),
ratio: default_ratio(),
rootless: false,
log: default_log(),
secret: None,
memory: default_memory(),
address: default_addr(),
}
}
}
4 changes: 2 additions & 2 deletions judger/src/filesystem/adapter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ mod test {
.ok();

log::info!("mounting test tarball in .temp ...");
let template = Template::new("test/nested.tar").await.unwrap();
let template = Template::new("plugins/rlua-54.lang").await.unwrap();
let filesystem = template.as_filesystem(1024 * 1024 * 1024);
let mut mount_handle = filesystem.mount_with_path("./.temp/1").await.unwrap();
let mut mount_handle = filesystem.mount_with_path("./.temp/5").await.unwrap();
let handle = &mut mount_handle;

tokio::select! {
Expand Down
17 changes: 5 additions & 12 deletions judger/src/filesystem/entry/ro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ where
F: AsyncRead + AsyncSeek + Unpin + 'static,
{
pub fn new(file: Arc<Mutex<F>>, start: u64, size: u32) -> Self {
log::info!("new block: start={}, size={}", start, size);
log::trace!("new block: start={}, size={}", start, size);
Self {
file,
start,
Expand Down Expand Up @@ -85,7 +85,8 @@ where
F: AsyncRead + AsyncSeek + Unpin + 'static,
{
async fn read(&mut self, offset: u64, size: u32) -> std::io::Result<bytes::Bytes> {
let size = size as usize;
let size = size.min(self.size - self.cursor) as usize;

let mut lock = self.file.lock().await;
let seek_from = self.get_seek_from(offset).ok_or(io::Error::new(
io::ErrorKind::UnexpectedEof,
Expand All @@ -95,18 +96,10 @@ where

let mut buf = vec![0_u8; size];

let mut readed_byte = 0;
while readed_byte < size {
match lock.read(&mut buf).await {
Err(err) if readed_byte == 0 => return Err(err),
Ok(0) | Err(_) => break,
Ok(x) => readed_byte += x,
};
if let Err(err) = lock.read_exact(&mut buf).await {
log::warn!("tarball change at runtime, result in error: {}", err);
}
readed_byte = readed_byte.min(size);
self.cursor += readed_byte as u32;

buf.resize(readed_byte, 0_u8);
Ok(bytes::Bytes::from(buf))
}
}
Expand Down
9 changes: 7 additions & 2 deletions judger/src/language/builder.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use grpc::judger::JudgeResponse;
use grpc::judger::{JudgeResponse, JudgerCode};

use super::stage::{AssertionMode, StatusCode};

Expand Down Expand Up @@ -26,7 +26,12 @@ pub struct JudgeResult {

impl From<JudgeResult> for JudgeResponse {
fn from(value: JudgeResult) -> Self {
todo!()
JudgeResponse {
status: Into::<JudgerCode>::into(value.status) as i32,
time: value.time,
memory: value.memory,
accuracy: 0, // FIXME: accuracy
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions judger/src/language/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::{collections::BTreeMap, path::Path, pin::Pin, sync::Arc};

use async_stream::{stream, try_stream};
use futures_core::Stream;
use grpc::judger::LangInfo;
use rustix::path::Arg;
use tokio::{
fs::{read_dir, File},
Expand Down Expand Up @@ -46,8 +47,10 @@ pub async fn load_plugins(path: impl AsRef<Path>) -> Result<Vec<Plugin<File>>> {
let mut dir_list = read_dir(path).await?;
while let Some(entry) = dir_list.next_entry().await? {
let path = entry.path();
log::trace!("find potential plugin from {}", path.display());
let ext = path.extension();
if path.is_file() && ext.is_some() && ext.unwrap() == EXTENSION {
log::info!("load plugin from {}", path.display());
let plugin = Plugin::new(path).await?;
plugins.push(plugin);
}
Expand All @@ -72,6 +75,9 @@ impl Map<File> {
pub fn get(&self, id: &Uuid) -> Option<Plugin<File>> {
self.0.get(id).cloned()
}
pub fn iter(&self) -> impl Iterator<Item = &Plugin<File>> {
self.0.values()
}
}

impl JudgeResult {
Expand Down Expand Up @@ -121,7 +127,14 @@ impl<F> Plugin<F>
where
F: AsyncRead + AsyncSeek + Unpin + Send + Sync + 'static,
{
pub fn get_info(&self) -> &LangInfo {
&self.spec.info
}
pub async fn as_compiler(&self, source: Vec<u8>) -> Result<Compiler> {
log::trace!(
"create compiler from plugin {}",
self.spec.info.lang_name.as_str()
);
let filesystem = self.template.as_filesystem(self.spec.fs_limit);
filesystem.insert_by_path(self.spec.file.as_os_str(), source);
Ok(Compiler::new(self.spec.clone(), filesystem.mount().await?))
Expand All @@ -132,6 +145,7 @@ where
) -> Pin<Box<dyn Stream<Item = Result<JudgeResult>> + Send>> {
let compiler = trys!(self.as_compiler(args.source).await);
let maybe_runner = trys!(compiler.compile().await);
log::debug!("runner created");
let mut runner = trys!(maybe_runner, Ok(JudgeResult::compile_error()));

let mem_cpu = (args.mem, args.cpu);
Expand Down
40 changes: 32 additions & 8 deletions judger/src/language/spec.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{ffi::OsString, time::Duration};
use std::{ffi::OsString, str::FromStr, time::Duration};

use grpc::judger::LangInfo;
use serde::Deserialize;
use uuid::Uuid;

Expand Down Expand Up @@ -61,6 +62,7 @@ pub struct Spec {
pub compile_command: Vec<OsString>,
pub judge_command: Vec<OsString>,
pub file: OsString,
pub info: LangInfo,
}

impl Spec {
Expand Down Expand Up @@ -89,6 +91,7 @@ impl Spec {

// FIXME: use compsition instead
Self {
info: LangInfo::from(&raw),
id: raw.id,
fs_limit: raw.fs_limit.unwrap(),
compile_limit: Stat {
Expand All @@ -105,9 +108,19 @@ impl Spec {
output: raw.compile.output_limit.unwrap(),
walltime: Duration::from_nanos(raw.compile.walltime.unwrap()),
},
compile_command: raw.compile.command,
judge_command: raw.judge.command,
file: raw.file,
compile_command: raw
.compile
.command
.iter()
.map(|x| OsString::from(x))
.collect(),
judge_command: raw
.judge
.command
.iter()
.map(|x| OsString::from(x))
.collect(),
file: OsString::from(raw.file),
judge_cpu_factor: CpuFactor {
kernel: raw.judge.kernel_mem.unwrap(),
user: raw.judge.rt_time.unwrap(),
Expand All @@ -127,9 +140,9 @@ impl Spec {
}

#[derive(Deserialize)]
struct Raw {
pub struct Raw {
fs_limit: Option<u64>,
file: OsString,
file: String,
info: String,
extension: String,
name: String,
Expand All @@ -138,6 +151,17 @@ struct Raw {
judge: RawJudge,
}

impl<'a> From<&'a Raw> for LangInfo {
fn from(value: &'a Raw) -> Self {
LangInfo {
lang_uid: value.id.to_string(),
lang_name: value.name.clone(),
info: value.info.clone(),
lang_ext: value.extension.clone(),
}
}
}

impl Raw {
pub fn fill(&mut self) {
if self.fs_limit.is_none() {
Expand All @@ -150,7 +174,7 @@ impl Raw {

#[derive(Deserialize)]
struct RawCompile {
command: Vec<OsString>,
command: Vec<String>,
kernel_mem: Option<u64>,
memory: Option<u64>,
user_mem: Option<u64>,
Expand Down Expand Up @@ -206,7 +230,7 @@ impl Default for RawCompile {

#[derive(Deserialize)]
struct RawJudge {
command: Vec<OsString>,
command: Vec<String>,
kernel_mem: Option<u64>,
rt_time: Option<u64>,
memory_multiplier: Option<f64>,
Expand Down
4 changes: 3 additions & 1 deletion judger/src/language/stage/compile.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::time;
use std::{path::PathBuf, sync::Arc, time::Duration};

use crate::{
Expand Down Expand Up @@ -26,7 +27,8 @@ impl Compiler {
let process = Process::new(ctx)?;
let corpse = process.wait(Vec::new()).await?;
if !corpse.success() {
log::debug!("compile failed {:?}", corpse.status());
log::trace!("compile failed, corpse: {:?}", corpse);
tokio::time::sleep(Duration::from_secs(3600)).await;
return Ok(None);
}

Expand Down
Loading

0 comments on commit 2811cd3

Please sign in to comment.