diff --git a/.github/workflows/integration_test.yml b/.github/workflows/aster_ci.yml similarity index 67% rename from .github/workflows/integration_test.yml rename to .github/workflows/aster_ci.yml index fa63a2b70..096fc6fdf 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/aster_ci.yml @@ -1,4 +1,4 @@ -name: Integration test +name: Asterinas CI on: pull_request: @@ -7,7 +7,43 @@ on: - main jobs: - test: + aster-lint: + runs-on: ubuntu-latest + timeout-minutes: 10 + container: asterinas/asterinas:0.3.0 + steps: + - run: echo "Running in asterinas/asterinas:0.3.0" + + - uses: actions/checkout@v3 + + - run: make install_osdk + + - name: Check + id: check + run: make check + + aster-unit-test: + runs-on: ubuntu-latest + timeout-minutes: 15 + container: asterinas/asterinas:0.3.0 + steps: + - run: echo "Running in asterinas/asterinas:0.3.0" + + - uses: actions/checkout@v3 + + - run: make install_osdk + + - name: Usermode Unit test + id: usermode_unit_test + run: make test + + - name: Ktest Unit Test + id: ktest_unit_test + run: make update_initramfs && make ktest + + # TODO: add component check. + + aster-integration-test: runs-on: ubuntu-latest timeout-minutes: 30 container: asterinas/asterinas:0.3.1 @@ -49,4 +85,3 @@ jobs: - name: Regression Test (MicroVM) id: regression_test_linux run: make run AUTO_TEST=regression ENABLE_KVM=0 QEMU_MACHINE=microvm RELEASE_MODE=1 - \ No newline at end of file diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 745d9711f..7d6937d6d 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -6,7 +6,7 @@ on: paths: - VERSION branches: - - 'main' + - main jobs: docker: diff --git a/.github/workflows/osdk_ci.yml b/.github/workflows/osdk_ci.yml index f6aa35a5a..66675791b 100644 --- a/.github/workflows/osdk_ci.yml +++ b/.github/workflows/osdk_ci.yml @@ -2,6 +2,8 @@ name: OSDK CI on: pull_request: + paths: + - osdk/** push: branches: - main @@ -16,9 +18,9 @@ jobs: - uses: actions/checkout@v3 - - name: Format check - id: fmt_check - run: cd osdk && cargo check && cargo clippy + - name: Lint + id: lint + run: cd osdk && cargo clippy -- -D warnings - name: Unit test id: unit_test diff --git a/.github/workflows/osdk_publish.yml b/.github/workflows/osdk_publish.yml new file mode 100644 index 000000000..028bf1d91 --- /dev/null +++ b/.github/workflows/osdk_publish.yml @@ -0,0 +1,23 @@ +name: OSDK Publish + +on: + workflow_dispatch: + push: + paths: + - osdk/Cargo.toml + branches: + - main + +jobs: + osdk-publish: + runs-on: ubuntu-latest + timeout-minutes: 10 + container: asterinas/asterinas:0.3.0 + steps: + - uses: actions/checkout@v3 + - uses: katyo/publish-crates@v2 + with: + path: './osdk' + args: --no-verify + registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }} + ignore-unpublished-changes: true diff --git a/README.md b/README.md index 7ef45c34a..1d36f00ca 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ A secure, fast, and general-purpose OS kernel written in Rust and compatible with Linux

+[![Asterinas CI](https://github.com/asterinas/asterinas/actions/workflows/aster_ci.yml/badge.svg)](https://github.com/asterinas/asterinas/actions/workflows/aster_ci.yml) + English | [中文版](README_CN.md) ## Introducing Asterinas diff --git a/README_CN.md b/README_CN.md index bd5fafd98..1334b4e2f 100644 --- a/README_CN.md +++ b/README_CN.md @@ -3,6 +3,8 @@ 一个安全、快速、通用的操作系统内核,使用Rust编写,并与Linux兼容

+[![Asterinas CI](https://github.com/asterinas/asterinas/actions/workflows/aster_ci.yml/badge.svg)](https://github.com/asterinas/asterinas/actions/workflows/aster_ci.yml) + [English](README.md) | 中文版 ## 初见星绽 diff --git a/osdk/.gitignore b/osdk/.gitignore index 2c54a7699..73fab072c 100644 --- a/osdk/.gitignore +++ b/osdk/.gitignore @@ -8,6 +8,3 @@ target/ # MSVC Windows builds of rustc generate these, which store debugging information *.pdb - -# Integration test generated files -workspace_* \ No newline at end of file diff --git a/osdk/Cargo.lock b/osdk/Cargo.lock index d41784003..a1d50f5d6 100644 --- a/osdk/Cargo.lock +++ b/osdk/Cargo.lock @@ -88,9 +88,9 @@ checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "bstr" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", "regex-automata", @@ -119,7 +119,7 @@ dependencies = [ [[package]] name = "cargo-osdk" -version = "0.1.5" +version = "0.2.0" dependencies = [ "assert_cmd", "clap", diff --git a/osdk/Cargo.toml b/osdk/Cargo.toml index c3e1f93c3..0113bf499 100644 --- a/osdk/Cargo.toml +++ b/osdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-osdk" -version = "0.1.5" +version = "0.2.0" edition = "2021" description = "Accelerate OS development with Asterinas OSDK" license = "MPL-2.0" diff --git a/osdk/README.md b/osdk/README.md index d5507c63e..533354cc0 100644 --- a/osdk/README.md +++ b/osdk/README.md @@ -1,6 +1,7 @@ # Accelerate OS development with Asterinas OSDK [![Crates.io](https://img.shields.io/crates/v/cargo-osdk.svg)](https://crates.io/crates/cargo-osdk) +[![OSDK CI](https://github.com/asterinas/asterinas/actions/workflows/osdk_ci.yml/badge.svg)](https://github.com/asterinas/asterinas/actions/workflows/osdk_ci.yml) ### What is it? diff --git a/osdk/rust-toolchain.toml b/osdk/rust-toolchain.toml index 65d0da22a..31578d3bf 100644 --- a/osdk/rust-toolchain.toml +++ b/osdk/rust-toolchain.toml @@ -1,3 +1,2 @@ [toolchain] -channel = "nightly-2023-12-01" -components = ["rust-src", "rustc-dev", "llvm-tools-preview"] \ No newline at end of file +channel = "stable" \ No newline at end of file diff --git a/osdk/src/base_crate/Cargo.toml.template b/osdk/src/base_crate/Cargo.toml.template new file mode 100644 index 000000000..fd3075419 --- /dev/null +++ b/osdk/src/base_crate/Cargo.toml.template @@ -0,0 +1,4 @@ +[package] +name = "#NAME#" +version = "#VERSION#" +edition = "2021" diff --git a/osdk/src/base_crate/mod.rs b/osdk/src/base_crate/mod.rs index 51a8b7766..d9bb61aa2 100644 --- a/osdk/src/base_crate/mod.rs +++ b/osdk/src/base_crate/mod.rs @@ -4,9 +4,7 @@ //! It will depend on the kernel crate. //! -use std::{fs, path::Path, process, process::Command, str::FromStr}; - -use crate::{error::Errno, error_msg}; +use std::{fs, path::Path, str::FromStr}; pub fn new_base_crate( base_crate_path: impl AsRef, @@ -17,17 +15,32 @@ pub fn new_base_crate( std::fs::remove_dir_all(&base_crate_path).unwrap(); } - let mut cmd = Command::new("cargo"); - cmd.arg("new").arg("--bin").arg(base_crate_path.as_ref()); - cmd.arg("--vcs").arg("none"); + let dep_crate_version = { + let cargo_toml = dep_crate_path.as_ref().join("Cargo.toml"); + let cargo_toml = fs::read_to_string(cargo_toml).unwrap(); + let cargo_toml: toml::Value = toml::from_str(&cargo_toml).unwrap(); + let dep_version = cargo_toml + .get("package") + .unwrap() + .as_table() + .unwrap() + .get("version") + .unwrap() + .as_str() + .unwrap(); + dep_version.to_string() + }; - if !cmd.status().unwrap().success() { - error_msg!( - "Failed to create base crate at: {:#?}", - base_crate_path.as_ref() - ); - process::exit(Errno::CreateBaseCrate as _); - } + // Create the directory + fs::create_dir_all(&base_crate_path).unwrap(); + // Create the src directory + fs::create_dir_all(base_crate_path.as_ref().join("src")).unwrap(); + + // Write Cargo.toml + let cargo_toml = include_str!("Cargo.toml.template"); + let cargo_toml = cargo_toml.replace("#NAME#", &(dep_crate_name.to_string() + "-osdk-bin")); + let cargo_toml = cargo_toml.replace("#VERSION#", &dep_crate_version); + fs::write(base_crate_path.as_ref().join("Cargo.toml"), cargo_toml).unwrap(); // Set the current directory to the target osdk directory let original_dir = std::env::current_dir().unwrap(); @@ -44,7 +57,7 @@ pub fn new_base_crate( // Overrite the main.rs file let main_rs = include_str!("main.rs.template"); // Replace all occurence of `#TARGET_NAME#` with the `dep_crate_name` - let main_rs = main_rs.replace("#TARGET_NAME#", &dep_crate_name.replace("-", "_")); + let main_rs = main_rs.replace("#TARGET_NAME#", &dep_crate_name.replace('-', "_")); fs::write("src/main.rs", main_rs).unwrap(); // Add dependencies to the Cargo.toml @@ -54,7 +67,7 @@ pub fn new_base_crate( copy_manifest_configurations(base_crate_path); // Get back to the original directory - std::env::set_current_dir(&original_dir).unwrap(); + std::env::set_current_dir(original_dir).unwrap(); } fn add_manifest_dependency(crate_name: &str, crate_path: impl AsRef) { @@ -65,6 +78,14 @@ fn add_manifest_dependency(crate_name: &str, crate_path: impl AsRef) { toml::from_str(&content).unwrap() }; + // Check if "dependencies" key exists, create it if it doesn't + if !manifest.contains_key("dependencies") { + manifest.insert( + "dependencies".to_string(), + toml::Value::Table(toml::Table::new()), + ); + } + let dependencies = manifest.get_mut("dependencies").unwrap(); let dep = toml::Table::from_str(&format!( diff --git a/osdk/src/bundle.rs b/osdk/src/bundle.rs index b827e0ea0..fa0fc04ae 100644 --- a/osdk/src/bundle.rs +++ b/osdk/src/bundle.rs @@ -44,7 +44,7 @@ impl Bundle { #[allow(dead_code)] pub fn load(path: impl AsRef) -> Self { let manifest_file_path = path.as_ref().join("bundle.toml"); - let manifest_file_content = std::fs::read_to_string(&manifest_file_path).unwrap(); + let manifest_file_content = std::fs::read_to_string(manifest_file_path).unwrap(); let manifest: BundleManifest = toml::from_str(&manifest_file_content).unwrap(); // TODO: check integrity of the loaded bundle. Self { @@ -142,7 +142,7 @@ impl Bundle { } let file_name = vm_image.path.file_name().unwrap(); let copied_path = self.path.join(file_name); - std::fs::copy(&vm_image.path, &copied_path).unwrap(); + std::fs::copy(&vm_image.path, copied_path).unwrap(); self.manifest.vm_image = Some(AsterVmImage { path: file_name.into(), typ: vm_image.typ.clone(), @@ -158,13 +158,13 @@ impl Bundle { } let file_name = aster_bin.path.file_name().unwrap(); let copied_path = self.path.join(file_name); - std::fs::copy(&aster_bin.path, &copied_path).unwrap(); + std::fs::copy(&aster_bin.path, copied_path).unwrap(); self.manifest.aster_bin = Some(AsterBin { path: file_name.into(), typ: aster_bin.typ.clone(), version: aster_bin.version.clone(), sha256sum: aster_bin.sha256sum.clone(), - stripped: aster_bin.stripped.clone(), + stripped: aster_bin.stripped, }); self.write_manifest_content(); } @@ -172,7 +172,7 @@ impl Bundle { fn write_manifest_content(&self) { let manifest_file_content = toml::to_string(&self.manifest).unwrap(); let manifest_file_path = self.path.join("bundle.toml"); - std::fs::write(&manifest_file_path, manifest_file_content).unwrap(); + std::fs::write(manifest_file_path, manifest_file_content).unwrap(); } } diff --git a/osdk/src/cli.rs b/osdk/src/cli.rs index b0d260ddf..13d629034 100644 --- a/osdk/src/cli.rs +++ b/osdk/src/cli.rs @@ -115,7 +115,7 @@ pub struct TestArgs { pub struct CargoArgs { #[arg( long, - help = "The Cargo build profile (built-in candidates are 'debug', 'release' and 'dev')", + help = "The Cargo build profile (built-in candidates are 'debug', 'release', 'dev' and 'bench')", default_value = "dev" )] pub profile: String, diff --git a/osdk/src/commands/build/bin.rs b/osdk/src/commands/build/bin.rs index 4618e3ad7..a330ffde5 100644 --- a/osdk/src/commands/build/bin.rs +++ b/osdk/src/commands/build/bin.rs @@ -49,7 +49,7 @@ pub fn make_install_bzimage( setup_install_dir.join("bin").join("linux-bzimage-setup") }; // Make the `bzImage`-compatible kernel image and place it in the boot directory. - let install_path = install_dir.as_ref().join(&target_name); + let install_path = install_dir.as_ref().join(target_name); info!("Building bzImage"); println!("install_path: {:?}", install_path); make_bzimage(&install_path, image_type, &aster_elf.path, &setup_bin); diff --git a/osdk/src/commands/build/grub.rs b/osdk/src/commands/build/grub.rs index 8eafa28cb..bdf90a345 100644 --- a/osdk/src/commands/build/grub.rs +++ b/osdk/src/commands/build/grub.rs @@ -25,7 +25,7 @@ pub fn create_bootdev_image( // Clear or make the iso dir. if iso_root.exists() { - fs::remove_dir_all(&iso_root).unwrap(); + fs::remove_dir_all(iso_root).unwrap(); } fs::create_dir_all(iso_root.join("boot").join("grub")).unwrap(); @@ -41,12 +41,12 @@ pub fn create_bootdev_image( // Make the kernel image and place it in the boot directory. match protocol { BootProtocol::LinuxLegacy32 | BootProtocol::LinuxEfiHandover64 => { - make_install_bzimage(&iso_root.join("boot"), &target_dir, aster_bin, protocol); + make_install_bzimage(iso_root.join("boot"), &target_dir, aster_bin, protocol); } BootProtocol::Multiboot | BootProtocol::Multiboot2 => { // Copy the kernel image to the boot directory. let target_path = iso_root.join("boot").join(&target_name); - fs::copy(&aster_bin.path, &target_path).unwrap(); + fs::copy(&aster_bin.path, target_path).unwrap(); } }; @@ -63,7 +63,7 @@ pub fn create_bootdev_image( protocol, ); let grub_cfg_path = iso_root.join("boot").join("grub").join("grub.cfg"); - fs::write(&grub_cfg_path, grub_cfg).unwrap(); + fs::write(grub_cfg_path, grub_cfg).unwrap(); // Make the boot device CDROM image using `grub-mkrescue`. let iso_path = &target_dir.as_ref().join(target_name.to_string() + ".iso"); @@ -109,11 +109,11 @@ fn generate_grub_cfg( let grub_cfg = grub_cfg.replace("#KERNEL_COMMAND_LINE#", kcmdline); // Replace the grub commands according to the protocol selected. let aster_bin_path_on_device = PathBuf::from("/boot") - .join(&target_name) + .join(target_name) .into_os_string() .into_string() .unwrap(); - let grub_cfg = match protocol { + match protocol { BootProtocol::Multiboot => grub_cfg .replace("#GRUB_CMD_KERNEL#", "multiboot") .replace("#KERNEL#", &aster_bin_path_on_device) @@ -147,9 +147,7 @@ fn generate_grub_cfg( "".to_owned() }, ), - }; - - grub_cfg + } } fn get_grub_mkrescue_version(grub_mkrescue: &PathBuf) -> String { diff --git a/osdk/src/commands/build/mod.rs b/osdk/src/commands/build/mod.rs index 2b58aceb4..1ef410ad7 100644 --- a/osdk/src/commands/build/mod.rs +++ b/osdk/src/commands/build/mod.rs @@ -29,9 +29,9 @@ pub fn execute_build_command(config: &BuildConfig) { std::fs::create_dir_all(&osdk_target_directory).unwrap(); } let target_info = get_current_crate_info(); - let bundle_path = osdk_target_directory.join(&target_info.name); + let bundle_path = osdk_target_directory.join(target_info.name); - let _bundle = create_base_and_build(&bundle_path, &osdk_target_directory, &config); + let _bundle = create_base_and_build(bundle_path, &osdk_target_directory, config); } pub fn create_base_and_build( @@ -43,12 +43,12 @@ pub fn create_base_and_build( new_base_crate( &base_crate_path, &get_current_crate_info().name, - &get_current_crate_info().path, + get_current_crate_info().path, ); let original_dir = std::env::current_dir().unwrap(); std::env::set_current_dir(&base_crate_path).unwrap(); - let bundle = do_build(&bundle_path, &osdk_target_directory, &config); - std::env::set_current_dir(&original_dir).unwrap(); + let bundle = do_build(&bundle_path, &osdk_target_directory, config); + std::env::set_current_dir(original_dir).unwrap(); bundle } @@ -92,7 +92,7 @@ pub fn do_build( &osdk_target_directory, &aster_elf, config.manifest.initramfs.as_ref(), - &config, + config, ); bundle.add_vm_image(&bootdev_image); } @@ -105,6 +105,7 @@ fn build_kernel_elf(args: &CargoArgs) -> AsterBin { let target_json_path = PathBuf::from_str("x86_64-custom.json").unwrap(); let mut command = cargo(); + command.env_remove("RUSTUP_TOOLCHAIN"); command.arg("build").arg("--target").arg(&target_json_path); command.args(COMMON_CARGO_ARGS); command.arg("--profile=".to_string() + &args.profile); @@ -114,8 +115,8 @@ fn build_kernel_elf(args: &CargoArgs) -> AsterBin { process::exit(Errno::ExecuteCommand as _); } - let aster_bin_path = PathBuf::from(target_directory) - .join(target_json_path.file_stem().unwrap().to_str().unwrap()); + let aster_bin_path = + target_directory.join(target_json_path.file_stem().unwrap().to_str().unwrap()); let aster_bin_path = if args.profile == "dev" { aster_bin_path.join("debug") } else { diff --git a/osdk/src/commands/new/mod.rs b/osdk/src/commands/new/mod.rs index e7bc92c73..00ca1cad4 100644 --- a/osdk/src/commands/new/mod.rs +++ b/osdk/src/commands/new/mod.rs @@ -77,7 +77,7 @@ fn create_osdk_manifest(cargo_metadata: &serde_json::Value) { // The apt OVMF repo installs to `/usr/share/OVMF` fs::write( osdk_manifest_path, - r#" + r#"\ [boot] ovmf = "/usr/share/OVMF" [qemu] diff --git a/osdk/src/commands/run.rs b/osdk/src/commands/run.rs index 7fa683dc6..b5e3f3447 100644 --- a/osdk/src/commands/run.rs +++ b/osdk/src/commands/run.rs @@ -18,10 +18,10 @@ pub fn execute_run_command(config: &RunConfig) { // TODO: Check if the bundle is already built and compatible with the run configuration. let bundle = create_base_and_build( - &default_bundle_directory, + default_bundle_directory, &osdk_target_directory, &required_build_config, ); - bundle.run(&config); + bundle.run(config); } diff --git a/osdk/src/commands/test.rs b/osdk/src/commands/test.rs index 22ad27710..a2d43a408 100644 --- a/osdk/src/commands/test.rs +++ b/osdk/src/commands/test.rs @@ -19,7 +19,7 @@ pub fn execute_test_command(config: &TestConfig) { let ktest_test_whitelist = match &config.test_name { Some(name) => format!(r#"Some(&["{}"])"#, name), - None => format!(r#"None"#), + None => r#"None"#.to_string(), }; let mut ktest_crate_whitelist = vec![current_crate.name]; @@ -54,12 +54,12 @@ pub static KTEST_CRATE_WHITELIST: Option<&[&str]> = Some(&{:#?}); // Add `--cfg ktest` to RUSTFLAGS std::env::set_var("RUSTFLAGS", "--cfg ktest"); let bundle = do_build( - &default_bundle_directory, + default_bundle_directory, &osdk_target_directory, &required_build_config, ); std::env::remove_var("RUSTFLAGS"); - std::env::set_current_dir(&original_dir).unwrap(); + std::env::set_current_dir(original_dir).unwrap(); let required_run_config = RunConfig { manifest: required_build_config.manifest.clone(), diff --git a/osdk/src/config_manager/manifest.rs b/osdk/src/config_manager/manifest.rs index e20572744..98a28c530 100644 --- a/osdk/src/config_manager/manifest.rs +++ b/osdk/src/config_manager/manifest.rs @@ -158,3 +158,16 @@ fn check_cfg(cfg: &str) { lazy_static::lazy_static! { pub static ref SELECT_REGEX: Regex = Regex::new(r#"cfg\(select="(?P