-
Install Rust on your macOS machine.
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
Clone mega repository and build it.
$ git clone https://github.com/web3infra-foundation/mega.git $ cd mega $ git submodule update --init --recursive $ cargo build
-
Install PostgreSQL and init database. (You can skip this step if using SQLite in
config.toml
)- Install PostgreSQL 16 with
brew
command.
$ brew install postgresql@16 $ echo 'export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH"' >> ~/.zshrc $ brew services start postgresql@16 $ initdb /Volumes/Data/postgres -E utf8 # /Volumes/Data is path store data
- Create a database, then find the dump file in the SQL directory of the Mega repository and import it into the database.
$ psql postgres
postgres=# \l postgres=# DROP DATABASE IF EXISTS mega; postgres=# CREATE DATABASE mega; postgres=# \q
$ cd mega/sql/postgres $ psql mega < pg_YYYYMMDD_init.sql
- Create user and grant privileges.
postgres=# DROP USER IF EXISTS mega; postgres=# CREATE USER mega WITH ENCRYPTED PASSWORD 'mega'; postgres=# GRANT ALL PRIVILEGES ON DATABASE mega TO mega;
$ psql mega -c "GRANT ALL ON ALL TABLES IN SCHEMA public to mega;" $ psql mega -c "GRANT ALL ON ALL SEQUENCES IN SCHEMA public to mega;" $ psql mega -c "GRANT ALL ON ALL FUNCTIONS IN SCHEMA public to mega;"
- Install PostgreSQL 16 with
-
Update config file for local test. For local testing, Mega uses the
config.toml
file to configure the required parameters. See Configuration. -
Init the Mega
$ cd mega $ cargo run init
-
Start the Mega server for testing.
# Starting a single http server $ cargo run service http # Or Starting multiple server $ cargo run service multi http ssh
-
Test the
git push
andgit clone
$ cd mega $ git remote add local http://localhost:8000/projects/mega.git $ git push local main $ cd /tmp $ git clone http://localhost:8000/projects/mega.git
-
Install Rust.
$ pacman -S rustup $ rustup default stable
-
Clone mega repository and build.
$ git clone https://github.com/web3infra-foundation/mega.git $ cd mega $ git submodule update --init --recursive $ cargo build
-
Install PostgreSQL and initialize database. (You can skip this step if using SQLite in
config.toml
)1.Install PostgreSQL.
$ pacman -S postgresql # Switch to `postgres` user $ sudo -i -u postgres postgres $ initdb -D /var/lib/postgres/data -E utf8 # /Volumes/Data is where data will be stored postgres $ exit $ systemctl enable --now postgresql
2.Create database.
$ sudo -u postgres psql postgres
postgres=# \l postgres=# DROP DATABASE IF EXISTS mega; postgres=# CREATE DATABASE mega; postgres=# \q
3.Import
mega/sql/postgres/pg_<time>_init.sql
tomega
.$ cd mega/sql/postgres $ sudo -u postgres psql mega < pg_YYYYMMDD__init.sql
4.Create user and grant privileges.
$ sudo -u postgres psql postgres postgres=# DROP USER IF EXISTS mega; postgres=# CREATE USER mega WITH ENCRYPTED PASSWORD 'mega'; postgres=# GRANT ALL PRIVILEGES ON DATABASE mega TO mega;
$ sudo -u postgres psql mega -c "GRANT ALL ON ALL TABLES IN SCHEMA public to mega;" $ sudo -u postgres psql mega -c "GRANT ALL ON ALL SEQUENCES IN SCHEMA public to mega;" $ sudo -u postgres psql mega -c "GRANT ALL ON ALL FUNCTIONS IN SCHEMA public to mega;"
-
Config
confg.toml
. See Configuration. -
Init Mega.
$ cd mega $ cargo run init
-
Start Mega server.
# Start a single https server $ cargo run service http # Or Start multiple server $ cargo run service multi http ssh
-
Test
git push
andgit clone
$ cd /tmp $ git clone https://github.com/Rust-for-Linux/linux.git $ cd linux $ git remote add mega http://localhost:8000/third-part/linux.git $ git push --all mega $ sudo rm -r /tmp/linux $ cd /tmp $ git clone http://localhost:8000/third-part/linux.git
If you are using GitHub codespaces, you can follow the steps below to set up the Mega project. When you create a new Codespace, the Mega project will be cloned automatically. You can then follow the steps below to set up the project.
You can skip this step (PostgreSQL setup) if using SQLite in config.toml
.
When the codespace is ready, the PostgreSQL will be installed and started automatically. You can then follow the steps below to set up the database with below steps.
## Start PostgreSQL
/etc/init.d/postgresql start
sudo -u postgres psql mega -c "CREATE DATABASE mega;"
sudo -u postgres psql mega < /workspaces/mega/sql/pg_YYYYMMDD__init.sql
sudo -u postgres psql mega -c "CREATE USER mega WITH ENCRYPTED PASSWORD 'mega';"
sudo -u postgres psql mega -c "GRANT ALL PRIVILEGES ON DATABASE mega TO mega;"
sudo -u postgres psql mega -c "GRANT ALL ON ALL TABLES IN SCHEMA public to mega;"
sudo -u postgres psql mega -c "GRANT ALL ON ALL TABLES IN SCHEMA public to mega;"
sudo -u postgres psql mega -c "GRANT ALL ON ALL SEQUENCES IN SCHEMA public to mega;"
sudo -u postgres psql mega -c "GRANT ALL ON ALL FUNCTIONS IN SCHEMA public to mega;"
Config confg.toml
file for the Mega project.
Config confg.toml
file for the Mega project.
- Default: automatically load
config.toml
in current directory. - Specify manually: use
--config "/path/to/config.toml"
- You can use environment variables starting with
MEGA_
to override the configuration inconfig.toml
.- like
MEGA_BASE_DIR
to overridebase_dir
. // withenv::set_var()
- use separator
__
(2 *_
) for nested keys, likeMEGA_LOG__LOG_PATH
forlog.log_path
.
- like
- Support
${}
syntax to reference other keys in the same file.- like
log_path = "${base_dir}/logs"
,${base_dir}
will be replaced by the value ofbase_dir
- or
key = "${xxx.yyy}/zzz"
(prefixxxx.
can't be omitted) - only support
String
type - substitute from up to down
- see codes in config.rs
- like
# The directory where the data files is located, such as logs, database, etc.
# can be overrided by environment variable `MEGA_BASE_DIR`
base_dir = "/tmp/.mega"
# Filling the following environment variables with values you set
## Logging Configuration
[log]
# The path which log file is saved
log_path = "${base_dir}/logs"
# log level
level = "debug"
# print std log in console, disable it on production for performance
print_std = true
[database]
# "sqlite" | "postgres"
# "sqlite" will use `db_path` and ignore `db_url`
db_type = "sqlite"
# used for sqlite
db_path = "${base_dir}/mega.db"
# database connection url
db_url = "postgres://mega:mega@localhost:5432/mega"
# db max connection, setting it to twice the number of CPU cores would be appropriate.
max_connection = 32
# db min connection, setting it to the number of CPU cores would be appropriate.
min_connection = 16
# Whether to disabling SQLx Log
sqlx_logging = false
[storage]
obs_access_key = ""
obs_secret_key = ""
# cloud storage region
obs_region = "cn-east-3"
# Override the endpoint URL used for remote storage services
obs_endpoint = "https://obs.cn-east-3.myhuaweicloud.com"
[monorepo]
## Only import directory support multi-branch commit and tag, monorepo only support main branch
## Mega treats files under this directory as import repo and other directories as monorepo
import_dir = "/third-part"
disable_http_push = false
[pack]
# The maximum memory used by decode, Unit is GB
pack_decode_mem_size = 4
# The location where the object stored when the memory used by decode exceeds the limit
pack_decode_cache_path = "${base_dir}/cache"
clean_cache_after_decode = true
# The maximum meesage size in channel buffer while decode
channel_message_size = 1_000_000
[ztm]
ca = "http://127.0.0.1:9999"
hub = "http://127.0.0.1:8888"
agent = "http://127.0.0.1:7777"
[lfs]
# LFS Server url
url = "https://git.gitmono.com"
# set the local path of the lfs storage
lfs_obj_local_path = "${base_dir}/lfs"
## IMPORTANT: The 'enable_split' feature can only be enabled for new databases. Existing databases do not support this feature.
# Enable or disable splitting large files into smaller chunks
enable_split = false # Default is disabled. Set to true to enable file splitting.
# Size of each file chunk when splitting is enabled, in bytes. Ignored if splitting is disabled.
split_size = 20971520 # Default size is 20MB (20971520 bytes)
Currently, the tables of database are created by .sql
file.
If you want to add a new table or modify the existing table, you need to update the .sql
files which are located in the sql
directory.
- Each database corresponds to one
.sql
file, you must modify all of them if you want to update the tables in order to keep the consistency of the database. - DO NOT use
Array
Type in PostgreSQL but useJSON
instead, for compatibility with SQLite & MySQL. (JSON
<==>serde_json::Value
)
Keep in mind that it's impossible to find all bugs.
Tests are the last line of defense.
Unit tests are small, focused tests that verify the behavior of a single function or module in isolation.
// ...Other Codes
#[cfg(test)] // indicates this block will only be compiled when running tests
mod tests {
use super::*;
#[test] // indicates that this function is a test, which will be run by `cargo test`
fn test_add() {
let result = add(1, 1);
assert_eq!(result, 2); // assert is important to tests
}
}
Integration tests verify that different parts of your library work correctly together. They are external to your crate and use your code in the same way any other code would.
You can refer to the implementation of the mega module. (mega/tests)
- Create a
tests
directory at the same level as yoursrc
directory (e.g.libra/tests
). - Add
*.rs
files in this directory. // Each file will be compiled as a separate crate.
- The
tests
in root directory (workspace) is NOT integration tests, but somedata
for other tests. - If you need a common module, use
tests/common/mod.rs
rather thantests/common.rs
, to declare it's not a test file. - There is no need to add
#[cfg(test)]
to thetests
directory.tests
will be compiled only when running tests.
The following command will be executed in GitHub Actions
.
This command DOES NOT run Unit Tests (which could be very messy).
cargo test --workspace --test '*' -- --nocapture
--workspace
: Run tests for all packages in the workspace.--test
: Test the specified integration test.--
: Pass the following arguments to the test binary.--nocapture
: DO NOT capture the output (e.g.println!
) of the test.
If you want to run tests in a specific package, you can use --package
.
For more information, please refer to the rust wiki.
This guide outlines the recommended order for importing dependencies in Rust projects.
This guide outlines the recommended order for importing dependencies in Rust projects.
Import dependencies from the Rust standard library.
Import dependencies from third-party crates.
Import dependencies from other modules within the project workspace.
Import functions and structs from within modules.
Example:
// 1. Rust Standard Library
use std::collections::HashMap;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::{Arc, Mutex};
// 2. Third-Party Crates
use bytes::{BufMut, Bytes, BytesMut};
use russh::server::{self, Auth, Msg, Session};
use russh::{Channel, ChannelId};
use russh_keys::key;
use tokio::io::{AsyncReadExt, BufReader};
// 3. Other Modules in Workspace
use storage::driver::database::storage::ObjectStorage;
// 4. Other Files in the Same Module
use crate::protocol::pack::{self};
use crate::protocol::ServiceType;
use crate::protocol::{PackProtocol, Protocol};
- Always group imports with an empty line between different sections for better readability.
- Alphabetize imports within each section to maintain consistency.
- Avoid using extern crate syntax for Rust 2018 edition and later; prefer using use with crates.
- Do not use
super::
andself::
in imports. It can lead to ambiguity and hinder code readability. Instead, use crate to reference the current crate's modules.