diff --git a/Cargo.lock b/Cargo.lock index 12f8917e..48a94473 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -342,7 +342,7 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", - "base64 0.21.4", + "base64", "bitflags 1.3.2", "bytes", "futures-util", @@ -414,12 +414,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.4" @@ -438,7 +432,7 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d1c9c15093eb224f0baa400f38fcd713fc1391a6f1c389d886beef146d60a3" dependencies = [ - "base64 0.21.4", + "base64", "blowfish", "getrandom", "subtle", @@ -645,6 +639,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "bytesize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" + [[package]] name = "camino" version = "1.1.6" @@ -861,42 +861,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "console-api" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e" -dependencies = [ - "prost", - "prost-types", - "tonic", - "tracing-core", -] - -[[package]] -name = "console-subscriber" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4cf42660ac07fcebed809cfe561dd8730bcd35b075215e6479c516bcd0d11cb" -dependencies = [ - "console-api", - "crossbeam-channel", - "crossbeam-utils", - "futures", - "hdrhistogram", - "humantime", - "prost-types", - "serde", - "serde_json", - "thread_local", - "tokio", - "tokio-stream", - "tonic", - "tracing", - "tracing-core", - "tracing-subscriber", -] - [[package]] name = "const-oid" version = "0.9.5" @@ -1305,7 +1269,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbfb21b9878cf7a348dcb8559109aabc0ec40d69924bd706fa5149846c4fef75" dependencies = [ - "base64 0.21.4", + "base64", "memchr", ] @@ -1429,6 +1393,18 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "filetime" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "windows-sys", +] + [[package]] name = "finl_unicode" version = "1.2.0" @@ -1766,26 +1742,13 @@ dependencies = [ "hashbrown 0.14.1", ] -[[package]] -name = "hdrhistogram" -version = "7.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" -dependencies = [ - "base64 0.13.1", - "byteorder", - "flate2", - "nom", - "num-traits", -] - [[package]] name = "headers" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.21.4", + "base64", "bytes", "headers-core", "http", @@ -1902,12 +1865,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "hyper" version = "0.14.27" @@ -1946,18 +1903,6 @@ dependencies = [ "tokio-rustls", ] -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - [[package]] name = "iana-time-zone" version = "0.1.57" @@ -2076,7 +2021,7 @@ dependencies = [ [[package]] name = "integration-test" -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" dependencies = [ "anyhow", "reqwest", @@ -2204,7 +2149,7 @@ dependencies = [ [[package]] name = "land-center" -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" dependencies = [ "anyhow", "axum", @@ -2232,13 +2177,15 @@ dependencies = [ [[package]] name = "land-cli" -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" dependencies = [ "anyhow", "async-trait", "axum", + "bytes", + "bytesize", "clap", - "console-subscriber", + "flate2", "land-core", "land-worker", "lazy_static", @@ -2249,6 +2196,8 @@ dependencies = [ "rust-embed", "serde", "serde_json", + "tar", + "tempfile", "tokio", "tracing", "uuid", @@ -2256,7 +2205,7 @@ dependencies = [ [[package]] name = "land-core" -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" dependencies = [ "anyhow", "envconfig", @@ -2275,7 +2224,7 @@ dependencies = [ [[package]] name = "land-dao" -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" dependencies = [ "anyhow", "async-std", @@ -2297,7 +2246,7 @@ dependencies = [ [[package]] name = "land-runtime" -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" dependencies = [ "anyhow", "async-trait", @@ -2323,7 +2272,7 @@ dependencies = [ [[package]] name = "land-sdk" -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" dependencies = [ "anyhow", "http", @@ -2335,7 +2284,7 @@ dependencies = [ [[package]] name = "land-sdk-macro" -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" dependencies = [ "anyhow", "http", @@ -2345,7 +2294,7 @@ dependencies = [ [[package]] name = "land-storage" -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" dependencies = [ "anyhow", "envconfig", @@ -2360,7 +2309,7 @@ dependencies = [ [[package]] name = "land-worker" -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" dependencies = [ "anyhow", "async-trait", @@ -2400,7 +2349,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76bd09637ae3ec7bd605b8e135e757980b3968430ff2b1a4a94fb7769e50166d" dependencies = [ - "base64 0.21.4", + "base64", "email-encoding", "email_address", "fastrand 1.9.0", @@ -2754,7 +2703,7 @@ dependencies = [ "async-compat", "async-trait", "backon", - "base64 0.21.4", + "base64", "bytes", "chrono", "flagset", @@ -3034,38 +2983,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost", -] - [[package]] name = "psm" version = "0.1.21" @@ -3331,7 +3248,7 @@ checksum = "3228e570df74d69d3d3236a71371f1edd748a3e4eb728ea1f29d403bc10fc727" dependencies = [ "anyhow", "async-trait", - "base64 0.21.4", + "base64", "chrono", "form_urlencoded", "hex", @@ -3358,7 +3275,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.4", + "base64", "bytes", "encoding_rs", "futures-core", @@ -3611,7 +3528,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.4", + "base64", ] [[package]] @@ -4224,7 +4141,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" dependencies = [ "atoi", - "base64 0.21.4", + "base64", "bigdecimal", "bitflags 2.4.0", "byteorder", @@ -4271,7 +4188,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" dependencies = [ "atoi", - "base64 0.21.4", + "base64", "bigdecimal", "bitflags 2.4.0", "byteorder", @@ -4468,6 +4385,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tar" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "target-lexicon" version = "0.12.11" @@ -4587,20 +4515,9 @@ dependencies = [ "signal-hook-registry", "socket2 0.5.4", "tokio-macros", - "tracing", "windows-sys", ] -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-macros" version = "2.1.0" @@ -4713,34 +4630,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "axum", - "base64 0.21.4", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding 2.3.0", - "pin-project", - "prost", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower" version = "0.4.13" @@ -4749,13 +4638,9 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", "futures-util", - "indexmap 1.9.3", "pin-project", "pin-project-lite", - "rand", - "slab", "tokio", - "tokio-util", "tower-layer", "tower-service", "tracing", @@ -5347,7 +5232,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41376a7c094335ee08abe6a4eff79a32510cc805a249eff1b5e7adf0a42e7cdf" dependencies = [ "anyhow", - "base64 0.21.4", + "base64", "bincode", "directories-next", "log", @@ -6024,6 +5909,15 @@ dependencies = [ "tap", ] +[[package]] +name = "xattr" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" +dependencies = [ + "libc", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index c72374d4..fb2363e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,9 @@ authors = { workspace = true } anyhow = { workspace = true } async-trait = { workspace = true } axum = { workspace = true } +bytesize = "1.3.0" +tempfile = "3.8.0" clap = { workspace = true } -console-subscriber = "0.1.10" land-core = { workspace = true } land-worker = { workspace = true } lazy_static = { workspace = true } @@ -23,6 +24,9 @@ serde_json = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } uuid = { workspace = true } +tar = { workspace = true } +flate2 = { workspace = true } +bytes = { workspace = true } [build-dependencies] land-worker = { workspace = true } @@ -42,17 +46,17 @@ members = [ ] [workspace.package] -version = "0.1.4-beta.6" +version = "0.1.4-rc.1" edition = "2021" authors = ["fuxiaohei "] [workspace.dependencies] -land-worker = { path = "crates/worker", version = "0.1.4-beta.6" } -land-sdk-macro = { path = "crates/sdk-macro", version = "0.1.4-beta.6" } -land-sdk = { path = "crates/sdk", version = "0.1.4-beta.6" } -land-core = { path = "crates/core", version = "0.1.4-beta.6" } -land-dao = { path = "crates/dao", version = "0.1.4-beta.6" } -land-storage = { path = "crates/storage", version = "0.1.4-beta.6" } +land-worker = { path = "crates/worker", version = "0.1.4-rc.1" } +land-sdk-macro = { path = "crates/sdk-macro", version = "0.1.4-rc.1" } +land-sdk = { path = "crates/sdk", version = "0.1.4-rc.1" } +land-core = { path = "crates/core", version = "0.1.4-rc.1" } +land-dao = { path = "crates/dao", version = "0.1.4-rc.1" } +land-storage = { path = "crates/storage", version = "0.1.4-rc.1" } anyhow = "1.0.75" axum = { version = "0.6.20", features = ["headers", "ws"] } clap = { version = "4.4.6", features = ["derive", "env"] } @@ -100,3 +104,6 @@ strum = { version = "0.25.0", features = ["derive"] } rust-embed = "8.0.0" moka = { version = "0.12.1", default-features = false, features = ["sync"] } md-5 = "0.10.6" +tar = "0.4.40" +flate2 = "1.0.27" +bytes = "1.5.0" diff --git a/crates/core/src/metadata.rs b/crates/core/src/metadata.rs index 70098500..8c696fd2 100644 --- a/crates/core/src/metadata.rs +++ b/crates/core/src/metadata.rs @@ -23,6 +23,7 @@ pub struct Metadata { #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct MetadataBuild { pub rust_target_dir: Option, + pub rust_src_dir: Option>, } impl Metadata { @@ -71,6 +72,17 @@ impl Metadata { target_dir.join(name).to_str().unwrap().to_string() } + /// get source dir + pub fn get_source_dirs(&self) -> Vec { + let src_dir = self + .build + .clone() + .unwrap_or_default() + .rust_src_dir + .unwrap_or_else(|| vec!["src".to_string()]); + src_dir + } + /// get output file pub fn get_output(&self) -> String { self.get_target().replace(".wasm", ".component.wasm") diff --git a/src/deploy.rs b/src/deploy.rs index 5ebe23d7..5e1ced94 100644 --- a/src/deploy.rs +++ b/src/deploy.rs @@ -3,7 +3,7 @@ use land_core::metadata::Metadata; use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; use std::path::Path; -use tracing::debug; +use tracing::{debug, error}; /// LOCAL_PROJECT_ENV_FILE is the file name of the local project env file const LOCAL_PROJECT_ENV_FILE: &str = ".land.env"; @@ -17,7 +17,7 @@ pub async fn load_project( meta: &Metadata, addr: &str, token: &str, -) -> Result { +) -> Result> { let local_project = read_project_env()?; if project_name.is_some() { // load project info from given name, local env @@ -25,7 +25,7 @@ pub async fn load_project( debug!("Try to load project from given name: {}", project_name); if let Some(local_project) = local_project { if project_name == &local_project.name { - return Ok(local_project); + return Ok(Some(local_project)); } } @@ -34,18 +34,20 @@ pub async fn load_project( debug!("Try to load project from cloud: {}", project_name); let project = query_project(addr, token, project_name.to_string()).await?; write_project_env(&project.project)?; - return Ok(project.project); + return Ok(Some(project.project)); } // if project name not provided, load from local env debug!("Try to load project from local env"); if let Some(local_project) = local_project { - return Ok(local_project); + return Ok(Some(local_project)); } debug!("Try to create new project from cloud"); - let project = create_project(meta, addr, token).await?; - write_project_env(&project)?; - Ok(project) + if let Some(project) = create_project(meta, addr, token).await? { + write_project_env(&project)?; + return Ok(Some(project)); + } + Ok(None) } #[derive(Serialize, Default, Debug)] @@ -93,8 +95,8 @@ pub async fn query_project(addr: &str, token: &str, name: String) -> Result Result { - let url = format!("{}/v1/project", addr); +pub async fn create_project(meta: &Metadata, addr: &str, token: &str) -> Result> { + let url = format!("{}/v2/project", addr); let data = CreateProjectRequest { language: meta.language.clone(), prefix: Some(meta.name.clone().replace('-', "")), @@ -107,8 +109,12 @@ pub async fn create_project(meta: &Metadata, addr: &str, token: &str) -> Result< .json(&data) .send() .await?; + if !resp.status().is_success() { + error!("create project failed, status: {}", resp.status()); + return Ok(None); + } let project = resp.json::().await?; - Ok(project) + Ok(Some(project)) } /// read_project_env reads the project name from env file diff --git a/src/flags.rs b/src/flags.rs index 3a4fa9d7..9da0cf93 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -1,9 +1,15 @@ use crate::deploy; +use anyhow::Result; +use bytesize::ByteSize; use clap::Args; +use flate2::write::GzEncoder; +use flate2::Compression; use land_core::metadata::{Metadata, DEFAULT_FILE as DEFAULT_METADATA_FILE}; use path_slash::PathBufExt as _; use std::path::{Path, PathBuf}; -use tracing::{debug, debug_span, info, Instrument}; +use tar::Header; +use tempfile::tempdir; +use tracing::{debug, debug_span, error, info, Instrument}; static SDK_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -209,13 +215,29 @@ impl Deploy { let meta = Metadata::from_file(DEFAULT_METADATA_FILE).expect("Project meta.toml not found"); debug!("Meta: {meta:?}"); - let project = deploy::load_project(self.project.clone(), &meta, addr, &self.token) - .await - .expect("Load project failed"); + let project = + match deploy::load_project(self.project.clone(), &meta, addr, &self.token).await { + Ok(project) => { + if project.is_none() { + error!("Load project failed"); + return; + } + project.unwrap() + } + Err(e) => { + error!("Load project failed: {}", e); + return; + } + }; info!("Project name: {}", project.name); - let output = meta.get_output(); - let content = std::fs::read(output).expect("Read compiled target failed"); + let content = match prepare_upload_bundle(&meta) { + Ok(content) => content, + Err(e) => { + error!("Prepare upload bundle failed: {}", e); + return; + } + }; let deployment = deploy::create_deployment( project, @@ -238,3 +260,53 @@ impl Deploy { info!("Deployment url: \t\n{}", deployment.domain_url); } } + +fn prepare_upload_bundle(meta: &Metadata) -> Result> { + let output = meta.get_output(); + + // print output file size + let size = std::fs::metadata(&output)?.len(); + info!( + "Webassembly size: {}, size: {}", + bytesize::to_string(size, true), + size + ); + + let dir = tempdir()?; + let file_path = "bundle.tar.gz"; + debug!("Bundle file: {:?}", file_path); + + let tar_gz = std::fs::File::create(&file_path)?; + let enc = GzEncoder::new(tar_gz, Compression::default()); + let mut tar = tar::Builder::new(enc); + + // add wasm module + let mut wasm_file = std::fs::File::open(output)?; + tar.append_file("bin/bundle.wasm", &mut wasm_file)?; + + // add src dir + let src_dirs = meta.get_source_dirs(); + for src_dir in src_dirs { + let src_dir_path = Path::new(&src_dir); + if !src_dir_path.exists() { + continue; + } + debug!("Add src dir: {:?}", src_dir); + tar.append_dir_all(src_dir.clone(), src_dir)?; + } + + tar.finish()?; + + std::thread::sleep(std::time::Duration::from_secs(3)); + + let size = std::fs::metadata(&file_path)?.len(); + println!("------size:{}", size); + info!("Bundle size: {}", bytesize::ByteSize::b(size)); + + let content2 = std::fs::read(file_path)?; + println!("content2.size: {}", content2.len()); + + dir.close()?; + + Ok(content2) +}