mirror of
https://github.com/rustfs/rustfs.git
synced 2026-01-16 17:20:33 +00:00
feat: translate chinese to english (#402)
* Checkpoint before follow-up message Co-authored-by: anzhengchao <anzhengchao@gmail.com> * Translate project documentation and comments from Chinese to English Co-authored-by: anzhengchao <anzhengchao@gmail.com> * Fix typo: "unparseable" to "unparsable" in version test comment Co-authored-by: anzhengchao <anzhengchao@gmail.com> * Refactor compression test code with minor syntax improvements Co-authored-by: anzhengchao <anzhengchao@gmail.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
146
Makefile
146
Makefile
@@ -1,5 +1,5 @@
|
||||
###########
|
||||
# 远程开发,需要 VSCode 安装 Dev Containers, Remote SSH, Remote Explorer
|
||||
# Remote development requires VSCode with Dev Containers, Remote SSH, Remote Explorer
|
||||
# https://code.visualstudio.com/docs/remote/containers
|
||||
###########
|
||||
DOCKER_CLI ?= docker
|
||||
@@ -126,7 +126,7 @@ docker-buildx-push:
|
||||
.PHONY: docker-buildx-version
|
||||
docker-buildx-version:
|
||||
@if [ -z "$(VERSION)" ]; then \
|
||||
echo "❌ 错误: 请指定版本, 例如: make docker-buildx-version VERSION=v1.0.0"; \
|
||||
echo "❌ Error: Please specify version, example: make docker-buildx-version VERSION=v1.0.0"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "🏗️ Building multi-architecture production Docker images (version: $(VERSION))..."
|
||||
@@ -135,7 +135,7 @@ docker-buildx-version:
|
||||
.PHONY: docker-buildx-push-version
|
||||
docker-buildx-push-version:
|
||||
@if [ -z "$(VERSION)" ]; then \
|
||||
echo "❌ 错误: 请指定版本, 例如: make docker-buildx-push-version VERSION=v1.0.0"; \
|
||||
echo "❌ Error: Please specify version, example: make docker-buildx-push-version VERSION=v1.0.0"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "🚀 Building and pushing multi-architecture production Docker images (version: $(VERSION))..."
|
||||
@@ -168,11 +168,11 @@ docker-dev-local:
|
||||
.PHONY: docker-dev-push
|
||||
docker-dev-push:
|
||||
@if [ -z "$(REGISTRY)" ]; then \
|
||||
echo "❌ 错误: 请指定镜像仓库, 例如: make docker-dev-push REGISTRY=ghcr.io/username"; \
|
||||
echo "❌ Error: Please specify registry, example: make docker-dev-push REGISTRY=ghcr.io/username"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "🚀 Building and pushing multi-architecture development Docker images..."
|
||||
@echo "💡 推送到仓库: $(REGISTRY)"
|
||||
@echo "💡 Pushing to registry: $(REGISTRY)"
|
||||
$(DOCKER_CLI) buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--file $(DOCKERFILE_SOURCE) \
|
||||
@@ -249,7 +249,7 @@ dev-env-restart: dev-env-stop dev-env-start
|
||||
.PHONY: docker-inspect-multiarch
|
||||
docker-inspect-multiarch:
|
||||
@if [ -z "$(IMAGE)" ]; then \
|
||||
echo "❌ 错误: 请指定镜像, 例如: make docker-inspect-multiarch IMAGE=rustfs/rustfs:latest"; \
|
||||
echo "❌ Error: Please specify image, example: make docker-inspect-multiarch IMAGE=rustfs/rustfs:latest"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "🔍 Inspecting multi-architecture image: $(IMAGE)"
|
||||
@@ -277,93 +277,93 @@ build-cross-all:
|
||||
|
||||
.PHONY: help-build
|
||||
help-build:
|
||||
@echo "🔨 RustFS 构建帮助:"
|
||||
@echo "🔨 RustFS Build Help:"
|
||||
@echo ""
|
||||
@echo "🚀 本地构建 (推荐使用):"
|
||||
@echo " make build # 构建 RustFS 二进制文件 (默认包含 console)"
|
||||
@echo " make build-dev # 开发模式构建"
|
||||
@echo " make build-musl # 构建 x86_64 musl 版本"
|
||||
@echo " make build-gnu # 构建 x86_64 GNU 版本"
|
||||
@echo " make build-musl-arm64 # 构建 aarch64 musl 版本"
|
||||
@echo " make build-gnu-arm64 # 构建 aarch64 GNU 版本"
|
||||
@echo "🚀 Local Build (Recommended):"
|
||||
@echo " make build # Build RustFS binary (includes console by default)"
|
||||
@echo " make build-dev # Development mode build"
|
||||
@echo " make build-musl # Build x86_64 musl version"
|
||||
@echo " make build-gnu # Build x86_64 GNU version"
|
||||
@echo " make build-musl-arm64 # Build aarch64 musl version"
|
||||
@echo " make build-gnu-arm64 # Build aarch64 GNU version"
|
||||
@echo ""
|
||||
@echo "🐳 Docker 构建:"
|
||||
@echo " make build-docker # 使用 Docker 容器构建"
|
||||
@echo " make build-docker BUILD_OS=ubuntu22.04 # 指定构建系统"
|
||||
@echo "🐳 Docker Build:"
|
||||
@echo " make build-docker # Build using Docker container"
|
||||
@echo " make build-docker BUILD_OS=ubuntu22.04 # Specify build system"
|
||||
@echo ""
|
||||
@echo "🏗️ 跨架构构建:"
|
||||
@echo " make build-cross-all # 构建所有架构的二进制文件"
|
||||
@echo "🏗️ Cross-architecture Build:"
|
||||
@echo " make build-cross-all # Build binaries for all architectures"
|
||||
@echo ""
|
||||
@echo "🔧 直接使用 build-rustfs.sh 脚本:"
|
||||
@echo " ./build-rustfs.sh --help # 查看脚本帮助"
|
||||
@echo " ./build-rustfs.sh --no-console # 构建时跳过 console 资源"
|
||||
@echo " ./build-rustfs.sh --force-console-update # 强制更新 console 资源"
|
||||
@echo " ./build-rustfs.sh --dev # 开发模式构建"
|
||||
@echo " ./build-rustfs.sh --sign # 签名二进制文件"
|
||||
@echo " ./build-rustfs.sh --platform x86_64-unknown-linux-gnu # 指定目标平台"
|
||||
@echo " ./build-rustfs.sh --skip-verification # 跳过二进制验证"
|
||||
@echo "🔧 Direct usage of build-rustfs.sh script:"
|
||||
@echo " ./build-rustfs.sh --help # View script help"
|
||||
@echo " ./build-rustfs.sh --no-console # Build without console resources"
|
||||
@echo " ./build-rustfs.sh --force-console-update # Force update console resources"
|
||||
@echo " ./build-rustfs.sh --dev # Development mode build"
|
||||
@echo " ./build-rustfs.sh --sign # Sign binary files"
|
||||
@echo " ./build-rustfs.sh --platform x86_64-unknown-linux-gnu # Specify target platform"
|
||||
@echo " ./build-rustfs.sh --skip-verification # Skip binary verification"
|
||||
@echo ""
|
||||
@echo "💡 build-rustfs.sh 脚本提供了更多选项、智能检测和二进制验证功能"
|
||||
@echo "💡 build-rustfs.sh script provides more options, smart detection and binary verification"
|
||||
|
||||
.PHONY: help-docker
|
||||
help-docker:
|
||||
@echo "🐳 Docker 多架构构建帮助:"
|
||||
@echo "🐳 Docker Multi-architecture Build Help:"
|
||||
@echo ""
|
||||
@echo "🚀 生产镜像构建 (推荐使用 docker-buildx.sh):"
|
||||
@echo " make docker-buildx # 构建生产多架构镜像(不推送)"
|
||||
@echo " make docker-buildx-push # 构建并推送生产多架构镜像"
|
||||
@echo " make docker-buildx-version VERSION=v1.0.0 # 构建指定版本"
|
||||
@echo " make docker-buildx-push-version VERSION=v1.0.0 # 构建并推送指定版本"
|
||||
@echo "🚀 Production Image Build (Recommended to use docker-buildx.sh):"
|
||||
@echo " make docker-buildx # Build production multi-arch image (no push)"
|
||||
@echo " make docker-buildx-push # Build and push production multi-arch image"
|
||||
@echo " make docker-buildx-version VERSION=v1.0.0 # Build specific version"
|
||||
@echo " make docker-buildx-push-version VERSION=v1.0.0 # Build and push specific version"
|
||||
@echo ""
|
||||
@echo "🔧 开发/源码镜像构建 (本地开发测试):"
|
||||
@echo " make docker-dev # 构建开发多架构镜像(无法本地加载)"
|
||||
@echo " make docker-dev-local # 构建开发单架构镜像(本地加载)"
|
||||
@echo " make docker-dev-push REGISTRY=xxx # 构建并推送开发镜像"
|
||||
@echo "🔧 Development/Source Image Build (Local development testing):"
|
||||
@echo " make docker-dev # Build dev multi-arch image (cannot load locally)"
|
||||
@echo " make docker-dev-local # Build dev single-arch image (local load)"
|
||||
@echo " make docker-dev-push REGISTRY=xxx # Build and push dev image"
|
||||
@echo ""
|
||||
@echo "🏗️ 本地生产镜像构建 (替代方案):"
|
||||
@echo " make docker-buildx-production-local # 本地构建生产单架构镜像"
|
||||
@echo "🏗️ Local Production Image Build (Alternative):"
|
||||
@echo " make docker-buildx-production-local # Build production single-arch image locally"
|
||||
@echo ""
|
||||
@echo "📦 单架构构建 (传统方式):"
|
||||
@echo " make docker-build-production # 构建单架构生产镜像"
|
||||
@echo " make docker-build-source # 构建单架构源码镜像"
|
||||
@echo "📦 Single-architecture Build (Traditional way):"
|
||||
@echo " make docker-build-production # Build single-arch production image"
|
||||
@echo " make docker-build-source # Build single-arch source image"
|
||||
@echo ""
|
||||
@echo "🚀 开发环境管理:"
|
||||
@echo " make dev-env-start # 启动开发容器环境"
|
||||
@echo " make dev-env-stop # 停止开发容器环境"
|
||||
@echo " make dev-env-restart # 重启开发容器环境"
|
||||
@echo "🚀 Development Environment Management:"
|
||||
@echo " make dev-env-start # Start development container environment"
|
||||
@echo " make dev-env-stop # Stop development container environment"
|
||||
@echo " make dev-env-restart # Restart development container environment"
|
||||
@echo ""
|
||||
@echo "🔧 辅助工具:"
|
||||
@echo " make build-cross-all # 构建所有架构的二进制文件"
|
||||
@echo " make docker-inspect-multiarch IMAGE=xxx # 检查镜像的架构支持"
|
||||
@echo "🔧 Auxiliary Tools:"
|
||||
@echo " make build-cross-all # Build binaries for all architectures"
|
||||
@echo " make docker-inspect-multiarch IMAGE=xxx # Check image architecture support"
|
||||
@echo ""
|
||||
@echo "📋 环境变量:"
|
||||
@echo " REGISTRY 镜像仓库地址 (推送时需要)"
|
||||
@echo " DOCKERHUB_USERNAME Docker Hub 用户名"
|
||||
@echo " DOCKERHUB_TOKEN Docker Hub 访问令牌"
|
||||
@echo " GITHUB_TOKEN GitHub 访问令牌"
|
||||
@echo "📋 Environment Variables:"
|
||||
@echo " REGISTRY Image registry address (required for push)"
|
||||
@echo " DOCKERHUB_USERNAME Docker Hub username"
|
||||
@echo " DOCKERHUB_TOKEN Docker Hub access token"
|
||||
@echo " GITHUB_TOKEN GitHub access token"
|
||||
@echo ""
|
||||
@echo "💡 建议:"
|
||||
@echo " - 生产用途: 使用 docker-buildx* 命令 (基于预编译二进制)"
|
||||
@echo " - 本地开发: 使用 docker-dev* 命令 (从源码构建)"
|
||||
@echo " - 开发环境: 使用 dev-env-* 命令管理开发容器"
|
||||
@echo "💡 Suggestions:"
|
||||
@echo " - Production use: Use docker-buildx* commands (based on precompiled binaries)"
|
||||
@echo " - Local development: Use docker-dev* commands (build from source)"
|
||||
@echo " - Development environment: Use dev-env-* commands to manage dev containers"
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo "🦀 RustFS Makefile 帮助:"
|
||||
@echo "🦀 RustFS Makefile Help:"
|
||||
@echo ""
|
||||
@echo "📋 主要命令分类:"
|
||||
@echo " make help-build # 显示构建相关帮助"
|
||||
@echo " make help-docker # 显示 Docker 相关帮助"
|
||||
@echo "📋 Main Command Categories:"
|
||||
@echo " make help-build # Show build-related help"
|
||||
@echo " make help-docker # Show Docker-related help"
|
||||
@echo ""
|
||||
@echo "🔧 代码质量:"
|
||||
@echo " make fmt # 格式化代码"
|
||||
@echo " make clippy # 运行 clippy 检查"
|
||||
@echo " make test # 运行测试"
|
||||
@echo " make pre-commit # 运行所有预提交检查"
|
||||
@echo "🔧 Code Quality:"
|
||||
@echo " make fmt # Format code"
|
||||
@echo " make clippy # Run clippy checks"
|
||||
@echo " make test # Run tests"
|
||||
@echo " make pre-commit # Run all pre-commit checks"
|
||||
@echo ""
|
||||
@echo "🚀 快速开始:"
|
||||
@echo " make build # 构建 RustFS 二进制"
|
||||
@echo " make docker-dev-local # 构建开发 Docker 镜像(本地)"
|
||||
@echo " make dev-env-start # 启动开发环境"
|
||||
@echo "🚀 Quick Start:"
|
||||
@echo " make build # Build RustFS binary"
|
||||
@echo " make docker-dev-local # Build development Docker image (local)"
|
||||
@echo " make dev-env-start # Start development environment"
|
||||
@echo ""
|
||||
@echo "💡 更多帮助请使用 'make help-build' 或 'make help-docker'"
|
||||
@echo "💡 For more help use 'make help-build' or 'make help-docker'"
|
||||
|
||||
@@ -158,7 +158,7 @@ pub fn Home() -> Element {
|
||||
Meta {
|
||||
name: "description",
|
||||
// TODO: translate to english
|
||||
content: "RustFS RustFS 用热门安全的 Rust 语言开发,兼容 S3 协议。适用于 AI/ML 及海量数据存储、大数据、互联网、工业和保密存储等全部场景。近乎免费使用。遵循 Apache 2 协议,支持国产保密设备和系统。",
|
||||
content: "RustFS is developed in the popular and secure Rust language, compatible with S3 protocol. Suitable for all scenarios including AI/ML and massive data storage, big data, internet, industrial and secure storage. Nearly free to use. Follows Apache 2 license, supports domestic security devices and systems.",
|
||||
}
|
||||
div { class: "min-h-screen flex flex-col items-center bg-white",
|
||||
div { class: "absolute top-4 right-6 flex space-x-2",
|
||||
|
||||
@@ -36,7 +36,7 @@ pub fn Navbar() -> Element {
|
||||
pub struct LoadingSpinnerProps {
|
||||
#[props(default = true)]
|
||||
loading: bool,
|
||||
#[props(default = "正在处理中...")]
|
||||
#[props(default = "Processing...")]
|
||||
text: &'static str,
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ pub fn Setting() -> Element {
|
||||
let config = config.read().clone();
|
||||
spawn(async move {
|
||||
if let Err(e) = service.read().restart(config).await {
|
||||
ServiceManager::show_error(&format!("发送重启命令失败:{e}"));
|
||||
ServiceManager::show_error(&format!("Failed to send restart command: {e}"));
|
||||
}
|
||||
// reset the status when you're done
|
||||
loading.set(false);
|
||||
@@ -209,7 +209,7 @@ pub fn Setting() -> Element {
|
||||
}
|
||||
LoadingSpinner {
|
||||
loading: loading.read().to_owned(),
|
||||
text: "服务处理中...",
|
||||
text: "Service processing...",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ impl RustFSConfig {
|
||||
if !stored_config.address.is_empty() && stored_config.address != Self::DEFAULT_ADDRESS_VALUE {
|
||||
config.address = stored_config.address;
|
||||
let (host, port) = Self::extract_host_port(config.address.as_str())
|
||||
.ok_or_else(|| format!("无法从地址 '{}' 中提取主机和端口", config.address))?;
|
||||
.ok_or_else(|| format!("Unable to extract host and port from address '{}'", config.address))?;
|
||||
config.host = host.to_string();
|
||||
config.port = port.to_string();
|
||||
}
|
||||
@@ -538,17 +538,17 @@ mod tests {
|
||||
address: "127.0.0.1:9000".to_string(),
|
||||
host: "127.0.0.1".to_string(),
|
||||
port: "9000".to_string(),
|
||||
access_key: "用户名".to_string(),
|
||||
secret_key: "密码 123".to_string(),
|
||||
domain_name: "测试.com".to_string(),
|
||||
volume_name: "/数据/存储".to_string(),
|
||||
access_key: "username".to_string(),
|
||||
secret_key: "password123".to_string(),
|
||||
domain_name: "test.com".to_string(),
|
||||
volume_name: "/data/storage".to_string(),
|
||||
console_address: "127.0.0.1:9001".to_string(),
|
||||
};
|
||||
|
||||
assert_eq!(config.access_key, "用户名");
|
||||
assert_eq!(config.secret_key, "密码 123");
|
||||
assert_eq!(config.domain_name, "测试.com");
|
||||
assert_eq!(config.volume_name, "/数据/存储");
|
||||
assert_eq!(config.access_key, "username");
|
||||
assert_eq!(config.secret_key, "password123");
|
||||
assert_eq!(config.domain_name, "test.com");
|
||||
assert_eq!(config.volume_name, "/data/storage");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -81,7 +81,7 @@ pub enum ServiceCommand {
|
||||
/// success: true,
|
||||
/// start_time: chrono::Local::now(),
|
||||
/// end_time: chrono::Local::now(),
|
||||
/// message: "服务启动成功".to_string(),
|
||||
/// message: "Service started successfully".to_string(),
|
||||
/// };
|
||||
///
|
||||
/// println!("{:?}", result);
|
||||
@@ -175,7 +175,7 @@ impl ServiceManager {
|
||||
/// ```
|
||||
async fn prepare_service() -> Result<PathBuf, Box<dyn Error>> {
|
||||
// get the user directory
|
||||
let home_dir = dirs::home_dir().ok_or("无法获取用户目录")?;
|
||||
let home_dir = dirs::home_dir().ok_or("Unable to get user directory")?;
|
||||
let rustfs_dir = home_dir.join("rustfs");
|
||||
let bin_dir = rustfs_dir.join("bin");
|
||||
let data_dir = rustfs_dir.join("data");
|
||||
@@ -247,23 +247,23 @@ impl ServiceManager {
|
||||
match cmd {
|
||||
ServiceCommand::Start(config) => {
|
||||
if let Err(e) = Self::start_service(&config).await {
|
||||
Self::show_error(&format!("启动服务失败:{e}"));
|
||||
Self::show_error(&format!("Failed to start service: {e}"));
|
||||
}
|
||||
}
|
||||
ServiceCommand::Stop => {
|
||||
if let Err(e) = Self::stop_service().await {
|
||||
Self::show_error(&format!("停止服务失败:{e}"));
|
||||
Self::show_error(&format!("Failed to stop service: {e}"));
|
||||
}
|
||||
}
|
||||
ServiceCommand::Restart(config) => {
|
||||
if Self::check_service_status().await.is_some() {
|
||||
if let Err(e) = Self::stop_service().await {
|
||||
Self::show_error(&format!("重启服务失败:{e}"));
|
||||
Self::show_error(&format!("Failed to restart service: {e}"));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Err(e) = Self::start_service(&config).await {
|
||||
Self::show_error(&format!("重启服务失败:{e}"));
|
||||
Self::show_error(&format!("Failed to restart service: {e}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,7 +295,7 @@ impl ServiceManager {
|
||||
async fn start_service(config: &RustFSConfig) -> Result<(), Box<dyn Error>> {
|
||||
// Check if the service is already running
|
||||
if let Some(existing_pid) = Self::check_service_status().await {
|
||||
return Err(format!("服务已经在运行,PID: {existing_pid}").into());
|
||||
return Err(format!("Service is already running, PID: {existing_pid}").into());
|
||||
}
|
||||
|
||||
// Prepare the service program
|
||||
@@ -307,16 +307,16 @@ impl ServiceManager {
|
||||
}
|
||||
|
||||
// Extract the port from the configuration
|
||||
let main_port = Self::extract_port(&config.address).ok_or("无法解析主服务端口")?;
|
||||
let console_port = Self::extract_port(&config.console_address).ok_or("无法解析控制台端口")?;
|
||||
let main_port = Self::extract_port(&config.address).ok_or("Unable to parse main service port")?;
|
||||
let console_port = Self::extract_port(&config.console_address).ok_or("Unable to parse console port")?;
|
||||
|
||||
let host = config.address.split(':').next().ok_or("无法解析主机地址")?;
|
||||
let host = config.address.split(':').next().ok_or("Unable to parse host address")?;
|
||||
|
||||
// Check the port
|
||||
let ports = vec![main_port, console_port];
|
||||
for port in ports {
|
||||
if Self::is_port_in_use(host, port).await {
|
||||
return Err(format!("端口 {port} 已被占用").into());
|
||||
return Err(format!("Port {port} is already in use").into());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,12 +339,12 @@ impl ServiceManager {
|
||||
|
||||
// Check if the service started successfully
|
||||
if Self::is_port_in_use(host, main_port).await {
|
||||
Self::show_info(&format!("服务启动成功!进程 ID: {process_pid}"));
|
||||
Self::show_info(&format!("Service started successfully! Process ID: {process_pid}"));
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
child.kill().await?;
|
||||
Err("服务启动失败".into())
|
||||
Err("Service failed to start".into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,13 +378,13 @@ impl ServiceManager {
|
||||
// Verify that the service is indeed stopped
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
if Self::check_service_status().await.is_some() {
|
||||
return Err("服务停止失败".into());
|
||||
return Err("Service failed to stop".into());
|
||||
}
|
||||
Self::show_info("服务已成功停止");
|
||||
Self::show_info("Service stopped successfully");
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err("服务未运行".into())
|
||||
Err("Service is not running".into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,7 +411,7 @@ impl ServiceManager {
|
||||
/// ```
|
||||
pub(crate) fn show_error(message: &str) {
|
||||
rfd::MessageDialog::new()
|
||||
.set_title("错误")
|
||||
.set_title("Error")
|
||||
.set_description(message)
|
||||
.set_level(rfd::MessageLevel::Error)
|
||||
.show();
|
||||
@@ -426,7 +426,7 @@ impl ServiceManager {
|
||||
/// ```
|
||||
pub(crate) fn show_info(message: &str) {
|
||||
rfd::MessageDialog::new()
|
||||
.set_title("成功")
|
||||
.set_title("Success")
|
||||
.set_description(message)
|
||||
.set_level(rfd::MessageLevel::Info)
|
||||
.show();
|
||||
@@ -475,7 +475,7 @@ impl ServiceManager {
|
||||
self.command_tx.send(ServiceCommand::Start(config.clone())).await?;
|
||||
|
||||
let host = &config.host;
|
||||
let port = config.port.parse::<u16>().expect("无效的端口号");
|
||||
let port = config.port.parse::<u16>().expect("Invalid port number");
|
||||
// wait for the service to actually start
|
||||
let mut retries = 0;
|
||||
while retries < 30 {
|
||||
@@ -486,14 +486,14 @@ impl ServiceManager {
|
||||
success: true,
|
||||
start_time,
|
||||
end_time,
|
||||
message: "服务启动成功".to_string(),
|
||||
message: "Service started successfully".to_string(),
|
||||
});
|
||||
}
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
retries += 1;
|
||||
}
|
||||
|
||||
Err("服务启动超时".into())
|
||||
Err("Service start timeout".into())
|
||||
}
|
||||
|
||||
/// Stop the service
|
||||
@@ -537,14 +537,14 @@ impl ServiceManager {
|
||||
success: true,
|
||||
start_time,
|
||||
end_time,
|
||||
message: "服务停止成功".to_string(),
|
||||
message: "Service stopped successfully".to_string(),
|
||||
});
|
||||
}
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
retries += 1;
|
||||
}
|
||||
|
||||
Err("服务停止超时".into())
|
||||
Err("Service stop timeout".into())
|
||||
}
|
||||
|
||||
/// Restart the service
|
||||
@@ -590,7 +590,7 @@ impl ServiceManager {
|
||||
self.command_tx.send(ServiceCommand::Restart(config.clone())).await?;
|
||||
|
||||
let host = &config.host;
|
||||
let port = config.port.parse::<u16>().expect("无效的端口号");
|
||||
let port = config.port.parse::<u16>().expect("Invalid port number");
|
||||
|
||||
// wait for the service to restart
|
||||
let mut retries = 0;
|
||||
@@ -602,8 +602,8 @@ impl ServiceManager {
|
||||
Err(e) => {
|
||||
error!("save config error: {}", e);
|
||||
self.command_tx.send(ServiceCommand::Stop).await?;
|
||||
Self::show_error("保存配置失败");
|
||||
return Err("保存配置失败".into());
|
||||
Self::show_error("Failed to save configuration");
|
||||
return Err("Failed to save configuration".into());
|
||||
}
|
||||
}
|
||||
let end_time = chrono::Local::now();
|
||||
@@ -611,13 +611,13 @@ impl ServiceManager {
|
||||
success: true,
|
||||
start_time,
|
||||
end_time,
|
||||
message: "服务重启成功".to_string(),
|
||||
message: "Service restarted successfully".to_string(),
|
||||
});
|
||||
}
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
retries += 1;
|
||||
}
|
||||
Err("服务重启超时".into())
|
||||
Err("Service restart timeout".into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -802,10 +802,10 @@ mod tests {
|
||||
success: true,
|
||||
start_time: chrono::Local::now(),
|
||||
end_time: chrono::Local::now(),
|
||||
message: "操作成功 🎉".to_string(),
|
||||
message: "Operation successful 🎉".to_string(),
|
||||
};
|
||||
|
||||
assert_eq!(result.message, "操作成功 🎉");
|
||||
assert_eq!(result.message, "Operation successful 🎉");
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ use tracing_subscriber::util::SubscriberInitExt;
|
||||
/// that rotates log files daily
|
||||
pub fn init_logger() -> WorkerGuard {
|
||||
// configuring rolling logs rolling by day
|
||||
let home_dir = dirs::home_dir().expect("无法获取用户目录");
|
||||
let home_dir = dirs::home_dir().expect("Unable to get user directory");
|
||||
let rustfs_dir = home_dir.join("rustfs");
|
||||
let logs_dir = rustfs_dir.join("logs");
|
||||
let file_appender = RollingFileAppender::builder()
|
||||
|
||||
@@ -556,19 +556,19 @@ mod tests {
|
||||
fn test_index_add() -> io::Result<()> {
|
||||
let mut index = Index::new();
|
||||
|
||||
// 测试添加第一个索引
|
||||
// Test adding first index
|
||||
index.add(100, 1000)?;
|
||||
assert_eq!(index.info.len(), 1);
|
||||
assert_eq!(index.info[0].compressed_offset, 100);
|
||||
assert_eq!(index.info[0].uncompressed_offset, 1000);
|
||||
|
||||
// 测试添加相同未压缩偏移量的索引
|
||||
// Test adding index with same uncompressed offset
|
||||
index.add(200, 1000)?;
|
||||
assert_eq!(index.info.len(), 1);
|
||||
assert_eq!(index.info[0].compressed_offset, 200);
|
||||
assert_eq!(index.info[0].uncompressed_offset, 1000);
|
||||
|
||||
// 测试添加新的索引(确保距离足够大)
|
||||
// Test adding new index (ensure distance is large enough)
|
||||
index.add(300, 2000 + MIN_INDEX_DIST)?;
|
||||
assert_eq!(index.info.len(), 2);
|
||||
assert_eq!(index.info[1].compressed_offset, 300);
|
||||
@@ -581,14 +581,14 @@ mod tests {
|
||||
fn test_index_add_errors() {
|
||||
let mut index = Index::new();
|
||||
|
||||
// 添加初始索引
|
||||
// Add initial index
|
||||
index.add(100, 1000).unwrap();
|
||||
|
||||
// 测试添加更小的未压缩偏移量
|
||||
// Test adding smaller uncompressed offset
|
||||
let err = index.add(200, 500).unwrap_err();
|
||||
assert_eq!(err.kind(), io::ErrorKind::InvalidData);
|
||||
|
||||
// 测试添加更小的压缩偏移量
|
||||
// Test adding smaller compressed offset
|
||||
let err = index.add(50, 2000).unwrap_err();
|
||||
assert_eq!(err.kind(), io::ErrorKind::InvalidData);
|
||||
}
|
||||
@@ -599,22 +599,22 @@ mod tests {
|
||||
index.total_uncompressed = 1000 + MIN_INDEX_DIST * 3;
|
||||
index.total_compressed = 5000;
|
||||
|
||||
// 添加一些测试数据,确保索引间距满足 MIN_INDEX_DIST 要求
|
||||
// Add some test data, ensure index spacing meets MIN_INDEX_DIST requirement
|
||||
index.add(100, 1000)?;
|
||||
index.add(300, 1000 + MIN_INDEX_DIST)?;
|
||||
index.add(500, 1000 + MIN_INDEX_DIST * 2)?;
|
||||
|
||||
// 测试查找存在的偏移量
|
||||
// Test finding existing offset
|
||||
let (comp, uncomp) = index.find(1500)?;
|
||||
assert_eq!(comp, 100);
|
||||
assert_eq!(uncomp, 1000);
|
||||
|
||||
// 测试查找边界值
|
||||
// Test finding boundary value
|
||||
let (comp, uncomp) = index.find(1000 + MIN_INDEX_DIST)?;
|
||||
assert_eq!(comp, 300);
|
||||
assert_eq!(uncomp, 1000 + MIN_INDEX_DIST);
|
||||
|
||||
// 测试查找最后一个索引
|
||||
// Test finding last index
|
||||
let (comp, uncomp) = index.find(1000 + MIN_INDEX_DIST * 2)?;
|
||||
assert_eq!(comp, 500);
|
||||
assert_eq!(uncomp, 1000 + MIN_INDEX_DIST * 2);
|
||||
@@ -628,16 +628,16 @@ mod tests {
|
||||
index.total_uncompressed = 10000;
|
||||
index.total_compressed = 5000;
|
||||
|
||||
// 测试未初始化的索引
|
||||
// Test uninitialized index
|
||||
let uninit_index = Index::new();
|
||||
let err = uninit_index.find(1000).unwrap_err();
|
||||
assert_eq!(err.kind(), io::ErrorKind::Other);
|
||||
|
||||
// 测试超出范围的偏移量
|
||||
// Test offset out of range
|
||||
let err = index.find(15000).unwrap_err();
|
||||
assert_eq!(err.kind(), io::ErrorKind::UnexpectedEof);
|
||||
|
||||
// 测试负数偏移量
|
||||
// Test negative offset
|
||||
let err = match index.find(-1000) {
|
||||
Ok(_) => panic!("should be error"),
|
||||
Err(e) => e,
|
||||
@@ -650,15 +650,15 @@ mod tests {
|
||||
let mut index = Index::new();
|
||||
index.est_block_uncomp = MIN_INDEX_DIST;
|
||||
|
||||
// 添加超过最大索引数量的条目,确保间距满足 MIN_INDEX_DIST 要求
|
||||
// Add entries exceeding maximum index count, ensure spacing meets MIN_INDEX_DIST requirement
|
||||
for i in 0..MAX_INDEX_ENTRIES + 100 {
|
||||
index.add(i as i64 * 100, i as i64 * MIN_INDEX_DIST).unwrap();
|
||||
}
|
||||
|
||||
// 手动调用 reduce 方法
|
||||
// Manually call reduce method
|
||||
index.reduce();
|
||||
|
||||
// 验证索引数量是否被正确减少
|
||||
// Verify index count has been correctly reduced
|
||||
assert!(index.info.len() <= MAX_INDEX_ENTRIES);
|
||||
}
|
||||
|
||||
@@ -666,16 +666,16 @@ mod tests {
|
||||
fn test_index_json() -> io::Result<()> {
|
||||
let mut index = Index::new();
|
||||
|
||||
// 添加一些测试数据
|
||||
// Add some test data
|
||||
index.add(100, 1000)?;
|
||||
index.add(300, 2000 + MIN_INDEX_DIST)?;
|
||||
|
||||
// 测试 JSON 序列化
|
||||
// Test JSON serialization
|
||||
let json = index.to_json().unwrap();
|
||||
let json_str = String::from_utf8(json).unwrap();
|
||||
|
||||
println!("json_str: {json_str}");
|
||||
// 验证 JSON 内容
|
||||
// Verify JSON content
|
||||
|
||||
assert!(json_str.contains("\"compressed\": 100"));
|
||||
assert!(json_str.contains("\"uncompressed\": 1000"));
|
||||
|
||||
@@ -443,7 +443,7 @@ mod tests {
|
||||
let mut compressed = Vec::new();
|
||||
compress_reader.read_to_end(&mut compressed).await.unwrap();
|
||||
|
||||
// DecompressReader解包
|
||||
// DecompressReader unpacking
|
||||
let mut decompress_reader = DecompressReader::new(Cursor::new(compressed.clone()), CompressionAlgorithm::Gzip);
|
||||
let mut decompressed = Vec::new();
|
||||
decompress_reader.read_to_end(&mut decompressed).await.unwrap();
|
||||
@@ -460,7 +460,7 @@ mod tests {
|
||||
let mut compressed = Vec::new();
|
||||
compress_reader.read_to_end(&mut compressed).await.unwrap();
|
||||
|
||||
// DecompressReader解包
|
||||
// DecompressReader unpacking
|
||||
let mut decompress_reader = DecompressReader::new(Cursor::new(compressed.clone()), CompressionAlgorithm::Deflate);
|
||||
let mut decompressed = Vec::new();
|
||||
decompress_reader.read_to_end(&mut decompressed).await.unwrap();
|
||||
|
||||
@@ -223,7 +223,7 @@ mod tests {
|
||||
let n = etag_reader.read_to_end(&mut buf).await.unwrap();
|
||||
assert_eq!(n, data.len());
|
||||
assert_eq!(&buf, data);
|
||||
// 校验通过,etag应等于expected
|
||||
// Verification passed, etag should equal expected
|
||||
assert_eq!(etag_reader.try_resolve_etag(), Some(expected));
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ mod tests {
|
||||
let mut etag_reader = EtagReader::new(reader, Some(wrong_checksum));
|
||||
|
||||
let mut buf = Vec::new();
|
||||
// 校验失败,应该返回InvalidData错误
|
||||
// Verification failed, should return InvalidData error
|
||||
let err = etag_reader.read_to_end(&mut buf).await.unwrap_err();
|
||||
assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ mod tests {
|
||||
let hardlimit = HardLimitReader::new(reader, 3);
|
||||
let mut r = hardlimit;
|
||||
let mut buf = vec![0u8; 10];
|
||||
// 读取超限,应该返回错误
|
||||
// Reading exceeds limit, should return error
|
||||
let err = match read_full(&mut r, &mut buf).await {
|
||||
Ok(n) => {
|
||||
println!("Read {n} bytes");
|
||||
|
||||
@@ -53,9 +53,9 @@ pub trait QueryExecution: Send + Sync {
|
||||
fn query_type(&self) -> QueryType {
|
||||
QueryType::Batch
|
||||
}
|
||||
// 开始
|
||||
// Start
|
||||
async fn start(&self) -> QueryResult<Output>;
|
||||
// 停止
|
||||
// Stop
|
||||
fn cancel(&self) -> QueryResult<()>;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,15 +87,15 @@ impl PhysicalPlanner for DefaultPhysicalPlanner {
|
||||
logical_plan: &LogicalPlan,
|
||||
session: &SessionCtx,
|
||||
) -> QueryResult<Arc<dyn ExecutionPlan>> {
|
||||
// 将扩展的物理计划优化规则注入 df 的 session state
|
||||
// Inject extended physical plan optimization rules into df's session state
|
||||
let new_state = SessionStateBuilder::new_from_existing(session.inner().clone())
|
||||
.with_physical_optimizer_rules(self.ext_physical_optimizer_rules.clone())
|
||||
.build();
|
||||
|
||||
// 通过扩展的物理计划转换规则构造 df 的 Physical Planner
|
||||
// Construct df's Physical Planner with extended physical plan transformation rules
|
||||
let planner = DFDefaultPhysicalPlanner::with_extension_planners(self.ext_physical_transform_rules.clone());
|
||||
|
||||
// 执行 df 的物理计划规划及优化
|
||||
// Execute df's physical plan planning and optimization
|
||||
planner
|
||||
.create_physical_plan(logical_plan, &new_state)
|
||||
.await
|
||||
|
||||
@@ -289,44 +289,44 @@ mod tests {
|
||||
CompressionAlgorithm::Snappy,
|
||||
];
|
||||
|
||||
println!("\n压缩算法基准测试结果:");
|
||||
println!("\nCompression algorithm benchmark results:");
|
||||
println!(
|
||||
"{:<10} {:<10} {:<15} {:<15} {:<15}",
|
||||
"数据大小", "算法", "压缩时间(ms)", "压缩后大小", "压缩率"
|
||||
"Data Size", "Algorithm", "Compress Time(ms)", "Compressed Size", "Compression Ratio"
|
||||
);
|
||||
|
||||
for size in sizes {
|
||||
// 生成可压缩的数据(重复的文本模式)
|
||||
// Generate compressible data (repeated text pattern)
|
||||
let pattern = b"Hello, this is a test pattern that will be repeated multiple times to create compressible data. ";
|
||||
let data: Vec<u8> = pattern.iter().cycle().take(size).copied().collect();
|
||||
|
||||
for algo in algorithms {
|
||||
// 压缩测试
|
||||
// Compression test
|
||||
let start = Instant::now();
|
||||
let compressed = compress_block(&data, algo);
|
||||
let compress_time = start.elapsed();
|
||||
let compression_time = start.elapsed();
|
||||
|
||||
// 解压测试
|
||||
// Decompression test
|
||||
let start = Instant::now();
|
||||
let _decompressed = decompress_block(&compressed, algo).unwrap();
|
||||
let _decompress_time = start.elapsed();
|
||||
let _decompression_time = start.elapsed();
|
||||
|
||||
// 计算压缩率
|
||||
// Calculate compression ratio
|
||||
let compression_ratio = (size as f64 / compressed.len() as f64) as f32;
|
||||
|
||||
println!(
|
||||
"{:<10} {:<10} {:<15.2} {:<15} {:<15.2}x",
|
||||
format!("{}KB", size / 1024),
|
||||
algo.as_str(),
|
||||
compress_time.as_secs_f64() * 1000.0,
|
||||
compression_time.as_secs_f64() * 1000.0,
|
||||
compressed.len(),
|
||||
compression_ratio
|
||||
);
|
||||
|
||||
// 验证解压结果
|
||||
// Verify decompression result
|
||||
assert_eq!(_decompressed, data);
|
||||
}
|
||||
println!(); // 添加空行分隔不同大小的结果
|
||||
println!(); // Add blank line to separate results of different sizes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,18 +110,18 @@ use siphasher::sip::SipHasher;
|
||||
pub const EMPTY_STRING_SHA256_HASH: &str = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
||||
|
||||
pub fn sip_hash(key: &str, cardinality: usize, id: &[u8; 16]) -> usize {
|
||||
// 你的密钥,必须是 16 字节
|
||||
// Your key, must be 16 bytes
|
||||
|
||||
// 计算字符串的 SipHash 值
|
||||
// Calculate SipHash value of the string
|
||||
let result = SipHasher::new_with_key(id).hash(key.as_bytes());
|
||||
|
||||
result as usize % cardinality
|
||||
(result as usize) % cardinality
|
||||
}
|
||||
|
||||
pub fn crc_hash(key: &str, cardinality: usize) -> usize {
|
||||
let mut hasher = Hasher::new(); // 创建一个新的哈希器
|
||||
let mut hasher = Hasher::new(); // Create a new hasher
|
||||
|
||||
hasher.update(key.as_bytes()); // 更新哈希状态,添加数据
|
||||
hasher.update(key.as_bytes()); // Update hash state, add data
|
||||
|
||||
let checksum = hasher.finalize();
|
||||
|
||||
|
||||
@@ -599,7 +599,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_format_consistency_with_extensions() {
|
||||
// 测试格式与扩展名的一致性
|
||||
// Test format consistency with extensions
|
||||
let consistency_tests = vec![
|
||||
(CompressionFormat::Gzip, "gz"),
|
||||
(CompressionFormat::Bzip2, "bz2"),
|
||||
@@ -721,20 +721,20 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_compression_format_clone_and_copy() {
|
||||
// 测试 CompressionFormat 是否可以被复制
|
||||
// Test if CompressionFormat can be copied
|
||||
let format = CompressionFormat::Gzip;
|
||||
let format_copy = format;
|
||||
|
||||
// 验证复制后的值相等
|
||||
// Verify copied values are equal
|
||||
assert_eq!(format, format_copy);
|
||||
|
||||
// 验证原值仍然可用
|
||||
// Verify original value is still usable
|
||||
assert_eq!(format, CompressionFormat::Gzip);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compression_format_match_exhaustiveness() {
|
||||
// 测试 match 语句的完整性
|
||||
// Test match statement completeness
|
||||
fn handle_format(format: CompressionFormat) -> &'static str {
|
||||
match format {
|
||||
CompressionFormat::Gzip => "gzip",
|
||||
@@ -748,7 +748,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
// 测试所有变体都有对应的处理
|
||||
// Test all variants have corresponding handlers
|
||||
assert_eq!(handle_format(CompressionFormat::Gzip), "gzip");
|
||||
assert_eq!(handle_format(CompressionFormat::Bzip2), "bzip2");
|
||||
assert_eq!(handle_format(CompressionFormat::Zip), "zip");
|
||||
@@ -760,10 +760,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_extension_parsing_performance() {
|
||||
// 测试扩展名解析的性能(简单的性能测试)
|
||||
// Test extension parsing performance (simple performance test)
|
||||
let extensions = vec!["gz", "bz2", "zip", "xz", "zlib", "zst", "unknown"];
|
||||
|
||||
// 多次调用以测试性能一致性
|
||||
// Multiple calls to test performance consistency
|
||||
for _ in 0..1000 {
|
||||
for ext in &extensions {
|
||||
let _format = CompressionFormat::from_extension(ext);
|
||||
@@ -775,7 +775,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_format_default_behavior() {
|
||||
// 测试格式的默认行为
|
||||
// Test format default behavior
|
||||
let unknown_extensions = vec!["", "txt", "doc", "pdf", "unknown_ext"];
|
||||
|
||||
for ext in unknown_extensions {
|
||||
@@ -786,7 +786,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_compression_level() {
|
||||
// 测试压缩级别
|
||||
// Test compression level
|
||||
let default_level = CompressionLevel::default();
|
||||
assert_eq!(default_level, CompressionLevel::Default);
|
||||
|
||||
@@ -800,7 +800,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_format_extension() {
|
||||
// 测试格式扩展名获取
|
||||
// Test format extension retrieval
|
||||
assert_eq!(CompressionFormat::Gzip.extension(), "gz");
|
||||
assert_eq!(CompressionFormat::Bzip2.extension(), "bz2");
|
||||
assert_eq!(CompressionFormat::Zip.extension(), "zip");
|
||||
@@ -813,7 +813,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_format_is_supported() {
|
||||
// 测试格式支持检查
|
||||
// Test format support check
|
||||
assert!(CompressionFormat::Gzip.is_supported());
|
||||
assert!(CompressionFormat::Bzip2.is_supported());
|
||||
assert!(CompressionFormat::Zip.is_supported());
|
||||
@@ -826,7 +826,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_format_from_path() {
|
||||
// 测试从路径识别格式
|
||||
// Test format recognition from path
|
||||
use std::path::Path;
|
||||
|
||||
assert_eq!(CompressionFormat::from_path("file.gz"), CompressionFormat::Gzip);
|
||||
@@ -840,7 +840,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_encoder_supported_formats() {
|
||||
// 测试支持的格式能够创建编码器
|
||||
// Test supported formats can create encoders
|
||||
use std::io::Cursor;
|
||||
|
||||
let output = Vec::new();
|
||||
@@ -853,7 +853,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_encoder_unsupported_formats() {
|
||||
// 测试不支持的格式返回错误
|
||||
// Test unsupported formats return errors
|
||||
use std::io::Cursor;
|
||||
|
||||
let output1 = Vec::new();
|
||||
@@ -900,7 +900,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_decompressor_creation() {
|
||||
// 测试解压缩器创建
|
||||
// Test decompressor creation
|
||||
let decompressor = Decompressor::new(CompressionFormat::Gzip);
|
||||
assert_eq!(decompressor.format, CompressionFormat::Gzip);
|
||||
|
||||
@@ -910,7 +910,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_zip_entry_creation() {
|
||||
// 测试 ZIP 条目信息创建
|
||||
// Test ZIP entry info creation
|
||||
let entry = ZipEntry {
|
||||
name: "test.txt".to_string(),
|
||||
size: 1024,
|
||||
@@ -928,7 +928,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_compression_level_variants() {
|
||||
// 测试压缩级别的所有变体
|
||||
// Test all compression level variants
|
||||
let levels = vec![
|
||||
CompressionLevel::Fastest,
|
||||
CompressionLevel::Best,
|
||||
@@ -938,14 +938,14 @@ mod tests {
|
||||
];
|
||||
|
||||
for level in levels {
|
||||
// 验证每个级别都有对应的 Debug 实现
|
||||
// Verify each level has corresponding Debug implementation
|
||||
let _debug_str = format!("{level:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_comprehensive_coverage() {
|
||||
// 测试格式的全面覆盖
|
||||
// Test comprehensive format coverage
|
||||
let all_formats = vec![
|
||||
CompressionFormat::Gzip,
|
||||
CompressionFormat::Bzip2,
|
||||
@@ -958,13 +958,13 @@ mod tests {
|
||||
];
|
||||
|
||||
for format in all_formats {
|
||||
// 验证每个格式都有扩展名
|
||||
// Verify each format has an extension
|
||||
let _ext = format.extension();
|
||||
|
||||
// 验证支持状态检查
|
||||
// Verify support status check
|
||||
let _supported = format.is_supported();
|
||||
|
||||
// 验证 Debug 实现
|
||||
// Verify Debug implementation
|
||||
let _debug = format!("{format:?}");
|
||||
}
|
||||
}
|
||||
@@ -975,7 +975,7 @@ mod tests {
|
||||
// use std::path::Path;
|
||||
// use tokio::fs::File;
|
||||
|
||||
// let input_path = "/Users/weisd/Downloads/wsd.tar.gz"; // 替换为你的压缩文件路径
|
||||
// let input_path = "/Users/weisd/Downloads/wsd.tar.gz"; // Replace with your compressed file path
|
||||
|
||||
// let f = File::open(input_path).await?;
|
||||
|
||||
@@ -994,8 +994,8 @@ mod tests {
|
||||
// )
|
||||
// .await
|
||||
// {
|
||||
// Ok(_) => println!("解压成功!"),
|
||||
// Err(e) => println!("解压失败:{}", e),
|
||||
// Ok(_) => println!("Decompression successful!"),
|
||||
// Err(e) => println!("Decompression failed: {}", e),
|
||||
// }
|
||||
|
||||
// Ok(())
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
# RustFS 管理员用户名
|
||||
# RustFS admin username
|
||||
RUSTFS_ROOT_USER=rustfsadmin
|
||||
# RustFS 管理员密码
|
||||
# RustFS admin password
|
||||
RUSTFS_ROOT_PASSWORD=rustfsadmin
|
||||
|
||||
# 数据卷配置示例路径:deploy/data/rustfs.env
|
||||
# RustFS 数据卷存储路径,支持多卷配置,vol1 到 vol4
|
||||
# Data volume configuration example path: deploy/data/rustfs.env
|
||||
# RustFS data volume storage path, supports multi-volume configuration, vol1 to vol4
|
||||
RUSTFS_VOLUMES="./deploy/deploy/vol{1...4}"
|
||||
# RustFS 服务启动参数,指定监听地址和端口
|
||||
# RustFS service startup parameters, specify listening address and port
|
||||
RUSTFS_OPTS="--address :9000"
|
||||
# RustFS 服务监听地址和端口
|
||||
# RustFS service listening address and port
|
||||
RUSTFS_ADDRESS=":9000"
|
||||
# 是否启用 RustFS 控制台功能
|
||||
# Whether to enable RustFS console functionality
|
||||
RUSTFS_CONSOLE_ENABLE=true
|
||||
# RustFS 服务域名配置
|
||||
# RustFS service domain configuration
|
||||
RUSTFS_SERVER_DOMAINS=127.0.0.1:9000
|
||||
# RustFS 许可证内容
|
||||
# RustFS license content
|
||||
RUSTFS_LICENSE="license content"
|
||||
# 可观测性配置Endpoint:http://localhost:4317
|
||||
# Observability configuration Endpoint: http://localhost:4317
|
||||
RUSTFS_OBS_ENDPOINT=http://localhost:4317
|
||||
# TLS 证书目录路径:deploy/certs
|
||||
# TLS certificate directory path: deploy/certs
|
||||
RUSTFS_TLS_PATH=/etc/default/tls
|
||||
@@ -7,21 +7,21 @@ type VersionParseResult = Result<(u32, u32, u32, Option<String>), Box<dyn std::e
|
||||
|
||||
#[allow(clippy::const_is_empty)]
|
||||
pub fn get_version() -> String {
|
||||
// 获取最新的 tag
|
||||
// Get the latest tag
|
||||
if let Ok(latest_tag) = get_latest_tag() {
|
||||
// 检查当前 commit 是否比最新 tag 更新
|
||||
// Check if current commit is newer than the latest tag
|
||||
if is_head_newer_than_tag(&latest_tag) {
|
||||
// 如果当前 commit 更新,则提升版本号
|
||||
// If current commit is newer, increment the version number
|
||||
if let Ok(new_version) = increment_version(&latest_tag) {
|
||||
return format!("refs/tags/{new_version}");
|
||||
}
|
||||
}
|
||||
|
||||
// 如果当前 commit 就是最新 tag,或者版本提升失败,返回当前 tag
|
||||
// If current commit is the latest tag, or version increment failed, return current tag
|
||||
return format!("refs/tags/{latest_tag}");
|
||||
}
|
||||
|
||||
// 如果没有 tag,使用原来的逻辑
|
||||
// If no tag exists, use original logic
|
||||
if !build::TAG.is_empty() {
|
||||
format!("refs/tags/{}", build::TAG)
|
||||
} else if !build::SHORT_COMMIT.is_empty() {
|
||||
@@ -31,7 +31,7 @@ pub fn get_version() -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取最新的 git tag
|
||||
/// Get the latest git tag
|
||||
fn get_latest_tag() -> Result<String, Box<dyn std::error::Error>> {
|
||||
let output = Command::new("git").args(["describe", "--tags", "--abbrev=0"]).output()?;
|
||||
|
||||
@@ -43,7 +43,7 @@ fn get_latest_tag() -> Result<String, Box<dyn std::error::Error>> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查当前 HEAD 是否比指定的 tag 更新
|
||||
/// Check if current HEAD is newer than specified tag
|
||||
fn is_head_newer_than_tag(tag: &str) -> bool {
|
||||
let output = Command::new("git")
|
||||
.args(["merge-base", "--is-ancestor", tag, "HEAD"])
|
||||
@@ -55,23 +55,23 @@ fn is_head_newer_than_tag(tag: &str) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
/// 提升版本号(增加 patch 版本)
|
||||
/// Increment version number (increase patch version)
|
||||
fn increment_version(version: &str) -> Result<String, Box<dyn std::error::Error>> {
|
||||
// 解析版本号,例如 "1.0.0-alpha.19" -> (1, 0, 0, Some("alpha.19"))
|
||||
// Parse version number, e.g. "1.0.0-alpha.19" -> (1, 0, 0, Some("alpha.19"))
|
||||
let (major, minor, patch, pre_release) = parse_version(version)?;
|
||||
|
||||
// 如果有预发布标识符,则增加预发布版本号
|
||||
// If there's a pre-release identifier, increment the pre-release version number
|
||||
if let Some(pre) = pre_release {
|
||||
if let Some(new_pre) = increment_pre_release(&pre) {
|
||||
return Ok(format!("{major}.{minor}.{patch}-{new_pre}"));
|
||||
}
|
||||
}
|
||||
|
||||
// 否则增加 patch 版本号
|
||||
// Otherwise increment patch version number
|
||||
Ok(format!("{major}.{minor}.{}", patch + 1))
|
||||
}
|
||||
|
||||
/// 解析版本号
|
||||
/// Parse version number
|
||||
pub fn parse_version(version: &str) -> VersionParseResult {
|
||||
let parts: Vec<&str> = version.split('-').collect();
|
||||
let base_version = parts[0];
|
||||
@@ -89,9 +89,9 @@ pub fn parse_version(version: &str) -> VersionParseResult {
|
||||
Ok((major, minor, patch, pre_release))
|
||||
}
|
||||
|
||||
/// 增加预发布版本号
|
||||
/// Increment pre-release version number
|
||||
fn increment_pre_release(pre_release: &str) -> Option<String> {
|
||||
// 处理形如 "alpha.19" 的预发布版本
|
||||
// Handle pre-release versions like "alpha.19"
|
||||
let parts: Vec<&str> = pre_release.split('.').collect();
|
||||
if parts.len() == 2 {
|
||||
if let Ok(num) = parts[1].parse::<u32>() {
|
||||
@@ -99,7 +99,7 @@ fn increment_pre_release(pre_release: &str) -> Option<String> {
|
||||
}
|
||||
}
|
||||
|
||||
// 处理形如 "alpha19" 的预发布版本
|
||||
// Handle pre-release versions like "alpha19"
|
||||
if let Some(pos) = pre_release.rfind(|c: char| c.is_alphabetic()) {
|
||||
let prefix = &pre_release[..=pos];
|
||||
let suffix = &pre_release[pos + 1..];
|
||||
@@ -208,14 +208,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_parse_version() {
|
||||
// 测试标准版本解析
|
||||
// Test standard version parsing
|
||||
let (major, minor, patch, pre_release) = parse_version("1.0.0").unwrap();
|
||||
assert_eq!(major, 1);
|
||||
assert_eq!(minor, 0);
|
||||
assert_eq!(patch, 0);
|
||||
assert_eq!(pre_release, None);
|
||||
|
||||
// 测试预发布版本解析
|
||||
// Test pre-release version parsing
|
||||
let (major, minor, patch, pre_release) = parse_version("1.0.0-alpha.19").unwrap();
|
||||
assert_eq!(major, 1);
|
||||
assert_eq!(minor, 0);
|
||||
@@ -225,32 +225,32 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_increment_pre_release() {
|
||||
// 测试 alpha.19 -> alpha.20
|
||||
// Test alpha.19 -> alpha.20
|
||||
assert_eq!(increment_pre_release("alpha.19"), Some("alpha.20".to_string()));
|
||||
|
||||
// 测试 beta.5 -> beta.6
|
||||
// Test beta.5 -> beta.6
|
||||
assert_eq!(increment_pre_release("beta.5"), Some("beta.6".to_string()));
|
||||
|
||||
// 测试无法解析的情况
|
||||
// Test unparsable case
|
||||
assert_eq!(increment_pre_release("unknown"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_increment_version() {
|
||||
// 测试预发布版本递增
|
||||
// Test pre-release version increment
|
||||
assert_eq!(increment_version("1.0.0-alpha.19").unwrap(), "1.0.0-alpha.20");
|
||||
|
||||
// 测试标准版本递增
|
||||
// Test standard version increment
|
||||
assert_eq!(increment_version("1.0.0").unwrap(), "1.0.1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version_format() {
|
||||
// 测试版本格式是否以 refs/tags/ 开头
|
||||
// Test if version format starts with refs/tags/
|
||||
let version = get_version();
|
||||
assert!(version.starts_with("refs/tags/") || version.starts_with("@"));
|
||||
|
||||
// 如果是 refs/tags/ 格式,应该包含版本号
|
||||
// If it's refs/tags/ format, should contain version number
|
||||
if let Some(version_part) = version.strip_prefix("refs/tags/") {
|
||||
assert!(!version_part.is_empty());
|
||||
}
|
||||
@@ -258,14 +258,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_current_version_output() {
|
||||
// 显示当前版本输出
|
||||
// Display current version output
|
||||
let version = get_version();
|
||||
println!("Current version: {version}");
|
||||
|
||||
// 验证版本格式
|
||||
// Verify version format
|
||||
assert!(version.starts_with("refs/tags/") || version.starts_with("@"));
|
||||
|
||||
// 如果是 refs/tags/ 格式,验证版本号不为空
|
||||
// If it's refs/tags/ format, verify version number is not empty
|
||||
if let Some(version_part) = version.strip_prefix("refs/tags/") {
|
||||
assert!(!version_part.is_empty());
|
||||
println!("Version part: {version_part}");
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
|
||||
for i in {0..3}; do
|
||||
DIR="/data/rustfs$i"
|
||||
echo "处理 $DIR"
|
||||
echo "Processing $DIR"
|
||||
if [ -d "$DIR" ]; then
|
||||
echo "清空 $DIR"
|
||||
echo "Clearing $DIR"
|
||||
sudo rm -rf "$DIR"/* "$DIR"/.[!.]* "$DIR"/..?* 2>/dev/null || true
|
||||
echo "已清空 $DIR"
|
||||
echo "Cleared $DIR"
|
||||
else
|
||||
echo "$DIR 不存在,跳过"
|
||||
echo "$DIR does not exist, skipping"
|
||||
fi
|
||||
done
|
||||
@@ -14,32 +14,32 @@
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
# 脚本名称:scp_to_servers.sh
|
||||
# Script name: scp_to_servers.sh
|
||||
|
||||
rm ./target/x86_64-unknown-linux-gnu/release/rustfs.zip
|
||||
# 压缩./target/x86_64-unknown-linux-gnu/release/rustfs
|
||||
# Compress ./target/x86_64-unknown-linux-gnu/release/rustfs
|
||||
zip -j ./target/x86_64-unknown-linux-gnu/release/rustfs.zip ./target/x86_64-unknown-linux-gnu/release/rustfs
|
||||
|
||||
# 上传到服务器
|
||||
# Upload to server
|
||||
LOCAL_FILE="./target/x86_64-unknown-linux-gnu/release/rustfs.zip"
|
||||
REMOTE_PATH="~"
|
||||
|
||||
# 必须传入IP参数,否则报错退出
|
||||
# IP parameter must be provided, otherwise exit with error
|
||||
if [ -z "$1" ]; then
|
||||
echo "用法: $0 <server_ip>"
|
||||
echo "请传入目标服务器IP地址"
|
||||
echo "Usage: $0 <server_ip>"
|
||||
echo "Please provide target server IP address"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SERVER_LIST=("root@$1")
|
||||
|
||||
# 遍历服务器列表
|
||||
# Iterate through server list
|
||||
for SERVER in "${SERVER_LIST[@]}"; do
|
||||
echo "正在将文件复制到服务器:$SERVER 目标路径:$REMOTE_PATH"
|
||||
echo "Copying file to server: $SERVER target path: $REMOTE_PATH"
|
||||
scp "$LOCAL_FILE" "${SERVER}:${REMOTE_PATH}"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "成功复制到 $SERVER"
|
||||
echo "Successfully copied to $SERVER"
|
||||
else
|
||||
echo "复制到 $SERVER 失败"
|
||||
echo "Failed to copy to $SERVER"
|
||||
fi
|
||||
done
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
# ps -ef | grep rustfs | awk '{print $2}'| xargs kill -9
|
||||
|
||||
# 本地 rustfs.zip 路径
|
||||
# Local rustfs.zip path
|
||||
ZIP_FILE="./rustfs.zip"
|
||||
# 解压目标
|
||||
# Unzip target
|
||||
UNZIP_TARGET="./"
|
||||
|
||||
|
||||
@@ -35,119 +35,119 @@ SERVER_LIST=(
|
||||
|
||||
REMOTE_TMP="~/rustfs"
|
||||
|
||||
# 部署 rustfs 到所有服务器
|
||||
# Deploy rustfs to all servers
|
||||
deploy() {
|
||||
echo "解压 $ZIP_FILE ..."
|
||||
echo "Unzipping $ZIP_FILE ..."
|
||||
unzip -o "$ZIP_FILE" -d "$UNZIP_TARGET"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "解压失败,退出"
|
||||
echo "Unzip failed, exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LOCAL_RUSTFS="${UNZIP_TARGET}rustfs"
|
||||
if [ ! -f "$LOCAL_RUSTFS" ]; then
|
||||
echo "未找到解压后的 rustfs 文件,退出"
|
||||
echo "Unzipped rustfs file not found, exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for SERVER in "${SERVER_LIST[@]}"; do
|
||||
echo "上传 $LOCAL_RUSTFS 到 $SERVER:$REMOTE_TMP"
|
||||
echo "Uploading $LOCAL_RUSTFS to $SERVER:$REMOTE_TMP"
|
||||
scp "$LOCAL_RUSTFS" "${SERVER}:${REMOTE_TMP}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ 上传到 $SERVER 失败,跳过"
|
||||
echo "❌ Upload to $SERVER failed, skipping"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "在 $SERVER 上操作 systemctl 和文件替换"
|
||||
echo "Operating systemctl and file replacement on $SERVER"
|
||||
ssh "$SERVER" bash <<EOF
|
||||
set -e
|
||||
echo "停止 rustfs 服务"
|
||||
echo "Stopping rustfs service"
|
||||
sudo systemctl stop rustfs || true
|
||||
echo "覆盖 /usr/local/bin/rustfs"
|
||||
echo "Overwriting /usr/local/bin/rustfs"
|
||||
sudo cp ~/rustfs /usr/local/bin/rustfs
|
||||
sudo chmod +x /usr/local/bin/rustfs
|
||||
echo "启动 rustfs 服务"
|
||||
echo "Starting rustfs service"
|
||||
sudo systemctl start rustfs
|
||||
echo "检测 rustfs 服务状态"
|
||||
echo "Checking rustfs service status"
|
||||
sudo systemctl status rustfs --no-pager --lines=10
|
||||
EOF
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ $SERVER 部署并重启 rustfs 成功"
|
||||
echo "✅ $SERVER deployed and restarted rustfs successfully"
|
||||
else
|
||||
echo "❌ $SERVER 部署或重启 rustfs 失败"
|
||||
echo "❌ $SERVER failed to deploy or restart rustfs"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 清空 /data/rustfs0~3 目录下所有文件(包括隐藏文件)
|
||||
# Clear all files (including hidden files) in /data/rustfs0~3 directories
|
||||
clear_data_dirs() {
|
||||
for SERVER in "${SERVER_LIST[@]}"; do
|
||||
echo "清空 $SERVER:/data/rustfs0~3 下所有文件"
|
||||
echo "Clearing all files in $SERVER:/data/rustfs0~3"
|
||||
ssh "$SERVER" bash <<EOF
|
||||
for i in {0..3}; do
|
||||
DIR="/data/rustfs$i"
|
||||
echo "处理 $DIR"
|
||||
if [ -d "$DIR" ]; then
|
||||
echo "清空 $DIR"
|
||||
sudo rm -rf "$DIR"/* "$DIR"/.[!.]* "$DIR"/..?* 2>/dev/null || true
|
||||
echo "已清空 $DIR"
|
||||
DIR="/data/rustfs\$i"
|
||||
echo "Processing \$DIR"
|
||||
if [ -d "\$DIR" ]; then
|
||||
echo "Clearing \$DIR"
|
||||
sudo rm -rf "\$DIR"/* "\$DIR"/.[!.]* "\$DIR"/..?* 2>/dev/null || true
|
||||
echo "Cleared \$DIR"
|
||||
else
|
||||
echo "$DIR 不存在,跳过"
|
||||
echo "\$DIR does not exist, skipping"
|
||||
fi
|
||||
done
|
||||
EOF
|
||||
done
|
||||
}
|
||||
|
||||
# 控制 rustfs 服务
|
||||
# Control rustfs service
|
||||
stop_rustfs() {
|
||||
for SERVER in "${SERVER_LIST[@]}"; do
|
||||
echo "停止 $SERVER rustfs 服务"
|
||||
echo "Stopping $SERVER rustfs service"
|
||||
ssh "$SERVER" "sudo systemctl stop rustfs"
|
||||
done
|
||||
}
|
||||
|
||||
start_rustfs() {
|
||||
for SERVER in "${SERVER_LIST[@]}"; do
|
||||
echo "启动 $SERVER rustfs 服务"
|
||||
echo "Starting $SERVER rustfs service"
|
||||
ssh "$SERVER" "sudo systemctl start rustfs"
|
||||
done
|
||||
}
|
||||
|
||||
restart_rustfs() {
|
||||
for SERVER in "${SERVER_LIST[@]}"; do
|
||||
echo "重启 $SERVER rustfs 服务"
|
||||
echo "Restarting $SERVER rustfs service"
|
||||
ssh "$SERVER" "sudo systemctl restart rustfs"
|
||||
done
|
||||
}
|
||||
|
||||
# 向所有服务器追加公钥到 ~/.ssh/authorized_keys
|
||||
# Append public key to ~/.ssh/authorized_keys on all servers
|
||||
add_ssh_key() {
|
||||
if [ -z "$2" ]; then
|
||||
echo "用法: $0 addkey <pubkey_file>"
|
||||
echo "Usage: $0 addkey <pubkey_file>"
|
||||
exit 1
|
||||
fi
|
||||
PUBKEY_FILE="$2"
|
||||
if [ ! -f "$PUBKEY_FILE" ]; then
|
||||
echo "指定的公钥文件不存在: $PUBKEY_FILE"
|
||||
echo "Specified public key file does not exist: $PUBKEY_FILE"
|
||||
exit 1
|
||||
fi
|
||||
PUBKEY_CONTENT=$(cat "$PUBKEY_FILE")
|
||||
for SERVER in "${SERVER_LIST[@]}"; do
|
||||
echo "追加公钥到 $SERVER:~/.ssh/authorized_keys"
|
||||
echo "Appending public key to $SERVER:~/.ssh/authorized_keys"
|
||||
ssh "$SERVER" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '$PUBKEY_CONTENT' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ $SERVER 公钥追加成功"
|
||||
echo "✅ $SERVER public key appended successfully"
|
||||
else
|
||||
echo "❌ $SERVER 公钥追加失败"
|
||||
echo "❌ $SERVER public key append failed"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
monitor_logs() {
|
||||
for SERVER in "${SERVER_LIST[@]}"; do
|
||||
echo "监控 $SERVER:/var/logs/rustfs/rustfs.log ..."
|
||||
echo "Monitoring $SERVER:/var/logs/rustfs/rustfs.log ..."
|
||||
ssh "$SERVER" "tail -F /var/logs/rustfs/rustfs.log" |
|
||||
sed "s/^/[$SERVER] /" &
|
||||
done
|
||||
@@ -156,32 +156,32 @@ monitor_logs() {
|
||||
|
||||
set_env_file() {
|
||||
if [ -z "$2" ]; then
|
||||
echo "用法: $0 setenv <env_file>"
|
||||
echo "Usage: $0 setenv <env_file>"
|
||||
exit 1
|
||||
fi
|
||||
ENV_FILE="$2"
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "指定的环境变量文件不存在: $ENV_FILE"
|
||||
echo "Specified environment variable file does not exist: $ENV_FILE"
|
||||
exit 1
|
||||
fi
|
||||
for SERVER in "${SERVER_LIST[@]}"; do
|
||||
echo "上传 $ENV_FILE 到 $SERVER:~/rustfs.env"
|
||||
echo "Uploading $ENV_FILE to $SERVER:~/rustfs.env"
|
||||
scp "$ENV_FILE" "${SERVER}:~/rustfs.env"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "❌ 上传到 $SERVER 失败,跳过"
|
||||
echo "❌ Upload to $SERVER failed, skipping"
|
||||
continue
|
||||
fi
|
||||
echo "覆盖 $SERVER:/etc/default/rustfs"
|
||||
echo "Overwriting $SERVER:/etc/default/rustfs"
|
||||
ssh "$SERVER" "sudo mv ~/rustfs.env /etc/default/rustfs"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ $SERVER /etc/default/rustfs 覆盖成功"
|
||||
echo "✅ $SERVER /etc/default/rustfs overwritten successfully"
|
||||
else
|
||||
echo "❌ $SERVER /etc/default/rustfs 覆盖失败"
|
||||
echo "❌ $SERVER /etc/default/rustfs overwrite failed"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 主命令分发
|
||||
# Main command dispatcher
|
||||
case "$1" in
|
||||
deploy)
|
||||
deploy
|
||||
@@ -208,6 +208,6 @@ case "$1" in
|
||||
set_env_file "$@"
|
||||
;;
|
||||
*)
|
||||
echo "用法: $0 {deploy|clear|stop|start|restart|addkey <pubkey_file>|monitor_logs|setenv <env_file>}"
|
||||
echo "Usage: $0 {deploy|clear|stop|start|restart|addkey <pubkey_file>|monitor_logs|setenv <env_file>}"
|
||||
;;
|
||||
esac
|
||||
@@ -26,6 +26,6 @@ fi
|
||||
echo "Creating log directory if it does not exist..."
|
||||
mkdir -p "$current_dir/deploy/logs/notify"
|
||||
|
||||
# 启动 webhook 服务器
|
||||
# Start webhook server
|
||||
echo "Starting webhook server..."
|
||||
cargo run --example webhook -p rustfs-notify &
|
||||
@@ -47,19 +47,19 @@ export RUSTFS_ADDRESS=":9000"
|
||||
export RUSTFS_CONSOLE_ENABLE=true
|
||||
export RUSTFS_CONSOLE_ADDRESS=":9001"
|
||||
# export RUSTFS_SERVER_DOMAINS="localhost:9000"
|
||||
# HTTPS 证书目录
|
||||
# HTTPS certificate directory
|
||||
# export RUSTFS_TLS_PATH="./deploy/certs"
|
||||
|
||||
# 可观测性 相关配置信息
|
||||
#export RUSTFS_OBS_ENDPOINT=http://localhost:4317 # OpenTelemetry Collector 的地址
|
||||
#export RUSTFS_OBS_USE_STDOUT=false # 是否使用标准输出
|
||||
#export RUSTFS_OBS_SAMPLE_RATIO=2.0 # 采样率,0.0-1.0之间,0.0表示不采样,1.0表示全部采样
|
||||
#export RUSTFS_OBS_METER_INTERVAL=1 # 采样间隔,单位为秒
|
||||
#export RUSTFS_OBS_SERVICE_NAME=rustfs # 服务名称
|
||||
#export RUSTFS_OBS_SERVICE_VERSION=0.1.0 # 服务版本
|
||||
export RUSTFS_OBS_ENVIRONMENT=develop # 环境名称
|
||||
export RUSTFS_OBS_LOGGER_LEVEL=info # 日志级别,支持 trace, debug, info, warn, error
|
||||
export RUSTFS_OBS_LOCAL_LOGGING_ENABLED=true # 是否启用本地日志记录
|
||||
# Observability related configuration
|
||||
#export RUSTFS_OBS_ENDPOINT=http://localhost:4317 # OpenTelemetry Collector address
|
||||
#export RUSTFS_OBS_USE_STDOUT=false # Whether to use standard output
|
||||
#export RUSTFS_OBS_SAMPLE_RATIO=2.0 # Sample ratio, between 0.0-1.0, 0.0 means no sampling, 1.0 means full sampling
|
||||
#export RUSTFS_OBS_METER_INTERVAL=1 # Sampling interval in seconds
|
||||
#export RUSTFS_OBS_SERVICE_NAME=rustfs # Service name
|
||||
#export RUSTFS_OBS_SERVICE_VERSION=0.1.0 # Service version
|
||||
export RUSTFS_OBS_ENVIRONMENT=develop # Environment name
|
||||
export RUSTFS_OBS_LOGGER_LEVEL=info # Log level, supports trace, debug, info, warn, error
|
||||
export RUSTFS_OBS_LOCAL_LOGGING_ENABLED=true # Whether to enable local logging
|
||||
export RUSTFS_OBS_LOG_DIRECTORY="$current_dir/deploy/logs" # Log directory
|
||||
export RUSTFS_OBS_LOG_ROTATION_TIME="hour" # Log rotation time unit, can be "second", "minute", "hour", "day"
|
||||
export RUSTFS_OBS_LOG_ROTATION_SIZE_MB=100 # Log rotation size in MB
|
||||
@@ -89,34 +89,34 @@ export OTEL_INSTRUMENTATION_SCHEMA_URL="https://opentelemetry.io/schemas/1.31.0"
|
||||
export OTEL_INSTRUMENTATION_ATTRIBUTES="env=production"
|
||||
|
||||
# notify
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENABLE="on" # 是否启用 webhook 通知
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENDPOINT="http://[::]:3020/webhook" # webhook 通知地址
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENABLE="on" # Whether to enable webhook notification
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENDPOINT="http://[::]:3020/webhook" # Webhook notification address
|
||||
export RUSTFS_NOTIFY_WEBHOOK_QUEUE_DIR="$current_dir/deploy/logs/notify"
|
||||
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENABLE_PRIMARY="on" # 是否启用 webhook 通知
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENDPOINT_PRIMARY="http://[::]:3020/webhook" # webhook 通知地址
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENABLE_PRIMARY="on" # Whether to enable webhook notification
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENDPOINT_PRIMARY="http://[::]:3020/webhook" # Webhook notification address
|
||||
export RUSTFS_NOTIFY_WEBHOOK_QUEUE_DIR_PRIMARY="$current_dir/deploy/logs/notify"
|
||||
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENABLE_MASTER="on" # 是否启用 webhook 通知
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENDPOINT_MASTER="http://[::]:3020/webhook" # webhook 通知地址
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENABLE_MASTER="on" # Whether to enable webhook notification
|
||||
export RUSTFS_NOTIFY_WEBHOOK_ENDPOINT_MASTER="http://[::]:3020/webhook" # Webhook notification address
|
||||
export RUSTFS_NOTIFY_WEBHOOK_QUEUE_DIR_MASTER="$current_dir/deploy/logs/notify"
|
||||
|
||||
|
||||
export RUSTFS_NS_SCANNER_INTERVAL=60 # 对象扫描间隔时间,单位为秒
|
||||
export RUSTFS_NS_SCANNER_INTERVAL=60 # Object scanning interval in seconds
|
||||
# exportRUSTFS_SKIP_BACKGROUND_TASK=true
|
||||
|
||||
export RUSTFS_COMPRESSION_ENABLED=true # 是否启用压缩
|
||||
export RUSTFS_COMPRESSION_ENABLED=true # Whether to enable compression
|
||||
|
||||
#export RUSTFS_REGION="us-east-1"
|
||||
|
||||
# 事件消息配置
|
||||
# Event message configuration
|
||||
#export RUSTFS_EVENT_CONFIG="./deploy/config/event.example.toml"
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
export RUSTFS_VOLUMES="$1"
|
||||
fi
|
||||
|
||||
# 启动 webhook 服务器
|
||||
# Start webhook server
|
||||
#cargo run --example webhook -p rustfs-notify &
|
||||
# 启动主服务
|
||||
# Start main service
|
||||
cargo run --bin rustfs
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "🔍 验证所有PR分支的CI状态..."
|
||||
|
||||
branches=(
|
||||
"feature/add-auth-module-tests"
|
||||
"feature/add-storage-core-tests"
|
||||
"feature/add-admin-handlers-tests"
|
||||
"feature/add-server-components-tests"
|
||||
"feature/add-integration-tests"
|
||||
)
|
||||
|
||||
cd /workspace
|
||||
|
||||
for branch in "${branches[@]}"; do
|
||||
echo ""
|
||||
echo "🌟 检查分支: $branch"
|
||||
|
||||
git checkout $branch 2>/dev/null
|
||||
|
||||
echo "📝 检查代码格式..."
|
||||
if cargo fmt --all --check; then
|
||||
echo "✅ 代码格式正确"
|
||||
else
|
||||
echo "❌ 代码格式有问题"
|
||||
fi
|
||||
|
||||
echo "🔧 检查基本编译..."
|
||||
if cargo check --quiet; then
|
||||
echo "✅ 基本编译通过"
|
||||
else
|
||||
echo "❌ 编译失败"
|
||||
fi
|
||||
|
||||
echo "🧪 运行核心测试..."
|
||||
if timeout 60 cargo test --lib --quiet 2>/dev/null; then
|
||||
echo "✅ 核心测试通过"
|
||||
else
|
||||
echo "⚠️ 测试超时或失败(可能是依赖问题)"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "🎉 所有分支检查完毕!"
|
||||
echo ""
|
||||
echo "📋 PR状态总结:"
|
||||
echo "- PR #309: feature/add-auth-module-tests"
|
||||
echo "- PR #313: feature/add-storage-core-tests"
|
||||
echo "- PR #314: feature/add-admin-handlers-tests"
|
||||
echo "- PR #315: feature/add-server-components-tests"
|
||||
echo "- PR #316: feature/add-integration-tests"
|
||||
echo ""
|
||||
echo "✅ 所有冲突已解决,代码已格式化"
|
||||
echo "🔗 请检查GitHub上的CI状态"
|
||||
Reference in New Issue
Block a user