Compare commits

..

1186 Commits

Author SHA1 Message Date
DamonXue
9948b1f709 feat: Implement KMS configuration management and dynamic updates
- Added a new KMS configuration subsystem to support dynamic KMS settings.
- Introduced a global ConfigManager for managing KMS and general configurations.
- Implemented KMS configuration validation and connection testing.
- Created REST API endpoints for retrieving and updating KMS configurations.
- Enhanced the existing configuration handling to include KMS-specific parameters.
- Updated the Cargo.toml to include the new KMS feature.
- Added comprehensive tests for KMS configuration management and validation.
2025-06-07 20:56:22 +08:00
DamonXue
4d67c1d0a6 Merge branch 'main' of https://github.com/rustfs/s3-rustfs into dev_objectEncrypt_v1 2025-06-07 17:18:26 +08:00
houseme
ff264f3385 feat(obs): upgrade OpenTelemetry dependencies to latest version (#447)
- Update opentelemetry from 0.29.1 to 0.30.0
- Update related opentelemetry dependencies for compatibility
- Ensure compatibility with existing observability implementation
- Improve tracing and metrics collection capabilities

This upgrade provides better performance and stability for our observability stack.
2025-06-07 00:10:20 +08:00
weisd
ff4da5cd47 fix filemeta 2025-06-06 22:19:40 +08:00
loverustfs
4cc915fb45 off self-hosted
off self-hosted
2025-06-06 16:48:59 +08:00
houseme
751abeca2b set logger level from RUST_LOG 2025-06-06 16:19:17 +08:00
houseme
5ab2ce3cfe cargo fmt 2025-06-06 15:30:27 +08:00
houseme
4d26fa48d7 Merge branch 'main' of github.com:rustfs/s3-rustfs
* 'main' of github.com:rustfs/s3-rustfs:
  change rustfs-rsc new version not use openssl

# Conflicts:
#	ecstore/Cargo.toml
2025-06-06 15:17:58 +08:00
houseme
5c65368729 fix: remove dep crate openssl relation 2025-06-06 15:13:55 +08:00
laoliu
c16ce7b61b Merge pull request #446 from rustfs/change-rustfs-src-version
change rustfs-rsc version not use openssl
2025-06-06 14:55:10 +08:00
lygn128
25388ba70c change rustfs-rsc new version not use openssl 2025-06-06 06:50:39 +00:00
houseme
9cc34f9f01 improve code for reqwest feature 2025-06-06 14:35:40 +08:00
houseme
02ad3d3832 fix 2025-06-06 13:50:50 +08:00
houseme
1c5ba761ef upgrade version 2025-06-06 13:49:31 +08:00
houseme
7fec5b250a Merge branch 'main' of github.com:rustfs/s3-rustfs
* 'main' of github.com:rustfs/s3-rustfs:
  add Cargo.lock
  fix filemeta/intofileversions

# Conflicts:
#	Cargo.lock
2025-06-06 12:19:29 +08:00
houseme
c861635332 fix cargo.toml 2025-06-06 12:11:08 +08:00
weisd
f4d0a81e06 add Cargo.lock 2025-06-06 11:49:24 +08:00
weisd
b6a5094382 fix filemeta/intofileversions 2025-06-06 11:46:51 +08:00
laoliu
9865b5aa3e Merge pull request #443 from rustfs/bucket-replication
bucket replication
2025-06-06 10:19:56 +08:00
lygn128
5850c3e8a3 bucket replication 2025-06-05 14:26:42 +00:00
weisd
b52198d7f2 rustfs:add get/put_object_retention 2025-06-04 20:06:58 +08:00
weisd
58c3a46138 fix(rustfs):get_object_legal_hold default response 2025-06-04 19:16:57 +08:00
DamonXue
bd4e7c23bb refactor: update encryption metadata handling and improve KMS client initialization 2025-05-30 22:22:09 +08:00
DamonXue
66c2a2fd93 Merge branch 'main' of https://github.com/rustfs/s3-rustfs into dev_objectEncrypt_v1 2025-05-30 20:45:16 +08:00
houseme
cdd41752e0 improve code for obs crate 2025-05-30 13:04:24 +08:00
安正超
bf407715d0 Merge pull request #439 from rustfs/scanner
add static/.gitkeep file
2025-05-30 07:02:07 +08:00
houseme
5e3c97b0e9 fix(obs): align stdout log level with configured logger_level
- Replace fixed `flexi_logger::Duplicate::Info` with dynamic level from config
- Convert logger_level string to corresponding LevelFilter enum
- Ensure terminal output respects the same log level as file logs
- Fix documentation to reflect the dynamic level behavior
2025-05-30 00:22:21 +08:00
houseme
2f20fe9749 docs(.docker): add bilingual README for OpenObserve+OpenTelemetry setup
- Create English and Chinese README files for the openobserve-otel directory
- Document configuration details for both OpenObserve and OTel Collector
- Include setup instructions and application integration examples
- Add badges for both OpenObserve and OpenTelemetry projects
2025-05-29 23:48:11 +08:00
houseme
5e13fc3be2 Merge pull request #440 from rustfs/feature/obs-config
Enhance flexi_logger Integration with Log Rotation by Time and Size
2025-05-29 23:09:47 +08:00
houseme
1d45123968 fix 2025-05-29 22:30:33 +08:00
houseme
03af4369bd improve comment run.sh 2025-05-29 21:30:26 +08:00
houseme
88b2d893dc fix 2025-05-29 21:15:45 +08:00
loverustfs
756e70cc93 add linux arm64 package 2025-05-29 21:11:22 +08:00
junxiang Mu
d2a0c9fd62 decrease scanner frequency
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-29 21:11:22 +08:00
junxiang Mu
d6de724517 improve scanner(1)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-29 21:11:22 +08:00
junxiang Mu
8dfb3643ec improve scanner metric
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-29 21:11:22 +08:00
junxiang Mu
d2857467e0 improve run_data_scanner
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-29 21:11:22 +08:00
houseme
8887b7ea90 improve code for obs 2025-05-29 21:10:04 +08:00
junxiang Mu
18ca25fbfd add static/.gitkeep file
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-29 06:53:11 +00:00
loverustfs
f3c1116935 add linux arm64 package 2025-05-29 14:50:02 +08:00
houseme
2fd5ef75cf modify config for obs 2025-05-29 13:24:56 +08:00
guojidan
c673fa0e3d Merge pull request #438 from rustfs/scanner
Scanner
2025-05-29 11:40:36 +08:00
junxiang Mu
707406e4c5 decrease scanner frequency
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-29 03:17:54 +00:00
junxiang Mu
8a7a6599c8 improve scanner(1)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-29 03:17:54 +00:00
junxiang Mu
881afbfae6 improve scanner metric
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-29 03:17:54 +00:00
junxiang Mu
e050fffcae improve run_data_scanner
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-29 03:17:54 +00:00
houseme
41e378fc28 upgrade config 2025-05-29 09:53:03 +08:00
houseme
751be4bdf6 init openobserve docker yml 2025-05-29 08:34:17 +08:00
houseme
659869e8ad refactor(ci): improve samply profiling workflow with timeout handling
- Add 2-minute timeout to samply record command with proper error handling
- Improve test volume directory creation
- Add workflow_dispatch for manual triggering
- Add job timeout of 10 minutes
- Set environment variables to match run.sh configuration
- Add run number to artifact name for better identification
- Add proper error checking and output when profiling fails
- Set artifact retention period to 7 days
2025-05-28 16:58:19 +08:00
安正超
52da2569dd Merge pull request #437 from rustfs/feat/add-formatting-rules-and-type-inference
feat: add comprehensive formatting rules and type inference guidelines
2025-05-28 16:20:59 +08:00
houseme
c9ff699030 modify install samply 2025-05-28 16:18:01 +08:00
overtrue
3a32517f79 feat: add comprehensive formatting rules and type inference guidelines 2025-05-28 16:04:38 +08:00
houseme
d5539bf22f add workflow Samply action and modify console address port 9001 2025-05-28 16:02:53 +08:00
houseme
1993a7036f upgrade crates reqwest from 0.12.15 to 0.12.16 and clap from 4.5.37 to 4.5.39 2025-05-28 16:02:53 +08:00
安正超
0782f05388 Merge pull request #436 from rustfs/feat/enhance-ci-with-clippy-checks
feat: enhance CI with comprehensive clippy checks for pull requests
2025-05-28 15:55:06 +08:00
overtrue
2f697d0635 feat: enhance CI with comprehensive clippy checks for pull requests 2025-05-28 15:49:47 +08:00
安正超
ad2c1a15b7 Merge pull request #435 from rustfs/fix/e2e-lock-test-errors
fix: resolve clippy warnings and doctest failures
2025-05-28 15:34:29 +08:00
overtrue
5ef7571211 fix: resolve all doctest failures in rustfs-obs crate 2025-05-28 15:29:09 +08:00
overtrue
b0174122c8 fix: resolve clippy warnings for field reassignment with default in last_minute.rs tests 2025-05-28 15:14:49 +08:00
安正超
7f70ab3cd6 Merge pull request #422 from rustfs/feat/improve-last-minute-latency-tests
feat: add comprehensive test coverage for last_minute latency module
2025-05-28 14:53:10 +08:00
overtrue
fefa8cb2c8 resolve: merge conflicts in last_minute.rs tests 2025-05-28 14:48:53 +08:00
guojidan
ae4c23e316 Merge pull request #433 from rustfs/fix/clippy-warnings-and-test-failures
fix: resolve critical namespace lock bug and improve test reliability
2025-05-28 14:40:26 +08:00
安正超
fffc79e981 fix: revert ns_lock test to use distributed locks and add ignore attribute 2025-05-28 14:38:43 +08:00
安正超
4cd2c8e99c refactor: remove dead code comment in observability config test 2025-05-28 14:36:38 +08:00
安正超
a8bd8809b0 docs: add critical rule to never commit directly to master branch 2025-05-28 12:01:46 +08:00
安正超
6f7d279fce test: add ignore attributes to e2e tests requiring external services 2025-05-28 11:56:39 +08:00
安正超
bcbd72d849 fix: resolve critical namespace lock bug and improve test reliability 2025-05-28 11:51:48 +08:00
安正超
b73e4ac7e8 fix: resolve critical namespace lock bug and improve test reliability 2025-05-28 11:46:46 +08:00
安正超
ea8dfa43a4 fix: resolve all Clippy warnings and test failures - Fixed field reassignment warnings in ecstore/src/file_meta.rs by using struct initialization - Fixed overly complex boolean expression in ecstore/src/utils/os/mod.rs - Fixed JWT claims extraction tests in iam module to handle error cases properly - Fixed filter_policies tests to match actual function behavior with empty cache - Fixed tracing subscriber initialization conflicts in rustfs-event-notifier tests - Added buffer length validation in ecstore read_bytes_header function - Fixed concurrent read locks test by clearing global state and improving test reliability - Removed unused imports to eliminate Clippy warnings - All tests now pass: cargo test --workspace --lib --all-features --exclude e2e_test - All Clippy warnings resolved: cargo clippy --all-targets --all-features -- -D warnings 2025-05-28 11:40:05 +08:00
安正超
b50e88a5a0 fix: resolve all remaining test failures and Clippy warnings 2025-05-28 11:28:43 +08:00
安正超
b0447bb692 fix: resolve remaining Clippy warnings and add buffer length validation - Fixed read_bytes_header function by adding buffer length validation before split_at(5) - Added proper error handling for buffers smaller than 5 bytes - Fixed test_file_meta_read_bytes_header to use proper XL format data - All code now passes comprehensive Clippy check: cargo clippy --all-targets --all-features -- -D warnings - Improved code robustness and error handling in file metadata operations 2025-05-28 11:11:15 +08:00
安正超
9ec22255e0 fix: resolve all Clippy warnings across codebase - Fixed field reassignment warnings in ecstore/src/file_meta.rs by using struct initialization instead of default + field assignment - Fixed overly complex boolean expression in ecstore/src/utils/os/mod.rs by removing meaningless assertion - Replaced manual Default implementation with derive in crates/zip/src/lib.rs - Updated io::Error usage to use io::Error::other() instead of deprecated pattern - Removed useless assertions and clone-on-copy warnings - Fixed unwrap usage by replacing with expect() providing meaningful error messages - Fixed useless vec usage by using array repeat instead - All code now passes comprehensive Clippy check with --all-targets --all-features -- -D warnings 2025-05-28 11:00:07 +08:00
安正超
249a46bc8e Merge pull request #432 from rustfs/feat/improve-rustfs-storage-tests
feat: add comprehensive tests for rustfs storage module
2025-05-28 00:27:07 +08:00
overtrue
920551ca92 feat: add comprehensive tests for rustfs storage module 2025-05-28 00:12:41 +08:00
安正超
f056b3fb44 Merge pull request #431 from rustfs/feat/improve-cli-gui-utils-tests
feat: add comprehensive test coverage for CLI GUI utils module
2025-05-27 23:56:23 +08:00
overtrue
b675e01707 feat: add comprehensive test coverage for CLI GUI utils module 2025-05-27 23:54:09 +08:00
安正超
1c93a5e4e0 Merge pull request #430 from rustfs/feat/improve-madmin-module-tests
feat: improve madmin module test coverage - Add comprehensive test ca…
2025-05-27 23:44:17 +08:00
overtrue
d65c58d9de feat: improve madmin module test coverage - Add comprehensive test cases for health.rs, user.rs, and info_commands.rs modules - Total: 114 test cases added, improving coverage from minimal to comprehensive 2025-05-27 23:41:34 +08:00
安正超
28a8977308 Merge pull request #429 from rustfs/feat/improve-s3select-query-tests
feat: add comprehensive test coverage for s3select query module
2025-05-27 23:31:39 +08:00
overtrue
35cf7db9ed feat: add comprehensive test coverage for s3select query module 2025-05-27 23:29:39 +08:00
安正超
e1513aa00e Merge pull request #428 from rustfs/feat/improve-config-module-tests
feat: add comprehensive test coverage for config module
2025-05-27 23:14:21 +08:00
overtrue
670636b3aa feat: add comprehensive test coverage for config module 2025-05-27 23:11:29 +08:00
安正超
2b62560f48 Merge pull request #427 from rustfs/feat/improve-common-module-tests
feat: add comprehensive test coverage for common module
2025-05-27 23:03:16 +08:00
overtrue
01a340d596 feat: add comprehensive test coverage for common module 2025-05-27 22:58:06 +08:00
安正超
3a6e3d49b3 Merge pull request #426 from rustfs/feat/add-utils-certs-comprehensive-tests
feat: add comprehensive test coverage for utils certs module
2025-05-27 22:50:34 +08:00
overtrue
86a99d214c feat: add comprehensive test coverage for utils certs module 2025-05-27 22:44:30 +08:00
安正超
7fe325f47e Merge pull request #425 from rustfs/feat/improve-crypto-jwt-tests
feat: enhance crypto module test coverage with comprehensive test cases
2025-05-27 22:19:12 +08:00
overtrue
671263e22c feat: enhance crypto module test coverage with comprehensive test cases 2025-05-27 22:15:57 +08:00
安正超
e4e923b4b2 Merge pull request #423 from rustfs/feat/add-drwmutex-comprehensive-tests
feat: add comprehensive tests for DRWMutex and fix critical bugs
2025-05-27 22:12:01 +08:00
安正超
87482e82f4 Merge pull request #424 from rustfs/feat/add-io-module-comprehensive-tests
feat: add comprehensive tests for ecstore io module
2025-05-27 22:11:11 +08:00
overtrue
902993a133 feat: add comprehensive tests for ecstore io module 2025-05-27 22:08:21 +08:00
overtrue
609e55a5a2 feat: add comprehensive tests for DRWMutex and fix critical bugs 2025-05-27 21:21:47 +08:00
overtrue
1e3287f610 feat: add comprehensive test coverage for last_minute latency module 2025-05-27 21:03:56 +08:00
houseme
27c6030f09 improve code 2025-05-27 19:07:09 +08:00
houseme
1e00db816c fix typo 2025-05-27 16:56:44 +08:00
houseme
366fd98aeb format comment 2025-05-27 13:56:19 +08:00
houseme
f1ef7149e3 improve code for otel (#418) 2025-05-26 12:05:57 +08:00
DamonXue
ab88166990 feat: Add KMS support with RustyVault integration for object encryption
- Updated Cargo.lock to include the crypto dependency.
- Modified crypto/Cargo.toml to add KMS feature dependency.
- Enhanced error handling in crypto/src/error.rs with new ErrNotSupported variant.
- Made rusty_vault_client and sse_kms modules public in crypto/src/lib.rs.
- Refactored sse.rs to support KMS initialization and updated SSE headers to lowercase for AWS compatibility.
- Implemented lazy initialization of KMS client in sse_kms.rs, allowing deferred setup until first use.
- Updated SSEKMSEncryption to utilize RustyVault for key management and encryption operations.
- Integrated KMS encryption into the object storage layer in ecstore/src/set_disk.rs, allowing part-level encryption.
- Added metadata handling for encrypted parts in the storage API.
- Cleaned up unused imports and improved code organization across various files.
2025-05-25 21:37:12 +08:00
安正超
34dadee8a6 Merge pull request #416 from rustfs/feat/add-store-api-tests
feat: add comprehensive tests for store_api.rs
2025-05-25 18:55:56 +08:00
安正超
021dc36f2f Merge pull request #415 from rustfs/feat/add-file-meta-tests
feat: add tests for file_meta.rs
2025-05-25 18:54:42 +08:00
安正超
09b24d5d41 Merge pull request #414 from rustfs/feat/add-ecfs-tests
feat: add comprehensive tests for set_disk module
2025-05-25 18:53:30 +08:00
overtrue
947ced1d92 fix: correct test_common_parity assertion for HashMap iteration order 2025-05-25 18:52:37 +08:00
overtrue
8f01696dbe fix: correct test_read_xl_meta_no_data test data format 2025-05-25 18:50:32 +08:00
overtrue
bfb4c6dfd4 feat: add comprehensive tests for set_disk module - Add 21 test functions covering utility and validation functions - Test constants, MD5 calculation, path generation, algorithms - Test error handling, healing logic, data manipulation - All tests pass successfully with proper function behavior verification 2025-05-25 18:50:32 +08:00
overtrue
992b0c2cb6 feat: add comprehensive tests for store_api.rs - Add 51 new test functions covering all major structs, enums, and methods - Test FileInfo creation, validation, serialization, and utility methods - Test ErasureInfo shard calculations and checksum handling - Test HTTPRangeSpec range calculations and edge cases - Test ObjectInfo compression detection and size calculations - Test all default implementations and struct conversions - Test serialization/deserialization roundtrip compatibility - Add edge case tests for error handling and boundary conditions - Skip problematic test cases that expose implementation limitations - Improve test coverage for core storage API components 2025-05-25 18:32:19 +08:00
overtrue
01220f88d9 feat: add comprehensive tests for file_meta.rs - Add 24 new test functions covering FileMeta, FileMetaVersion, and related structs - Test utility functions like load, check_xl2_v1, read_bytes_header - Test enum methods for VersionType, ErasureAlgo, ChecksumAlgo - Test FileMetaVersionHeader comparison and validation methods - Test MetaObject and MetaDeleteMarker serialization/deserialization - Test async functions like read_xl_meta_no_data and get_file_info - Add edge case tests for error handling and boundary conditions - Improve test coverage for complex file metadata operations 2025-05-25 18:19:15 +08:00
overtrue
42e020c0bb fix: fix failing test cases in file_meta module - Fix test expectations to match actual function behavior - Update sort and latest_mod_time test logic - Add version_id to delete marker test 2025-05-25 18:13:21 +08:00
overtrue
4e5d6ff772 feat: add comprehensive tests for file_meta module - Add 24 new test functions covering FileMeta operations, validation, and edge cases 2025-05-25 18:07:31 +08:00
houseme
ea4a225d70 cargo fmt 2025-05-25 17:46:59 +08:00
安正超
d4bd8b66a9 Merge pull request #413 from rustfs/feat/add-set-disk-tests
feat: add comprehensive tests for set_disk module
2025-05-25 16:33:39 +08:00
overtrue
defdcf528f feat: add comprehensive tests for set_disk module - Add 24 test functions covering utility and validation functions - Test constants, MD5 calculation, path generation, algorithms - Test error handling, healing logic, data manipulation - All tests pass successfully 2025-05-25 16:27:16 +08:00
安正超
69cb6ead25 Merge pull request #412 from rustfs/feat/add-store-tests
feat: add comprehensive tests for ecstore/store module
2025-05-25 16:01:03 +08:00
安正超
0403c23492 Merge pull request #411 from rustfs/feat/add-grpc-tests
feat: add comprehensive test cases for grpc module
2025-05-25 16:00:41 +08:00
overtrue
413d581d7c feat: add comprehensive tests for ecstore/store module 2025-05-25 15:59:24 +08:00
DamonXue
1777994de7 feat: update dependencies and improve encryption handling
- Added base64 and ring dependencies to Cargo.toml and Cargo.lock.
- Refactored encryption logic in encrypt.rs to use base64 standard encoding.
- Removed unnecessary decryption checks in store.rs for cleaner code.
2025-05-25 15:46:44 +08:00
overtrue
e8efd8ef79 feat: add comprehensive test cases for grpc module 2025-05-25 15:39:04 +08:00
安正超
1380598a0c Merge pull request #410 from rustfs/feat/translate-chinese-comments-to-english
feat: translate Chinese comments to English across codebase
2025-05-25 15:25:25 +08:00
overtrue
142281e96a feat: translate Chinese comments to English across codebase 2025-05-25 15:24:34 +08:00
安正超
af6bb3ae5b Merge pull request #409 from rustfs/fix/zip-import-and-static-files
fix: resolve zip import issue and add missing static files
2025-05-25 15:06:37 +08:00
overtrue
9734d4cfa5 fix: resolve zip import issue by using rustfs-zip package 2025-05-25 15:04:46 +08:00
安正超
9ad152c14f Merge pull request #408 from rustfs/feat/enhance-iam-utils-test-coverage
feat: enhance test coverage for IAM utils and OS utils modules
2025-05-25 14:12:16 +08:00
overtrue
b40b6a17f4 feat: enhance test coverage for IAM utils and OS utils modules 2025-05-25 14:09:40 +08:00
安正超
eae1ccc629 Merge pull request #407 from rustfs/feat/improve-test-coverage-and-translations
feat: improve test coverage and fix critical crypto bug
2025-05-25 14:00:34 +08:00
overtrue
295b502e2a docs: add commit message length and PR format rules 2025-05-25 13:59:22 +08:00
overtrue
a3214222af docs: add cross-platform CPU architecture compatibility guidelines 2025-05-25 13:57:06 +08:00
overtrue
257e858017 docs: add requirement for English PR descriptions in development workflow 2025-05-25 13:55:51 +08:00
overtrue
9c90426032 feat: improve test coverage and fix critical crypto bug - Translate all Chinese comments to English in utils/ip.rs and config/constants/app.rs - Add comprehensive test suite for crypto/encdec/id.rs module (14 new tests) - Fix critical bug in Argon2 key generation that was returning all-zero keys - Improve test coverage for IP utilities and configuration constants - Ensure all test cases follow English naming conventions and meaningful descriptions 2025-05-25 13:53:59 +08:00
overtrue
5c7b105b4a docs: add strict branch management rules to prevent direct main branch modifications 2025-05-25 13:43:24 +08:00
overtrue
a032c401d1 refactor: improve test code quality by replacing meaningless names and content 2025-05-25 13:40:54 +08:00
安正超
a608e0dd65 Merge pull request #404 from rustfs/feat/zip-features
feat: complete zip compression module implementation
2025-05-25 13:35:46 +08:00
安正超
2ef98ee43a Merge pull request #405 from rustfs/feat/event-notifier-error-tests
feat: Add comprehensive test coverage for event-notifier error module
2025-05-25 13:35:17 +08:00
overtrue
8d4e68fe5f docs: enhance cursor rules with code quality standards 2025-05-25 13:34:06 +08:00
overtrue
4e5345d01f docs: translate .cursorrules from Chinese to English 2025-05-25 13:32:33 +08:00
overtrue
8a09a81a69 feat: add comprehensive tests for event-notifier error module 2025-05-25 13:28:16 +08:00
overtrue
62d994c103 feat: add comprehensive tests for event-notifier error module 2025-05-25 13:26:25 +08:00
overtrue
41373960bc feat: complete zip compression module implementation 2025-05-25 13:14:38 +08:00
安正超
bf543f9628 Merge pull request #403 from rustfs/feat/zip-tests
feat: add comprehensive test coverage for zip compression module
2025-05-25 13:11:23 +08:00
安正超
e24d74b1f0 Merge pull request #402 from rustfs/fix/tests
feat: enhance test coverage and fix compilation errors
2025-05-25 13:11:05 +08:00
overtrue
f81bef28df feat: add comprehensive test coverage for zip compression module 2025-05-25 13:05:11 +08:00
overtrue
7730e6cd3a feat: enhance test coverage and fix compilation errors 2025-05-25 12:56:43 +08:00
DamonXue
a18f549c1f Merge branch 'main' of https://github.com/rustfs/s3-rustfs into dev_objectEncrypt_v1 2025-05-17 10:33:17 +08:00
houseme
3592ffb791 fix 2025-05-14 19:04:52 +08:00
weisd
ad5bb38e2b Merge pull request #398 from rustfs/feat/legalhold
add legalhold api
2025-05-13 09:35:11 +08:00
weisd
6434728aea Update rustfs/src/storage/ecfs.rs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-13 09:28:22 +08:00
weisd
df7e690c47 add legalhold api 2025-05-12 15:45:22 +08:00
houseme
65be8145ff feat(obs): implement global OpenTelemetry guard management 2025-05-12 13:32:18 +08:00
houseme
4ac4b35c5e Feature/rustfs config (#396)
* init rustfs config

* improve code for rustfs-config crate

* add

* improve code for comment

* fix: modify rustfs-config crate name

* add default fn

* improve error logger

* fix: modify docker config yaml

* improve code for config

* feat: restrict kafka feature to Linux only

- Add target-specific feature configuration in Cargo.toml for obs and event-notifier crates
- Implement conditional compilation for kafka feature only on Linux systems
- Add appropriate error handling for non-Linux platforms
- Ensure backward compatibility with existing code

* refactor(ci): optimize build workflow for better efficiency

- Integrate GUI build steps into main build-rustfs job
- Add conditional GUI build execution based on tag releases
- Simplify workflow by removing redundant build-rustfs-gui job
- Copy binary directly to embedded-rustfs directory without downloading artifacts
- Update merge job dependency to only rely on build-rustfs
- Improve cross-platform compatibility for Windows binary naming (.exe)
- Streamline artifact uploading and OSS publishing process
- Maintain consistent conditional logic for release operations

* refactor(ci): optimize build workflow for better efficiency

- Integrate GUI build steps into main build-rustfs job
- Add conditional GUI build execution based on tag releases
- Simplify workflow by removing redundant build-rustfs-gui job
- Copy binary directly to embedded-rustfs directory without downloading artifacts
- Update merge job dependency to only rely on build-rustfs
- Improve cross-platform compatibility for Windows binary naming (.exe)
- Streamline artifact uploading and OSS publishing process
- Maintain consistent conditional logic for release operations

* fix(ci): add repo-token to setup-protoc action for authentication

- Add GITHUB_TOKEN parameter to arduino/setup-protoc@v3 action
- Ensure proper authentication for Protoc installation in CI workflow
- Maintain consistent setup across different CI environments

* modify config

* improve readme.md

* remove env config relation

* add allow(dead_code)
2025-05-12 01:17:31 +08:00
houseme
ab54ff49eb fix(ci): add repo-token to setup-protoc action for authentication
- Add GITHUB_TOKEN parameter to arduino/setup-protoc@v3 action
- Ensure proper authentication for Protoc installation in CI workflow
- Maintain consistent setup across different CI environments
2025-05-12 00:36:29 +08:00
houseme
a9de8e0d53 refactor(ci): optimize build workflow for better efficiency
- Integrate GUI build steps into main build-rustfs job
- Add conditional GUI build execution based on tag releases
- Simplify workflow by removing redundant build-rustfs-gui job
- Copy binary directly to embedded-rustfs directory without downloading artifacts
- Update merge job dependency to only rely on build-rustfs
- Improve cross-platform compatibility for Windows binary naming (.exe)
- Streamline artifact uploading and OSS publishing process
- Maintain consistent conditional logic for release operations
2025-05-11 23:41:19 +08:00
houseme
cebe84a896 refactor(ci): optimize build workflow for better efficiency
- Integrate GUI build steps into main build-rustfs job
- Add conditional GUI build execution based on tag releases
- Simplify workflow by removing redundant build-rustfs-gui job
- Copy binary directly to embedded-rustfs directory without downloading artifacts
- Update merge job dependency to only rely on build-rustfs
- Improve cross-platform compatibility for Windows binary naming (.exe)
- Streamline artifact uploading and OSS publishing process
- Maintain consistent conditional logic for release operations
2025-05-11 23:41:09 +08:00
DamonXue
96de156763 Implement SSE-KMS and SSE-S3 encryption mechanisms with comprehensive encryption and decryption functionalities. Added KMS client initialization and management, integrated AES-GCM and ChaCha20-Poly1305 for data encryption, and established metadata handling for encrypted objects. Enhanced error handling and included integration tests for encryption workflows. 2025-05-11 22:41:20 +08:00
houseme
93f1b5dbf1 add GH_TOKEN 2025-05-10 10:05:15 +08:00
houseme
ff908f19e7 add x86_64-unknown-linux-musl target 2025-05-10 09:46:49 +08:00
houseme
9b85384305 test 2025-05-10 00:52:41 +08:00
houseme
ca0bfcfc7e test target aarch64-apple-darwin 2025-05-10 00:39:08 +08:00
houseme
70a3c49b61 test 2025-05-10 00:30:01 +08:00
houseme
c43876ee46 fix 2025-05-10 00:27:54 +08:00
houseme
3bd25b63c8 # Expand ARM64 Linux Support in Build Pipeline
Added support for both ARM64 Linux variants to the CI/CD build pipeline:

1. Enabled the previously commented `aarch64-unknown-linux-gnu` target build
2. Re-enabled the `aarch64-unknown-linux-musl` target build
3. Updated the build matrix to ensure proper runner selection:
   - Ubuntu runners build all Linux targets
   - macOS runners build only Apple Silicon targets
4. Maintained compatibility with the existing build scripts and packaging process

This expansion gives users more options for deploying on ARM64 Linux platforms, supporting both glibc and musl libc environments for maximum compatibility and performance.
2025-05-10 00:24:14 +08:00
houseme
797d7218ee # Add aarch64-apple-darwin Build Target Support
Added ARM64 macOS (Apple Silicon) build target support to the CI/CD pipeline by:

1. Including `aarch64-apple-darwin` as a new build variant in the build matrix
2. Adding proper exclusion rules to ensure the target only runs on macOS runners
3. Ensuring compatibility with the existing build scripts and packaging process

This change enables native builds for Apple Silicon Macs, improving performance for users with M1/M2/M3/M4 processors while maintaining the same artifact organization and deployment process.
2025-05-10 00:15:05 +08:00
weisd
21289797c2 rm log 2025-05-09 22:57:09 +08:00
loverustfs
ff6d2fe84e Merge pull request #393 from rustfs/pref
improve multi put speed
2025-05-09 22:40:03 +08:00
junxiang Mu
f220b04074 improve multi put speed
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-09 17:13:25 +08:00
loverustfs
e0c02fa5bc Merge pull request #389 from rustfs/feat/zip
feat: auto-extract support
2025-05-09 16:19:21 +08:00
loverustfs
1a8574c96f Merge pull request #391 from rustfs/dada/fix-entry
feat: decom/rebalance
2025-05-09 16:19:09 +08:00
weisd
f2c9464eb0 Merge branch 'main' into feat/zip 2025-05-09 14:38:14 +08:00
weisd
22d085a5c9 Merge branch 'main' into dada/fix-entry 2025-05-09 14:33:30 +08:00
guojidan
d0bc3dec23 Merge pull request #390 from rustfs/pref
Pref
2025-05-08 19:35:22 +08:00
junxiang Mu
0a0fb41037 fix zero size object bug
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-08 19:34:58 +08:00
junxiang Mu
845f503739 improve speed
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-08 18:37:36 +08:00
weisd
143017f925 feat: auto-extract support 2025-05-08 17:42:20 +08:00
houseme
38377f81ed refactor: standardize constant management and fix typos (#387)
* init rustfs config

* init rustfs-utils crate

* improve code for rustfs-config crate

* add

* improve code for comment

* init rustfs config

* improve code for rustfs-config crate

* add

* improve code for comment

* Unified management of configurations and constants

* fix: modify rustfs-config crate name

* add default fn

* improve code for rustfs config

* refactor: standardize constant management and fix typos

- Create centralized constants module for global static constants
- Replace runtime format! expressions with compile-time constants
- Fix DEFAULT_PORT reference issues in configuration arguments
- Use const-str crate for compile-time string concatenation
- Update tokio dependency from 1.42.2 to 1.45.0
- Ensure consistent naming convention for configuration constants

* fix

* Update common/workers/src/workers.rs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-07 17:23:22 +08:00
guojidan
f80595e048 Merge pull request #382 from rustfs/sql
support spec char as delimiter
2025-05-06 11:12:15 +08:00
junxiang Mu
d5ba9cdf28 support spec char as delimiter
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-05-06 11:10:30 +08:00
houseme
a39f622402 upgrade version (#380) 2025-05-06 08:54:35 +08:00
houseme
26d4726181 Feature/bucket event notification (#365)
* add tracing instrument

* fix rebalance/decom

* modify Telemetry filter order

* feat: improve address binding and port handling mechanism (#366)

* feat: improve address binding and port handling mechanism

1. Add support for ":port" format to enable dual-stack binding (IPv4/IPv6)
2. Implement automatic port allocation when port 0 is specified
3. Optimize server startup process with unified address resolution
4. Enhance error handling and logging for address resolution
5. Improve graceful shutdown with signal listening
6. Clean up commented code in console.rs

Files:
- ecstore/src/utils/net.rs
- rustfs/src/console.rs
- rustfs/src/main.rs

Branch: feature/server-and-console-port

* improve code for console

* improve code

* improve code for console and net.rs

* Update rustfs/src/main.rs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update rustfs/src/utils/mod.rs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* upgrade config file

* modify

* fix readme

Signed-off-by: junxiang Mu <1948535941@qq.com>

* improve readme.md

* improve code for readme.md
add chinese readme.md

* Implement Storage Service Event Notification System

Added event notification capability to the storage module, enabling the storage service to publish object operation events. Key changes include:

1. Created `event_notifier` module providing core functionality:
   - `create_metadata()` - Creates event metadata objects with default configuration ID
   - `send_event()` - Asynchronously sends event notifications with error handling

2. Integrated the `rustfs_event_notifier` library:
   - Supports object creation, deletion, and access events
   - Provides event metadata building and management
   - Includes proper error propagation

These changes enable the system to trigger notifications when storage operations occur, facilitating auditing, monitoring, and integration with other systems.

* fix

---------

Signed-off-by: junxiang Mu <1948535941@qq.com>
Co-authored-by: weisd <im@weisd.in>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: junxiang Mu <1948535941@qq.com>
2025-04-30 00:31:55 +08:00
guojidan
0b4c050b21 Merge pull request #371 from rustfs/pref
tmp5
2025-04-29 19:09:30 +08:00
junxiang Mu
cf56a0650e tmp5
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-29 11:08:48 +00:00
houseme
31adf1486d upgrade docker image version and fix docker comman 2025-04-29 19:04:53 +08:00
guojidan
be5bdc0b20 Merge pull request #370 from rustfs/pref
Pref
2025-04-29 18:56:24 +08:00
junxiang Mu
bf1bb0823b tmp4
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-29 10:55:02 +00:00
junxiang Mu
45249ccf28 tmp3
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-29 10:53:03 +00:00
houseme
022304d046 improve code for request and telemetry 2025-04-29 11:55:59 +08:00
guojidan
3b2b4f08fc Merge pull request #369 from rustfs/pref
Pref
2025-04-29 11:42:22 +08:00
junxiang Mu
e9a31279bd tmp2
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-29 03:41:45 +00:00
junxiang Mu
6f50b69c5f tmp1
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-29 02:53:42 +00:00
houseme
e0bfedae75 improve code for readme.md
add chinese readme.md
2025-04-29 09:10:03 +08:00
houseme
c1355481cb improve readme.md 2025-04-29 09:10:03 +08:00
junxiang Mu
7c119d6c92 fix readme
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-29 09:10:03 +08:00
houseme
eeabaa71fb Comment certificate directory parameters 2025-04-28 23:00:54 +08:00
junxiang Mu
2ec135c9c0 tmp1
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-28 21:55:31 +08:00
junxiang Mu
21bff0075f tmp
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-28 10:00:28 +00:00
weisd
2a86608ee9 test 2025-04-28 17:35:27 +08:00
weisd
84ae72f71d test 2025-04-28 16:58:37 +08:00
houseme
6be4eb0322 improve code for readme.md
add chinese readme.md
2025-04-28 14:51:51 +08:00
houseme
df5e3dad27 improve readme.md 2025-04-28 14:37:28 +08:00
guojidan
f31d9c3f97 Merge pull request #368 from rustfs/pref
fix readme
2025-04-28 14:25:57 +08:00
junxiang Mu
301a7a20c5 fix readme
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-28 06:25:32 +00:00
weisd
fc67fbfadb test 2025-04-28 13:17:06 +08:00
houseme
89709184c2 modify 2025-04-28 12:50:56 +08:00
houseme
2949b7d203 upgrade config file 2025-04-28 11:34:52 +08:00
houseme
4e68d72de9 feat: improve address binding and port handling mechanism (#366)
* feat: improve address binding and port handling mechanism

1. Add support for ":port" format to enable dual-stack binding (IPv4/IPv6)
2. Implement automatic port allocation when port 0 is specified
3. Optimize server startup process with unified address resolution
4. Enhance error handling and logging for address resolution
5. Improve graceful shutdown with signal listening
6. Clean up commented code in console.rs

Files:
- ecstore/src/utils/net.rs
- rustfs/src/console.rs
- rustfs/src/main.rs

Branch: feature/server-and-console-port

* improve code for console

* improve code

* improve code for console and net.rs

* Update rustfs/src/main.rs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update rustfs/src/utils/mod.rs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-27 23:44:26 +08:00
houseme
02cef27230 modify Telemetry filter order 2025-04-27 09:50:32 +08:00
weisd
ba5cbcb3f1 fix rebalance/decom 2025-04-26 22:55:37 +08:00
houseme
922330ded2 Feature/upgrade obs docker (#364)
* upgrade docker config

* upgrade obs.toml

* modify dockerfile image from alpine to ubuntu
2025-04-26 22:36:38 +08:00
houseme
87c63193ae improve code for opentelemetry 2025-04-26 17:26:54 +08:00
guojidan
835b7fbac5 Merge pull request #362 from rustfs/pref
fix
2025-04-25 17:02:03 +08:00
junxiang Mu
fe456be075 fix
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-25 08:59:39 +00:00
weisd
b492342e55 fix:#355 multi pools select error 2025-04-25 14:52:20 +08:00
houseme
b80f64d9b4 improve code 2025-04-25 13:35:03 +08:00
houseme
dbbcd2a21b improve code for tracing log 2025-04-24 19:14:46 +08:00
houseme
fc9d433038 feat: add TraceLayer for HTTP service and improve metrics (#361)
* improve code for opentelemetry and add system metrics

* feat: add TraceLayer for HTTP service and improve metrics

- Add TraceLayer to HTTP server for request tracing
- Implement system metrics for process monitoring
- Optimize init_telemetry method for better resource management
- Add graceful shutdown handling for telemetry components
- Fix GracefulShutdown ownership issues with Arc wrapper

* improve code for init_process_observer

* remove tomlfmt.toml

* Translation comment

* improve code for console CompressionLayer params
2025-04-24 19:04:57 +08:00
guojidan
d852f62757 Merge pull request #360 from rustfs/pref
fix
2025-04-24 16:42:32 +08:00
junxiang Mu
b0f14e69f6 fix
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-24 08:41:40 +00:00
guojidan
6584bf9607 Merge pull request #359 from rustfs/pref
fix admin info
2025-04-24 16:22:03 +08:00
junxiang Mu
84f9989752 fix admin info
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-24 08:21:09 +00:00
guojidan
a01897211e Merge pull request #358 from rustfs/pref
Pref
2025-04-24 16:13:44 +08:00
junxiang Mu
88159507e3 support concurrency write
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-24 08:12:57 +00:00
weisd
91eb469a7d fix:#352, #353
fix: verify_file bug
2025-04-24 15:32:12 +08:00
weisd
e251ffe85d fix:#351 delete object err 2025-04-24 13:22:34 +08:00
junxiang Mu
91cfc335ba support async calculate etag
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-24 03:04:05 +00:00
weisd
3985330da3 rm unuse log 2025-04-24 09:22:31 +08:00
guojidan
d8f9161ae8 Merge pull request #349 from rustfs/fix-data-scan
Fix data scan
2025-04-23 17:30:05 +08:00
junxiang Mu
aef13a77a3 fmt
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-23 09:29:37 +00:00
junxiang Mu
44a514246b fix capacity
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-23 09:26:22 +00:00
weisd
5364779766 update info version output 2025-04-23 17:03:03 +08:00
weisd
7eefafaad5 merge fix/pools 2025-04-23 16:48:57 +08:00
weisd
6e17a91919 fix: #331 admin info version,uptime 2025-04-23 16:34:39 +08:00
guojidan
6f2b4b34b9 Merge pull request #348 from rustfs/fix-data-scan
fix
2025-04-23 16:28:12 +08:00
junxiang Mu
dbb5625199 fix
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-23 07:26:37 +00:00
weisd
89785dc06b pool select idx
fixs:#346, #339, #338, #337, #336, #334

test healbucket

test get_available_pool_idx

fix
2025-04-23 15:11:43 +08:00
houseme
46c3134487 Feature/bucket event notification (#347)
* init event notifer

* feat: implement event notification system

- Add core event notification interfaces
- Support multiple notification backends:
  - Webhook (default)
  - Kafka
  - MQTT
  - HTTP Producer
- Implement configurable event filtering
- Add async event dispatching with backpressure handling
- Provide serialization/deserialization for event payloads

This module enables system events to be published to various endpoints
with consistent delivery guarantees and failure handling.

* feat(event-notifier): improve notification system initialization safety

- Add READY atomic flag to track full initialization status
- Implement initialize_safe and start_safe methods with mutex protection
- Add wait_until_ready function with configurable timeout
- Create initialize_and_start_with_ready_check helper method
- Replace sleep-based waiting with proper readiness checks
- Add safety checks before sending events
- Replace chrono with std::time for time handling
- Update error handling to provide clear initialization status

This change reduces race conditions in multi-threaded environments
and ensures events are only processed when the system is fully ready.

* fix sql

Signed-off-by: junxiang Mu <1948535941@qq.com>

* move protobuf generate into bin crate

Signed-off-by: junxiang Mu <1948535941@qq.com>

* improve Cargo toml

* improve code

* improve code for global

* improve code

* feat(event-notifier): improve environment variable handling

- Fix deserialization error when parsing config from environment variables
- Add proper array format support for adapters configuration
- Update environment variable examples with correct format
- Improve documentation for configuration loading
- Implement helper functions for environment variable validation

This change fixes the "invalid type: map, expected a sequence" error
by ensuring proper formatting of array-type fields in environment variables.

* feat: integrate event-notifier system with rustfs

- Rename package from rustfs-event-notifier to event-notifier for consistency
- Add shutdown hooks for event notification system in main process
- Handle graceful termination of notification services on server shutdown
- Implement initialization and configuration loading for event notification
- Fix environment variable configuration to properly parse adapter arrays
- Update example code to demonstrate proper configuration usage

This change ensures proper integration between rustfs and the event
notification system, with clean startup and shutdown sequences to prevent
resource leaks during application lifecycle.

* feat: improve webhook server and run script integration

- Enhance webhook example with proper shutdown handling using tokio::select!
- Update run.sh to automatically start webhook server alongside main service
- Add event notification configuration to run.sh using environment variables
- Set proper port bindings to ensure webhook server starts on port 3000
- Improve console output for better debugging experience
- Fix race condition during service startup and shutdown

This change ensures proper integration between the webhook server and
the main rustfs service, providing a seamless development experience
with automatic service discovery and clean termination.

* improve for logger

* improve code for global.rs

* fix: modify webhook port

* fix

---------

Signed-off-by: junxiang Mu <1948535941@qq.com>
Co-authored-by: junxiang Mu <1948535941@qq.com>
2025-04-22 23:08:03 +08:00
houseme
b1a6da8d73 fix 2025-04-22 23:07:13 +08:00
houseme
dde551ef94 fix: modify webhook port 2025-04-22 23:06:43 +08:00
houseme
65f036442a improve code for global.rs 2025-04-22 22:59:31 +08:00
houseme
2167f5e728 improve for logger 2025-04-22 22:41:45 +08:00
houseme
9fc284bef3 feat: improve webhook server and run script integration
- Enhance webhook example with proper shutdown handling using tokio::select!
- Update run.sh to automatically start webhook server alongside main service
- Add event notification configuration to run.sh using environment variables
- Set proper port bindings to ensure webhook server starts on port 3000
- Improve console output for better debugging experience
- Fix race condition during service startup and shutdown

This change ensures proper integration between the webhook server and
the main rustfs service, providing a seamless development experience
with automatic service discovery and clean termination.
2025-04-22 21:40:20 +08:00
houseme
b57b92e382 feat: integrate event-notifier system with rustfs
- Rename package from rustfs-event-notifier to event-notifier for consistency
- Add shutdown hooks for event notification system in main process
- Handle graceful termination of notification services on server shutdown
- Implement initialization and configuration loading for event notification
- Fix environment variable configuration to properly parse adapter arrays
- Update example code to demonstrate proper configuration usage

This change ensures proper integration between rustfs and the event
notification system, with clean startup and shutdown sequences to prevent
resource leaks during application lifecycle.
2025-04-22 20:49:39 +08:00
houseme
0d28c1cbf8 feat(event-notifier): improve environment variable handling
- Fix deserialization error when parsing config from environment variables
- Add proper array format support for adapters configuration
- Update environment variable examples with correct format
- Improve documentation for configuration loading
- Implement helper functions for environment variable validation

This change fixes the "invalid type: map, expected a sequence" error
by ensuring proper formatting of array-type fields in environment variables.
2025-04-22 20:31:38 +08:00
houseme
e3af3d1b94 Merge branch 'main' of github.com:rustfs/s3-rustfs into feature/bucket-event-notification
# Conflicts:
#	Cargo.toml
2025-04-22 09:16:48 +08:00
houseme
7411283fc8 improve code 2025-04-22 09:14:09 +08:00
weisd
c331365ebf otel debug filter tower 2025-04-22 09:07:43 +08:00
weisd
0e9d1d63d3 fix pool select idx 2025-04-22 09:07:43 +08:00
DamonXue
4e9e63dff6 Merge pull request #345 from rustfs/dev_objectEncrypt_v1
feat: update launch configuration and clean unuseful docker-compose config
2025-04-21 22:08:02 +08:00
DamonXue
ad528935ad feat: update launch configuration and docker-compose for enhanced observability and logging 2025-04-21 22:05:31 +08:00
houseme
e634ffdd23 improve code for global 2025-04-21 21:39:57 +08:00
houseme
165660e106 improve code 2025-04-21 19:01:31 +08:00
houseme
14425be416 improve Cargo toml 2025-04-21 15:27:58 +08:00
junxiang Mu
47afb1a651 move protobuf generate into bin crate
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-21 13:28:32 +08:00
junxiang Mu
95d59d7206 fix sql
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-21 13:28:32 +08:00
houseme
e2b7a9772c feat(event-notifier): improve notification system initialization safety
- Add READY atomic flag to track full initialization status
- Implement initialize_safe and start_safe methods with mutex protection
- Add wait_until_ready function with configurable timeout
- Create initialize_and_start_with_ready_check helper method
- Replace sleep-based waiting with proper readiness checks
- Add safety checks before sending events
- Replace chrono with std::time for time handling
- Update error handling to provide clear initialization status

This change reduces race conditions in multi-threaded environments
and ensures events are only processed when the system is fully ready.
2025-04-21 13:28:01 +08:00
guojidan
5ccb08e73f Merge pull request #343 from rustfs/improve-proto
move protobuf generate into bin crate
2025-04-21 11:11:35 +08:00
junxiang Mu
778ca76607 move protobuf generate into bin crate
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-21 03:09:54 +00:00
guojidan
c78338df9f Merge pull request #342 from rustfs/fix-sql
fix sql
2025-04-21 09:47:02 +08:00
junxiang Mu
adf401e09a fix sql
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-21 01:43:13 +00:00
houseme
bb6324b4e5 feat: implement event notification system
- Add core event notification interfaces
- Support multiple notification backends:
  - Webhook (default)
  - Kafka
  - MQTT
  - HTTP Producer
- Implement configurable event filtering
- Add async event dispatching with backpressure handling
- Provide serialization/deserialization for event payloads

This module enables system events to be published to various endpoints
with consistent delivery guarantees and failure handling.
2025-04-21 00:17:27 +08:00
houseme
9b6170e94f init event notifer 2025-04-19 02:20:50 +08:00
weisd
8d865eb048 fix scstore::new bugs, stop ns_lock 2025-04-19 01:52:27 +08:00
weisd
8fefb8f7cb add tracing 2025-04-18 16:21:14 +08:00
weisd
443fbeee38 Merge branch 'main' into dada/decom 2025-04-18 16:02:05 +08:00
weisd
31addf01dd feat:decom,rebalance 2025-04-18 16:00:21 +08:00
houseme
2a6554a3c6 fix console http server 2025-04-16 17:01:25 +08:00
Nugine
691a0bed5d build(deps): upgrade s3s
resolves: #322
2025-04-16 15:16:19 +08:00
loverustfs
5088f51236 Merge pull request #330 from rustfs/nugine/performance/jemalloc
feat(rustfs/main): use jemalloc
2025-04-16 14:16:34 +08:00
Nugine
aeb1beab17 feat(rustfs/main): use jemalloc 2025-04-16 11:59:08 +08:00
houseme
d4b4ef1108 Feature/status Support IPV4 and IPV6 dual stack and 308 Permanent Redirect (#329)
* test 308 Permanent Redirect

* improve code and Support IPV4 and IPV6 dual stack

* remove code
2025-04-15 23:29:12 +08:00
loverustfs
16bbe517b4 Merge pull request #328 from rustfs/nugine/performance/tcp_nodelay
feat(rustfs/main): set TCP_NODELAY
2025-04-15 20:47:06 +08:00
loverustfs
f1add9dc58 Merge pull request #326 from rustfs/nugine/performance/v4
feat(ecstore/erasure): optimize `encode_data`
2025-04-15 20:46:51 +08:00
Nugine
2363a3706f feat(rustfs/main): set TCP_NODELAY 2025-04-15 19:36:34 +08:00
Nugine
08e8c7258c feat(ecstore/erasure): optimize encode_data 2025-04-15 18:07:51 +08:00
Nugine
5df2bdb063 build(deps): upgrade s3s 2025-04-15 17:37:08 +08:00
weisd
115d9ea780 merge main 2025-04-14 22:38:58 +08:00
weisd
70b65343ab todo 2025-04-14 17:32:49 +08:00
junxiangMu
77c7146677 Merge pull request #323 from rustfs/fix-data-scan
fix datascanner
2025-04-14 10:19:06 +08:00
junxiang Mu
980ecb8bd3 fix datascanner
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-14 02:18:40 +00:00
weisd
0408f29301 fix config_handler 2025-04-13 23:52:52 +08:00
loverustfs
1d7a97197a fix tls configs error 2025-04-13 19:53:29 +08:00
houseme
5152be44f0 Fix/fix domain server (#319)
* fix: server_domain and improve code for tls

* add log

* add tracing

* test

* improve config and tls

* Update rustfs/src/console.rs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-13 12:55:56 +08:00
houseme
a36730220e Merge pull request #314 from rustfs/feature/upgrade-version
Feature/upgrade version and readme.md
2025-04-11 22:44:52 +08:00
houseme
54069d7cc3 fix typo 2025-04-11 22:37:52 +08:00
houseme
abf3c5a5b5 Revert "improve README.md"
This reverts commit c2dd6e2a6a.
2025-04-11 22:32:06 +08:00
houseme
c2dd6e2a6a improve README.md 2025-04-11 21:48:44 +08:00
houseme
0cd10a9352 upgrade protobuf download link and improve code for readme.md 2025-04-11 21:44:23 +08:00
houseme
3cc4eb55b3 upgrade crate version 2025-04-11 20:53:51 +08:00
houseme
c1f781256f fix systemd notice 2025-04-11 20:02:51 +08:00
houseme
4fa63bec31 Merge pull request #313 from rustfs/feature/Systemd.service
feat: improve systemd integration and logging
2025-04-11 18:40:23 +08:00
houseme
56ce9d2776 Update crates/obs/src/sink.rs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-11 17:45:59 +08:00
houseme
c16bd2fec1 Remove unused crate 2025-04-11 17:38:44 +08:00
houseme
e25d444cdf Merge branch 'main' of github.com:rustfs/s3-rustfs into feature/Systemd.service 2025-04-11 16:48:46 +08:00
houseme
58b08ddbd1 improve signal watch 2025-04-11 16:48:07 +08:00
Nugine
015eeb0c9f fix: upgrade s3s 2025-04-11 16:01:46 +08:00
houseme
5e36f7f107 Update obs.example.toml 2025-04-11 14:27:55 +08:00
weisd
662563c216 Merge pull request #310 from rustfs/dada/admin-policy
add admin policy check for user operation
2025-04-11 11:39:30 +08:00
weisd
35065bc65a Merge pull request #311 from rustfs/fix/309
fix:#309 add head_object options
2025-04-11 11:35:09 +08:00
weisd
b9cf1765f8 fix:#309 add head_object options 2025-04-11 11:33:44 +08:00
weisd
15c815cae6 add admin policy check for user operation 2025-04-11 10:46:36 +08:00
houseme
85368b38d3 improve systemd relation config 2025-04-10 18:57:48 +08:00
houseme
61ea8fc988 chore(ci): optimize build workflow and update protoc version
- Update protoc version from 27.0 to 30.2 for better compatibility
- Improve build workflow parameters handling
2025-04-10 11:49:44 +08:00
houseme
928ccb1c80 fix 2025-04-10 00:43:55 +08:00
houseme
48ec993b60 improve code for signal 2025-04-10 00:38:17 +08:00
houseme
983f4f0316 improve code 2025-04-09 23:45:53 +08:00
houseme
b03d17bc97 create get default log path func 2025-04-09 21:52:30 +08:00
houseme
cba5eb2cc3 Merge pull request #308 from rustfs/feature/Systemd.service
refactor(service): optimize systemd dependencies and notifications for Linux platform
2025-04-09 19:16:00 +08:00
houseme
b221458d4d Update rustfs/src/main.rs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-09 19:15:49 +08:00
houseme
de5fdb9299 add rsutfs.service and run.md 2025-04-09 19:11:56 +08:00
houseme
fe7abc2611 add notify systemd 2025-04-09 19:11:31 +08:00
houseme
344fc6fb91 improve Cargo.toml and modify README.md conosel web static url 2025-04-09 18:36:17 +08:00
weisd
5a34318947 delete files when move to trash 2025-04-09 17:21:21 +08:00
weisd
6c363c8149 Merge pull request #306 from rustfs/fix/305
fix: #305
2025-04-09 15:57:55 +08:00
weisd
76948cae65 fix: #305 2025-04-09 15:55:30 +08:00
houseme
689d3ae03e improve code for obs 2025-04-09 15:12:31 +08:00
junxiangMu
8f0e239f3d Merge pull request #304 from rustfs/update-tonic
fix upgrade axum bug
2025-04-09 14:21:12 +08:00
junxiang Mu
a4a5170c1c fix upgrade axum bug
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-09 06:19:36 +00:00
junxiangMu
0f87cb1e72 Merge pull request #303 from rustfs/update-tonic
Update tonic
2025-04-09 11:28:22 +08:00
junxiang Mu
b7a7dcead8 degrade rand && object_store
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-09 03:27:03 +00:00
junxiang Mu
1cfd459b83 update tonic axum
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-09 02:41:06 +00:00
loverustfs
8d3d11b07e Merge pull request #299 from rustfs/dependabot/cargo/dependencies-ea473149c2
Bump the dependencies group across 1 directory with 3 updates
2025-04-09 10:33:04 +08:00
loverustfs
e3a81df926 Merge pull request #302 from rustfs/dev_damon_ps1
feat: add FileAccessDeniedWithContext error type for better file access error handling
2025-04-09 10:27:31 +08:00
Damonxue
3cc2f25450 feat: add FileAccessDeniedWithContext error type for better file access error handling 2025-04-09 10:25:41 +08:00
DamonXue
fd7e3cabca Merge pull request #300 from rustfs/dev_damon_ps1
fix: download rustfs-console-latest.zip first than build.
2025-04-09 09:31:27 +08:00
Damonxue
79be7370ed fix: remove duplicate download check for rustfs-console-latest.zip 2025-04-09 09:25:46 +08:00
loverustfs
375012bd17 Merge pull request #296 from rustfs/dev_damon_ps1
fix: fix run error in windows os.
2025-04-09 08:42:14 +08:00
DamonXue
7c186a84c6 Update ecstore/src/disk/local.rs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-09 08:13:45 +08:00
dependabot[bot]
59a66bdbd6 Bump the dependencies group across 1 directory with 3 updates
Bumps the dependencies group with 3 updates in the / directory: [rand](https://github.com/rust-random/rand), [tokio](https://github.com/tokio-rs/tokio) and [object_store](https://github.com/apache/arrow-rs).


Updates `rand` from 0.8.5 to 0.9.0
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/0.8.5...0.9.0)

Updates `tokio` from 1.44.1 to 1.44.2
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.44.1...tokio-1.44.2)

Updates `object_store` from 0.11.2 to 0.12.0
- [Release notes](https://github.com/apache/arrow-rs/releases)
- [Changelog](https://github.com/apache/arrow-rs/blob/main/CHANGELOG-old.md)
- [Commits](https://github.com/apache/arrow-rs/compare/object_store_0.11.2...object_store_0.12.0)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: tokio
  dependency-version: 1.44.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: object_store
  dependency-version: 0.12.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-08 15:33:56 +00:00
houseme
4e05fab8e0 upgrade opentelemetry version from 0.29 to 0.29.1 2025-04-08 23:26:02 +08:00
weisd
39950a4ca2 fix sts download 2025-04-08 22:52:13 +08:00
weisd
a770600fa7 merge license 2025-04-08 22:32:24 +08:00
weisd
b39b8838cc cache license 2025-04-08 22:32:24 +08:00
weisd
aca64b8c36 license api 2025-04-08 22:32:21 +08:00
weisd
f50c320fda rm log 2025-04-08 22:31:44 +08:00
weisd
00de1d2c89 fix sts download 2025-04-08 22:31:44 +08:00
DamonXue
1b5a181c1c Update ecstore/src/disk/local.rs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-08 17:42:02 +08:00
Damonxue
074c66fa00 feat: update file access error handling and improve script downloads
fix: correct file size retrieval in bitrot verification
chore: remove deprecated run.bat and add run.ps1 script
2025-04-08 17:32:12 +08:00
houseme
a4aa197a37 install target x86_64-unknown-linux-musl 2025-04-07 17:57:45 +08:00
houseme
25e70692ec improve code for build 2025-04-07 17:47:43 +08:00
houseme
ec2dd25f92 improve 2025-04-07 17:24:13 +08:00
houseme
bded37e2be update 2025-04-07 17:13:19 +08:00
houseme
188875933e Merge pull request #294 from rustfs/feature/action-x
Change build target to `x86_64-unknown-linux-musl` and update system …
2025-04-07 17:07:49 +08:00
houseme
24559537ab Change build target to x86_64-unknown-linux-musl and update system dependencies
- Change build target from `x86_64-unknown-linux-gnu` to `x86_64-unknown-linux-musl`
- Default install `x86_64-unknown-linux-musl` toolchain in setup action
- Add `musl-tools` and `build-essential` to system dependencies
2025-04-07 16:55:14 +08:00
weisd
7f4f40f3ba todo 2025-04-07 10:52:15 +08:00
houseme
9c5abf6831 improve code for dockerfile 2025-04-03 01:59:28 +08:00
houseme
59c64d4458 fix typo 2025-04-02 23:56:12 +08:00
houseme
c7394e1147 Create a docker-compose-obs.yaml file related to observability 2025-04-02 22:27:49 +08:00
houseme
ed340c1345 improve code for observability 2025-04-02 18:23:20 +08:00
houseme
2e4f444847 run.sh add RUSTFS_OBS_CONFIG = "./config/obs.example.toml" 2025-04-02 17:18:03 +08:00
houseme
a4fda6d21e Merge branch 'feature/observability'
* feature/observability: (27 commits)
  modify default value
  TryInto cover
  upgrade reqwest version from 0.12.12 to 0.12.15
  improve code for FileSink
  improve code for config and FileSink
  webhook add auth_token
  upgrade docker images
  feat(obs): enhance OpenTelemetry configuration and logging
  merge main
  feat: add metrics_handler
  add prometheus
  upgrade opentelemetry create from 0.28.0 to 0.29.0
  update .gitignore
  replace log to tracing
  improve code for observability
  improve code for main
  feat(observability): add obs_config option and document stdout export
  improve logger entry for Observability
  improve log struct
  improve code
  ...
2025-04-02 16:19:38 +08:00
houseme
c615d35cd0 modify default value 2025-04-02 16:08:51 +08:00
houseme
3a404c347c Merge main branches 2025-04-02 15:57:11 +08:00
weisd
456a56cd80 todo 2025-04-02 14:13:29 +08:00
houseme
587c7d41e9 add example certs readme.md 2025-04-02 08:37:06 +08:00
houseme
6616a4862f Merge pull request #287 from rustfs/feature/tls
Add TLS support and replace log crate with tracing crate
2025-04-02 01:21:37 +08:00
houseme
f70b654c35 improve code 2025-04-02 01:18:44 +08:00
houseme
a0261b4c82 Update rustfs/src/utils.rs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-02 01:12:54 +08:00
houseme
4e6f1e787b Update rustfs/src/utils.rs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-02 01:12:43 +08:00
houseme
173bacdb23 improve crate and remove log crate 2025-04-02 00:51:59 +08:00
houseme
27e5cafa22 add rustfs tls 2025-04-02 00:48:08 +08:00
houseme
1408913afe Log records uniformly use tracing 2025-04-01 23:27:48 +08:00
houseme
15f5962dc0 add rustls 2025-04-01 23:09:47 +08:00
houseme
7ebbb91553 improve tls for console 2025-04-01 22:06:47 +08:00
junxiangMu
6d6a8a2d6e Merge pull request #284 from rustfs/feature/s3select
support func
2025-04-01 11:55:14 +08:00
junxiang Mu
f4f764218d support func
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-04-01 03:52:55 +00:00
houseme
a7305de3ad TryInto cover 2025-03-31 18:32:22 +08:00
houseme
38411c675d upgrade reqwest version from 0.12.12 to 0.12.15 2025-03-31 16:32:22 +08:00
houseme
b3d43ce795 Merge branch 'main' of github.com:rustfs/s3-rustfs into feature/observability
# Conflicts:
#	Cargo.lock
#	Cargo.toml
2025-03-31 15:12:30 +08:00
junxiangMu
bcfcb97c8d Merge pull request #283 from rustfs/feature/s3select
Feature/s3select
2025-03-31 14:35:58 +08:00
junxiang Mu
8790e1e4db rename func
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-03-31 06:34:56 +00:00
junxiang Mu
a2284af3ea rebase to main
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-03-31 06:32:05 +00:00
junxiang Mu
b145dfd437 add test case
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-03-31 05:46:05 +00:00
junxiang Mu
4d423b6510 tmp3
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-03-31 05:46:03 +00:00
junxiang Mu
cd238f9b5a tmp2
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-03-31 05:44:48 +00:00
junxiang Mu
9a6178beee tmp1
Signed-off-by: junxiang Mu <1948535941@qq.com>
2025-03-31 05:43:01 +00:00
houseme
5a636d3254 improve code for FileSink 2025-03-30 21:28:29 +08:00
overtrue
5a5e1f6bd1 feat: latest zip 2025-03-29 19:38:30 +08:00
overtrue
811a9e3964 fix: filename 2025-03-29 14:29:36 +08:00
overtrue
cfff691a58 n 2025-03-29 14:08:33 +08:00
houseme
b64e78246d improve code for config and FileSink 2025-03-28 19:03:09 +08:00
weisd
8b7c33814f fix etag bug 2025-03-28 15:39:53 +08:00
houseme
6321dd5c72 webhook add auth_token 2025-03-27 23:18:09 +08:00
houseme
ff67a4382d upgrade docker images 2025-03-27 22:21:10 +08:00
houseme
bbee212b38 feat(obs): enhance OpenTelemetry configuration and logging
Improve observability setup with the following changes:

- Replace static OnceCell with tokio::sync::OnceCell for guard management
- Add logger_level to OtelConfig for configurable tracing verbosity
- Improve telemetry initialization with better error handling
- Enhance logging filters and span configuration

Breaking Changes:
- Configuration now requires logger_level field
- Global guard management uses async-safe primitives

Example config:
observability:
  endpoint: "http://localhost:4317"
  logger_level: "debug"  # New required field
2025-03-27 18:03:47 +08:00
houseme
2f94beff93 merge main 2025-03-26 17:26:34 +08:00
weisd
9c062f18b6 todo 2025-03-26 17:24:13 +08:00
weisd
49b68327bb fix decom status 2025-03-26 17:03:25 +08:00
houseme
8fb44cd89e feat: add metrics_handler 2025-03-26 16:59:34 +08:00
weisd
07ffb83356 move admin handlers 2025-03-26 16:22:09 +08:00
houseme
87790721c5 Merge branch 'main' of github.com:rustfs/s3-rustfs into feature/observability
# Conflicts:
#	rustfs/src/storage/ecfs.rs
2025-03-26 16:08:41 +08:00
weisd
900722e800 fix linux build error 2025-03-26 15:51:06 +08:00
houseme
c5d6bc20f8 add prometheus 2025-03-26 15:18:23 +08:00
weisd
6176f0b00e Merge pull request #279 from rustfs/dada/bucket_policy
Dada/bucket policy
2025-03-26 14:58:20 +08:00
weisd
4dc2551e1d add GetBucketPolicyStatus api 2025-03-26 14:35:36 +08:00
weisd
de4aec519b update s3 api access check support anonymous 2025-03-26 14:21:43 +08:00
weisd
bcb9db7c59 ecstore update bucket policy 2025-03-26 11:39:14 +08:00
weisd
93dcfc0cdd add bucketpolicy 2025-03-26 11:25:12 +08:00
weisd
2f25c74b32 move policy out of iam 2025-03-26 10:19:47 +08:00
houseme
cebf5699a4 upgrade opentelemetry create from 0.28.0 to 0.29.0 2025-03-25 19:02:52 +08:00
weisd
3d4760181d move ecsotre/error to common 2025-03-25 17:42:15 +08:00
loverustfs
1ead472da2 fix console-zip package error
fix console-zip package error
2025-03-24 22:58:00 +08:00
weisd
4dee6d5c76 fix console config server ip 2025-03-24 17:38:20 +08:00
houseme
f0bf2bed74 update .gitignore 2025-03-22 21:30:10 +08:00
weisd
4032e5459e fix move_to_trash 2025-03-20 01:16:55 +08:00
houseme
1ad3a76c3c replace log to tracing 2025-03-19 22:34:26 +08:00
houseme
47b9d45ff8 improve code for observability 2025-03-18 22:57:26 +08:00
houseme
f6b9964dcd improve code for main 2025-03-18 19:04:00 +08:00
houseme
1453a0fc5a Merge branch 'main' of github.com:rustfs/s3-rustfs into feature/observability
# Conflicts:
#	Cargo.lock
#	Cargo.toml
2025-03-18 16:51:25 +08:00
houseme
6d344d2aff feat(observability): add obs_config option and document stdout export
- Add obs_config parameter to config struct with default path
- Document how to modify use_stdout value in README.md
- Support configuring observability via file or environment variables

This change helps users configure telemetry output destination for better
observability options in different deployment scenarios.
2025-03-18 16:39:18 +08:00
houseme
cc4a8a8e51 improve logger entry for Observability 2025-03-18 16:36:23 +08:00
houseme
db1d0cf3df improve log struct 2025-03-17 21:37:47 +08:00
houseme
35a7bc310b improve code 2025-03-16 16:33:52 +08:00
weisd
8983db39ae update todo 2025-03-16 00:47:56 +08:00
weisd
ae06d87f10 opt network io 2025-03-14 23:26:54 +08:00
weisd
d724c6132d r/w io as async 2025-03-13 16:46:12 +08:00
houseme
283b2981e3 improve dependencies feature 2025-03-12 11:58:10 +08:00
houseme
3b2df514a7 improve code for observability 2025-03-12 00:46:01 +08:00
weisd
9b0f498add use http for remote read/write 2025-03-11 16:12:34 +08:00
weisd
eedeb188f2 use filereader as asyncread 2025-03-10 02:39:35 +08:00
houseme
6727e15055 Merge branch 'main' of github.com:rustfs/s3-rustfs into feature/logger 2025-03-09 10:47:26 +08:00
houseme
e758ef4022 rename rustfs-logging to rustfs-obs 2025-03-09 10:47:03 +08:00
weisd
4e09e0a11a add s3 access check 2025-03-07 10:07:23 +08:00
weisd
693b06eefd fix:#254 use console host for s3 host 2025-03-07 00:21:17 +08:00
houseme
2e4a63c4a0 Merge branch 'main' of github.com:rustfs/s3-rustfs into feature/logger
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	rustfs/src/main.rs
2025-03-06 16:54:17 +08:00
houseme
1d58a07f29 improve for build.yml 2025-03-06 12:07:25 +08:00
houseme
53d4cb81de add dx linux cmd 2025-03-06 11:23:56 +08:00
houseme
aaf39a4301 improve unzip cmd 2025-03-06 10:52:14 +08:00
houseme
f50406c789 improve 2025-03-06 10:31:23 +08:00
houseme
6356b3409a fix actions/download-artifact version to v4 2025-03-06 08:48:20 +08:00
houseme
ec268dcb5a test build-rustfs-gui 2025-03-06 08:37:51 +08:00
houseme
2ae714be31 fix 2025-03-06 00:34:50 +08:00
houseme
666a3db95d test build.yml 2025-03-06 00:06:34 +08:00
houseme
895317ec80 improve add cache 2025-03-06 00:00:57 +08:00
houseme
47c4e2ac73 improve build.yml 2025-03-05 23:43:00 +08:00
houseme
8413ac6be3 test build gui 2025-03-05 23:35:38 +08:00
houseme
8aaa916b31 Merge pull request #251 from rustfs/feature/gui-improve
Feature/gui improve
2025-03-05 23:33:34 +08:00
houseme
6a8a653f9d refactor: remove unused methods and dependencies
1. Removed unused `unzip_file` and `download_file` methods from `utils/helper.rs`.
2. Removed `reqwest` and `zip` crates from `Cargo.toml`.
2025-03-05 19:05:30 +08:00
houseme
9866f959c1 feat: add build-rustfs-gui process and optimize utils/helper.rs
1. Added a new build process `build-rustfs-gui` in `build.yaml` to streamline the build operations for the RustFS GUI.
2. Optimized `cli/rustfs-gui/utils/helper.rs` by using `rust-embed` to embed the `rustfs` resources directly into the binary.
2025-03-05 18:47:21 +08:00
DamonXue
c9f6da9732 Merge pull request #250 from rustfs/dev_dx
fix: Update workspace member descriptions for clarity
2025-03-04 11:32:14 +08:00
Damonxue
381f5f0a53 fix: Update workspace member descriptions for clarity 2025-03-04 11:30:19 +08:00
loverustfs
1bed82420e Merge pull request #249 from rustfs/feature/windows_path
Feature/windows path
2025-03-04 08:55:17 +08:00
shiro.lee
f965662514 fix: Correct the error prompt 2025-03-03 20:36:45 +08:00
shiro
da6ec62be5 fix: Optimize the issue of obtaining path errors on Windows. 2025-03-03 20:13:27 +08:00
weisd
b73439bce1 fix iam service_account bugs 2025-03-03 17:38:17 +08:00
DamonXue
23be31e1f2 Merge pull request #248 from rustfs/dev_dx
refactor: clean up unused imports and simplify conditional statement in main.rs
2025-03-03 14:54:49 +08:00
Damonxue
eaa8ce4bf7 refactor: clean up unused imports and simplify conditional statement in main.rs 2025-03-03 14:40:07 +08:00
loverustfs
c0658a8223 Merge pull request #247 from rustfs/dev_issue_233
[issue 244] Optimize startup infomation
2025-03-02 23:37:05 +08:00
DamonXue
373d97ce97 refactor: simplify logging statements in console.rs and main.rs 2025-03-02 22:29:11 +08:00
DamonXue
2568582271 refactor: remove proc-macro support and replace timed_println with tracing info logs 2025-03-02 22:27:15 +08:00
DamonXue
2d285ca504 feat: enhance tracing setup with pretty formatting and enable file/line number logging 2025-03-02 21:48:43 +08:00
DamonXue
ea0393f4c0 style: format code for consistency and readability 2025-03-02 20:06:45 +08:00
DamonXue
ff18894d5d refactor: remove unused dependencies and update s3s source references 2025-03-02 20:01:48 +08:00
DamonXue
b4caff13cf Merge branch 'main' of https://github.com/rustfs/s3-rustfs into dev_issue_233 2025-03-02 19:54:06 +08:00
DamonXue
c70994ee9d feat: add proc-macro support for timed logging and update console output 2025-03-02 19:43:47 +08:00
DamonXue
75fd8da685 feat: add chrono dependency and enhance console configuration with documentation and version info 2025-03-02 18:53:48 +08:00
DamonXue
54ca354d7e feat: add local IP address retrieval and update console address default 2025-03-02 17:40:36 +08:00
houseme
218e06a3fe improve build yml 2025-03-02 16:53:27 +08:00
Nugine
a95c9b32d8 ci: fix setup 2025-03-02 04:08:40 +08:00
Nugine
48f2fdc45d build: use lld 2025-03-02 03:48:53 +08:00
Nugine
ace5857959 ci: reduce setup time 2025-03-02 02:52:25 +08:00
houseme
1022bbec1e ci: confirm static directory placement in artifact package
Ensure the static directory is copied as a sibling to the rustfs binary
in the artifact package, maintaining the proper directory structure
for the application to locate its resources.
2025-03-02 01:14:10 +08:00
houseme
9c19e1aa41 ci: optimize GitHub Actions build workflow and fix artifact merging
- Fix artifact pattern matching in merge step to use consistent name pattern
- Standardize artifact naming convention with clear format
- Improve static assets handling with simpler download and extraction
- Add 7-day retention policy for artifacts to manage storage
- Use output variables to ensure consistency between artifact names and paths
- Optimize package creation process to eliminate redundant nesting
- Enhance error handling and script readability
2025-03-02 00:59:46 +08:00
Nugine
c338ea3c86 ci: enable cache for test 2025-03-02 00:37:56 +08:00
houseme
8cb4d72a7b improve buidl.yml 2025-03-02 00:28:45 +08:00
houseme
2b1dcb77cc test build action 2025-03-01 23:49:04 +08:00
weisd
f64d6751a6 use rand 0.8.5 2025-03-01 23:29:45 +08:00
houseme
e25cd9b5f6 feat: add remote file download, extraction, and packaging process in build.yml (#245)
* fix

* update README.md
2025-03-01 23:14:30 +08:00
loverustfs
40f6185b24 Update README.md 2025-03-01 22:28:19 +08:00
loverustfs
6ee30b8bfc Update README.md 2025-03-01 21:54:35 +08:00
loverustfs
8284d7d92c Update README.md 2025-03-01 21:48:41 +08:00
loverustfs
67ae916968 Merge pull request #241 from rustfs/dependabot/cargo/dependencies-4426481644
Bump the dependencies group with 5 updates
2025-03-01 21:24:42 +08:00
weisd
990db0636a Merge pull request #242 from rustfs/dev_issue_233 2025-03-01 17:54:08 +08:00
DamonXue
9ba6f89dc5 fix: update Functions deserialization logic and add run.bat script 2025-03-01 17:27:07 +08:00
dependabot[bot]
20e7dc919f Bump the dependencies group with 5 updates
Bumps the dependencies group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [clap](https://github.com/clap-rs/clap) | `4.5.30` | `4.5.31` |
| [rand](https://github.com/rust-random/rand) | `0.8.5` | `0.9.0` |
| [uuid](https://github.com/uuid-rs/uuid) | `1.14.0` | `1.15.1` |
| [rust-embed](https://github.com/pyros2097/rust-embed) | `8.5.0` | `8.6.0` |
| [strum](https://github.com/Peternator7/strum) | `0.26.3` | `0.27.1` |


Updates `clap` from 4.5.30 to 4.5.31
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.30...v4.5.31)

Updates `rand` from 0.8.5 to 0.9.0
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/0.8.5...0.9.0)

Updates `uuid` from 1.14.0 to 1.15.1
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.14.0...v1.15.1)

Updates `rust-embed` from 8.5.0 to 8.6.0
- [Changelog](https://github.com/pyrossh/rust-embed/blob/master/changelog.md)
- [Commits](https://github.com/pyros2097/rust-embed/commits)

Updates `strum` from 0.26.3 to 0.27.1
- [Release notes](https://github.com/Peternator7/strum/releases)
- [Changelog](https://github.com/Peternator7/strum/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Peternator7/strum/compare/v0.26.3...v0.27.1)

---
updated-dependencies:
- dependency-name: clap
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: rand
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: rust-embed
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: strum
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-01 06:02:44 +00:00
weisd
79351da42a add build info to console config 2025-02-28 09:26:02 +08:00
houseme
cb9ecd890c improve profile and upgrade zip 2.2.3 , chrono 0.4.40 2025-02-27 22:38:55 +08:00
houseme
ca4a936c6e Merge branch 'main' of github.com:rustfs/s3-rustfs into feature/logger
# Conflicts:
#	Cargo.toml
2025-02-27 19:03:32 +08:00
houseme
d7417d841f add 2025-02-27 19:00:47 +08:00
loverustfs
e65bee049a Merge pull request #240 from rustfs/dev_issue_233
fix: enforce condition element presence in Functions deserialization
2025-02-26 23:02:37 +08:00
DamonXue
87d6083807 fix: enforce condition element presence in Functions deserialization
feat: add binary target for rustfs
2025-02-26 21:08:44 +08:00
weisd
d8198cc01f add s3s host style 2025-02-26 17:38:39 +08:00
Nugine
1505429c5f ci: disable mint test 2025-02-26 17:10:37 +08:00
Nugine
24fe747b69 ci: fix e2e tests 2025-02-26 15:14:02 +08:00
weisd
4c0fbd238b use rust_embed for console static files 2025-02-25 11:08:40 +08:00
weisd
df4b285e46 Merge pull request #235 from rustfs/fix/226
complete_multipart_upload output etag
2025-02-25 10:20:36 +08:00
weisd
1744d8f23a sync s3s, return UnauthorizedAccess error code when credentials is none 2025-02-25 10:05:03 +08:00
weisd
3695bce742 fix add service_account 2025-02-25 00:39:19 +08:00
weisd
0295229e7e merge dada/admin 2025-02-24 23:40:09 +08:00
weisd
0122343075 merge fix/224 2025-02-24 23:05:16 +08:00
weisd
475d758645 add console static files 2025-02-24 23:00:40 +08:00
weisd
0dd21e9075 add console static files 2025-02-24 23:00:40 +08:00
weisd
4a0bc24aa6 fix:#226 complete_multipart_upload output etag 2025-02-24 14:27:43 +08:00
weisd
3d5cfab7c5 fix complete_multipart_md5 2025-02-24 13:21:42 +08:00
weisd
dddfb8cbc2 fix admin api bugs 2025-02-24 11:15:50 +08:00
houseme
ec9b1262cb improve code for audit 2025-02-23 16:38:41 +08:00
weisd
c844d16c2e fix service account action, add console config api 2025-02-23 15:06:13 +08:00
houseme
b3890cd07d Merge branch 'main' of github.com:rustfs/s3-rustfs into feature/logger 2025-02-23 09:21:07 +08:00
Nugine
5aa8616268 ci: build for old glibc (#232)
* build(deps): shadow_rs

* ci(build): build for old glibc

* ci: simplify all
2025-02-22 20:25:16 +08:00
houseme
784e3c82f8 Merge branch 'main' of github.com:rustfs/s3-rustfs into feature/logger
# Conflicts:
#	Cargo.toml
2025-02-22 17:00:58 +08:00
loverustfs
984faa2e85 Merge pull request #230 from rustfs/nugine/fix-ci
ci: fix basic checks
2025-02-22 16:39:01 +08:00
Nugine
b562bd20bb fix 2025-02-22 15:31:22 +08:00
Nugine
ad6c7ca623 fix 2025-02-22 15:28:26 +08:00
Nugine
9e57981114 rename 2025-02-22 15:09:42 +08:00
Nugine
41e7dfea55 fix gui dependencies 2025-02-22 15:08:22 +08:00
Nugine
f2767239af ci: fix basic checks 2025-02-22 15:00:39 +08:00
weisd
bf5c2b6a9c fix policy_db_get 2025-02-22 01:05:27 +08:00
houseme
7e7ab2cab3 feat(logging): add Kafka and Webhook audit targets
- Implemented `KafkaAuditTarget` to send audit entries to a Kafka topic.
- Implemented `WebhookAuditTarget` to send audit entries to a specified webhook URL.
- Updated `AuditLogger` to support multiple audit targets including Kafka and Webhook.
- Added examples and documentation for the new audit targets.
2025-02-21 18:49:25 +08:00
houseme
66910bdfee Implement initialization for packages/logging
- Add initialization logic for the `rustfs-logging` crate.
- Provide examples for logging utilities.
- Include tests for logging and telemetry functionalities.
- Ensure proper configuration of dependencies in `Cargo.toml`.
2025-02-21 13:46:35 +08:00
weisd
c9f9edfcf5 sync s3s, fix #224 2025-02-19 15:17:58 +08:00
houseme
cb9457ae09 Refactor main.rs for clarity and modularity in rustfs-gui (#225)
* Improve init_logger function and format code with cargo fmt

- Enhance `init_logger` function for better logging configuration.
- Apply `cargo fmt` to format the codebase.

* Refactor main.rs for clarity and modularity in rustfs-gui

- Move `init_logger` function to `utils/logger.rs` for better separation of concerns.
- Create a dedicated `router` module in `router/router.rs`.
- Update `main.rs` to use the new `logger` and `router` modules.
- Apply `cargo fmt` to format the codebase.
2025-02-18 18:37:17 +08:00
houseme
3aee1598a9 Add new setting view, component, and router to rustfs-gui (#223)
- Create `SettingViews` component in `views/setting.rs`.
- Update `views/mod.rs` to include the new `SettingViews` component.
- Update routing in `main.rs` to include the new route for `SettingViews`.
2025-02-18 01:39:16 +08:00
houseme
a9dbd5f341 Add new home views to rustfs-gui (#222)
- Create `Home` component in `components/Home.rs`.
- Create `Navbar` component in `components/navbar.rs`.
- Create `HomeView` component in `views/home.rs`.
- Update `views/mod.rs` to include new views.
- Update routing in `main.rs` to include new routes for `HomeView`.
2025-02-18 01:29:27 +08:00
houseme
0ff795f67a Add new CSS, JS, and icon assets to rustfs-gui (#221)
* Add new CSS, JS, and icon assets to rustfs-gui

- Add `navbar.css` for styling the navigation bar.
- Add `sts.js` for handling tab switching and password toggling.
- Include new icon assets in `assets/icons` directory.
- Update `Dioxus.toml` to reference new assets.

* Remove unused icons from dioxus.toml

- Remove `assets/icons/icon_*.png` from the icon list.
2025-02-18 01:12:25 +08:00
houseme
93f7370157 Add utility functions and configurations for rustfs-gui (#220)
* Initialize rustfs-gui crate

- Set up the `rustfs-gui` package in the workspace.
- Add `dioxus` dependency with `router` feature.
- Configure workspace settings for edition, license, repository, and rust-version.
- Include lints configuration for the workspace.

* Add utility functions and configurations for rustfs-gui

- Implement `RustFSConfig` struct with default values and methods for loading, saving, and clearing configurations.
- Add `ServiceCommand` enum for managing service commands.
- Implement `ServiceManager` struct for starting, stopping, and restarting the service.
- Include helper functions for checking service status, preparing the service, downloading files, and unzipping files.
- Add logging and error handling for service operations.
2025-02-18 00:55:34 +08:00
houseme
cb4732fe2f Initialize rustfs-gui crate (#219)
- Set up the `rustfs-gui` package in the workspace.
- Add `dioxus` dependency with `router` feature.
- Configure workspace settings for edition, license, repository, and rust-version.
- Include lints configuration for the workspace.
2025-02-17 17:54:57 +08:00
weisd
e65b7975fb clap env support 2025-02-17 16:15:16 +08:00
weisd
c0243ce329 Merge pull request #216 from rustfs/dada/policy
fix policy parse
2025-02-13 14:19:53 +08:00
weisd
12a1e667e2 fix policy parse 2025-02-12 17:34:23 +08:00
weisd
6ec7748677 add admin router params 2025-02-11 10:34:54 +08:00
weisd
671f2b7473 fix admin add user fail 2025-02-11 10:10:12 +08:00
weisd
1968bdc219 fix build target windows check errors 2025-02-10 15:44:21 +08:00
shiro.lee
59c28b4f86 fix: fix windows build 2025-02-06 19:59:36 +08:00
loverustfs
672f06eb80 Merge pull request #213 from rustfs/dependabot/cargo/dependencies-3ba431ae48
Bump the dependencies group with 17 updates
2025-02-02 20:38:30 +08:00
dependabot[bot]
b9712afd29 Bump the dependencies group with 17 updates
Bumps the dependencies group with 17 updates:

| Package | From | To |
| --- | --- | --- |
| [async-trait](https://github.com/dtolnay/async-trait) | `0.1.83` | `0.1.86` |
| [clap](https://github.com/clap-rs/clap) | `4.5.23` | `4.5.27` |
| [hyper](https://github.com/hyperium/hyper) | `1.5.2` | `1.6.0` |
| [pin-project-lite](https://github.com/taiki-e/pin-project-lite) | `0.2.15` | `0.2.16` |
| [prost-build](https://github.com/tokio-rs/prost) | `0.13.3` | `0.13.4` |
| [serde_json](https://github.com/serde-rs/json) | `1.0.134` | `1.0.138` |
| [tempfile](https://github.com/Stebalien/tempfile) | `3.14.0` | `3.16.0` |
| [thiserror](https://github.com/dtolnay/thiserror) | `2.0.9` | `2.0.11` |
| [tokio](https://github.com/tokio-rs/tokio) | `1.42.0` | `1.43.0` |
| [transform-stream](https://github.com/Nugine/transform-stream) | `0.3.0` | `0.3.1` |
| [uuid](https://github.com/uuid-rs/uuid) | `1.11.0` | `1.12.1` |
| [log](https://github.com/rust-lang/log) | `0.4.22` | `0.4.25` |
| [matchit](https://github.com/ibraheemdev/matchit) | `0.8.5` | `0.8.6` |
| [shadow-rs](https://github.com/baoyachi/shadow-rs) | `0.37.0` | `0.38.0` |
| [const-str](https://github.com/Nugine/const-str) | `0.5.7` | `0.6.1` |
| [highway](https://github.com/nickbabcock/highway-rs) | `1.2.0` | `1.3.0` |
| [ipnetwork](https://github.com/achanda/ipnetwork) | `0.20.0` | `0.21.1` |


Updates `async-trait` from 0.1.83 to 0.1.86
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.83...0.1.86)

Updates `clap` from 4.5.23 to 4.5.27
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.23...clap_complete-v4.5.27)

Updates `hyper` from 1.5.2 to 1.6.0
- [Release notes](https://github.com/hyperium/hyper/releases)
- [Changelog](https://github.com/hyperium/hyper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper/compare/v1.5.2...v1.6.0)

Updates `pin-project-lite` from 0.2.15 to 0.2.16
- [Release notes](https://github.com/taiki-e/pin-project-lite/releases)
- [Changelog](https://github.com/taiki-e/pin-project-lite/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project-lite/compare/v0.2.15...v0.2.16)

Updates `prost-build` from 0.13.3 to 0.13.4
- [Release notes](https://github.com/tokio-rs/prost/releases)
- [Changelog](https://github.com/tokio-rs/prost/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/prost/compare/v0.13.3...v0.13.4)

Updates `serde_json` from 1.0.134 to 1.0.138
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.134...v1.0.138)

Updates `tempfile` from 3.14.0 to 3.16.0
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.14.0...v3.16.0)

Updates `thiserror` from 2.0.9 to 2.0.11
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.9...2.0.11)

Updates `tokio` from 1.42.0 to 1.43.0
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.42.0...tokio-1.43.0)

Updates `transform-stream` from 0.3.0 to 0.3.1
- [Release notes](https://github.com/Nugine/transform-stream/releases)
- [Commits](https://github.com/Nugine/transform-stream/compare/v0.3.0...v0.3.1)

Updates `uuid` from 1.11.0 to 1.12.1
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.11.0...1.12.1)

Updates `log` from 0.4.22 to 0.4.25
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/compare/0.4.22...0.4.25)

Updates `matchit` from 0.8.5 to 0.8.6
- [Release notes](https://github.com/ibraheemdev/matchit/releases)
- [Commits](https://github.com/ibraheemdev/matchit/compare/v0.8.5...v0.8.6)

Updates `shadow-rs` from 0.37.0 to 0.38.0
- [Release notes](https://github.com/baoyachi/shadow-rs/releases)
- [Commits](https://github.com/baoyachi/shadow-rs/compare/v0.37.0...v0.38.0)

Updates `const-str` from 0.5.7 to 0.6.1
- [Release notes](https://github.com/Nugine/const-str/releases)
- [Commits](https://github.com/Nugine/const-str/compare/v0.5.7...v0.6.1)

Updates `highway` from 1.2.0 to 1.3.0
- [Changelog](https://github.com/nickbabcock/highway-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nickbabcock/highway-rs/compare/v1.2.0...v1.3.0)

Updates `ipnetwork` from 0.20.0 to 0.21.1
- [Release notes](https://github.com/achanda/ipnetwork/releases)
- [Changelog](https://github.com/achanda/ipnetwork/blob/master/CHANGELOG.md)
- [Commits](https://github.com/achanda/ipnetwork/compare/v0.20.0...v0.21.1)

---
updated-dependencies:
- dependency-name: async-trait
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: clap
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: hyper
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: pin-project-lite
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: prost-build
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tempfile
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: transform-stream
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: log
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: matchit
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: shadow-rs
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: const-str
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: highway
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: ipnetwork
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-01 05:15:24 +00:00
weisd
0531437c94 add console static server 2025-01-22 13:47:35 +08:00
weisd
bb3ea541a2 Merge pull request #212 from rustfs/rewrite-iam
add policy api
2025-01-22 12:41:06 +08:00
weisd
e4e2fa23ce add policy api 2025-01-22 12:37:41 +08:00
weisd
682f3009ba Merge pull request #211 from rustfs/rewrite-iam
Rewrite iam
2025-01-21 18:11:27 +08:00
weisd
9bfd259b03 fix get body bytes 2025-01-21 18:11:10 +08:00
weisd
3266af774c check 2025-01-21 17:49:55 +08:00
weisd
36f8101c21 rewrite group handler 2025-01-21 16:44:55 +08:00
weisd
dd83f870b9 rewrite service_account handler 2025-01-21 16:17:28 +08:00
weisd
2c3a9a3bc8 rewrite AssumeRoleHandle 2025-01-21 00:29:55 +08:00
weisd
10a4769115 rewrite iam 2025-01-17 17:22:39 +08:00
weisd
dc292ca657 fix get s3 body bytes use store_all_unlimited 2025-01-15 21:45:23 +08:00
weisd
7fc3a500d3 fix get s3 body bytes use store_all_unlimited 2025-01-15 21:44:02 +08:00
weisd
ccb0f15655 sync s3s 2025-01-14 13:48:57 +08:00
weisd
426f4cf569 fix access check 2025-01-14 13:26:41 +08:00
weisd
2585a09219 rm unused test 2025-01-14 11:03:12 +08:00
weisd
83edaef6d3 Merge pull request #210 from rustfs/feat/admin-api
Feat/admin api
2025-01-14 10:43:56 +08:00
weisd
1551360dda add admin api response content-type 2025-01-14 10:36:53 +08:00
weisd
977cef9d29 init group 2025-01-13 20:46:18 +08:00
weisd
f7b63ebac1 Merge pull request #209 from rustfs/feat/admin-api
feat: add admin user api
2025-01-13 17:26:16 +08:00
weisd
c90a98e427 feat: add admin user api 2025-01-13 17:25:15 +08:00
weisd
2cd2f99723 Merge pull request #205 from rustfs/feat/admin-api
add walk api
2025-01-12 22:51:39 +08:00
weisd
b5a1f6fcd6 add walk api, fix: load iam config 2025-01-12 22:36:57 +08:00
weisd
b99a9b68dc iam add_user 2025-01-12 03:29:57 +08:00
weisd
3ec7f90d95 iam add_user 2025-01-12 03:04:14 +08:00
weisd
86b4cae95d extract_claims 2025-01-12 01:41:22 +08:00
weisd
c3dd28c510 cargo fmt 2025-01-11 01:01:04 +08:00
weisd
bec2b2a5e0 Merge pull request #204 from rustfs/fix/make_bucket_created
fix make_bucket created not set
2025-01-10 23:50:18 +08:00
weisd
d01d3f9c96 Merge pull request #203 from rustfs/feat/cros
Feat/cros
2025-01-10 23:49:42 +08:00
weisd
057b6b63b3 fix make_bucket created not set 2025-01-10 23:49:21 +08:00
weisd
b522e15328 feat:cors 2025-01-07 22:26:26 +08:00
weisd
86247e59a0 feat:cros 2025-01-07 22:00:49 +08:00
weisd
7e0926febf Merge pull request #202 from rustfs/feat/admin-api
fix #110 #112 add ServerInfoHandler
2025-01-06 17:33:00 +08:00
weisd
141ad15a48 fix #110 #112 add ServerInfoHandler need test 2025-01-06 16:02:21 +08:00
weisd
39483d90d1 Merge pull request #201 from rustfs/fix/list-object
fix:#191
2025-01-03 15:15:32 +08:00
weisd
c0f0823076 fix:#191 2025-01-03 14:42:11 +08:00
weisd
ebee564436 Merge pull request #199 from rustfs/dependabot/cargo/dependencies-0b5f48f217
Bump the dependencies group with 19 updates
2025-01-03 09:21:47 +08:00
weisd
11d99845ce Merge pull request #200 from rustfs/copyobject
feat:#165 copyobject v1
2025-01-03 09:20:51 +08:00
weisd
f0fe3e30af feat:#165 copyobject v1 2025-01-03 02:09:51 +08:00
dependabot[bot]
21713ebea7 Bump the dependencies group with 19 updates
Bumps the dependencies group with 19 updates:

| Package | From | To |
| --- | --- | --- |
| [chrono](https://github.com/chronotope/chrono) | `0.4.38` | `0.4.39` |
| [clap](https://github.com/clap-rs/clap) | `4.5.21` | `4.5.23` |
| [flatbuffers](https://github.com/google/flatbuffers) | `24.3.25` | `24.12.23` |
| [hyper](https://github.com/hyperium/hyper) | `1.5.1` | `1.5.2` |
| [http](https://github.com/hyperium/http) | `1.1.0` | `1.2.0` |
| [prost](https://github.com/tokio-rs/prost) | `0.13.3` | `0.13.4` |
| [prost-types](https://github.com/tokio-rs/prost) | `0.13.3` | `0.13.4` |
| [serde](https://github.com/serde-rs/serde) | `1.0.215` | `1.0.217` |
| [serde_json](https://github.com/serde-rs/json) | `1.0.133` | `1.0.134` |
| [thiserror](https://github.com/dtolnay/thiserror) | `2.0.3` | `2.0.9` |
| [time](https://github.com/time-rs/time) | `0.3.36` | `0.3.37` |
| [tokio](https://github.com/tokio-rs/tokio) | `1.41.1` | `1.42.0` |
| [tokio-stream](https://github.com/tokio-rs/tokio) | `0.1.16` | `0.1.17` |
| [tower](https://github.com/tower-rs/tower) | `0.5.1` | `0.5.2` |
| [tokio-util](https://github.com/tokio-rs/tokio) | `0.7.12` | `0.7.13` |
| [shadow-rs](https://github.com/baoyachi/shadow-rs) | `0.36.0` | `0.37.0` |
| [glob](https://github.com/rust-lang/glob) | `0.3.1` | `0.3.2` |
| [xxhash-rust](https://github.com/DoumanAsh/xxhash-rust) | `0.8.12` | `0.8.15` |
| [itertools](https://github.com/rust-itertools/itertools) | `0.13.0` | `0.14.0` |


Updates `chrono` from 0.4.38 to 0.4.39
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.38...v0.4.39)

Updates `clap` from 4.5.21 to 4.5.23
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.21...clap_complete-v4.5.23)

Updates `flatbuffers` from 24.3.25 to 24.12.23
- [Release notes](https://github.com/google/flatbuffers/releases)
- [Changelog](https://github.com/google/flatbuffers/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/flatbuffers/compare/v24.3.25...v24.12.23)

Updates `hyper` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/hyperium/hyper/releases)
- [Changelog](https://github.com/hyperium/hyper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper/compare/v1.5.1...v1.5.2)

Updates `http` from 1.1.0 to 1.2.0
- [Release notes](https://github.com/hyperium/http/releases)
- [Changelog](https://github.com/hyperium/http/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/http/compare/v1.1.0...v1.2.0)

Updates `prost` from 0.13.3 to 0.13.4
- [Release notes](https://github.com/tokio-rs/prost/releases)
- [Changelog](https://github.com/tokio-rs/prost/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/prost/compare/v0.13.3...v0.13.4)

Updates `prost-types` from 0.13.3 to 0.13.4
- [Release notes](https://github.com/tokio-rs/prost/releases)
- [Changelog](https://github.com/tokio-rs/prost/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/prost/compare/v0.13.3...v0.13.4)

Updates `serde` from 1.0.215 to 1.0.217
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.215...v1.0.217)

Updates `serde_json` from 1.0.133 to 1.0.134
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.133...v1.0.134)

Updates `thiserror` from 2.0.3 to 2.0.9
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.3...2.0.9)

Updates `time` from 0.3.36 to 0.3.37
- [Release notes](https://github.com/time-rs/time/releases)
- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)
- [Commits](https://github.com/time-rs/time/compare/v0.3.36...v0.3.37)

Updates `tokio` from 1.41.1 to 1.42.0
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.41.1...tokio-1.42.0)

Updates `tokio-stream` from 0.1.16 to 0.1.17
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-stream-0.1.16...tokio-stream-0.1.17)

Updates `tower` from 0.5.1 to 0.5.2
- [Release notes](https://github.com/tower-rs/tower/releases)
- [Commits](https://github.com/tower-rs/tower/compare/tower-0.5.1...tower-0.5.2)

Updates `tokio-util` from 0.7.12 to 0.7.13
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-util-0.7.12...tokio-util-0.7.13)

Updates `shadow-rs` from 0.36.0 to 0.37.0
- [Release notes](https://github.com/baoyachi/shadow-rs/releases)
- [Commits](https://github.com/baoyachi/shadow-rs/compare/v0.36.0...v0.37.0)

Updates `glob` from 0.3.1 to 0.3.2
- [Release notes](https://github.com/rust-lang/glob/releases)
- [Changelog](https://github.com/rust-lang/glob/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/glob/compare/0.3.1...v0.3.2)

Updates `xxhash-rust` from 0.8.12 to 0.8.15
- [Commits](https://github.com/DoumanAsh/xxhash-rust/commits)

Updates `itertools` from 0.13.0 to 0.14.0
- [Changelog](https://github.com/rust-itertools/itertools/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-itertools/itertools/compare/v0.13.0...v0.14.0)

---
updated-dependencies:
- dependency-name: chrono
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: clap
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: flatbuffers
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: hyper
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: http
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: prost
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: prost-types
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: time
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: tokio-stream
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tower
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tokio-util
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: shadow-rs
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: glob
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: xxhash-rust
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: itertools
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 05:43:52 +00:00
weisd
f4f818277e Merge pull request #198 from rustfs/list-objects
fix: #137 #186 skip delete marker objects when list object
2024-12-31 17:02:20 +08:00
weisd
3316a6e073 fix: #137 #186 skip delete marker objects when list object 2024-12-31 16:57:01 +08:00
weisd
6246e8a675 Merge pull request #197 from rustfs/ec_test
fix: #196 can_decode blocks check err
2024-12-30 14:24:08 +08:00
weisd
861a714014 fix can_decode num count 2024-12-30 14:00:57 +08:00
junxiangMu
343aeda8ba Merge pull request #195 from rustfs/wip-dandan
fix remote err && lock err
2024-12-30 11:39:24 +08:00
junxiang Mu
53c1184c1f fix remote err && lock err
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-30 11:38:36 +08:00
weisd
43b52b32f2 fix: #189 #192 2024-12-29 23:49:34 +08:00
weisd
d1521c021d Merge pull request #194 from rustfs/fix/metadata
fix: #189 #192
2024-12-29 23:37:51 +08:00
weisd
bd7f82ce45 fix: #189 #192 2024-12-29 23:36:10 +08:00
junxiangMu
3ad460c6e9 Merge pull request #190 from rustfs/wip-dandan
fix heal
2024-12-29 20:35:29 +08:00
junxiang Mu
175a636755 remove debug info
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-29 20:34:39 +08:00
junxiang Mu
9e482e9dd4 tmp 5
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-29 20:27:05 +08:00
junxiang Mu
ce4842afd7 tmp 4
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-29 20:25:23 +08:00
junxiang Mu
ffa49aecea tmp 3
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-29 18:19:46 +08:00
weisd
a19c75f1ee Merge pull request #187 from rustfs/iam/add-tests
test(iam): add policy_is_allowed
2024-12-29 18:01:25 +08:00
weisd
55bf4d9597 Merge pull request #188 from rustfs/fix/versioning
fix: #186 multipart upload version
2024-12-29 17:57:32 +08:00
junxiang Mu
f0149c3e04 tmp 2
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-29 17:43:51 +08:00
junxiang Mu
2e1742c1f4 tmp1
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-29 17:43:51 +08:00
weisd
a0e956e61f fix: #186 multipart upload version 2024-12-29 17:18:26 +08:00
bestgopher
907c606bbd test(iam): add policy_is_allowed 2024-12-29 16:25:06 +08:00
weisd
baa8b62dc3 fix multipart upload etag 2024-12-29 08:51:25 +08:00
weisd
c5b8a20092 clippy 2024-12-28 22:41:51 +08:00
weisd
5afc578951 Merge pull request #184 from rustfs/list-objects
List objects
2024-12-28 22:34:15 +08:00
weisd
92a28b1639 Merge branch 'main' into list-objects 2024-12-28 22:31:46 +08:00
weisd
5f6ee3f9f2 Merge remote-tracking branch 'origin/main' into list-objects 2024-12-28 22:23:14 +08:00
weisd
8033cc7d72 Merge pull request #185 from rustfs/fix/etag
fix: #174  etag for multipart upload
2024-12-28 22:17:40 +08:00
weisd
3138f23648 fix: #174 etag for multipart upload 2024-12-28 22:07:03 +08:00
weisd
fffe24bd2c fix: #174 2024-12-26 16:32:27 +08:00
weisd
bc05217322 rm test 2024-12-26 09:30:40 +08:00
weisd
0dbc66af7a cargo fmt 2024-12-26 00:17:41 +08:00
weisd
130a719465 merge main 2024-12-26 00:10:11 +08:00
weisd
bdf11fe3b3 marker done, need test 2024-12-25 23:35:41 +08:00
junxiangMu
1e8bea42c7 Merge pull request #183 from rustfs/wip-dandan
reduce panic function call
2024-12-25 15:02:48 +08:00
junxiang Mu
acb6f72ee7 reduce panic function call
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-25 15:01:26 +08:00
loverustfs
74220acb2e Merge pull request #182 from rustfs/windows_compile
fix: fix windows compile error
2024-12-24 23:05:48 +08:00
shiro.lee
a15bda1bce fix: fix windows compile error 2024-12-24 22:51:50 +08:00
weisd
f8f6d7d9be clippy 2024-12-24 20:04:40 +08:00
weisd
0135ddcb36 Merge branch 'list-objects-rpc' into list-objects 2024-12-24 20:02:12 +08:00
weisd
cd306cd450 review list_objects 2024-12-24 17:01:37 +08:00
weisd
c4823c4c89 fix:#175 add list_object_versions 2024-12-23 23:24:11 +08:00
weisd
cf99ca2cf8 remove openssl dep 2024-12-23 19:58:37 +08:00
junxiang Mu
9c0364b0c3 rewrite decode
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-23 17:46:39 +08:00
junxiang Mu
39ffccbf45 fix unimport err
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-23 17:11:38 +08:00
junxiang Mu
dc42003969 add test case
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-23 16:21:30 +08:00
junxiang Mu
55583294c9 refactor walk_dir grpc api
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-23 16:21:30 +08:00
weisd
73c3f202d0 fix check file not found use is_err_object_not_found 2024-12-23 15:44:24 +08:00
weisd
b0b01c105f clippy 2024-12-22 11:27:56 +08:00
weisd
ba0b1c93d2 todo: rpc walk_dir use writer 2024-12-22 11:01:50 +08:00
weisd
e5ba415ec5 todo: rpc walk_dir use writer 2024-12-22 10:52:52 +08:00
weisd
74434317d3 fix mc ls -r 2024-12-22 05:35:08 +08:00
weisd
558d077ef6 clippy 2024-12-22 05:04:48 +08:00
weisd
354fa5470c list_object v2 use channel, todo other params 2024-12-22 04:57:15 +08:00
junxiangMu
dcac6fae70 Merge pull request #170 from rustfs/fix_heal
Fix heal
2024-12-19 18:20:57 +08:00
junxiang Mu
e9b00bb369 add tick check disk
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-19 17:27:17 +08:00
junxiang Mu
623869ce25 add auto fix disk
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-19 17:27:16 +08:00
junxiang Mu
052a27ddaf add down object heal
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-19 17:26:43 +08:00
junxiangMu
7133e492b6 Merge pull request #169 from rustfs/refactor-err
Refactor err
2024-12-19 17:21:21 +08:00
junxiang Mu
e7b94e9698 fix vec index out bound
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-18 21:07:11 +08:00
junxiang Mu
6af228d82b refactor error framework
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-18 20:50:22 +08:00
junxiang Mu
705d51c818 tmp1
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-18 17:48:43 +08:00
weisd
469d2cc321 need test merge_entry_channels 2024-12-18 16:57:24 +08:00
weisd
056b611125 test_list_merge 2024-12-17 17:45:56 +08:00
weisd
55827b0720 test_list_path done 2024-12-17 16:41:25 +08:00
weisd
a8b8ea10d1 test_list_path_raw done 2024-12-17 14:28:37 +08:00
weisd
8f98bb6897 test walk_dir done 2024-12-16 23:05:16 +08:00
weisd
3c76ee9109 cargo check 2024-12-16 22:22:58 +08:00
weisd
93f06e431e cargo check 2024-12-16 22:20:33 +08:00
weisd
1e04c65f76 test walk_dir done 2024-12-16 22:14:29 +08:00
weisd
b4696f8c60 test walk_dir done 2024-12-16 22:14:29 +08:00
weisd
cced40b5cb test metawrite 2024-12-16 22:14:29 +08:00
weisd
fb24c4550b test metacache 2024-12-16 22:14:29 +08:00
weisd
11fee7db63 test work_dir done 2024-12-16 22:14:29 +08:00
weisd
c28dc2f441 test 2024-12-16 22:14:29 +08:00
weisd
fefd96a5d3 clippy 2024-12-16 22:14:29 +08:00
weisd
e7042f4429 fix:#159, fix:#160 2024-12-16 22:14:29 +08:00
weisd
ad51ab6273 AssumeRoleHandle done 2024-12-16 22:14:29 +08:00
mujunxiang
2b05500ae3 tmp(1)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-16 22:13:59 +08:00
weisd
5dafee2c0f test walk 2024-12-16 22:11:05 +08:00
weisd
7370973a79 scandir 2024-12-16 22:11:05 +08:00
weisd
e1703d287b metacache done 2024-12-16 22:11:05 +08:00
weisd
8a0a25f0bf init metacache io 2024-12-16 22:11:05 +08:00
weisd
b350323440 init metacache io 2024-12-16 22:09:47 +08:00
weisd
420df51e47 rewrite real_meta 2024-12-16 22:09:47 +08:00
weisd
7f74ae6e79 clippy
clippy

clippy
2024-12-16 22:09:13 +08:00
weisd
2e04dee223 test walk_dir done 2024-12-16 22:04:47 +08:00
weisd
20e434be5a test metawrite 2024-12-16 17:45:28 +08:00
weisd
caec2767ab test metacache 2024-12-16 10:11:41 +08:00
weisd
73b003b0bc test work_dir done 2024-12-16 10:11:41 +08:00
weisd
352416e309 test 2024-12-16 10:11:41 +08:00
weisd
47d3d4f845 clippy 2024-12-16 10:05:34 +08:00
weisd
b08878c75a cargo fmt 2024-12-16 10:02:21 +08:00
weisd
1b99041e5f fix: bug crash when disk drop 2024-12-16 10:02:21 +08:00
weisd
8eb6a6fc8a fix:#159, fix:#160 2024-12-16 10:02:18 +08:00
weisd
96e3b5c9e0 fix init_global_action_cred 2024-12-16 10:01:29 +08:00
weisd
8f8d353eb2 AssumeRoleHandle done 2024-12-16 10:01:29 +08:00
weisd
86497d41e0 fix find_local_disk 2024-12-16 10:01:29 +08:00
mirschao
4129700cf3 Update mint.yml 2024-12-16 10:01:29 +08:00
mirschao
5d1f9d5cd9 Update mint.yml 2024-12-16 10:01:29 +08:00
junxiang Mu
8465f10648 rebase main
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-16 10:01:29 +08:00
junxiang Mu
8b2450cdcf fix GLOBAL_LOCAL_DISK_MAP key
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-16 10:01:29 +08:00
mujunxiang
baf03dffd4 tmp(1)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-16 10:01:25 +08:00
mirschao
807be52e8f mint测试 2024-12-16 09:56:45 +08:00
mirschao
bd42ff1393 Update mint.yml
测试执行
2024-12-16 09:56:45 +08:00
mirschao
b167a7b384 Update mint.yml
测试执行
2024-12-16 09:56:45 +08:00
mirschao
9f2b3a27fa Update mint.yml 2024-12-16 09:56:45 +08:00
mirschao
865f0aca80 Update mint.yml 2024-12-16 09:56:45 +08:00
mirschao
c3546a1931 Update mint.yml 2024-12-16 09:56:45 +08:00
mirschao
b0e65f71d4 Update mint.yml 2024-12-16 09:56:45 +08:00
mirschao
f763218864 Update mint.yml
测试运行结果
2024-12-16 09:56:45 +08:00
mirschao
9c4fc0c55c Update mint.yml 2024-12-16 09:56:45 +08:00
mirschao
893fa3131b Update mint.yml
测试mint之查看启动参数
2024-12-16 09:56:45 +08:00
mirschao
0a49a986a4 Create mint.yml
测试mint检测手段之确定启动参数
2024-12-16 09:56:45 +08:00
Nugine
0930ec2d3d style: workspace lints (#148)
* fix: clippy error

* style: workspace lints

* test: ignore failures
2024-12-16 09:56:45 +08:00
weisd
e20f556f37 cargo fmt 2024-12-12 10:13:12 +08:00
weisd
f78b0d82e9 Merge pull request #163 from rustfs/fix/disks_join
Fix/disks join
2024-12-12 09:57:43 +08:00
weisd
e4a58abd7b fix: bug crash when disk drop 2024-12-12 09:54:06 +08:00
weisd
ff28415863 fix:#159, fix:#160 2024-12-11 16:05:29 +08:00
weisd
975d15a8ef fix init_global_action_cred 2024-12-10 20:50:00 +08:00
weisd
653d2753d4 Merge pull request #157 from rustfs/assumerole
AssumeRoleHandle done
2024-12-10 20:37:17 +08:00
weisd
d301765263 AssumeRoleHandle done 2024-12-10 20:35:51 +08:00
weisd
a03f9a0f3e fix find_local_disk 2024-12-09 17:43:32 +08:00
mirschao
a80f26ec36 Update mint.yml 2024-12-09 17:03:48 +08:00
mirschao
c6088d97d3 Update mint.yml 2024-12-09 17:01:14 +08:00
weisd
e9339a16b1 test walk 2024-12-09 15:55:02 +08:00
junxiangMu
4de6c838b4 Merge pull request #154 from rustfs/scanner
Scanner
2024-12-09 15:31:49 +08:00
junxiang Mu
3cf262afbf rebase main
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-09 15:31:10 +08:00
junxiang Mu
36f9592a10 fix GLOBAL_LOCAL_DISK_MAP key
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-12-09 15:20:45 +08:00
mujunxiang
cc57d2a073 tmp(1)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-09 15:19:15 +08:00
mirschao
9d7baa855e mint测试 2024-12-09 10:15:39 +08:00
weisd
01d7bbe0bd scandir 2024-12-09 10:03:02 +08:00
mirschao
f470b380b8 Update mint.yml
测试执行
2024-12-08 23:31:58 +08:00
mirschao
e33956d584 Update mint.yml
测试执行
2024-12-08 23:25:01 +08:00
mirschao
821af69bbe Update mint.yml 2024-12-08 23:08:10 +08:00
mirschao
d5cac7acbf Update mint.yml 2024-12-08 23:02:59 +08:00
mirschao
185a24ff12 Update mint.yml 2024-12-08 22:51:59 +08:00
mirschao
f6a9df54d2 Update mint.yml 2024-12-08 22:36:27 +08:00
mirschao
28b273c38e Update mint.yml
测试运行结果
2024-12-08 22:23:36 +08:00
mirschao
cdedd1b8bf Update mint.yml 2024-12-08 22:08:13 +08:00
mirschao
abd875983f Update mint.yml
测试mint之查看启动参数
2024-12-08 22:06:27 +08:00
mirschao
30c2f1d1f8 Create mint.yml
测试mint检测手段之确定启动参数
2024-12-08 22:02:33 +08:00
weisd
a65c2dbd8f metacache done 2024-12-06 14:05:43 +08:00
weisd
72eb8d0d73 init metacache io 2024-12-05 17:42:26 +08:00
weisd
90b884fe64 init metacache io 2024-12-05 17:42:17 +08:00
bestgopher
29e9683c35 fix: make cargo check happy 2024-12-05 17:41:21 +08:00
Nugine
870ab67be4 style: workspace lints (#148)
* fix: clippy error

* style: workspace lints

* test: ignore failures
2024-12-05 15:12:52 +08:00
bestgopher
ecc73efe2b Merge pull request #147 from rustfs/iam-sys-4
fix: make cargo check happy
2024-12-04 20:50:35 +08:00
bestgopher
345d4d2f95 fix: make cargo check happy 2024-12-04 20:47:31 +08:00
weisd
97fd6ca57b rewrite real_meta 2024-12-04 17:36:16 +08:00
weisd
e021b911d9 clippy
clippy

clippy
2024-12-04 13:32:15 +08:00
weisd
6bb9737237 Merge pull request #146 from rustfs/feat/notification_sys
Feat/notification sys
2024-12-04 11:02:09 +08:00
weisd
f0594cec77 Merge branch 'main' into feat/notification_sys 2024-12-04 11:00:37 +08:00
weisd
eef8271d07 notification_sys base 2024-12-04 10:55:09 +08:00
mujunxiang
5dab98ec49 scanner(2)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-04 10:51:34 +08:00
mujunxiang
b3b9f128e2 sanner(1)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-04 10:51:34 +08:00
Nugine
3a0efcdbc7 ci: allow clippy warnings 2024-12-04 10:51:34 +08:00
weisd
13a7220af9 test StorageInfoHandler 2024-12-03 17:38:52 +08:00
junxiangMu
83d3a7a8b1 Merge pull request #145 from rustfs/scanner
Scanner
2024-12-03 17:07:43 +08:00
mujunxiang
de315e4b7e scanner(2)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-03 17:05:23 +08:00
mujunxiang
d053662cf6 sanner(1)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-03 15:32:43 +08:00
weisd
390da76f68 fix clippy 2024-12-03 13:37:22 +08:00
Nugine
04d480012c ci: allow clippy warnings 2024-12-03 12:01:53 +08:00
weisd
b6ebb66966 Merge pull request #144 from rustfs/iam-sys-3
add default-feature for crypto crate
2024-12-03 11:45:47 +08:00
bestgopher
602b721c0e add default-feature for crypto crate 2024-12-03 11:16:19 +08:00
weisd
33f0221c9e fix bug 2024-12-03 11:12:57 +08:00
junxiangMu
51b47fc389 Merge pull request #143 from rustfs/fix-os
fix none import
2024-12-03 11:11:38 +08:00
mujunxiang
5e6d636f82 fix none import
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-03 11:11:02 +08:00
weisd
24a8be7848 add filemeta 2024-12-03 11:04:36 +08:00
安正超
7b2f775723 wip 2024-12-03 02:54:23 +00:00
junxiangMu
5a5990f201 Merge pull request #142 from rustfs/heal
add scanner status command support
2024-12-03 10:40:00 +08:00
weisd
572e912c22 Merge pull request #141 from rustfs/nugine/ci-s3s-e2e
ci(e2e): run s3s-e2e tests
2024-12-03 10:38:39 +08:00
weisd
087b01a243 Merge pull request #139 from rustfs/fix/make-cargo-happy-1
refactor: make cargo check happy
2024-12-03 10:38:01 +08:00
mujunxiang
15d9665ac2 rebase main
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-03 10:36:03 +08:00
mujunxiang
cc694a4c2b scanner status command(3)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-03 10:20:43 +08:00
mujunxiang
2071df6f58 scanner status command(2)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-03 10:20:43 +08:00
mujunxiang
6dc0d4e301 scanner status command(1)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-12-03 10:20:41 +08:00
weisd
fad9582eac init list-objects 2024-12-03 10:12:49 +08:00
weisd
52edbfc6dc init xhost 2024-12-03 10:10:25 +08:00
Nugine
e9999befa9 ci(e2e): run s3s-e2e tests 2024-12-02 23:43:44 +08:00
weisd
b622ff69e2 init NotificationSys 2024-12-02 17:50:11 +08:00
weisd
3e8189f092 init NotificationSys 2024-12-02 17:40:06 +08:00
bestgopher
99918b8c62 refactor: make cargo check happy
Signed-off-by: bestgopher <84328409@qq.com>
2024-12-02 15:43:53 +08:00
loverustfs
ac8600451f Merge pull request #138 from rustfs/iam-sys
add iam system
2024-12-02 11:23:10 +08:00
bestgopher
bf8fac7809 add iam system
add iam store

feat: add crypto crate

introduce decrypt_data and encrypt_data functions

Signed-off-by: bestgopher <84328409@qq.com>
2024-12-02 10:50:31 +08:00
loverustfs
1ebd16e2ce Merge pull request #134 from rustfs/dependabot/cargo/dependencies-95bc395570
Bump the dependencies group with 14 updates
2024-12-02 10:11:53 +08:00
weisd
210558b353 rm unuse logs 2024-12-02 00:10:50 +08:00
weisd
f73e85d7ec Merge pull request #136 from rustfs/pool-api
fix download err where versioning enable
2024-12-02 00:05:13 +08:00
weisd
de16e0b35d fix download err where versioning enable 2024-12-02 00:02:31 +08:00
dependabot[bot]
fc8d2a3a3e Bump the dependencies group with 14 updates
Bumps the dependencies group with 14 updates:

| Package | From | To |
| --- | --- | --- |
| [backon](https://github.com/Xuanwo/backon) | `1.2.0` | `1.3.0` |
| [bytes](https://github.com/tokio-rs/bytes) | `1.8.0` | `1.9.0` |
| [clap](https://github.com/clap-rs/clap) | `4.5.20` | `4.5.21` |
| [hyper](https://github.com/hyperium/hyper) | `1.5.0` | `1.5.1` |
| [serde](https://github.com/serde-rs/serde) | `1.0.214` | `1.0.215` |
| [serde_json](https://github.com/serde-rs/json) | `1.0.132` | `1.0.133` |
| [thiserror](https://github.com/dtolnay/thiserror) | `1.0.68` | `2.0.3` |
| [tracing](https://github.com/tokio-rs/tracing) | `0.1.40` | `0.1.41` |
| [tracing-error](https://github.com/tokio-rs/tracing) | `0.2.0` | `0.2.1` |
| [tracing-subscriber](https://github.com/tokio-rs/tracing) | `0.3.18` | `0.3.19` |
| [url](https://github.com/servo/rust-url) | `2.5.3` | `2.5.4` |
| [axum](https://github.com/tokio-rs/axum) | `0.7.7` | `0.7.9` |
| [h2](https://github.com/hyperium/h2) | `0.4.6` | `0.4.7` |
| [shadow-rs](https://github.com/baoyachi/shadow-rs) | `0.35.2` | `0.36.0` |


Updates `backon` from 1.2.0 to 1.3.0
- [Release notes](https://github.com/Xuanwo/backon/releases)
- [Commits](https://github.com/Xuanwo/backon/compare/v1.2.0...v1.3.0)

Updates `bytes` from 1.8.0 to 1.9.0
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v1.8.0...v1.9.0)

Updates `clap` from 4.5.20 to 4.5.21
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.20...clap_complete-v4.5.21)

Updates `hyper` from 1.5.0 to 1.5.1
- [Release notes](https://github.com/hyperium/hyper/releases)
- [Changelog](https://github.com/hyperium/hyper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper/compare/v1.5.0...v1.5.1)

Updates `serde` from 1.0.214 to 1.0.215
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.214...v1.0.215)

Updates `serde_json` from 1.0.132 to 1.0.133
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.132...v1.0.133)

Updates `thiserror` from 1.0.68 to 2.0.3
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.68...2.0.3)

Updates `tracing` from 0.1.40 to 0.1.41
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.40...tracing-0.1.41)

Updates `tracing-error` from 0.2.0 to 0.2.1
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-error-0.2.0...tracing-error-0.2.1)

Updates `tracing-subscriber` from 0.3.18 to 0.3.19
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.3.18...tracing-subscriber-0.3.19)

Updates `url` from 2.5.3 to 2.5.4
- [Release notes](https://github.com/servo/rust-url/releases)
- [Commits](https://github.com/servo/rust-url/compare/v2.5.3...v2.5.4)

Updates `axum` from 0.7.7 to 0.7.9
- [Release notes](https://github.com/tokio-rs/axum/releases)
- [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/axum/compare/axum-v0.7.7...axum-v0.7.9)

Updates `h2` from 0.4.6 to 0.4.7
- [Release notes](https://github.com/hyperium/h2/releases)
- [Changelog](https://github.com/hyperium/h2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/h2/compare/v0.4.6...v0.4.7)

Updates `shadow-rs` from 0.35.2 to 0.36.0
- [Release notes](https://github.com/baoyachi/shadow-rs/releases)
- [Commits](https://github.com/baoyachi/shadow-rs/compare/v0.35.2...v0.36.0)

---
updated-dependencies:
- dependency-name: backon
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: bytes
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: clap
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: hyper
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: dependencies
- dependency-name: tracing
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tracing-error
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tracing-subscriber
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: url
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: axum
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: h2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: shadow-rs
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-01 06:10:57 +00:00
junxiangMu
7862430a18 Merge pull request #135 from rustfs/heal
add mc admin heal command support
2024-12-01 14:07:03 +08:00
mujunxiang
1dd0860bef support mc admin heal command
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-30 21:29:37 +08:00
weisd
ea3b182e2f todo file_info_from_raw 2024-11-30 20:54:51 +08:00
mujunxiang
68799ad044 rebase main
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-30 16:05:02 +08:00
mujunxiang
1f2cb78b9d heal admin api(3)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-30 15:40:22 +08:00
mujunxiang
a127fafc26 heal admin api(2)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-30 15:36:39 +08:00
mujunxiang
44f673317f heal admin api(1)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-30 15:34:04 +08:00
weisd
a93f03df54 Merge pull request #133 from rustfs/pool-api
Pool api
2024-11-29 15:47:00 +08:00
weisd
e8e74052c2 sync s3s minio branch, fix versiong config 2024-11-29 14:58:40 +08:00
weisd
06a129de07 todo decommission_pool 2024-11-29 11:44:53 +08:00
weisd
5931d1bbfd todo decommission_in_routine 2024-11-28 17:16:50 +08:00
weisd
dc95a7bd9c use Arc<ECStroe> 2024-11-28 14:47:01 +08:00
weisd
708c4d7251 fix get_net_info 2024-11-28 09:44:59 +08:00
weisd
c1c44ba070 fix get_net_info 2024-11-28 09:43:37 +08:00
junxiangMu
2c3e1facc1 Merge pull request #132 from rustfs/peer-rest
Peer rest
2024-11-27 15:01:14 +08:00
mujunxiang
472883ab03 fix endpoint display bug
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-27 15:00:16 +08:00
mujunxiang
f8958f9335 fix rebase err
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-27 14:44:01 +08:00
mujunxiang
e508b6b38e support some peer rest api
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-27 14:31:26 +08:00
mujunxiang
e931b5a6ad add server_info cpus net_info api
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-27 14:24:24 +08:00
mujunxiang
de25c7af4b peer rest frame
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-27 14:24:22 +08:00
weisd
b53bb46bdf move admin router to rustfs, add pool stats/list admin api 2024-11-26 17:34:18 +08:00
junxiangMu
d0a06d0b92 Merge pull request #131 from rustfs/deal-sign
fix ctrl +c
2024-11-26 11:22:38 +08:00
mujunxiang
9f498ecce1 fix ctrl +c
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-26 11:21:29 +08:00
weisd
e9bfa182b1 add logs 2024-11-26 11:19:16 +08:00
weisd
13c0353dae fix:#127 2024-11-23 19:05:00 +08:00
weisd
4241a702b6 add disk.delete_version 2024-11-22 20:58:01 +08:00
weisd
34a05c9bde Merge pull request #126 from rustfs/fix/errors
Fix/errors
2024-11-21 17:36:16 +08:00
weisd
eb300839ca rm unuse log 2024-11-21 17:35:13 +08:00
weisd
4aaeac88aa add to_s3_error 2024-11-21 17:25:49 +08:00
weisd
fac9640263 add get_multipart_info 2024-11-21 15:59:02 +08:00
weisd
e1b02b270a merge fixs 2024-11-20 17:50:29 +08:00
weisd
d41c9c90a9 merge heal 2024-11-20 17:40:11 +08:00
weisd
fc5a3715c7 add put_object_metadata 2024-11-20 16:10:14 +08:00
weisd
269aeac18c todo put_object_metadata 2024-11-20 14:12:33 +08:00
mujunxiang
bc76582c96 fix cache bug
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-20 09:47:10 +08:00
mujunxiang
bb6a6a3172 clippy(2)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-20 09:10:19 +08:00
mujunxiang
192898995d cllipy
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-19 17:30:50 +08:00
weisd
b5c824ebbd fix errors/delete_object 2024-11-19 17:16:42 +08:00
mujunxiang
1b966ecaf6 auto heal(3)
Signed-off-by: mujunxiang <1948535941@qq.com>
2024-11-19 17:15:37 +08:00
weisd
15e5333b09 fix errors/delete_object 2024-11-19 16:59:51 +08:00
weisd
51d3b8dfea fix bug 2024-11-19 10:44:27 +08:00
weisd
883e6b17d2 Merge branch 'bool-api' 2024-11-19 10:37:31 +08:00
junxiang Mu
c849fac54e auto heal(2)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-17 18:34:29 +08:00
root
61c1521fcb auto heal(1)
Signed-off-by: root <root@DESKTOP-QLJNS6S.localdomain>
2024-11-16 20:43:34 +08:00
junxiang Mu
6c53ee503c temp(4)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-16 12:57:31 +08:00
junxiang Mu
46b1f80611 temp(3)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-14 07:43:20 +00:00
junxiang Mu
1201649474 rebase main
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-14 10:47:51 +08:00
junxiang Mu
9d7f8ee80a tmp(2)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-14 10:30:02 +08:00
junxiang Mu
870ac2f371 tmp 2024-11-14 10:27:07 +08:00
weisd
4ff41d9416 Merge pull request #125 from rustfs/merge/s3s
merge s3s
2024-11-14 09:09:24 +08:00
weisd
52bb25cf2a merge s3s 2024-11-14 09:08:40 +08:00
weisd
2acfecfafc test accountinfo 2024-11-14 09:06:42 +08:00
weisd
52aabcbdfc test accountinfo 2024-11-12 17:38:36 +08:00
weisd
76cb6e7806 Merge remote-tracking branch 'origin/main' into bool-api 2024-11-12 16:18:11 +08:00
weisd
e5e6ac6064 Merge pull request #123 from rustfs/assumerole
Assumerole
2024-11-12 16:17:41 +08:00
weisd
a65cf09830 init AssumeRoleHandle 2024-11-12 15:53:47 +08:00
Nugine
c77a0d1ef9 feat(rustfs): adjust short version 2024-11-11 23:10:48 +08:00
weisd
5cf1bcef28 init AssumeRoleHandle 2024-11-11 17:34:46 +08:00
weisd
4dd65ee9b2 Merge pull request #122 from rustfs/fix/content-length
Fix/content length
2024-11-09 21:25:22 +08:00
weisd
967e7b65b1 fix put_object content-length empty 2024-11-09 20:44:16 +08:00
weisd
bb84439dc6 fix put_object content-length empty 2024-11-09 20:11:53 +08:00
Nugine
aa66366ea2 feat(rustfs): add build info (#121) 2024-11-09 15:23:51 +08:00
weisd
4994dd026c Merge branch 'main' into bool-api 2024-11-09 03:00:52 +08:00
weisd
0d43debd32 Merge pull request #120 from rustfs/fix/content_type
add content-type fix list_objects
2024-11-09 02:58:19 +08:00
weisd
18821d3feb fix list_objects 2024-11-09 02:52:05 +08:00
weisd
a65ad217a3 Merge branch 'fix/content_type' into bool-api 2024-11-08 19:58:26 +08:00
weisd
1b29a6ba3a fix content-type 2024-11-08 17:46:19 +08:00
weisd
77fdec48a9 change pool idx to i32 2024-11-07 17:15:23 +08:00
loverustfs
b21846cf76 Merge pull request #117 from rustfs/dependabot/cargo/dependencies-0ffeeacea9
Bump the dependencies group with 2 updates
2024-11-06 19:30:16 +08:00
weisd
e4599113fa init storage info api 2024-11-06 17:24:52 +08:00
weisd
394667637c fix router prefix 2024-11-06 11:42:36 +08:00
dependabot[bot]
5a99a9a78a Bump the dependencies group with 2 updates
Bumps the dependencies group with 2 updates: [thiserror](https://github.com/dtolnay/thiserror) and [url](https://github.com/servo/rust-url).


Updates `thiserror` from 1.0.66 to 1.0.68
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.66...1.0.68)

Updates `url` from 2.5.2 to 2.5.3
- [Release notes](https://github.com/servo/rust-url/releases)
- [Commits](https://github.com/servo/rust-url/compare/v2.5.2...v2.5.3)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: url
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-06 03:36:07 +00:00
weisd
21c3c36d7c Merge pull request #118 from rustfs/admin-router
Admin router
2024-11-06 11:33:46 +08:00
weisd
cea15032c9 init admin_route done 2024-11-06 11:28:39 +08:00
weisd
e73a055bc3 init admin_route 2024-11-05 17:41:35 +08:00
weisd
ce93715287 Merge pull request #116 from rustfs/reader
Reader
2024-11-05 09:43:20 +08:00
weisd
09d3a0edc3 ec use AsyncRead 2024-11-04 17:43:05 +08:00
Nugine
805d6c9de2 ci: improve build workflow (#115)
* ci: fix build workflow

* ci: use setup actions
2024-11-04 15:06:19 +08:00
weisd
7f5ffab148 cargo clippy 2024-11-04 09:08:21 +08:00
loverustfs
a551cbcedd Merge pull request #114 from rustfs/dev
cargo fmt
2024-11-03 21:32:03 +08:00
weisd
d27b74a9ab fix cargo clippy err 2024-11-03 10:25:17 +08:00
weisd
a69ad3bbdb cargo fmt 2024-11-03 10:05:50 +08:00
weisd
8d57a375ac Merge pull request #113 from rustfs/dev
update todo
2024-11-03 10:01:55 +08:00
weisd
84324e4340 update todo 2024-11-03 10:01:17 +08:00
weisd
3f58472ea7 fix linux get_info 2024-11-03 09:48:55 +08:00
weisd
a383d271e5 Optimization FileReader 2024-11-03 00:19:14 +08:00
weisd
cc70b9766f Optimization FileReader 2024-11-02 23:36:04 +08:00
weisd
c92a45a386 Optimization FileReader 2024-11-02 22:07:33 +08:00
weisd
abda820c0d fix bitrot readat bug 2024-11-02 17:53:30 +08:00
weisd
5320b8f260 fix bug 2024-11-02 15:29:47 +08:00
weisd
dd2bf7085a merge versioning, fix buff bitrot 2024-11-02 15:12:06 +08:00
weisd
f70365534a merge versioning, fix bug todo 2024-11-02 00:21:10 +08:00
loverustfs
b744a29df6 Merge pull request #106 from rustfs/dependabot/cargo/dependencies-44ddf1d0c7
Bump the dependencies group with 13 updates
2024-11-01 22:12:07 +08:00
dependabot[bot]
77905adc56 Bump the dependencies group with 13 updates
Bumps the dependencies group with 13 updates:

| Package | From | To |
| --- | --- | --- |
| [bytes](https://github.com/tokio-rs/bytes) | `1.7.2` | `1.8.0` |
| [hyper](https://github.com/hyperium/hyper) | `1.4.1` | `1.5.0` |
| [hyper-util](https://github.com/hyperium/hyper-util) | `0.1.9` | `0.1.10` |
| [pin-project-lite](https://github.com/taiki-e/pin-project-lite) | `0.2.14` | `0.2.15` |
| [protobuf](https://github.com/stepancheg/rust-protobuf) | `3.6.0` | `3.7.1` |
| [serde](https://github.com/serde-rs/serde) | `1.0.210` | `1.0.214` |
| [serde_json](https://github.com/serde-rs/json) | `1.0.128` | `1.0.132` |
| [thiserror](https://github.com/dtolnay/thiserror) | `1.0.64` | `1.0.66` |
| [tokio](https://github.com/tokio-rs/tokio) | `1.40.0` | `1.41.0` |
| [tower](https://github.com/tower-rs/tower) | `0.4.13` | `0.5.1` |
| [uuid](https://github.com/uuid-rs/uuid) | `1.10.0` | `1.11.0` |
| [regex](https://github.com/rust-lang/regex) | `1.11.0` | `1.11.1` |
| [openssl](https://github.com/sfackler/rust-openssl) | `0.10.66` | `0.10.68` |


Updates `bytes` from 1.7.2 to 1.8.0
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v1.7.2...v1.8.0)

Updates `hyper` from 1.4.1 to 1.5.0
- [Release notes](https://github.com/hyperium/hyper/releases)
- [Changelog](https://github.com/hyperium/hyper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper/compare/v1.4.1...v1.5.0)

Updates `hyper-util` from 0.1.9 to 0.1.10
- [Release notes](https://github.com/hyperium/hyper-util/releases)
- [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.9...v0.1.10)

Updates `pin-project-lite` from 0.2.14 to 0.2.15
- [Release notes](https://github.com/taiki-e/pin-project-lite/releases)
- [Changelog](https://github.com/taiki-e/pin-project-lite/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/pin-project-lite/compare/v0.2.14...v0.2.15)

Updates `protobuf` from 3.6.0 to 3.7.1
- [Changelog](https://github.com/stepancheg/rust-protobuf/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stepancheg/rust-protobuf/compare/v3.6.0...v3.7.1)

Updates `serde` from 1.0.210 to 1.0.214
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.210...v1.0.214)

Updates `serde_json` from 1.0.128 to 1.0.132
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/1.0.128...1.0.132)

Updates `thiserror` from 1.0.64 to 1.0.66
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.64...1.0.66)

Updates `tokio` from 1.40.0 to 1.41.0
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.40.0...tokio-1.41.0)

Updates `tower` from 0.4.13 to 0.5.1
- [Release notes](https://github.com/tower-rs/tower/releases)
- [Commits](https://github.com/tower-rs/tower/compare/tower-0.4.13...tower-0.5.1)

Updates `uuid` from 1.10.0 to 1.11.0
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/1.10.0...1.11.0)

Updates `regex` from 1.11.0 to 1.11.1
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.11.0...1.11.1)

Updates `openssl` from 0.10.66 to 0.10.68
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.66...openssl-v0.10.68)

---
updated-dependencies:
- dependency-name: bytes
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: hyper
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: hyper-util
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: pin-project-lite
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: protobuf
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: tower
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: openssl
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-01 10:44:33 +00:00
junxiangMu
192200a2cf Merge pull request #107 from rustfs/heal
Heal(step 1)
2024-11-01 18:41:04 +08:00
junxiang Mu
5cd7441052 fix import
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:43:23 +08:00
junxiang Mu
81bba2a7a0 heal object(1)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:40:54 +08:00
junxiang Mu
447884250e support bitrot
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:40:14 +08:00
junxiang Mu
0bf5e1be22 bitrot streaming
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:40:14 +08:00
junxiang Mu
d7004cf045 bitrot test(1)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:40:14 +08:00
junxiang Mu
c57db2454c bitrot(2)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:40:14 +08:00
junxiang Mu
9a0916aca0 bitrot(1)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:40:14 +08:00
junxiang Mu
b8d66ffe92 Cross platform get_info
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:40:14 +08:00
junxiang Mu
5838df0cde fmt
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:40:14 +08:00
junxiang Mu
37bd73591f heal object
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:40:14 +08:00
junxiang Mu
0dc8ce65b3 healing tracker
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-11-01 17:40:14 +08:00
junxiang Mu
f977545374 tmp 2024-11-01 17:40:09 +08:00
loverustfs
719e1091b6 Merge pull request #104 from rustfs/fix/blocking-when-start
fix: blocking forever
2024-10-29 22:57:32 +08:00
bestgopher
b3f951a5d7 fix: blocking forever
Closes #102
Signed-off-by: bestgopher <84328409@qq.com>
2024-10-29 21:07:35 +08:00
Nugine
c07817f0ec ci: add build workflow 2024-10-29 13:13:30 +08:00
junxiangMu
ef6262867f Merge pull request #99 from rustfs/fix-reply
fix reply warnning
2024-10-25 09:30:24 +08:00
junxiang Mu
88572a28f6 fix reply warnning
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-10-25 09:16:46 +08:00
junxiangMu
965b7b7fa8 Merge pull request #98 from rustfs/lock
add locker drop trait
2024-10-24 18:11:13 +08:00
junxiang Mu
f825ef4d85 fix lock drop
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-10-24 17:34:24 +08:00
junxiang Mu
c943779387 unuse locker(temporary)
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-10-24 17:01:13 +08:00
loverustfs
c11e6314a3 Merge pull request #92 from rustfs/change-url-prefix
fix: admin api prefix: /rustfs/admin
2024-10-18 09:24:27 +08:00
bestgopher
f86d2127d1 fix: admin api prefix: /rustfs/admin
fix #91

Signed-off-by: bestgopher <84328409@qq.com>
2024-10-16 22:41:41 +08:00
loverustfs
b18c3e60ea Merge pull request #89 from rustfs/adm-api-1
feat: introduce admin-api
2024-10-16 20:41:24 +08:00
bestgopher
271c709be6 refactor: move api crate to api dir
Signed-off-by: bestgopher <84328409@qq.com>
2024-10-16 10:31:05 +08:00
weisd
173bd3f679 fix list_volumes name 2024-10-15 14:45:50 +00:00
bestgopher
66cac921b9 feat: introduce admin-api
Signed-off-by: bestgopher <84328409@qq.com>
2024-10-15 19:51:00 +08:00
weisd
3a1d0cffaf opt:FileMetaVersion 2024-10-14 17:31:54 +08:00
weisd
6a6e4c5dd4 fix:#38 implement the basic storage functions of bucketmeta config use s3s struct define 2024-10-14 14:58:32 +08:00
Nugine
5b5082fd1a ci: enable cache on failure (#85)
* ci: enable cache on failure

* fix
2024-10-12 15:05:22 +08:00
junxiangMu
4e5297e12b Merge pull request #83 from rustfs/bug-fix
fix e2e_test token validate
2024-10-12 14:16:07 +08:00
junxiang Mu
a29399fde4 fmt
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-10-12 14:12:20 +08:00
junxiang Mu
6b1217d862 fix clippy
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-10-12 14:09:52 +08:00
junxiang Mu
bfd7d80b9f fix e2e_test token validate
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-10-12 09:05:53 +08:00
weisd
3cb233f2de Merge pull request #82 from rustfs/nugine/fmt
style: cargo fmt
2024-10-12 00:54:31 +08:00
weisd
6e3a8bc8aa Merge branch 'main' into nugine/fmt 2024-10-12 00:54:22 +08:00
weisd
a6a582ec08 Merge pull request #78 from rustfs/dependabot/cargo/dependencies-abc806330f
Bump the dependencies group with 4 updates
2024-10-12 00:53:15 +08:00
weisd
6d08904602 Merge pull request #77 from rustfs/nugine/ci-accel
ci: use skip-check and rust-cache
2024-10-12 00:52:47 +08:00
weisd
8aa9fbf47b Merge pull request #81 from rustfs/a
fix: use compile_protos
2024-10-12 00:52:09 +08:00
weisd
7ebe59502a done bucket policy, need test 2024-10-12 00:41:03 +08:00
Nugine
2b0d2a1ad0 style: cargo fmt 2024-10-11 23:21:19 +08:00
Nugine
139d107bad fix 2024-10-11 23:19:24 +08:00
bestgopher
87534580d6 fix: use compile_protos 2024-10-11 22:41:08 +08:00
mirschao
1619024818 Update rust.yml
cargo fmt --all --check 中--check为检查模式,如果有对应的格式化修改,则命令返回码为非零(错误),所以导致action运行失败,替换为cargo fmt --all即可解决问题。
2024-10-11 22:27:32 +08:00
mirschao
cd22fda858 Update rust.yml
cargo fmt --all --check 中--check为检查模式,如果有对应的格式化修改,则命令返回码为非零(错误),所以导致action运行失败,替换为cargo fmt --all即可解决问题。
2024-10-11 22:25:25 +08:00
Nugine
ee873711b7 ci: use skip-check and rust-cache 2024-10-11 20:02:39 +08:00
dependabot[bot]
a519a2f9a2 Bump the dependencies group with 4 updates
Bumps the dependencies group with 4 updates: [clap](https://github.com/clap-rs/clap), [futures](https://github.com/rust-lang/futures-rs), [futures-util](https://github.com/rust-lang/futures-rs) and [prost-build](https://github.com/tokio-rs/prost).


Updates `clap` from 4.5.18 to 4.5.20
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.18...clap_complete-v4.5.20)

Updates `futures` from 0.3.30 to 0.3.31
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.30...0.3.31)

Updates `futures-util` from 0.3.30 to 0.3.31
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.30...0.3.31)

Updates `prost-build` from 0.13.1 to 0.13.3
- [Release notes](https://github.com/tokio-rs/prost/releases)
- [Changelog](https://github.com/tokio-rs/prost/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/prost/compare/v0.13.1...v0.13.3)

---
updated-dependencies:
- dependency-name: clap
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: futures
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: futures-util
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: prost-build
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-11 05:37:44 +00:00
weisd
a834b5e926 Merge pull request #76 from rustfs/feat/ec_config
add env RUSTFS_ERASURE_SET_DRIVE_COUNT
2024-10-10 13:07:19 +08:00
weisd
5b133a8e53 Merge branch 'main' into feat/ec_config 2024-10-10 13:06:39 +08:00
weisd
251e1a06c5 Merge pull request #75 from rustfs/feat/versioning
Feat/versioning
2024-10-10 09:46:10 +08:00
weisd
7d59544b61 get/put BucketVersionin done 2024-10-10 09:40:30 +08:00
weisd
ba83b04da4 add versioning_sys 2024-10-09 20:45:34 +08:00
weisd
1cf1354abf init BucketVersionin api 2024-10-09 17:38:56 +08:00
weisd
9ecb045131 add bucket sys marshal func 2024-10-09 15:06:50 +08:00
weisd
2fe9d75cb5 Merge branch 'main' into bucketmeta 2024-10-09 14:36:22 +08:00
mirschao
641497a88c Update e2e.yml 2024-10-08 23:17:11 +08:00
mirschao
2fcc4f0db1 Update run.sh 2024-10-08 23:11:20 +08:00
mirschao
96948e8b8d Update run.sh 2024-10-08 23:10:12 +08:00
mirschao
17cdf17473 Update e2e.yml 2024-10-08 23:03:58 +08:00
mirschao
766d33ec94 Update e2e.yml 2024-10-08 22:47:32 +08:00
mirschao
1484b696c5 Update e2e.yml 2024-10-08 22:41:35 +08:00
mirschao
3053cd9238 Update e2e.yml
fix not listen 9000 port
2024-10-08 22:22:09 +08:00
loverustfs
18dd8c8ee1 Update e2e.yml 2024-10-08 16:10:11 +08:00
loverustfs
0d6b43e02e Update e2e.yml 2024-10-08 15:47:07 +08:00
loverustfs
d5c02a28c2 Merge pull request #73 from rustfs/asm
use asm && simd features improve performance
2024-10-08 14:18:14 +08:00
junxiang Mu
77eab865a0 use asm features
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-10-08 14:11:28 +08:00
weisd
308e16afa0 add env RUSTFS_ERASURE_SET_DRIVE_COUNT 2024-10-05 12:33:39 +08:00
weisd
39a4d6bc5b Fix: #38
Squashed commit of the following:

commit ff72105e1ec81b5679401b021fb44e8135444de8
Author: weisd <weishidavip@163.com>
Date:   Sat Oct 5 09:55:09 2024 +0800

    base bucketmetadata_sys done

commit 69d0c7725ae1065d25755c71aa54e42c4f3cdb50
Author: weisd <weishidavip@163.com>
Date:   Sat Oct 5 01:41:19 2024 +0800

    update bucket tagging op use bucketmetadata_sys

commit 39902c73d6f7a817041245af84a23d14115c70dc
Author: weisd <weishidavip@163.com>
Date:   Fri Oct 4 23:32:07 2024 +0800

    test bucketmetadata_sys

commit 15f1dfc765dc383ab26d71aca7c64dd0917b83f3
Author: weisd <weishidavip@163.com>
Date:   Fri Oct 4 23:21:58 2024 +0800

    init bucketmetadata_sys

commit 8c3c5e0f7385fa881b1dc4811d92afe8b86e9a6f
Author: weisd <weishidavip@163.com>
Date:   Tue Oct 1 23:06:09 2024 +0800

    init bucketmetadata_sys

commit e2746d154aa68be9dcf8add0241b38c72ef89b9c
Author: weisd <weishidavip@163.com>
Date:   Tue Oct 1 04:35:25 2024 +0800

    stash
2024-10-05 10:04:59 +08:00
weisd
823da21de1 base bucketmetadata_sys done 2024-10-05 09:55:09 +08:00
weisd
fc7c584719 Merge branch 'main' of github.com:rustfs/s3-rustfs 2024-10-05 09:52:25 +08:00
weisd
11ccd098ed update bucket tagging op use bucketmetadata_sys 2024-10-05 01:41:19 +08:00
weisd
1ea83b8748 test bucketmetadata_sys 2024-10-04 23:32:07 +08:00
weisd
bd0c404396 init bucketmetadata_sys 2024-10-04 23:21:58 +08:00
loverustfs
f117dd453d Merge pull request #68 from rustfs/nugine/ci-upgrade
ci: upgrade actions
2024-10-03 09:11:06 +08:00
loverustfs
26a6a004c1 Merge pull request #67 from rustfs/dependabot/cargo/dependencies-79d5d07e08
Bump the dependencies group with 18 updates
2024-10-03 09:10:52 +08:00
weisd
8707518433 init bucketmetadata_sys 2024-10-01 23:06:09 +08:00
Nugine
fdd12fc6b6 ci: upgrade actions 2024-10-01 13:33:08 +08:00
dependabot[bot]
04989f3554 Bump the dependencies group with 18 updates
Bumps the dependencies group with 18 updates:

| Package | From | To |
| --- | --- | --- |
| [async-trait](https://github.com/dtolnay/async-trait) | `0.1.80` | `0.1.83` |
| [bytes](https://github.com/tokio-rs/bytes) | `1.6.0` | `1.7.2` |
| [clap](https://github.com/clap-rs/clap) | `4.5.7` | `4.5.18` |
| [hyper](https://github.com/hyperium/hyper) | `1.3.1` | `1.4.1` |
| [hyper-util](https://github.com/hyperium/hyper-util) | `0.1.5` | `0.1.9` |
| [http-body](https://github.com/hyperium/http-body) | `1.0.0` | `1.0.1` |
| [prost](https://github.com/tokio-rs/prost) | `0.13.1` | `0.13.3` |
| [prost-types](https://github.com/tokio-rs/prost) | `0.13.1` | `0.13.3` |
| [protobuf](https://github.com/stepancheg/rust-protobuf) | `3.5.1` | `3.6.0` |
| [serde](https://github.com/serde-rs/serde) | `1.0.203` | `1.0.210` |
| [serde_json](https://github.com/serde-rs/json) | `1.0.118` | `1.0.128` |
| [thiserror](https://github.com/dtolnay/thiserror) | `1.0.61` | `1.0.64` |
| [tokio](https://github.com/tokio-rs/tokio) | `1.38.0` | `1.40.0` |
| [tonic](https://github.com/hyperium/tonic) | `0.12.1` | `0.12.3` |
| [tonic-build](https://github.com/hyperium/tonic) | `0.12.1` | `0.12.3` |
| [tonic-reflection](https://github.com/hyperium/tonic) | `0.12.1` | `0.12.3` |
| [regex](https://github.com/rust-lang/regex) | `1.10.5` | `1.11.0` |
| [tokio-util](https://github.com/tokio-rs/tokio) | `0.7.11` | `0.7.12` |


Updates `async-trait` from 0.1.80 to 0.1.83
- [Release notes](https://github.com/dtolnay/async-trait/releases)
- [Commits](https://github.com/dtolnay/async-trait/compare/0.1.80...0.1.83)

Updates `bytes` from 1.6.0 to 1.7.2
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v1.6.0...v1.7.2)

Updates `clap` from 4.5.7 to 4.5.18
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.7...clap_complete-v4.5.18)

Updates `hyper` from 1.3.1 to 1.4.1
- [Release notes](https://github.com/hyperium/hyper/releases)
- [Changelog](https://github.com/hyperium/hyper/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper/compare/v1.3.1...v1.4.1)

Updates `hyper-util` from 0.1.5 to 0.1.9
- [Release notes](https://github.com/hyperium/hyper-util/releases)
- [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.5...v0.1.9)

Updates `http-body` from 1.0.0 to 1.0.1
- [Release notes](https://github.com/hyperium/http-body/releases)
- [Commits](https://github.com/hyperium/http-body/compare/v1.0.0...v1.0.1)

Updates `prost` from 0.13.1 to 0.13.3
- [Release notes](https://github.com/tokio-rs/prost/releases)
- [Changelog](https://github.com/tokio-rs/prost/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/prost/compare/v0.13.1...v0.13.3)

Updates `prost-types` from 0.13.1 to 0.13.3
- [Release notes](https://github.com/tokio-rs/prost/releases)
- [Changelog](https://github.com/tokio-rs/prost/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/prost/compare/v0.13.1...v0.13.3)

Updates `protobuf` from 3.5.1 to 3.6.0
- [Changelog](https://github.com/stepancheg/rust-protobuf/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stepancheg/rust-protobuf/compare/v3.5.1...v3.6.0)

Updates `serde` from 1.0.203 to 1.0.210
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.203...v1.0.210)

Updates `serde_json` from 1.0.118 to 1.0.128
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.118...1.0.128)

Updates `thiserror` from 1.0.61 to 1.0.64
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.61...1.0.64)

Updates `tokio` from 1.38.0 to 1.40.0
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.38.0...tokio-1.40.0)

Updates `tonic` from 0.12.1 to 0.12.3
- [Release notes](https://github.com/hyperium/tonic/releases)
- [Changelog](https://github.com/hyperium/tonic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/tonic/compare/v0.12.1...v0.12.3)

Updates `tonic-build` from 0.12.1 to 0.12.3
- [Release notes](https://github.com/hyperium/tonic/releases)
- [Changelog](https://github.com/hyperium/tonic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/tonic/compare/v0.12.1...v0.12.3)

Updates `tonic-reflection` from 0.12.1 to 0.12.3
- [Release notes](https://github.com/hyperium/tonic/releases)
- [Changelog](https://github.com/hyperium/tonic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/tonic/compare/v0.12.1...v0.12.3)

Updates `regex` from 1.10.5 to 1.11.0
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.10.5...1.11.0)

Updates `tokio-util` from 0.7.11 to 0.7.12
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-util-0.7.11...tokio-util-0.7.12)

---
updated-dependencies:
- dependency-name: async-trait
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: bytes
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: clap
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: hyper
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: hyper-util
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: http-body
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: prost
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: prost-types
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: protobuf
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: tonic
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tonic-build
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: tonic-reflection
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: tokio-util
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-01 05:17:37 +00:00
weisd
c4ed189e28 stash 2024-10-01 04:35:25 +08:00
weisd
2cb425c9fc stash 2024-09-30 21:40:17 +08:00
weisd
029964d886 Merge remote-tracking branch 'origin/main' into bucketmeta 2024-09-30 21:25:31 +08:00
loverustfs
526effa743 Update rust.yml
delete push on actions
2024-09-30 16:33:12 +08:00
loverustfs
5dca424132 Merge pull request #66 from rustfs/wip-dandan
new future support
2024-09-29 15:33:17 +08:00
junxiang Mu
c76a633de3 fix: make_volume api error
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-09-29 14:08:48 +08:00
weisd
b6db68b064 init bucketmeta struct 2024-09-27 22:00:45 +08:00
weisd
0b1cfb3b43 merge main 2024-09-27 20:12:54 +08:00
weisd
4c14710596 init bucketmeta struct 2024-09-27 18:08:33 +08:00
weisd
1006cd9b56 init bucketmeta struct 2024-09-27 17:53:44 +08:00
junxiang Mu
d55e369a7f refact error
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-09-27 16:51:54 +08:00
weisd
3edcac4d3c init bucketmeta 2024-09-27 16:33:56 +08:00
junxiang Mu
70ff8e22f2 multiplex channel && rpc service add authentication
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-09-27 16:29:40 +08:00
junxiang Mu
b7824075a3 put_object func add lock
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-09-27 10:31:16 +08:00
weisd
96644d3430 Merge branch 'quorum' 2024-09-27 09:09:50 +08:00
weisd
6c8b88eb7e review disk 2024-09-27 09:08:44 +08:00
weisd
33aa966937 opt 2024-09-27 09:05:38 +08:00
weisd
80776c2442 opt: rename_data 2024-09-27 00:06:34 +08:00
weisd
c9a52da723 opt: rename_data 2024-09-26 23:45:29 +08:00
weisd
a79b788b27 Merge pull request #62 from rustfs/jimchen/builder
Add docker builder
2024-09-26 17:29:36 +08:00
weisd
31981f473b Merge pull request #63 from rustfs/quorum
Quorum
2024-09-26 17:26:13 +08:00
weisd
7194bbe18f fix:read_metadata 2024-09-26 16:27:01 +08:00
weisd
c600d85e7a merge remote support 2024-09-26 16:04:20 +08:00
weisd
de7d80f1a7 Merge branch 'quorum' of github.com:rustfs/s3-rustfs into quorum 2024-09-26 15:51:56 +08:00
weisd
8d287f9106 opt:read/write_all 2024-09-26 15:51:44 +08:00
junxiang Mu
24b90ae6f8 add remote support: delete_version,rename_part,delete_paths,update_metadata
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-09-26 15:15:26 +08:00
weisd
65d4ae8e65 add xl_meta.update_object_version 2024-09-26 14:12:47 +08:00
junxiang Mu
f76cde683d support distribute lock
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-09-26 11:30:56 +08:00
weisd
8970fc912f review localdisk 2024-09-26 01:52:52 +08:00
JimChenWYU
144da0a212 add docker builder 2024-09-25 19:46:02 +08:00
weisd
ac96a99b9f stash 2024-09-25 17:31:46 +08:00
weisd
4b3a5e9bcb merge main 2024-09-25 16:58:58 +08:00
weisd
8a8d33b437 fix: delete_objects 2024-09-25 16:56:10 +08:00
weisd
e0eb3860fa Merge branch 'main' into quorum 2024-09-25 16:55:20 +08:00
weisd
67aeadff42 Merge branch 'main' of github.com:rustfs/s3-rustfs 2024-09-25 16:55:00 +08:00
weisd
5140ce43d1 fix: delete_objects 2024-09-25 16:54:48 +08:00
weisd
fe3cb81209 done read/write quorum, need test 2024-09-25 16:28:07 +08:00
weisd
0c7aaeeee5 done read/write quorum, need test 2024-09-25 16:21:21 +08:00
weisd
9afaada3fb update stock api 2024-09-25 15:27:23 +08:00
weisd
a697ffe442 add rename_part 2024-09-25 11:49:12 +08:00
loverustfs
d720064919 Merge pull request #60 from rustfs/jimchen/exclude
Improve ci
2024-09-25 10:47:27 +08:00
weisd
b09e3ed8c7 putobject reduce_read_quorum_errs 2024-09-24 23:36:26 +08:00
weisd
556b650133 fix fileinfo serialize 2024-09-24 22:51:21 +08:00
weisd
8da69d6ad1 fix fileinfo mod_time bug 2024-09-24 17:58:36 +08:00
weisd
47182c0544 fix: #23 need test reduce_read_quorum_errs 2024-09-24 16:21:02 +08:00
JimChenWYU
5dcd1e9aca fix 2024-09-24 16:17:31 +08:00
JimChenWYU
e60933819a fix cargo cache 2024-09-24 15:20:04 +08:00
JimChenWYU
18dd4db147 POSIX Shell 2024-09-24 15:12:16 +08:00
JimChenWYU
a601be3af0 POSIX Shell 2024-09-24 15:09:31 +08:00
JimChenWYU
ac60c9984c add probe 2024-09-24 15:00:59 +08:00
JimChenWYU
0c3f6b8ffa add cargo cache 2024-09-24 14:50:12 +08:00
JimChenWYU
6b4b662d2c add e2e test ci 2024-09-24 14:33:41 +08:00
JimChenWYU
facd77dbf8 add e2e test ci 2024-09-24 14:12:17 +08:00
JimChenWYU
8b6aa1dedd add e2e test ci 2024-09-24 14:07:57 +08:00
loverustfs
11a87bab8c Merge pull request #59 from rustfs/jimchen/dev
设置ci流水线
2024-09-24 11:04:05 +08:00
loverustfs
fa92edff2f Merge pull request #58 from rustfs/jimchen/perf-delete_objects
优化并发删除对象
2024-09-24 11:03:51 +08:00
weisd
3686afafc0 fix quorum err 2024-09-24 10:39:12 +08:00
weisd
86f50f7262 review disk 2024-09-24 00:00:44 +08:00
JimChenWYU
c3d0e621a7 install flatc 2024-09-23 18:44:55 +08:00
JimChenWYU
4e1d1bdc2f install flatc 2024-09-23 18:11:08 +08:00
JimChenWYU
fc018cb5bb print protoc version 2024-09-23 18:05:18 +08:00
weisd
a2b661965a rm unuse log 2024-09-23 18:02:03 +08:00
weisd
ab9bd0cc9b review disk api 2024-09-23 17:56:30 +08:00
JimChenWYU
7e3aee4a1a 设置ci流水线 2024-09-23 17:53:26 +08:00
weisd
2a0d7a047d merge getdiskid 2024-09-23 17:27:10 +08:00
weisd
59b38976fa merge main 2024-09-23 17:20:28 +08:00
JimChenWYU
a1bba52b49 统一开发环境 2024-09-23 16:49:03 +08:00
JimChenWYU
f0d1488cf9 统一开发环境 2024-09-23 16:49:03 +08:00
JimChenWYU
cc79d5590a make clippy happy 2024-09-23 16:27:33 +08:00
JimChenWYU
3caeb73bb8 优化并发删除对象 2024-09-23 16:07:02 +08:00
JimChenWYU
6b226847aa make clippy happy 2024-09-23 15:38:00 +08:00
weisd
9d30d8c8d8 clone_err 2024-09-23 15:33:48 +08:00
JimChenWYU
635cf9d568 chore: 添加删除并发限制 2024-09-23 15:32:48 +08:00
weisd
ee517f09ec clone_err 2024-09-23 15:26:57 +08:00
weisd
124d3f6a4f test rename_data 2024-09-23 14:32:48 +08:00
weisd
d6bd189a5b add all StorageErr 2024-09-23 11:46:48 +08:00
loverustfs
05746b346a Merge pull request #55 from rustfs/feat/object-tagging
Feat/object tagging
2024-09-23 10:33:25 +08:00
weisd
c0ff822fc6 feat: 添加定时检测重连disk 2024-09-20 16:45:17 +08:00
bestgopher
38846b36a0 feat: object tagging
Closes: #54
Signed-off-by: bestgopher <84328409@qq.com>
2024-09-20 13:30:59 +08:00
loverustfs
28c357a6ad Create dependabot.yml 2024-09-20 10:38:13 +08:00
loverustfs
68c02f88ef Delete .github/workflows/Audit.yml 2024-09-20 10:28:03 +08:00
loverustfs
01705a2e0d Create audit.yml 2024-09-20 10:27:51 +08:00
loverustfs
3a1f814ef2 Create rust.yml 2024-09-20 10:26:44 +08:00
loverustfs
2a3bc4c5ea Create Audit.yml 2024-09-20 10:24:50 +08:00
weisd
2acc3e19ef add: monitor_and_connect_endpoints 2024-09-19 18:06:44 +08:00
weisd
6db989620a fix: use option writer when disk is none 2024-09-19 13:12:32 +08:00
weisd
6111c43a65 Merge pull request #47 from rustfs/feat/delete-tagging
feat: remove bucket tagging
2024-09-19 10:04:36 +08:00
weisd
bec61d8ad6 fix get_disk_id 2024-09-19 09:41:29 +08:00
weisd
599491f578 fix get_disk_id 2024-09-18 22:57:08 +08:00
weisd
dd18d57a9b add log 2024-09-18 17:04:42 +08:00
bestgopher
b5daa5c51f feat: remove bucket tagging 2024-09-18 16:29:47 +08:00
weisd
dec3b45d70 Fix bug:#45 #43 #42 2024-09-18 13:53:13 +08:00
weisd
88c1e76300 Merge pull request #40 from rustfs/feat/tagging-2
feat: support bucket tagging
2024-09-18 09:23:38 +08:00
junxiang Mu
852cbd8b65 add base lock
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-09-16 13:08:27 +08:00
bestgopher
ccde55c4e3 feat: support bucket tagging
Closes #41
Signed-off-by: bestgopher <84328409@qq.com>
2024-09-14 10:19:29 +08:00
junxiang Mu
6651dcd873 support stream read
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-09-13 15:17:10 +08:00
weisd
953f31662b update todo.md 2024-09-13 15:09:16 +08:00
weisd
97ad2285b9 fix:delete_bucket skip when volume not empty 2024-09-13 14:15:09 +08:00
junxiang Mu
3f1d99273f support stream write
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-09-13 13:53:26 +08:00
weisd
b1df4aa615 merge main 2024-09-13 13:33:23 +08:00
weisd
a006cad19e add delete_bucket opts 2024-09-13 13:30:10 +08:00
weisd
cc86719898 merge upload 2024-09-13 11:11:55 +08:00
weisd
480ef9005a fix: delete_object buf 2024-09-13 11:05:58 +08:00
junxiang Mu
128fe42d98 support multi node
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-09-13 10:12:57 +08:00
weisd
51fe557b2f update fn name 2024-09-11 16:27:39 +08:00
weisd
e42a3315ae update fn name 2024-09-11 16:27:04 +08:00
weisd
6b41e8e7bc update fn name 2024-09-11 16:26:04 +08:00
weisd
0d1686412e test get_format_file_in_quorum 2024-09-11 15:26:54 +08:00
weisd
04635ae321 test get_format_file_in_quorum 2024-09-11 15:19:59 +08:00
weisd
300d006e6b 更新全局disk 2024-09-11 14:34:03 +08:00
weisd
ca85999d8f 更新全局disk 2024-09-11 14:27:02 +08:00
weisd
7b9467a972 更新全局disk 2024-09-11 14:25:53 +08:00
weisd
9aa2c7bedd init global_local_disks 2024-09-10 18:06:15 +08:00
weisd
51e2333890 merge global_disks 2024-09-10 17:59:23 +08:00
weisd
472df9dbb9 test global_disks 2024-09-10 17:32:39 +08:00
weisd
819e417d17 test 2024-09-10 17:23:47 +08:00
weisd
a430771e03 重写stores初始化 2024-09-10 16:27:35 +08:00
weisd
bb83f4bef3 rm zip 2024-09-10 15:32:44 +08:00
weisd
4058d66644 Merge branch 'upload' 2024-09-10 15:29:55 +08:00
loverustfs
c73dbd31d2 添加注释 2024-09-08 21:52:51 +08:00
weisd
41152cbd56 fix:reduce_write_quorum_errs 2024-09-03 13:34:03 +08:00
weisd
15ef8aabf4 fix:reduce_write_quorum_errs 2024-09-03 09:12:32 +08:00
weisd
fd85572b87 fix:reduce_write_quorum_errs 2024-09-02 17:05:22 +08:00
loverustfs
8fbff623e2 Update TODO.md 2024-09-01 22:38:35 +08:00
junxiang Mu
13bf39004e wip-remote
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-08-30 17:44:21 +08:00
weisd
403c50b233 todo: quorum err check 2024-08-30 16:18:47 +08:00
weisd
1849e8ef6a todo: quorum err check 2024-08-30 16:18:24 +08:00
junxiang Mu
d1989c6990 support remote peer sys
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-08-29 19:29:13 +08:00
junxiang Mu
40ab19b380 support remote disk
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-08-29 18:28:47 +08:00
weisd
fb69061f99 rpc add local_peer 2024-08-27 17:15:47 +08:00
junxiang Mu
6c630cb33a remote make bucket
Signed-off-by: junxiang Mu <1948535941@qq.com>
2024-08-27 16:43:12 +08:00
weisd
3dfa4d83b9 update:delete_object 2024-08-27 15:42:09 +08:00
weisd
85915a2f11 update:todo.md 2024-08-27 15:13:59 +08:00
weisd
8acc1127e5 add: delete_versions Option<uuid> 2024-08-27 15:10:58 +08:00
weisd
e5b75ca056 add: delete_versions 2024-08-27 14:12:15 +08:00
junxiang Mu
c3cee07c78 通过tonic支持节点间通信(初步 2024-08-27 11:40:00 +08:00
loverustfs
48e2c86d5e fix license 2024-08-26 14:44:50 +08:00
weisd
bc79ea515d stash delete_object 2024-08-23 17:48:29 +08:00
weisd
94f98c35b8 stash delete_object 2024-08-22 17:48:35 +08:00
weisd
b15d01c59d stash delete_object 2024-08-22 17:18:40 +08:00
loverustfs
32592289dc Update .gitignore 2024-08-21 23:42:42 +08:00
weisd
dfdfded371 stash delete_object 2024-08-21 17:14:46 +08:00
loverustfs
e0e31ba5e1 Update TODO.md 2024-08-21 14:59:29 +08:00
weisd
4f1306fe5d update TODO.md 2024-08-21 10:14:33 +08:00
weisd
56d05e3dca delete_bucket todo 2024-08-21 10:05:19 +08:00
weisd
67f6726c25 listobject v1 rm log 2024-08-20 16:28:32 +08:00
weisd
4519c01fd0 listobject v1 未使用chan 2024-08-20 14:49:15 +08:00
weisd
4db7d77381 init listobject 2024-08-19 18:02:22 +08:00
shiro.lee
0417e3035d fix: Body转换 2024-08-16 10:34:06 +08:00
weisd
33c4249013 fix:上传同名文件时删除旧版本 2024-08-15 17:37:58 +08:00
weisd
6c2071eeb9 fix:上传同名文件时删除旧版本 2024-08-15 17:25:42 +08:00
weisd
ad9dad49e3 fix:上传同名文件时删除旧版本 2024-08-15 17:24:19 +08:00
shiro.lee
0b8b70a990 fix: 小优化 2024-08-15 09:14:08 +08:00
weisd
8d1dca3b8e fix add_version 2024-08-14 18:02:57 +08:00
weisd
c071a19d54 test read xl.meta 2024-08-14 17:32:33 +08:00
weisd
4a0419520f test read xl.meta 2024-08-14 17:16:26 +08:00
weisd
ed6ba83768 test read xl.meta 2024-08-14 17:03:53 +08:00
weisd
5986bc3b39 添加 FileMetaVersionHeader marshal 2024-08-14 11:07:41 +08:00
weisd
12cd756920 添加 自定义FileMetaVersion marshal 2024-08-13 17:36:48 +08:00
weisd
08c238957d 添加 自定义MetaObject marshal 2024-08-13 14:32:32 +08:00
weisd
d08fc72052 添加 自定义MetaObject marshal 2024-08-12 17:55:23 +08:00
weisd
d2c09c2182 update todo.md 2024-08-09 23:33:22 +08:00
weisd
c063b19418 过滤无效bucketname 2024-08-09 23:15:56 +08:00
weisd
ca19c4849e 过滤无效bucketname 2024-08-09 23:03:44 +08:00
weisd
cc22a9f7ef 过滤无效bucketname 2024-08-09 22:59:44 +08:00
weisd
b9e907b401 添加config默认值 2024-08-09 21:30:59 +08:00
weisd
4324c3e006 添加config默认值 2024-08-09 21:27:10 +08:00
weisd
b630dfb229 添加单盘支持 2024-08-09 20:20:27 +08:00
shiro.lee
527ef74b6d fix: unix下增加openssl依赖包 2024-08-09 09:45:04 +08:00
shiro.lee
47d1b545d5 fix: 去除anyhow的依赖 2024-08-06 22:59:28 +08:00
shiro.lee
6c8a41ece1 fix: 小优化 2024-08-06 17:19:22 +08:00
shiro.lee
0dcd704c55 fix: 优化警告代码 2024-08-06 09:31:48 +08:00
shiro.lee
d1d38cb2e2 fix: 调整init_disks位置 2024-08-05 23:06:37 +08:00
shiro.lee
906c27a9ba fix: 调整endpoint位置 2024-08-05 22:48:30 +08:00
shiro.lee
acaad6c58c fix: 调整disk trait位置 2024-08-05 22:43:45 +08:00
shiro.lee
83e0e6d8ab fix: 小优化 2024-08-05 22:28:04 +08:00
shiro.lee
c9dfef95fb fix: 去除anyhow提供的错误处理,统一使用自定义的Error和Result 2024-08-05 18:48:45 +08:00
shiro.lee
62fe12fed7 fix: 调整错误处理 2024-08-05 08:53:45 +08:00
weisd
106fc7f063 fix:上传时ec顺序不正确 2024-07-31 17:44:32 +08:00
weisd
7e4b782aed Merge pull request #10 from rustfs/feat/delete-bucket
feat: 删除桶
2024-07-30 17:54:19 +08:00
overtrue
59866b8867 feat: delete bucket 2024-07-30 16:54:11 +08:00
weisd
ea04ce8545 test:abort_multipart_upload 2024-07-29 15:08:27 +08:00
weisd
df6cbb4660 todo:list_object 2024-07-26 17:30:39 +08:00
weisd
9ab742168c todo:list_object 2024-07-26 17:29:50 +08:00
weisd
f51cabc3d9 test debug 2024-07-25 18:06:05 +08:00
shiro.lee
c8fdbcf548 fix: debug 2024-07-25 17:55:07 +08:00
weisd
9ac0565a19 test debug 2024-07-25 17:48:17 +08:00
weisd
30cd97004f update todo 2024-07-25 17:06:16 +08:00
weisd
4f189b6216 list_bucket done 2024-07-25 16:57:43 +08:00
weisd
28e7498e9a test:get_object done 2024-07-25 13:51:18 +08:00
weisd
af59922112 test:get_object done 2024-07-25 13:45:37 +08:00
weisd
327fb687ca test:get_object 2024-07-25 11:22:00 +08:00
weisd
44a7d8d315 test:get_object 2024-07-25 09:07:06 +08:00
weisd
3224a39ed8 test:get_object 2024-07-24 16:45:23 +08:00
weisd
c1a3442cd5 todo:ec decode 2024-07-23 17:02:52 +08:00
weisd
ad85245743 todo:ec decode 2024-07-23 11:25:20 +08:00
weisd
df82aa5ef1 todo:ec decode 2024-07-22 15:33:41 +08:00
weisd
16767cc36d todo:download 2024-07-22 11:47:29 +08:00
weisd
c494167bee todo: get_object_reader 2024-07-18 16:25:46 +08:00
weisd
a8ee7d45d5 up log 2024-07-18 14:48:21 +08:00
weisd
536519328c plugin 2024-07-17 14:15:22 +08:00
weisd
1e902f4688 test complete_multipart_upload 2024-07-12 16:45:31 +08:00
weisd
4afd8872d0 todo:readMultipleFiles 2024-07-11 17:57:59 +08:00
weisd
d0d82adc85 use FileWriter 2024-07-10 17:16:44 +08:00
weisd
4b5dbbf4c3 test: erasure 2024-07-10 16:12:01 +08:00
weisd
d7264dc7d2 test: AsyncWrite 2024-07-10 11:44:58 +08:00
weisd
90ac002c42 bug:ec.encode 2024-07-09 18:09:02 +08:00
weisd
495a6ffa05 fix: add set_disk 2024-07-09 13:30:49 +08:00
weisd
0876e8845c fix: 优化unused 2024-07-09 11:31:20 +08:00
weisd
872017243f merge erasure 2024-07-09 11:03:46 +08:00
weisd
4a514f4ab3 todo:put_object_part 2024-07-09 10:57:35 +08:00
weisd
80688be059 todo:put_object_part 2024-07-09 10:47:44 +08:00
weisd
16f7368514 test:mc cp 2024-07-08 18:03:56 +08:00
weisd
3f2d94687f test:mc cp 2024-07-08 11:39:43 +08:00
shiro.lee
ad9a20337b fix: 清除多余的引入 2024-07-06 14:08:30 +08:00
shiro.lee
79a0992773 Merge branch 'endpoint' into erasure 2024-07-06 14:01:14 +08:00
shiro.lee
55c6b1b498 fix: 解决依赖endpoint出现的问题 2024-07-06 13:58:57 +08:00
shiro.lee
31e13a966a test: add endpoint tet 2024-07-06 13:15:45 +08:00
lihaixing
ca915a5f6d test: 优化endpoint单元测试 2024-07-06 12:56:20 +08:00
shiro.lee
9778c91ac7 test: add endpoint tet 2024-07-06 10:36:37 +08:00
shiro.lee
24544a30a1 test: add endpoint tet 2024-07-05 23:18:25 +08:00
shiro.lee
dc041da402 test: 增加endpoints的验证逻辑 2024-07-05 18:47:22 +08:00
weisd
8aa966a31a test:mc cp 2024-07-05 18:02:27 +08:00
weisd
ea70c607eb Merge branch 'upload' into erasure 2024-07-05 17:30:00 +08:00
weisd
0f9b8df1b8 test:put_object 2024-07-05 17:29:31 +08:00
shiro.lee
c9e2319c3a test: 增加endpoint的单元测试 2024-07-05 15:45:33 +08:00
weisd
e85b469df7 test:FileMeta 2024-07-05 11:48:34 +08:00
shiro.lee
de59cd2deb fix: 优化endpoint new的逻辑 2024-07-05 11:47:13 +08:00
shiro.lee
91db1fc3dc test: add net tet 2024-07-04 23:35:07 +08:00
shiro.lee
9d7e2b439c test: add net tet 2024-07-04 23:26:25 +08:00
shiro.lee
85ffa447f3 fix: 优化endpoint 2024-07-04 19:01:11 +08:00
shiro.lee
9880a0e039 Merge branch 'endpoint' into erasure 2024-07-04 18:37:13 +08:00
shiro.lee
b14826f05c fix: 优化endpoint 2024-07-04 18:31:08 +08:00
weisd
36fa900817 test:FileMeta 2024-07-04 18:07:03 +08:00
weisd
50d61d96d9 test:FileMeta 2024-07-04 17:30:16 +08:00
shiro.lee
64c37260b7 fix: 优化net 2024-07-03 23:00:32 +08:00
shiro.lee
0b8c698392 fix: 优化endpoint 2024-07-03 18:57:57 +08:00
weisd
65bde5555c Merge branch 'erasure' of github.com:rustfs/s3-rustfs into erasure 2024-07-03 17:47:39 +08:00
weisd
5794017cdd todo:rename_data 2024-07-03 17:47:28 +08:00
shiro.lee
a9239be2e1 fix: 替换Error 2024-07-03 16:47:27 +08:00
weisd
fdfa68be2e Merge branch 'erasure' of github.com:rustfs/s3-rustfs into erasure 2024-07-03 11:45:40 +08:00
weisd
2649b0edb5 todo:put_object 2024-07-03 11:45:29 +08:00
shiro.lee
ed1e3676b1 test: 给disks_layout增加单元测试 2024-07-02 23:35:15 +08:00
shiro.lee
1215ed152b fix: 优化disks_layout 2024-07-02 18:51:50 +08:00
weisd
938ad4ec44 test:encode 2024-07-02 18:09:00 +08:00
weisd
21bceecccb todo:Error 2024-07-02 17:01:54 +08:00
weisd
e1f265c940 todo:Error 2024-07-02 16:03:26 +08:00
weisd
dbf0d46a08 rm pipe 2024-07-02 15:07:40 +08:00
shiro.lee
7eca5ea9dc fix: 优化ellipses 2024-07-01 22:46:40 +08:00
shiro.lee
0206b84b63 fix: 优化ellipses 2024-07-01 19:33:20 +08:00
weisd
15675927ad todo:put_object 2024-07-01 18:10:16 +08:00
weisd
4e2d5c7107 todo:put_object 2024-06-28 18:13:50 +08:00
weisd
5d3166168e use anyhow:Result 2024-06-28 13:37:56 +08:00
weisd
570ada9050 init:store 2024-06-28 11:09:20 +08:00
weisd
617bd38a01 init:store 2024-06-28 10:54:58 +08:00
weisd
43e5e7dd55 init:store 2024-06-27 18:18:38 +08:00
weisd
de9f69dd54 init:store 2024-06-26 18:16:10 +08:00
weisd
241c80880c init:store 2024-06-26 18:15:45 +08:00
weisd
2e5c3b2d09 init:store 2024-06-26 16:02:25 +08:00
weisd
85daac92b5 init:store 2024-06-26 15:53:11 +08:00
shiro.lee
aeb81908c7 fix: 调整cargo引用 & Endpoint修改 2024-06-25 23:28:05 +08:00
weisd
2c1d0bf792 run init 2024-06-25 17:48:14 +08:00
weisd
d9c8871da0 run init 2024-06-25 17:44:46 +08:00
weisd
0a5c9c8376 run init 2024-06-25 17:35:31 +08:00
weisd
d68f7c7b72 run init 2024-06-25 17:33:46 +08:00
weisd
f7b0bfa76a merge main 2024-06-25 16:41:41 +08:00
weisd
df7e31380b run init 2024-06-25 16:22:14 +08:00
weisd
a2df4128ed rename ecstore 2024-06-25 15:45:21 +08:00
1062 changed files with 61879 additions and 193365 deletions

View File

@@ -1,117 +1,45 @@
# RustFS Project AI Coding Rules # RustFS Project Cursor Rules
## 🚨🚨🚨 CRITICAL DEVELOPMENT RULES - ZERO TOLERANCE 🚨🚨🚨 ## ⚠️ CRITICAL DEVELOPMENT RULES ⚠️
### ⛔️ ABSOLUTE PROHIBITION: NEVER COMMIT DIRECTLY TO MASTER/MAIN BRANCH ⛔️ ### 🚨 NEVER COMMIT DIRECTLY TO MASTER/MAIN BRANCH 🚨
- **This is the most important rule - NEVER modify code directly on main or master branch**
**🔥 THIS IS THE MOST CRITICAL RULE - VIOLATION WILL RESULT IN IMMEDIATE REVERSAL 🔥** - **Always work on feature branches and use pull requests for all changes**
- **Any direct commits to master/main branch are strictly forbidden**
- **🚫 ZERO DIRECT COMMITS TO MAIN/MASTER BRANCH - ABSOLUTELY FORBIDDEN** - Before starting any development, always:
- **🚫 ANY DIRECT COMMIT TO MAIN BRANCH MUST BE IMMEDIATELY REVERTED** 1. `git checkout main` (switch to main branch)
- **🚫 NO EXCEPTIONS FOR HOTFIXES, EMERGENCIES, OR URGENT CHANGES** 2. `git pull` (get latest changes)
- **🚫 NO EXCEPTIONS FOR SMALL CHANGES, TYPOS, OR DOCUMENTATION UPDATES** 3. `git checkout -b feat/your-feature-name` (create and switch to feature branch)
- **🚫 NO EXCEPTIONS FOR ANYONE - MAINTAINERS, CONTRIBUTORS, OR ADMINS** 4. Make your changes on the feature branch
5. Commit and push to the feature branch
### 📋 MANDATORY WORKFLOW - STRICTLY ENFORCED 6. Create a pull request for review
**EVERY SINGLE CHANGE MUST FOLLOW THIS WORKFLOW:**
1. **Check current branch**: `git branch` (MUST NOT be on main/master)
2. **Switch to main**: `git checkout main`
3. **Pull latest**: `git pull origin main`
4. **Create feature branch**: `git checkout -b feat/your-feature-name`
5. **Make changes ONLY on feature branch**
6. **Test thoroughly before committing**
7. **Commit and push to feature branch**: `git push origin feat/your-feature-name`
8. **Create Pull Request**: Use `gh pr create` (MANDATORY)
9. **Wait for PR approval**: NO self-merging allowed
10. **Merge through GitHub interface**: ONLY after approval
### 🔒 ENFORCEMENT MECHANISMS
- **Branch protection rules**: Main branch is protected
- **Pre-commit hooks**: Will block direct commits to main
- **CI/CD checks**: All PRs must pass before merging
- **Code review requirement**: At least one approval needed
- **Automated reversal**: Direct commits to main will be automatically reverted
## 🎯 Core AI Development Principles
### Five Execution Steps
#### 1. Task Analysis and Planning
- **Clear Objectives**: Deeply understand task requirements and expected results before starting coding
- **Plan Development**: List specific files, components, and functions that need modification, explaining the reasons for changes
- **Risk Assessment**: Evaluate the impact of changes on existing functionality, develop rollback plans
#### 2. Precise Code Location
- **File Identification**: Determine specific files and line numbers that need modification
- **Impact Analysis**: Avoid modifying irrelevant files, clearly state the reason for each file modification
- **Minimization Principle**: Unless explicitly required by the task, do not create new abstraction layers or refactor existing code
#### 3. Minimal Code Changes
- **Focus on Core**: Only write code directly required by the task
- **Avoid Redundancy**: Do not add unnecessary logs, comments, tests, or error handling
- **Isolation**: Ensure new code does not interfere with existing functionality, maintain code independence
#### 4. Strict Code Review
- **Correctness Check**: Verify the correctness and completeness of code logic
- **Style Consistency**: Ensure code conforms to established project coding style
- **Side Effect Assessment**: Evaluate the impact of changes on downstream systems
#### 5. Clear Delivery Documentation
- **Change Summary**: Detailed explanation of all modifications and reasons
- **File List**: List all modified files and their specific changes
- **Risk Statement**: Mark any assumptions or potential risk points
### Core Principles
- **🎯 Precise Execution**: Strictly follow task requirements, no arbitrary innovation
- **⚡ Efficient Development**: Avoid over-design, only do necessary work
- **🛡️ Safe and Reliable**: Always follow development processes, ensure code quality and system stability
- **🔒 Cautious Modification**: Only modify when clearly knowing what needs to be changed and having confidence
### Additional AI Behavior Rules
1. **Use English for all code comments and documentation** - All comments, variable names, function names, documentation, and user-facing text in code should be in English
2. **Clean up temporary scripts after use** - Any temporary scripts, test files, or helper files created during AI work should be removed after task completion
3. **Only make confident modifications** - Do not make speculative changes or "convenient" modifications outside the task scope. If uncertain about a change, ask for clarification rather than guessing
## Project Overview ## Project Overview
RustFS is a high-performance distributed object storage system written in Rust, compatible with S3 API. The project adopts a modular architecture, supporting erasure coding storage, multi-tenant management, observability, and other enterprise-level features. RustFS is a high-performance distributed object storage system written in Rust, compatible with S3 API. The project adopts a modular architecture, supporting erasure coding storage, multi-tenant management, observability, and other enterprise-level features.
## Core Architecture Principles ## Core Architecture Principles
### 1. Modular Design ### 1. Modular Design
- Project uses Cargo workspace structure, containing multiple independent crates - Project uses Cargo workspace structure, containing multiple independent crates
- Core modules: `rustfs` (main service), `ecstore` (erasure coding storage), `common` (shared components) - Core modules: `rustfs` (main service), `ecstore` (erasure coding storage), `common` (shared components)
- Functional modules: `iam` (identity management), `madmin` (management interface), `crypto` (encryption), etc. - Functional modules: `iam` (identity management), `madmin` (management interface), `crypto` (encryption), etc.
- Tool modules: `cli` (command line tool), `crates/*` (utility libraries) - Tool modules: `cli` (command line tool), `crates/*` (utility libraries)
### 2. Asynchronous Programming Pattern ### 2. Asynchronous Programming Pattern
- Comprehensive use of `tokio` async runtime - Comprehensive use of `tokio` async runtime
- Prioritize `async/await` syntax - Prioritize `async/await` syntax
- Use `async-trait` for async methods in traits - Use `async-trait` for async methods in traits
- Avoid blocking operations, use `spawn_blocking` when necessary - Avoid blocking operations, use `spawn_blocking` when necessary
### 3. Error Handling Strategy ### 3. Error Handling Strategy
- Use unified error type `common::error::Error`
- **Use modular, type-safe error handling with `thiserror`** - Support error chains and context information
- Each module should define its own error type using `thiserror::Error` derive macro - Use `thiserror` to define specific error types
- Support error chains and context information through `#[from]` and `#[source]` attributes - Error conversion uses `downcast_ref` for type checking
- Use `Result<T>` type aliases for consistency within each module
- Error conversion between modules should use explicit `From` implementations
- Follow the pattern: `pub type Result<T> = core::result::Result<T, Error>`
- Use `#[error("description")]` attributes for clear error messages
- Support error downcasting when needed through `other()` helper methods
- Implement `Clone` for errors when required by the domain logic
## Code Style Guidelines ## Code Style Guidelines
### 1. Formatting Configuration ### 1. Formatting Configuration
```toml ```toml
max_width = 130 max_width = 130
fn_call_width = 90 fn_call_width = 90
@@ -173,8 +101,49 @@ make pre-commit
make setup-hooks make setup-hooks
``` ```
### 3. Naming Conventions #### 🔒 Automated Pre-commit Hooks
This project includes a pre-commit hook that automatically runs before each commit to ensure:
- ✅ Code is properly formatted (`cargo fmt --all --check`)
- ✅ No clippy warnings (`cargo clippy --all-targets --all-features -- -D warnings`)
- ✅ Code compiles successfully (`cargo check --all-targets`)
**Setting Up Pre-commit Hooks** (MANDATORY for all developers):
Run this command once after cloning the repository:
```bash
make setup-hooks
```
Or manually:
```bash
chmod +x .git/hooks/pre-commit
```
#### 🚫 Commit Prevention
If your code doesn't meet the formatting requirements, the pre-commit hook will:
1. **Block the commit** and show clear error messages
2. **Provide exact commands** to fix the issues
3. **Guide you through** the resolution process
Example output when formatting fails:
```
❌ Code formatting check failed!
💡 Please run 'cargo fmt --all' to format your code before committing.
🔧 Quick fix:
cargo fmt --all
git add .
git commit
```
### 3. Naming Conventions
- Use `snake_case` for functions, variables, modules - Use `snake_case` for functions, variables, modules
- Use `PascalCase` for types, traits, enums - Use `PascalCase` for types, traits, enums
- Constants use `SCREAMING_SNAKE_CASE` - Constants use `SCREAMING_SNAKE_CASE`
@@ -184,7 +153,6 @@ make setup-hooks
- Choose names that clearly express the purpose and intent - Choose names that clearly express the purpose and intent
### 4. Type Declaration Guidelines ### 4. Type Declaration Guidelines
- **Prefer type inference over explicit type declarations** when the type is obvious from context - **Prefer type inference over explicit type declarations** when the type is obvious from context
- Let the Rust compiler infer types whenever possible to reduce verbosity and improve maintainability - Let the Rust compiler infer types whenever possible to reduce verbosity and improve maintainability
- Only specify types explicitly when: - Only specify types explicitly when:
@@ -193,8 +161,38 @@ make setup-hooks
- Required for API boundaries (function signatures, public struct fields) - Required for API boundaries (function signatures, public struct fields)
- Needed to resolve ambiguity between multiple possible types - Needed to resolve ambiguity between multiple possible types
### 5. Documentation Comments **Good examples (prefer these):**
```rust
// Compiler can infer the type
let items = vec![1, 2, 3, 4];
let config = Config::default();
let result = process_data(&input);
// Iterator chains with clear context
let filtered: Vec<_> = items.iter().filter(|&&x| x > 2).collect();
```
**Avoid unnecessary explicit types:**
```rust
// Unnecessary - type is obvious
let items: Vec<i32> = vec![1, 2, 3, 4];
let config: Config = Config::default();
let result: ProcessResult = process_data(&input);
```
**When explicit types are beneficial:**
```rust
// API boundaries - always specify types
pub fn process_data(input: &[u8]) -> Result<ProcessResult, Error> { ... }
// Ambiguous cases - explicit type needed
let value: f64 = "3.14".parse().unwrap();
// Complex generic types - explicit for clarity
let cache: HashMap<String, Arc<Mutex<CacheEntry>>> = HashMap::new();
```
### 5. Documentation Comments
- Public APIs must have documentation comments - Public APIs must have documentation comments
- Use `///` for documentation comments - Use `///` for documentation comments
- Complex functions add `# Examples` and `# Parameters` descriptions - Complex functions add `# Examples` and `# Parameters` descriptions
@@ -203,7 +201,6 @@ make setup-hooks
- Avoid meaningless comments like "debug 111" or placeholder text - Avoid meaningless comments like "debug 111" or placeholder text
### 6. Import Guidelines ### 6. Import Guidelines
- Standard library imports first - Standard library imports first
- Third-party crate imports in the middle - Third-party crate imports in the middle
- Project internal imports last - Project internal imports last
@@ -212,7 +209,6 @@ make setup-hooks
## Asynchronous Programming Guidelines ## Asynchronous Programming Guidelines
### 1. Trait Definition ### 1. Trait Definition
```rust ```rust
#[async_trait::async_trait] #[async_trait::async_trait]
pub trait StorageAPI: Send + Sync { pub trait StorageAPI: Send + Sync {
@@ -221,7 +217,6 @@ pub trait StorageAPI: Send + Sync {
``` ```
### 2. Error Handling ### 2. Error Handling
```rust ```rust
// Use ? operator to propagate errors // Use ? operator to propagate errors
async fn example_function() -> Result<()> { async fn example_function() -> Result<()> {
@@ -232,7 +227,6 @@ async fn example_function() -> Result<()> {
``` ```
### 3. Concurrency Control ### 3. Concurrency Control
- Use `Arc` and `Mutex`/`RwLock` for shared state management - Use `Arc` and `Mutex`/`RwLock` for shared state management
- Prioritize async locks from `tokio::sync` - Prioritize async locks from `tokio::sync`
- Avoid holding locks for long periods - Avoid holding locks for long periods
@@ -240,7 +234,6 @@ async fn example_function() -> Result<()> {
## Logging and Tracing Guidelines ## Logging and Tracing Guidelines
### 1. Tracing Usage ### 1. Tracing Usage
```rust ```rust
#[tracing::instrument(skip(self, data))] #[tracing::instrument(skip(self, data))]
async fn process_data(&self, data: &[u8]) -> Result<()> { async fn process_data(&self, data: &[u8]) -> Result<()> {
@@ -250,7 +243,6 @@ async fn process_data(&self, data: &[u8]) -> Result<()> {
``` ```
### 2. Log Levels ### 2. Log Levels
- `error!`: System errors requiring immediate attention - `error!`: System errors requiring immediate attention
- `warn!`: Warning information that may affect functionality - `warn!`: Warning information that may affect functionality
- `info!`: Important business information - `info!`: Important business information
@@ -258,7 +250,6 @@ async fn process_data(&self, data: &[u8]) -> Result<()> {
- `trace!`: Detailed execution paths - `trace!`: Detailed execution paths
### 3. Structured Logging ### 3. Structured Logging
```rust ```rust
info!( info!(
counter.rustfs_api_requests_total = 1_u64, counter.rustfs_api_requests_total = 1_u64,
@@ -271,75 +262,45 @@ info!(
## Error Handling Guidelines ## Error Handling Guidelines
### 1. Error Type Definition ### 1. Error Type Definition
```rust ```rust
// Use thiserror for module-specific error types #[derive(Debug, thiserror::Error)]
#[derive(thiserror::Error, Debug)]
pub enum MyError { pub enum MyError {
#[error("IO error: {0}")] #[error("IO error: {0}")]
Io(#[from] std::io::Error), Io(#[from] std::io::Error),
#[error("Storage error: {0}")]
Storage(#[from] ecstore::error::StorageError),
#[error("Custom error: {message}")] #[error("Custom error: {message}")]
Custom { message: String }, Custom { message: String },
#[error("File not found: {path}")]
FileNotFound { path: String },
#[error("Invalid configuration: {0}")]
InvalidConfig(String),
} }
// Provide Result type alias for the module
pub type Result<T> = core::result::Result<T, MyError>;
``` ```
### 2. Error Helper Methods ### 2. Error Conversion
```rust ```rust
impl MyError { pub fn to_s3_error(err: Error) -> S3Error {
/// Create error from any compatible error type if let Some(storage_err) = err.downcast_ref::<StorageError>() {
pub fn other<E>(error: E) -> Self match storage_err {
where StorageError::ObjectNotFound(bucket, object) => {
E: Into<Box<dyn std::error::Error + Send + Sync>>, s3_error!(NoSuchKey, "{}/{}", bucket, object)
{ }
MyError::Io(std::io::Error::other(error)) // Other error types...
}
} }
// Default error handling
} }
``` ```
### 3. Error Context and Propagation ### 3. Error Context
```rust ```rust
// Use ? operator for clean error propagation // Add error context
async fn example_function() -> Result<()> { .map_err(|e| Error::from_string(format!("Failed to process {}: {}", path, e)))?
let data = read_file("path").await?;
process_data(data).await?;
Ok(())
}
// Add context to errors
fn process_with_context(path: &str) -> Result<()> {
std::fs::read(path)
.map_err(|e| MyError::Custom {
message: format!("Failed to read {}: {}", path, e)
})?;
Ok(())
}
``` ```
## Performance Optimization Guidelines ## Performance Optimization Guidelines
### 1. Memory Management ### 1. Memory Management
- Use `Bytes` instead of `Vec<u8>` for zero-copy operations - Use `Bytes` instead of `Vec<u8>` for zero-copy operations
- Avoid unnecessary cloning, use reference passing - Avoid unnecessary cloning, use reference passing
- Use `Arc` for sharing large objects - Use `Arc` for sharing large objects
### 2. Concurrency Optimization ### 2. Concurrency Optimization
```rust ```rust
// Use join_all for concurrent operations // Use join_all for concurrent operations
let futures = disks.iter().map(|disk| disk.operation()); let futures = disks.iter().map(|disk| disk.operation());
@@ -347,14 +308,12 @@ let results = join_all(futures).await;
``` ```
### 3. Caching Strategy ### 3. Caching Strategy
- Use `lazy_static` or `OnceCell` for global caching
- Use `LazyLock` for global caching
- Implement LRU cache to avoid memory leaks - Implement LRU cache to avoid memory leaks
## Testing Guidelines ## Testing Guidelines
### 1. Unit Tests ### 1. Unit Tests
```rust ```rust
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
@@ -376,12 +335,10 @@ mod tests {
``` ```
### 2. Integration Tests ### 2. Integration Tests
- Use `e2e_test` module for end-to-end testing - Use `e2e_test` module for end-to-end testing
- Simulate real storage environments - Simulate real storage environments
### 3. Test Quality Standards ### 3. Test Quality Standards
- Write meaningful test cases that verify actual functionality - Write meaningful test cases that verify actual functionality
- Avoid placeholder or debug content like "debug 111", "test test", etc. - Avoid placeholder or debug content like "debug 111", "test test", etc.
- Use descriptive test names that clearly indicate what is being tested - Use descriptive test names that clearly indicate what is being tested
@@ -391,11 +348,9 @@ mod tests {
## Cross-Platform Compatibility Guidelines ## Cross-Platform Compatibility Guidelines
### 1. CPU Architecture Compatibility ### 1. CPU Architecture Compatibility
- **Always consider multi-platform and different CPU architecture compatibility** when writing code - **Always consider multi-platform and different CPU architecture compatibility** when writing code
- Support major architectures: x86_64, aarch64 (ARM64), and other target platforms - Support major architectures: x86_64, aarch64 (ARM64), and other target platforms
- Use conditional compilation for architecture-specific code: - Use conditional compilation for architecture-specific code:
```rust ```rust
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn optimized_x86_64_function() { /* x86_64 specific implementation */ } fn optimized_x86_64_function() { /* x86_64 specific implementation */ }
@@ -408,19 +363,16 @@ fn generic_function() { /* Generic fallback implementation */ }
``` ```
### 2. Platform-Specific Dependencies ### 2. Platform-Specific Dependencies
- Use feature flags for platform-specific dependencies - Use feature flags for platform-specific dependencies
- Provide fallback implementations for unsupported platforms - Provide fallback implementations for unsupported platforms
- Test on multiple architectures in CI/CD pipeline - Test on multiple architectures in CI/CD pipeline
### 3. Endianness Considerations ### 3. Endianness Considerations
- Use explicit byte order conversion when dealing with binary data - Use explicit byte order conversion when dealing with binary data
- Prefer `to_le_bytes()`, `from_le_bytes()` for consistent little-endian format - Prefer `to_le_bytes()`, `from_le_bytes()` for consistent little-endian format
- Use `byteorder` crate for complex binary format handling - Use `byteorder` crate for complex binary format handling
### 4. SIMD and Performance Optimizations ### 4. SIMD and Performance Optimizations
- Use portable SIMD libraries like `wide` or `packed_simd` - Use portable SIMD libraries like `wide` or `packed_simd`
- Provide fallback implementations for non-SIMD architectures - Provide fallback implementations for non-SIMD architectures
- Use runtime feature detection when appropriate - Use runtime feature detection when appropriate
@@ -428,12 +380,10 @@ fn generic_function() { /* Generic fallback implementation */ }
## Security Guidelines ## Security Guidelines
### 1. Memory Safety ### 1. Memory Safety
- Disable `unsafe` code (workspace.lints.rust.unsafe_code = "deny") - Disable `unsafe` code (workspace.lints.rust.unsafe_code = "deny")
- Use `rustls` instead of `openssl` - Use `rustls` instead of `openssl`
### 2. Authentication and Authorization ### 2. Authentication and Authorization
```rust ```rust
// Use IAM system for permission checks // Use IAM system for permission checks
let identity = iam.authenticate(&access_key, &secret_key).await?; let identity = iam.authenticate(&access_key, &secret_key).await?;
@@ -443,13 +393,11 @@ iam.authorize(&identity, &action, &resource).await?;
## Configuration Management Guidelines ## Configuration Management Guidelines
### 1. Environment Variables ### 1. Environment Variables
- Use `RUSTFS_` prefix - Use `RUSTFS_` prefix
- Support both configuration files and environment variables - Support both configuration files and environment variables
- Provide reasonable default values - Provide reasonable default values
### 2. Configuration Structure ### 2. Configuration Structure
```rust ```rust
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize, Clone)]
pub struct Config { pub struct Config {
@@ -463,12 +411,10 @@ pub struct Config {
## Dependency Management Guidelines ## Dependency Management Guidelines
### 1. Workspace Dependencies ### 1. Workspace Dependencies
- Manage versions uniformly at workspace level - Manage versions uniformly at workspace level
- Use `workspace = true` to inherit configuration - Use `workspace = true` to inherit configuration
### 2. Feature Flags ### 2. Feature Flags
```rust ```rust
[features] [features]
default = ["file"] default = ["file"]
@@ -479,18 +425,15 @@ kafka = ["dep:rdkafka"]
## Deployment and Operations Guidelines ## Deployment and Operations Guidelines
### 1. Containerization ### 1. Containerization
- Provide Dockerfile and docker-compose configuration - Provide Dockerfile and docker-compose configuration
- Support multi-stage builds to optimize image size - Support multi-stage builds to optimize image size
### 2. Observability ### 2. Observability
- Integrate OpenTelemetry for distributed tracing - Integrate OpenTelemetry for distributed tracing
- Support Prometheus metrics collection - Support Prometheus metrics collection
- Provide Grafana dashboards - Provide Grafana dashboards
### 3. Health Checks ### 3. Health Checks
```rust ```rust
// Implement health check endpoint // Implement health check endpoint
async fn health_check() -> Result<HealthStatus> { async fn health_check() -> Result<HealthStatus> {
@@ -501,7 +444,6 @@ async fn health_check() -> Result<HealthStatus> {
## Code Review Checklist ## Code Review Checklist
### 1. **Code Formatting and Quality (MANDATORY)** ### 1. **Code Formatting and Quality (MANDATORY)**
- [ ] **Code is properly formatted** (`cargo fmt --all --check` passes) - [ ] **Code is properly formatted** (`cargo fmt --all --check` passes)
- [ ] **All clippy warnings are resolved** (`cargo clippy --all-targets --all-features -- -D warnings` passes) - [ ] **All clippy warnings are resolved** (`cargo clippy --all-targets --all-features -- -D warnings` passes)
- [ ] **Code compiles successfully** (`cargo check --all-targets` passes) - [ ] **Code compiles successfully** (`cargo check --all-targets` passes)
@@ -509,32 +451,27 @@ async fn health_check() -> Result<HealthStatus> {
- [ ] **No formatting-related changes** mixed with functional changes (separate commits) - [ ] **No formatting-related changes** mixed with functional changes (separate commits)
### 2. Functionality ### 2. Functionality
- [ ] Are all error cases properly handled? - [ ] Are all error cases properly handled?
- [ ] Is there appropriate logging? - [ ] Is there appropriate logging?
- [ ] Is there necessary test coverage? - [ ] Is there necessary test coverage?
### 3. Performance ### 3. Performance
- [ ] Are unnecessary memory allocations avoided? - [ ] Are unnecessary memory allocations avoided?
- [ ] Are async operations used correctly? - [ ] Are async operations used correctly?
- [ ] Are there potential deadlock risks? - [ ] Are there potential deadlock risks?
### 4. Security ### 4. Security
- [ ] Are input parameters properly validated? - [ ] Are input parameters properly validated?
- [ ] Are there appropriate permission checks? - [ ] Are there appropriate permission checks?
- [ ] Is information leakage avoided? - [ ] Is information leakage avoided?
### 5. Cross-Platform Compatibility ### 5. Cross-Platform Compatibility
- [ ] Does the code work on different CPU architectures (x86_64, aarch64)? - [ ] Does the code work on different CPU architectures (x86_64, aarch64)?
- [ ] Are platform-specific features properly gated with conditional compilation? - [ ] Are platform-specific features properly gated with conditional compilation?
- [ ] Is byte order handling correct for binary data? - [ ] Is byte order handling correct for binary data?
- [ ] Are there appropriate fallback implementations for unsupported platforms? - [ ] Are there appropriate fallback implementations for unsupported platforms?
### 6. Code Commits and Documentation ### 6. Code Commits and Documentation
- [ ] Does it comply with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)? - [ ] Does it comply with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)?
- [ ] Are commit messages concise and under 72 characters for the title line? - [ ] Are commit messages concise and under 72 characters for the title line?
- [ ] Commit titles should be concise and in English, avoid Chinese - [ ] Commit titles should be concise and in English, avoid Chinese
@@ -543,7 +480,6 @@ async fn health_check() -> Result<HealthStatus> {
## Common Patterns and Best Practices ## Common Patterns and Best Practices
### 1. Resource Management ### 1. Resource Management
```rust ```rust
// Use RAII pattern for resource management // Use RAII pattern for resource management
pub struct ResourceGuard { pub struct ResourceGuard {
@@ -558,7 +494,6 @@ impl Drop for ResourceGuard {
``` ```
### 2. Dependency Injection ### 2. Dependency Injection
```rust ```rust
// Use dependency injection pattern // Use dependency injection pattern
pub struct Service { pub struct Service {
@@ -568,7 +503,6 @@ pub struct Service {
``` ```
### 3. Graceful Shutdown ### 3. Graceful Shutdown
```rust ```rust
// Implement graceful shutdown // Implement graceful shutdown
async fn shutdown_gracefully(shutdown_rx: &mut Receiver<()>) { async fn shutdown_gracefully(shutdown_rx: &mut Receiver<()>) {
@@ -587,116 +521,59 @@ async fn shutdown_gracefully(shutdown_rx: &mut Receiver<()>) {
## Domain-Specific Guidelines ## Domain-Specific Guidelines
### 1. Storage Operations ### 1. Storage Operations
- All storage operations must support erasure coding - All storage operations must support erasure coding
- Implement read/write quorum mechanisms - Implement read/write quorum mechanisms
- Support data integrity verification - Support data integrity verification
### 2. Network Communication ### 2. Network Communication
- Use gRPC for internal service communication - Use gRPC for internal service communication
- HTTP/HTTPS support for S3-compatible API - HTTP/HTTPS support for S3-compatible API
- Implement connection pooling and retry mechanisms - Implement connection pooling and retry mechanisms
### 3. Metadata Management ### 3. Metadata Management
- Use FlatBuffers for serialization - Use FlatBuffers for serialization
- Support version control and migration - Support version control and migration
- Implement metadata caching - Implement metadata caching
## Branch Management and Development Workflow These rules should serve as guiding principles when developing the RustFS project, ensuring code quality, performance, and maintainability.
### Branch Management ### 4. Code Operations
- **🚨 CRITICAL: NEVER modify code directly on main or master branch - THIS IS ABSOLUTELY FORBIDDEN 🚨** #### Branch Management
- **⚠️ ANY DIRECT COMMITS TO MASTER/MAIN WILL BE REJECTED AND MUST BE REVERTED IMMEDIATELY ⚠️** - **🚨 CRITICAL: NEVER modify code directly on main or master branch - THIS IS ABSOLUTELY FORBIDDEN 🚨**
- **🔒 ALL CHANGES MUST GO THROUGH PULL REQUESTS - NO DIRECT COMMITS TO MAIN UNDER ANY CIRCUMSTANCES 🔒** - **⚠️ ANY DIRECT COMMITS TO MASTER/MAIN WILL BE REJECTED AND MUST BE REVERTED IMMEDIATELY ⚠️**
- **Always work on feature branches - NO EXCEPTIONS** - **Always work on feature branches - NO EXCEPTIONS**
- Always check the .rules.md file before starting to ensure you understand the project guidelines - Always check the .cursorrules file before starting to ensure you understand the project guidelines
- **MANDATORY workflow for ALL changes:** - **MANDATORY workflow for ALL changes:**
1. `git checkout main` (switch to main branch) 1. `git checkout main` (switch to main branch)
2. `git pull` (get latest changes) 2. `git pull` (get latest changes)
3. `git checkout -b feat/your-feature-name` (create and switch to feature branch) 3. `git checkout -b feat/your-feature-name` (create and switch to feature branch)
4. Make your changes ONLY on the feature branch 4. Make your changes ONLY on the feature branch
5. Test thoroughly before committing 5. Test thoroughly before committing
6. Commit and push to the feature branch 6. Commit and push to the feature branch
7. **Create a pull request for code review - THIS IS THE ONLY WAY TO MERGE TO MAIN** 7. Create a pull request for code review
8. **Wait for PR approval before merging - NEVER merge your own PRs without review** - Use descriptive branch names following the pattern: `feat/feature-name`, `fix/issue-name`, `refactor/component-name`, etc.
- Use descriptive branch names following the pattern: `feat/feature-name`, `fix/issue-name`, `refactor/component-name`, etc. - **Double-check current branch before ANY commit: `git branch` to ensure you're NOT on main/master**
- **Double-check current branch before ANY commit: `git branch` to ensure you're NOT on main/master** - Ensure all changes are made on feature branches and merged through pull requests
- **Pull Request Requirements:**
- All changes must be submitted via PR regardless of size or urgency
- PRs must include comprehensive description and testing information
- PRs must pass all CI/CD checks before merging
- PRs require at least one approval from code reviewers
- Even hotfixes and emergency changes must go through PR process
- **Enforcement:**
- Main branch should be protected with branch protection rules
- Direct pushes to main should be blocked by repository settings
- Any accidental direct commits to main must be immediately reverted via PR
### Development Workflow #### Development Workflow
- Use English for all code comments, documentation, and variable names
## 🎯 **Core Development Principles** - Write meaningful and descriptive names for variables, functions, and methods
- Avoid meaningless test content like "debug 111" or placeholder values
- **🔴 Every change must be precise - don't modify unless you're confident** - Before each change, carefully read the existing code to ensure you understand the code structure and implementation, do not break existing logic implementation, do not introduce new issues
- Carefully analyze code logic and ensure complete understanding before making changes - Ensure each change provides sufficient test cases to guarantee code correctness
- When uncertain, prefer asking users or consulting documentation over blind modifications - Do not arbitrarily modify numbers and constants in test cases, carefully analyze their meaning to ensure test case correctness
- Use small iterative steps, modify only necessary parts at a time - When writing or modifying tests, check existing test cases to ensure they have scientific naming and rigorous logic testing, if not compliant, modify test cases to ensure scientific and rigorous testing
- Evaluate impact scope before changes to ensure no new issues are introduced - **Before committing any changes, run `cargo clippy --all-targets --all-features -- -D warnings` to ensure all code passes Clippy checks**
- After each development completion, first git add . then git commit -m "feat: feature description" or "fix: issue description", ensure compliance with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
- **🚀 GitHub PR creation prioritizes gh command usage** - **Keep commit messages concise and under 72 characters** for the title line, use body for detailed explanations if needed
- Prefer using `gh pr create` command to create Pull Requests - After each development completion, first git push to remote repository
- Avoid having users manually create PRs through web interface - After each change completion, summarize the changes, do not create summary files, provide a brief change description, ensure compliance with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
- Provide clear and professional PR titles and descriptions - Provide change descriptions needed for PR in the conversation, ensure compliance with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
- Using `gh` commands ensures better integration and automation - **Always provide PR descriptions in English** after completing any changes, including:
- Clear and concise title following Conventional Commits format
## 📝 **Code Quality Requirements** - Detailed description of what was changed and why
- List of key changes and improvements
- Use English for all code comments, documentation, and variable names - Any breaking changes or migration notes if applicable
- Write meaningful and descriptive names for variables, functions, and methods - Testing information and verification steps
- Avoid meaningless test content like "debug 111" or placeholder values - **Provide PR descriptions in copyable markdown format** enclosed in code blocks for easy one-click copying
- Before each change, carefully read the existing code to ensure you understand the code structure and implementation, do not break existing logic implementation, do not introduce new issues
- Ensure each change provides sufficient test cases to guarantee code correctness
- Do not arbitrarily modify numbers and constants in test cases, carefully analyze their meaning to ensure test case correctness
- When writing or modifying tests, check existing test cases to ensure they have scientific naming and rigorous logic testing, if not compliant, modify test cases to ensure scientific and rigorous testing
- **Before committing any changes, run `cargo clippy --all-targets --all-features -- -D warnings` to ensure all code passes Clippy checks**
- After each development completion, first git add . then git commit -m "feat: feature description" or "fix: issue description", ensure compliance with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
- **Keep commit messages concise and under 72 characters** for the title line, use body for detailed explanations if needed
- After each development completion, first git push to remote repository
- After each change completion, summarize the changes, do not create summary files, provide a brief change description, ensure compliance with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
- Provide change descriptions needed for PR in the conversation, ensure compliance with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
- **Always provide PR descriptions in English** after completing any changes, including:
- Clear and concise title following Conventional Commits format
- Detailed description of what was changed and why
- List of key changes and improvements
- Any breaking changes or migration notes if applicable
- Testing information and verification steps
- **Provide PR descriptions in copyable markdown format** enclosed in code blocks for easy one-click copying
## 🚫 AI Documentation Generation Restrictions
### Forbidden Summary Documents
- **Strictly forbidden to create any form of AI-generated summary documents**
- **Do not create documents containing large amounts of emoji, detailed formatting tables and typical AI style**
- **Do not generate the following types of documents in the project:**
- Benchmark summary documents (BENCHMARK*.md)
- Implementation comparison analysis documents (IMPLEMENTATION_COMPARISON*.md)
- Performance analysis report documents
- Architecture summary documents
- Feature comparison documents
- Any documents with large amounts of emoji and formatted content
- **If documentation is needed, only create when explicitly requested by the user, and maintain a concise and practical style**
- **Documentation should focus on actually needed information, avoiding excessive formatting and decorative content**
- **Any discovered AI-generated summary documents should be immediately deleted**
### Allowed Documentation Types
- README.md (project introduction, keep concise)
- Technical documentation (only create when explicitly needed)
- User manual (only create when explicitly needed)
- API documentation (generated from code)
- Changelog (CHANGELOG.md)
These rules should serve as guiding principles when developing the RustFS project, ensuring code quality, performance, and maintainability.

29
.docker/Dockerfile.devenv Normal file
View File

@@ -0,0 +1,29 @@
FROM m.daocloud.io/docker.io/library/ubuntu:22.04
ENV LANG C.UTF-8
RUN sed -i s@http://.*archive.ubuntu.com@http://repo.huaweicloud.com@g /etc/apt/sources.list
RUN apt-get clean && apt-get update && apt-get install wget git curl unzip gcc pkg-config libssl-dev lld libdbus-1-dev libwayland-dev libwebkit2gtk-4.1-dev libxdo-dev -y
# install protoc
RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v30.2/protoc-30.2-linux-x86_64.zip \
&& unzip protoc-30.2-linux-x86_64.zip -d protoc3 \
&& mv protoc3/bin/* /usr/local/bin/ && chmod +x /usr/local/bin/protoc && mv protoc3/include/* /usr/local/include/ && rm -rf protoc-30.2-linux-x86_64.zip protoc3
# install flatc
RUN wget https://github.com/google/flatbuffers/releases/download/v25.2.10/Linux.flatc.binary.g++-13.zip \
&& unzip Linux.flatc.binary.g++-13.zip \
&& mv flatc /usr/local/bin/ && chmod +x /usr/local/bin/flatc && rm -rf Linux.flatc.binary.g++-13.zip
# install rust
ENV RUSTUP_DIST_SERVER="https://rsproxy.cn"
ENV RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup"
RUN curl -o rustup-init.sh --proto '=https' --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh \
&& sh rustup-init.sh -y && rm -rf rustup-init.sh
COPY .docker/cargo.config.toml /root/.cargo/config.toml
WORKDIR /root/s3-rustfs
CMD [ "bash", "-c", "while true; do sleep 1; done" ]

View File

@@ -0,0 +1,35 @@
FROM m.daocloud.io/docker.io/library/rockylinux:9.3 AS builder
ENV LANG C.UTF-8
RUN sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.ustc.edu.cn/rocky|g' \
-i.bak \
/etc/yum.repos.d/rocky-extras.repo \
/etc/yum.repos.d/rocky.repo
RUN dnf makecache
RUN yum install wget git unzip gcc openssl-devel pkgconf-pkg-config -y
# install protoc
RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v30.2/protoc-30.2-linux-x86_64.zip \
&& unzip protoc-30.2-linux-x86_64.zip -d protoc3 \
&& mv protoc3/bin/* /usr/local/bin/ && chmod +x /usr/local/bin/protoc \
&& rm -rf protoc-30.2-linux-x86_64.zip protoc3
# install flatc
RUN wget https://github.com/google/flatbuffers/releases/download/v25.2.10/Linux.flatc.binary.g++-13.zip \
&& unzip Linux.flatc.binary.g++-13.zip \
&& mv flatc /usr/local/bin/ && chmod +x /usr/local/bin/flatc \
&& rm -rf Linux.flatc.binary.g++-13.zip
# install rust
ENV RUSTUP_DIST_SERVER="https://rsproxy.cn"
ENV RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup"
RUN curl -o rustup-init.sh --proto '=https' --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh \
&& sh rustup-init.sh -y && rm -rf rustup-init.sh
COPY .docker/cargo.config.toml /root/.cargo/config.toml
WORKDIR /root/s3-rustfs

View File

@@ -0,0 +1,22 @@
FROM vault:1.13
# Configure Vault for dev mode
ENV VAULT_DEV_ROOT_TOKEN_ID=rustfs-root-token
ENV VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200
# Install curl for health checks
USER root
RUN apk add --no-cache curl jq
# Copy the Vault initialization script
COPY vault-init.sh /usr/local/bin/vault-init.sh
RUN chmod +x /usr/local/bin/vault-init.sh
# Switch back to vault user
USER vault
# Expose Vault port
EXPOSE 8200
# Start Vault in dev mode and run the initialization script
ENTRYPOINT ["sh", "-c", "vault server -dev & sleep 5 && vault-init.sh"]

View File

@@ -0,0 +1,27 @@
FROM m.daocloud.io/docker.io/library/ubuntu:22.04
ENV LANG C.UTF-8
RUN sed -i s@http://.*archive.ubuntu.com@http://repo.huaweicloud.com@g /etc/apt/sources.list
RUN apt-get clean && apt-get update && apt-get install wget git curl unzip gcc pkg-config libssl-dev lld libdbus-1-dev libwayland-dev libwebkit2gtk-4.1-dev libxdo-dev -y
# install protoc
RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v30.2/protoc-30.2-linux-x86_64.zip \
&& unzip protoc-30.2-linux-x86_64.zip -d protoc3 \
&& mv protoc3/bin/* /usr/local/bin/ && chmod +x /usr/local/bin/protoc && mv protoc3/include/* /usr/local/include/ && rm -rf protoc-30.2-linux-x86_64.zip protoc3
# install flatc
RUN wget https://github.com/google/flatbuffers/releases/download/v25.2.10/Linux.flatc.binary.g++-13.zip \
&& unzip Linux.flatc.binary.g++-13.zip \
&& mv flatc /usr/local/bin/ && chmod +x /usr/local/bin/flatc && rm -rf Linux.flatc.binary.g++-13.zip
# install rust
ENV RUSTUP_DIST_SERVER="https://rsproxy.cn"
ENV RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup"
RUN curl -o rustup-init.sh --proto '=https' --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh \
&& sh rustup-init.sh -y && rm -rf rustup-init.sh
COPY .docker/cargo.config.toml /root/.cargo/config.toml
WORKDIR /root/s3-rustfs

View File

@@ -1,261 +0,0 @@
# RustFS Docker Images
This directory contains Docker configuration files and supporting infrastructure for building and running RustFS container images.
## 📁 Directory Structure
```
rustfs/
├── Dockerfile # Production image (Alpine + pre-built binaries)
├── Dockerfile.source # Development image (Debian + source build)
├── docker-buildx.sh # Multi-architecture build script
├── Makefile # Build automation with simplified commands
└── .docker/ # Supporting infrastructure
├── observability/ # Monitoring and observability configs
├── compose/ # Docker Compose configurations
├── mqtt/ # MQTT broker configs
└── openobserve-otel/ # OpenObserve + OpenTelemetry configs
```
## 🎯 Image Variants
### Core Images
| Image | Base OS | Build Method | Size | Use Case |
|-------|---------|--------------|------|----------|
| `production` (default) | Alpine 3.18 | GitHub Releases | Smallest | Production deployment |
| `source` | Debian Bookworm | Source build | Medium | Custom builds with cross-compilation |
| `dev` | Debian Bookworm | Development tools | Large | Interactive development |
## 🚀 Usage Examples
### Quick Start (Production)
```bash
# Default production image (Alpine + GitHub Releases)
docker run -p 9000:9000 rustfs/rustfs:latest
# Specific version
docker run -p 9000:9000 rustfs/rustfs:1.2.3
```
### Complete Tag Strategy Examples
```bash
# Stable Releases
docker run rustfs/rustfs:1.2.3 # Main version (production)
docker run rustfs/rustfs:1.2.3-production # Explicit production variant
docker run rustfs/rustfs:1.2.3-source # Source build variant
docker run rustfs/rustfs:latest # Latest stable
# Prerelease Versions
docker run rustfs/rustfs:1.3.0-alpha.2 # Specific alpha version
docker run rustfs/rustfs:alpha # Latest alpha
docker run rustfs/rustfs:beta # Latest beta
docker run rustfs/rustfs:rc # Latest release candidate
# Development Versions
docker run rustfs/rustfs:dev # Latest main branch development
docker run rustfs/rustfs:dev-13e4a0b # Specific commit
docker run rustfs/rustfs:dev-latest # Latest development
docker run rustfs/rustfs:main-latest # Main branch latest
```
### Development Environment
```bash
# Quick setup using Makefile (recommended)
make docker-dev-local # Build development image locally
make dev-env-start # Start development container
# Manual Docker commands
docker run -it -v $(pwd):/workspace -p 9000:9000 rustfs/rustfs:latest-dev
# Build from source locally
docker build -f Dockerfile.source -t rustfs:custom .
# Development with hot reload
docker-compose up rustfs-dev
```
## 🏗️ Build Arguments and Scripts
### Using Makefile Commands (Recommended)
The easiest way to build images using simplified commands:
```bash
# Development images (build from source)
make docker-dev-local # Build for local use (single arch)
make docker-dev # Build multi-arch (for CI/CD)
make docker-dev-push REGISTRY=xxx # Build and push to registry
# Production images (using pre-built binaries)
make docker-buildx # Build multi-arch production images
make docker-buildx-push # Build and push production images
make docker-buildx-version VERSION=v1.0.0 # Build specific version
# Development environment
make dev-env-start # Start development container
make dev-env-stop # Stop development container
make dev-env-restart # Restart development container
# Help
make help-docker # Show all Docker-related commands
```
### Using docker-buildx.sh (Advanced)
For direct script usage and advanced scenarios:
```bash
# Build latest version for all architectures
./docker-buildx.sh
# Build and push to registry
./docker-buildx.sh --push
# Build specific version
./docker-buildx.sh --release v1.2.3
# Build and push specific version
./docker-buildx.sh --release v1.2.3 --push
```
### Manual Docker Builds
All images support dynamic version selection:
```bash
# Build production image with latest release
docker build --build-arg RELEASE="latest" -t rustfs:latest .
# Build from source with specific target
docker build -f Dockerfile.source \
--build-arg TARGETPLATFORM="linux/amd64" \
-t rustfs:source .
# Development build
docker build -f Dockerfile.source -t rustfs:dev .
```
## 🔧 Binary Download Sources
### Unified GitHub Releases
The production image downloads from GitHub Releases for reliability and transparency:
-**production** → GitHub Releases API with automatic latest detection
-**Checksum verification** → SHA256SUMS validation when available
-**Multi-architecture** → Supports amd64 and arm64
### Source Build
The source variant compiles from source code with advanced features:
- 🔧 **Cross-compilation** → Supports multiple target platforms via `TARGETPLATFORM`
-**Build caching** → sccache for faster compilation
- 🎯 **Optimized builds** → Release optimizations with LTO and symbol stripping
## 📋 Architecture Support
All variants support multi-architecture builds:
- **linux/amd64** (x86_64)
- **linux/arm64** (aarch64)
Architecture is automatically detected during build using Docker's `TARGETARCH` build argument.
## 🔐 Security Features
- **Checksum Verification**: Production image verifies SHA256SUMS when available
- **Non-root User**: All images run as user `rustfs` (UID 1000)
- **Minimal Runtime**: Production image only includes necessary dependencies
- **Secure Defaults**: No hardcoded credentials or keys
## 🛠️ Development Workflow
### Quick Start with Makefile (Recommended)
```bash
# 1. Start development environment
make dev-env-start
# 2. Your development container is now running with:
# - Port 9000 exposed for RustFS
# - Port 9010 exposed for admin console
# - Current directory mounted as /workspace
# 3. Stop when done
make dev-env-stop
```
### Manual Development Setup
```bash
# Build development image from source
make docker-dev-local
# Or use traditional Docker commands
docker build -f Dockerfile.source -t rustfs:dev .
# Run with development tools
docker run -it -v $(pwd):/workspace -p 9000:9000 rustfs:dev bash
# Or use docker-compose for complex setups
docker-compose up rustfs-dev
```
### Common Development Tasks
```bash
# Build and test locally
make build # Build binary natively
make docker-dev-local # Build development Docker image
make test # Run tests
make fmt # Format code
make clippy # Run linter
# Get help
make help # General help
make help-docker # Docker-specific help
make help-build # Build-specific help
```
## 🚀 CI/CD Integration
The project uses GitHub Actions for automated multi-architecture Docker builds:
### Automated Builds
- **Tags**: Automatic builds triggered on version tags (e.g., `v1.2.3`)
- **Main Branch**: Development builds with `dev-latest` and `main-latest` tags
- **Pull Requests**: Test builds without registry push
### Build Variants
Each build creates three image variants:
- `rustfs/rustfs:v1.2.3` (production - Alpine-based)
- `rustfs/rustfs:v1.2.3-source` (source build - Debian-based)
- `rustfs/rustfs:v1.2.3-dev` (development - Debian-based with tools)
### Manual Builds
Trigger custom builds via GitHub Actions:
```bash
# Use workflow_dispatch to build specific versions
# Available options: latest, main-latest, dev-latest, v1.2.3, dev-abc123
```
## 📦 Supporting Infrastructure
The `.docker/` directory contains supporting configuration files:
- **observability/** - Prometheus, Grafana, OpenTelemetry configs
- **compose/** - Multi-service Docker Compose setups
- **mqtt/** - MQTT broker configurations
- **openobserve-otel/** - Log aggregation and tracing setup
See individual README files in each subdirectory for specific usage instructions.

13
.docker/cargo.config.toml Normal file
View File

@@ -0,0 +1,13 @@
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
replace-with = 'rsproxy-sparse'
[source.rsproxy]
registry = "https://rsproxy.cn/crates.io-index"
[registries.rsproxy]
index = "https://rsproxy.cn/crates.io-index"
[source.rsproxy-sparse]
registry = "sparse+https://rsproxy.cn/index/"
[net]
git-fetch-with-cli = true

View File

@@ -1,80 +0,0 @@
# Docker Compose Configurations
This directory contains specialized Docker Compose configurations for different use cases.
## 📁 Configuration Files
This directory contains specialized Docker Compose configurations and their associated Dockerfiles, keeping related files organized together.
### Main Configuration (Root Directory)
- **`../../docker-compose.yml`** - **Default Production Setup**
- Complete production-ready configuration
- Includes RustFS server + full observability stack
- Supports multiple profiles: `dev`, `observability`, `cache`, `proxy`
- Recommended for most users
### Specialized Configurations
- **`docker-compose.cluster.yaml`** - **Distributed Testing**
- 4-node cluster setup for testing distributed storage
- Uses local compiled binaries
- Simulates multi-node environment
- Ideal for development and cluster testing
- **`docker-compose.observability.yaml`** - **Observability Focus**
- Specialized setup for testing observability features
- Includes OpenTelemetry, Jaeger, Prometheus, Loki, Grafana
- Uses `../../Dockerfile.source` for builds
- Perfect for observability development
## 🚀 Usage Examples
### Production Setup
```bash
# Start main service
docker-compose up -d
# Start with development profile
docker-compose --profile dev up -d
# Start with full observability
docker-compose --profile observability up -d
```
### Cluster Testing
```bash
# Build and start 4-node cluster (run from project root)
cd .docker/compose
docker-compose -f docker-compose.cluster.yaml up -d
# Or run directly from project root
docker-compose -f .docker/compose/docker-compose.cluster.yaml up -d
```
### Observability Testing
```bash
# Start observability-focused environment (run from project root)
cd .docker/compose
docker-compose -f docker-compose.observability.yaml up -d
# Or run directly from project root
docker-compose -f .docker/compose/docker-compose.observability.yaml up -d
```
## 🔧 Configuration Overview
| Configuration | Nodes | Storage | Observability | Use Case |
|---------------|-------|---------|---------------|----------|
| **Main** | 1 | Volume mounts | Full stack | Production |
| **Cluster** | 4 | HTTP endpoints | Basic | Testing |
| **Observability** | 4 | Local data | Advanced | Development |
## 📝 Notes
- Always ensure you have built the required binaries before starting cluster tests
- The main configuration is sufficient for most use cases
- Specialized configurations are for specific testing scenarios

View File

@@ -1,82 +0,0 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services:
node0:
image: rustfs/rustfs:latest # Replace with your image name and label
container_name: node0
hostname: node0
environment:
- RUSTFS_VOLUMES=http://node{0...3}:9000/data/rustfs{0...3}
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_CONSOLE_ENABLE=true
- RUSTFS_ACCESS_KEY=rustfsadmin
- RUSTFS_SECRET_KEY=rustfsadmin
platform: linux/amd64
ports:
- "9000:9000" # Map port 9001 of the host to port 9000 of the container
volumes:
- ../../target/x86_64-unknown-linux-gnu/release/rustfs:/app/rustfs
command: "/app/rustfs"
node1:
image: rustfs/rustfs:latest
container_name: node1
hostname: node1
environment:
- RUSTFS_VOLUMES=http://node{0...3}:9000/data/rustfs{0...3}
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_CONSOLE_ENABLE=true
- RUSTFS_ACCESS_KEY=rustfsadmin
- RUSTFS_SECRET_KEY=rustfsadmin
platform: linux/amd64
ports:
- "9001:9000" # Map port 9002 of the host to port 9000 of the container
volumes:
- ../../target/x86_64-unknown-linux-gnu/release/rustfs:/app/rustfs
command: "/app/rustfs"
node2:
image: rustfs/rustfs:latest
container_name: node2
hostname: node2
environment:
- RUSTFS_VOLUMES=http://node{0...3}:9000/data/rustfs{0...3}
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_CONSOLE_ENABLE=true
- RUSTFS_ACCESS_KEY=rustfsadmin
- RUSTFS_SECRET_KEY=rustfsadmin
platform: linux/amd64
ports:
- "9002:9000" # Map port 9003 of the host to port 9000 of the container
volumes:
- ../../target/x86_64-unknown-linux-gnu/release/rustfs:/app/rustfs
command: "/app/rustfs"
node3:
image: rustfs/rustfs:latest
container_name: node3
hostname: node3
environment:
- RUSTFS_VOLUMES=http://node{0...3}:9000/data/rustfs{0...3}
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_CONSOLE_ENABLE=true
- RUSTFS_ACCESS_KEY=rustfsadmin
- RUSTFS_SECRET_KEY=rustfsadmin
platform: linux/amd64
ports:
- "9003:9000" # Map port 9004 of the host to port 9000 of the container
volumes:
- ../../target/x86_64-unknown-linux-gnu/release/rustfs:/app/rustfs
command: "/app/rustfs"

View File

@@ -0,0 +1,26 @@
services:
rustyvault:
build:
context: ./.docker
dockerfile: Dockerfile.rustyvault
container_name: rustyvault
hostname: rustyvault
ports:
- "8200:8200" # Vault API port
volumes:
- vault-data:/vault/data
- vault-config:/vault/config
cap_add:
- IPC_LOCK # Allow the vault to lock sensitive data in memory
environment:
- VAULT_DEV_ROOT_TOKEN_ID=rustfs-root-token
- VAULT_ADDR=http://0.0.0.0:8200
healthcheck:
test: ["CMD", "curl", "-s", "http://127.0.0.1:8200/v1/sys/health"]
interval: 10s
timeout: 5s
retries: 3
networks:
default:
driver: bridge

View File

@@ -1,37 +0,0 @@
# 节点配置
node.name = "emqx@127.0.0.1"
node.cookie = "aBcDeFgHiJkLmNoPqRsTuVwXyZ012345"
node.data_dir = "/opt/emqx/data"
# 日志配置
log.console = {level = info, enable = true}
log.file = {path = "/opt/emqx/log/emqx.log", enable = true, level = info}
# MQTT TCP 监听器
listeners.tcp.default = {bind = "0.0.0.0:1883", max_connections = 1000000, enable = true}
# MQTT SSL 监听器
listeners.ssl.default = {bind = "0.0.0.0:8883", enable = false}
# MQTT WebSocket 监听器
listeners.ws.default = {bind = "0.0.0.0:8083", enable = true}
# MQTT WebSocket SSL 监听器
listeners.wss.default = {bind = "0.0.0.0:8084", enable = false}
# 管理控制台
dashboard.listeners.http = {bind = "0.0.0.0:18083", enable = true}
# HTTP API
management.listeners.http = {bind = "0.0.0.0:8081", enable = true}
# 认证配置
authentication = [
{enable = true, mechanism = password_based, backend = built_in_database, user_id_type = username}
]
# 授权配置
authorization.sources = [{type = built_in_database, enable = true}]
# 持久化消息存储
message.storage.backend = built_in_database

View File

@@ -1,9 +0,0 @@
-name emqx@127.0.0.1
-setcookie aBcDeFgHiJkLmNoPqRsTuVwXyZ012345
+P 2097152
+t 1048576
+zdbbl 32768
-kernel inet_dist_listen_min 6000
-kernel inet_dist_listen_max 6100
-smp enable
-mnesia dir "/opt/emqx/data/mnesia"

View File

@@ -1,74 +0,0 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services:
emqx:
image: emqx/emqx:latest
container_name: emqx
restart: unless-stopped
environment:
- EMQX_NODE__NAME=emqx@127.0.0.1
- EMQX_NODE__COOKIE=aBcDeFgHiJkLmNoPqRsTuVwXyZ012345
- EMQX_NODE__DATA_DIR=/opt/emqx/data
- EMQX_LOG__CONSOLE__LEVEL=info
- EMQX_LOG__CONSOLE__ENABLE=true
- EMQX_LOG__FILE__PATH=/opt/emqx/log/emqx.log
- EMQX_LOG__FILE__LEVEL=info
- EMQX_LOG__FILE__ENABLE=true
- EMQX_LISTENERS__TCP__DEFAULT__BIND=0.0.0.0:1883
- EMQX_LISTENERS__TCP__DEFAULT__MAX_CONNECTIONS=1000000
- EMQX_LISTENERS__TCP__DEFAULT__ENABLE=true
- EMQX_LISTENERS__SSL__DEFAULT__BIND=0.0.0.0:8883
- EMQX_LISTENERS__SSL__DEFAULT__ENABLE=false
- EMQX_LISTENERS__WS__DEFAULT__BIND=0.0.0.0:8083
- EMQX_LISTENERS__WS__DEFAULT__ENABLE=true
- EMQX_LISTENERS__WSS__DEFAULT__BIND=0.0.0.0:8084
- EMQX_LISTENERS__WSS__DEFAULT__ENABLE=false
- EMQX_DASHBOARD__LISTENERS__HTTP__BIND=0.0.0.0:18083
- EMQX_DASHBOARD__LISTENERS__HTTP__ENABLE=true
- EMQX_MANAGEMENT__LISTENERS__HTTP__BIND=0.0.0.0:8081
- EMQX_MANAGEMENT__LISTENERS__HTTP__ENABLE=true
- EMQX_AUTHENTICATION__1__ENABLE=true
- EMQX_AUTHENTICATION__1__MECHANISM=password_based
- EMQX_AUTHENTICATION__1__BACKEND=built_in_database
- EMQX_AUTHENTICATION__1__USER_ID_TYPE=username
- EMQX_AUTHORIZATION__SOURCES__1__TYPE=built_in_database
- EMQX_AUTHORIZATION__SOURCES__1__ENABLE=true
ports:
- "1883:1883" # MQTT TCP
- "8883:8883" # MQTT SSL
- "8083:8083" # MQTT WebSocket
- "8084:8084" # MQTT WebSocket SSL
- "18083:18083" # Web 管理控制台
- "8081:8081" # HTTP API
volumes:
- ./data:/opt/emqx/data
- ./log:/opt/emqx/log
- ./config:/opt/emqx/etc
networks:
- mqtt-net
healthcheck:
test: [ "CMD", "/opt/emqx/bin/emqx_ctl", "status" ]
interval: 30s
timeout: 10s
retries: 3
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "3"
networks:
mqtt-net:
driver: bridge

View File

@@ -1,29 +0,0 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services:
emqx:
image: emqx/emqx:latest
container_name: emqx
ports:
- "1883:1883"
- "8083:8083"
- "8084:8084"
- "8883:8883"
- "18083:18083"
restart: unless-stopped
networks:
default:
driver: bridge

View File

@@ -22,6 +22,21 @@ docker compose -f docker-compose.yml up -d
## 配置可观测性 ## 配置可观测性
```shell ### 创建配置文件
export RUSTFS_OBS_ENDPOINT="http://localhost:4317" # OpenTelemetry Collector 地址
1. 进入 `deploy/config` 目录
2. 复制示例配置:`cp obs.toml.example obs.toml`
3. 编辑 `obs.toml` 配置文件,修改以下关键参数:
| 配置项 | 说明 | 示例值 |
|-----------------|----------------------------|-----------------------|
| endpoint | OpenTelemetry Collector 地址 | http://localhost:4317 |
| service_name | 服务名称 | rustfs |
| service_version | 服务版本 | 1.0.0 |
| environment | 运行环境 | production |
| meter_interval | 指标导出间隔 (秒) | 30 |
| sample_ratio | 采样率 | 1.0 |
| use_stdout | 是否输出到控制台 | true/false |
| logger_level | 日志级别 | info |
``` ```

View File

@@ -0,0 +1,34 @@
[observability]
endpoint = "http://otel-collector:4317" # Default is "http://localhost:4317" if not specified
use_stdout = false # Output with stdout, true output, false no output
sample_ratio = 2.0
meter_interval = 30
service_name = "rustfs"
service_version = "0.1.0"
environments = "production"
logger_level = "debug"
local_logging_enabled = true
#[[sinks]]
#type = "Kafka"
#brokers = "localhost:9092"
#topic = "logs"
#batch_size = 100 # Default is 100 if not specified
#batch_timeout_ms = 1000 # Default is 1000ms if not specified
#
#[[sinks]]
#type = "Webhook"
#endpoint = "http://localhost:8080/webhook"
#auth_token = ""
#batch_size = 100 # Default is 3 if not specified
#batch_timeout_ms = 1000 # Default is 100ms if not specified
[[sinks]]
type = "File"
path = "/root/data/logs/rustfs.log"
buffer_size = 100 # Default is 8192 bytes if not specified
flush_interval_ms = 1000
flush_threshold = 100
[logger]
queue_capacity = 10

View File

@@ -0,0 +1,34 @@
[observability]
endpoint = "http://localhost:4317" # Default is "http://localhost:4317" if not specified
use_stdout = false # Output with stdout, true output, false no output
sample_ratio = 2.0
meter_interval = 30
service_name = "rustfs"
service_version = "0.1.0"
environments = "production"
logger_level = "debug"
local_logging_enabled = true
#[[sinks]]
#type = "Kafka"
#brokers = "localhost:9092"
#topic = "logs"
#batch_size = 100 # Default is 100 if not specified
#batch_timeout_ms = 1000 # Default is 1000ms if not specified
#
#[[sinks]]
#type = "Webhook"
#endpoint = "http://localhost:8080/webhook"
#auth_token = ""
#batch_size = 100 # Default is 3 if not specified
#batch_timeout_ms = 1000 # Default is 100ms if not specified
[[sinks]]
type = "File"
path = "/root/data/logs/rustfs.log"
buffer_size = 100 # Default is 8192 bytes if not specified
flush_interval_ms = 1000
flush_threshold = 100
[logger]
queue_capacity = 10

View File

@@ -1,178 +1,65 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services: services:
tempo-init:
image: busybox:latest
command: [ "sh", "-c", "chown -R 10001:10001 /var/tempo" ]
volumes:
- ./tempo-data:/var/tempo
user: root
networks:
- otel-network
restart: "no"
tempo:
image: grafana/tempo:latest
user: "10001" # The container must be started with root to execute chown in the script
command: [ "-config.file=/etc/tempo.yaml" ] # This is passed as a parameter to the entry point script
volumes:
- ./tempo.yaml:/etc/tempo.yaml:ro
- ./tempo-data:/var/tempo
ports:
- "3200:3200" # tempo
- "24317:4317" # otlp grpc
- "24318:4318" # otlp http
restart: unless-stopped
networks:
- otel-network
healthcheck:
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:3200/metrics" ]
interval: 10s
timeout: 5s
retries: 3
start_period: 15s
otel-collector: otel-collector:
image: otel/opentelemetry-collector-contrib:latest image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:0.127.0
environment: environment:
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
volumes: volumes:
- ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml:ro - ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
ports: ports:
- "1888:1888" # pprof - 1888:1888
- "8888:8888" # Prometheus metrics for Collector - 8888:8888
- "8889:8889" # Prometheus metrics for application indicators - 8889:8889
- "13133:13133" # health check - 13133:13133
- "4317:4317" # OTLP gRPC - 4317:4317
- "4318:4318" # OTLP HTTP - 4318:4318
- "55679:55679" # zpages - 55679:55679
networks: networks:
- otel-network - otel-network
depends_on:
jaeger:
condition: service_started
tempo:
condition: service_started
prometheus:
condition: service_started
loki:
condition: service_started
healthcheck:
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:13133" ]
interval: 10s
timeout: 5s
retries: 3
jaeger: jaeger:
image: jaegertracing/jaeger:latest image: jaegertracing/jaeger:2.6.0
environment: environment:
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
- SPAN_STORAGE_TYPE=memory
- COLLECTOR_OTLP_ENABLED=true
ports: ports:
- "16686:16686" # Web UI - "16686:16686"
- "14317:4317" # OTLP gRPC - "14317:4317"
- "14318:4318" # OTLP HTTP - "14318:4318"
- "18888:8888" # collector
networks: networks:
- otel-network - otel-network
healthcheck:
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:16686" ]
interval: 10s
timeout: 5s
retries: 3
prometheus: prometheus:
image: prom/prometheus:latest image: prom/prometheus:v3.4.1
environment: environment:
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
volumes: volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./prometheus.yml:/etc/prometheus/prometheus.yml
- ./prometheus-data:/prometheus
ports: ports:
- "9090:9090" - "9090:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--web.enable-otlp-receiver' # Enable OTLP
- '--web.enable-remote-write-receiver' # Enable remote write
- '--enable-feature=promql-experimental-functions' # Enable info()
- '--storage.tsdb.min-block-duration=15m' # Minimum block duration
- '--storage.tsdb.max-block-duration=1h' # Maximum block duration
- '--log.level=info'
- '--storage.tsdb.retention.time=30d'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
restart: unless-stopped
networks: networks:
- otel-network - otel-network
healthcheck:
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:9090/-/healthy" ]
interval: 10s
timeout: 5s
retries: 3
loki: loki:
image: grafana/loki:latest image: grafana/loki:3.5.1
environment: environment:
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
volumes: volumes:
- ./loki-config.yaml:/etc/loki/local-config.yaml:ro - ./loki-config.yaml:/etc/loki/local-config.yaml
ports: ports:
- "3100:3100" - "3100:3100"
command: -config.file=/etc/loki/local-config.yaml command: -config.file=/etc/loki/local-config.yaml
networks: networks:
- otel-network - otel-network
healthcheck:
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:3100/ready" ]
interval: 10s
timeout: 5s
retries: 3
grafana: grafana:
image: grafana/grafana:latest image: grafana/grafana:12.0.1
ports: ports:
- "3000:3000" # Web UI - "3000:3000" # Web UI
volumes:
- ./grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
environment: environment:
- GF_SECURITY_ADMIN_PASSWORD=admin - GF_SECURITY_ADMIN_PASSWORD=admin
- GF_SECURITY_ADMIN_USER=admin
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
- GF_INSTALL_PLUGINS=grafana-pyroscope-datasource
restart: unless-stopped
networks: networks:
- otel-network - otel-network
depends_on:
- prometheus
- tempo
- loki
healthcheck:
test: [ "CMD", "wget", "--spider", "-q", "http://localhost:3000/api/health" ]
interval: 10s
timeout: 5s
retries: 3
volumes:
prometheus-data:
tempo-data:
networks: networks:
otel-network: otel-network:
driver: bridge driver: bridge
name: "network_otel_config" name: "network_otel_config"
ipam:
config:
- subnet: 172.28.0.0/16
driver_opts: driver_opts:
com.docker.network.enable_ipv6: "true" com.docker.network.enable_ipv6: "true"

View File

@@ -1,108 +0,0 @@
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
uid: prometheus
access: proxy
orgId: 1
url: http://prometheus:9090
basicAuth: false
isDefault: false
version: 1
editable: false
jsonData:
httpMethod: GET
- name: Tempo
type: tempo
access: proxy
orgId: 1
url: http://tempo:3200
basicAuth: false
isDefault: true
version: 1
editable: false
apiVersion: 1
uid: tempo
jsonData:
httpMethod: GET
serviceMap:
datasourceUid: prometheus
streamingEnabled:
search: true
tracesToLogsV2:
# Field with an internal link pointing to a logs data source in Grafana.
# datasourceUid value must match the uid value of the logs data source.
datasourceUid: 'loki'
spanStartTimeShift: '-1h'
spanEndTimeShift: '1h'
tags: [ 'job', 'instance', 'pod', 'namespace' ]
filterByTraceID: false
filterBySpanID: false
customQuery: true
query: 'method="$${__span.tags.method}"'
tracesToMetrics:
datasourceUid: 'prometheus'
spanStartTimeShift: '-1h'
spanEndTimeShift: '1h'
tags: [ { key: 'service.name', value: 'service' }, { key: 'job' } ]
queries:
- name: 'Sample query'
query: 'sum(rate(traces_spanmetrics_latency_bucket{$$__tags}[5m]))'
tracesToProfiles:
datasourceUid: 'grafana-pyroscope-datasource'
tags: [ 'job', 'instance', 'pod', 'namespace' ]
profileTypeId: 'process_cpu:cpu:nanoseconds:cpu:nanoseconds'
customQuery: true
query: 'method="$${__span.tags.method}"'
serviceMap:
datasourceUid: 'prometheus'
nodeGraph:
enabled: true
search:
hide: false
traceQuery:
timeShiftEnabled: true
spanStartTimeShift: '-1h'
spanEndTimeShift: '1h'
spanBar:
type: 'Tag'
tag: 'http.path'
streamingEnabled:
search: true
- name: Jaeger
type: jaeger
uid: Jaeger
url: http://jaeger:16686
basicAuth: false
access: proxy
readOnly: false
isDefault: false
jsonData:
tracesToLogsV2:
# Field with an internal link pointing to a logs data source in Grafana.
# datasourceUid value must match the uid value of the logs data source.
datasourceUid: 'loki'
spanStartTimeShift: '1h'
spanEndTimeShift: '-1h'
tags: [ 'job', 'instance', 'pod', 'namespace' ]
filterByTraceID: false
filterBySpanID: false
customQuery: true
query: 'method="$${__span.tags.method}"'
tracesToMetrics:
datasourceUid: 'Prometheus'
spanStartTimeShift: '1h'
spanEndTimeShift: '-1h'
tags: [ { key: 'service.name', value: 'service' }, { key: 'job' } ]
queries:
- name: 'Sample query'
query: 'sum(rate(traces_spanmetrics_latency_bucket{$$__tags}[5m]))'
nodeGraph:
enabled: true
traceQuery:
timeShiftEnabled: true
spanStartTimeShift: '1h'
spanEndTimeShift: '-1h'
spanBar:
type: 'None'

View File

@@ -1,17 +1,3 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
service: service:
extensions: [ jaeger_storage, jaeger_query, remote_sampling, healthcheckv2 ] extensions: [ jaeger_storage, jaeger_query, remote_sampling, healthcheckv2 ]
pipelines: pipelines:
@@ -64,11 +50,10 @@ extensions:
backends: backends:
some_store: some_store:
memory: memory:
max_traces: 1000000 max_traces: 100000
max_events: 100000
another_store: another_store:
memory: memory:
max_traces: 1000000 max_traces: 100000
metric_backends: metric_backends:
some_metrics_storage: some_metrics_storage:
prometheus: prometheus:
@@ -103,7 +88,6 @@ receivers:
processors: processors:
batch: batch:
metadata_keys: [ "span.kind", "http.method", "http.status_code", "db.system", "db.statement", "messaging.system", "messaging.destination", "messaging.operation","span.events","span.links" ]
# Adaptive Sampling Processor is required to support adaptive sampling. # Adaptive Sampling Processor is required to support adaptive sampling.
# It expects remote_sampling extension with `adaptive:` config to be enabled. # It expects remote_sampling extension with `adaptive:` config to be enabled.
adaptive_sampling: adaptive_sampling:

View File

@@ -1,17 +1,3 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
auth_enabled: false auth_enabled: false
server: server:
@@ -41,9 +27,6 @@ query_range:
limits_config: limits_config:
metric_aggregation_enabled: true metric_aggregation_enabled: true
max_line_size: 256KB
max_line_size_truncate: false
allow_structured_metadata: true
schema_config: schema_config:
configs: configs:
@@ -54,7 +37,6 @@ schema_config:
index: index:
prefix: index_ prefix: index_
period: 24h period: 24h
row_shards: 16
pattern_ingester: pattern_ingester:
enabled: true enabled: true
@@ -67,7 +49,6 @@ ruler:
frontend: frontend:
encoding: protobuf encoding: protobuf
# By default, Loki will send anonymous, but uniquely-identifiable usage and configuration # By default, Loki will send anonymous, but uniquely-identifiable usage and configuration
# analytics to Grafana Labs. These statistics are sent to https://stats.grafana.org/ # analytics to Grafana Labs. These statistics are sent to https://stats.grafana.org/
# #

View File

@@ -1,122 +1,57 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
receivers: receivers:
otlp: otlp:
protocols: protocols:
grpc: # OTLP gRPC receiver grpc: # OTLP gRPC 接收器
endpoint: 0.0.0.0:4317 endpoint: 0.0.0.0:4317
http: # OTLP HTTP receiver http: # OTLP HTTP 接收器
endpoint: 0.0.0.0:4318 endpoint: 0.0.0.0:4318
processors: processors:
batch: # Batch processor to improve throughput batch: # 批处理处理器,提升吞吐量
timeout: 5s timeout: 5s
send_batch_size: 1000 send_batch_size: 1000
metadata_keys: [ ]
metadata_cardinality_limit: 1000
memory_limiter: memory_limiter:
check_interval: 1s check_interval: 1s
limit_mib: 512 limit_mib: 512
transform/logs:
log_statements:
- context: log
statements:
# Extract Body as attribute "message"
- set(attributes["message"], body.string)
# Retain the original Body
- set(attributes["log.body"], body.string)
exporters: exporters:
otlp/traces: # OTLP exporter for trace data otlp/traces: # OTLP 导出器,用于跟踪数据
endpoint: "http://jaeger:4317" # OTLP gRPC endpoint for Jaeger endpoint: "jaeger:4317" # Jaeger 的 OTLP gRPC 端点
tls: tls:
insecure: true # TLS is disabled in the development environment and a certificate needs to be configured in the production environment. insecure: true # 开发环境禁用 TLS生产环境需配置证书
compression: gzip # Enable compression to reduce network bandwidth prometheus: # Prometheus 导出器,用于指标数据
retry_on_failure: endpoint: "0.0.0.0:8889" # Prometheus 刮取端点
enabled: true # Enable retry on failure namespace: "rustfs" # 指标前缀
initial_interval: 1s # Initial interval for retry send_timestamps: true # 发送时间戳
max_interval: 30s # Maximum interval for retry # enable_open_metrics: true
max_elapsed_time: 300s # Maximum elapsed time for retry loki: # Loki 导出器,用于日志数据
sending_queue: # endpoint: "http://loki:3100/otlp/v1/logs"
enabled: true # Enable sending queue endpoint: "http://loki:3100/loki/api/v1/push"
num_consumers: 10 # Number of consumers
queue_size: 5000 # Queue size
otlp/tempo: # OTLP exporter for trace data
endpoint: "http://tempo:4317" # OTLP gRPC endpoint for tempo
tls:
insecure: true # TLS is disabled in the development environment and a certificate needs to be configured in the production environment.
compression: gzip # Enable compression to reduce network bandwidth
retry_on_failure:
enabled: true # Enable retry on failure
initial_interval: 1s # Initial interval for retry
max_interval: 30s # Maximum interval for retry
max_elapsed_time: 300s # Maximum elapsed time for retry
sending_queue:
enabled: true # Enable sending queue
num_consumers: 10 # Number of consumers
queue_size: 5000 # Queue size
prometheus: # Prometheus exporter for metrics data
endpoint: "0.0.0.0:8889" # Prometheus scraping endpoint
namespace: "metrics" # indicator prefix
send_timestamps: true # Send timestamp
metric_expiration: 5m # Metric expiration time
resource_to_telemetry_conversion:
enabled: true # Enable resource to telemetry conversion
otlphttp/loki: # Loki exporter for log data
endpoint: "http://loki:3100/otlp"
tls: tls:
insecure: true insecure: true
compression: gzip # Enable compression to reduce network bandwidth
extensions: extensions:
health_check: health_check:
endpoint: 0.0.0.0:13133
pprof: pprof:
endpoint: 0.0.0.0:1888
zpages: zpages:
endpoint: 0.0.0.0:55679
service: service:
extensions: [ health_check, pprof, zpages ] # Enable extension extensions: [ health_check, pprof, zpages ] # 启用扩展
pipelines: pipelines:
traces: traces:
receivers: [ otlp ] receivers: [ otlp ]
processors: [ memory_limiter, batch ] processors: [ memory_limiter,batch ]
exporters: [ otlp/traces, otlp/tempo ] exporters: [ otlp/traces ]
metrics: metrics:
receivers: [ otlp ] receivers: [ otlp ]
processors: [ batch ] processors: [ batch ]
exporters: [ prometheus ] exporters: [ prometheus ]
logs: logs:
receivers: [ otlp ] receivers: [ otlp ]
processors: [ batch, transform/logs ] processors: [ batch ]
exporters: [ otlphttp/loki ] exporters: [ loki ]
telemetry: telemetry:
logs: logs:
level: "debug" # Collector log level level: "info" # Collector 日志级别
encoding: "json" # Log encoding: console or json
metrics: metrics:
level: "detailed" # Can be basic, normal, detailed address: "0.0.0.0:8888" # Collector 自身指标暴露
readers:
- periodic:
exporter:
otlp:
protocol: http/protobuf
endpoint: http://otel-collector:4318
- pull:
exporter:
prometheus:
host: '0.0.0.0'
port: 8888

View File

@@ -1 +0,0 @@
*

View File

@@ -1,65 +1,11 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
global: global:
scrape_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. scrape_interval: 5s # 刮取间隔
evaluation_interval: 15s
external_labels:
cluster: 'rustfs-dev' # Label to identify the cluster
relica: '1' # Replica identifier
scrape_configs: scrape_configs:
- job_name: 'otel-collector-internal' - job_name: 'otel-collector'
static_configs: static_configs:
- targets: [ 'otel-collector:8888' ] # Scrape metrics from Collector - targets: ['otel-collector:8888'] # Collector 刮取指标
scrape_interval: 10s - job_name: 'otel-metrics'
- job_name: 'rustfs-app-metrics'
static_configs: static_configs:
- targets: [ 'otel-collector:8889' ] # Application indicators - targets: ['otel-collector:8889'] # 应用指标
scrape_interval: 15s
metric_relabel_configs:
- job_name: 'tempo'
static_configs:
- targets: [ 'tempo:3200' ] # Scrape metrics from Tempo
- job_name: 'jaeger'
static_configs:
- targets: [ 'jaeger:8888' ] # Jaeger admin port
otlp:
# Recommended attributes to be promoted to labels.
promote_resource_attributes:
- service.instance.id
- service.name
- service.namespace
- cloud.availability_zone
- cloud.region
- container.name
- deployment.environment.name
- k8s.cluster.name
- k8s.container.name
- k8s.cronjob.name
- k8s.daemonset.name
- k8s.deployment.name
- k8s.job.name
- k8s.namespace.name
- k8s.pod.name
- k8s.replicaset.name
- k8s.statefulset.name
# Ingest OTLP data keeping all characters in metric/label names.
translation_strategy: NoUTF8EscapingWithSuffixes
storage:
# OTLP is a push-based protocol, Out of order samples is a common scenario.
tsdb:
out_of_order_time_window: 30m

View File

@@ -1 +0,0 @@
*

View File

@@ -1,57 +0,0 @@
stream_over_http_enabled: true
server:
http_listen_port: 3200
log_level: info
query_frontend:
search:
duration_slo: 5s
throughput_bytes_slo: 1.073741824e+09
metadata_slo:
duration_slo: 5s
throughput_bytes_slo: 1.073741824e+09
trace_by_id:
duration_slo: 5s
distributor:
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
http:
endpoint: "0.0.0.0:4318"
ingester:
max_block_duration: 5m # cut the headblock when this much time passes. this is being set for demo purposes and should probably be left alone normally
compactor:
compaction:
block_retention: 1h # overall Tempo trace retention. set for demo purposes
metrics_generator:
registry:
external_labels:
source: tempo
cluster: docker-compose
storage:
path: /var/tempo/generator/wal
remote_write:
- url: http://prometheus:9090/api/v1/write
send_exemplars: true
traces_storage:
path: /var/tempo/generator/traces
storage:
trace:
backend: local # backend configuration to use
wal:
path: /var/tempo/wal # where to store the wal locally
local:
path: /var/tempo/blocks
overrides:
defaults:
metrics_generator:
processors: [ service-graphs, span-metrics, local-blocks ] # enables metrics generator
generate_native_histograms: both

View File

@@ -1,17 +1,3 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
services: services:
openobserve: openobserve:
image: public.ecr.aws/zinclabs/openobserve:latest image: public.ecr.aws/zinclabs/openobserve:latest

View File

@@ -1,17 +1,3 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
receivers: receivers:
otlp: otlp:
protocols: protocols:

71
.docker/vault-init.sh Normal file
View File

@@ -0,0 +1,71 @@
#!/bin/sh
# vault-init.sh - Initialize Vault for RustFS SSE-KMS
# Wait for Vault to start
until curl -s http://127.0.0.1:8200/v1/sys/health | grep "initialized" > /dev/null; do
echo "Waiting for Vault to start..."
sleep 1
done
# Set the Vault token
export VAULT_TOKEN="$VAULT_DEV_ROOT_TOKEN_ID"
export VAULT_ADDR="http://127.0.0.1:8200"
echo "Vault is running and initialized"
# Enable the Transit secrets engine (for encryption operations)
vault secrets enable transit
echo "Transit secrets engine enabled"
# Create a key for RustFS encryption
vault write -f transit/keys/rustfs-encryption-key
echo "Created rustfs-encryption-key"
# Create another key for RustFS with rotation capability
vault write -f transit/keys/rustfs-rotating-key
echo "Created rustfs-rotating-key"
# Set up key rotation policy
vault write transit/keys/rustfs-rotating-key/config auto_rotate_period="30d"
echo "Set up auto rotation for rustfs-rotating-key"
# Create a policy for RustFS to access these keys
cat > /tmp/rustfs-policy.hcl << EOF
# Policy for RustFS encryption operations
path "transit/encrypt/rustfs-encryption-key" {
capabilities = ["create", "update"]
}
path "transit/decrypt/rustfs-encryption-key" {
capabilities = ["create", "update"]
}
path "transit/encrypt/rustfs-rotating-key" {
capabilities = ["create", "update"]
}
path "transit/decrypt/rustfs-rotating-key" {
capabilities = ["create", "update"]
}
EOF
# Create the policy
vault policy write rustfs-encryption-policy /tmp/rustfs-policy.hcl
echo "Created rustfs-encryption-policy"
# Create a token for RustFS to use
RUSTFS_TOKEN=$(vault token create -policy=rustfs-encryption-policy -field=token)
echo "Created token for RustFS: $RUSTFS_TOKEN"
# Store the token for RustFS to use
echo "RUSTFS_KMS_VAULT_TOKEN=$RUSTFS_TOKEN" > /vault/config/rustfs-kms.env
echo "RUSTFS_KMS_VAULT_ENDPOINT=http://rustyvault:8200" >> /vault/config/rustfs-kms.env
echo "RUSTFS_KMS_VAULT_KEY_NAME=rustfs-encryption-key" >> /vault/config/rustfs-kms.env
echo "RustFS KMS configuration has been created"
echo "============================================"
echo "Vault is ready for use with RustFS SSE-KMS"
echo "============================================"
# Keep the container running
tail -f /dev/null

View File

@@ -1 +0,0 @@
target

1
.envrc
View File

@@ -1 +0,0 @@
use flake

View File

@@ -1,38 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,93 +1,54 @@
# Copyright 2024 RustFS Team name: "setup"
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: "Setup Rust Environment" description: "setup environment for rustfs"
description: "Setup Rust development environment with caching for RustFS"
inputs: inputs:
rust-version: rust-version:
description: "Rust version to install" required: true
required: false
default: "stable" default: "stable"
description: "Rust version to use"
cache-shared-key: cache-shared-key:
description: "Shared cache key for Rust dependencies" required: true
required: false default: ""
default: "rustfs-deps" description: "Cache key for shared cache"
cache-save-if: cache-save-if:
description: "Condition for saving cache" required: true
required: false default: true
default: "true" description: "Cache save condition"
install-cross-tools: run-os:
description: "Install cross-compilation tools" required: true
required: false default: "ubuntu-latest"
default: "false" description: "Running system"
target:
description: "Target architecture to add"
required: false
default: ""
github-token:
description: "GitHub token for API access"
required: false
default: ""
runs: runs:
using: "composite" using: "composite"
steps: steps:
- name: Install system dependencies (Ubuntu) - name: Install system dependencies
if: runner.os == 'Linux' if: inputs.run-os == 'ubuntu-latest'
shell: bash shell: bash
run: | run: |
sudo apt-get update sudo apt update
sudo apt-get install -y \ sudo apt install -y musl-tools build-essential lld libdbus-1-dev libwayland-dev libwebkit2gtk-4.1-dev libxdo-dev
musl-tools \
build-essential \
pkg-config \
libssl-dev
- name: Install protoc - uses: arduino/setup-protoc@v3
uses: arduino/setup-protoc@v3
with: with:
version: "33.1" version: "30.2"
repo-token: ${{ inputs.github-token }}
- name: Install flatc - uses: Nugine/setup-flatc@v1
uses: Nugine/setup-flatc@v1
with: with:
version: "25.9.23" version: "24.3.25"
- name: Install Rust toolchain - uses: dtolnay/rust-toolchain@master
uses: dtolnay/rust-toolchain@stable
with: with:
toolchain: ${{ inputs.rust-version }} toolchain: ${{ inputs.rust-version }}
targets: ${{ inputs.target }}
components: rustfmt, clippy components: rustfmt, clippy
- name: Install Zig - uses: Swatinem/rust-cache@v2
if: inputs.install-cross-tools == 'true'
uses: mlugg/setup-zig@v2
- name: Install cargo-zigbuild
if: inputs.install-cross-tools == 'true'
uses: taiki-e/install-action@cargo-zigbuild
- name: Install cargo-nextest
uses: taiki-e/install-action@cargo-nextest
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with: with:
cache-all-crates: true
cache-on-failure: true cache-on-failure: true
cache-all-crates: true
shared-key: ${{ inputs.cache-shared-key }} shared-key: ${{ inputs.cache-shared-key }}
save-if: ${{ inputs.cache-save-if }} save-if: ${{ inputs.cache-save-if }}
- uses: mlugg/setup-zig@v2
- uses: taiki-e/install-action@cargo-zigbuild

View File

@@ -1,17 +1,3 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# To get started with Dependabot version updates, you'll need to specify which # To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located. # package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options: # Please see the documentation for all configuration options:
@@ -22,18 +8,8 @@ updates:
- package-ecosystem: "cargo" # See documentation for possible values - package-ecosystem: "cargo" # See documentation for possible values
directory: "/" # Location of package manifests directory: "/" # Location of package manifests
schedule: schedule:
interval: "weekly" interval: "monthly"
day: "monday"
timezone: "Asia/Shanghai"
time: "08:00"
groups: groups:
s3s:
update-types:
- "minor"
- "patch"
patterns:
- "s3s"
- "s3s-*"
dependencies: dependencies:
patterns: patterns:
- "*" - "*"

View File

@@ -1,37 +0,0 @@
<!--
Pull Request Template for RustFS
-->
## Type of Change
- [ ] New Feature
- [ ] Bug Fix
- [ ] Documentation
- [ ] Performance Improvement
- [ ] Test/CI
- [ ] Refactor
- [ ] Other:
## Related Issues
<!-- List related Issue numbers, e.g. #123 -->
## Summary of Changes
<!-- Briefly describe the main changes and motivation for this PR -->
## Checklist
- [ ] I have read and followed the [CONTRIBUTING.md](CONTRIBUTING.md) guidelines
- [ ] Passed `make pre-commit`
- [ ] Added/updated necessary tests
- [ ] Documentation updated (if needed)
- [ ] CI/CD passed (if applicable)
## Impact
- [ ] Breaking change (compatibility)
- [ ] Requires doc/config/deployment update
- [ ] Other impact:
## Additional Notes
<!-- Any extra information for reviewers -->
---
Thank you for your contribution! Please ensure your PR follows the community standards ([CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)) and sign the CLA if this is your first contribution.

View File

@@ -1,103 +0,0 @@
# S3 Compatibility Tests Configuration
This directory contains the configuration for running [Ceph S3 compatibility tests](https://github.com/ceph/s3-tests) against RustFS.
## Configuration File
The `s3tests.conf` file is based on the official `s3tests.conf.SAMPLE` from the ceph/s3-tests repository. It uses environment variable substitution via `envsubst` to configure the endpoint and credentials.
### Key Configuration Points
- **Host**: Set via `${S3_HOST}` environment variable (e.g., `rustfs-single` for single-node, `lb` for multi-node)
- **Port**: 9000 (standard RustFS port)
- **Credentials**: Uses `${S3_ACCESS_KEY}` and `${S3_SECRET_KEY}` from workflow environment
- **TLS**: Disabled (`is_secure = False`)
## Test Execution Strategy
### Network Connectivity Fix
Tests run inside a Docker container on the `rustfs-net` network, which allows them to resolve and connect to the RustFS container hostnames. This fixes the "Temporary failure in name resolution" error that occurred when tests ran on the GitHub runner host.
### Performance Optimizations
1. **Parallel Execution**: Uses `pytest-xdist` with `-n 4` to run tests in parallel across 4 workers
2. **Load Distribution**: Uses `--dist=loadgroup` to distribute test groups across workers
3. **Fail-Fast**: Uses `--maxfail=50` to stop after 50 failures, saving time on catastrophic failures
### Feature Filtering
Tests are filtered using pytest markers (`-m`) to skip features not yet supported by RustFS:
- `lifecycle` - Bucket lifecycle policies
- `versioning` - Object versioning
- `s3website` - Static website hosting
- `bucket_logging` - Bucket logging
- `encryption` / `sse_s3` - Server-side encryption
- `cloud_transition` / `cloud_restore` - Cloud storage transitions
- `lifecycle_expiration` / `lifecycle_transition` - Lifecycle operations
This filtering:
1. Reduces test execution time significantly (from 1+ hour to ~10-15 minutes)
2. Focuses on features RustFS currently supports
3. Avoids hundreds of expected failures
## Running Tests Locally
### Single-Node Test
```bash
# Set credentials
export S3_ACCESS_KEY=rustfsadmin
export S3_SECRET_KEY=rustfsadmin
# Start RustFS container
docker run -d --name rustfs-single \
--network rustfs-net \
-e RUSTFS_ADDRESS=0.0.0.0:9000 \
-e RUSTFS_ACCESS_KEY=$S3_ACCESS_KEY \
-e RUSTFS_SECRET_KEY=$S3_SECRET_KEY \
-e RUSTFS_VOLUMES="/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3" \
rustfs-ci
# Generate config
export S3_HOST=rustfs-single
envsubst < .github/s3tests/s3tests.conf > /tmp/s3tests.conf
# Run tests
docker run --rm \
--network rustfs-net \
-v /tmp/s3tests.conf:/etc/s3tests.conf:ro \
python:3.12-slim \
bash -c '
apt-get update -qq && apt-get install -y -qq git
git clone --depth 1 https://github.com/ceph/s3-tests.git /s3-tests
cd /s3-tests
pip install -q -r requirements.txt pytest-xdist
S3TEST_CONF=/etc/s3tests.conf pytest -v -n 4 \
s3tests/functional/test_s3.py \
-m "not lifecycle and not versioning and not s3website and not bucket_logging and not encryption and not sse_s3"
'
```
## Test Results Interpretation
- **PASSED**: Test succeeded, feature works correctly
- **FAILED**: Test failed, indicates a potential bug or incompatibility
- **ERROR**: Test setup failed (e.g., network issues, missing dependencies)
- **SKIPPED**: Test skipped due to marker filtering
## Adding New Feature Support
When adding support for a new S3 feature to RustFS:
1. Remove the corresponding marker from the filter in `.github/workflows/e2e-s3tests.yml`
2. Run the tests to verify compatibility
3. Fix any failing tests
4. Update this README to reflect the newly supported feature
## References
- [Ceph S3 Tests Repository](https://github.com/ceph/s3-tests)
- [S3 API Compatibility](https://docs.aws.amazon.com/AmazonS3/latest/API/)
- [pytest-xdist Documentation](https://pytest-xdist.readthedocs.io/)

View File

@@ -1,185 +0,0 @@
# RustFS s3-tests configuration
# Based on: https://github.com/ceph/s3-tests/blob/master/s3tests.conf.SAMPLE
#
# Usage:
# Single-node: S3_HOST=rustfs-single envsubst < s3tests.conf > /tmp/s3tests.conf
# Multi-node: S3_HOST=lb envsubst < s3tests.conf > /tmp/s3tests.conf
[DEFAULT]
## this section is just used for host, port and bucket_prefix
# host set for RustFS - will be substituted via envsubst
host = ${S3_HOST}
# port for RustFS
port = 9000
## say "False" to disable TLS
is_secure = False
## say "False" to disable SSL Verify
ssl_verify = False
[fixtures]
## all the buckets created will start with this prefix;
## {random} will be filled with random characters to pad
## the prefix to 30 characters long, and avoid collisions
bucket prefix = rustfs-{random}-
# all the iam account resources (users, roles, etc) created
# will start with this name prefix
iam name prefix = s3-tests-
# all the iam account resources (users, roles, etc) created
# will start with this path prefix
iam path prefix = /s3-tests/
[s3 main]
# main display_name
display_name = RustFS Tester
# main user_id
user_id = rustfsadmin
# main email
email = tester@rustfs.local
# zonegroup api_name for bucket location
api_name = default
## main AWS access key
access_key = ${S3_ACCESS_KEY}
## main AWS secret key
secret_key = ${S3_SECRET_KEY}
## replace with key id obtained when secret is created, or delete if KMS not tested
#kms_keyid = 01234567-89ab-cdef-0123-456789abcdef
## Storage classes
#storage_classes = "LUKEWARM, FROZEN"
## Lifecycle debug interval (default: 10)
#lc_debug_interval = 20
## Restore debug interval (default: 100)
#rgw_restore_debug_interval = 60
#rgw_restore_processor_period = 60
[s3 alt]
# alt display_name
display_name = RustFS Alt Tester
## alt email
email = alt@rustfs.local
# alt user_id
user_id = rustfsalt
# alt AWS access key (must be different from s3 main for many tests)
access_key = ${S3_ALT_ACCESS_KEY}
# alt AWS secret key
secret_key = ${S3_ALT_SECRET_KEY}
#[s3 cloud]
## to run the testcases with "cloud_transition" for transition
## and "cloud_restore" for restore attribute.
## Note: the waiting time may have to tweaked depending on
## the I/O latency to the cloud endpoint.
## host set for cloud endpoint
# host = localhost
## port set for cloud endpoint
# port = 8001
## say "False" to disable TLS
# is_secure = False
## cloud endpoint credentials
# access_key = 0555b35654ad1656d804
# secret_key = h7GhxuBLTrlhVUyxSPUKUV8r/2EI4ngqJxD7iBdBYLhwluN30JaT3Q==
## storage class configured as cloud tier on local rgw server
# cloud_storage_class = CLOUDTIER
## Below are optional -
## Above configured cloud storage class config options
# retain_head_object = false
# allow_read_through = false # change it to enable read_through
# read_through_restore_days = 2
# target_storage_class = Target_SC
# target_path = cloud-bucket
## another regular storage class to test multiple transition rules,
# storage_class = S1
[s3 tenant]
# tenant display_name
display_name = RustFS Tenant Tester
# tenant user_id
user_id = rustfstenant
# tenant AWS access key
access_key = ${S3_ACCESS_KEY}
# tenant AWS secret key
secret_key = ${S3_SECRET_KEY}
# tenant email
email = tenant@rustfs.local
# tenant name
tenant = testx
#following section needs to be added for all sts-tests
[iam]
#used for iam operations in sts-tests
#email
email = s3@rustfs.local
#user_id
user_id = rustfsiam
#access_key
access_key = ${S3_ACCESS_KEY}
#secret_key
secret_key = ${S3_SECRET_KEY}
#display_name
display_name = RustFS IAM User
# iam account root user for iam_account tests
[iam root]
access_key = ${S3_ACCESS_KEY}
secret_key = ${S3_SECRET_KEY}
user_id = RGW11111111111111111
email = account1@rustfs.local
# iam account root user in a different account than [iam root]
[iam alt root]
access_key = ${S3_ACCESS_KEY}
secret_key = ${S3_SECRET_KEY}
user_id = RGW22222222222222222
email = account2@rustfs.local
#following section needs to be added when you want to run Assume Role With Webidentity test
[webidentity]
#used for assume role with web identity test in sts-tests
#all parameters will be obtained from ceph/qa/tasks/keycloak.py
#token=<access_token>
#aud=<obtained after introspecting token>
#sub=<obtained after introspecting token>
#azp=<obtained after introspecting token>
#user_token=<access token for a user, with attribute Department=[Engineering, Marketing>]
#thumbprint=<obtained from x509 certificate>
#KC_REALM=<name of the realm>

View File

@@ -1,81 +1,25 @@
# Copyright 2024 RustFS Team name: Audit
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Security Audit
on: on:
push: push:
branches: [ main ] branches:
- main
paths: paths:
- '**/Cargo.toml' - '**/Cargo.toml'
- '**/Cargo.lock' - '**/Cargo.lock'
- '.github/workflows/audit.yml'
pull_request: pull_request:
branches: [ main ] branches:
- main
paths: paths:
- '**/Cargo.toml' - '**/Cargo.toml'
- '**/Cargo.lock' - '**/Cargo.lock'
- '.github/workflows/audit.yml'
schedule: schedule:
- cron: '0 0 * * 0' # Weekly on Sunday at midnight UTC - cron: '0 0 * * 0' # at midnight of each sunday
workflow_dispatch:
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs: jobs:
security-audit: audit:
name: Security Audit runs-on: ubuntu-latest
runs-on: ubicloud-standard-4
timeout-minutes: 15
steps: steps:
- name: Checkout repository - uses: actions/checkout@v4
uses: actions/checkout@v6 - uses: taiki-e/install-action@cargo-audit
- run: cargo audit -D warnings
- name: Install cargo-audit
uses: taiki-e/install-action@v2
with:
tool: cargo-audit
- name: Run security audit
run: |
cargo audit -D warnings --json | tee audit-results.json
- name: Upload audit results
if: always()
uses: actions/upload-artifact@v4
with:
name: security-audit-results-${{ github.run_number }}
path: audit-results.json
retention-days: 30
dependency-review:
name: Dependency Review
runs-on: ubicloud-standard-4
if: github.event_name == 'pull_request'
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
fail-on-severity: moderate
comment-summary-in-pr: true

File diff suppressed because it is too large Load Diff

View File

@@ -1,182 +1,122 @@
# Copyright 2024 RustFS Team name: CI
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Continuous Integration
on: on:
push: push:
branches: [ main ] branches:
paths-ignore: - main
- "**.md"
- "**.txt"
- "docs/**"
- "deploy/**"
- "scripts/dev_*.sh"
- "scripts/probe.sh"
- "LICENSE*"
- ".gitignore"
- ".dockerignore"
- "README*"
- "**/*.png"
- "**/*.jpg"
- "**/*.svg"
- ".github/workflows/build.yml"
- ".github/workflows/docker.yml"
- ".github/workflows/audit.yml"
- ".github/workflows/performance.yml"
pull_request: pull_request:
branches: [ main ] branches:
paths-ignore: - main
- "**.md"
- "**.txt"
- "docs/**"
- "deploy/**"
- "scripts/dev_*.sh"
- "scripts/probe.sh"
- "LICENSE*"
- ".gitignore"
- ".dockerignore"
- "README*"
- "**/*.png"
- "**/*.jpg"
- "**/*.svg"
- ".github/workflows/build.yml"
- ".github/workflows/docker.yml"
- ".github/workflows/audit.yml"
- ".github/workflows/performance.yml"
schedule: schedule:
- cron: "0 0 * * 0" # Weekly on Sunday at midnight UTC - cron: '0 0 * * 0' # at midnight of each sunday
workflow_dispatch: workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
CARGO_BUILD_JOBS: 8
jobs: jobs:
skip-check: skip-check:
name: Skip Duplicate Actions
permissions: permissions:
actions: write actions: write
contents: read contents: read
runs-on: ubicloud-standard-4 runs-on: ubuntu-latest
outputs: outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }} should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps: steps:
- name: Skip duplicate actions - id: skip_check
id: skip_check
uses: fkirc/skip-duplicate-actions@v5 uses: fkirc/skip-duplicate-actions@v5
with: with:
concurrent_skipping: "same_content_newer" concurrent_skipping: 'same_content_newer'
cancel_others: true cancel_others: true
paths_ignore: '["*.md", "docs/**", "deploy/**"]' paths_ignore: '["*.md"]'
do_not_skip: '["workflow_dispatch", "schedule", "merge_group", "release", "push"]'
typos: # Quality checks for pull requests
name: Typos pr-checks:
runs-on: ubicloud-standard-4 name: Pull Request Quality Checks
if: github.event_name == 'pull_request'
runs-on: self-hosted
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable - uses: ./.github/actions/setup
- name: Typos check with custom config file
uses: crate-ci/typos@master
test-and-lint: - name: Format Check
name: Test and Lint
needs: skip-check
if: needs.skip-check.outputs.should_skip != 'true'
runs-on: ubicloud-standard-4
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Rust environment
uses: ./.github/actions/setup
with:
rust-version: stable
cache-shared-key: ci-test-${{ hashFiles('**/Cargo.lock') }}
github-token: ${{ secrets.GITHUB_TOKEN }}
cache-save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install cargo-nextest
uses: taiki-e/install-action@nextest
- name: Run tests
run: |
cargo nextest run --all --exclude e2e_test
cargo test --all --doc
- name: Check code formatting
run: cargo fmt --all --check run: cargo fmt --all --check
- name: Run clippy lints - name: Lint Check
run: cargo check --all-targets
- name: Clippy Check
run: cargo clippy --all-targets --all-features -- -D warnings run: cargo clippy --all-targets --all-features -- -D warnings
e2e-tests: - name: Unit Tests
name: End-to-End Tests run: cargo test --all --exclude e2e_test
develop:
needs: skip-check needs: skip-check
if: needs.skip-check.outputs.should_skip != 'true' if: needs.skip-check.outputs.should_skip != 'true'
runs-on: ubicloud-standard-4 runs-on: self-hosted
timeout-minutes: 30
steps: steps:
- name: Checkout repository - uses: actions/checkout@v4
uses: actions/checkout@v6 - uses: ./.github/actions/setup
- name: Clean up previous test run - name: Format
run: | run: cargo fmt --all --check
rm -rf /tmp/rustfs
rm -f /tmp/rustfs.log
- name: Setup Rust environment - name: Lint
uses: ./.github/actions/setup run: cargo check --all-targets
with:
rust-version: stable
cache-shared-key: ci-e2e-${{ hashFiles('**/Cargo.lock') }}
cache-save-if: ${{ github.ref == 'refs/heads/main' }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install s3s-e2e test tool - name: Clippy
uses: taiki-e/cache-cargo-install-action@v2 run: cargo clippy --all-targets --all-features -- -D warnings
with:
tool: s3s-e2e
git: https://github.com/Nugine/s3s.git
rev: b7714bfaa17ddfa9b23ea01774a1e7bbdbfc2ca3
- name: Build debug binary - name: Test
run: cargo test --all --exclude e2e_test
- name: Build debug
run: | run: |
touch rustfs/build.rs touch rustfs/build.rs
# Limit concurrency to prevent OOM cargo build -p rustfs --bins
cargo build -p rustfs --bins --jobs 4
- name: Run end-to-end tests - name: Pack artifacts
run: | run: |
s3s-e2e --version mkdir -p ./target/artifacts
./scripts/e2e-run.sh ./target/debug/rustfs /tmp/rustfs cp target/debug/rustfs ./target/artifacts/rustfs-debug
- name: Upload test logs - uses: actions/upload-artifact@v4
if: failure()
uses: actions/upload-artifact@v4
with: with:
name: e2e-test-logs-${{ github.run_number }} name: rustfs
path: ./target/artifacts/*
s3s-e2e:
name: E2E (s3s-e2e)
needs:
- skip-check
- develop
if: needs.skip-check.outputs.should_skip != 'true'
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
cache-all-crates: true
- name: Install s3s-e2e
run: |
cargo install s3s-e2e --git https://github.com/Nugine/s3s.git
s3s-e2e --version
- uses: actions/download-artifact@v4
with:
name: rustfs
path: ./target/artifacts
- name: Run s3s-e2e
timeout-minutes: 10
run: |
./scripts/e2e-run.sh ./target/artifacts/rustfs-debug /tmp/rustfs
- uses: actions/upload-artifact@v4
with:
name: s3s-e2e.logs
path: /tmp/rustfs.log path: /tmp/rustfs.log
retention-days: 3

View File

@@ -1,443 +0,0 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Docker Images Workflow
#
# This workflow builds Docker images using pre-built binaries from the build workflow.
#
# Trigger Types:
# 1. workflow_run: Automatically triggered when "Build and Release" workflow completes
# 2. workflow_dispatch: Manual trigger for standalone Docker builds
#
# Key Features:
# - Only triggers when Linux builds (x86_64 + aarch64) are successful
# - Independent of macOS/Windows build status
# - Uses workflow_run event for precise control
# - Only builds Docker images for releases and prereleases (development builds are skipped)
name: Docker Images
# Permissions needed for workflow_run event and Docker registry access
permissions:
contents: read
packages: write
on:
# Automatically triggered when build workflow completes
workflow_run:
workflows: [ "Build and Release" ]
types: [ completed ]
# Manual trigger with same parameters for consistency
workflow_dispatch:
inputs:
push_images:
description: "Push images to registries"
required: false
default: true
type: boolean
version:
description: "Version to build (latest for stable release, or specific version like v1.0.0, v1.0.0-alpha1)"
required: false
default: "latest"
type: string
force_rebuild:
description: "Force rebuild even if binary exists (useful for testing)"
required: false
default: false
type: boolean
env:
CONCLUSION: ${{ github.event.workflow_run.conclusion }}
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
TRIGGERING_EVENT: ${{ github.event.workflow_run.event }}
DOCKERHUB_USERNAME: rustfs
CARGO_TERM_COLOR: always
REGISTRY_DOCKERHUB: rustfs/rustfs
REGISTRY_GHCR: ghcr.io/${{ github.repository }}
DOCKER_PLATFORMS: linux/amd64,linux/arm64
jobs:
# Check if we should build Docker images
build-check:
name: Docker Build Check
runs-on: ubicloud-standard-4
outputs:
should_build: ${{ steps.check.outputs.should_build }}
should_push: ${{ steps.check.outputs.should_push }}
build_type: ${{ steps.check.outputs.build_type }}
version: ${{ steps.check.outputs.version }}
short_sha: ${{ steps.check.outputs.short_sha }}
is_prerelease: ${{ steps.check.outputs.is_prerelease }}
create_latest: ${{ steps.check.outputs.create_latest }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
# For workflow_run events, checkout the specific commit that triggered the workflow
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
- name: Check build conditions
id: check
run: |
should_build=false
should_push=false
build_type="none"
version=""
short_sha=""
is_prerelease=false
create_latest=false
if [[ "${{ github.event_name }}" == "workflow_run" ]]; then
# Triggered by build workflow completion
echo "🔗 Triggered by build workflow completion"
# Check if the triggering workflow was successful
# If the workflow succeeded, it means ALL builds (including Linux x86_64 and aarch64) succeeded
if [[ "$CONCLUSION" == "success" ]]; then
echo "✅ Build workflow succeeded, all builds including Linux are successful"
should_build=true
should_push=true
else
echo "❌ Build workflow failed (conclusion: $CONCLUSION), skipping Docker build"
should_build=false
fi
# Extract version info from commit message or use commit SHA
# Use Git to generate consistent short SHA (ensures uniqueness like build.yml)
short_sha=$(git rev-parse --short "$HEAD_SHA")
# Determine build type based on triggering workflow event and ref
triggering_event="$TRIGGERING_EVENT"
head_branch="$HEAD_BRANCH"
echo "🔍 Analyzing triggering workflow:"
echo " 📋 Event: $triggering_event"
echo " 🌿 Head branch: $head_branch"
echo " 📎 Head SHA: $HEAD_SHA"
# Check if this was triggered by a tag push
if [[ "$triggering_event" == "push" ]]; then
# For tag pushes, head_branch will be like "refs/tags/v1.0.0" or just "v1.0.0"
if [[ "$head_branch" == refs/tags/* ]]; then
# Extract tag name from refs/tags/TAG_NAME
tag_name="${head_branch#refs/tags/}"
version="$tag_name"
elif [[ "$head_branch" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+ ]]; then
# Direct tag name like "v1.0.0" or "1.0.0-alpha.1"
version="$head_branch"
elif [[ "$head_branch" == "main" ]]; then
# Regular branch push to main
build_type="development"
version="dev-${short_sha}"
should_build=false
echo "⏭️ Skipping Docker build for development version (main branch push)"
else
# Other branch push
build_type="development"
version="dev-${short_sha}"
should_build=false
echo "⏭️ Skipping Docker build for development version (branch: $head_branch)"
fi
# If we extracted a version (tag), determine release type
if [[ -n "$version" ]] && [[ "$version" != "dev-${short_sha}" ]]; then
# Remove 'v' prefix if present for consistent version format
if [[ "$version" == v* ]]; then
version="${version#v}"
fi
if [[ "$version" == *"alpha"* ]] || [[ "$version" == *"beta"* ]] || [[ "$version" == *"rc"* ]]; then
build_type="prerelease"
is_prerelease=true
# TODO: Temporary change - currently allows alpha versions to also create latest tags
# After the version is stable, you need to remove the following line and restore the original logic (latest is created only for stable versions)
if [[ "$version" == *"alpha"* ]]; then
create_latest=true
echo "🧪 Building Docker image for prerelease: $version (temporarily allowing creation of latest tag)"
else
echo "🧪 Building Docker image for prerelease: $version"
fi
else
build_type="release"
create_latest=true
echo "🚀 Building Docker image for release: $version"
fi
fi
else
# Non-push events
build_type="development"
version="dev-${short_sha}"
should_build=false
echo "⏭️ Skipping Docker build for development version (event: $triggering_event)"
fi
echo "🔄 Build triggered by workflow_run:"
echo " 📋 Conclusion: $CONCLUSION"
echo " 🌿 Branch: $HEAD_BRANCH"
echo " 📎 SHA: $HEAD_SHA"
echo " 🎯 Event: $TRIGGERING_EVENT"
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
# Manual trigger
input_version="${{ github.event.inputs.version }}"
version="${input_version}"
should_push="${{ github.event.inputs.push_images }}"
should_build=true
# Get short SHA
short_sha=$(git rev-parse --short HEAD)
echo "🎯 Manual Docker build triggered:"
echo " 📋 Requested version: $input_version"
echo " 🔧 Force rebuild: ${{ github.event.inputs.force_rebuild }}"
echo " 🚀 Push images: $should_push"
case "$input_version" in
"latest")
build_type="release"
create_latest=true
echo "🚀 Building with latest stable release version"
;;
# Prerelease versions (must match first, more specific)
v*alpha*|v*beta*|v*rc*|*alpha*|*beta*|*rc*)
build_type="prerelease"
is_prerelease=true
# TODO: Temporary change - currently allows alpha versions to also create latest tags
# After the version is stable, you need to remove the if block below and restore the original logic.
if [[ "$input_version" == *"alpha"* ]]; then
create_latest=true
echo "🧪 Building with prerelease version: $input_version (temporarily allowing creation of latest tag)"
else
echo "🧪 Building with prerelease version: $input_version"
fi
;;
# Release versions (match after prereleases, more general)
v[0-9]*|[0-9]*.*.*)
build_type="release"
create_latest=true
echo "📦 Building with specific release version: $input_version"
;;
*)
# Invalid version for Docker build
should_build=false
echo "❌ Invalid version for Docker build: $input_version"
echo "⚠️ Only release versions (latest, v1.0.0, 1.0.0) and prereleases (v1.0.0-alpha1, 1.0.0-beta2) are supported"
;;
esac
fi
echo "should_build=$should_build" >> $GITHUB_OUTPUT
echo "should_push=$should_push" >> $GITHUB_OUTPUT
echo "build_type=$build_type" >> $GITHUB_OUTPUT
echo "version=$version" >> $GITHUB_OUTPUT
echo "short_sha=$short_sha" >> $GITHUB_OUTPUT
echo "is_prerelease=$is_prerelease" >> $GITHUB_OUTPUT
echo "create_latest=$create_latest" >> $GITHUB_OUTPUT
echo "🐳 Docker Build Summary:"
echo " - Should build: $should_build"
echo " - Should push: $should_push"
echo " - Build type: $build_type"
echo " - Version: $version"
echo " - Short SHA: $short_sha"
echo " - Is prerelease: $is_prerelease"
echo " - Create latest: $create_latest"
# Build multi-arch Docker images
# Strategy: Build images using pre-built binaries from dl.rustfs.com
# Supports both release and dev channel binaries based on build context
# Only runs when should_build is true (which includes workflow success check)
build-docker:
name: Build Docker Images
needs: build-check
if: needs.build-check.outputs.should_build == 'true'
runs-on: ubicloud-standard-4
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ env.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# - name: Login to GitHub Container Registry
# uses: docker/login-action@v3
# with:
# registry: ghcr.io
# username: ${{ github.actor }}
# password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract metadata and generate tags
id: meta
run: |
BUILD_TYPE="${{ needs.build-check.outputs.build_type }}"
VERSION="${{ needs.build-check.outputs.version }}"
SHORT_SHA="${{ needs.build-check.outputs.short_sha }}"
CREATE_LATEST="${{ needs.build-check.outputs.create_latest }}"
# Convert version format for Dockerfile compatibility
case "$VERSION" in
"latest")
# For stable latest, use RELEASE=latest + release CHANNEL
DOCKER_RELEASE="latest"
DOCKER_CHANNEL="release"
;;
v*)
# For versioned releases (v1.0.0), remove 'v' prefix for Dockerfile
DOCKER_RELEASE="${VERSION#v}"
DOCKER_CHANNEL="release"
;;
*)
# For other versions, pass as-is
DOCKER_RELEASE="${VERSION}"
DOCKER_CHANNEL="release"
;;
esac
echo "docker_release=$DOCKER_RELEASE" >> $GITHUB_OUTPUT
echo "docker_channel=$DOCKER_CHANNEL" >> $GITHUB_OUTPUT
echo "🐳 Docker build parameters:"
echo " - Original version: $VERSION"
echo " - Docker RELEASE: $DOCKER_RELEASE"
echo " - Docker CHANNEL: $DOCKER_CHANNEL"
# Generate tags based on build type
# Only support release and prerelease builds (no development builds)
TAGS="${{ env.REGISTRY_DOCKERHUB }}:${VERSION}"
# Add channel tags for prereleases and latest for stable
if [[ "$CREATE_LATEST" == "true" ]]; then
# TODO: Temporary change - the current alpha version will also create the latest tag
# After the version is stabilized, the logic here remains unchanged, but the upstream CREATE_LATEST setting needs to be restored.
# Stable release (and temporary alpha versions)
TAGS="$TAGS,${{ env.REGISTRY_DOCKERHUB }}:latest"
elif [[ "$BUILD_TYPE" == "prerelease" ]]; then
# Prerelease channel tags (alpha, beta, rc)
if [[ "$VERSION" == *"alpha"* ]]; then
CHANNEL="alpha"
elif [[ "$VERSION" == *"beta"* ]]; then
CHANNEL="beta"
elif [[ "$VERSION" == *"rc"* ]]; then
CHANNEL="rc"
fi
if [[ -n "$CHANNEL" ]]; then
TAGS="$TAGS,${{ env.REGISTRY_DOCKERHUB }}:${CHANNEL}"
fi
fi
# Output tags
echo "tags=$TAGS" >> $GITHUB_OUTPUT
# Generate labels
LABELS="org.opencontainers.image.title=RustFS"
LABELS="$LABELS,org.opencontainers.image.description=RustFS distributed object storage system"
LABELS="$LABELS,org.opencontainers.image.version=$VERSION"
LABELS="$LABELS,org.opencontainers.image.revision=${{ github.sha }}"
LABELS="$LABELS,org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}"
LABELS="$LABELS,org.opencontainers.image.created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
LABELS="$LABELS,org.opencontainers.image.build-type=$BUILD_TYPE"
echo "labels=$LABELS" >> $GITHUB_OUTPUT
echo "🐳 Generated Docker tags:"
echo "$TAGS" | tr ',' '\n' | sed 's/^/ - /'
echo "📋 Build type: $BUILD_TYPE"
echo "🔖 Version: $VERSION"
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
platforms: ${{ env.DOCKER_PLATFORMS }}
push: ${{ needs.build-check.outputs.should_push == 'true' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: |
type=gha,scope=docker-binary
cache-to: |
type=gha,mode=max,scope=docker-binary
build-args: |
BUILDTIME=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
VERSION=${{ needs.build-check.outputs.version }}
BUILD_TYPE=${{ needs.build-check.outputs.build_type }}
REVISION=${{ github.sha }}
RELEASE=${{ steps.meta.outputs.docker_release }}
CHANNEL=${{ steps.meta.outputs.docker_channel }}
BUILDKIT_INLINE_CACHE=1
# Enable advanced BuildKit features for better performance
provenance: false
sbom: false
# Add retry mechanism by splitting the build process
no-cache: false
pull: true
# Note: Manifest creation is no longer needed as we only build one variant
# Multi-arch manifests are automatically created by docker/build-push-action
# Docker build summary
docker-summary:
name: Docker Build Summary
needs: [ build-check, build-docker ]
if: always() && needs.build-check.outputs.should_build == 'true'
runs-on: ubicloud-standard-4
steps:
- name: Docker build completion summary
run: |
BUILD_TYPE="${{ needs.build-check.outputs.build_type }}"
VERSION="${{ needs.build-check.outputs.version }}"
CREATE_LATEST="${{ needs.build-check.outputs.create_latest }}"
echo "🐳 Docker build completed successfully!"
echo "📦 Build type: $BUILD_TYPE"
echo "🔢 Version: $VERSION"
echo "🚀 Strategy: Images using pre-built binaries (release channel only)"
echo ""
case "$BUILD_TYPE" in
"release")
echo "🚀 Release Docker image has been built with ${VERSION} tags"
echo "✅ This image is ready for production use"
if [[ "$CREATE_LATEST" == "true" ]]; then
echo "🏷️ Latest tag has been created for stable release"
fi
;;
"prerelease")
echo "🧪 Prerelease Docker image has been built with ${VERSION} tags"
echo "⚠️ This is a prerelease image - use with caution"
# TODO: Temporary change - alpha versions currently create the latest tag
# After the version is stable, you need to restore the following prompt information
if [[ "$VERSION" == *"alpha"* ]] && [[ "$CREATE_LATEST" == "true" ]]; then
echo "🏷️ Latest tag has been created for alpha version (temporary measures)"
else
echo "🚫 Latest tag NOT created for prerelease"
fi
;;
*)
echo "❌ Unexpected build type: $BUILD_TYPE"
;;
esac

View File

@@ -1,260 +0,0 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: e2e-mint
on:
push:
branches: [ main ]
paths:
- ".github/workflows/e2e-mint.yml"
- "Dockerfile.source"
- "rustfs/**"
- "crates/**"
workflow_dispatch:
inputs:
run-multi:
description: "Run multi-node Mint as well"
required: false
default: "false"
env:
ACCESS_KEY: rustfsadmin
SECRET_KEY: rustfsadmin
RUST_LOG: info
PLATFORM: linux/amd64
jobs:
mint-single:
runs-on: ubicloud-standard-4
timeout-minutes: 40
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Enable buildx
uses: docker/setup-buildx-action@v3
- name: Build RustFS image (source)
run: |
DOCKER_BUILDKIT=1 docker buildx build --load \
--platform ${PLATFORM} \
-t rustfs-ci \
-f Dockerfile.source .
- name: Create network
run: |
docker network inspect rustfs-net >/dev/null 2>&1 || docker network create rustfs-net
- name: Remove existing rustfs-single (if any)
run: docker rm -f rustfs-single >/dev/null 2>&1 || true
- name: Start single RustFS
run: |
docker run -d --name rustfs-single \
--network rustfs-net \
-e RUSTFS_ADDRESS=0.0.0.0:9000 \
-e RUSTFS_ACCESS_KEY=$ACCESS_KEY \
-e RUSTFS_SECRET_KEY=$SECRET_KEY \
-e RUSTFS_VOLUMES="/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3" \
-v /tmp/rustfs-single:/data \
rustfs-ci
- name: Wait for RustFS ready
run: |
for i in {1..30}; do
if docker exec rustfs-single curl -sf http://localhost:9000/health >/dev/null; then
exit 0
fi
sleep 2
done
echo "RustFS did not become ready" >&2
docker logs rustfs-single || true
exit 1
- name: Run Mint (single, S3-only)
run: |
mkdir -p artifacts/mint-single
docker run --rm --network rustfs-net \
--platform ${PLATFORM} \
-e SERVER_ENDPOINT=rustfs-single:9000 \
-e ACCESS_KEY=$ACCESS_KEY \
-e SECRET_KEY=$SECRET_KEY \
-e ENABLE_HTTPS=0 \
-e SERVER_REGION=us-east-1 \
-e RUN_ON_FAIL=1 \
-e MINT_MODE=core \
-v ${GITHUB_WORKSPACE}/artifacts/mint-single:/mint/log \
--entrypoint /mint/mint.sh \
minio/mint:edge \
awscli aws-sdk-go aws-sdk-java-v2 aws-sdk-php aws-sdk-ruby s3cmd s3select
- name: Collect RustFS logs
run: |
mkdir -p artifacts/rustfs-single
docker logs rustfs-single > artifacts/rustfs-single/rustfs.log || true
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: mint-single
path: artifacts/**
mint-multi:
if: github.event_name == 'workflow_dispatch' && github.event.inputs.run-multi == 'true'
needs: mint-single
runs-on: ubicloud-standard-4
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Enable buildx
uses: docker/setup-buildx-action@v3
- name: Build RustFS image (source)
run: |
DOCKER_BUILDKIT=1 docker buildx build --load \
--platform ${PLATFORM} \
-t rustfs-ci \
-f Dockerfile.source .
- name: Prepare cluster compose
run: |
cat > compose.yml <<'EOF'
version: '3.8'
services:
rustfs1:
image: rustfs-ci
hostname: rustfs1
networks: [rustfs-net]
environment:
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_ACCESS_KEY=${ACCESS_KEY}
- RUSTFS_SECRET_KEY=${SECRET_KEY}
- RUSTFS_VOLUMES=/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3
volumes:
- rustfs1-data:/data
rustfs2:
image: rustfs-ci
hostname: rustfs2
networks: [rustfs-net]
environment:
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_ACCESS_KEY=${ACCESS_KEY}
- RUSTFS_SECRET_KEY=${SECRET_KEY}
- RUSTFS_VOLUMES=/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3
volumes:
- rustfs2-data:/data
rustfs3:
image: rustfs-ci
hostname: rustfs3
networks: [rustfs-net]
environment:
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_ACCESS_KEY=${ACCESS_KEY}
- RUSTFS_SECRET_KEY=${SECRET_KEY}
- RUSTFS_VOLUMES=/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3
volumes:
- rustfs3-data:/data
rustfs4:
image: rustfs-ci
hostname: rustfs4
networks: [rustfs-net]
environment:
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_ACCESS_KEY=${ACCESS_KEY}
- RUSTFS_SECRET_KEY=${SECRET_KEY}
- RUSTFS_VOLUMES=/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3
volumes:
- rustfs4-data:/data
lb:
image: haproxy:2.9
hostname: lb
networks: [rustfs-net]
ports:
- "9000:9000"
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
networks:
rustfs-net:
name: rustfs-net
volumes:
rustfs1-data:
rustfs2-data:
rustfs3-data:
rustfs4-data:
EOF
cat > haproxy.cfg <<'EOF'
defaults
mode http
timeout connect 5s
timeout client 30s
timeout server 30s
frontend fe_s3
bind *:9000
default_backend be_s3
backend be_s3
balance roundrobin
server s1 rustfs1:9000 check
server s2 rustfs2:9000 check
server s3 rustfs3:9000 check
server s4 rustfs4:9000 check
EOF
- name: Launch cluster
run: docker compose -f compose.yml up -d
- name: Wait for LB ready
run: |
for i in {1..60}; do
if docker run --rm --network rustfs-net curlimages/curl -sf http://lb:9000/health >/dev/null; then
exit 0
fi
sleep 2
done
echo "LB or backend not ready" >&2
docker compose -f compose.yml logs --tail=200 || true
exit 1
- name: Run Mint (multi, S3-only)
run: |
mkdir -p artifacts/mint-multi
docker run --rm --network rustfs-net \
--platform ${PLATFORM} \
-e SERVER_ENDPOINT=lb:9000 \
-e ACCESS_KEY=$ACCESS_KEY \
-e SECRET_KEY=$SECRET_KEY \
-e ENABLE_HTTPS=0 \
-e SERVER_REGION=us-east-1 \
-e RUN_ON_FAIL=1 \
-e MINT_MODE=core \
-v ${GITHUB_WORKSPACE}/artifacts/mint-multi:/mint/log \
--entrypoint /mint/mint.sh \
minio/mint:edge \
awscli aws-sdk-go aws-sdk-java-v2 aws-sdk-php aws-sdk-ruby s3cmd s3select
- name: Collect logs
run: |
mkdir -p artifacts/cluster
docker compose -f compose.yml logs --no-color > artifacts/cluster/cluster.log || true
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: mint-multi
path: artifacts/**

View File

@@ -1,422 +0,0 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: e2e-s3tests
on:
workflow_dispatch:
inputs:
test-mode:
description: "Test mode to run"
required: true
type: choice
default: "single"
options:
- single
- multi
xdist:
description: "Enable pytest-xdist (parallel). '0' to disable."
required: false
default: "0"
maxfail:
description: "Stop after N failures (debug friendly)"
required: false
default: "1"
markexpr:
description: "pytest -m expression (feature filters)"
required: false
default: "not lifecycle and not versioning and not s3website and not bucket_logging and not encryption"
env:
# main user
S3_ACCESS_KEY: rustfsadmin
S3_SECRET_KEY: rustfsadmin
# alt user (must be different from main for many s3-tests)
S3_ALT_ACCESS_KEY: rustfsalt
S3_ALT_SECRET_KEY: rustfsalt
S3_REGION: us-east-1
RUST_LOG: info
PLATFORM: linux/amd64
defaults:
run:
shell: bash
jobs:
s3tests-single:
if: github.event.inputs.test-mode == 'single'
runs-on: ubicloud-standard-4
timeout-minutes: 120
steps:
- uses: actions/checkout@v6
- name: Enable buildx
uses: docker/setup-buildx-action@v3
- name: Build RustFS image (source, cached)
run: |
DOCKER_BUILDKIT=1 docker buildx build --load \
--platform ${PLATFORM} \
--cache-from type=gha \
--cache-to type=gha,mode=max \
-t rustfs-ci \
-f Dockerfile.source .
- name: Create network
run: docker network inspect rustfs-net >/dev/null 2>&1 || docker network create rustfs-net
- name: Remove existing rustfs-single (if any)
run: docker rm -f rustfs-single >/dev/null 2>&1 || true
- name: Start single RustFS
run: |
docker run -d --name rustfs-single \
--network rustfs-net \
-p 9000:9000 \
-e RUSTFS_ADDRESS=0.0.0.0:9000 \
-e RUSTFS_ACCESS_KEY=$S3_ACCESS_KEY \
-e RUSTFS_SECRET_KEY=$S3_SECRET_KEY \
-e RUSTFS_VOLUMES="/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3" \
-v /tmp/rustfs-single:/data \
rustfs-ci
- name: Wait for RustFS ready
run: |
for i in {1..60}; do
if curl -sf http://127.0.0.1:9000/health >/dev/null 2>&1; then
echo "RustFS is ready"
exit 0
fi
if [ "$(docker inspect -f '{{.State.Running}}' rustfs-single 2>/dev/null)" != "true" ]; then
echo "RustFS container not running" >&2
docker logs rustfs-single || true
exit 1
fi
sleep 2
done
echo "Health check timed out" >&2
docker logs rustfs-single || true
exit 1
- name: Generate s3tests config
run: |
export S3_HOST=127.0.0.1
envsubst < .github/s3tests/s3tests.conf > s3tests.conf
- name: Provision s3-tests alt user (required by suite)
run: |
python3 -m pip install --user --upgrade pip awscurl
export PATH="$HOME/.local/bin:$PATH"
# Admin API requires AWS SigV4 signing. awscurl is used by RustFS codebase as well.
awscurl \
--service s3 \
--region "${S3_REGION}" \
--access_key "${S3_ACCESS_KEY}" \
--secret_key "${S3_SECRET_KEY}" \
-X PUT \
-H 'Content-Type: application/json' \
-d '{"secretKey":"'"${S3_ALT_SECRET_KEY}"'","status":"enabled","policy":"readwrite"}' \
"http://127.0.0.1:9000/rustfs/admin/v3/add-user?accessKey=${S3_ALT_ACCESS_KEY}"
# Explicitly attach built-in policy via policy mapping.
# s3-tests relies on alt client being able to ListBuckets during setup cleanup.
awscurl \
--service s3 \
--region "${S3_REGION}" \
--access_key "${S3_ACCESS_KEY}" \
--secret_key "${S3_SECRET_KEY}" \
-X PUT \
"http://127.0.0.1:9000/rustfs/admin/v3/set-user-or-group-policy?policyName=readwrite&userOrGroup=${S3_ALT_ACCESS_KEY}&isGroup=false"
# Sanity check: alt user can list buckets (should not be AccessDenied).
awscurl \
--service s3 \
--region "${S3_REGION}" \
--access_key "${S3_ALT_ACCESS_KEY}" \
--secret_key "${S3_ALT_SECRET_KEY}" \
-X GET \
"http://127.0.0.1:9000/" >/dev/null
- name: Prepare s3-tests
run: |
python3 -m pip install --user --upgrade pip tox
export PATH="$HOME/.local/bin:$PATH"
git clone --depth 1 https://github.com/ceph/s3-tests.git s3-tests
- name: Run ceph s3-tests (debug friendly)
run: |
export PATH="$HOME/.local/bin:$PATH"
mkdir -p artifacts/s3tests-single
cd s3-tests
set -o pipefail
MAXFAIL="${{ github.event.inputs.maxfail }}"
if [ -z "$MAXFAIL" ]; then MAXFAIL="1"; fi
MARKEXPR="${{ github.event.inputs.markexpr }}"
if [ -z "$MARKEXPR" ]; then MARKEXPR="not lifecycle and not versioning and not s3website and not bucket_logging and not encryption"; fi
XDIST="${{ github.event.inputs.xdist }}"
if [ -z "$XDIST" ]; then XDIST="0"; fi
XDIST_ARGS=""
if [ "$XDIST" != "0" ]; then
# Add pytest-xdist to requirements.txt so tox installs it inside
# its virtualenv. Installing outside tox does NOT work.
echo "pytest-xdist" >> requirements.txt
XDIST_ARGS="-n $XDIST --dist=loadgroup"
fi
# Run tests from s3tests/functional (boto2+boto3 combined directory).
S3TEST_CONF=${GITHUB_WORKSPACE}/s3tests.conf \
tox -- \
-vv -ra --showlocals --tb=long \
--maxfail="$MAXFAIL" \
--junitxml=${GITHUB_WORKSPACE}/artifacts/s3tests-single/junit.xml \
$XDIST_ARGS \
s3tests/functional/test_s3.py \
-m "$MARKEXPR" \
2>&1 | tee ${GITHUB_WORKSPACE}/artifacts/s3tests-single/pytest.log
- name: Collect RustFS logs
if: always()
run: |
mkdir -p artifacts/rustfs-single
docker logs rustfs-single > artifacts/rustfs-single/rustfs.log 2>&1 || true
docker inspect rustfs-single > artifacts/rustfs-single/inspect.json || true
- name: Upload artifacts
if: always() && env.ACT != 'true'
uses: actions/upload-artifact@v4
with:
name: s3tests-single
path: artifacts/**
s3tests-multi:
if: github.event_name == 'workflow_dispatch' && github.event.inputs.test-mode == 'multi'
runs-on: ubicloud-standard-4
timeout-minutes: 150
steps:
- uses: actions/checkout@v6
- name: Enable buildx
uses: docker/setup-buildx-action@v3
- name: Build RustFS image (source, cached)
run: |
DOCKER_BUILDKIT=1 docker buildx build --load \
--platform ${PLATFORM} \
--cache-from type=gha \
--cache-to type=gha,mode=max \
-t rustfs-ci \
-f Dockerfile.source .
- name: Prepare cluster compose
run: |
cat > compose.yml <<'EOF'
services:
rustfs1:
image: rustfs-ci
hostname: rustfs1
networks: [rustfs-net]
environment:
RUSTFS_ADDRESS: "0.0.0.0:9000"
RUSTFS_ACCESS_KEY: ${S3_ACCESS_KEY}
RUSTFS_SECRET_KEY: ${S3_SECRET_KEY}
RUSTFS_VOLUMES: "/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3"
volumes:
- rustfs1-data:/data
rustfs2:
image: rustfs-ci
hostname: rustfs2
networks: [rustfs-net]
environment:
RUSTFS_ADDRESS: "0.0.0.0:9000"
RUSTFS_ACCESS_KEY: ${S3_ACCESS_KEY}
RUSTFS_SECRET_KEY: ${S3_SECRET_KEY}
RUSTFS_VOLUMES: "/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3"
volumes:
- rustfs2-data:/data
rustfs3:
image: rustfs-ci
hostname: rustfs3
networks: [rustfs-net]
environment:
RUSTFS_ADDRESS: "0.0.0.0:9000"
RUSTFS_ACCESS_KEY: ${S3_ACCESS_KEY}
RUSTFS_SECRET_KEY: ${S3_SECRET_KEY}
RUSTFS_VOLUMES: "/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3"
volumes:
- rustfs3-data:/data
rustfs4:
image: rustfs-ci
hostname: rustfs4
networks: [rustfs-net]
environment:
RUSTFS_ADDRESS: "0.0.0.0:9000"
RUSTFS_ACCESS_KEY: ${S3_ACCESS_KEY}
RUSTFS_SECRET_KEY: ${S3_SECRET_KEY}
RUSTFS_VOLUMES: "/data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3"
volumes:
- rustfs4-data:/data
lb:
image: haproxy:2.9
hostname: lb
networks: [rustfs-net]
ports:
- "9000:9000"
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
networks:
rustfs-net:
name: rustfs-net
volumes:
rustfs1-data:
rustfs2-data:
rustfs3-data:
rustfs4-data:
EOF
cat > haproxy.cfg <<'EOF'
defaults
mode http
timeout connect 5s
timeout client 30s
timeout server 30s
frontend fe_s3
bind *:9000
default_backend be_s3
backend be_s3
balance roundrobin
server s1 rustfs1:9000 check
server s2 rustfs2:9000 check
server s3 rustfs3:9000 check
server s4 rustfs4:9000 check
EOF
- name: Launch cluster
run: docker compose -f compose.yml up -d
- name: Wait for LB ready
run: |
for i in {1..90}; do
if curl -sf http://127.0.0.1:9000/health >/dev/null 2>&1; then
echo "Load balancer is ready"
exit 0
fi
sleep 2
done
echo "LB or backend not ready" >&2
docker compose -f compose.yml logs --tail=200 || true
exit 1
- name: Generate s3tests config
run: |
export S3_HOST=127.0.0.1
envsubst < .github/s3tests/s3tests.conf > s3tests.conf
- name: Provision s3-tests alt user (required by suite)
run: |
python3 -m pip install --user --upgrade pip awscurl
export PATH="$HOME/.local/bin:$PATH"
awscurl \
--service s3 \
--region "${S3_REGION}" \
--access_key "${S3_ACCESS_KEY}" \
--secret_key "${S3_SECRET_KEY}" \
-X PUT \
-H 'Content-Type: application/json' \
-d '{"secretKey":"'"${S3_ALT_SECRET_KEY}"'","status":"enabled","policy":"readwrite"}' \
"http://127.0.0.1:9000/rustfs/admin/v3/add-user?accessKey=${S3_ALT_ACCESS_KEY}"
awscurl \
--service s3 \
--region "${S3_REGION}" \
--access_key "${S3_ACCESS_KEY}" \
--secret_key "${S3_SECRET_KEY}" \
-X PUT \
"http://127.0.0.1:9000/rustfs/admin/v3/set-user-or-group-policy?policyName=readwrite&userOrGroup=${S3_ALT_ACCESS_KEY}&isGroup=false"
awscurl \
--service s3 \
--region "${S3_REGION}" \
--access_key "${S3_ALT_ACCESS_KEY}" \
--secret_key "${S3_ALT_SECRET_KEY}" \
-X GET \
"http://127.0.0.1:9000/" >/dev/null
- name: Prepare s3-tests
run: |
python3 -m pip install --user --upgrade pip tox
export PATH="$HOME/.local/bin:$PATH"
git clone --depth 1 https://github.com/ceph/s3-tests.git s3-tests
- name: Run ceph s3-tests (multi, debug friendly)
run: |
export PATH="$HOME/.local/bin:$PATH"
mkdir -p artifacts/s3tests-multi
cd s3-tests
set -o pipefail
MAXFAIL="${{ github.event.inputs.maxfail }}"
if [ -z "$MAXFAIL" ]; then MAXFAIL="1"; fi
MARKEXPR="${{ github.event.inputs.markexpr }}"
if [ -z "$MARKEXPR" ]; then MARKEXPR="not lifecycle and not versioning and not s3website and not bucket_logging and not encryption"; fi
XDIST="${{ github.event.inputs.xdist }}"
if [ -z "$XDIST" ]; then XDIST="0"; fi
XDIST_ARGS=""
if [ "$XDIST" != "0" ]; then
# Add pytest-xdist to requirements.txt so tox installs it inside
# its virtualenv. Installing outside tox does NOT work.
echo "pytest-xdist" >> requirements.txt
XDIST_ARGS="-n $XDIST --dist=loadgroup"
fi
# Run tests from s3tests/functional (boto2+boto3 combined directory).
S3TEST_CONF=${GITHUB_WORKSPACE}/s3tests.conf \
tox -- \
-vv -ra --showlocals --tb=long \
--maxfail="$MAXFAIL" \
--junitxml=${GITHUB_WORKSPACE}/artifacts/s3tests-multi/junit.xml \
$XDIST_ARGS \
s3tests/functional/test_s3.py \
-m "$MARKEXPR" \
2>&1 | tee ${GITHUB_WORKSPACE}/artifacts/s3tests-multi/pytest.log
- name: Collect logs
if: always()
run: |
mkdir -p artifacts/cluster
docker compose -f compose.yml logs --no-color > artifacts/cluster/cluster.log 2>&1 || true
- name: Upload artifacts
if: always() && env.ACT != 'true'
uses: actions/upload-artifact@v4
with:
name: s3tests-multi
path: artifacts/**

View File

@@ -1,95 +0,0 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Publish helm chart to artifacthub
on:
workflow_run:
workflows: [ "Build and Release" ]
types: [ completed ]
permissions:
contents: read
env:
new_version: ${{ github.event.workflow_run.head_branch }}
jobs:
build-helm-package:
runs-on: ubicloud-standard-4
# Only run on successful builds triggered by tag pushes (version format: x.y.z or x.y.z-suffix)
if: |
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'push' &&
contains(github.event.workflow_run.head_branch, '.')
steps:
- name: Checkout helm chart repo
uses: actions/checkout@v6
- name: Replace chart app version
run: |
set -e
set -x
old_version=$(grep "^appVersion:" helm/rustfs/Chart.yaml | awk '{print $2}')
sed -i "s/$old_version/$new_version/g" helm/rustfs/Chart.yaml
sed -i "/^image:/,/^[^ ]/ s/tag:.*/tag: "$new_version"/" helm/rustfs/values.yaml
- name: Set up Helm
uses: azure/setup-helm@v4.3.0
- name: Package Helm Chart
run: |
cp helm/README.md helm/rustfs/
package_version=$(echo $new_version | awk -F '-' '{print $2}' | awk -F '.' '{print $NF}')
helm package ./helm/rustfs --destination helm/rustfs/ --version "0.0.$package_version"
- name: Upload helm package as artifact
uses: actions/upload-artifact@v4
with:
name: helm-package
path: helm/rustfs/*.tgz
retention-days: 1
publish-helm-package:
runs-on: ubicloud-standard-4
needs: [ build-helm-package ]
steps:
- name: Checkout helm package repo
uses: actions/checkout@v6
with:
repository: rustfs/helm
token: ${{ secrets.RUSTFS_HELM_PACKAGE }}
- name: Download helm package
uses: actions/download-artifact@v4
with:
name: helm-package
path: ./
- name: Set up helm
uses: azure/setup-helm@v4.3.0
- name: Generate index
run: helm repo index . --url https://charts.rustfs.com
- name: Push helm package and index file
run: |
git config --global user.name "${{ secrets.USERNAME }}"
git config --global user.email "${{ secrets.EMAIL_ADDRESS }}"
git status .
git add .
git commit -m "Update rustfs helm package with $new_version."
git push origin main

View File

@@ -1,36 +0,0 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: "issue-translator"
on:
issue_comment:
types: [ created ]
issues:
types: [ opened ]
permissions:
contents: read
issues: write
jobs:
build:
runs-on: ubicloud-standard-4
steps:
- uses: usthe/issues-translate-action@v2.7
with:
IS_MODIFY_TITLE: false
# not require, default false, . Decide whether to modify the issue title
# if true, the robot account @Issues-translate-bot must have modification permissions, invite @Issues-translate-bot to your project or use your custom bot.
CUSTOM_BOT_NOTE: Bot detected the issue body's language is not English, translate it automatically.
# not require. Customize the translation robot prefix message.

View File

@@ -1,142 +0,0 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Performance Testing
on:
push:
branches: [ main ]
paths:
- "**/*.rs"
- "**/Cargo.toml"
- "**/Cargo.lock"
- ".github/workflows/performance.yml"
workflow_dispatch:
inputs:
profile_duration:
description: "Profiling duration in seconds"
required: false
default: "120"
type: string
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
performance-profile:
name: Performance Profiling
runs-on: ubicloud-standard-4
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Rust environment
uses: ./.github/actions/setup
with:
rust-version: nightly
cache-shared-key: perf-${{ hashFiles('**/Cargo.lock') }}
cache-save-if: ${{ github.ref == 'refs/heads/main' }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install additional nightly components
run: rustup component add llvm-tools-preview
- name: Install samply profiler
uses: taiki-e/cache-cargo-install-action@v2
with:
tool: samply
- name: Configure kernel for profiling
run: echo '1' | sudo tee /proc/sys/kernel/perf_event_paranoid
- name: Prepare test environment
run: |
# Create test volumes
for i in {0..4}; do
mkdir -p ./target/volume/test$i
done
# Set environment variables
echo "RUSTFS_VOLUMES=./target/volume/test{0...4}" >> $GITHUB_ENV
echo "RUST_LOG=rustfs=info,ecstore=info,s3s=info,iam=info,rustfs-obs=info" >> $GITHUB_ENV
- name: Verify console static assets
run: |
# Console static assets are already embedded in the repository
echo "Console static assets size: $(du -sh rustfs/static/)"
echo "Console static assets are embedded via rust-embed, no external download needed"
- name: Build with profiling optimizations
run: |
RUSTFLAGS="-C force-frame-pointers=yes -C debug-assertions=off" \
cargo +nightly build --profile profiling -p rustfs --bins
- name: Run performance profiling
id: profiling
run: |
DURATION="${{ github.event.inputs.profile_duration || '120' }}"
echo "Running profiling for ${DURATION} seconds..."
timeout "${DURATION}s" samply record \
--output samply-profile.json \
./target/profiling/rustfs ${RUSTFS_VOLUMES} || true
if [ -f "samply-profile.json" ]; then
echo "profile_generated=true" >> $GITHUB_OUTPUT
echo "Profile generated successfully"
else
echo "profile_generated=false" >> $GITHUB_OUTPUT
echo "::warning::Profile data not generated"
fi
- name: Upload profile data
if: steps.profiling.outputs.profile_generated == 'true'
uses: actions/upload-artifact@v4
with:
name: performance-profile-${{ github.run_number }}
path: samply-profile.json
retention-days: 30
benchmark:
name: Benchmark Tests
runs-on: ubicloud-standard-4
timeout-minutes: 45
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Rust environment
uses: ./.github/actions/setup
with:
rust-version: stable
cache-shared-key: bench-${{ hashFiles('**/Cargo.lock') }}
github-token: ${{ secrets.GITHUB_TOKEN }}
cache-save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Run benchmarks
run: |
cargo bench --package ecstore --bench comparison_benchmark -- --output-format json | \
tee benchmark-results.json
- name: Upload benchmark results
uses: actions/upload-artifact@v4
with:
name: benchmark-results-${{ github.run_number }}
path: benchmark-results.json
retention-days: 7

68
.github/workflows/samply.yml vendored Normal file
View File

@@ -0,0 +1,68 @@
name: Profile with Samply
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
profile:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
components: llvm-tools-preview
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Install samply
uses: taiki-e/cache-cargo-install-action@v2
with:
tool: samply
- name: Configure kernel for profiling
run: echo '1' | sudo tee /proc/sys/kernel/perf_event_paranoid
- name: Create test volumes
run: |
for i in {0..4}; do
mkdir -p ./target/volume/test$i
done
- name: Set environment variables
run: |
echo "RUSTFS_VOLUMES=./target/volume/test{0...4}" >> $GITHUB_ENV
echo "RUST_LOG=rustfs=info,ecstore=info,s3s=info,iam=info,rustfs-obs=info" >> $GITHUB_ENV
- name: Download static files
run: |
curl -L "https://dl.rustfs.com/artifacts/console/rustfs-console-latest.zip" -o tempfile.zip && unzip -o tempfile.zip -d ./rustfs/static && rm tempfile.zip
- name: Build with profiling
run: |
RUSTFLAGS="-C force-frame-pointers=yes" cargo +nightly build --profile profiling -p rustfs --bins
- name: Run samply with timeout
id: samply_record
run: |
timeout 120s samply record --output samply.json ./target/profiling/rustfs ${RUSTFS_VOLUMES}
if [ -f "samply.json" ]; then
echo "profile_generated=true" >> $GITHUB_OUTPUT
else
echo "profile_generated=false" >> $GITHUB_OUTPUT
echo "::error::Failed to generate profile data"
fi
- name: Upload profile data
if: steps.samply_record.outputs.profile_generated == 'true'
uses: actions/upload-artifact@v4
with:
name: samply-profile-${{ github.run_number }}
path: samply.json
retention-days: 7

17
.gitignore vendored
View File

@@ -2,7 +2,6 @@
.DS_Store .DS_Store
.idea .idea
.vscode .vscode
.direnv/
/test /test
/logs /logs
/data /data
@@ -11,6 +10,7 @@ rustfs/static/*
!rustfs/static/.gitkeep !rustfs/static/.gitkeep
vendor vendor
cli/rustfs-gui/embedded-rustfs/rustfs cli/rustfs-gui/embedded-rustfs/rustfs
deploy/config/obs.toml
*.log *.log
deploy/certs/* deploy/certs/*
*jsonl *jsonl
@@ -19,18 +19,3 @@ deploy/certs/*
.cargo .cargo
profile.json profile.json
.docker/openobserve-otel/data .docker/openobserve-otel/data
*.zst
.secrets
*.go
*.pb
*.svg
deploy/logs/*.log.*
# s3-tests local artifacts (root directory only)
/s3-tests/
/s3-tests-local/
/s3tests.conf
/s3tests.conf.*
*.events
*.audit
*.snappy

View File

@@ -1,32 +0,0 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: local
hooks:
- id: cargo-fmt
name: cargo fmt
entry: cargo fmt --all --check
language: system
types: [rust]
pass_filenames: false
- id: cargo-clippy
name: cargo clippy
entry: cargo clippy --all-targets --all-features -- -D warnings
language: system
types: [rust]
pass_filenames: false
- id: cargo-check
name: cargo check
entry: cargo check --all-targets
language: system
types: [rust]
pass_filenames: false
- id: cargo-test
name: cargo test
entry: bash -c 'cargo test --workspace --exclude e2e_test && cargo test --all --doc'
language: system
types: [rust]
pass_filenames: false

124
.vscode/launch.json vendored
View File

@@ -1,31 +1,9 @@
{ {
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug(only) executable 'rustfs'",
"env": {
"RUST_LOG": "rustfs=info,ecstore=info,s3s=info,iam=info",
"RUSTFS_SKIP_BACKGROUND_TASK": "on"
//"RUSTFS_OBS_LOG_DIRECTORY": "./deploy/logs",
// "RUSTFS_POLICY_PLUGIN_URL":"http://localhost:8181/v1/data/rustfs/authz/allow",
// "RUSTFS_POLICY_PLUGIN_AUTH_TOKEN":"your-opa-token"
},
"program": "${workspaceFolder}/target/debug/rustfs",
"args": [
"--access-key",
"rustfsadmin",
"--secret-key",
"rustfsadmin",
"--address",
"0.0.0.0:9010",
"--server-domains",
"127.0.0.1:9010",
"./target/volume/test{1...4}"
],
"cwd": "${workspaceFolder}"
},
{ {
"type": "lldb", "type": "lldb",
"request": "launch", "request": "launch",
@@ -42,23 +20,33 @@
} }
}, },
"env": { "env": {
"RUST_LOG": "rustfs=debug,ecstore=info,s3s=debug,iam=debug", "RUST_LOG": "rustfs=debug,ecstore=info,s3s=debug",
"RUSTFS_SKIP_BACKGROUND_TASK": "on", "RUSTFS_VOLUMES": "./target/volume/test{0...3}",
//"RUSTFS_OBS_LOG_DIRECTORY": "./deploy/logs", "RUSTFS_ADDRESS": "[::]:9000",
// "RUSTFS_POLICY_PLUGIN_URL":"http://localhost:8181/v1/data/rustfs/authz/allow", "RUSTFS_CONSOLE_ENABLE": "true",
// "RUSTFS_POLICY_PLUGIN_AUTH_TOKEN":"your-opa-token" "RUSTFS_CONSOLE_ADDRESS": "[::]:9002",
"RUSTFS_SERVER_DOMAINS": "localhost:9000",
"RUSTFS_TLS_PATH": "./deploy/certs",
"RUSTFS_OBS_CONFIG": "./deploy/config/obs.example.toml",
"RUSTFS__OBSERVABILITY__ENDPOINT": "http://localhost:4317",
"RUSTFS__OBSERVABILITY__USE_STDOUT": "true",
"RUSTFS__OBSERVABILITY__SAMPLE_RATIO": "2.0",
"RUSTFS__OBSERVABILITY__METER_INTERVAL": "30",
"RUSTFS__OBSERVABILITY__SERVICE_NAME": "rustfs",
"RUSTFS__OBSERVABILITY__SERVICE_VERSION": "0.1.0",
"RUSTFS__OBSERVABILITY__ENVIRONMENT": "develop",
"RUSTFS__OBSERVABILITY__LOGGER_LEVEL": "info",
"RUSTFS__SINKS__FILE__ENABLED": "true",
"RUSTFS__SINKS__FILE__PATH": "./deploy/logs/rustfs.log",
"RUSTFS__SINKS__WEBHOOK__ENABLED": "false",
"RUSTFS__SINKS__WEBHOOK__ENDPOINT": "",
"RUSTFS__SINKS__WEBHOOK__AUTH_TOKEN": "",
"RUSTFS__SINKS__KAFKA__ENABLED": "false",
"RUSTFS__SINKS__KAFKA__BOOTSTRAP_SERVERS": "",
"RUSTFS__SINKS__KAFKA__TOPIC": "",
"RUSTFS__LOGGER__QUEUE_CAPACITY": "10"
}, },
"args": [
"--access-key",
"rustfsadmin",
"--secret-key",
"rustfsadmin",
"--address",
"0.0.0.0:9010",
"--server-domains",
"127.0.0.1:9010",
"./target/volume/test{1...4}"
],
"cwd": "${workspaceFolder}" "cwd": "${workspaceFolder}"
}, },
{ {
@@ -89,57 +77,15 @@
"test", "test",
"--no-run", "--no-run",
"--lib", "--lib",
"--package=rustfs-ecstore" "--package=ecstore"
] ],
"filter": {
"name": "ecstore",
"kind": "lib"
}
}, },
"args": [], "args": [],
"cwd": "${workspaceFolder}" "cwd": "${workspaceFolder}"
},
{
"name": "Debug executable target/debug/rustfs",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/target/debug/rustfs",
"args": [],
"cwd": "${workspaceFolder}",
//"stopAtEntry": false,
//"preLaunchTask": "cargo build",
"env": {
"RUSTFS_ACCESS_KEY": "rustfsadmin",
"RUSTFS_SECRET_KEY": "rustfsadmin",
"RUSTFS_VOLUMES": "./target/volume/test{1...4}",
"RUSTFS_ADDRESS": ":9000",
"RUSTFS_CONSOLE_ENABLE": "true",
// "RUSTFS_OBS_TRACE_ENDPOINT": "http://127.0.0.1:4318/v1/traces", // jeager otlp http endpoint
// "RUSTFS_OBS_METRIC_ENDPOINT": "http://127.0.0.1:4318/v1/metrics", // default otlp http endpoint
// "RUSTFS_OBS_LOG_ENDPOINT": "http://127.0.0.1:4318/v1/logs", // default otlp http endpoint
// "RUSTFS_COMPRESS_ENABLE": "true",
"RUSTFS_CONSOLE_ADDRESS": "127.0.0.1:9001",
"RUSTFS_OBS_LOG_DIRECTORY": "./target/logs",
},
"sourceLanguages": [
"rust"
],
},
{
"name": "Debug executable target/debug/test",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/target/debug/deps/lifecycle_integration_test-5915cbfcab491b3b",
"args": [
"--skip",
"test_lifecycle_expiry_basic",
"--skip",
"test_lifecycle_expiry_deletemarker",
//"--skip",
//"test_lifecycle_transition_basic",
],
"cwd": "${workspaceFolder}",
//"stopAtEntry": false,
//"preLaunchTask": "cargo build",
"sourceLanguages": [
"rust"
],
} }
] ]
} }

View File

@@ -1,25 +0,0 @@
# Repository Guidelines
## Communication Rules
- Respond to the user in Chinese; use English in all other contexts.
- Code and documentation must be written in English only. Chinese text is allowed solely as test data/fixtures when a case explicitly requires Chinese-language content for validation.
## Project Structure & Module Organization
The workspace root hosts shared dependencies in `Cargo.toml`. The service binary lives under `rustfs/src/main.rs`, while reusable crates sit in `crates/` (`crypto`, `iam`, `kms`, and `e2e_test`). Local fixtures for standalone flows reside in `test_standalone/`, deployment manifests are under `deploy/`, Docker assets sit at the root, and automation lives in `scripts/`. Skim each crates README or module docs before contributing changes.
## Build, Test, and Development Commands
Run `cargo check --all-targets` for fast validation. Build release binaries via `cargo build --release` or the pipeline-aligned `make build`. Use `./build-rustfs.sh --dev` for iterative development and `./build-rustfs.sh --platform <target>` for cross-compiles. Prefer `make pre-commit` before pushing to cover formatting, clippy, checks, and tests.
Always ensure `cargo fmt --all --check`, `cargo test --workspace --exclude e2e_test`, and `cargo clippy --all-targets --all-features -- -D warnings` complete successfully after each code change to keep the tree healthy and warning-free.
## Coding Style & Naming Conventions
Formatting follows the repo `rustfmt.toml` (130-column width). Use `snake_case` for items, `PascalCase` for types, and `SCREAMING_SNAKE_CASE` for constants. Avoid `unwrap()` or `expect()` outside tests; bubble errors with `Result` and crate-specific `thiserror` types. Keep async code non-blocking and offload CPU-heavy work with `tokio::task::spawn_blocking` when necessary.
## Testing Guidelines
Co-locate unit tests with their modules and give behavior-led names such as `handles_expired_token`. Integration suites belong in each crates `tests/` directory, while exhaustive end-to-end scenarios live in `crates/e2e_test/`. Run `cargo test --workspace --exclude e2e_test` during iteration, `cargo nextest run --all --exclude e2e_test` when available, and finish with `cargo test --all` before requesting review. Use `NO_PROXY=127.0.0.1,localhost HTTP_PROXY= HTTPS_PROXY=` for KMS e2e tests.
When fixing bugs or adding features, include regression tests that capture the new behavior so future changes cannot silently break it.
## Commit & Pull Request Guidelines
Work on feature branches (e.g., `feat/...`) after syncing `main`. Follow Conventional Commits under 72 characters (e.g., `feat: add kms key rotation`). Each commit must compile, format cleanly, and pass `make pre-commit`. Open PRs with a concise summary, note verification commands, link relevant issues, and wait for reviewer approval.
## Security & Configuration Tips
Do not commit secrets or cloud credentials; prefer environment variables or vault tooling. Review IAM- and KMS-related changes with a second maintainer. Confirm proxy settings before running sensitive tests to avoid leaking traffic outside localhost.

88
CLA.md
View File

@@ -1,88 +0,0 @@
RustFS Individual Contributor License Agreement
Thank you for your interest in contributing documentation and related software code to a project hosted or managed by
RustFS. In order to clarify the intellectual property license granted with Contributions from any person or entity,
RustFS must have a Contributor License Agreement ("CLA") on file that has been signed by each Contributor, indicating
agreement to the license terms below. This version of the Contributor License Agreement allows an individual to submit
Contributions to the applicable project. If you are making a submission on behalf of a legal entity, then you should
sign the separate Corporate Contributor License Agreement.
You accept and agree to the following terms and conditions for Your present and future Contributions submitted to
RustFS. You hereby irrevocably assign and transfer to RustFS all right, title, and interest in and to Your
Contributions, including all copyrights and other intellectual property rights therein.
Definitions
“You” (or “Your”) shall mean the copyright owner or legal entity authorized by the copyright owner that is making this
Agreement with RustFS. For legal entities, the entity making a Contribution and all other entities that control, are
controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes
of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such
entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares,
or (iii) beneficial ownership of such entity.
“Contribution” shall mean any original work of authorship, including any modifications or additions to an existing work,
that is intentionally submitted by You to RustFS for inclusion in, or documentation of, any of the products or projects
owned or managed by RustFS (the "Work"), including without limitation any Work described in Schedule A. For the purposes
of this definition, "submitted" means any form of electronic or written communication sent to RustFS or its
representatives, including but not limited to communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, RustFS for the purpose of discussing and improving the
Work.
Assignment of Copyright
Subject to the terms and conditions of this Agreement, You hereby irrevocably assign and transfer to RustFS all right,
title, and interest in and to Your Contributions, including all copyrights and other intellectual property rights
therein, for the entire term of such rights, including all renewals and extensions. You agree to execute all documents
and take all actions as may be reasonably necessary to vest in RustFS the ownership of Your Contributions and to assist
RustFS in perfecting, maintaining, and enforcing its rights in Your Contributions.
Grant of Patent License
Subject to the terms and conditions of this Agreement, You hereby grant to RustFS and to recipients of documentation and
software distributed by RustFS a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as
stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the
Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your
Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was
submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or
counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes
direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for
that Contribution or Work shall terminate as of the date such litigation is filed.
You represent that you are legally entitled to grant the above assignment and license.
You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of
others). You represent that Your Contribution submissions include complete details of any third-party license or other
restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which
are associated with any part of Your Contributions.
You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You
may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You
provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
A PARTICULAR PURPOSE.
Should You wish to submit work that is not Your original creation, You may submit it to RustFS separately from any
Contribution, identifying the complete details of its source and of any license or other restriction (including, but not
limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously
marking the work as "Submitted on behalf of a third-party: [named here]”.
You agree to notify RustFS of any facts or circumstances of which you become aware that would make these representations
inaccurate in any respect.
Modification of CLA
RustFS reserves the right to update or modify this CLA in the future. Any updates or modifications to this CLA shall
apply only to Contributions made after the effective date of the revised CLA. Contributions made prior to the update
shall remain governed by the version of the CLA that was in effect at the time of submission. It is not necessary for
all Contributors to re-sign the CLA when the CLA is updated or modified.
Governing Law and Dispute Resolution
This Agreement will be governed by and construed in accordance with the laws of the People's Republic of China excluding
that body of laws known as conflict of laws. The parties expressly agree that the United Nations Convention on Contracts
for the International Sale of Goods will not apply. Any legal action or proceeding arising under this Agreement will be
brought exclusively in the courts located in Beijing, China, and the parties hereby irrevocably consent to the personal
jurisdiction and venue therein.
For your reading convenience, this Agreement is written in parallel English and Chinese sections. To the extent there is
a conflict between the English and Chinese sections, the English sections shall govern.

275
CLAUDE.md
View File

@@ -1,275 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
RustFS is a high-performance distributed object storage software built with Rust, providing S3-compatible APIs and
advanced features like data lakes, AI, and big data support. It's designed as an alternative to MinIO with better
performance and a more business-friendly Apache 2.0 license.
## Build Commands
### Primary Build Commands
- `cargo build --release` - Build the main RustFS binary
- `./build-rustfs.sh` - Recommended build script that handles console resources and cross-platform compilation
- `./build-rustfs.sh --dev` - Development build with debug symbols
- `make build` or `just build` - Use Make/Just for standardized builds
### Platform-Specific Builds
- `./build-rustfs.sh --platform x86_64-unknown-linux-musl` - Build for musl target
- `./build-rustfs.sh --platform aarch64-unknown-linux-gnu` - Build for ARM64
- `make build-musl` or `just build-musl` - Build musl variant
- `make build-cross-all` - Build all supported architectures
### Testing Commands
- `cargo test --workspace --exclude e2e_test` - Run unit tests (excluding e2e tests)
- `cargo nextest run --all --exclude e2e_test` - Use nextest if available (faster)
- `cargo test --all --doc` - Run documentation tests
- `make test` or `just test` - Run full test suite
- `make pre-commit` - Run all quality checks (fmt, clippy, check, test)
### End-to-End Testing
- `cargo test --package e2e_test` - Run all e2e tests
- `./scripts/run_e2e_tests.sh` - Run e2e tests via script
- `./scripts/run_scanner_benchmarks.sh` - Run scanner performance benchmarks
### KMS-Specific Testing (with proxy bypass)
-
`NO_PROXY=127.0.0.1,localhost HTTP_PROXY= HTTPS_PROXY= http_proxy= https_proxy= cargo test --package e2e_test test_local_kms_end_to_end -- --nocapture --test-threads=1` -
Run complete KMS end-to-end test
-
`NO_PROXY=127.0.0.1,localhost HTTP_PROXY= HTTPS_PROXY= http_proxy= https_proxy= cargo test --package e2e_test kms:: -- --nocapture --test-threads=1` -
Run all KMS tests
- `cargo test --package e2e_test test_local_kms_key_isolation -- --nocapture --test-threads=1` - Test KMS key isolation
- `cargo test --package e2e_test test_local_kms_large_file -- --nocapture --test-threads=1` - Test KMS with large files
### Code Quality
- `cargo fmt --all` - Format code
- `cargo clippy --all-targets --all-features -- -D warnings` - Lint code
- `make pre-commit` or `just pre-commit` - Run all quality checks (fmt, clippy, check, test)
### Quick Development Commands
- `make help` or `just help` - Show all available commands with descriptions
- `make help-build` - Show detailed build options and cross-compilation help
- `make help-docker` - Show comprehensive Docker build and deployment options
- `./scripts/dev_deploy.sh <IP>` - Deploy development build to remote server
- `./scripts/run.sh` - Start local development server
- `./scripts/probe.sh` - Health check and connectivity testing
### Docker Build Commands
- `make docker-buildx` - Build multi-architecture production images
- `make docker-dev-local` - Build development image for local use
- `./docker-buildx.sh --push` - Build and push production images
## Architecture Overview
### Core Components
**Main Binary (`rustfs/`):**
- Entry point at `rustfs/src/main.rs`
- Core modules: admin, auth, config, server, storage, license management, profiling
- HTTP server with S3-compatible APIs
- Service state management and graceful shutdown
- Parallel service initialization with DNS resolver, bucket metadata, and IAM
**Key Crates (`crates/`):**
- `ecstore` - Erasure coding storage implementation (core storage layer)
- `iam` - Identity and Access Management
- `kms` - Key Management Service for encryption and key handling
- `madmin` - Management dashboard and admin API interface
- `s3select-api` & `s3select-query` - S3 Select API and query engine
- `config` - Configuration management with notify features
- `crypto` - Cryptography and security features
- `lock` - Distributed locking implementation
- `filemeta` - File metadata management
- `rio` - Rust I/O utilities and abstractions
- `common` - Shared utilities and data structures
- `protos` - Protocol buffer definitions
- `audit-logger` - Audit logging for file operations
- `notify` - Event notification system
- `obs` - Observability utilities
- `workers` - Worker thread pools and task scheduling
- `appauth` - Application authentication and authorization
- `ahm` - Asynchronous Hash Map for concurrent data structures
- `mcp` - MCP server for S3 operations
- `signer` - Client request signing utilities
- `checksums` - Client checksum calculation utilities
- `utils` - General utility functions and helpers
- `zip` - ZIP file handling and compression
- `targets` - Target-specific configurations and utilities
### Build System
- Cargo workspace with 25+ crates (including new KMS functionality)
- Custom `build-rustfs.sh` script for advanced build options
- Multi-architecture Docker builds via `docker-buildx.sh`
- Both Make and Just task runners supported with comprehensive help
- Cross-compilation support for multiple Linux targets
- Automated CI/CD with GitHub Actions for testing, building, and Docker publishing
- Performance benchmarking and audit workflows
### Key Dependencies
- `axum` - HTTP framework for S3 API server
- `tokio` - Async runtime
- `s3s` - S3 protocol implementation library
- `datafusion` - For S3 Select query processing
- `hyper`/`hyper-util` - HTTP client/server utilities
- `rustls` - TLS implementation
- `serde`/`serde_json` - Serialization
- `tracing` - Structured logging and observability
- `pprof` - Performance profiling with flamegraph support
- `tikv-jemallocator` - Memory allocator for Linux GNU builds
### Development Workflow
- Console resources are embedded during build via `rust-embed`
- Protocol buffers generated via custom `gproto` binary
- E2E tests in separate crate (`e2e_test`) with comprehensive KMS testing
- Shadow build for version/metadata embedding
- Support for both GNU and musl libc targets
- Development scripts in `scripts/` directory for common tasks
- Git hooks setup available via `make setup-hooks` or `just setup-hooks`
### Performance & Observability
- Performance profiling available with `pprof` integration (disabled on Windows)
- Profiling enabled via environment variables in production
- Built-in observability with OpenTelemetry integration
- Background services (scanner, heal) can be controlled via environment variables:
- `RUSTFS_ENABLE_SCANNER` (default: true)
- `RUSTFS_ENABLE_HEAL` (default: true)
### Service Architecture
- Service state management with graceful shutdown handling
- Parallel initialization of core systems (DNS, bucket metadata, IAM)
- Event notification system with MQTT and webhook support
- Auto-heal and data scanner for storage integrity
- Jemalloc allocator for Linux GNU targets for better performance
## Environment Variables
- `RUSTFS_ENABLE_SCANNER` - Enable/disable background data scanner (default: true)
- `RUSTFS_ENABLE_HEAL` - Enable/disable auto-heal functionality (default: true)
- Various profiling and observability controls
- Build-time variables for Docker builds (RELEASE, REGISTRY, etc.)
- Test environment configurations in `scripts/dev_rustfs.env`
### KMS Environment Variables
- `NO_PROXY=127.0.0.1,localhost` - Required for KMS E2E tests to bypass proxy
- `HTTP_PROXY=` `HTTPS_PROXY=` `http_proxy=` `https_proxy=` - Clear proxy settings for local KMS testing
## KMS (Key Management Service) Architecture
### KMS Implementation Status
- **Full KMS Integration:** Complete implementation with Local and Vault backends
- **Automatic Configuration:** KMS auto-configures on startup with `--kms-enable` flag
- **Encryption Support:** Full S3-compatible server-side encryption (SSE-S3, SSE-KMS, SSE-C)
- **Admin API:** Complete KMS management via HTTP admin endpoints
- **Production Ready:** Comprehensive testing including large files and key isolation
### KMS Configuration
- **Local Backend:** `--kms-backend local --kms-key-dir <path> --kms-default-key-id <id>`
- **Vault Backend:** `--kms-backend vault --kms-vault-endpoint <url> --kms-vault-key-name <name>`
- **Auto-startup:** KMS automatically initializes when `--kms-enable` is provided
- **Manual Configuration:** Also supports dynamic configuration via admin API
### S3 Encryption Support
- **SSE-S3:** Server-side encryption with S3-managed keys (`ServerSideEncryption: AES256`)
- **SSE-KMS:** Server-side encryption with KMS-managed keys (`ServerSideEncryption: aws:kms`)
- **SSE-C:** Server-side encryption with customer-provided keys
- **Response Headers:** All encryption types return correct `server_side_encryption` headers in PUT/GET responses
### KMS Testing Architecture
- **Comprehensive E2E Tests:** Located in `crates/e2e_test/src/kms/`
- **Test Environments:** Automated test environment setup with temporary directories
- **Encryption Coverage:** Tests all three encryption types (SSE-S3, SSE-KMS, SSE-C)
- **API Coverage:** Tests all KMS admin APIs (CreateKey, DescribeKey, ListKeys, etc.)
- **Edge Cases:** Key isolation, large file handling, error scenarios
### Key Files for KMS
- `crates/kms/` - Core KMS implementation with Local/Vault backends
- `rustfs/src/main.rs` - KMS auto-initialization in `init_kms_system()`
- `rustfs/src/storage/ecfs.rs` - SSE encryption/decryption in PUT/GET operations
- `rustfs/src/admin/handlers/kms*.rs` - KMS admin endpoints
- `crates/e2e_test/src/kms/` - Comprehensive KMS test suite
- `crates/rio/src/encrypt_reader.rs` - Streaming encryption for large files
## Code Style and Safety Requirements
- **Language Requirements:**
- Communicate with me in Chinese, but **only English can be used in code files**
- Code comments, function names, variable names, and all text in source files must be in English only
- No Chinese characters, emojis, or non-ASCII characters are allowed in any source code files
- This includes comments, strings, documentation, and any other text within code files
- **Safety-Critical Rules:**
- `unsafe_code = "deny"` enforced at workspace level
- Never use `unwrap()`, `expect()`, or panic-inducing code except in tests
- Avoid blocking I/O operations in async contexts
- Use proper error handling with `Result<T, E>` and `Option<T>`
- Follow Rust's ownership and borrowing rules strictly
- **Performance Guidelines:**
- Use `cargo clippy --all-targets --all-features -- -D warnings` to catch issues
- Prefer `anyhow` for error handling in applications, `thiserror` for libraries
- Use appropriate async runtimes and avoid blocking calls
- **Testing Standards:**
- All new features must include comprehensive tests
- Use `#[cfg(test)]` for test-only code that may use panic macros
- E2E tests should cover KMS integration scenarios
## Common Development Tasks
### Running KMS Tests Locally
1. **Clear proxy settings:** KMS tests require direct localhost connections
2. **Use serial execution:** `--test-threads=1` prevents port conflicts
3. **Enable output:** `--nocapture` shows detailed test logs
4. **Full command:**
`NO_PROXY=127.0.0.1,localhost HTTP_PROXY= HTTPS_PROXY= http_proxy= https_proxy= cargo test --package e2e_test test_local_kms_end_to_end -- --nocapture --test-threads=1`
### KMS Development Workflow
1. **Code changes:** Modify KMS-related code in `crates/kms/` or `rustfs/src/`
2. **Compile:** Always run `cargo build` after changes
3. **Test specific functionality:** Use targeted test commands for faster iteration
4. **Full validation:** Run complete end-to-end tests before commits
### Debugging KMS Issues
- **Server startup:** Check that KMS auto-initializes with debug logs
- **Encryption failures:** Verify SSE headers are correctly set in both PUT and GET responses
- **Test failures:** Use `--nocapture` to see detailed error messages
- **Key management:** Test admin API endpoints with proper authentication
## Important Reminders
- **Always compile after code changes:** Use `cargo build` to catch errors early
- **Don't bypass tests:** All functionality must be properly tested, not worked around
- **Use proper error handling:** Never use `unwrap()` or `expect()` in production code (except tests)
- **Follow S3 compatibility:** Ensure all encryption types return correct HTTP response headers
# important-instruction-reminders
Do what has been asked; nothing more, nothing less.
NEVER create files unless they're absolutely necessary for achieving your goal.
ALWAYS prefer editing an existing file to creating a new one.
NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly
requested by the User.

View File

@@ -1,128 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
hello@rustfs.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

9210
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,60 +1,33 @@
# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[workspace] [workspace]
members = [ members = [
"rustfs", # Core file system implementation "appauth", # Application authentication and authorization
"crates/appauth", # Application authentication and authorization "cli/rustfs-gui", # Graphical user interface client
"crates/audit", # Audit target management system with multi-target fan-out "common/common", # Shared utilities and data structures
"crates/common", # Shared utilities and data structures "common/lock", # Distributed locking implementation
"common/protos", # Protocol buffer definitions
"common/workers", # Worker thread pools and task scheduling
"crates/config", # Configuration management "crates/config", # Configuration management
"crates/crypto", # Cryptography and security features "crates/event-notifier", # Event notification system
"crates/ecstore", # Erasure coding storage implementation
"crates/e2e_test", # End-to-end test suite
"crates/filemeta", # File metadata management
"crates/iam", # Identity and Access Management
"crates/lock", # Distributed locking implementation
"crates/madmin", # Management dashboard and admin API interface
"crates/notify", # Notification system for events
"crates/obs", # Observability utilities "crates/obs", # Observability utilities
"crates/policy", # Policy management
"crates/protos", # Protocol buffer definitions
"crates/rio", # Rust I/O utilities and abstractions
"crates/targets", # Target-specific configurations and utilities
"crates/s3select-api", # S3 Select API interface
"crates/s3select-query", # S3 Select query engine
"crates/signer", # client signer
"crates/checksums", # client checksums
"crates/utils", # Utility functions and helpers "crates/utils", # Utility functions and helpers
"crates/workers", # Worker thread pools and task scheduling "crypto", # Cryptography and security features
"crates/zip", # ZIP file handling and compression "ecstore", # Erasure coding storage implementation
"crates/ahm", # Asynchronous Hash Map for concurrent data structures "e2e_test", # End-to-end test suite
"crates/mcp", # MCP server for S3 operations "iam", # Identity and Access Management
"crates/kms", # Key Management Service "madmin", # Management dashboard and admin API interface
"rustfs", # Core file system implementation
"s3select/api", # S3 Select API interface
"s3select/query", # S3 Select query engine
"crates/zip",
] ]
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]
edition = "2024" edition = "2021"
license = "Apache-2.0" license = "Apache-2.0"
repository = "https://github.com/rustfs/rustfs" repository = "https://github.com/rustfs/rustfs"
rust-version = "1.85" rust-version = "1.75"
version = "0.0.5" version = "0.0.1"
homepage = "https://rustfs.com"
description = "RustFS is a high-performance distributed object storage software built using Rust, one of the most popular languages worldwide. "
keywords = ["RustFS", "Minio", "object-storage", "filesystem", "s3"]
categories = ["web-programming", "development-tools", "filesystem", "network-programming"]
[workspace.lints.rust] [workspace.lints.rust]
unsafe_code = "deny" unsafe_code = "deny"
@@ -63,225 +36,194 @@ unsafe_code = "deny"
all = "warn" all = "warn"
[workspace.dependencies] [workspace.dependencies]
# RustFS Internal Crates api = { path = "./s3select/api", version = "0.0.1" }
rustfs = { path = "./rustfs", version = "0.0.5" } appauth = { path = "./appauth", version = "0.0.1" }
rustfs-ahm = { path = "crates/ahm", version = "0.0.5" } common = { path = "./common/common", version = "0.0.1" }
rustfs-appauth = { path = "crates/appauth", version = "0.0.5" } crypto = { path = "./crypto", version = "0.0.1" }
rustfs-audit = { path = "crates/audit", version = "0.0.5" } ecstore = { path = "./ecstore", version = "0.0.1" }
rustfs-checksums = { path = "crates/checksums", version = "0.0.5" } iam = { path = "./iam", version = "0.0.1" }
rustfs-common = { path = "crates/common", version = "0.0.5" } lock = { path = "./common/lock", version = "0.0.1" }
rustfs-config = { path = "./crates/config", version = "0.0.5" } madmin = { path = "./madmin", version = "0.0.1" }
rustfs-crypto = { path = "crates/crypto", version = "0.0.5" } policy = { path = "./policy", version = "0.0.1" }
rustfs-ecstore = { path = "crates/ecstore", version = "0.0.5" } protos = { path = "./common/protos", version = "0.0.1" }
rustfs-filemeta = { path = "crates/filemeta", version = "0.0.5" } query = { path = "./s3select/query", version = "0.0.1" }
rustfs-iam = { path = "crates/iam", version = "0.0.5" } rustfs = { path = "./rustfs", version = "0.0.1" }
rustfs-kms = { path = "crates/kms", version = "0.0.5" } rustfs-zip = { path = "./crates/zip", version = "0.0.1" }
rustfs-lock = { path = "crates/lock", version = "0.0.5" } rustfs-config = { path = "./crates/config", version = "0.0.1" }
rustfs-madmin = { path = "crates/madmin", version = "0.0.5" } rustfs-obs = { path = "crates/obs", version = "0.0.1" }
rustfs-mcp = { path = "crates/mcp", version = "0.0.5" } rustfs-event-notifier = { path = "crates/event-notifier", version = "0.0.1" }
rustfs-notify = { path = "crates/notify", version = "0.0.5" } rustfs-utils = { path = "crates/utils", version = "0.0.1" }
rustfs-obs = { path = "crates/obs", version = "0.0.5" } workers = { path = "./common/workers", version = "0.0.1" }
rustfs-policy = { path = "crates/policy", version = "0.0.5" } tokio-tar = "0.3.1"
rustfs-protos = { path = "crates/protos", version = "0.0.5" } atoi = "2.0.0"
rustfs-rio = { path = "crates/rio", version = "0.0.5" }
rustfs-s3select-api = { path = "crates/s3select-api", version = "0.0.5" }
rustfs-s3select-query = { path = "crates/s3select-query", version = "0.0.5" }
rustfs-signer = { path = "crates/signer", version = "0.0.5" }
rustfs-targets = { path = "crates/targets", version = "0.0.5" }
rustfs-utils = { path = "crates/utils", version = "0.0.5" }
rustfs-workers = { path = "crates/workers", version = "0.0.5" }
rustfs-zip = { path = "./crates/zip", version = "0.0.5" }
# Async Runtime and Networking
async-channel = "2.5.0"
async-compression = { version = "0.4.19" }
async-recursion = "1.1.1" async-recursion = "1.1.1"
async-trait = "0.1.89" async-trait = "0.1.88"
axum = "0.8.7" atomic_enum = "0.3.0"
axum-extra = "0.12.2" aws-sdk-s3 = "1.29.0"
axum-server = { version = "0.8.0", features = ["tls-rustls-no-provider"], default-features = false } axum = "0.8.4"
axum-extra = "0.10.1"
axum-server = { version = "0.7.2", features = ["tls-rustls"] }
backon = "1.5.1"
blake2 = "0.10.6"
bytes = "1.10.1"
bytesize = "2.0.1"
byteorder = "1.5.0"
chrono = { version = "0.4.41", features = ["serde"] }
clap = { version = "4.5.39", features = ["derive", "env"] }
config = "0.15.11"
const-str = { version = "0.6.2", features = ["std", "proc"] }
datafusion = "46.0.1"
derive_builder = "0.20.2"
dioxus = { version = "0.6.3", features = ["router"] }
dirs = "6.0.0"
flatbuffers = "25.2.10"
flexi_logger = { version = "0.30.2", features = ["trc"] }
futures = "0.3.31" futures = "0.3.31"
futures-core = "0.3.31" futures-core = "0.3.31"
futures-util = "0.3.31" futures-util = "0.3.31"
pollster = "0.4.0" glob = "0.3.2"
hyper = { version = "1.8.1", features = ["http2", "http1", "server"] } hex = "0.4.3"
hyper-rustls = { version = "0.27.7", default-features = false, features = ["native-tokio", "http1", "tls12", "logging", "http2", "ring", "webpki-roots"] }
hyper-util = { version = "0.1.19", features = ["tokio", "server-auto", "server-graceful"] }
http = "1.4.0"
http-body = "1.0.1"
reqwest = { version = "0.12.26", default-features = false, features = ["rustls-tls-webpki-roots", "charset", "http2", "system-proxy", "stream", "json", "blocking"] }
socket2 = "0.6.1"
tokio = { version = "1.48.0", features = ["fs", "rt-multi-thread"] }
tokio-rustls = { version = "0.26.4", default-features = false, features = ["logging", "tls12", "ring"] }
tokio-stream = { version = "0.1.17" }
tokio-test = "0.4.4"
tokio-util = { version = "0.7.17", features = ["io", "compat"] }
tonic = { version = "0.14.2", features = ["gzip"] }
tonic-prost = { version = "0.14.2" }
tonic-prost-build = { version = "0.14.2" }
tower = { version = "0.5.2", features = ["timeout"] }
tower-http = { version = "0.6.8", features = ["cors"] }
# Serialization and Data Formats
bytes = { version = "1.11.0", features = ["serde"] }
bytesize = "2.3.1"
byteorder = "1.5.0"
flatbuffers = "25.9.23"
form_urlencoded = "1.2.2"
prost = "0.14.1"
quick-xml = "0.38.4"
rmcp = { version = "0.12.0" }
rmp = { version = "0.8.14" }
rmp-serde = { version = "1.3.0" }
serde = { version = "1.0.228", features = ["derive"] }
serde_json = { version = "1.0.145", features = ["raw_value"] }
serde_urlencoded = "0.7.1"
schemars = "1.1.0"
# Cryptography and Security
aes-gcm = { version = "0.11.0-rc.2", features = ["rand_core"] }
argon2 = { version = "0.6.0-rc.5" }
blake3 = { version = "1.8.2", features = ["rayon", "mmap"] }
chacha20poly1305 = { version = "0.11.0-rc.2" }
crc-fast = "1.6.0"
hmac = { version = "0.13.0-rc.3" }
jsonwebtoken = { version = "10.2.0", features = ["rust_crypto"] }
pbkdf2 = "0.13.0-rc.5"
rsa = { version = "0.10.0-rc.10" }
rustls = { version = "0.23.35", features = ["ring", "logging", "std", "tls12"], default-features = false }
rustls-pemfile = "2.2.0"
rustls-pki-types = "1.13.2"
sha1 = "0.11.0-rc.3"
sha2 = "0.11.0-rc.3"
subtle = "2.6"
zeroize = { version = "1.8.2", features = ["derive"] }
# Time and Date
chrono = { version = "0.4.42", features = ["serde"] }
humantime = "2.3.0"
time = { version = "0.3.44", features = ["std", "parsing", "formatting", "macros", "serde"] }
# Utilities and Tools
anyhow = "1.0.100"
arc-swap = "1.7.1"
astral-tokio-tar = "0.5.6"
atoi = "2.0.0"
atomic_enum = "0.3.0"
aws-config = { version = "1.8.12" }
aws-credential-types = { version = "1.2.11" }
aws-sdk-s3 = { version = "1.117.0", default-features = false, features = ["sigv4a", "rustls", "rt-tokio"] }
aws-smithy-types = { version = "1.3.5" }
base64 = "0.22.1"
base64-simd = "0.8.0"
brotli = "8.0.2"
cfg-if = "1.0.4"
clap = { version = "4.5.53", features = ["derive", "env"] }
const-str = { version = "0.7.1", features = ["std", "proc"] }
convert_case = "0.10.0"
criterion = { version = "0.8", features = ["html_reports"] }
crossbeam-queue = "0.3.12"
datafusion = "51.0.0"
derive_builder = "0.20.2"
enumset = "1.1.10"
faster-hex = "0.10.0"
flate2 = "1.1.5"
flexi_logger = { version = "0.31.7", features = ["trc", "dont_minimize_extra_stacks", "compress", "kv", "json"] }
glob = "0.3.3"
google-cloud-storage = "1.5.0"
google-cloud-auth = "1.3.0"
hashbrown = { version = "0.16.1", features = ["serde", "rayon"] }
heed = { version = "0.22.0" }
hex-simd = "0.8.0"
highway = { version = "1.3.0" } highway = { version = "1.3.0" }
ipnetwork = { version = "0.21.1", features = ["serde"] } hyper = "1.6.0"
hyper-util = { version = "0.1.14", features = [
"tokio",
"server-auto",
"server-graceful",
] }
http = "1.3.1"
http-body = "1.0.1"
humantime = "2.2.0"
include_dir = "0.7.4"
jsonwebtoken = "9.3.1"
keyring = { version = "3.6.2", features = [
"apple-native",
"windows-native",
"sync-secret-service",
] }
lazy_static = "1.5.0" lazy_static = "1.5.0"
libc = "0.2.178" libsystemd = { version = "0.7.2" }
libsystemd = "0.7.2" local-ip-address = "0.6.5"
local-ip-address = "0.6.8" matchit = "0.8.4"
lz4 = "1.28.1" md-5 = "0.10.6"
matchit = "0.9.0" mime = "0.3.17"
md-5 = "0.11.0-rc.3"
md5 = "0.8.0"
mime_guess = "2.0.5" mime_guess = "2.0.5"
moka = { version = "0.12.11", features = ["future"] }
netif = "0.1.6" netif = "0.1.6"
nix = { version = "0.30.1", features = ["fs"] } nix = { version = "0.30.1", features = ["fs"] }
nu-ansi-term = "0.50.3" nu-ansi-term = "0.50.1"
num_cpus = { version = "1.17.0" } num_cpus = { version = "1.17.0" }
nvml-wrapper = "0.11.0" nvml-wrapper = "0.11.0"
object_store = "0.12.4" object_store = "0.11.2"
parking_lot = "0.12.5" once_cell = "1.21.3"
path-absolutize = "3.1.1" opentelemetry = { version = "0.30.0" }
path-clean = "1.0.1" opentelemetry-appender-tracing = { version = "0.30.1", features = [
"experimental_use_tracing_span_context",
"experimental_metadata_attributes",
"spec_unstable_logs_enabled"
] }
opentelemetry_sdk = { version = "0.30.0" }
opentelemetry-stdout = { version = "0.30.0" }
opentelemetry-otlp = { version = "0.30.0", default-features = false, features = [
"grpc-tonic", "gzip-tonic", "trace", "metrics", "logs", "internal-logs"
] }
opentelemetry-semantic-conventions = { version = "0.30.0", features = [
"semconv_experimental",
] }
parking_lot = "0.12.4"
percent-encoding = "2.3.1"
pin-project-lite = "0.2.16" pin-project-lite = "0.2.16"
pretty_assertions = "1.4.1" # pin-utils = "0.1.0"
rand = { version = "0.10.0-rc.5", features = ["serde"] } prost = "0.13.5"
rayon = "1.11.0" prost-build = "0.13.5"
reed-solomon-simd = { version = "3.1.0" } protobuf = "3.7"
regex = { version = "1.12.2" } rand = "0.8.5"
rumqttc = { version = "0.25.1" } rdkafka = { version = "0.37.0", features = ["tokio"] }
rust-embed = { version = "8.9.0" } reed-solomon-erasure = { version = "6.0.0", features = ["simd-accel"] }
rustc-hash = { version = "2.1.1" } regex = { version = "1.11.1" }
s3s = { version = "0.12.0-rc.6", features = ["minio"], git = "https://github.com/s3s-project/s3s.git", branch = "main" } reqwest = { version = "0.12.19", default-features = false, features = [
serial_test = "3.2.0" "rustls-tls",
shadow-rs = { version = "1.4.0", default-features = false } "charset",
siphasher = "1.0.1" "http2",
smallvec = { version = "1.15.1", features = ["serde"] } "system-proxy",
smartstring = "1.0.1" "stream",
snafu = "0.8.9" "json",
snap = "1.1.1" "blocking",
starshard = { version = "0.6.0", features = ["rayon", "async", "serde"] } ] }
strum = { version = "0.27.2", features = ["derive"] } rfd = { version = "0.15.3", default-features = false, features = [
sysctl = "0.7.1" "xdg-portal",
sysinfo = "0.37.2" "tokio",
temp-env = "0.3.6" ] }
tempfile = "3.23.0" rmp = "0.8.14"
rmp-serde = "1.3.0"
rumqttc = { version = "0.24" }
rust-embed = { version = "8.7.2" }
rustfs-rsc = "2025.506.1"
rustls = { version = "0.23.27" }
rustls-pki-types = "1.12.0"
rustls-pemfile = "2.2.0"
s3s = { git = "https://github.com/Nugine/s3s.git", rev = "4733cdfb27b2713e832967232cbff413bb768c10" }
s3s-policy = { git = "https://github.com/Nugine/s3s.git", rev = "4733cdfb27b2713e832967232cbff413bb768c10" }
shadow-rs = { version = "1.1.1", default-features = false }
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140"
serde_urlencoded = "0.7.1"
serde_with = "3.12.0"
sha2 = "0.10.9"
smallvec = { version = "1.15.0", features = ["serde"] }
snafu = "0.8.6"
socket2 = "0.5.10"
strum = { version = "0.27.1", features = ["derive"] }
sysinfo = "0.35.2"
tempfile = "3.20.0"
test-case = "3.3.1" test-case = "3.3.1"
thiserror = "2.0.17" thiserror = "2.0.12"
tracing = { version = "0.1.44" } time = { version = "0.3.41", features = [
tracing-appender = "0.2.4" "std",
"parsing",
"formatting",
"macros",
"serde",
] }
tokio = { version = "1.45.1", features = ["fs", "rt-multi-thread"] }
tonic = { version = "0.13.1", features = ["gzip"] }
tonic-build = { version = "0.13.1" }
tokio-rustls = { version = "0.26.2", default-features = false }
tokio-stream = { version = "0.1.17" }
tokio-util = { version = "0.7.15", features = ["io", "compat"] }
tower = { version = "0.5.2", features = ["timeout"] }
tower-http = { version = "0.6.6", features = ["cors"] }
tracing = "0.1.41"
tracing-core = "0.1.34"
tracing-error = "0.2.1" tracing-error = "0.2.1"
tracing-opentelemetry = "0.32.0" tracing-subscriber = { version = "0.3.19", features = ["env-filter", "time"] }
tracing-subscriber = { version = "0.3.22", features = ["env-filter", "time"] } tracing-appender = "0.2.3"
tracing-opentelemetry = "0.31.0"
transform-stream = "0.3.1" transform-stream = "0.3.1"
url = "2.5.7" url = "2.5.4"
urlencoding = "2.1.3" urlencoding = "2.1.3"
uuid = { version = "1.19.0", features = ["v4", "fast-rng", "macro-diagnostics"] } uuid = { version = "1.17.0", features = [
vaultrs = { version = "0.7.4" } "v4",
walkdir = "2.5.0" "fast-rng",
wildmatch = { version = "2.6.1", features = ["serde"] } "macro-diagnostics",
] }
winapi = { version = "0.3.9" } winapi = { version = "0.3.9" }
xxhash-rust = { version = "0.8.15", features = ["xxh64", "xxh3"] }
zip = "6.0.0"
zstd = "0.13.3"
# Observability and Metrics
metrics = "0.24.3"
opentelemetry = { version = "0.31.0" }
opentelemetry-appender-tracing = { version = "0.31.1", features = ["experimental_use_tracing_span_context", "experimental_metadata_attributes", "spec_unstable_logs_enabled"] }
opentelemetry-otlp = { version = "0.31.0", features = ["gzip-http", "reqwest-rustls"] }
opentelemetry_sdk = { version = "0.31.0" }
opentelemetry-semantic-conventions = { version = "0.31.0", features = ["semconv_experimental"] }
opentelemetry-stdout = { version = "0.31.0" }
# Performance Analysis and Memory Profiling
mimalloc = "0.1"
# Use tikv-jemallocator as memory allocator and enable performance analysis
tikv-jemallocator = { version = "0.6", features = ["profiling", "stats", "unprefixed_malloc_on_supported_platforms", "background_threads"] }
# Used to control and obtain statistics for jemalloc at runtime
tikv-jemalloc-ctl = { version = "0.6", features = ["use_std", "stats", "profiling"] }
# Used to generate pprof-compatible memory profiling data and support symbolization and flame graphs
jemalloc_pprof = { version = "0.8.1", features = ["symbolize", "flamegraph"] }
# Used to generate CPU performance analysis data and flame diagrams
pprof = { version = "0.15.0", features = ["flamegraph", "protobuf-codec"] }
[profile.wasm-dev]
inherits = "dev"
opt-level = 1
[workspace.metadata.cargo-shear] [profile.server-dev]
ignored = ["rustfs", "rustfs-mcp"] inherits = "dev"
[profile.android-dev]
inherits = "dev"
[profile.release] [profile.release]
opt-level = 3 opt-level = 3
lto = "thin"
codegen-units = 1
panic = "abort" # Optional, remove the panic expansion code
strip = true # strip symbol information to reduce binary size
[profile.production] [profile.production]
inherits = "release" inherits = "release"

View File

@@ -2,8 +2,6 @@
## 📋 Code Quality Requirements ## 📋 Code Quality Requirements
For instructions on setting up and running the local development environment, please see [Development Guide](docs/DEVELOPMENT.md).
### 🔧 Code Formatting Rules ### 🔧 Code Formatting Rules
**MANDATORY**: All code must be properly formatted before committing. This project enforces strict formatting standards to maintain code consistency and readability. **MANDATORY**: All code must be properly formatted before committing. This project enforces strict formatting standards to maintain code consistency and readability.
@@ -13,25 +11,21 @@ For instructions on setting up and running the local development environment, pl
Before every commit, you **MUST**: Before every commit, you **MUST**:
1. **Format your code**: 1. **Format your code**:
```bash ```bash
cargo fmt --all cargo fmt --all
``` ```
2. **Verify formatting**: 2. **Verify formatting**:
```bash ```bash
cargo fmt --all --check cargo fmt --all --check
``` ```
3. **Pass clippy checks**: 3. **Pass clippy checks**:
```bash ```bash
cargo clippy --all-targets --all-features -- -D warnings cargo clippy --all-targets --all-features -- -D warnings
``` ```
4. **Ensure compilation**: 4. **Ensure compilation**:
```bash ```bash
cargo check --all-targets cargo check --all-targets
``` ```
@@ -142,7 +136,6 @@ Install the `rust-analyzer` extension and add to your `settings.json`:
#### Other IDEs #### Other IDEs
Configure your IDE to: Configure your IDE to:
- Use the project's `rustfmt.toml` configuration - Use the project's `rustfmt.toml` configuration
- Format on save - Format on save
- Run clippy checks - Run clippy checks

View File

@@ -1,94 +1,17 @@
FROM alpine:3.22 AS build FROM alpine:latest
ARG TARGETARCH # RUN apk add --no-cache <package-name>
ARG RELEASE=latest
RUN apk add --no-cache ca-certificates curl unzip WORKDIR /app
WORKDIR /build
RUN set -eux; \ RUN mkdir -p /data/rustfs0 /data/rustfs1 /data/rustfs2 /data/rustfs3
case "$TARGETARCH" in \
amd64) ARCH_SUBSTR="x86_64-musl" ;; \ COPY ./target/x86_64-unknown-linux-musl/release/rustfs /app/rustfs
arm64) ARCH_SUBSTR="aarch64-musl" ;; \
*) echo "Unsupported TARGETARCH=$TARGETARCH" >&2; exit 1 ;; \ RUN chmod +x /app/rustfs
esac; \
if [ "$RELEASE" = "latest" ]; then \ EXPOSE 9000
TAG="$(curl -fsSL https://api.github.com/repos/rustfs/rustfs/releases \ EXPOSE 9001
| grep -o '"tag_name": "[^"]*"' | cut -d'"' -f4 | head -n 1)"; \
else \
TAG="$RELEASE"; \
fi; \
echo "Using tag: $TAG (arch pattern: $ARCH_SUBSTR)"; \
# Find download URL in assets list for this tag that contains arch substring and ends with .zip
URL="$(curl -fsSL "https://api.github.com/repos/rustfs/rustfs/releases/tags/$TAG" \
| grep -o "\"browser_download_url\": \"[^\"]*${ARCH_SUBSTR}[^\"]*\\.zip\"" \
| cut -d'"' -f4 | head -n 1)"; \
if [ -z "$URL" ]; then echo "Failed to locate release asset for $ARCH_SUBSTR at tag $TAG" >&2; exit 1; fi; \
echo "Downloading: $URL"; \
curl -fL "$URL" -o rustfs.zip; \
unzip -q rustfs.zip -d /build; \
# If binary is not in root directory, try to locate and move from zip to /build/rustfs
if [ ! -x /build/rustfs ]; then \
BIN_PATH="$(unzip -Z -1 rustfs.zip | grep -E '(^|/)rustfs$' | head -n 1 || true)"; \
if [ -n "$BIN_PATH" ]; then \
mkdir -p /build/.tmp && unzip -q rustfs.zip "$BIN_PATH" -d /build/.tmp && \
mv "/build/.tmp/$BIN_PATH" /build/rustfs; \
fi; \
fi; \
[ -x /build/rustfs ] || { echo "rustfs binary not found in asset" >&2; exit 1; }; \
chmod +x /build/rustfs; \
rm -rf rustfs.zip /build/.tmp || true
FROM alpine:3.22 CMD ["/app/rustfs"]
ARG RELEASE=latest
ARG BUILD_DATE
ARG VCS_REF
LABEL name="RustFS" \
vendor="RustFS Team" \
maintainer="RustFS Team <dev@rustfs.com>" \
version="v${RELEASE#v}" \
release="${RELEASE}" \
build-date="${BUILD_DATE}" \
vcs-ref="${VCS_REF}" \
summary="High-performance distributed object storage system compatible with S3 API" \
description="RustFS is a distributed object storage system written in Rust, supporting erasure coding, multi-tenant management, and observability." \
url="https://rustfs.com" \
license="Apache-2.0"
RUN apk add --no-cache ca-certificates coreutils curl
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /build/rustfs /usr/bin/rustfs
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /usr/bin/rustfs /entrypoint.sh
RUN addgroup -g 10001 -S rustfs && \
adduser -u 10001 -G rustfs -S rustfs -D && \
mkdir -p /data /logs && \
chown -R rustfs:rustfs /data /logs && \
chmod 0750 /data /logs
ENV RUSTFS_ADDRESS=":9000" \
RUSTFS_CONSOLE_ADDRESS=":9001" \
RUSTFS_ACCESS_KEY="rustfsadmin" \
RUSTFS_SECRET_KEY="rustfsadmin" \
RUSTFS_CONSOLE_ENABLE="true" \
RUSTFS_EXTERNAL_ADDRESS="" \
RUSTFS_CORS_ALLOWED_ORIGINS="*" \
RUSTFS_CONSOLE_CORS_ALLOWED_ORIGINS="*" \
RUSTFS_VOLUMES="/data" \
RUST_LOG="warn"
EXPOSE 9000 9001
VOLUME ["/data"]
USER rustfs
ENTRYPOINT ["/entrypoint.sh"]
CMD ["rustfs"]

21
Dockerfile.obs Normal file
View File

@@ -0,0 +1,21 @@
FROM ubuntu:latest
# RUN apk add --no-cache <package-name>
# 如果 rustfs 有依赖,可以在这里添加,例如:
# RUN apk add --no-cache openssl
# RUN apk add --no-cache bash # 安装 Bash
WORKDIR /app
# 创建与 RUSTFS_VOLUMES 一致的目录
RUN mkdir -p /root/data/target/volume/test1 /root/data/target/volume/test2 /root/data/target/volume/test3 /root/data/target/volume/test4
# COPY ./target/x86_64-unknown-linux-musl/release/rustfs /app/rustfs
COPY ./target/x86_64-unknown-linux-gnu/release/rustfs /app/rustfs
RUN chmod +x /app/rustfs
EXPOSE 9000
EXPOSE 9002
CMD ["/app/rustfs"]

View File

@@ -1,223 +0,0 @@
# syntax=docker/dockerfile:1.6
# Multi-stage Dockerfile for RustFS - LOCAL DEVELOPMENT ONLY
#
# IMPORTANT: This Dockerfile builds RustFS from source for local development and testing.
# CI/CD uses the production Dockerfile with prebuilt binaries instead.
#
# Example:
# docker build -f Dockerfile.source -t rustfs:dev-local .
# docker run --rm -p 9000:9000 rustfs:dev-local
#
# Supports cross-compilation for amd64 and arm64 via TARGETPLATFORM.
ARG TARGETPLATFORM
ARG BUILDPLATFORM
# -----------------------------
# Build stage
# -----------------------------
FROM rust:1.88-bookworm AS builder
# Re-declare args after FROM
ARG TARGETPLATFORM
ARG BUILDPLATFORM
# Debug: print platforms
RUN echo "Build info -> BUILDPLATFORM=${BUILDPLATFORM}, TARGETPLATFORM=${TARGETPLATFORM}"
# Install build toolchain and headers
# Use distro packages for protoc/flatc to avoid host-arch mismatch
RUN set -eux; \
export DEBIAN_FRONTEND=noninteractive; \
apt-get update; \
apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
curl \
git \
pkg-config \
libssl-dev \
lld \
protobuf-compiler \
flatbuffers-compiler \
gcc-aarch64-linux-gnu \
gcc-x86-64-linux-gnu; \
rm -rf /var/lib/apt/lists/*
# Optional: cross toolchain for aarch64 (only when targeting linux/arm64)
RUN set -eux; \
if [ "${TARGETPLATFORM:-linux/amd64}" = "linux/arm64" ]; then \
export DEBIAN_FRONTEND=noninteractive; \
apt-get update; \
apt-get install -y --no-install-recommends gcc-aarch64-linux-gnu; \
rm -rf /var/lib/apt/lists/*; \
fi
# Add Rust targets for both arches (to support cross-builds on multi-arch runners)
RUN set -eux; \
rustup target add x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; \
rustup component add rust-std-x86_64-unknown-linux-gnu rust-std-aarch64-unknown-linux-gnu
# Cross-compilation environment (used only when targeting aarch64)
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
ENV CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
ENV CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc
ENV CC_x86_64_unknown_linux_gnu=x86_64-linux-gnu-gcc
ENV CXX_x86_64_unknown_linux_gnu=x86_64-linux-gnu-g++
WORKDIR /usr/src/rustfs
# Layered copy to maximize caching:
# 1) top-level manifests
COPY Cargo.toml Cargo.lock ./
# 2) workspace member manifests (adjust if workspace layout changes)
COPY rustfs/Cargo.toml rustfs/Cargo.toml
COPY crates/*/Cargo.toml crates/
# Pre-fetch dependencies for better caching
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
cargo fetch --locked || true
# 3) copy full sources (this is the main cache invalidation point)
COPY . .
# Cargo build configuration for lean release artifacts
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true \
CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse \
CARGO_INCREMENTAL=0 \
CARGO_PROFILE_RELEASE_DEBUG=false \
CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO=off \
CARGO_PROFILE_RELEASE_STRIP=symbols
# Generate protobuf/flatbuffers code (uses protoc/flatc from distro)
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/usr/src/rustfs/target \
cargo run --bin gproto
# Build RustFS (target depends on TARGETPLATFORM)
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=/usr/src/rustfs/target \
set -eux; \
case "${TARGETPLATFORM:-linux/amd64}" in \
linux/amd64) \
echo "Building for x86_64-unknown-linux-gnu"; \
cargo build --release --locked --target x86_64-unknown-linux-gnu --bin rustfs -j "$(nproc)"; \
install -m 0755 target/x86_64-unknown-linux-gnu/release/rustfs /usr/local/bin/rustfs \
;; \
linux/arm64) \
echo "Building for aarch64-unknown-linux-gnu"; \
cargo build --release --locked --target aarch64-unknown-linux-gnu --bin rustfs -j "$(nproc)"; \
install -m 0755 target/aarch64-unknown-linux-gnu/release/rustfs /usr/local/bin/rustfs \
;; \
*) \
echo "Unsupported TARGETPLATFORM=${TARGETPLATFORM}" >&2; exit 1 \
;; \
esac
# -----------------------------
# Development stage (keeps toolchain)
# -----------------------------
FROM builder AS dev
ARG BUILD_DATE
ARG VCS_REF
LABEL name="RustFS (dev-source)" \
maintainer="RustFS Team" \
build-date="${BUILD_DATE}" \
vcs-ref="${VCS_REF}" \
description="RustFS - local development with Rust toolchain."
# Install runtime dependencies that might be missing in partial builder
# (builder already has build-essential, lld, etc.)
WORKDIR /app
ENV CARGO_INCREMENTAL=1
# Ensure we have the same default env vars available
ENV RUSTFS_ADDRESS=":9000" \
RUSTFS_ACCESS_KEY="rustfsadmin" \
RUSTFS_SECRET_KEY="rustfsadmin" \
RUSTFS_CONSOLE_ENABLE="true" \
RUSTFS_VOLUMES="/data" \
RUST_LOG="warn" \
RUSTFS_OBS_LOG_DIRECTORY="/logs" \
RUSTFS_USERNAME="rustfs" \
RUSTFS_GROUPNAME="rustfs" \
RUSTFS_UID="1000" \
RUSTFS_GID="1000"
# Note: We don't COPY source here because we expect it to be mounted at /app
# We rely on cargo run to build and run
EXPOSE 9000 9001
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["cargo", "run", "--bin", "rustfs", "--"]
# -----------------------------
# Runtime stage (Ubuntu minimal)
# -----------------------------
FROM ubuntu:22.04
ARG BUILD_DATE
ARG VCS_REF
LABEL name="RustFS (dev-local)" \
maintainer="RustFS Team" \
build-date="${BUILD_DATE}" \
vcs-ref="${VCS_REF}" \
description="RustFS - local development image built from source (NOT for production)."
# Minimal runtime deps: certificates + tzdata + coreutils (for chroot --userspec)
RUN set -eux; \
export DEBIAN_FRONTEND=noninteractive; \
apt-get update; \
apt-get install -y --no-install-recommends \
ca-certificates \
tzdata \
coreutils; \
rm -rf /var/lib/apt/lists/*
# Create a conventional runtime user/group (final switch happens in entrypoint via chroot --userspec)
RUN set -eux; \
groupadd -g 1000 rustfs; \
useradd -u 1000 -g rustfs -M -s /usr/sbin/nologin rustfs
WORKDIR /app
# Prepare data/log directories with sane defaults
RUN set -eux; \
mkdir -p /data /logs; \
chown -R rustfs:rustfs /data /logs /app; \
chmod 0750 /data /logs
# Copy the freshly built binary and the entrypoint
COPY --from=builder /usr/local/bin/rustfs /usr/bin/rustfs
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /usr/bin/rustfs /entrypoint.sh
# Default environment (override in docker run/compose as needed)
ENV RUSTFS_ADDRESS=":9000" \
RUSTFS_ACCESS_KEY="rustfsadmin" \
RUSTFS_SECRET_KEY="rustfsadmin" \
RUSTFS_CONSOLE_ENABLE="true" \
RUSTFS_VOLUMES="/data" \
RUST_LOG="warn" \
RUSTFS_USERNAME="rustfs" \
RUSTFS_GROUPNAME="rustfs" \
RUSTFS_UID="1000" \
RUSTFS_GID="1000"
EXPOSE 9000
VOLUME ["/data"]
# Keep root here; entrypoint will drop privileges using chroot --userspec
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/usr/bin/rustfs"]

258
Justfile
View File

@@ -1,258 +0,0 @@
DOCKER_CLI := env("DOCKER_CLI", "docker")
IMAGE_NAME := env("IMAGE_NAME", "rustfs:v1.0.0")
DOCKERFILE_SOURCE := env("DOCKERFILE_SOURCE", "Dockerfile.source")
DOCKERFILE_PRODUCTION := env("DOCKERFILE_PRODUCTION", "Dockerfile")
CONTAINER_NAME := env("CONTAINER_NAME", "rustfs-dev")
[group("📒 Help")]
[private]
default:
@just --list --list-heading $'🦀 RustFS justfile manual page:\n'
[doc("show help")]
[group("📒 Help")]
help: default
[doc("run `cargo fmt` to format codes")]
[group("👆 Code Quality")]
fmt:
@echo "🔧 Formatting code..."
cargo fmt --all
[doc("run `cargo fmt` in check mode")]
[group("👆 Code Quality")]
fmt-check:
@echo "📝 Checking code formatting..."
cargo fmt --all --check
[doc("run `cargo clippy`")]
[group("👆 Code Quality")]
clippy:
@echo "🔍 Running clippy checks..."
cargo clippy --all-targets --all-features --fix --allow-dirty -- -D warnings
[doc("run `cargo check`")]
[group("👆 Code Quality")]
check:
@echo "🔨 Running compilation check..."
cargo check --all-targets
[doc("run `cargo test`")]
[group("👆 Code Quality")]
test:
@echo "🧪 Running tests..."
cargo nextest run --all --exclude e2e_test
cargo test --all --doc
[doc("run `fmt` `clippy` `check` `test` at once")]
[group("👆 Code Quality")]
pre-commit: fmt clippy check test
@echo "✅ All pre-commit checks passed!"
[group("🤔 Git")]
setup-hooks:
@echo "🔧 Setting up git hooks..."
chmod +x .git/hooks/pre-commit
@echo "✅ Git hooks setup complete!"
[doc("use `release` mode for building")]
[group("🔨 Build")]
build:
@echo "🔨 Building RustFS using build-rustfs.sh script..."
./build-rustfs.sh
[doc("use `debug` mode for building")]
[group("🔨 Build")]
build-dev:
@echo "🔨 Building RustFS in development mode..."
./build-rustfs.sh --dev
[group("🔨 Build")]
[private]
build-target target:
@echo "🔨 Building rustfs for {{ target }}..."
@echo "💡 On macOS/Windows, use 'make build-docker' or 'make docker-dev' instead"
./build-rustfs.sh --platform {{ target }}
[doc("use `x86_64-unknown-linux-musl` target for building")]
[group("🔨 Build")]
build-musl: (build-target "x86_64-unknown-linux-musl")
[doc("use `x86_64-unknown-linux-gnu` target for building")]
[group("🔨 Build")]
build-gnu: (build-target "x86_64-unknown-linux-gnu")
[doc("use `aarch64-unknown-linux-musl` target for building")]
[group("🔨 Build")]
build-musl-arm64: (build-target "aarch64-unknown-linux-musl")
[doc("use `aarch64-unknown-linux-gnu` target for building")]
[group("🔨 Build")]
build-gnu-arm64: (build-target "aarch64-unknown-linux-gnu")
[doc("build and deploy to server")]
[group("🔨 Build")]
deploy-dev ip: build-musl
@echo "🚀 Deploying to dev server: {{ ip }}"
./scripts/dev_deploy.sh {{ ip }}
[group("🔨 Build")]
[private]
build-cross-all-pre:
@echo "🔧 Building all target architectures..."
@echo "💡 On macOS/Windows, use 'make docker-dev' for reliable multi-arch builds"
@echo "🔨 Generating protobuf code..."
-cargo run --bin gproto
[doc("build all targets at once")]
[group("🔨 Build")]
build-cross-all: build-cross-all-pre && build-gnu build-gnu-arm64 build-musl build-musl-arm64
# ========================================================================================
# Docker Multi-Architecture Builds (Primary Methods)
# ========================================================================================
[doc("build an image and run it")]
[group("🐳 Build Image")]
build-docker os="rockylinux9.3" cli=(DOCKER_CLI) dockerfile=(DOCKERFILE_SOURCE):
#!/usr/bin/env bash
SOURCE_BUILD_IMAGE_NAME="rustfs/rustfs-{{ os }}:v1"
SOURCE_BUILD_CONTAINER_NAME="rustfs-{{ os }}-build"
BUILD_CMD="/root/.cargo/bin/cargo build --release --bin rustfs --target-dir /root/s3-rustfs/target/{{ os }}"
echo "🐳 Building RustFS using Docker ({{ os }})..."
{{ cli }} buildx build -t $SOURCE_BUILD_IMAGE_NAME -f {{ dockerfile }} .
{{ cli }} run --rm --name $SOURCE_BUILD_CONTAINER_NAME -v $(pwd):/root/s3-rustfs -it $SOURCE_BUILD_IMAGE_NAME $BUILD_CMD
[doc("build an image")]
[group("🐳 Build Image")]
docker-buildx:
@echo "🏗️ Building multi-architecture production Docker images with buildx..."
./docker-buildx.sh
[doc("build an image and push it")]
[group("🐳 Build Image")]
docker-buildx-push:
@echo "🚀 Building and pushing multi-architecture production Docker images with buildx..."
./docker-buildx.sh --push
[doc("build an image with a version")]
[group("🐳 Build Image")]
docker-buildx-version version:
@echo "🏗️ Building multi-architecture production Docker images (version: {{ version }}..."
./docker-buildx.sh --release {{ version }}
[doc("build an image with a version and push it")]
[group("🐳 Build Image")]
docker-buildx-push-version version:
@echo "🚀 Building and pushing multi-architecture production Docker images (version: {{ version }}..."
./docker-buildx.sh --release {{ version }} --push
[doc("build an image with a version and push it to registry")]
[group("🐳 Build Image")]
docker-dev-push registry cli=(DOCKER_CLI) source=(DOCKERFILE_SOURCE):
@echo "🚀 Building and pushing multi-architecture development Docker images..."
@echo "💡 push to registry: {{ registry }}"
{{ cli }} buildx build \
--platform linux/amd64,linux/arm64 \
--file {{ source }} \
--tag {{ registry }}/rustfs:source-latest \
--tag {{ registry }}/rustfs:dev-latest \
--push \
.
# Local production builds using direct buildx (alternative to docker-buildx.sh)
[group("🐳 Build Image")]
docker-buildx-production-local cli=(DOCKER_CLI) source=(DOCKERFILE_PRODUCTION):
@echo "🏗️ Building single-architecture production Docker image locally..."
@echo "💡 Alternative to docker-buildx.sh for local testing"
{{ cli }} buildx build \
--file {{ source }} \
--tag rustfs:production-latest \
--tag rustfs:latest \
--load \
--build-arg RELEASE=latest \
.
# Development/Source builds using direct buildx commands
[group("🐳 Build Image")]
docker-dev cli=(DOCKER_CLI) source=(DOCKERFILE_SOURCE):
@echo "🏗️ Building multi-architecture development Docker images with buildx..."
@echo "💡 This builds from source code and is intended for local development and testing"
@echo "⚠️ Multi-arch images cannot be loaded locally, use docker-dev-push to push to registry"
{{ cli }} buildx build \
--platform linux/amd64,linux/arm64 \
--file {{ source }} \
--tag rustfs:source-latest \
--tag rustfs:dev-latest \
.
[group("🐳 Build Image")]
docker-dev-local cli=(DOCKER_CLI) source=(DOCKERFILE_SOURCE):
@echo "🏗️ Building single-architecture development Docker image for local use..."
@echo "💡 This builds from source code for the current platform and loads locally"
{{ cli }} buildx build \
--file {{ source }} \
--tag rustfs:source-latest \
--tag rustfs:dev-latest \
--load \
.
# ========================================================================================
# Single Architecture Docker Builds (Traditional)
# ========================================================================================
[group("🐳 Build Image")]
docker-build-production cli=(DOCKER_CLI) source=(DOCKERFILE_PRODUCTION):
@echo "🏗️ Building single-architecture production Docker image..."
@echo "💡 Consider using 'make docker-buildx-production-local' for multi-arch support"
{{ cli }} build -f {{ source }} -t rustfs:latest .
[group("🐳 Build Image")]
docker-build-source cli=(DOCKER_CLI) source=(DOCKERFILE_SOURCE):
@echo "🏗️ Building single-architecture source Docker image..."
@echo "💡 Consider using 'make docker-dev-local' for multi-arch support"
{{ cli }} build -f {{ source }} -t rustfs:source .
# ========================================================================================
# Development Environment
# ========================================================================================
[group("🏃 Running")]
dev-env-start cli=(DOCKER_CLI) source=(DOCKERFILE_SOURCE) container=(CONTAINER_NAME):
@echo "🚀 Starting development environment..."
{{ cli }} buildx build \
--file {{ source }} \
--tag rustfs:dev \
--load \
.
-{{ cli }} stop {{ container }} 2>/dev/null
-{{ cli }} rm {{ container }} 2>/dev/null
{{ cli }} run -d --name {{ container }} \
-p 9010:9010 -p 9000:9000 \
-v {{ invocation_directory() }}:/workspace \
-it rustfs:dev
[group("🏃 Running")]
dev-env-stop cli=(DOCKER_CLI) container=(CONTAINER_NAME):
@echo "🛑 Stopping development environment..."
-{{ cli }} stop {{ container }} 2>/dev/null
-{{ cli }} rm {{ container }} 2>/dev/null
[group("🏃 Running")]
dev-env-restart: dev-env-stop dev-env-start
[group("👍 E2E")]
e2e-server:
sh scripts/run.sh
[group("👍 E2E")]
probe-e2e:
sh scripts/probe.sh
[doc("inspect one image")]
[group("🚚 Other")]
docker-inspect-multiarch image cli=(DOCKER_CLI):
@echo "🔍 Inspecting multi-architecture image: {{ image }}"
{{ cli }} buildx imagetools inspect {{ image }}

201
LICENSE
View File

@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2024 Beijing Henghesha Technology Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

353
Makefile
View File

@@ -1,13 +1,11 @@
########### ###########
# Remote development requires VSCode with Dev Containers, Remote SSH, Remote Explorer # 远程开发,需要 VSCode 安装 Dev Containers, Remote SSH, Remote Explorer
# https://code.visualstudio.com/docs/remote/containers # https://code.visualstudio.com/docs/remote/containers
########### ###########
DOCKER_CLI ?= docker DOCKER_CLI ?= docker
IMAGE_NAME ?= rustfs:v1.0.0 IMAGE_NAME ?= rustfs:v1.0.0
CONTAINER_NAME ?= rustfs-dev CONTAINER_NAME ?= rustfs-dev
# Docker build configurations DOCKERFILE_PATH = $(shell pwd)/.docker
DOCKERFILE_PRODUCTION = Dockerfile
DOCKERFILE_SOURCE = Dockerfile.source
# Code quality and formatting targets # Code quality and formatting targets
.PHONY: fmt .PHONY: fmt
@@ -23,7 +21,6 @@ fmt-check:
.PHONY: clippy .PHONY: clippy
clippy: clippy:
@echo "🔍 Running clippy checks..." @echo "🔍 Running clippy checks..."
cargo clippy --fix --allow-dirty
cargo clippy --all-targets --all-features -- -D warnings cargo clippy --all-targets --all-features -- -D warnings
.PHONY: check .PHONY: check
@@ -34,13 +31,7 @@ check:
.PHONY: test .PHONY: test
test: test:
@echo "🧪 Running tests..." @echo "🧪 Running tests..."
@if command -v cargo-nextest >/dev/null 2>&1; then \ cargo test --all --exclude e2e_test
cargo nextest run --all --exclude e2e_test; \
else \
echo " cargo-nextest not found; falling back to 'cargo test'"; \
cargo test --workspace --exclude e2e_test -- --nocapture; \
fi
cargo test --all --doc
.PHONY: pre-commit .PHONY: pre-commit
pre-commit: fmt clippy check test pre-commit: fmt clippy check test
@@ -52,6 +43,21 @@ setup-hooks:
chmod +x .git/hooks/pre-commit chmod +x .git/hooks/pre-commit
@echo "✅ Git hooks setup complete!" @echo "✅ Git hooks setup complete!"
.PHONY: init-devenv
init-devenv:
$(DOCKER_CLI) build -t $(IMAGE_NAME) -f $(DOCKERFILE_PATH)/Dockerfile.devenv .
$(DOCKER_CLI) stop $(CONTAINER_NAME)
$(DOCKER_CLI) rm $(CONTAINER_NAME)
$(DOCKER_CLI) run -d --name $(CONTAINER_NAME) -p 9010:9010 -p 9000:9000 -v $(shell pwd):/root/s3-rustfs -it $(IMAGE_NAME)
.PHONY: start
start:
$(DOCKER_CLI) start $(CONTAINER_NAME)
.PHONY: stop
stop:
$(DOCKER_CLI) stop $(CONTAINER_NAME)
.PHONY: e2e-server .PHONY: e2e-server
e2e-server: e2e-server:
sh $(shell pwd)/scripts/run.sh sh $(shell pwd)/scripts/run.sh
@@ -60,317 +66,16 @@ e2e-server:
probe-e2e: probe-e2e:
sh $(shell pwd)/scripts/probe.sh sh $(shell pwd)/scripts/probe.sh
# Native build using build-rustfs.sh script # make BUILD_OS=ubuntu22.04 build
.PHONY: build # in target/ubuntu22.04/release/rustfs
build:
@echo "🔨 Building RustFS using build-rustfs.sh script..."
./build-rustfs.sh
.PHONY: build-dev # make BUILD_OS=rockylinux9.3 build
build-dev: # in target/rockylinux9.3/release/rustfs
@echo "🔨 Building RustFS in development mode..."
./build-rustfs.sh --dev
# Docker-based build (alternative approach)
# Usage: make BUILD_OS=ubuntu22.04 build-docker
# Output: target/ubuntu22.04/release/rustfs
BUILD_OS ?= rockylinux9.3 BUILD_OS ?= rockylinux9.3
.PHONY: build-docker .PHONY: build
build-docker: SOURCE_BUILD_IMAGE_NAME = rustfs-$(BUILD_OS):v1 build: ROCKYLINUX_BUILD_IMAGE_NAME = rustfs-$(BUILD_OS):v1
build-docker: SOURCE_BUILD_CONTAINER_NAME = rustfs-$(BUILD_OS)-build build: ROCKYLINUX_BUILD_CONTAINER_NAME = rustfs-$(BUILD_OS)-build
build-docker: BUILD_CMD = /root/.cargo/bin/cargo build --release --bin rustfs --target-dir /root/s3-rustfs/target/$(BUILD_OS) build: BUILD_CMD = /root/.cargo/bin/cargo build --release --bin rustfs --target-dir /root/s3-rustfs/target/$(BUILD_OS)
build-docker: build:
@echo "🐳 Building RustFS using Docker ($(BUILD_OS))..." $(DOCKER_CLI) build -t $(ROCKYLINUX_BUILD_IMAGE_NAME) -f $(DOCKERFILE_PATH)/Dockerfile.$(BUILD_OS) .
$(DOCKER_CLI) buildx build -t $(SOURCE_BUILD_IMAGE_NAME) -f $(DOCKERFILE_SOURCE) . $(DOCKER_CLI) run --rm --name $(ROCKYLINUX_BUILD_CONTAINER_NAME) -v $(shell pwd):/root/s3-rustfs -it $(ROCKYLINUX_BUILD_IMAGE_NAME) $(BUILD_CMD)
$(DOCKER_CLI) run --rm --name $(SOURCE_BUILD_CONTAINER_NAME) -v $(shell pwd):/root/s3-rustfs -it $(SOURCE_BUILD_IMAGE_NAME) $(BUILD_CMD)
.PHONY: build-musl
build-musl:
@echo "🔨 Building rustfs for x86_64-unknown-linux-musl..."
@echo "💡 On macOS/Windows, use 'make build-docker' or 'make docker-dev' instead"
./build-rustfs.sh --platform x86_64-unknown-linux-musl
.PHONY: build-gnu
build-gnu:
@echo "🔨 Building rustfs for x86_64-unknown-linux-gnu..."
@echo "💡 On macOS/Windows, use 'make build-docker' or 'make docker-dev' instead"
./build-rustfs.sh --platform x86_64-unknown-linux-gnu
.PHONY: build-musl-arm64
build-musl-arm64:
@echo "🔨 Building rustfs for aarch64-unknown-linux-musl..."
@echo "💡 On macOS/Windows, use 'make build-docker' or 'make docker-dev' instead"
./build-rustfs.sh --platform aarch64-unknown-linux-musl
.PHONY: build-gnu-arm64
build-gnu-arm64:
@echo "🔨 Building rustfs for aarch64-unknown-linux-gnu..."
@echo "💡 On macOS/Windows, use 'make build-docker' or 'make docker-dev' instead"
./build-rustfs.sh --platform aarch64-unknown-linux-gnu
.PHONY: deploy-dev
deploy-dev: build-musl
@echo "🚀 Deploying to dev server: $${IP}"
./scripts/dev_deploy.sh $${IP}
# ========================================================================================
# Docker Multi-Architecture Builds (Primary Methods)
# ========================================================================================
# Production builds using docker-buildx.sh (for CI/CD and production)
.PHONY: docker-buildx
docker-buildx:
@echo "🏗️ Building multi-architecture production Docker images with buildx..."
./docker-buildx.sh
.PHONY: docker-buildx-push
docker-buildx-push:
@echo "🚀 Building and pushing multi-architecture production Docker images with buildx..."
./docker-buildx.sh --push
.PHONY: docker-buildx-version
docker-buildx-version:
@if [ -z "$(VERSION)" ]; then \
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))..."
./docker-buildx.sh --release $(VERSION)
.PHONY: docker-buildx-push-version
docker-buildx-push-version:
@if [ -z "$(VERSION)" ]; then \
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))..."
./docker-buildx.sh --release $(VERSION) --push
# Development/Source builds using direct buildx commands
.PHONY: docker-dev
docker-dev:
@echo "🏗️ Building multi-architecture development Docker images with buildx..."
@echo "💡 This builds from source code and is intended for local development and testing"
@echo "⚠️ Multi-arch images cannot be loaded locally, use docker-dev-push to push to registry"
$(DOCKER_CLI) buildx build \
--platform linux/amd64,linux/arm64 \
--file $(DOCKERFILE_SOURCE) \
--tag rustfs:source-latest \
--tag rustfs:dev-latest \
.
.PHONY: docker-dev-local
docker-dev-local:
@echo "🏗️ Building single-architecture development Docker image for local use..."
@echo "💡 This builds from source code for the current platform and loads locally"
$(DOCKER_CLI) buildx build \
--file $(DOCKERFILE_SOURCE) \
--tag rustfs:source-latest \
--tag rustfs:dev-latest \
--load \
.
.PHONY: docker-dev-push
docker-dev-push:
@if [ -z "$(REGISTRY)" ]; then \
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 "💡 Pushing to registry: $(REGISTRY)"
$(DOCKER_CLI) buildx build \
--platform linux/amd64,linux/arm64 \
--file $(DOCKERFILE_SOURCE) \
--tag $(REGISTRY)/rustfs:source-latest \
--tag $(REGISTRY)/rustfs:dev-latest \
--push \
.
# Local production builds using direct buildx (alternative to docker-buildx.sh)
.PHONY: docker-buildx-production-local
docker-buildx-production-local:
@echo "🏗️ Building single-architecture production Docker image locally..."
@echo "💡 Alternative to docker-buildx.sh for local testing"
$(DOCKER_CLI) buildx build \
--file $(DOCKERFILE_PRODUCTION) \
--tag rustfs:production-latest \
--tag rustfs:latest \
--load \
--build-arg RELEASE=latest \
.
# ========================================================================================
# Single Architecture Docker Builds (Traditional)
# ========================================================================================
.PHONY: docker-build-production
docker-build-production:
@echo "🏗️ Building single-architecture production Docker image..."
@echo "💡 Consider using 'make docker-buildx-production-local' for multi-arch support"
$(DOCKER_CLI) build -f $(DOCKERFILE_PRODUCTION) -t rustfs:latest .
.PHONY: docker-build-source
docker-build-source:
@echo "🏗️ Building single-architecture source Docker image..."
@echo "💡 Consider using 'make docker-dev-local' for multi-arch support"
DOCKER_BUILDKIT=1 $(DOCKER_CLI) build \
--build-arg BUILDKIT_INLINE_CACHE=1 \
-f $(DOCKERFILE_SOURCE) -t rustfs:source .
# ========================================================================================
# Development Environment
# ========================================================================================
.PHONY: dev-env-start
dev-env-start:
@echo "🚀 Starting development environment..."
$(DOCKER_CLI) buildx build \
--file $(DOCKERFILE_SOURCE) \
--tag rustfs:dev \
--load \
.
$(DOCKER_CLI) stop $(CONTAINER_NAME) 2>/dev/null || true
$(DOCKER_CLI) rm $(CONTAINER_NAME) 2>/dev/null || true
$(DOCKER_CLI) run -d --name $(CONTAINER_NAME) \
-p 9010:9010 -p 9000:9000 \
-v $(shell pwd):/workspace \
-it rustfs:dev
.PHONY: dev-env-stop
dev-env-stop:
@echo "🛑 Stopping development environment..."
$(DOCKER_CLI) stop $(CONTAINER_NAME) 2>/dev/null || true
$(DOCKER_CLI) rm $(CONTAINER_NAME) 2>/dev/null || true
.PHONY: dev-env-restart
dev-env-restart: dev-env-stop dev-env-start
# ========================================================================================
# Build Utilities
# ========================================================================================
.PHONY: docker-inspect-multiarch
docker-inspect-multiarch:
@if [ -z "$(IMAGE)" ]; then \
echo "❌ Error: Please specify image, example: make docker-inspect-multiarch IMAGE=rustfs/rustfs:latest"; \
exit 1; \
fi
@echo "🔍 Inspecting multi-architecture image: $(IMAGE)"
docker buildx imagetools inspect $(IMAGE)
.PHONY: build-cross-all
build-cross-all:
@echo "🔧 Building all target architectures..."
@echo "💡 On macOS/Windows, use 'make docker-dev' for reliable multi-arch builds"
@echo "🔨 Generating protobuf code..."
cargo run --bin gproto || true
@echo "🔨 Building x86_64-unknown-linux-gnu..."
./build-rustfs.sh --platform x86_64-unknown-linux-gnu
@echo "🔨 Building aarch64-unknown-linux-gnu..."
./build-rustfs.sh --platform aarch64-unknown-linux-gnu
@echo "🔨 Building x86_64-unknown-linux-musl..."
./build-rustfs.sh --platform x86_64-unknown-linux-musl
@echo "🔨 Building aarch64-unknown-linux-musl..."
./build-rustfs.sh --platform aarch64-unknown-linux-musl
@echo "✅ All architectures built successfully!"
# ========================================================================================
# Help and Documentation
# ========================================================================================
.PHONY: help-build
help-build:
@echo "🔨 RustFS Build Help:"
@echo ""
@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 Build:"
@echo " make build-docker # Build using Docker container"
@echo " make build-docker BUILD_OS=ubuntu22.04 # Specify build system"
@echo ""
@echo "🏗️ Cross-architecture Build:"
@echo " make build-cross-all # Build binaries for all architectures"
@echo ""
@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 script provides more options, smart detection and binary verification"
.PHONY: help-docker
help-docker:
@echo "🐳 Docker Multi-architecture Build Help:"
@echo ""
@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 "🔧 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 "🏗️ Local Production Image Build (Alternative):"
@echo " make docker-buildx-production-local # Build production single-arch image locally"
@echo ""
@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 "🚀 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 "🔧 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 "📋 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 "💡 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 Help:"
@echo ""
@echo "📋 Main Command Categories:"
@echo " make help-build # Show build-related help"
@echo " make help-docker # Show Docker-related help"
@echo ""
@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 "🚀 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 "💡 For more help use 'make help-build' or 'make help-docker'"

283
README.md
View File

@@ -1,233 +1,94 @@
[![RustFS](https://rustfs.com/images/rustfs-github.png)](https://rustfs.com) # RustFS
<p align="center">RustFS is a high-performance, distributed object storage system built in Rust.</p> ## English Documentation |[中文文档](README_ZH.md)
<p align="center"> ### Prerequisites
<a href="https://github.com/rustfs/rustfs/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/rustfs/rustfs/actions/workflows/ci.yml/badge.svg" /></a>
<a href="https://github.com/rustfs/rustfs/actions/workflows/docker.yml"><img alt="Build and Push Docker Images" src="https://github.com/rustfs/rustfs/actions/workflows/docker.yml/badge.svg" /></a>
<img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/m/rustfs/rustfs"/>
<img alt="Github Last Commit" src="https://img.shields.io/github/last-commit/rustfs/rustfs"/>
<a href="https://hellogithub.com/repository/rustfs/rustfs" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=b95bcb72bdc340b68f16fdf6790b7d5b&claim_uid=MsbvjYeLDKAH457&theme=small" alt="FeaturedHelloGitHub" /></a>
</p>
<p align="center"> | Package | Version | Download Link |
<a href="https://docs.rustfs.com/installation/">Getting Started</a> |---------|---------|----------------------------------------------------------------------------------------------------------------------------------|
· <a href="https://docs.rustfs.com/">Docs</a> | Rust | 1.8.5+ | [rust-lang.org/tools/install](https://www.rust-lang.org/tools/install) |
· <a href="https://github.com/rustfs/rustfs/issues">Bug reports</a> | protoc | 30.2+ | [protoc-30.2-linux-x86_64.zip](https://github.com/protocolbuffers/protobuf/releases/download/v30.2/protoc-30.2-linux-x86_64.zip) |
· <a href="https://github.com/rustfs/rustfs/discussions">Discussions</a> | flatc | 24.0+ | [Linux.flatc.binary.g++-13.zip](https://github.com/google/flatbuffers/releases/download/v25.2.10/Linux.flatc.binary.g++-13.zip) |
</p>
<p align="center"> ### Building RustFS
English | <a href="https://github.com/rustfs/rustfs/blob/main/README_ZH.md">简体中文</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=de">Deutsch</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=es">Español</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=fr">français</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=ja">日本語</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=ko">한국어</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=pt">Portuguese</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=ru">Русский</a>
</p>
RustFS is a high-performance, distributed object storage system built in Rust—one of the most loved programming languages worldwide. RustFS combines the simplicity of MinIO with the memory safety and raw performance of Rust. It offers full S3 compatibility, is completely open-source, and is optimized for data lakes, AI, and big data workloads. #### Generate Protobuf Code
Unlike other storage systems, RustFS is released under the permissible Apache 2.0 license, avoiding the restrictions of AGPL. With Rust as its foundation, RustFS delivers superior speed and secure distributed features for next-generation object storage.
## Feature & Status
- **High Performance**: Built with Rust to ensure maximum speed and resource efficiency.
- **Distributed Architecture**: Scalable and fault-tolerant design suitable for large-scale deployments.
- **S3 Compatibility**: Seamless integration with existing S3-compatible applications and tools.
- **Data Lake Support**: Optimized for high-throughput big data and AI workloads.
- **Open Source**: Licensed under Apache 2.0, encouraging unrestricted community contributions and commercial usage.
- **User-Friendly**: Designed with simplicity in mind for easy deployment and management.
| Feature | Status | Feature | Status |
| :--- | :--- | :--- | :--- |
| **S3 Core Features** | ✅ Available | **Bitrot Protection** | ✅ Available |
| **Upload / Download** | ✅ Available | **Single Node Mode** | ✅ Available |
| **Versioning** | ✅ Available | **Bucket Replication** | ⚠️ Partial Support |
| **Logging** | ✅ Available | **Lifecycle Management** | 🚧 Under Testing |
| **Event Notifications** | ✅ Available | **Distributed Mode** | 🚧 Under Testing |
| **K8s Helm Charts** | ✅ Available | **OPA (Open Policy Agent)** | 🚧 Under Testing |
## RustFS vs MinIO Performance
**Stress Test Environment:**
| Type | Parameter | Remark |
|---------|-----------|----------------------------------------------------------|
| CPU | 2 Core | Intel Xeon (Sapphire Rapids) Platinum 8475B, 2.7/3.2 GHz |
| Memory | 4GB | |
| Network | 15Gbps | |
| Drive | 40GB x 4 | IOPS 3800 / Drive |
<https://github.com/user-attachments/assets/2e4979b5-260c-4f2c-ac12-c87fd558072a>
### RustFS vs Other Object Storage
| Feature | RustFS | Other Object Storage |
| :--- | :--- | :--- |
| **Console Experience** | **Powerful Console**<br>Comprehensive management interface. | **Basic / Limited Console**<br>Often overly simple or lacking critical features. |
| **Language & Safety** | **Rust-based**<br>Memory safety by design. | **Go or C-based**<br>Potential for memory GC pauses or leaks. |
| **Data Sovereignty** | **No Telemetry / Full Compliance**<br>Guards against unauthorized cross-border data egress. Compliant with GDPR (EU/UK), CCPA (US), and APPI (Japan). | **Potential Risk**<br>Possible legal exposure and unwanted data telemetry. |
| **Licensing** | **Permissive Apache 2.0**<br>Business-friendly, no "poison pill" clauses. | **Restrictive AGPL v3**<br>Risk of license traps and intellectual property pollution. |
| **Compatibility** | **100% S3 Compatible**<br>Works with any cloud provider or client, anywhere. | **Variable Compatibility**<br>May lack support for local cloud vendors or specific APIs. |
| **Edge & IoT** | **Strong Edge Support**<br>Ideal for secure, innovative edge devices. | **Weak Edge Support**<br>Often too heavy for edge gateways. |
| **Risk Profile** | **Enterprise Risk Mitigation**<br>Clear IP rights and safe for commercial use. | **Legal Risks**<br>Intellectual property ambiguity and usage restrictions. |
## Quickstart
To get started with RustFS, follow these steps:
### 1. One-click Installation (Option 1)
```bash
curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh
````
### 2\. Docker Quick Start (Option 2)
The RustFS container runs as a non-root user `rustfs` (UID `10001`). If you run Docker with `-v` to mount a host directory, please ensure the host directory owner is set to `10001`, otherwise you will encounter permission denied errors.
```bash ```bash
# Create data and logs directories cargo run --bin gproto
mkdir -p data logs
# Change the owner of these directories
chown -R 10001:10001 data logs
# Using latest version
docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:latest
# Using specific version
docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:1.0.0.alpha.68
``` ```
You can also use Docker Compose. Using the `docker-compose.yml` file in the root directory: #### Using Docker for Prerequisites
```yaml
- uses: arduino/setup-protoc@v3
with:
version: "30.2"
- uses: Nugine/setup-flatc@v1
with:
version: "25.2.10"
```
#### Adding Console Web UI
1. Download the latest console UI:
```bash
wget https://dl.rustfs.com/artifacts/console/rustfs-console-latest.zip
```
2. Create the static directory:
```bash
mkdir -p ./rustfs/static
```
3. Extract and compile RustFS:
```bash
unzip rustfs-console-latest.zip -d ./rustfs/static
cargo build
```
### Running RustFS
#### Configuration
Set the required environment variables:
```bash ```bash
docker compose --profile observability up -d # Basic config
export RUSTFS_VOLUMES="./target/volume/test"
export RUSTFS_ADDRESS="0.0.0.0:9000"
export RUSTFS_CONSOLE_ENABLE=true
export RUSTFS_CONSOLE_ADDRESS="0.0.0.0:9001"
# Observability config
export RUSTFS_OBS_ENDPOINT="http://localhost:4317"
# Event message configuration
#export RUSTFS_EVENT_CONFIG="./deploy/config/event.toml"
``` ```
**NOTE**: We recommend reviewing the `docker-compose.yaml` file before running. It defines several services including Grafana, Prometheus, and Jaeger, which are helpful for RustFS observability. If you wish to start Redis or Nginx containers, you can specify the corresponding profiles. #### Start the service
### 3\. Build from Source (Option 3) - Advanced Users
For developers who want to build RustFS Docker images from source with multi-architecture support:
```bash ```bash
# Build multi-architecture images locally ./rustfs /data/rustfs
./docker-buildx.sh --build-arg RELEASE=latest
# Build and push to registry
./docker-buildx.sh --push
# Build specific version
./docker-buildx.sh --release v1.0.0 --push
# Build for custom registry
./docker-buildx.sh --registry your-registry.com --namespace yourname --push
``` ```
The `docker-buildx.sh` script supports: ### Observability Stack
\- **Multi-architecture builds**: `linux/amd64`, `linux/arm64`
\- **Automatic version detection**: Uses git tags or commit hashes
\- **Registry flexibility**: Supports Docker Hub, GitHub Container Registry, etc.
\- **Build optimization**: Includes caching and parallel builds
You can also use Make targets for convenience: #### Deployment
```bash 1. Navigate to the observability directory:
make docker-buildx # Build locally ```bash
make docker-buildx-push # Build and push cd .docker/observability
make docker-buildx-version VERSION=v1.0.0 # Build specific version ```
make help-docker # Show all Docker-related commands
```
> **Heads-up (macOS cross-compilation)**: macOS keeps the default `ulimit -n` at 256, so `cargo zigbuild` or `./build-rustfs.sh --platform ...` may fail with `ProcessFdQuotaExceeded` when targeting Linux. The build script attempts to raise the limit automatically, but if you still see the warning, run `ulimit -n 4096` (or higher) in your shell before building. 2. Start the observability stack:
```bash
docker compose -f docker-compose.yml up -d
```
### 4\. Build with Helm Chart (Option 4) - Cloud Native #### Access Monitoring Dashboards
Follow the instructions in the [Helm Chart README](https://charts.rustfs.com/) to install RustFS on a Kubernetes cluster.
### 5\. Nix Flake (Option 5)
If you have [Nix with flakes enabled](https://nixos.wiki/wiki/Flakes#Enable_flakes):
```bash
# Run directly without installing
nix run github:rustfs/rustfs
# Build the binary
nix build github:rustfs/rustfs
./result/bin/rustfs --help
# Or from a local checkout
nix build
nix run
```
-----
### Accessing RustFS
5. **Access the Console**: Open your web browser and navigate to `http://localhost:9000` to access the RustFS console.
* Default credentials: `rustfsadmin` / `rustfsadmin`
6. **Create a Bucket**: Use the console to create a new bucket for your objects.
7. **Upload Objects**: You can upload files directly through the console or use S3-compatible APIs/clients to interact with your RustFS instance.
**NOTE**: To access the RustFS instance via `https`, please refer to the [TLS Configuration Docs](https://docs.rustfs.com/integration/tls-configured.html).
## Documentation
For detailed documentation, including configuration options, API references, and advanced usage, please visit our [Documentation](https://docs.rustfs.com).
## Getting Help
If you have any questions or need assistance:
- Check the [FAQ](https://github.com/rustfs/rustfs/discussions/categories/q-a) for common issues and solutions.
- Join our [GitHub Discussions](https://github.com/rustfs/rustfs/discussions) to ask questions and share your experiences.
- Open an issue on our [GitHub Issues](https://github.com/rustfs/rustfs/issues) page for bug reports or feature requests.
## Links
- [Documentation](https://docs.rustfs.com) - The manual you should read
- [Changelog](https://github.com/rustfs/rustfs/releases) - What we broke and fixed
- [GitHub Discussions](https://github.com/rustfs/rustfs/discussions) - Where the community lives
## Contact
- **Bugs**: [GitHub Issues](https://github.com/rustfs/rustfs/issues)
- **Business**: [hello@rustfs.com](mailto:hello@rustfs.com)
- **Jobs**: [jobs@rustfs.com](mailto:jobs@rustfs.com)
- **General Discussion**: [GitHub Discussions](https://github.com/rustfs/rustfs/discussions)
- **Contributing**: [CONTRIBUTING.md](CONTRIBUTING.md)
## Contributors
RustFS is a community-driven project, and we appreciate all contributions. Check out the [Contributors](https://github.com/rustfs/rustfs/graphs/contributors) page to see the amazing people who have helped make RustFS better.
<a href="https://github.com/rustfs/rustfs/graphs/contributors">
<img src="https://opencollective.com/rustfs/contributors.svg?width=890&limit=500&button=false" alt="Contributors" />
</a>
## Github Trending Top
🚀 RustFS is beloved by open-source enthusiasts and enterprise users worldwide, often appearing on the GitHub Trending top charts.
<a href="https://trendshift.io/repositories/14181" target="_blank"><img src="https://raw.githubusercontent.com/rustfs/rustfs/refs/heads/main/docs/rustfs-trending.jpg" alt="rustfs%2Frustfs | Trendshift" /></a>
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=rustfs/rustfs&type=date&legend=top-left)](https://www.star-history.com/#rustfs/rustfs&type=date&legend=top-left)
## License
[Apache 2.0](https://opensource.org/licenses/Apache-2.0)
**RustFS** is a trademark of RustFS, Inc. All other trademarks are the property of their respective owners.
- Grafana: `http://localhost:3000` (credentials: `admin`/`admin`)
- Jaeger: `http://localhost:16686`
- Prometheus: `http://localhost:9090`

View File

@@ -1,219 +1,99 @@
[![RustFS](https://rustfs.com/images/rustfs-github.png)](https://rustfs.com) # RustFS
<p align="center">RustFS 是一个基于 Rust 构建的高性能分布式对象存储系统。</p> ## [English Documentation](README.md) |中文文档
<p align="center"> ### 前置要求
<a href="https://github.com/rustfs/rustfs/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/rustfs/rustfs/actions/workflows/ci.yml/badge.svg" /></a>
<a href="https://github.com/rustfs/rustfs/actions/workflows/docker.yml"><img alt="构建并推送 Docker 镜像" src="https://github.com/rustfs/rustfs/actions/workflows/docker.yml/badge.svg" /></a>
<img alt="GitHub 提交活跃度" src="https://img.shields.io/github/commit-activity/m/rustfs/rustfs"/>
<img alt="Github 最新提交" src="https://img.shields.io/github/last-commit/rustfs/rustfs"/>
<a href="https://hellogithub.com/repository/rustfs/rustfs" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=b95bcb72bdc340b68f16fdf6790b7d5b&claim_uid=MsbvjYeLDKAH457&theme=small" alt="FeaturedHelloGitHub" /></a>
</p>
<p align="center"> | 软件包 | 版本 | 下载链接 |
<a href="https://docs.rustfs.com/installation/">快速开始</a> |--------|--------|----------------------------------------------------------------------------------------------------------------------------------|
· <a href="https://docs.rustfs.com/">文档</a> | Rust | 1.8.5+ | [rust-lang.org/tools/install](https://www.rust-lang.org/tools/install) |
· <a href="https://github.com/rustfs/rustfs/issues">报告 Bug</a> | protoc | 30.2+ | [protoc-30.2-linux-x86_64.zip](https://github.com/protocolbuffers/protobuf/releases/download/v30.2/protoc-30.2-linux-x86_64.zip) |
· <a href="https://github.com/rustfs/rustfs/discussions">社区讨论</a> | flatc | 24.0+ | [Linux.flatc.binary.g++-13.zip](https://github.com/google/flatbuffers/releases/download/v25.2.10/Linux.flatc.binary.g++-13.zip) |
</p>
<p align="center"> ### 构建 RustFS
<a href="https://github.com/rustfs/rustfs/blob/main/README.md">English</a> | 简体中文 |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=de">Deutsch</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=es">Español</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=fr">français</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=ja">日本語</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=ko">한국어</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=pt">Portuguese</a> |
<a href="https://readme-i18n.com/rustfs/rustfs?lang=ru">Русский</a>
</p>
RustFS 是一个基于 Rust 构建的高性能分布式对象存储系统。Rust 是全球最受开发者喜爱的编程语言之一RustFS 完美结合了 MinIO 的简洁性与 Rust 的内存安全及高性能优势。它提供完整的 S3 兼容性完全开源并专为数据湖、人工智能AI和大数据负载进行了优化。 #### 生成 Protobuf 代码
与其他存储系统不同RustFS 采用更宽松、商业友好的 Apache 2.0 许可证,避免了 AGPL 协议的限制。以 Rust 为基石RustFS 为下一代对象存储提供了更快的速度和更安全的分布式特性。
## 特征和功能状态
- **高性能**:基于 Rust 构建,确保极致的速度和资源效率。
- **分布式架构**:可扩展且容错的设计,适用于大规模部署。
- **S3 兼容性**:与现有的 S3 兼容应用和工具无缝集成。
- **数据湖支持**:专为高吞吐量的大数据和 AI 工作负载优化。
- **完全开源**:采用 Apache 2.0 许可证,鼓励社区贡献和商业使用。
- **简单易用**:设计简洁,易于部署和管理。
| 功能 | 状态 | 功能 | 状态 |
| :--- | :--- | :--- | :--- |
| **S3 核心功能** | ✅ 可用 | **Bitrot (防数据腐烂)** | ✅ 可用 |
| **上传 / 下载** | ✅ 可用 | **单机模式** | ✅ 可用 |
| **版本控制** | ✅ 可用 | **存储桶复制** | ⚠️ 部分可用 |
| **日志功能** | ✅ 可用 | **生命周期管理** | 🚧 测试中 |
| **事件通知** | ✅ 可用 | **分布式模式** | 🚧 测试中 |
| **K8s Helm Chart** | ✅ 可用 | **OPA (策略引擎)** | 🚧 测试中 |
## RustFS vs MinIO 性能对比
**压力测试环境参数:**
| 类型 | 参数 | 备注 |
|---------|-----------|----------------------------------------------------------|
| CPU | 2 核 | Intel Xeon (Sapphire Rapids) Platinum 8475B , 2.7/3.2 GHz |
| 内存 | 4GB |   |
| 网络 | 15Gbps |   |
| 硬盘 | 40GB x 4 | IOPS 3800 / Drive |
<https://github.com/user-attachments/assets/2e4979b5-260c-4f2c-ac12-c87fd558072a>
### RustFS vs 其他对象存储
| 特性 | RustFS | 其他对象存储 |
| :--- | :--- | :--- |
| **控制台体验** | **功能强大的控制台**<br>提供全面的管理界面。 | **基础/简陋的控制台**<br>通常功能过于简单或缺失关键特性。 |
| **语言与安全** | **基于 Rust 开发**<br>天生的内存安全。 | **基于 Go 或 C 开发**<br>存在内存 GC 停顿或内存泄漏的潜在风险。 |
| **数据主权** | **无遥测 / 完全合规**<br>防止未经授权的数据跨境传输。完全符合 GDPR (欧盟/英国)、CCPA (美国) 和 APPI (日本) 等法规。 | **潜在风险**<br>可能存在法律风险和隐蔽的数据遥测Telemetry。 |
| **开源协议** | **宽松的 Apache 2.0**<br>商业友好,无“毒丸”条款。 | **受限的 AGPL v3**<br>存在许可证陷阱和知识产权污染的风险。 |
| **兼容性** | **100% S3 兼容**<br>适用于任何云提供商和客户端,随处运行。 | **兼容性不一**<br>虽然支持 S3但可能缺乏对本地云厂商或特定 API 的支持。 |
| **边缘与 IoT** | **强大的边缘支持**<br>非常适合安全、创新的边缘设备。 | **边缘支持较弱**<br>对于边缘网关来说通常过于沉重。 |
| **成本** | **稳定且免费**<br>免费社区支持,稳定的商业定价。 | **高昂成本**<br>1PiB 的成本可能高达 250,000 美元。 |
| **风险控制** | **企业级风险规避**<br>清晰的知识产权,商业使用安全无忧。 | **法律风险**<br>知识产权归属模糊及使用限制风险。 |
## 快速开始
请按照以下步骤快速上手 RustFS
### 1. 一键安装脚本 (选项 1)
```bash
curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh
````
### 2\. Docker 快速启动 (选项 2)
RustFS 容器以非 root 用户 `rustfs` (UID `10001`) 运行。如果您使用 Docker 的 `-v` 参数挂载宿主机目录,请务必确保宿主机目录的所有者已更改为 `1000`,否则会遇到权限拒绝错误。
```bash ```bash
# 创建数据和日志目录 cargo run --bin gproto
mkdir -p data logs
# 更改这两个目录的所有者
chown -R 10001:10001 data logs
# 使用最新版本运行
docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:latest
# 使用指定版本运行
docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:1.0.0.alpha.68
``` ```
您也可以使用 Docker Compose。使用根目录下的 `docker-compose.yml` 文件: #### 使用 Docker 安装依赖
```yaml
- uses: arduino/setup-protoc@v3
with:
version: "30.2"
- uses: Nugine/setup-flatc@v1
with:
version: "25.2.10"
```
#### 添加控制台 Web UI
1. 下载最新的控制台 UI
```bash
wget https://dl.rustfs.com/artifacts/console/rustfs-console-latest.zip
```
2. 创建静态资源目录:
```bash
mkdir -p ./rustfs/static
```
3. 解压并编译 RustFS
```bash
unzip rustfs-console-latest.zip -d ./rustfs/static
cargo build
```
### 运行 RustFS
#### 配置
设置必要的环境变量:
```bash ```bash
docker compose --profile observability up -d # 基础配置
export RUSTFS_VOLUMES="./target/volume/test"
export RUSTFS_ADDRESS="0.0.0.0:9000"
export RUSTFS_CONSOLE_ENABLE=true
export RUSTFS_CONSOLE_ADDRESS="0.0.0.0:9001"
# 可观测性配置
export RUSTFS_OBS_ENDPOINT="http://localhost:4317"
# 事件消息配置
#export RUSTFS_EVENT_CONFIG="./deploy/config/event.toml"
``` ```
**注意**: 我们建议您在运行前查看 `docker-compose.yaml` 文件。该文件定义了包括 Grafana、Prometheus 和 Jaeger 在内的多个服务,有助于 RustFS 的可观测性监控。如果您还想启动 Redis 或 Nginx 容器,可以指定相应的 profile。 #### 启动服务
### 3\. 源码编译 (选项 3) - 进阶用户
适用于希望从源码构建支持多架构 RustFS Docker 镜像的开发者:
```bash ```bash
# 在本地构建多架构镜像 ./rustfs /data/rustfs
./docker-buildx.sh --build-arg RELEASE=latest
# 构建并推送到仓库
./docker-buildx.sh --push
# 构建指定版本
./docker-buildx.sh --release v1.0.0 --push
# 构建并推送到自定义仓库
./docker-buildx.sh --registry your-registry.com --namespace yourname --push
``` ```
`docker-buildx.sh` 脚本支持: ### 可观测性系统
\- **多架构构建**: `linux/amd64`, `linux/arm64`
\- **自动版本检测**: 使用 git tags 或 commit hash
\- **灵活的仓库支持**: 支持 Docker Hub, GitHub Container Registry 等
\- **构建优化**: 包含缓存和并行构建
为了方便起见,您也可以使用 Make 命令: #### 部署
1. 进入可观测性目录:
```bash
cd .docker/observability
```
2. 启动可观测性系统:
```bash
docker compose -f docker-compose.yml up -d
```
#### 访问监控面板
- Grafana: `http://localhost:3000` (默认账号/密码:`admin`/`admin`)
- Jaeger: `http://localhost:16686`
- Prometheus: `http://localhost:9090`
#### 配置可观测性
```bash
make docker-buildx # 本地构建
make docker-buildx-push # 构建并推送
make docker-buildx-version VERSION=v1.0.0 # 构建指定版本
make help-docker # 显示所有 Docker 相关命令
``` ```
OpenTelemetry Collector 地址(endpoint): http://localhost:4317
> **注意 (macOS 交叉编译)**: macOS 默认的 `ulimit -n` 限制为 256因此在使用 `cargo zigbuild` 或 `./build-rustfs.sh --platform ...` 交叉编译 Linux 版本时,可能会因 `ProcessFdQuotaExceeded` 失败。构建脚本会尝试自动提高限制,但如果您仍然看到警告,请在构建前在终端运行 `ulimit -n 4096` (或更高)。 ```
### 4\. 使用 Helm Chart 安装 (选项 4) - 云原生环境
请按照 [Helm Chart README](https://charts.rustfs.com) 上的说明在 Kubernetes 集群上安装 RustFS。
-----
### 访问 RustFS
5. **访问控制台**: 打开浏览器并访问 `http://localhost:9000` 进入 RustFS 控制台。
* 默认账号/密码: `rustfsadmin` / `rustfsadmin`
6. **创建存储桶**: 使用控制台为您​​的对象创建一个新的存储桶 (Bucket)。
7. **上传对象**: 您可以直接通过控制台上传文件,或使用 S3 兼容的 API/客户端与您的 RustFS 实例进行交互。
**注意**: 如果您希望通过 `https` 访问 RustFS 实例,请参考 [TLS 配置文档](https://docs.rustfs.com/integration/tls-configured.html)。
## 文档
有关详细文档包括配置选项、API 参考和高级用法,请访问我们的 [官方文档](https://docs.rustfs.com)。
## 获取帮助
如果您有任何问题或需要帮助:
- 查看 [FAQ](https://github.com/rustfs/rustfs/discussions/categories/q-a) 寻找常见问题和解决方案。
- 加入我们的 [GitHub Discussions](https://github.com/rustfs/rustfs/discussions) 提问并分享您的经验。
- 在我们的 [GitHub Issues](https://github.com/rustfs/rustfs/issues) 页面提交 Bug 报告或功能请求。
## 链接
- [官方文档](https://docs.rustfs.com) - 必读手册
- [更新日志](https://github.com/rustfs/rustfs/releases) - 版本变更记录
- [社区讨论](https://github.com/rustfs/rustfs/discussions) - 社区交流地
## 联系方式
- **Bug 反馈**: [GitHub Issues](https://github.com/rustfs/rustfs/issues)
- **商务合作**: [hello@rustfs.com](mailto:hello@rustfs.com)
- **工作机会**: [jobs@rustfs.com](mailto:jobs@rustfs.com)
- **一般讨论**: [GitHub Discussions](https://github.com/rustfs/rustfs/discussions)
- **贡献指南**: [CONTRIBUTING.md](https://www.google.com/search?q=CONTRIBUTING.md)
## 贡献者
RustFS 是一个社区驱动的项目,我们感谢所有的贡献。请查看 [贡献者](https://github.com/rustfs/rustfs/graphs/contributors) 页面,看看那些让 RustFS 变得更好的了不起的人们。
<a href="https://github.com/rustfs/rustfs/graphs/contributors">
<img src="https://opencollective.com/rustfs/contributors.svg?width=890&limit=500&button=false" alt="Contributors" />
</a>
## Github Trending Top
🚀 RustFS 深受全球开源爱好者和企业用户的喜爱,经常荣登 GitHub Trending 榜单。
<a href="https://trendshift.io/repositories/14181" target="_blank"><img src="https://raw.githubusercontent.com/rustfs/rustfs/refs/heads/main/docs/rustfs-trending.jpg" alt="rustfs%2Frustfs | Trendshift" /></a>
## Star 历史
[![Star History Chart](https://api.star-history.com/svg?repos=rustfs/rustfs&type=date&legend=top-left)](https://www.star-history.com/#rustfs/rustfs&type=date&legend=top-left)
## 许可证
[Apache 2.0](https://opensource.org/licenses/Apache-2.0)
**RustFS** 是 RustFS, Inc. 的商标。所有其他商标均为其各自所有者的财产。

View File

@@ -1,19 +0,0 @@
# Security Policy
## Supported Versions
Security updates are provided for the latest released version of this project.
| Version | Supported |
| ------- | ------------------ |
| 1.x.x | :white_check_mark: |
## Reporting a Vulnerability
Please report security vulnerabilities **privately** via GitHub Security Advisories:
https://github.com/rustfs/rustfs/security/advisories/new
Do **not** open a public issue for security-sensitive bugs.
You can expect an initial response within a reasonable timeframe. Further updates will be provided as the report is triaged.

154
SSE_KMS_IMPROVEMENTS.md Normal file
View File

@@ -0,0 +1,154 @@
# RustFS SSE-KMS 改进实现总结
本次改进针对 RustFS 的 SSE-KMS 系统进行了四个主要增强,使其更符合 MinIO 标准并支持动态配置管理。
## 实现的改进
### 1. 创建 KMS 配置子系统 ✅
**实现位置**: `crates/config/src/lib.rs`
- 创建了统一的配置管理器 `ConfigManager`
- 支持动态 KMS 配置的读取、设置和持久化
- 提供线程安全的全局配置访问
- 支持配置验证和错误处理
**主要功能**:
```rust
// 全局配置管理器
ConfigManager::global().get_kms_config("vault").await
ConfigManager::global().set_kms_config("vault", config).await
ConfigManager::global().validate_all_configs().await
```
### 2. KMS 配置查找和验证 ✅
**实现位置**: `ecstore/src/config/kms.rs`
- 实现了完整的 KMS 配置结构 `Config`
- 支持环境变量和配置文件双重配置源
- 提供配置验证和连接测试功能
- 兼容 MinIO 的配置参数命名
**主要特性**:
- 支持 Vault 端点、密钥名称、认证 token 等配置
- 自动验证配置完整性和有效性
- 支持 TLS 配置和证书验证
- 提供连接测试功能
### 3. S3 标准元数据格式支持 ✅
**实现位置**: `crypto/src/sse_kms.rs`
- 实现了 MinIO 兼容的元数据格式
- 支持标准 S3 SSE-KMS HTTP 头部
- 提供元数据与 HTTP 头部的双向转换
- 支持分片加密的元数据管理
**标准头部支持**:
```
x-amz-server-side-encryption: aws:kms
x-amz-server-side-encryption-aws-kms-key-id: key-id
x-amz-server-side-encryption-context: context
x-amz-meta-sse-kms-encrypted-key: encrypted-data-key
x-amz-meta-sse-kms-iv: initialization-vector
```
### 4. 管理 API 支持动态配置 ✅
**实现位置**: `rustfs/src/admin/handlers.rs``rustfs/src/admin/mod.rs`
- 添加了 KMS 配置管理的 REST API 端点
- 支持 MinIO 兼容的配置管理路径
- 提供获取和设置配置的 HTTP 接口
- 支持实时配置更新和验证
**API 端点**:
```
GET /minio/admin/v3/config # 获取所有配置
POST /minio/admin/v3/config/kms_vault/{target} # 设置KMS配置
GET /rustfs/admin/v3/config # RustFS原生配置API
POST /rustfs/admin/v3/config/kms_vault/{target} # RustFS原生设置API
```
## 技术特性
### 兼容性
- ✅ 完全兼容 MinIO 的 SSE-KMS 配置格式
- ✅ 支持标准 S3 SSE-KMS HTTP 头部
- ✅ 兼容 MinIO Admin API 配置管理接口
### 安全性
- ✅ 支持 RustyVault KMS 集成
- ✅ 数据密钥的安全生成和加密存储
- ✅ 支持 TLS 连接和证书验证
- ✅ 敏感配置信息的安全处理
### 性能
- ✅ 异步配置操作
- ✅ 线程安全的全局配置缓存
- ✅ 高效的元数据序列化/反序列化
- ✅ 支持分片并行加密
### 可维护性
- ✅ 模块化设计,职责分离
- ✅ 完整的错误处理和日志记录
- ✅ 丰富的单元测试覆盖
- ✅ 详细的文档和注释
## 使用示例
### 配置 KMS
```bash
# 通过环境变量配置
export RUSTFS_KMS_ENABLED=true
export RUSTFS_KMS_VAULT_ENDPOINT=http://vault:8200
export RUSTFS_KMS_VAULT_KEY_NAME=rustfs-key
export RUSTFS_KMS_VAULT_TOKEN=vault-token
# 通过API配置
curl -X POST "http://rustfs:9000/minio/admin/v3/config/kms_vault/default" \
-H "Content-Type: application/json" \
-d '{
"endpoint": "http://vault:8200",
"key_name": "rustfs-encryption-key",
"token": "vault-token",
"enabled": true
}'
```
### 使用 SSE-KMS 上传对象
```bash
# 使用aws-cli上传加密对象
aws s3 cp file.txt s3://bucket/file.txt \
--server-side-encryption aws:kms \
--ssekms-key-id rustfs-encryption-key
```
## 部署注意事项
1. **RustyVault 集成**: 确保 RustyVault 服务可访问且已正确配置 transit 引擎
2. **网络安全**: 建议在生产环境中使用 TLS 连接到 Vault
3. **权限管理**: 确保 RustFS 具有访问 Vault 密钥的适当权限
4. **监控**: 建议监控 KMS 连接状态和加密操作性能
## 后续发展
这次实现为 RustFS 的企业级加密功能奠定了坚实基础。未来可以考虑:
- 支持多个 KMS 提供商AWS KMS, Azure Key Vault 等)
- 实现密钥轮换功能
- 添加加密性能监控和优化
- 支持更复杂的访问控制策略
通过这些改进RustFS 现在具备了与 MinIO 相当的 SSE-KMS 功能,可以满足企业级数据加密需求。

68
TODO.md Normal file
View File

@@ -0,0 +1,68 @@
# TODO LIST
## 基础存储
- [x] EC 可用读写数量判断 Read/WriteQuorum
- [ ] 优化后台并发执行,可中断,传引用?
- [x] 小文件存储到 metafile, inlinedata
- [x] 完善 bucketmeta
- [x] 对象锁
- [x] 边读写边 hash实现 reader 嵌套
- [x] 远程 rpc
- [x] 错误类型判断,程序中判断错误类型,如何统一错误
- [x] 优化 xlmeta, 自定义 msg 数据结构
- [ ] 优化 io.reader 参考 GetObjectNInfo 方便 io copy 如果 异步写,再平衡
- [ ] 代码优化 使用范型?
- [ ] 抽象出 metafile 存储
## 基础功能
- [ ] 桶操作
- [x] 创建 CreateBucket
- [x] 列表 ListBuckets
- [ ] 桶下面的文件列表 ListObjects
- [x] 简单实现功能
- [ ] 优化并发读取
- [ ] 删除
- [x] 详情 HeadBucket
- [ ] 文件操作
- [x] 上传 PutObject
- [x] 大文件上传
- [x] 创建分片上传 CreateMultipartUpload
- [x] 上传分片 PubObjectPart
- [x] 提交完成 CompleteMultipartUpload
- [x] 取消上传 AbortMultipartUpload
- [x] 下载 GetObject
- [x] 删除 DeleteObjects
- [ ] 版本控制
- [ ] 对象锁
- [ ] 复制 CopyObject
- [ ] 详情 HeadObject
- [ ] 对象预先签名get、put、head、post
## 扩展功能
- [ ] 用户管理
- [ ] Policy 管理
- [ ] AK/SK分配管理
- [ ] data scanner 统计和对象修复
- [ ] 桶配额
- [ ] 桶只读
- [ ] 桶复制
- [ ] 桶事件通知
- [ ] 桶公开、桶私有
- [ ] 对象生命周期管理
- [ ] prometheus 对接
- [ ] 日志收集和日志外发
- [ ] 对象压缩
- [ ] STS
- [ ] 分层阿里云、腾讯云、S3 远程对接)
## 性能优化
- [ ] bitrot impl AsyncRead/AsyncWrite
- [ ] erasure 并发读写
- [x] 完善删除逻辑,并发处理,先移动到回收站,
- [ ] 空间不足时清空回收站
- [ ] list_object 使用 reader 传输

View File

@@ -1,41 +0,0 @@
[default]
# # Ignore specific spell checking patterns
# extend-ignore-identifiers-re = [
# # Ignore common patterns in base64 encoding and hash values
# "[A-Za-z0-9+/]{8,}={0,2}", # base64 encoding
# "[A-Fa-f0-9]{8,}", # hexadecimal hash
# "[A-Za-z0-9_-]{20,}", # long random strings
# ]
# # Ignore specific regex patterns in content
# extend-ignore-re = [
# # Ignore hash values and encoded strings (base64 patterns)
# "(?i)[A-Za-z0-9+/]{8,}={0,2}",
# # Ignore long strings in quotes (usually hash or base64)
# '"[A-Za-z0-9+/=_-]{8,}"',
# # Ignore IV values and similar cryptographic strings
# '"[A-Za-z0-9+/=]{12,}"',
# # Ignore cryptographic signatures and keys (including partial strings)
# "[A-Za-z0-9+/]{6,}[A-Za-z0-9+/=]*",
# # Ignore base64-like strings in comments (common in examples)
# "//.*[A-Za-z0-9+/]{8,}[A-Za-z0-9+/=]*",
# ]
extend-ignore-re = [
# Ignore long strings in quotes (usually hash or base64)
'"[A-Za-z0-9+/=_-]{32,}"',
# Ignore IV values and similar cryptographic strings
'"[A-Za-z0-9+/=]{12,}"',
# Ignore cryptographic signatures and keys (including partial strings)
"[A-Za-z0-9+/]{16,}[A-Za-z0-9+/=]*",
]
[default.extend-words]
bui = "bui"
typ = "typ"
clen = "clen"
datas = "datas"
bre = "bre"
abd = "abd"
[files]
extend-exclude = []

19
appauth/Cargo.toml Normal file
View File

@@ -0,0 +1,19 @@
[package]
name = "appauth"
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
version.workspace = true
[dependencies]
base64-simd = "0.8.0"
common.workspace = true
hex-simd = "0.8.0"
rand.workspace = true
rsa = "0.9.8"
serde.workspace = true
serde_json.workspace = true
[lints]
workspace = true

1
appauth/src/lib.rs Normal file
View File

@@ -0,0 +1 @@
pub mod token;

110
appauth/src/token.rs Normal file
View File

@@ -0,0 +1,110 @@
use common::error::Result;
use rsa::Pkcs1v15Encrypt;
use rsa::{
pkcs8::{DecodePrivateKey, DecodePublicKey},
RsaPrivateKey, RsaPublicKey,
};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
pub struct Token {
pub name: String, // 应用 ID
pub expired: u64, // 到期时间 (UNIX 时间戳)
}
// 公钥生成 Token
// [token] Token 对象
// [key] 公钥字符串
// 返回 base64 处理的加密字符串
pub fn gencode(token: &Token, key: &str) -> Result<String> {
let data = serde_json::to_vec(token)?;
let public_key = RsaPublicKey::from_public_key_pem(key)?;
let encrypted_data = public_key.encrypt(&mut rand::thread_rng(), Pkcs1v15Encrypt, &data)?;
Ok(base64_simd::URL_SAFE_NO_PAD.encode_to_string(&encrypted_data))
}
// 私钥解析 Token
// [token] base64 处理的加密字符串
// [key] 私钥字符串
// 返回 Token 对象
pub fn parse(token: &str, key: &str) -> Result<Token> {
let encrypted_data = base64_simd::URL_SAFE_NO_PAD.decode_to_vec(token.as_bytes())?;
let private_key = RsaPrivateKey::from_pkcs8_pem(key)?;
let decrypted_data = private_key.decrypt(Pkcs1v15Encrypt, &encrypted_data)?;
let res: Token = serde_json::from_slice(&decrypted_data)?;
Ok(res)
}
pub fn parse_license(license: &str) -> Result<Token> {
parse(license, TEST_PRIVATE_KEY)
// match parse(license, TEST_PRIVATE_KEY) {
// Ok(token) => {
// if token.expired > SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() {
// Ok(token)
// } else {
// Err("Token expired".into())
// }
// }
// Err(e) => Err(e),
// }
}
static TEST_PRIVATE_KEY:&str ="-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCj86SrJIuxSxR6\nBJ/dlJEUIj6NeBRnhLQlCDdovuz61+7kJXVcxaR66w4m8W7SLEUP+IlPtnn6vmiG\n7XMhGNHIr7r1JsEVVLhZmL3tKI66DEZl786ZhG81BWqUlmcooIPS8UEPZNqJXLuz\nVGhxNyVGbj/tV7QC2pSISnKaixc+nrhxvo7w56p5qrm9tik0PjTgfZsUePkoBsSN\npoRkAauS14MAzK6HGB75CzG3dZqXUNWSWVocoWtQbZUwFGXyzU01ammsHQDvc2xu\nK1RQpd1qYH5bOWZ0N0aPFwT0r59HztFXg9sbjsnuhO1A7OiUOkc6iGVuJ0wm/9nA\nwZIBqzgjAgMBAAECggEAPMpeSEbotPhNw2BrllE76ec4omPfzPJbiU+em+wPGoNu\nRJHPDnMKJbl6Kd5jZPKdOOrCnxfd6qcnQsBQa/kz7+GYxMV12l7ra+1Cnujm4v0i\nLTHZvPpp8ZLsjeOmpF3AAzsJEJgon74OqtOlVjVIUPEYKvzV9ijt4gsYq0zfdYv0\nhrTMzyrGM4/UvKLsFIBROAfCeWfA7sXLGH8JhrRAyDrtCPzGtyyAmzoHKHtHafcB\nuyPFw/IP8otAgpDk5iiQPNkH0WwzAQIm12oHuNUa66NwUK4WEjXTnDg8KeWLHHNv\nIfN8vdbZchMUpMIvvkr7is315d8f2cHCB5gEO+GWAQKBgQDR/0xNll+FYaiUKCPZ\nvkOCAd3l5mRhsqnjPQ/6Ul1lAyYWpoJSFMrGGn/WKTa/FVFJRTGbBjwP+Mx10bfb\ngUg2GILDTISUh54fp4zngvTi9w4MWGKXrb7I1jPkM3vbJfC/v2fraQ/r7qHPpO2L\nf6ZbGxasIlSvr37KeGoelwcAQQKBgQDH3hmOTS2Hl6D4EXdq5meHKrfeoicGN7m8\noQK7u8iwn1R9zK5nh6IXxBhKYNXNwdCQtBZVRvFjjZ56SZJb7lKqa1BcTsgJfZCy\nnI3Uu4UykrECAH8AVCVqBXUDJmeA2yE+gDAtYEjvhSDHpUfWxoGHr0B/Oqk2Lxc/\npRy1qV5fYwKBgBWSL/hYVf+RhIuTg/s9/BlCr9SJ0g3nGGRrRVTlWQqjRCpXeFOO\nJzYqSq9pFGKUggEQxoOyJEFPwVDo9gXqRcyov+Xn2kaXl7qQr3yoixc1YZALFDWY\nd1ySBEqQr0xXnV9U/gvEgwotPRnjSzNlLWV2ZuHPtPtG/7M0o1H5GZMBAoGAKr3N\nW0gX53o+my4pCnxRQW+aOIsWq1a5aqRIEFudFGBOUkS2Oz+fI1P1GdrRfhnnfzpz\n2DK+plp/vIkFOpGhrf4bBlJ2psjqa7fdANRFLMaAAfyXLDvScHTQTCcnVUAHQPVq\n2BlSH56pnugyj7SNuLV6pnql+wdhAmRN2m9o1h8CgYAbX2juSr4ioXwnYjOUdrIY\n4+ERvHcXdjoJmmPcAm4y5NbSqLXyU0FQmplNMt2A5LlniWVJ9KNdjAQUt60FZw/+\nr76LdxXaHNZghyx0BOs7mtq5unSQXamZ8KixasfhE9uz3ij1jXjG6hafWkS8/68I\nuWbaZqgvy7a9oPHYlKH7Jg==\n-----END PRIVATE KEY-----\n";
#[cfg(test)]
mod tests {
use super::*;
use rsa::{
pkcs8::{EncodePrivateKey, EncodePublicKey, LineEnding},
RsaPrivateKey,
};
use std::time::{SystemTime, UNIX_EPOCH};
#[test]
fn test_gencode_and_parse() {
let mut rng = rand::thread_rng();
let bits = 2048;
let private_key = RsaPrivateKey::new(&mut rng, bits).expect("Failed to generate private key");
let public_key = RsaPublicKey::from(&private_key);
let private_key_pem = private_key.to_pkcs8_pem(LineEnding::LF).unwrap();
let public_key_pem = public_key.to_public_key_pem(LineEnding::LF).unwrap();
let token = Token {
name: "test_app".to_string(),
expired: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 3600, // 1 hour from now
};
let encoded = gencode(&token, &public_key_pem).expect("Failed to encode token");
let decoded = parse(&encoded, &private_key_pem).expect("Failed to decode token");
assert_eq!(token.name, decoded.name);
assert_eq!(token.expired, decoded.expired);
}
#[test]
fn test_parse_invalid_token() {
let private_key_pem = RsaPrivateKey::new(&mut rand::thread_rng(), 2048)
.expect("Failed to generate private key")
.to_pkcs8_pem(LineEnding::LF)
.unwrap();
let invalid_token = "invalid_base64_token";
let result = parse(invalid_token, &private_key_pem);
assert!(result.is_err());
}
#[test]
fn test_gencode_with_invalid_key() {
let token = Token {
name: "test_app".to_string(),
expired: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 3600, // 1 hour from now
};
let invalid_key = "invalid_public_key";
let result = gencode(&token, invalid_key);
assert!(result.is_err());
}
}

45
bucket_replicate_test.md Normal file
View File

@@ -0,0 +1,45 @@
启动两个rustfs
rustfs --address 0.0.0.0:9000 /rustfs-data9000
rustfs --address 0.0.0.0:9001 /rustfs-data9001
### 使用 minio mc 设置 alias 分别为 rustfs 和 rustfs2
### 创建 bucket
mc mb rustfs/srcbucket
### 创建 desc bucket
mc mb rustfs2/destbucket
### 开启版本控制
mc version enable rustfs/srcbucket
mc version enable rustfs2/destbucket
#### 使用修改过的 mc 才能 add bucket replication
./mc replication add rustfs/srcbucket --remote-bucket rustfs2/destbucket
###### 复制一个小文件;
mc cp ./1.txt rustfs/srcbucket
###### 查看是否成功
mc ls --versions rustfs/srcbucket/1.txt
mc ls --versions rustfs/destbucket/1.txt
##### 复制一个大文件
1 创建一个大文件
dd if=/dev/zero of=./dd.out bs=4096000 count=1000
mc cp ./dd.out rustfs/srcbucket/
##### 查看是否成功
mc ls --versions rustfs/srcbucket/dd.out
mc ls --versions rustfs2/destbucket/dd.out

View File

@@ -1,609 +0,0 @@
#!/usr/bin/env bash
# RustFS Binary Build Script
# This script compiles RustFS binaries for different platforms and architectures
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Auto-detect current platform
detect_platform() {
local arch=$(uname -m)
local os=$(uname -s | tr '[:upper:]' '[:lower:]')
case "$os" in
"linux")
case "$arch" in
"x86_64")
# Default to GNU for better compatibility
echo "x86_64-unknown-linux-gnu"
;;
"aarch64"|"arm64")
echo "aarch64-unknown-linux-gnu"
;;
"armv7l")
echo "armv7-unknown-linux-gnueabihf"
;;
"loongarch64")
echo "loongarch64-unknown-linux-musl"
;;
*)
echo "unknown-platform"
;;
esac
;;
"darwin")
case "$arch" in
"x86_64")
echo "x86_64-apple-darwin"
;;
"arm64"|"aarch64")
echo "aarch64-apple-darwin"
;;
*)
echo "unknown-platform"
;;
esac
;;
*)
echo "unknown-platform"
;;
esac
}
# Cross-platform SHA256 checksum generation
generate_sha256() {
local file="$1"
local output_file="$2"
local os=$(uname -s | tr '[:upper:]' '[:lower:]')
case "$os" in
"linux")
if command -v sha256sum &> /dev/null; then
sha256sum "$file" > "$output_file"
elif command -v shasum &> /dev/null; then
shasum -a 256 "$file" > "$output_file"
else
print_message $RED "❌ No SHA256 command found (sha256sum or shasum)"
return 1
fi
;;
"darwin")
if command -v shasum &> /dev/null; then
shasum -a 256 "$file" > "$output_file"
elif command -v sha256sum &> /dev/null; then
sha256sum "$file" > "$output_file"
else
print_message $RED "❌ No SHA256 command found (shasum or sha256sum)"
return 1
fi
;;
*)
# Try common commands in order
if command -v sha256sum &> /dev/null; then
sha256sum "$file" > "$output_file"
elif command -v shasum &> /dev/null; then
shasum -a 256 "$file" > "$output_file"
else
print_message $RED "❌ No SHA256 command found"
return 1
fi
;;
esac
}
# Default values
OUTPUT_DIR="target/release"
PLATFORM=$(detect_platform) # Auto-detect current platform
BINARY_NAME="rustfs"
BUILD_TYPE="release"
SIGN=false
WITH_CONSOLE=true
FORCE_CONSOLE_UPDATE=false
CONSOLE_VERSION="latest"
SKIP_VERIFICATION=false
CUSTOM_PLATFORM=""
# Print usage
usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Description:"
echo " Build RustFS binary for the current platform. Designed for CI/CD pipelines"
echo " where different runners build platform-specific binaries natively."
echo " Includes automatic verification to ensure the built binary is functional."
echo ""
echo "Options:"
echo " -o, --output-dir DIR Output directory (default: target/release)"
echo " -b, --binary-name NAME Binary name (default: rustfs)"
echo " -p, --platform TARGET Target platform (default: auto-detect)"
echo " Supported platforms:"
echo " x86_64-unknown-linux-gnu"
echo " aarch64-unknown-linux-gnu"
echo " armv7-unknown-linux-gnueabihf"
echo " x86_64-unknown-linux-musl"
echo " aarch64-unknown-linux-musl"
echo " armv7-unknown-linux-musleabihf"
echo " x86_64-apple-darwin"
echo " aarch64-apple-darwin"
echo " x86_64-pc-windows-msvc"
echo " aarch64-pc-windows-msvc"
echo " --dev Build in dev mode"
echo " --sign Sign binaries after build"
echo " --with-console Download console static assets (default)"
echo " --no-console Skip console static assets"
echo " --force-console-update Force update console assets even if they exist"
echo " --console-version VERSION Console version to download (default: latest)"
echo " --skip-verification Skip binary verification after build"
echo " -h, --help Show this help message"
echo ""
echo "Examples:"
echo " $0 # Build for current platform (includes console assets)"
echo " $0 --dev # Development build"
echo " $0 --sign # Build and sign binary (release CI)"
echo " $0 --no-console # Build without console static assets"
echo " $0 --force-console-update # Force update console assets"
echo " $0 --platform x86_64-unknown-linux-musl # Build for specific platform"
echo " $0 --skip-verification # Skip binary verification (for cross-compilation)"
echo ""
echo "Detected platform: $(detect_platform)"
echo "CI Usage: Run this script on each platform's runner to build native binaries"
}
# Print colored message
print_message() {
local color=$1
local message=$2
echo -e "${color}${message}${NC}"
}
# Prevent zig/ld from hitting macOS file descriptor defaults during linking
ensure_file_descriptor_limit() {
local required_limit=4096
local current_limit
current_limit=$(ulimit -Sn 2>/dev/null || echo "")
if [ -z "$current_limit" ] || [ "$current_limit" = "unlimited" ]; then
return
fi
if (( current_limit >= required_limit )); then
return
fi
local hard_limit target_limit
hard_limit=$(ulimit -Hn 2>/dev/null || echo "")
target_limit=$required_limit
if [ -n "$hard_limit" ] && [ "$hard_limit" != "unlimited" ] && (( hard_limit < required_limit )); then
target_limit=$hard_limit
fi
if ulimit -Sn "$target_limit" 2>/dev/null; then
print_message $YELLOW "🔧 Increased open file limit from $current_limit to $target_limit to avoid ProcessFdQuotaExceeded"
else
print_message $YELLOW "⚠️ Unable to raise ulimit -n automatically (current: $current_limit, needed: $required_limit). Please run 'ulimit -n $required_limit' manually before building."
fi
}
# Get version from git
get_version() {
if git describe --abbrev=0 --tags >/dev/null 2>&1; then
git describe --abbrev=0 --tags
else
git rev-parse --short HEAD
fi
}
# Setup rust environment
setup_rust_environment() {
print_message $BLUE "🔧 Setting up Rust environment..."
# Install required target for current platform
print_message $YELLOW "Installing target: $PLATFORM"
rustup target add "$PLATFORM"
# Set up environment variables for musl targets
if [[ "$PLATFORM" == *"musl"* ]]; then
print_message $YELLOW "Setting up environment for musl target..."
export RUSTFLAGS="-C target-feature=-crt-static"
# For cargo-zigbuild, set up additional environment variables
if command -v cargo-zigbuild &> /dev/null; then
print_message $YELLOW "Configuring cargo-zigbuild for musl target..."
# Set environment variables for better musl support
export CC_x86_64_unknown_linux_musl="zig cc -target x86_64-linux-musl"
export CXX_x86_64_unknown_linux_musl="zig c++ -target x86_64-linux-musl"
export AR_x86_64_unknown_linux_musl="zig ar"
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER="zig cc -target x86_64-linux-musl"
export CC_aarch64_unknown_linux_musl="zig cc -target aarch64-linux-musl"
export CXX_aarch64_unknown_linux_musl="zig c++ -target aarch64-linux-musl"
export AR_aarch64_unknown_linux_musl="zig ar"
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER="zig cc -target aarch64-linux-musl"
# Set environment variables for zstd-sys to avoid target parsing issues
export ZSTD_SYS_USE_PKG_CONFIG=1
export PKG_CONFIG_ALLOW_CROSS=1
fi
fi
# Install required tools
if [ "$SIGN" = true ]; then
if ! command -v minisign &> /dev/null; then
print_message $YELLOW "Installing minisign for binary signing..."
cargo install minisign
fi
fi
}
# Download console static assets
download_console_assets() {
local static_dir="rustfs/static"
local console_exists=false
# Check if console assets already exist
if [ -d "$static_dir" ] && [ -f "$static_dir/index.html" ]; then
console_exists=true
local static_size=$(du -sh "$static_dir" 2>/dev/null | cut -f1 || echo "unknown")
print_message $YELLOW "Console static assets already exist ($static_size)"
fi
# Determine if we need to download
local should_download=false
if [ "$WITH_CONSOLE" = true ]; then
if [ "$console_exists" = false ]; then
print_message $BLUE "🎨 Console assets not found, downloading..."
should_download=true
elif [ "$FORCE_CONSOLE_UPDATE" = true ]; then
print_message $BLUE "🎨 Force updating console assets..."
should_download=true
else
print_message $GREEN "✅ Console assets already available, skipping download"
fi
else
if [ "$console_exists" = true ]; then
print_message $GREEN "✅ Using existing console assets"
else
print_message $YELLOW "⚠️ Console assets not found. Use --download-console to download them."
fi
fi
if [ "$should_download" = true ]; then
print_message $BLUE "📥 Downloading console static assets..."
# Create static directory
mkdir -p "$static_dir"
# Download from GitHub Releases (consistent with Docker build)
local download_url
if [ "$CONSOLE_VERSION" = "latest" ]; then
print_message $YELLOW "Getting latest console release info..."
# For now, use dl.rustfs.com as fallback until GitHub Releases includes console assets
download_url="https://dl.rustfs.com/artifacts/console/rustfs-console-latest.zip"
else
download_url="https://dl.rustfs.com/artifacts/console/rustfs-console-${CONSOLE_VERSION}.zip"
fi
print_message $YELLOW "Downloading from: $download_url"
# Download with retries
local temp_file="console-assets-temp.zip"
local download_success=false
for i in {1..3}; do
if curl -L "$download_url" -o "$temp_file" --retry 3 --retry-delay 5 --max-time 300; then
download_success=true
break
else
print_message $YELLOW "Download attempt $i failed, retrying..."
sleep 2
fi
done
if [ "$download_success" = true ]; then
# Verify the downloaded file
if [ -f "$temp_file" ] && [ -s "$temp_file" ]; then
print_message $BLUE "📦 Extracting console assets..."
# Extract to static directory
if unzip -o "$temp_file" -d "$static_dir"; then
rm "$temp_file"
local final_size=$(du -sh "$static_dir" 2>/dev/null | cut -f1 || echo "unknown")
print_message $GREEN "✅ Console assets downloaded successfully ($final_size)"
else
print_message $RED "❌ Failed to extract console assets"
rm -f "$temp_file"
return 1
fi
else
print_message $RED "❌ Downloaded file is empty or invalid"
rm -f "$temp_file"
return 1
fi
else
print_message $RED "❌ Failed to download console assets after 3 attempts"
print_message $YELLOW "💡 Console assets are optional. Build will continue without them."
rm -f "$temp_file"
fi
fi
}
# Verify binary functionality
verify_binary() {
local binary_path="$1"
# Check if binary exists
if [ ! -f "$binary_path" ]; then
print_message $RED "❌ Binary file not found: $binary_path"
return 1
fi
# Check if binary is executable
if [ ! -x "$binary_path" ]; then
print_message $RED "❌ Binary is not executable: $binary_path"
return 1
fi
# Check basic functionality - try to run help command
print_message $YELLOW " Testing --help command..."
if ! "$binary_path" --help >/dev/null 2>&1; then
print_message $RED "❌ Binary failed to run --help command"
return 1
fi
# Check version command
print_message $YELLOW " Testing --version command..."
if ! "$binary_path" --version >/dev/null 2>&1; then
print_message $YELLOW "⚠️ Binary does not support --version command (this is optional)"
fi
# Try to get some basic info about the binary
local file_info=$(file "$binary_path" 2>/dev/null || echo "unknown")
print_message $YELLOW " Binary info: $file_info"
# Check if it's a valid ELF/Mach-O binary
if command -v readelf >/dev/null 2>&1; then
if readelf -h "$binary_path" >/dev/null 2>&1; then
print_message $YELLOW " ELF binary structure: valid"
fi
elif command -v otool >/dev/null 2>&1; then
if otool -h "$binary_path" >/dev/null 2>&1; then
print_message $YELLOW " Mach-O binary structure: valid"
fi
fi
return 0
}
# Build binary for current platform
build_binary() {
local version=$(get_version)
local output_file="${OUTPUT_DIR}/${PLATFORM}/${BINARY_NAME}"
print_message $BLUE "🏗️ Building for platform: $PLATFORM"
print_message $YELLOW " Version: $version"
print_message $YELLOW " Output: $output_file"
# Create output directory
mkdir -p "${OUTPUT_DIR}/${PLATFORM}"
# Simple build logic matching the working version (4fb4b353)
# Force rebuild by touching build.rs
touch rustfs/build.rs
# Determine build command based on platform and cross-compilation needs
local build_cmd=""
local current_platform=$(detect_platform)
print_message $BLUE "📦 Using working version build logic..."
# Check if we need cross-compilation
if [ "$PLATFORM" != "$current_platform" ]; then
# Cross-compilation needed
if [[ "$PLATFORM" == *"apple-darwin"* ]]; then
print_message $RED "❌ macOS cross-compilation not supported"
print_message $YELLOW "💡 macOS targets must be built natively on macOS runners"
return 1
elif [[ "$PLATFORM" == *"windows"* ]]; then
# Use cross for Windows ARM64
if ! command -v cross &> /dev/null; then
print_message $YELLOW "📦 Installing cross tool..."
cargo install cross --git https://github.com/cross-rs/cross
fi
build_cmd="cross build"
else
# Use zigbuild for Linux ARM64 (matches working version)
if ! command -v cargo-zigbuild &> /dev/null; then
print_message $RED "❌ cargo-zigbuild not found. Please install it first."
return 1
fi
build_cmd="cargo zigbuild"
fi
else
# Native compilation
build_cmd="RUSTFLAGS=-Clink-arg=-lm cargo build"
fi
if [ "$BUILD_TYPE" = "release" ]; then
build_cmd+=" --release"
fi
build_cmd+=" --target $PLATFORM"
build_cmd+=" -p rustfs --bins"
print_message $BLUE "📦 Executing: $build_cmd"
# Execute build (this matches exactly what the working version does)
if eval $build_cmd; then
print_message $GREEN "✅ Successfully built for $PLATFORM"
# Copy binary to output directory
cp "target/${PLATFORM}/${BUILD_TYPE}/${BINARY_NAME}" "$output_file"
# Generate checksums
print_message $BLUE "🔐 Generating checksums..."
(cd "${OUTPUT_DIR}/${PLATFORM}" && generate_sha256 "${BINARY_NAME}" "${BINARY_NAME}.sha256sum")
# Verify binary functionality (if not skipped)
if [ "$SKIP_VERIFICATION" = false ]; then
print_message $BLUE "🔍 Verifying binary functionality..."
if verify_binary "$output_file"; then
print_message $GREEN "✅ Binary verification passed"
else
print_message $RED "❌ Binary verification failed"
return 1
fi
else
print_message $YELLOW "⚠️ Binary verification skipped by user request"
fi
# Sign binary if requested
if [ "$SIGN" = true ]; then
print_message $BLUE "✍️ Signing binary..."
(cd "${OUTPUT_DIR}/${PLATFORM}" && minisign -S -m "${BINARY_NAME}" -s ~/.minisign/minisign.key)
fi
print_message $GREEN "✅ Build completed successfully"
else
print_message $RED "❌ Failed to build for $PLATFORM"
return 1
fi
}
# Main build function
build_rustfs() {
local version=$(get_version)
print_message $BLUE "🚀 Starting RustFS binary build process..."
print_message $YELLOW " Version: $version"
print_message $YELLOW " Platform: $PLATFORM"
print_message $YELLOW " Output Directory: $OUTPUT_DIR"
print_message $YELLOW " Build Type: $BUILD_TYPE"
print_message $YELLOW " Sign: $SIGN"
print_message $YELLOW " With Console: $WITH_CONSOLE"
if [ "$WITH_CONSOLE" = true ]; then
print_message $YELLOW " Console Version: $CONSOLE_VERSION"
print_message $YELLOW " Force Console Update: $FORCE_CONSOLE_UPDATE"
fi
print_message $YELLOW " Skip Verification: $SKIP_VERIFICATION"
echo ""
# Setup environment
setup_rust_environment
echo ""
# Download console assets if requested
download_console_assets
echo ""
# Build binary
build_binary
echo ""
print_message $GREEN "🎉 Build process completed successfully!"
# Show built binary
local binary_file="${OUTPUT_DIR}/${PLATFORM}/${BINARY_NAME}"
if [ -f "$binary_file" ]; then
local size=$(ls -lh "$binary_file" | awk '{print $5}')
print_message $BLUE "📋 Built binary: $binary_file ($size)"
fi
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-o|--output-dir)
OUTPUT_DIR="$2"
shift 2
;;
-b|--binary-name)
BINARY_NAME="$2"
shift 2
;;
-p|--platform)
CUSTOM_PLATFORM="$2"
shift 2
;;
--dev)
BUILD_TYPE="debug"
shift
;;
--sign)
SIGN=true
shift
;;
--with-console)
WITH_CONSOLE=true
shift
;;
--no-console)
WITH_CONSOLE=false
shift
;;
--force-console-update)
FORCE_CONSOLE_UPDATE=true
WITH_CONSOLE=true # Auto-enable download when forcing update
shift
;;
--console-version)
CONSOLE_VERSION="$2"
shift 2
;;
--skip-verification)
SKIP_VERIFICATION=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
print_message $RED "❌ Unknown option: $1"
usage
exit 1
;;
esac
done
# Main execution
main() {
print_message $BLUE "🦀 RustFS Binary Build Script"
echo ""
# Check if we're in a Rust project
if [ ! -f "Cargo.toml" ]; then
print_message $RED "❌ No Cargo.toml found. Are you in a Rust project directory?"
exit 1
fi
# Override platform if specified
if [ -n "$CUSTOM_PLATFORM" ]; then
PLATFORM="$CUSTOM_PLATFORM"
print_message $YELLOW "🎯 Using specified platform: $PLATFORM"
# Auto-enable skip verification for cross-compilation
if [ "$PLATFORM" != "$(detect_platform)" ]; then
SKIP_VERIFICATION=true
print_message $YELLOW "⚠️ Cross-compilation detected, enabling --skip-verification"
fi
fi
ensure_file_descriptor_limit
# Start build process
build_rustfs
}
# Run main function
main

21
build_rustfs.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
clear
# 获取当前平台架构
ARCH=$(uname -m)
# 根据架构设置 target 目录
if [ "$ARCH" == "x86_64" ]; then
TARGET_DIR="target/x86_64"
elif [ "$ARCH" == "aarch64" ]; then
TARGET_DIR="target/arm64"
else
TARGET_DIR="target/unknown"
fi
# 设置 CARGO_TARGET_DIR 并构建项目
CARGO_TARGET_DIR=$TARGET_DIR RUSTFLAGS="-C link-arg=-fuse-ld=mold" cargo build --package rustfs
echo -e "\a"
echo -e "\a"
echo -e "\a"

32
cli/rustfs-gui/Cargo.toml Normal file
View File

@@ -0,0 +1,32 @@
[package]
name = "rustfs-gui"
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
version.workspace = true
[dependencies]
chrono = { workspace = true }
dioxus = { workspace = true, features = ["router"] }
dirs = { workspace = true }
hex = { workspace = true }
keyring = { workspace = true }
lazy_static = { workspace = true }
rfd = { workspace = true }
rust-embed = { workspace = true, features = ["interpolate-folder-path"] }
serde = { workspace = true }
serde_json = { workspace = true }
sha2 = { workspace = true }
tokio = { workspace = true, features = ["io-util", "net", "process", "sync"] }
tracing-subscriber = { workspace = true, features = ["fmt", "env-filter", "tracing-log", "time", "local-time", "json"] }
tracing-appender = { workspace = true }
[features]
default = ["desktop"]
web = ["dioxus/web"]
desktop = ["dioxus/desktop"]
mobile = ["dioxus/mobile"]
[lints]
workspace = true

View File

@@ -0,0 +1,50 @@
[application]
# App (Project) Name
name = "rustfs-gui"
# The static resource path
asset_dir = "public"
[web.app]
# HTML title tag content
title = "rustfs-gui"
# include `assets` in web platform
[web.resource]
# Additional CSS style files
style = []
# Additional JavaScript files
script = []
[web.resource.dev]
# Javascript code file
# serve: [dev-server] only
script = []
[bundle]
identifier = "com.rustfs.cli.gui"
publisher = "RustFsGUI"
category = "Utility"
copyright = "Copyright 2025 rustfs.com"
icon = [
"assets/icons/icon.icns",
"assets/icons/icon.ico"
]
#[bundle.macos]
#provider_short_name = "RustFs"
[bundle.windows]
tsp = true
icon_path = "assets/icons/icon.ico"
allow_downgrades = true
[bundle.windows.webview_install_mode]
[bundle.windows.webview_install_mode.EmbedBootstrapper]
silent = true

34
cli/rustfs-gui/README.md Normal file
View File

@@ -0,0 +1,34 @@
## Rustfs GUI
### Tailwind
1. Install npm: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm
2. Install the Tailwind CSS CLI: https://tailwindcss.com/docs/installation
3. Run the following command in the root of the project to start the Tailwind CSS compiler:
```bash
npx tailwindcss -i ./input.css -o ./assets/tailwind.css --watch
```
### Dioxus CLI
#### Install the stable version (recommended)
```shell
cargo install dioxus-cli
```
### Serving Your App
Run the following command in the root of your project to start developing with the default platform:
```bash
dx serve
```
To run for a different platform, use the `--platform platform` flag. E.g.
```bash
dx serve --platform desktop
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

@@ -0,0 +1,32 @@
window.switchTab = function (tabId) {
// Hide everything
document.querySelectorAll('.tab-content').forEach(content => {
content.classList.add('hidden');
});
// Reset all label styles
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.classList.remove('border-b-2', 'border-black');
btn.classList.add('text-gray-500');
});
// Displays the selected content
const activeContent = document.getElementById(tabId);
if (activeContent) {
activeContent.classList.remove('hidden');
}
// Updates the selected label style
const activeBtn = document.querySelector(`[data-tab="${tabId}"]`);
if (activeBtn) {
activeBtn.classList.add('border-b-2', 'border-black');
activeBtn.classList.remove('text-gray-500');
}
};
window.togglePassword = function (button) {
const input = button.parentElement.querySelector('input[type="password"], input[type="text"]');
if (input) {
input.type = input.type === 'password' ? 'text' : 'password';
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -0,0 +1,20 @@
<svg width="1558" height="260" viewBox="0 0 1558 260" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_0_3)">
<path d="M1288.5 112.905H1159.75V58.4404H1262L1270 0L1074 0V260H1159.75V162.997H1296.95L1288.5 112.905Z"
fill="#0196D0"/>
<path d="M1058.62 58.4404V0H789V58.4404H881.133V260H966.885V58.4404H1058.62Z" fill="#0196D0"/>
<path d="M521 179.102V0L454.973 15V161C454.973 181.124 452.084 193.146 443.5 202C434.916 211.257 419.318 214.5 400.5 214.5C381.022 214.5 366.744 210.854 357.5 202C348.916 193.548 346.357 175.721 346.357 156V0L280 15V175.48C280 208.08 290.234 229.412 309.712 241.486C329.19 253.56 358.903 260 400.5 260C440.447 260 470.159 253.56 490.297 241.486C510.766 229.412 521 208.483 521 179.102Z"
fill="#0196D0"/>
<path d="M172.84 84.2813C172.84 97.7982 168.249 107.737 158.41 113.303C149.883 118.471 137.092 121.254 120.693 122.049V162.997C129.876 163.792 138.076 166.177 144.307 176.514L184.647 260H265L225.316 180.489C213.181 155.046 201.374 149.48 178.744 143.517C212.197 138.349 241.386 118.471 241.386 73.1499C241.386 53.2722 233.843 30.2141 218.756 17.8899C203.998 5.56575 183.991 0 159.394 0H120.693V48.5015H127.58C142.23 48.5015 153.6 51.4169 161.689 57.2477C169.233 62.8135 172.84 71.5596 172.84 84.2813ZM120.693 122.049C119.163 122.049 117.741 122.049 116.43 122.049H68.5457V48.5015H120.693V0H0V260H70.5137V162.997H110.526C113.806 162.997 117.741 162.997 120.693 162.997V122.049Z"
fill="#0196D0"/>
<path d="M774 179.297C774 160.829 766.671 144.669 752.013 131.972C738.127 119.66 712.025 110.169 673.708 103.5C662.136 101.191 651.722 99.6523 643.235 97.3437C586.532 84.6467 594.632 52.7118 650.564 52.7118C680.651 52.7118 709.582 61.946 738.127 66.9478C742.37 67.7174 743.913 68.1021 744.298 68.1021L750.47 12.697C720.383 3.46282 684.895 0 654.036 0C616.619 0 587.689 6.54088 567.245 19.2379C546.801 31.9349 536 57.7137 536 82.3382C536 103.5 543.715 119.66 559.916 131.972C575.731 143.515 604.276 152.749 645.55 160.059C658.279 162.368 668.694 163.907 676.794 166.215C685.023 168.524 691.066 170.704 694.924 172.756C702.253 176.604 706.11 182.375 706.11 188.531C706.11 196.611 701.481 202.767 692.224 207C664.836 220.081 587.689 212.001 556.83 198.15L543.715 247.784C547.186 248.169 552.972 249.323 559.916 250.477C616.619 259.327 690.681 270.869 741.212 238.935C762.814 225.468 774 206.23 774 179.297Z"
fill="#0196D0"/>
<path d="M1558 179.568C1558 160.383 1550.42 144.268 1535.67 131.99C1521.32 119.968 1494.34 110.631 1454.74 103.981C1442.38 101.679 1432.01 99.3764 1422.84 97.8416C1422.44 97.8416 1422.04 97.8416 1422.04 97.4579V112.422L1361.04 75.2038L1422.04 38.3692V52.9496C1424.7 52.9496 1427.49 52.9496 1430.41 52.9496C1461.51 52.9496 1491.42 62.5419 1521.32 67.5299C1525.31 67.9136 1526.9 67.9136 1527.3 67.9136L1533.68 12.6619C1502.98 3.83692 1465.9 0 1434 0C1395.33 0 1365.43 6.52277 1345.09 19.5683C1323.16 32.6139 1312 57.9376 1312 82.8776C1312 103.981 1320.37 120.096 1336.72 131.607C1353.46 143.885 1382.97 153.093 1425.23 160.383C1434 161.535 1441.18 162.686 1447.56 164.22L1448.36 150.791L1507.36 190.312L1445.57 224.844L1445.96 212.949C1409.68 215.635 1357.45 209.112 1333.53 197.985L1320.37 247.482C1323.56 248.249 1329.54 248.633 1336.72 250.551C1395.33 259.376 1471.88 270.887 1524.11 238.657C1546.84 225.611 1558 205.659 1558 179.568Z"
fill="#0196D0"/>
</g>
<defs>
<clipPath id="clip0_0_3">
<rect width="1558" height="260" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,17 @@
#navbar {
display: flex;
flex-direction: row;
}
#navbar a {
color: #ffffff;
margin-right: 20px;
text-decoration: none;
transition: color 0.2s ease;
}
#navbar a:hover {
cursor: pointer;
color: #ffffff;
/ / #91a4d2;
}

View File

@@ -0,0 +1,956 @@
*, ::before, ::after {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
}
::backdrop {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
}
/*
! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com
*/
/*
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
*/
*,
::before,
::after {
box-sizing: border-box;
/* 1 */
border-width: 0;
/* 2 */
border-style: solid;
/* 2 */
border-color: #e5e7eb;
/* 2 */
}
::before,
::after {
--tw-content: '';
}
/*
1. Use a consistent sensible line-height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.
3. Use a more readable tab size.
4. Use the user's configured `sans` font-family by default.
5. Use the user's configured `sans` font-feature-settings by default.
6. Use the user's configured `sans` font-variation-settings by default.
7. Disable tap highlights on iOS
*/
html,
:host {
line-height: 1.5;
/* 1 */
-webkit-text-size-adjust: 100%;
/* 2 */
-moz-tab-size: 4;
/* 3 */
-o-tab-size: 4;
tab-size: 4;
/* 3 */
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
/* 4 */
font-feature-settings: normal;
/* 5 */
font-variation-settings: normal;
/* 6 */
-webkit-tap-highlight-color: transparent;
/* 7 */
}
/*
1. Remove the margin in all browsers.
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
*/
body {
margin: 0;
/* 1 */
line-height: inherit;
/* 2 */
}
/*
1. Add the correct height in Firefox.
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
3. Ensure horizontal rules are visible by default.
*/
hr {
height: 0;
/* 1 */
color: inherit;
/* 2 */
border-top-width: 1px;
/* 3 */
}
/*
Add the correct text decoration in Chrome, Edge, and Safari.
*/
abbr:where([title]) {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
}
/*
Remove the default font size and weight for headings.
*/
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: inherit;
font-weight: inherit;
}
/*
Reset links to optimize for opt-in styling instead of opt-out.
*/
a {
color: inherit;
text-decoration: inherit;
}
/*
Add the correct font weight in Edge and Safari.
*/
b,
strong {
font-weight: bolder;
}
/*
1. Use the user's configured `mono` font-family by default.
2. Use the user's configured `mono` font-feature-settings by default.
3. Use the user's configured `mono` font-variation-settings by default.
4. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp,
pre {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
/* 1 */
font-feature-settings: normal;
/* 2 */
font-variation-settings: normal;
/* 3 */
font-size: 1em;
/* 4 */
}
/*
Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/*
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/*
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
3. Remove gaps between table borders by default.
*/
table {
text-indent: 0;
/* 1 */
border-color: inherit;
/* 2 */
border-collapse: collapse;
/* 3 */
}
/*
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
3. Remove default padding in all browsers.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit;
/* 1 */
font-feature-settings: inherit;
/* 1 */
font-variation-settings: inherit;
/* 1 */
font-size: 100%;
/* 1 */
font-weight: inherit;
/* 1 */
line-height: inherit;
/* 1 */
letter-spacing: inherit;
/* 1 */
color: inherit;
/* 1 */
margin: 0;
/* 2 */
padding: 0;
/* 3 */
}
/*
Remove the inheritance of text transform in Edge and Firefox.
*/
button,
select {
text-transform: none;
}
/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Remove default button styles.
*/
button,
input:where([type='button']),
input:where([type='reset']),
input:where([type='submit']) {
-webkit-appearance: button;
/* 1 */
background-color: transparent;
/* 2 */
background-image: none;
/* 2 */
}
/*
Use the modern Firefox focus style for all focusable elements.
*/
:-moz-focusring {
outline: auto;
}
/*
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
*/
:-moz-ui-invalid {
box-shadow: none;
}
/*
Add the correct vertical alignment in Chrome and Firefox.
*/
progress {
vertical-align: baseline;
}
/*
Correct the cursor style of increment and decrement buttons in Safari.
*/
::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
height: auto;
}
/*
1. Correct the odd appearance in Chrome and Safari.
2. Correct the outline style in Safari.
*/
[type='search'] {
-webkit-appearance: textfield;
/* 1 */
outline-offset: -2px;
/* 2 */
}
/*
Remove the inner padding in Chrome and Safari on macOS.
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button;
/* 1 */
font: inherit;
/* 2 */
}
/*
Add the correct display in Chrome and Safari.
*/
summary {
display: list-item;
}
/*
Removes the default spacing and border for appropriate elements.
*/
blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
margin: 0;
}
fieldset {
margin: 0;
padding: 0;
}
legend {
padding: 0;
}
ol,
ul,
menu {
list-style: none;
margin: 0;
padding: 0;
}
/*
Reset default styling for dialogs.
*/
dialog {
padding: 0;
}
/*
Prevent resizing textareas horizontally by default.
*/
textarea {
resize: vertical;
}
/*
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
2. Set the default placeholder color to the user's configured gray 400 color.
*/
input::-moz-placeholder, textarea::-moz-placeholder {
opacity: 1;
/* 1 */
color: #9ca3af;
/* 2 */
}
input::placeholder,
textarea::placeholder {
opacity: 1;
/* 1 */
color: #9ca3af;
/* 2 */
}
/*
Set the default cursor for buttons.
*/
button,
[role="button"] {
cursor: pointer;
}
/*
Make sure disabled buttons don't get the pointer cursor.
*/
:disabled {
cursor: default;
}
/*
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
This can trigger a poorly considered lint error in some tools but is included by design.
*/
img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
display: block;
/* 1 */
vertical-align: middle;
/* 2 */
}
/*
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
*/
img,
video {
max-width: 100%;
height: auto;
}
/* Make elements with the HTML hidden attribute stay hidden by default */
[hidden]:where(:not([hidden="until-found"])) {
display: none;
}
.static {
position: static;
}
.absolute {
position: absolute;
}
.relative {
position: relative;
}
.right-2 {
right: 0.5rem;
}
.right-6 {
right: 1.5rem;
}
.top-1\/2 {
top: 50%;
}
.top-4 {
top: 1rem;
}
.z-10 {
z-index: 10;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.mb-4 {
margin-bottom: 1rem;
}
.mb-6 {
margin-bottom: 1.5rem;
}
.mb-8 {
margin-bottom: 2rem;
}
.ml-2 {
margin-left: 0.5rem;
}
.flex {
display: flex;
}
.hidden {
display: none;
}
.h-16 {
height: 4rem;
}
.h-24 {
height: 6rem;
}
.h-4 {
height: 1rem;
}
.h-5 {
height: 1.25rem;
}
.h-6 {
height: 1.5rem;
}
.min-h-screen {
min-height: 100vh;
}
.w-16 {
width: 4rem;
}
.w-20 {
width: 5rem;
}
.w-24 {
width: 6rem;
}
.w-4 {
width: 1rem;
}
.w-48 {
width: 12rem;
}
.w-5 {
width: 1.25rem;
}
.w-6 {
width: 1.5rem;
}
.w-full {
width: 100%;
}
.flex-1 {
flex: 1 1 0%;
}
.-translate-y-1\/2 {
--tw-translate-y: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.animate-spin {
animation: spin 1s linear infinite;
}
.flex-col {
flex-direction: column;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-x-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(1rem * var(--tw-space-x-reverse));
margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-x-8 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(2rem * var(--tw-space-x-reverse));
margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
}
.space-y-6 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
}
.rounded {
border-radius: 0.25rem;
}
.rounded-full {
border-radius: 9999px;
}
.rounded-lg {
border-radius: 0.5rem;
}
.rounded-md {
border-radius: 0.375rem;
}
.border {
border-width: 1px;
}
.border-b {
border-bottom-width: 1px;
}
.border-b-2 {
border-bottom-width: 2px;
}
.border-black {
--tw-border-opacity: 1;
border-color: rgb(0 0 0 / var(--tw-border-opacity, 1));
}
.border-gray-200 {
--tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity, 1));
}
.bg-\[\#111827\] {
--tw-bg-opacity: 1;
background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1));
}
.bg-gray-100 {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
}
.bg-gray-900 {
--tw-bg-opacity: 1;
background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1));
}
.bg-red-500 {
--tw-bg-opacity: 1;
background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
}
.bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
}
.p-2 {
padding: 0.5rem;
}
.p-4 {
padding: 1rem;
}
.p-8 {
padding: 2rem;
}
.px-1 {
padding-left: 0.25rem;
padding-right: 0.25rem;
}
.px-3 {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.py-0\.5 {
padding-top: 0.125rem;
padding-bottom: 0.125rem;
}
.py-2 {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
.py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
.py-6 {
padding-top: 1.5rem;
padding-bottom: 1.5rem;
}
.pr-10 {
padding-right: 2.5rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-base {
font-size: 1rem;
line-height: 1.5rem;
}
.text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
}
.font-medium {
font-weight: 500;
}
.font-semibold {
font-weight: 600;
}
.text-blue-500 {
--tw-text-opacity: 1;
color: rgb(59 130 246 / var(--tw-text-opacity, 1));
}
.text-blue-600 {
--tw-text-opacity: 1;
color: rgb(37 99 235 / var(--tw-text-opacity, 1));
}
.text-gray-400 {
--tw-text-opacity: 1;
color: rgb(156 163 175 / var(--tw-text-opacity, 1));
}
.text-gray-500 {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity, 1));
}
.text-gray-600 {
--tw-text-opacity: 1;
color: rgb(75 85 99 / var(--tw-text-opacity, 1));
}
.text-white {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.opacity-25 {
opacity: 0.25;
}
.opacity-75 {
opacity: 0.75;
}
.filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.hover\:bg-\[\#1f2937\]:hover {
--tw-bg-opacity: 1;
background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
}
.hover\:bg-gray-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
}
.hover\:bg-red-600:hover {
--tw-bg-opacity: 1;
background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
}
.hover\:text-gray-700:hover {
--tw-text-opacity: 1;
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
}
.hover\:text-gray-900:hover {
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity, 1));
}
.focus\:outline-none:focus {
outline: 2px solid transparent;
outline-offset: 2px;
}
.focus\:ring-2:focus {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.focus\:ring-blue-500:focus {
--tw-ring-opacity: 1;
--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1));
}

View File

@@ -0,0 +1 @@
rustfs bin path, do not delete

3
cli/rustfs-gui/input.css Normal file
View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -0,0 +1,315 @@
use crate::components::navbar::LoadingSpinner;
use crate::route::Route;
use crate::utils::{RustFSConfig, ServiceManager};
use chrono::Datelike;
use dioxus::logger::tracing::debug;
use dioxus::prelude::*;
use std::time::Duration;
const HEADER_LOGO: Asset = asset!("/assets/rustfs-logo.svg");
const TAILWIND_CSS: Asset = asset!("/assets/tailwind.css");
/// Define the state of the service
#[derive(PartialEq, Debug, Clone)]
enum ServiceState {
Start,
Stop,
}
/// Define the Home component
/// The Home component is the main component of the application
/// It is responsible for starting and stopping the service
/// It also displays the service status and provides a button to toggle the service
/// The Home component also displays the footer of the application
/// The footer contains links to the official site, documentation, GitHub, and license
/// The footer also displays the version of the application
/// The Home component also contains a button to change the theme of the application
/// The Home component also contains a button to go to the settings page
#[component]
pub fn Home() -> Element {
#[allow(clippy::redundant_closure)]
let service = use_signal(|| ServiceManager::new());
let conf = RustFSConfig::load().unwrap_or_else(|e| {
ServiceManager::show_error(&format!("加载配置失败:{}", e));
RustFSConfig::default()
});
debug!("loaded configurations:{:?}", conf);
let config = use_signal(|| conf.clone());
use dioxus_router::prelude::Link;
use document::{Meta, Stylesheet, Title};
let mut service_state = use_signal(|| ServiceState::Start);
// Create a periodic check on the effect of the service status
use_effect(move || {
spawn(async move {
loop {
if let Some(pid) = ServiceManager::check_service_status().await {
debug!("service_running true pid: {:?}", pid);
service_state.set(ServiceState::Stop);
} else {
debug!("service_running true pid: 0");
service_state.set(ServiceState::Start);
}
tokio::time::sleep(Duration::from_secs(2)).await;
}
});
});
debug!("project start service_state: {:?}", service_state.read());
// Use 'use_signal' to manage service status
let mut loading = use_signal(|| false);
let mut start_service = move |_| {
let service = service;
let config = config.read().clone();
let mut service_state = service_state;
// set the loading status
loading.set(true);
debug!("stop loading_state: {:?}", loading.read());
spawn(async move {
match service.read().start(config).await {
Ok(result) => {
if result.success {
let duration = result.end_time - result.start_time;
debug!("The service starts successfully and takes a long time:{}ms", duration.num_milliseconds());
service_state.set(ServiceState::Stop);
} else {
ServiceManager::show_error(&result.message);
service_state.set(ServiceState::Start);
}
}
Err(e) => {
ServiceManager::show_error(&format!("服务启动失败:{}", e));
}
}
// Only set loading to false when it's actually done
loading.set(false);
debug!("start loading_state: {:?}", loading.read());
});
};
let mut stop_service = move |_| {
let service = service;
let mut service_state = service_state;
// set the loading status
loading.set(true);
spawn(async move {
match service.read().stop().await {
Ok(result) => {
if result.success {
let duration = result.end_time - result.start_time;
debug!("The service stops successfully and takes a long time:{}ms", duration.num_milliseconds());
service_state.set(ServiceState::Start);
} else {
ServiceManager::show_error(&result.message);
}
}
Err(e) => {
ServiceManager::show_error(&format!("服务停止失败:{}", e));
}
}
debug!("service_state: {:?}", service_state.read());
// Only set loading to false when it's actually done
loading.set(false);
debug!("stop loading_state: {:?}", loading.read());
});
};
// Toggle the state when the button is clicked
let toggle_service = {
let mut service_state = service_state;
debug!("toggle_service service_state: {:?}", service_state.read());
move |_| {
if service_state.read().eq(&ServiceState::Stop) {
// If the service status is started, you need to run a command to stop the service
stop_service(());
service_state.set(ServiceState::Start);
} else {
start_service(());
service_state.set(ServiceState::Stop);
}
}
};
// Define dynamic styles based on state
let button_class = if service_state.read().eq(&ServiceState::Start) {
"bg-[#111827] hover:bg-[#1f2937] text-white px-4 py-2 rounded-md flex items-center space-x-2"
} else {
"bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md flex items-center space-x-2"
};
rsx! {
// The Stylesheet component inserts a style link into the head of the document
Stylesheet {href: TAILWIND_CSS,}
Title { "RustFS APP" }
Meta {
name: "description",
content: "RustFS RustFS 用热门安全的 Rust 语言开发,兼容 S3 协议。适用于 AI/ML 及海量数据存储、大数据、互联网、工业和保密存储等全部场景。近乎免费使用。遵循 Apache 2 协议,支持国产保密设备和系统。",
}
div { class: "min-h-screen flex flex-col items-center bg-white",
div { class: "absolute top-4 right-6 flex space-x-2",
// change theme
button { class: "p-2 hover:bg-gray-100 rounded-lg", ChangeThemeButton {} }
// setting button
Link {
class: "p-2 hover:bg-gray-100 rounded-lg",
to: Route::SettingViews {},
SettingButton {}
}
}
main { class: "flex-1 flex flex-col items-center justify-center space-y-6 p-4",
div { class: "w-24 h-24 bg-gray-900 rounded-full flex items-center justify-center",
img { alt: "Logo", class: "w-16 h-16", src: HEADER_LOGO }
}
div { class: "text-gray-600",
"Service is running on "
span { class: "text-blue-600", " 127.0.0.1:9000 " }
}
LoadingSpinner {
loading: loading.read().to_owned(),
text: "服务处理中...",
}
button { class: button_class, onclick: toggle_service,
svg {
class: "h-4 w-4",
fill: "none",
stroke: "currentColor",
view_box: "0 0 24 24",
xmlns: "http://www.w3.org/2000/svg",
if service_state.read().eq(&ServiceState::Start) {
path {
d: "M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z",
stroke_linecap: "round",
stroke_linejoin: "round",
stroke_width: "2",
}
path {
d: "M21 12a9 9 0 11-18 0 9 9 0 0118 0z",
stroke_linecap: "round",
stroke_linejoin: "round",
stroke_width: "2",
}
} else {
path {
stroke_linecap: "round",
stroke_linejoin: "round",
stroke_width: "2",
d: "M21 12a9 9 0 11-18 0 9 9 0 0118 0z",
}
path {
stroke_linecap: "round",
stroke_linejoin: "round",
stroke_width: "2",
d: "M9 10h6v4H9z",
}
}
}
span { id: "serviceStatus",
if service_state.read().eq(&ServiceState::Start) {
"Start service"
} else {
"Stop service"
}
}
}
}
Footer { version: "v1.0.0".to_string() }
}
}
}
#[component]
pub fn Footer(version: String) -> Element {
let now = chrono::Local::now();
let year = now.naive_local().year();
rsx! {
footer { class: "w-full py-6 flex flex-col items-center space-y-4 mb-6",
nav { class: "flex space-x-4 text-gray-600",
a { class: "hover:text-gray-900", href: "https://rustfs.com", "Official Site" }
a {
class: "hover:text-gray-900",
href: "https://rustfs.com/docs",
"Documentation"
}
a {
class: "hover:text-gray-900",
href: "https://github.com/rustfs/rustfs",
"GitHub"
}
a {
class: "hover:text-gray-900",
href: "https://rustfs.com/docs/license/",
"License"
}
a { class: "hover:text-gray-900", href: "#", "Sponsors" }
}
div { class: "text-gray-500 text-sm", " © rustfs.com {year}, All rights reserved." }
div { class: "text-gray-400 text-sm mb-8", " version {version} " }
}
}
}
#[component]
pub fn GoBackButtons() -> Element {
rsx! {
button {
class: "p-2 hover:bg-gray-100 rounded-lg",
"onclick": "window.history.back()",
"Back to the Past"
}
}
}
#[component]
pub fn GoForwardButtons() -> Element {
rsx! {
button {
class: "p-2 hover:bg-gray-100 rounded-lg",
"onclick": "window.history.forward()",
"Back to the Future"
}
}
}
#[component]
pub fn ChangeThemeButton() -> Element {
rsx! {
svg {
class: "h-6 w-6 text-gray-600",
fill: "none",
stroke: "currentColor",
view_box: "0 0 24 24",
xmlns: "http://www.w3.org/2000/svg",
path {
d: "M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z",
stroke_linecap: "round",
stroke_linejoin: "round",
stroke_width: "2",
}
}
}
}
#[component]
pub fn SettingButton() -> Element {
rsx! {
svg {
class: "h-6 w-6 text-gray-600",
fill: "none",
stroke: "currentColor",
view_box: "0 0 24 24",
xmlns: "http://www.w3.org/2000/svg",
path {
d: "M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z",
stroke_linecap: "round",
stroke_linejoin: "round",
stroke_width: "2",
}
path {
d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z",
stroke_linecap: "round",
stroke_linejoin: "round",
stroke_width: "2",
}
}
}
}

View File

@@ -0,0 +1,6 @@
mod home;
pub use home::Home;
mod navbar;
pub use navbar::Navbar;
mod setting;
pub use setting::Setting;

View File

@@ -0,0 +1,60 @@
use crate::route::Route;
use dioxus::logger::tracing::debug;
use dioxus::prelude::*;
const NAVBAR_CSS: Asset = asset!("/assets/styling/navbar.css");
#[component]
pub fn Navbar() -> Element {
rsx! {
document::Link { rel: "stylesheet", href: NAVBAR_CSS }
div { id: "navbar", class: "hidden", style: "display: none;",
Link { to: Route::HomeViews {}, "Home" }
Link { to: Route::SettingViews {}, "Setting" }
}
Outlet::<Route> {}
}
}
#[derive(Props, PartialEq, Debug, Clone)]
pub struct LoadingSpinnerProps {
#[props(default = true)]
loading: bool,
#[props(default = "正在处理中...")]
text: &'static str,
}
#[component]
pub fn LoadingSpinner(props: LoadingSpinnerProps) -> Element {
debug!("loading: {}", props.loading);
if !props.loading {
debug!("LoadingSpinner false loading: {}", props.loading);
return rsx! {};
}
rsx! {
div { class: "flex items-center justify-center z-10",
svg {
class: "animate-spin h-5 w-5 text-blue-500",
xmlns: "http://www.w3.org/2000/svg",
fill: "none",
view_box: "0 0 24 24",
circle {
class: "opacity-25",
cx: "12",
cy: "12",
r: "10",
stroke: "currentColor",
stroke_width: "4",
}
path {
class: "opacity-75",
fill: "currentColor",
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z",
}
}
span { class: "ml-2 text-gray-600", "{props.text}" }
}
}
}

View File

@@ -0,0 +1,202 @@
use crate::components::navbar::LoadingSpinner;
use dioxus::logger::tracing::{debug, error};
use dioxus::prelude::*;
const SETTINGS_JS: Asset = asset!("/assets/js/sts.js");
const TAILWIND_CSS: Asset = asset!("/assets/tailwind.css");
#[component]
pub fn Setting() -> Element {
use crate::utils::{RustFSConfig, ServiceManager};
use document::{Meta, Script, Stylesheet, Title};
#[allow(clippy::redundant_closure)]
let service = use_signal(|| ServiceManager::new());
let conf = RustFSConfig::load().unwrap_or_else(|e| {
error!("load config error: {}", e);
RustFSConfig::default_config()
});
debug!("conf address: {:?}", conf.clone().address);
let config = use_signal(|| conf.clone());
let address_state = use_signal(|| conf.address.to_string());
let mut host_state = use_signal(|| conf.host.to_string());
let mut port_state = use_signal(|| conf.port.to_string());
let mut access_key_state = use_signal(|| conf.access_key.to_string());
let mut secret_key_state = use_signal(|| conf.secret_key.to_string());
let mut volume_name_state = use_signal(|| conf.volume_name.to_string());
let loading = use_signal(|| false);
let save_and_restart = {
let host_state = host_state;
let port_state = port_state;
let access_key_state = access_key_state;
let secret_key_state = secret_key_state;
let volume_name_state = volume_name_state;
let mut loading = loading;
debug!("save_and_restart access_key:{}", access_key_state.read());
move |_| {
// set the loading status
loading.set(true);
let mut config = config;
config.write().address = format!("{}:{}", host_state.read(), port_state.read());
config.write().host = host_state.read().to_string();
config.write().port = port_state.read().to_string();
config.write().access_key = access_key_state.read().to_string();
config.write().secret_key = secret_key_state.read().to_string();
config.write().volume_name = volume_name_state.read().to_string();
// restart service
let service = service;
let config = config.read().clone();
spawn(async move {
if let Err(e) = service.read().restart(config).await {
ServiceManager::show_error(&format!("发送重启命令失败:{}", e));
}
// reset the status when you're done
loading.set(false);
});
}
};
rsx! {
Title { "Settings - RustFS App" }
Meta { name: "description", content: "Settings - RustFS App." }
// The Stylesheet component inserts a style link into the head of the document
Stylesheet { href: TAILWIND_CSS }
Script { src: SETTINGS_JS }
div { class: "bg-white p-8",
h1 { class: "text-2xl font-semibold mb-6", "Settings" }
div { class: "border-b border-gray-200 mb-6",
nav { class: "flex space-x-8",
button {
class: "tab-btn px-1 py-4 text-sm font-medium border-b-2 border-black",
"data-tab": "service",
"onclick": "switchTab('service')",
"Service "
}
button {
class: "tab-btn px-1 py-4 text-sm font-medium text-gray-500 hover:text-gray-700",
"data-tab": "user",
"onclick": "switchTab('user')",
"User "
}
button {
class: "tab-btn px-1 py-4 text-sm font-medium text-gray-500 hover:text-gray-700 hidden",
"data-tab": "logs",
"onclick": "switchTab('logs')",
"Logs "
}
}
}
div { id: "tabContent",
div { class: "tab-content", id: "service",
div { class: "mb-8",
h2 { class: "text-base font-medium mb-2", "Service address" }
p { class: "text-gray-600 mb-4",
" The service address is the IP address and port number of the service. the default address is "
code { class: "bg-gray-100 px-1 py-0.5 rounded", {address_state} }
". "
}
div { class: "flex space-x-2",
input {
class: "border rounded px-3 py-2 w-48 focus:outline-none focus:ring-2 focus:ring-blue-500",
r#type: "text",
value: host_state,
oninput: move |evt| host_state.set(evt.value().clone()),
}
span { class: "flex items-center", ":" }
input {
class: "border rounded px-3 py-2 w-20 focus:outline-none focus:ring-2 focus:ring-blue-500",
r#type: "text",
value: port_state,
oninput: move |evt| port_state.set(evt.value().clone()),
}
}
}
div { class: "mb-8",
h2 { class: "text-base font-medium mb-2", "Storage path" }
p { class: "text-gray-600 mb-4",
"Update the storage path of the service. the default path is {volume_name_state}."
}
input {
class: "border rounded px-3 py-2 w-full focus:outline-none focus:ring-2 focus:ring-blue-500",
r#type: "text",
value: volume_name_state,
oninput: move |evt| volume_name_state.set(evt.value().clone()),
}
}
}
div { class: "tab-content hidden", id: "user",
div { class: "mb-8",
h2 { class: "text-base font-medium mb-2", "User" }
p { class: "text-gray-600 mb-4",
"The user is the owner of the service. the default user is "
code { class: "bg-gray-100 px-1 py-0.5 rounded", {access_key_state} }
}
input {
class: "border rounded px-3 py-2 w-full focus:outline-none focus:ring-2 focus:ring-blue-500",
r#type: "text",
value: access_key_state,
oninput: move |evt| access_key_state.set(evt.value().clone()),
}
}
div { class: "mb-8",
h2 { class: "text-base font-medium mb-2", "Password" }
p { class: "text-gray-600 mb-4",
"The password is the password of the user. the default password is "
code { class: "bg-gray-100 px-1 py-0.5 rounded", {secret_key_state} }
}
div { class: "relative",
input {
class: "border rounded px-3 py-2 w-full pr-10 focus:outline-none focus:ring-2 focus:ring-blue-500",
r#type: "password",
value: secret_key_state,
oninput: move |evt| secret_key_state.set(evt.value().clone()),
}
button {
class: "absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-500 hover:text-gray-700",
"onclick": "togglePassword(this)",
svg {
class: "h-5 w-5",
fill: "currentColor",
view_box: "0 0 20 20",
xmlns: "http://www.w3.org/2000/svg",
path { d: "M10 12a2 2 0 100-4 2 2 0 000 4z" }
path {
clip_rule: "evenodd",
d: "M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z",
fill_rule: "evenodd",
}
}
}
}
}
}
div { class: "tab-content hidden", id: "logs",
div { class: "mb-8",
h2 { class: "text-base font-medium mb-2", "Logs storage path" }
p { class: "text-gray-600 mb-4",
"The logs storage path is the path where the logs are stored. the default path is /var/log/rustfs. "
}
input {
class: "border rounded px-3 py-2 w-full focus:outline-none focus:ring-2 focus:ring-blue-500",
r#type: "text",
value: "/var/logs/rustfs",
}
}
}
}
div { class: "flex space-x-4",
button {
class: "bg-[#111827] text-white px-4 py-2 rounded hover:bg-[#1f2937]",
onclick: save_and_restart,
" Save and restart "
}
GoBackButton { "Back" }
}
LoadingSpinner {
loading: loading.read().to_owned(),
text: "服务处理中...",
}
}
}
}

View File

@@ -0,0 +1,9 @@
mod components;
mod route;
mod utils;
mod views;
fn main() {
let _worker_guard = utils::init_logger();
dioxus::launch(views::App);
}

View File

@@ -0,0 +1,3 @@
mod router;
pub use router::Route;

View File

@@ -0,0 +1,14 @@
use crate::components::Navbar;
use crate::views::{HomeViews, SettingViews};
use dioxus::prelude::*;
/// The router for the application
#[derive(Debug, Clone, Routable, PartialEq)]
#[rustfmt::skip]
pub enum Route {
#[layout(Navbar)]
#[route("/")]
HomeViews {},
#[route("/settings")]
SettingViews {},
}

View File

@@ -0,0 +1,550 @@
use keyring::Entry;
use serde::{Deserialize, Serialize};
use std::error::Error;
/// Configuration for the RustFS service
///
/// # Fields
/// * `address` - The address of the RustFS service
/// * `host` - The host of the RustFS service
/// * `port` - The port of the RustFS service
/// * `access_key` - The access key of the RustFS service
/// * `secret_key` - The secret key of the RustFS service
/// * `domain_name` - The domain name of the RustFS service
/// * `volume_name` - The volume name of the RustFS service
/// * `console_address` - The console address of the RustFS service
///
/// # Example
/// ```
/// let config = RustFSConfig {
/// address: "127.0.0.1:9000".to_string(),
/// host: "127.0.0.1".to_string(),
/// port: "9000".to_string(),
/// access_key: "rustfsadmin".to_string(),
/// secret_key: "rustfsadmin".to_string(),
/// domain_name: "demo.rustfs.com".to_string(),
/// volume_name: "data".to_string(),
/// console_address: "127.0.0.1:9001".to_string(),
/// };
/// println!("{:?}", config);
/// assert_eq!(config.address, "127.0.0.1:9000");
/// ```
#[derive(Debug, Clone, Default, Deserialize, Serialize, Ord, PartialOrd, Eq, PartialEq)]
pub struct RustFSConfig {
pub address: String,
pub host: String,
pub port: String,
pub access_key: String,
pub secret_key: String,
pub domain_name: String,
pub volume_name: String,
pub console_address: String,
}
impl RustFSConfig {
/// keyring the name of the service
const SERVICE_NAME: &'static str = "rustfs-service";
/// keyring the key of the service
const SERVICE_KEY: &'static str = "rustfs_key";
/// default domain name
const DEFAULT_DOMAIN_NAME_VALUE: &'static str = "demo.rustfs.com";
/// default address value
const DEFAULT_ADDRESS_VALUE: &'static str = "127.0.0.1:9000";
/// default port value
const DEFAULT_PORT_VALUE: &'static str = "9000";
/// default host value
const DEFAULT_HOST_VALUE: &'static str = "127.0.0.1";
/// default access key value
const DEFAULT_ACCESS_KEY_VALUE: &'static str = "rustfsadmin";
/// default secret key value
const DEFAULT_SECRET_KEY_VALUE: &'static str = "rustfsadmin";
/// default console address value
const DEFAULT_CONSOLE_ADDRESS_VALUE: &'static str = "127.0.0.1:9001";
/// get the default volume_name
///
/// # Returns
/// * The default volume name
///
/// # Example
/// ```
/// let volume_name = RustFSConfig::default_volume_name();
/// ```
pub fn default_volume_name() -> String {
dirs::home_dir()
.map(|home| home.join("rustfs").join("data"))
.and_then(|path| path.to_str().map(String::from))
.unwrap_or_else(|| "data".to_string())
}
/// create a default configuration
///
/// # Returns
/// * The default configuration
///
/// # Example
/// ```
/// let config = RustFSConfig::default_config();
/// println!("{:?}", config);
/// assert_eq!(config.address, "127.0.0.1:9000");
/// ```
pub fn default_config() -> Self {
Self {
address: Self::DEFAULT_ADDRESS_VALUE.to_string(),
host: Self::DEFAULT_HOST_VALUE.to_string(),
port: Self::DEFAULT_PORT_VALUE.to_string(),
access_key: Self::DEFAULT_ACCESS_KEY_VALUE.to_string(),
secret_key: Self::DEFAULT_SECRET_KEY_VALUE.to_string(),
domain_name: Self::DEFAULT_DOMAIN_NAME_VALUE.to_string(),
volume_name: Self::default_volume_name(),
console_address: Self::DEFAULT_CONSOLE_ADDRESS_VALUE.to_string(),
}
}
/// Load the configuration from the keyring
///
/// # Errors
/// * If the configuration cannot be loaded from the keyring
/// * If the configuration cannot be deserialized
/// * If the address cannot be extracted from the configuration
///
/// # Example
/// ```
/// let config = RustFSConfig::load().unwrap();
/// println!("{:?}", config);
/// assert_eq!(config.address, "127.0.0.1:9000");
/// ```
pub fn load() -> Result<Self, Box<dyn Error>> {
let mut config = Self::default_config();
// Try to get the configuration of the storage from the keyring
let entry = Entry::new(Self::SERVICE_NAME, Self::SERVICE_KEY)?;
if let Ok(stored_json) = entry.get_password() {
if let Ok(stored_config) = serde_json::from_str::<RustFSConfig>(&stored_json) {
// update fields that are not empty and non default
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))?;
config.host = host.to_string();
config.port = port.to_string();
}
if !stored_config.access_key.is_empty() && stored_config.access_key != Self::DEFAULT_ACCESS_KEY_VALUE {
config.access_key = stored_config.access_key;
}
if !stored_config.secret_key.is_empty() && stored_config.secret_key != Self::DEFAULT_SECRET_KEY_VALUE {
config.secret_key = stored_config.secret_key;
}
if !stored_config.domain_name.is_empty() && stored_config.domain_name != Self::DEFAULT_DOMAIN_NAME_VALUE {
config.domain_name = stored_config.domain_name;
}
// The stored volume_name is updated only if it is not empty and different from the default
if !stored_config.volume_name.is_empty() && stored_config.volume_name != Self::default_volume_name() {
config.volume_name = stored_config.volume_name;
}
if !stored_config.console_address.is_empty()
&& stored_config.console_address != Self::DEFAULT_CONSOLE_ADDRESS_VALUE
{
config.console_address = stored_config.console_address;
}
}
}
Ok(config)
}
/// Auxiliary method: Extract the host and port from the address string
/// # Arguments
/// * `address` - The address string
///
/// # Returns
/// * `Some((host, port))` - The host and port
///
/// # Errors
/// * If the address is not in the form 'host:port'
/// * If the port is not a valid u16
///
/// # Example
/// ```
/// let (host, port) = RustFSConfig::extract_host_port("127.0.0.1:9000").unwrap();
/// assert_eq!(host, "127.0.0.1");
/// assert_eq!(port, 9000);
/// ```
pub fn extract_host_port(address: &str) -> Option<(&str, u16)> {
let parts: Vec<&str> = address.split(':').collect();
if parts.len() == 2 {
if let Ok(port) = parts[1].parse::<u16>() {
return Some((parts[0], port));
}
}
None
}
/// save the configuration to keyring
///
/// # Errors
/// * If the configuration cannot be serialized
/// * If the configuration cannot be saved to the keyring
///
/// # Example
/// ```
/// let config = RustFSConfig::default_config();
/// config.save().unwrap();
/// ```
pub fn save(&self) -> Result<(), Box<dyn Error>> {
let entry = Entry::new(Self::SERVICE_NAME, Self::SERVICE_KEY)?;
let json = serde_json::to_string(self)?;
entry.set_password(&json)?;
Ok(())
}
/// Clear the stored configuration from the system keyring
///
/// # Returns
/// Returns `Ok(())` if the configuration was successfully cleared, or an error if the operation failed.
///
/// # Example
/// ```
/// RustFSConfig::clear().unwrap();
/// ```
#[allow(dead_code)]
pub fn clear() -> Result<(), Box<dyn Error>> {
let entry = Entry::new(Self::SERVICE_NAME, Self::SERVICE_KEY)?;
entry.delete_credential()?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rustfs_config_default() {
let config = RustFSConfig::default();
assert!(config.address.is_empty());
assert!(config.host.is_empty());
assert!(config.port.is_empty());
assert!(config.access_key.is_empty());
assert!(config.secret_key.is_empty());
assert!(config.domain_name.is_empty());
assert!(config.volume_name.is_empty());
assert!(config.console_address.is_empty());
}
#[test]
fn test_rustfs_config_creation() {
let config = RustFSConfig {
address: "192.168.1.100:9000".to_string(),
host: "192.168.1.100".to_string(),
port: "9000".to_string(),
access_key: "testuser".to_string(),
secret_key: "testpass".to_string(),
domain_name: "test.rustfs.com".to_string(),
volume_name: "/data/rustfs".to_string(),
console_address: "192.168.1.100:9001".to_string(),
};
assert_eq!(config.address, "192.168.1.100:9000");
assert_eq!(config.host, "192.168.1.100");
assert_eq!(config.port, "9000");
assert_eq!(config.access_key, "testuser");
assert_eq!(config.secret_key, "testpass");
assert_eq!(config.domain_name, "test.rustfs.com");
assert_eq!(config.volume_name, "/data/rustfs");
assert_eq!(config.console_address, "192.168.1.100:9001");
}
#[test]
fn test_default_volume_name() {
let volume_name = RustFSConfig::default_volume_name();
assert!(!volume_name.is_empty());
// Should either be the home directory path or fallback to "data"
assert!(volume_name.contains("rustfs") || volume_name == "data");
}
#[test]
fn test_default_config() {
let config = RustFSConfig::default_config();
assert_eq!(config.address, RustFSConfig::DEFAULT_ADDRESS_VALUE);
assert_eq!(config.host, RustFSConfig::DEFAULT_HOST_VALUE);
assert_eq!(config.port, RustFSConfig::DEFAULT_PORT_VALUE);
assert_eq!(config.access_key, RustFSConfig::DEFAULT_ACCESS_KEY_VALUE);
assert_eq!(config.secret_key, RustFSConfig::DEFAULT_SECRET_KEY_VALUE);
assert_eq!(config.domain_name, RustFSConfig::DEFAULT_DOMAIN_NAME_VALUE);
assert_eq!(config.console_address, RustFSConfig::DEFAULT_CONSOLE_ADDRESS_VALUE);
assert!(!config.volume_name.is_empty());
}
#[test]
fn test_extract_host_port_valid() {
let test_cases = vec![
("127.0.0.1:9000", Some(("127.0.0.1", 9000))),
("localhost:8080", Some(("localhost", 8080))),
("192.168.1.100:3000", Some(("192.168.1.100", 3000))),
("0.0.0.0:80", Some(("0.0.0.0", 80))),
("example.com:443", Some(("example.com", 443))),
];
for (input, expected) in test_cases {
let result = RustFSConfig::extract_host_port(input);
assert_eq!(result, expected, "Failed for input: {}", input);
}
}
#[test]
fn test_extract_host_port_invalid() {
let invalid_cases = vec![
"127.0.0.1", // Missing port
"127.0.0.1:", // Empty port
"127.0.0.1:abc", // Invalid port
"127.0.0.1:99999", // Port out of range
"", // Empty string
"127.0.0.1:9000:extra", // Too many parts
"invalid", // No colon
];
for input in invalid_cases {
let result = RustFSConfig::extract_host_port(input);
assert_eq!(result, None, "Should be None for input: {}", input);
}
// Special case: empty host but valid port should still work
let result = RustFSConfig::extract_host_port(":9000");
assert_eq!(result, Some(("", 9000)));
}
#[test]
fn test_extract_host_port_edge_cases() {
// Test edge cases for port numbers
assert_eq!(RustFSConfig::extract_host_port("host:0"), Some(("host", 0)));
assert_eq!(RustFSConfig::extract_host_port("host:65535"), Some(("host", 65535)));
assert_eq!(RustFSConfig::extract_host_port("host:65536"), None); // Out of range
}
#[test]
fn test_serialization() {
let config = RustFSConfig {
address: "127.0.0.1:9000".to_string(),
host: "127.0.0.1".to_string(),
port: "9000".to_string(),
access_key: "admin".to_string(),
secret_key: "password".to_string(),
domain_name: "test.com".to_string(),
volume_name: "/data".to_string(),
console_address: "127.0.0.1:9001".to_string(),
};
let json = serde_json::to_string(&config).unwrap();
assert!(json.contains("127.0.0.1:9000"));
assert!(json.contains("admin"));
assert!(json.contains("test.com"));
}
#[test]
fn test_deserialization() {
let json = r#"{
"address": "192.168.1.100:9000",
"host": "192.168.1.100",
"port": "9000",
"access_key": "testuser",
"secret_key": "testpass",
"domain_name": "example.com",
"volume_name": "/opt/data",
"console_address": "192.168.1.100:9001"
}"#;
let config: RustFSConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.address, "192.168.1.100:9000");
assert_eq!(config.host, "192.168.1.100");
assert_eq!(config.port, "9000");
assert_eq!(config.access_key, "testuser");
assert_eq!(config.secret_key, "testpass");
assert_eq!(config.domain_name, "example.com");
assert_eq!(config.volume_name, "/opt/data");
assert_eq!(config.console_address, "192.168.1.100:9001");
}
#[test]
fn test_serialization_deserialization_roundtrip() {
let original_config = RustFSConfig {
address: "10.0.0.1:8080".to_string(),
host: "10.0.0.1".to_string(),
port: "8080".to_string(),
access_key: "roundtrip_user".to_string(),
secret_key: "roundtrip_pass".to_string(),
domain_name: "roundtrip.test".to_string(),
volume_name: "/tmp/roundtrip".to_string(),
console_address: "10.0.0.1:8081".to_string(),
};
let json = serde_json::to_string(&original_config).unwrap();
let deserialized_config: RustFSConfig = serde_json::from_str(&json).unwrap();
assert_eq!(original_config, deserialized_config);
}
#[test]
fn test_config_ordering() {
let config1 = RustFSConfig {
address: "127.0.0.1:9000".to_string(),
host: "127.0.0.1".to_string(),
port: "9000".to_string(),
access_key: "admin".to_string(),
secret_key: "password".to_string(),
domain_name: "test.com".to_string(),
volume_name: "/data".to_string(),
console_address: "127.0.0.1:9001".to_string(),
};
let config2 = RustFSConfig {
address: "127.0.0.1:9000".to_string(),
host: "127.0.0.1".to_string(),
port: "9000".to_string(),
access_key: "admin".to_string(),
secret_key: "password".to_string(),
domain_name: "test.com".to_string(),
volume_name: "/data".to_string(),
console_address: "127.0.0.1:9001".to_string(),
};
let config3 = RustFSConfig {
address: "127.0.0.1:9001".to_string(), // Different port
host: "127.0.0.1".to_string(),
port: "9001".to_string(),
access_key: "admin".to_string(),
secret_key: "password".to_string(),
domain_name: "test.com".to_string(),
volume_name: "/data".to_string(),
console_address: "127.0.0.1:9002".to_string(),
};
assert_eq!(config1, config2);
assert_ne!(config1, config3);
assert!(config1 < config3); // Lexicographic ordering
}
#[test]
fn test_clone() {
let original = RustFSConfig::default_config();
let cloned = original.clone();
assert_eq!(original, cloned);
assert_eq!(original.address, cloned.address);
assert_eq!(original.access_key, cloned.access_key);
}
#[test]
fn test_debug_format() {
let config = RustFSConfig::default_config();
let debug_str = format!("{:?}", config);
assert!(debug_str.contains("RustFSConfig"));
assert!(debug_str.contains("address"));
assert!(debug_str.contains("127.0.0.1:9000"));
}
#[test]
fn test_constants() {
assert_eq!(RustFSConfig::SERVICE_NAME, "rustfs-service");
assert_eq!(RustFSConfig::SERVICE_KEY, "rustfs_key");
assert_eq!(RustFSConfig::DEFAULT_DOMAIN_NAME_VALUE, "demo.rustfs.com");
assert_eq!(RustFSConfig::DEFAULT_ADDRESS_VALUE, "127.0.0.1:9000");
assert_eq!(RustFSConfig::DEFAULT_PORT_VALUE, "9000");
assert_eq!(RustFSConfig::DEFAULT_HOST_VALUE, "127.0.0.1");
assert_eq!(RustFSConfig::DEFAULT_ACCESS_KEY_VALUE, "rustfsadmin");
assert_eq!(RustFSConfig::DEFAULT_SECRET_KEY_VALUE, "rustfsadmin");
assert_eq!(RustFSConfig::DEFAULT_CONSOLE_ADDRESS_VALUE, "127.0.0.1:9001");
}
#[test]
fn test_empty_strings() {
let config = RustFSConfig {
address: "".to_string(),
host: "".to_string(),
port: "".to_string(),
access_key: "".to_string(),
secret_key: "".to_string(),
domain_name: "".to_string(),
volume_name: "".to_string(),
console_address: "".to_string(),
};
assert!(config.address.is_empty());
assert!(config.host.is_empty());
assert!(config.port.is_empty());
assert!(config.access_key.is_empty());
assert!(config.secret_key.is_empty());
assert!(config.domain_name.is_empty());
assert!(config.volume_name.is_empty());
assert!(config.console_address.is_empty());
}
#[test]
fn test_very_long_strings() {
let long_string = "a".repeat(1000);
let config = RustFSConfig {
address: format!("{}:9000", long_string),
host: long_string.clone(),
port: "9000".to_string(),
access_key: long_string.clone(),
secret_key: long_string.clone(),
domain_name: format!("{}.com", long_string),
volume_name: format!("/data/{}", long_string),
console_address: format!("{}:9001", long_string),
};
assert_eq!(config.host.len(), 1000);
assert_eq!(config.access_key.len(), 1000);
assert_eq!(config.secret_key.len(), 1000);
}
#[test]
fn test_special_characters() {
let config = RustFSConfig {
address: "127.0.0.1:9000".to_string(),
host: "127.0.0.1".to_string(),
port: "9000".to_string(),
access_key: "user@domain.com".to_string(),
secret_key: "p@ssw0rd!#$%".to_string(),
domain_name: "test-domain.example.com".to_string(),
volume_name: "/data/rust-fs/storage".to_string(),
console_address: "127.0.0.1:9001".to_string(),
};
assert!(config.access_key.contains("@"));
assert!(config.secret_key.contains("!#$%"));
assert!(config.domain_name.contains("-"));
assert!(config.volume_name.contains("/"));
}
#[test]
fn test_unicode_strings() {
let config = RustFSConfig {
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(),
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, "/数据/存储");
}
#[test]
fn test_memory_efficiency() {
// Test that the structure doesn't use excessive memory
assert!(std::mem::size_of::<RustFSConfig>() < 1000);
}
// Note: Keyring-related tests (load, save, clear) are not included here
// because they require actual keyring access and would be integration tests
// rather than unit tests. They should be tested separately in an integration
// test environment where keyring access can be properly mocked or controlled.
}

View File

@@ -0,0 +1,887 @@
use crate::utils::RustFSConfig;
use dioxus::logger::tracing::{debug, error, info};
use lazy_static::lazy_static;
use rust_embed::RustEmbed;
use sha2::{Digest, Sha256};
use std::error::Error;
use std::path::{Path, PathBuf};
use std::process::Command as StdCommand;
use std::time::Duration;
use tokio::fs;
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
use tokio::net::TcpStream;
use tokio::sync::{mpsc, Mutex};
#[derive(RustEmbed)]
#[folder = "$CARGO_MANIFEST_DIR/embedded-rustfs/"]
struct Asset;
// Use `lazy_static` to cache the checksum of embedded resources
lazy_static! {
static ref RUSTFS_HASH: Mutex<String> = {
let rustfs_file = if cfg!(windows) { "rustfs.exe" } else { "rustfs" };
let rustfs_data = Asset::get(rustfs_file).expect("RustFs binary not embedded");
let hash = hex::encode(Sha256::digest(&rustfs_data.data));
Mutex::new(hash)
};
}
/// Service command
/// This enum represents the commands that can be sent to the service manager
/// to start, stop, or restart the service
/// The `Start` variant contains the configuration for the service
/// The `Restart` variant contains the configuration for the service
///
/// # Example
/// ```
/// let config = RustFSConfig {
/// address: "127.0.0.1:9000".to_string(),
/// host: "127.0.0.1".to_string(),
/// port: "9000".to_string(),
/// access_key: "rustfsadmin".to_string(),
/// secret_key: "rustfsadmin".to_string(),
/// domain_name: "demo.rustfs.com".to_string(),
/// volume_name: "data".to_string(),
/// console_address: "127.0.0.1:9001".to_string(),
/// };
///
/// let command = ServiceCommand::Start(config);
/// println!("{:?}", command);
///
/// assert_eq!(command, ServiceCommand::Start(config));
/// ```
pub enum ServiceCommand {
Start(RustFSConfig),
Stop,
Restart(RustFSConfig),
}
/// Service operation result
/// This struct represents the result of a service operation
/// It contains information about the success of the operation,
///
/// # Example
/// ```
/// use chrono::Local;
///
/// let result = ServiceOperationResult {
/// success: true,
/// start_time: chrono::Local::now(),
/// end_time: chrono::Local::now(),
/// message: "服务启动成功".to_string(),
/// };
///
/// println!("{:?}", result);
/// assert_eq!(result.success, true);
/// ```
#[derive(Debug)]
pub struct ServiceOperationResult {
pub success: bool,
pub start_time: chrono::DateTime<chrono::Local>,
pub end_time: chrono::DateTime<chrono::Local>,
pub message: String,
}
/// Service manager
/// This struct represents a service manager that can be used to start, stop, or restart a service
/// It contains a command sender that can be used to send commands to the service manager
///
/// # Example
/// ```
/// let service_manager = ServiceManager::new();
/// println!("{:?}", service_manager);
/// ```
#[derive(Debug, Clone)]
pub struct ServiceManager {
command_tx: mpsc::Sender<ServiceCommand>,
// process: Arc<Mutex<Option<Child>>>,
// pid: Arc<Mutex<Option<u32>>>, // Add PID storage
// current_config: Arc<Mutex<Option<RustFSConfig>>>, // Add configuration storage
}
impl ServiceManager {
/// check if the service is running and return a pid
/// This function is platform dependent
/// On Unix systems, it uses the `ps` command to check for the service
/// On Windows systems, it uses the `wmic` command to check for the service
///
/// # Example
/// ```
/// let pid = check_service_status().await;
/// println!("{:?}", pid);
/// ```
pub async fn check_service_status() -> Option<u32> {
#[cfg(unix)]
{
// use the ps command on a unix system
if let Ok(output) = StdCommand::new("ps").arg("-ef").output() {
let output_str = String::from_utf8_lossy(&output.stdout);
for line in output_str.lines() {
// match contains `rustfs/bin/rustfs` of the line
if line.contains("rustfs/bin/rustfs") && !line.contains("grep") {
if let Some(pid_str) = line.split_whitespace().nth(1) {
if let Ok(pid) = pid_str.parse::<u32>() {
return Some(pid);
}
}
}
}
}
}
#[cfg(windows)]
{
if let Ok(output) = StdCommand::new("wmic")
.arg("process")
.arg("where")
.arg("caption='rustfs.exe'")
.arg("get")
.arg("processid")
.output()
{
let output_str = String::from_utf8_lossy(&output.stdout);
for line in output_str.lines() {
if let Ok(pid) = line.trim().parse::<u32>() {
return Some(pid);
}
}
}
}
None
}
/// Prepare the service
/// This function downloads the service executable if it doesn't exist
/// It also creates the necessary directories for the service
///
/// # Example
/// ```
/// let executable_path = prepare_service().await;
/// println!("{:?}", executable_path);
/// ```
async fn prepare_service() -> Result<PathBuf, Box<dyn Error>> {
// get the user directory
let home_dir = dirs::home_dir().ok_or("无法获取用户目录")?;
let rustfs_dir = home_dir.join("rustfs");
let bin_dir = rustfs_dir.join("bin");
let data_dir = rustfs_dir.join("data");
let logs_dir = rustfs_dir.join("logs");
// create the necessary directories
for dir in [&bin_dir, &data_dir, &logs_dir] {
if !dir.exists() {
tokio::fs::create_dir_all(dir).await?;
}
}
let rustfs_file = if cfg!(windows) { "rustfs.exe" } else { "rustfs" };
let executable_path = bin_dir.join(rustfs_file);
let hash_path = bin_dir.join("embedded_rustfs.sha256");
if executable_path.exists() && hash_path.exists() {
let cached_hash = fs::read_to_string(&hash_path).await?;
let expected_hash = RUSTFS_HASH.lock().await;
if cached_hash == *expected_hash {
println!("Use cached rustfs: {:?}", executable_path);
return Ok(executable_path);
}
}
// Extract and write files
let rustfs_data = Asset::get(rustfs_file).expect("RustFS binary not embedded");
let mut file = File::create(&executable_path).await?;
file.write_all(&rustfs_data.data).await?;
let expected_hash = hex::encode(Sha256::digest(&rustfs_data.data));
fs::write(&hash_path, expected_hash).await?;
// set execution permissions on unix systems
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mut perms = std::fs::metadata(&executable_path)?.permissions();
perms.set_mode(0o755);
std::fs::set_permissions(&executable_path, perms)?;
}
Ok(executable_path)
}
/// Helper function: Extracts the port from the address string
///
/// # Example
/// ```
/// let address = "127.0.0.1:9000";
/// let port = extract_port(address);
/// println!("{:?}", port);
/// ```
fn extract_port(address: &str) -> Option<u16> {
address.split(':').nth(1)?.parse().ok()
}
/// Create a new instance of the service manager
///
/// # Example
/// ```
/// let service_manager = ServiceManager::new();
/// println!("{:?}", service_manager);
/// ```
pub(crate) fn new() -> Self {
let (command_tx, mut command_rx) = mpsc::channel(10);
// Start the control loop
tokio::spawn(async move {
while let Some(cmd) = command_rx.recv().await {
match cmd {
ServiceCommand::Start(config) => {
if let Err(e) = Self::start_service(&config).await {
Self::show_error(&format!("启动服务失败:{}", e));
}
}
ServiceCommand::Stop => {
if let Err(e) = Self::stop_service().await {
Self::show_error(&format!("停止服务失败:{}", 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));
continue;
}
}
if let Err(e) = Self::start_service(&config).await {
Self::show_error(&format!("重启服务失败:{}", e));
}
}
}
}
});
ServiceManager { command_tx }
}
/// Start the service
/// This function starts the service with the given configuration
///
/// # Example
/// ```
/// let config = RustFSConfig {
/// address: "127.0.0.1:9000".to_string(),
/// host: "127.0.0.1".to_string(),
/// port: "9000".to_string(),
/// access_key: "rustfsadmin".to_string(),
/// secret_key: "rustfsadmin".to_string(),
/// domain_name: "demo.rustfs.com".to_string(),
/// volume_name: "data".to_string(),
/// console_address: "127.0.0.1:9001".to_string(),
/// };
///
/// let result = start_service(&config).await;
/// println!("{:?}", result);
/// ```
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());
}
// Prepare the service program
let executable_path = Self::prepare_service().await?;
// Check the data catalog
let volume_name_path = Path::new(&config.volume_name);
if !volume_name_path.exists() {
tokio::fs::create_dir_all(&config.volume_name).await?;
}
// 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 host = config.address.split(':').next().ok_or("无法解析主机地址")?;
// 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());
}
}
// Start the service
let mut child = tokio::process::Command::new(executable_path)
.arg("--address")
.arg(&config.address)
.arg("--access-key")
.arg(&config.access_key)
.arg("--secret-key")
.arg(&config.secret_key)
.arg("--console-address")
.arg(&config.console_address)
.arg(config.volume_name.clone())
.spawn()?;
let process_pid = child.id().unwrap();
// Wait for the service to start
tokio::time::sleep(Duration::from_secs(2)).await;
// Check if the service started successfully
if Self::is_port_in_use(host, main_port).await {
Self::show_info(&format!("服务启动成功!进程 ID: {}", process_pid));
Ok(())
} else {
child.kill().await?;
Err("服务启动失败".into())
}
}
/// Stop the service
/// This function stops the service
///
/// # Example
/// ```
/// let result = stop_service().await;
/// println!("{:?}", result);
/// ```
async fn stop_service() -> Result<(), Box<dyn Error>> {
let existing_pid = Self::check_service_status().await;
debug!("existing_pid: {:?}", existing_pid);
if let Some(service_pid) = existing_pid {
// An attempt was made to terminate the process
#[cfg(unix)]
{
StdCommand::new("kill").arg("-9").arg(service_pid.to_string()).output()?;
}
#[cfg(windows)]
{
StdCommand::new("taskkill")
.arg("/F")
.arg("/PID")
.arg(&service_pid.to_string())
.output()?;
}
// 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());
}
Self::show_info("服务已成功停止");
Ok(())
} else {
Err("服务未运行".into())
}
}
/// Check if the port is in use
/// This function checks if the given port is in use on the given host
///
/// # Example
/// ```
/// let host = "127.0.0.1";
/// let port = 9000;
/// let result = is_port_in_use(host, port).await;
/// println!("{:?}", result);
/// ```
async fn is_port_in_use(host: &str, port: u16) -> bool {
TcpStream::connect(format!("{}:{}", host, port)).await.is_ok()
}
/// Show an error message
/// This function shows an error message dialog
///
/// # Example
/// ```
/// show_error("This is an error message");
/// ```
pub(crate) fn show_error(message: &str) {
rfd::MessageDialog::new()
.set_title("错误")
.set_description(message)
.set_level(rfd::MessageLevel::Error)
.show();
}
/// Show an information message
/// This function shows an information message dialog
///
/// # Example
/// ```
/// show_info("This is an information message");
/// ```
pub(crate) fn show_info(message: &str) {
rfd::MessageDialog::new()
.set_title("成功")
.set_description(message)
.set_level(rfd::MessageLevel::Info)
.show();
}
/// Start the service
/// This function sends a `Start` command to the service manager
///
/// # Example
/// ```
/// let config = RustFSConfig {
/// address: "127.0.0.1:9000".to_string(),
/// host: "127.0.0.1".to_string(),
/// port: "9000".to_string(),
/// access_key: "rustfsadmin".to_string(),
/// secret_key: "rustfsadmin".to_string(),
/// domain_name: "demo.rustfs.com".to_string(),
/// volume_name: "data".to_string(),
/// console_address: "127.0.0.1:9001".to_string(),
/// };
///
/// let service_manager = ServiceManager::new();
/// let result = service_manager.start(config).await;
/// println!("{:?}", result);
/// ```
///
/// # Errors
/// This function returns an error if the service fails to start
///
/// # Panics
/// This function panics if the port number is invalid
///
/// # Safety
/// This function is not marked as unsafe
///
/// # Performance
/// This function is not optimized for performance
///
/// # Design
/// This function is designed to be simple and easy to use
///
/// # Security
/// This function does not have any security implications
pub async fn start(&self, config: RustFSConfig) -> Result<ServiceOperationResult, Box<dyn Error>> {
let start_time = chrono::Local::now();
self.command_tx.send(ServiceCommand::Start(config.clone())).await?;
let host = &config.host;
let port = config.port.parse::<u16>().expect("无效的端口号");
// wait for the service to actually start
let mut retries = 0;
while retries < 30 {
// wait up to 30 seconds
if Self::check_service_status().await.is_some() && Self::is_port_in_use(host, port).await {
let end_time = chrono::Local::now();
return Ok(ServiceOperationResult {
success: true,
start_time,
end_time,
message: "服务启动成功".to_string(),
});
}
tokio::time::sleep(Duration::from_secs(1)).await;
retries += 1;
}
Err("服务启动超时".into())
}
/// Stop the service
/// This function sends a `Stop` command to the service manager
///
/// # Example
/// ```
/// let service_manager = ServiceManager::new();
/// let result = service_manager.stop().await;
/// println!("{:?}", result);
/// ```
///
/// # Errors
/// This function returns an error if the service fails to stop
///
/// # Panics
/// This function panics if the port number is invalid
///
/// # Safety
/// This function is not marked as unsafe
///
/// # Performance
/// This function is not optimized for performance
///
/// # Design
/// This function is designed to be simple and easy to use
///
/// # Security
/// This function does not have any security implications
pub async fn stop(&self) -> Result<ServiceOperationResult, Box<dyn Error>> {
let start_time = chrono::Local::now();
self.command_tx.send(ServiceCommand::Stop).await?;
// Wait for the service to actually stop
let mut retries = 0;
while retries < 15 {
// Wait up to 15 seconds
if Self::check_service_status().await.is_none() {
let end_time = chrono::Local::now();
return Ok(ServiceOperationResult {
success: true,
start_time,
end_time,
message: "服务停止成功".to_string(),
});
}
tokio::time::sleep(Duration::from_secs(1)).await;
retries += 1;
}
Err("服务停止超时".into())
}
/// Restart the service
/// This function sends a `Restart` command to the service manager
///
/// # Example
/// ```
/// let config = RustFSConfig {
/// address: "127.0.0.1:9000".to_string(),
/// host: "127.0.0.1".to_string(),
/// port: "9000".to_string(),
/// access_key: "rustfsadmin".to_string(),
/// secret_key: "rustfsadmin".to_string(),
/// domain_name: "demo.rustfs.com".to_string(),
/// volume_name: "data".to_string(),
/// console_address: "127.0.0.1:9001".to_string(),
/// };
///
/// let service_manager = ServiceManager::new();
/// let result = service_manager.restart(config).await;
/// println!("{:?}", result);
/// ```
///
/// # Errors
/// This function returns an error if the service fails to restart
///
/// # Panics
/// This function panics if the port number is invalid
///
/// # Safety
/// This function is not marked as unsafe
///
/// # Performance
/// This function is not optimized for performance
///
/// # Design
/// This function is designed to be simple and easy to use
///
/// # Security
/// This function does not have any security implications
pub async fn restart(&self, config: RustFSConfig) -> Result<ServiceOperationResult, Box<dyn Error>> {
let start_time = chrono::Local::now();
self.command_tx.send(ServiceCommand::Restart(config.clone())).await?;
let host = &config.host;
let port = config.port.parse::<u16>().expect("无效的端口号");
// wait for the service to restart
let mut retries = 0;
while retries < 45 {
// Longer waiting time is given as both the stop and start processes are involved
if Self::check_service_status().await.is_some() && Self::is_port_in_use(host, port).await {
match config.save() {
Ok(_) => info!("save config success"),
Err(e) => {
error!("save config error: {}", e);
self.command_tx.send(ServiceCommand::Stop).await?;
Self::show_error("保存配置失败");
return Err("保存配置失败".into());
}
}
let end_time = chrono::Local::now();
return Ok(ServiceOperationResult {
success: true,
start_time,
end_time,
message: "服务重启成功".to_string(),
});
}
tokio::time::sleep(Duration::from_secs(1)).await;
retries += 1;
}
Err("服务重启超时".into())
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn test_service_command_creation() {
let config = RustFSConfig::default_config();
let start_cmd = ServiceCommand::Start(config.clone());
let stop_cmd = ServiceCommand::Stop;
let restart_cmd = ServiceCommand::Restart(config);
// Test that commands can be created
match start_cmd {
ServiceCommand::Start(_) => {}
_ => panic!("Expected Start command"),
}
match stop_cmd {
ServiceCommand::Stop => {}
_ => panic!("Expected Stop command"),
}
match restart_cmd {
ServiceCommand::Restart(_) => {}
_ => panic!("Expected Restart command"),
}
}
#[test]
fn test_service_operation_result_creation() {
let start_time = chrono::Local::now();
let end_time = chrono::Local::now();
let success_result = ServiceOperationResult {
success: true,
start_time,
end_time,
message: "Operation successful".to_string(),
};
let failure_result = ServiceOperationResult {
success: false,
start_time,
end_time,
message: "Operation failed".to_string(),
};
assert!(success_result.success);
assert_eq!(success_result.message, "Operation successful");
assert!(!failure_result.success);
assert_eq!(failure_result.message, "Operation failed");
}
#[test]
fn test_service_operation_result_debug() {
let result = ServiceOperationResult {
success: true,
start_time: chrono::Local::now(),
end_time: chrono::Local::now(),
message: "Test message".to_string(),
};
let debug_str = format!("{:?}", result);
assert!(debug_str.contains("ServiceOperationResult"));
assert!(debug_str.contains("success: true"));
assert!(debug_str.contains("Test message"));
}
#[test]
fn test_service_manager_creation() {
// Test ServiceManager creation in a tokio runtime
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let service_manager = ServiceManager::new();
// Test that ServiceManager can be created and cloned
let cloned_manager = service_manager.clone();
// Both should be valid (we can't test much more without async runtime)
assert!(format!("{:?}", service_manager).contains("ServiceManager"));
assert!(format!("{:?}", cloned_manager).contains("ServiceManager"));
});
}
#[test]
fn test_extract_port_valid() {
let test_cases = vec![
("127.0.0.1:9000", Some(9000)),
("localhost:8080", Some(8080)),
("192.168.1.100:3000", Some(3000)),
("0.0.0.0:80", Some(80)),
("example.com:443", Some(443)),
("host:65535", Some(65535)),
("host:1", Some(1)),
];
for (input, expected) in test_cases {
let result = ServiceManager::extract_port(input);
assert_eq!(result, expected, "Failed for input: {}", input);
}
}
#[test]
fn test_extract_port_invalid() {
let invalid_cases = vec![
"127.0.0.1", // Missing port
"127.0.0.1:", // Empty port
"127.0.0.1:abc", // Invalid port
"127.0.0.1:99999", // Port out of range
"", // Empty string
"invalid", // No colon
"host:-1", // Negative port
"host:0.5", // Decimal port
];
for input in invalid_cases {
let result = ServiceManager::extract_port(input);
assert_eq!(result, None, "Should be None for input: {}", input);
}
// Special case: empty host but valid port should still work
assert_eq!(ServiceManager::extract_port(":9000"), Some(9000));
// Special case: multiple colons - extract_port takes the second part
// For "127.0.0.1:9000:extra", it takes "9000" which is valid
assert_eq!(ServiceManager::extract_port("127.0.0.1:9000:extra"), Some(9000));
}
#[test]
fn test_extract_port_edge_cases() {
// Test edge cases for port numbers
assert_eq!(ServiceManager::extract_port("host:0"), Some(0));
assert_eq!(ServiceManager::extract_port("host:65535"), Some(65535));
assert_eq!(ServiceManager::extract_port("host:65536"), None); // Out of range
// IPv6-like address - extract_port takes the second part after split(':')
// For "::1:8080", split(':') gives ["", "", "1", "8080"], nth(1) gives ""
assert_eq!(ServiceManager::extract_port("::1:8080"), None); // Second part is empty
// For "[::1]:8080", split(':') gives ["[", "", "1]", "8080"], nth(1) gives ""
assert_eq!(ServiceManager::extract_port("[::1]:8080"), None); // Second part is empty
}
#[test]
fn test_show_error() {
// Test that show_error function exists and can be called
// We can't actually test the dialog in a test environment
// so we just verify the function signature
}
#[test]
fn test_show_info() {
// Test that show_info function exists and can be called
// We can't actually test the dialog in a test environment
// so we just verify the function signature
}
#[test]
fn test_service_operation_result_timing() {
let start_time = chrono::Local::now();
std::thread::sleep(Duration::from_millis(10)); // Small delay
let end_time = chrono::Local::now();
let result = ServiceOperationResult {
success: true,
start_time,
end_time,
message: "Timing test".to_string(),
};
// End time should be after start time
assert!(result.end_time >= result.start_time);
}
#[test]
fn test_service_operation_result_with_unicode() {
let result = ServiceOperationResult {
success: true,
start_time: chrono::Local::now(),
end_time: chrono::Local::now(),
message: "操作成功 🎉".to_string(),
};
assert_eq!(result.message, "操作成功 🎉");
assert!(result.success);
}
#[test]
fn test_service_operation_result_with_long_message() {
let long_message = "A".repeat(10000);
let result = ServiceOperationResult {
success: false,
start_time: chrono::Local::now(),
end_time: chrono::Local::now(),
message: long_message.clone(),
};
assert_eq!(result.message.len(), 10000);
assert_eq!(result.message, long_message);
assert!(!result.success);
}
#[test]
fn test_service_command_with_different_configs() {
let config1 = RustFSConfig {
address: "127.0.0.1:9000".to_string(),
host: "127.0.0.1".to_string(),
port: "9000".to_string(),
access_key: "admin1".to_string(),
secret_key: "pass1".to_string(),
domain_name: "test1.com".to_string(),
volume_name: "/data1".to_string(),
console_address: "127.0.0.1:9001".to_string(),
};
let config2 = RustFSConfig {
address: "192.168.1.100:8080".to_string(),
host: "192.168.1.100".to_string(),
port: "8080".to_string(),
access_key: "admin2".to_string(),
secret_key: "pass2".to_string(),
domain_name: "test2.com".to_string(),
volume_name: "/data2".to_string(),
console_address: "192.168.1.100:8081".to_string(),
};
let start_cmd1 = ServiceCommand::Start(config1);
let restart_cmd2 = ServiceCommand::Restart(config2);
// Test that different configs can be used
match start_cmd1 {
ServiceCommand::Start(config) => {
assert_eq!(config.address, "127.0.0.1:9000");
assert_eq!(config.access_key, "admin1");
}
_ => panic!("Expected Start command"),
}
match restart_cmd2 {
ServiceCommand::Restart(config) => {
assert_eq!(config.address, "192.168.1.100:8080");
assert_eq!(config.access_key, "admin2");
}
_ => panic!("Expected Restart command"),
}
}
#[test]
fn test_memory_efficiency() {
// Test that structures don't use excessive memory
assert!(std::mem::size_of::<ServiceCommand>() < 2000);
assert!(std::mem::size_of::<ServiceOperationResult>() < 1000);
assert!(std::mem::size_of::<ServiceManager>() < 1000);
}
// Note: The following methods are not tested here because they require:
// - Async runtime (tokio)
// - File system access
// - Network access
// - Process management
// - External dependencies (embedded assets)
//
// These should be tested in integration tests:
// - check_service_status()
// - prepare_service()
// - start_service()
// - stop_service()
// - is_port_in_use()
// - ServiceManager::start()
// - ServiceManager::stop()
// - ServiceManager::restart()
//
// The RUSTFS_HASH lazy_static is also not tested here as it depends
// on embedded assets that may not be available in unit test environment.
}

Some files were not shown because too many files have changed in this diff Show More