Skip to content

Commit

Permalink
feat: init xtask support
Browse files Browse the repository at this point in the history
  • Loading branch information
foobar123asdf committed Feb 29, 2024
1 parent 17af07a commit 8f06454
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[alias]
xtask = "run --package xtask --"
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@

.DS_Store

# The cache for docker container dependency
.cargo

# The cache for chain data in container
.local

Expand Down
51 changes: 37 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["node", "pallets/subspace", "runtime"]
members = ["node", "pallets/subspace", "runtime", "xtask"]
resolver = "2"

[profile.release]
Expand Down
11 changes: 11 additions & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "xtask"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde_json = { workspace = true, features = ["std"] }
tempfile = "3.10.1"
xflags = "0.3.2"
66 changes: 66 additions & 0 deletions xtask/src/flags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use std::path::PathBuf;

xflags::xflags! {
src "src/flags.rs"

cmd localnet {

cmd run {
optional --path path: PathBuf
optional --chain-name chain_name: String
optional --chain-path chain: PathBuf
optional --secrets-path secrets_path: PathBuf
optional --base-path base_path: PathBuf
optional --port tcp_port: u16
optional --rpc-port rpc_port: u16
repeated --bootnodes bootnodes: String
optional --validator
optional --purge
}
}
}

// generated start
// The following code is generated by `xflags` macro.
// Run `env UPDATE_XFLAGS=1 cargo build` to regenerate.
#[derive(Debug)]
pub struct Localnet {
pub subcommand: LocalnetCmd,
}

#[derive(Debug)]
pub enum LocalnetCmd {
Run(Run),
}

#[derive(Debug)]
pub struct Run {
pub path: Option<PathBuf>,
pub chain_name: Option<String>,
pub chain_path: Option<PathBuf>,
pub secrets_path: Option<PathBuf>,
pub base_path: Option<PathBuf>,
pub port: Option<u16>,
pub rpc_port: Option<u16>,
pub bootnodes: Vec<String>,
pub validator: bool,
pub purge: bool,
}

impl Localnet {
#[allow(dead_code)]
pub fn from_env_or_exit() -> Self {
Self::from_env_or_exit_()
}

#[allow(dead_code)]
pub fn from_env() -> xflags::Result<Self> {
Self::from_env_()
}

#[allow(dead_code)]
pub fn from_vec(args: Vec<std::ffi::OsString>) -> xflags::Result<Self> {
Self::from_vec_(args)
}
}
// generated end
173 changes: 173 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
use std::fs::File;

mod flags;

fn main() {
let flags = flags::Localnet::from_env_or_exit();
match flags.subcommand {
flags::LocalnetCmd::Run(r) => {
let path = r.path.unwrap_or_else(|| {
tempfile::Builder::new()
.prefix("commune-node-data")
.tempdir()
.expect("failed to create tempdir")
.into_path()
});
match (path.exists(), path.is_dir()) {
(true, false) => panic!("provided path must be a directory"),
(false, false) => std::fs::create_dir(&path).unwrap(),
_ => {},
}

let base_path = r
.base_path
.or_else(|| {
let path = path.join("data");
path.is_dir().then_some(path)
})
.unwrap_or_else(|| path.join("data"));

let chain_path = r
.chain_path
.or_else(|| {
let path = path.join("spec.json");
path.is_file().then_some(path)
})
.unwrap_or_else(|| {
let chain = path.join("spec.json");
let chain_name = r.chain_name.expect(
"chain name must be specified if no chain path is provided or found",
);
let output = foo::build_chain_spec(&chain_name).output().unwrap();
std::fs::write(&chain, &output.stdout).unwrap();
chain
});

let secrets_path = r.secrets_path.unwrap_or_else(|| path.clone());

let key_aura = secrets_path.join("aura.sr25519.key.json");
if !key_aura.exists() {
let output = foo::key_generate().output().unwrap();
std::fs::write(&key_aura, &output.stdout).unwrap();
}

let mnemonic = {
let val: serde_json::Value =
serde_json::from_reader(File::open(key_aura).unwrap()).unwrap();
val.get("secretPhrase").unwrap().as_str().unwrap().to_string()
};

let key_gran = secrets_path.join("gran.ed25519.key.json");
if !key_gran.exists() {
let output = foo::key_inspect_cmd(&mnemonic).output().unwrap();
std::fs::write(&key_gran, &output.stdout).unwrap();
}

let _key_insert_aura = foo::key_insert_cmd(&base_path, &chain_path, &mnemonic, "aura")
.spawn()
.unwrap()
.wait();
let _key_insert_gran = foo::key_insert_cmd(&base_path, &chain_path, &mnemonic, "gran")
.spawn()
.unwrap()
.wait();

let bootnodes = (!r.bootnodes.is_empty()).then_some(r.bootnodes);
let run = foo::run_node(
&base_path,
&chain_path,
r.port.unwrap_or(30333),
r.rpc_port.unwrap_or(9944),
r.validator,
bootnodes,
)
.spawn()
.unwrap()
.wait();
},
}
}

mod foo {
use std::{ffi::OsStr, process::Command};

pub fn base_node_run_cmd() -> Command {
let mut cmd = Command::new("cargo");
cmd.args(&["run", "--release", "--package", "node-subspace", "--"]);
cmd
}

pub fn build_chain_spec(chain_spec: &str) -> Command {
let mut cmd = base_node_run_cmd();
cmd.args(&["build-spec", "--raw"])
.args(&["--chain", chain_spec])
.arg("--disable-default-bootnode");
cmd
}

pub fn key_generate() -> Command {
let mut cmd = base_node_run_cmd();
cmd.args(&["key", "generate"])
.args(&["--scheme", "sr25519"])
.args(&["--output-type", "json"]);
cmd
}

pub fn key_insert_cmd(
base_path: &dyn AsRef<OsStr>,
chain_spec: &dyn AsRef<OsStr>,
mnemonic: &str,
key_type: &str,
) -> Command {
let mut cmd = base_node_run_cmd();
cmd.args(&["key", "insert"])
.args(&[&"--base-path" as &(dyn AsRef<_>), base_path])
.args(&[&"--chain" as &(dyn AsRef<_>), chain_spec])
.args(&[
"--scheme",
match key_type {
"aura" => "sr25519",
"gran" => "sr25519",
_ => panic!(),
},
])
.args(&["--suri", &mnemonic])
.args(&["--key-type", key_type]);
cmd
}

pub fn key_inspect_cmd(mnemonic: &str) -> Command {
let mut cmd = base_node_run_cmd();
cmd.args(&["key", "inspect"])
.args(&["--scheme", "sr25519"])
.args(&["--output-type", "json"])
.arg(mnemonic);
cmd
}

pub fn run_node(
base_path: &dyn AsRef<OsStr>,
chain_spec: &dyn AsRef<OsStr>,
port: u16,
rpc_port: u16,
is_validator: bool,
bootnodes: Option<Vec<String>>,
) -> Command {
let mut cmd = base_node_run_cmd();

cmd.args(&[&"--base-path" as &(dyn AsRef<_>), base_path])
.args(&[&"--chain" as &(dyn AsRef<_>), chain_spec])
.args(&["--unsafe-rpc-external", "--rpc-cors", "all"])
.args(&["--port", &port.to_string(), "--rpc-port", &rpc_port.to_string()]);

if is_validator {
cmd.arg("--validator");
}

if let Some(bootnodes) = bootnodes {
cmd.arg("--bootnodes").args(&bootnodes);
}

cmd
}
}

0 comments on commit 8f06454

Please sign in to comment.