refactor(code-runner): default CODE_RUNNER_LANGUAGES to all-open
CODE_RUNNER_LANGUAGES 未设置时,白名单不再默认为 python,node, 而是放行 LANGUAGES 注册表里的全部语言。该环境变量变为「可选的收窄开关」: 新增语言到注册表即可默认启用,无需再同步运维白名单(避免两边脱节, 如本次 go/rust 就因 .env 未同步白名单导致 is_supported_lang 拒绝)。 - RunnerConfig.languages: Vec<String> → Option<Vec<String>>, None 表示不限制 - is_supported_lang: Option 为 None 时直接放行注册表语言 - 测试 is_supported_lang_default_whitelist → is_supported_lang_default_all_open, 断言 go/rust 在默认(未设白名单)下可用
This commit is contained in:
parent
75767661ac
commit
2f6f8e549d
@ -140,7 +140,8 @@ CODE_RUNNER_MAX_CPU_CORES=2.0
|
|||||||
CODE_RUNNER_MAX_MEMORY_MB=1024
|
CODE_RUNNER_MAX_MEMORY_MB=1024
|
||||||
CODE_RUNNER_MAX_TIMEOUT_SECS=30
|
CODE_RUNNER_MAX_TIMEOUT_SECS=30
|
||||||
CODE_RUNNER_MAX_OUTPUT_BYTES=1048576
|
CODE_RUNNER_MAX_OUTPUT_BYTES=1048576
|
||||||
CODE_RUNNER_LANGUAGES=python,node,go,rust
|
# 默认全开:注册表里的语言均可用。设置则收窄到逗号分隔列表(如 python,node)。
|
||||||
|
# CODE_RUNNER_LANGUAGES=python,node
|
||||||
DOCKER_SOCKET_PATH=/var/run/docker.sock
|
DOCKER_SOCKET_PATH=/var/run/docker.sock
|
||||||
|
|
||||||
# Rate limits (governor keyed limiters)
|
# Rate limits (governor keyed limiters)
|
||||||
|
|||||||
@ -97,7 +97,7 @@ CODE_RUNNER_MAX_OUTPUT_BYTES=1048576 # hard cap on stdout+stderr captured
|
|||||||
CODE_RUNNER_MAX_SOURCE_BYTES=65536 # max source size accepted by StartExec
|
CODE_RUNNER_MAX_SOURCE_BYTES=65536 # max source size accepted by StartExec
|
||||||
CODE_RUNNER_QUEUE_TIMEOUT_SECS=30 # how long a task waits for a container slot before failing
|
CODE_RUNNER_QUEUE_TIMEOUT_SECS=30 # how long a task waits for a container slot before failing
|
||||||
CODE_RUNNER_TASK_TTL_SECS=300 # DashMap task entry lifetime (gc_old_tasks)
|
CODE_RUNNER_TASK_TTL_SECS=300 # DashMap task entry lifetime (gc_old_tasks)
|
||||||
CODE_RUNNER_LANGUAGES=python,node # ops whitelist (must also exist in LANGUAGES registry)
|
CODE_RUNNER_LANGUAGES= # unset = all registered langs; set a comma-list to narrow (e.g. python,node)
|
||||||
DOCKER_SOCKET_PATH=/var/run/docker.sock
|
DOCKER_SOCKET_PATH=/var/run/docker.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
//! [`parse_fence_info`] 解析 markdown 围栏代码块的信息串,识别 `runnable` 标记与
|
//! [`parse_fence_info`] 解析 markdown 围栏代码块的信息串,识别 `runnable` 标记与
|
||||||
//! 可选的 JSON 资源覆盖(如 `python runnable {"timeout_secs":10}`)。
|
//! 可选的 JSON 资源覆盖(如 `python runnable {"timeout_secs":10}`)。
|
||||||
//!
|
//!
|
||||||
//! 实际可用语言还受 `RUNNER_CONFIG.languages`(环境变量 `CODE_RUNNER_LANGUAGES`)双重约束:
|
//! 实际可用语言默认即注册表里的全部;若设置了 `CODE_RUNNER_LANGUAGES`
|
||||||
//! 既要在注册表中存在,也要在运维白名单中启用,才视为支持([`is_supported_lang`])。
|
//! 环境变量,则进一步收窄到该白名单内([`is_supported_lang`])。
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
@ -24,8 +24,8 @@ pub struct LanguageDef {
|
|||||||
pub allow_network: bool,
|
pub allow_network: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 内置语言注册表。新增语言时在此 `insert`,并在 `.env.example` / `CODE_RUNNER_LANGUAGES`
|
/// 内置语言注册表。新增语言时在此 `insert` 即可默认启用;
|
||||||
/// 中默认启用。
|
/// 若运维需要收窄,设置 `CODE_RUNNER_LANGUAGES` 为逗号分隔列表。
|
||||||
pub static LANGUAGES: LazyLock<HashMap<String, LanguageDef>> = LazyLock::new(|| {
|
pub static LANGUAGES: LazyLock<HashMap<String, LanguageDef>> = LazyLock::new(|| {
|
||||||
let mut m = HashMap::new();
|
let mut m = HashMap::new();
|
||||||
|
|
||||||
@ -106,10 +106,16 @@ pub static LANGUAGES: LazyLock<HashMap<String, LanguageDef>> = LazyLock::new(||
|
|||||||
m
|
m
|
||||||
});
|
});
|
||||||
|
|
||||||
/// 同时存在于注册表与运维白名单 (`RUNNER_CONFIG.languages`) 才视为支持。
|
/// 是否支持该语言:必须在 LANGUAGES 注册表中存在。
|
||||||
|
/// 若设置了 `CODE_RUNNER_LANGUAGES`,还需同时在该白名单内(用于收窄可用语言);
|
||||||
|
/// 未设置则注册表里的语言全部放行。
|
||||||
pub fn is_supported_lang(lang: &str) -> bool {
|
pub fn is_supported_lang(lang: &str) -> bool {
|
||||||
let clean = lang.trim().to_lowercase();
|
let clean = lang.trim().to_lowercase();
|
||||||
RUNNER_CONFIG.languages.iter().any(|l| l == &clean) && LANGUAGES.contains_key(&clean)
|
LANGUAGES.contains_key(&clean)
|
||||||
|
&& RUNNER_CONFIG
|
||||||
|
.languages
|
||||||
|
.as_ref()
|
||||||
|
.is_none_or(|list| list.iter().any(|l| l == &clean))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 解析围栏代码块的 info string。
|
/// 解析围栏代码块的 info string。
|
||||||
@ -202,11 +208,14 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn is_supported_lang_default_whitelist() {
|
fn is_supported_lang_default_all_open() {
|
||||||
// 默认 CODE_RUNNER_LANGUAGES=python,node
|
// 默认未设 CODE_RUNNER_LANGUAGES:注册表里的语言全部放行。
|
||||||
assert!(is_supported_lang("python"));
|
assert!(is_supported_lang("python"));
|
||||||
assert!(is_supported_lang("node"));
|
assert!(is_supported_lang("node"));
|
||||||
assert!(!is_supported_lang("rust"));
|
assert!(is_supported_lang("go"));
|
||||||
|
assert!(is_supported_lang("rust"));
|
||||||
|
// 未注册的语言仍不支持。
|
||||||
|
assert!(!is_supported_lang("ruby"));
|
||||||
assert!(!is_supported_lang(""));
|
assert!(!is_supported_lang(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,9 @@ pub struct RunnerConfig {
|
|||||||
pub queue_timeout_secs: u64,
|
pub queue_timeout_secs: u64,
|
||||||
pub task_ttl_secs: u64,
|
pub task_ttl_secs: u64,
|
||||||
pub docker_socket_path: String,
|
pub docker_socket_path: String,
|
||||||
pub languages: Vec<String>,
|
/// 语言白名单。`None` 表示不限制——注册表里的所有语言均视为支持;
|
||||||
|
/// `Some(list)` 表示收窄到列表内(仍须同时在 LANGUAGES 注册表存在)。
|
||||||
|
pub languages: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
@ -36,8 +38,11 @@ fn parse_allow_network(v: &str) -> bool {
|
|||||||
|
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
pub static RUNNER_CONFIG: LazyLock<RunnerConfig> = LazyLock::new(|| {
|
pub static RUNNER_CONFIG: LazyLock<RunnerConfig> = LazyLock::new(|| {
|
||||||
let languages_str = env::var("CODE_RUNNER_LANGUAGES").unwrap_or_else(|_| "python,node".to_string());
|
// CODE_RUNNER_LANGUAGES 未设置时默认全开(None):注册表里的语言均可用,
|
||||||
let languages = languages_str.split(',').map(|s| s.trim().to_lowercase()).collect();
|
// 新增语言无需同步白名单。设置为逗号分隔列表则收窄到这些语言。
|
||||||
|
let languages = env::var("CODE_RUNNER_LANGUAGES").ok().map(|s| {
|
||||||
|
s.split(',').map(|t| t.trim().to_lowercase()).filter(|t| !t.is_empty()).collect()
|
||||||
|
});
|
||||||
|
|
||||||
RunnerConfig {
|
RunnerConfig {
|
||||||
max_cpu_cores: env::var("CODE_RUNNER_MAX_CPU_CORES").ok().and_then(|v| v.parse().ok()).unwrap_or(2.0),
|
max_cpu_cores: env::var("CODE_RUNNER_MAX_CPU_CORES").ok().and_then(|v| v.parse().ok()).unwrap_or(2.0),
|
||||||
@ -118,7 +123,7 @@ mod tests {
|
|||||||
queue_timeout_secs: 1,
|
queue_timeout_secs: 1,
|
||||||
task_ttl_secs: 1,
|
task_ttl_secs: 1,
|
||||||
docker_socket_path: "".to_string(),
|
docker_socket_path: "".to_string(),
|
||||||
languages: vec![],
|
languages: None,
|
||||||
};
|
};
|
||||||
let raw = ResourceLimits {
|
let raw = ResourceLimits {
|
||||||
cpu_cores: 1.0,
|
cpu_cores: 1.0,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user