Conversation
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
| .file_name() | ||
| .context("Invalid project path")? | ||
| .to_str() | ||
| .context("Project name must be valid UTF-8")?; |
There was a problem hiding this comment.
might want to do a bit more validation here on the name? I am not sure what makes up a valid project name but we would want to strip strings from beginning end etc. Maybe special characters?
| use anyhow::{Context, Result, ensure}; | ||
| use clap::Parser; | ||
|
|
||
| const HYPERLIGHT_VERSION: &str = "0.13"; |
There was a problem hiding this comment.
can we take this as input so we don't need to bump the tool everytime?
There was a problem hiding this comment.
I thought about this, but I'm not sure it makes sense, since we might have breaking changes. I think it's better we just bump it manually and at that time make sure the template is up to date. Perhaps we could do a quick check to make sure the version is the latest released version and add a warning if not to make users aware they are using an old version. Although this does require a cargo-hyperlight release for every hyperlight release, which I am unsure if we currently do.
jsturtevant
left a comment
There was a problem hiding this comment.
I think this will make it much easier to get started and be successful! Did you consider any existing templating libraries in the eco system? This is pretty straight forward for now but there are often a lot of edge cases for projects that are larger.
Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com>
I thought this was simple enough so didn't really consider it, but happy to use something if you have ideas |
| [dependencies] | ||
| hyperlight-guest = "{version}" | ||
| hyperlight-guest-bin = "{version}" | ||
| hyperlight-common = { version = "{version}", default-features = false } |
There was a problem hiding this comment.
We should fix hyperlight-guest to re-export the things from common needed for the most common workflows.
Ideally we should only depend on one crate, the others should be re-export, so that we don't force users to keep versions in sync.
jprendes
left a comment
There was a problem hiding this comment.
This looks great. It will be very useful.
I left a few comments, mostly with my preferences, feel free to dismiss if you don't agree.
| #![no_std] | ||
| #![no_main] | ||
| extern crate alloc; | ||
| extern crate hyperlight_guest_bin; |
There was a problem hiding this comment.
you don't need this, right?
| COUNTER.fetch_add(1, Ordering::Relaxed); | ||
| Ok(COUNTER.load(Ordering::Relaxed)) |
There was a problem hiding this comment.
| COUNTER.fetch_add(1, Ordering::Relaxed); | |
| Ok(COUNTER.load(Ordering::Relaxed)) | |
| let old = COUNTER.fetch_add(1, Ordering::Relaxed); | |
| Ok(old + 1) |
| let guest_path = ["debug", "release"] | ||
| .iter() | ||
| .map(|p| base.join(p).join("{guest_name}")) | ||
| .find(|p| p.exists()) | ||
| .expect( | ||
| "guest binary not found - build it first with: cd ../guest && cargo hyperlight build", | ||
| ); |
There was a problem hiding this comment.
I would either use std::env::args or a use debug, to make the example as minimal as possible
| // Create a sandbox from the guest binary. It starts uninitialized so you | ||
| // can register host functions before the guest begins executing. | ||
| let mut sandbox = UninitializedSandbox::new( | ||
| GuestBinary::FilePath(guest_path.display().to_string()), |
There was a problem hiding this comment.
:-O GuestBinary::FilePath takes a String and not a PathBuf?? We must fix that (not all valid paths are valid utf-8 valid in all platforms)
| let days = [ | ||
| "Monday", | ||
| "Tuesday", | ||
| "Wednesday", | ||
| "Thursday", | ||
| "Friday", | ||
| "Saturday", | ||
| "Sunday", | ||
| ]; | ||
| let secs = SystemTime::now() | ||
| .duration_since(UNIX_EPOCH) | ||
| .expect("system clock before Unix epoch") | ||
| .as_secs(); | ||
| // January 1, 1970 was a Thursday (day index 3 when Monday = 0). | ||
| Ok(days[((secs / (60 * 60 * 24) + 3) % 7) as usize].to_string()) |
There was a problem hiding this comment.
I would have it allways return "Monday", to keep it as minimal as possible and not distract from the logic we really care about
maybe with a funny comment
// It's always mondays here, sorry Garfield!
or similar, so that people don't think it's a bug
| use hyperlight_host::{GuestBinary, MultiUseSandbox, UninitializedSandbox}; | ||
|
|
||
| fn main() -> hyperlight_host::Result<()> { | ||
| // TODO: support aarch64-hyperlight-none when aarch64 guests are supported. |
There was a problem hiding this comment.
Remove the TODO from here, we don't want a TODO in the generated file.
This is not a TODO for the user, it's for us.
Maybe do something like
"../target/{arch}-hyperlight-none"
and we put the TODO when we replace it in the template
.replace("{arch}", "x86_64") // TODO: ...
| /// Generate only a guest project instead of both host and guest. | ||
| #[arg(long, default_value_t = false)] | ||
| guest_only: bool, |
There was a problem hiding this comment.
how about
--no-host
and
--no-guest
specifying both would be incompatible, I think you can use #[arg(conflicts_with = "no_host")]
| struct ScaffoldCli { | ||
| /// Path to create the project at. The directory name is used as the crate | ||
| /// name (like `cargo new`). | ||
| path: PathBuf, |
There was a problem hiding this comment.
if this is similar to cargo new, why no call this "new"? cargo hyperlight new
| std::process::exit(1); | ||
| } | ||
| } | ||
| Some(a) if a == "scaffold" => { |
There was a problem hiding this comment.
should we use "new" or "init" like the cargo subcommands?
| // Called once when the guest binary is loaded, during evolve(). | ||
| // Use this for initialization. | ||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn hyperlight_main() {} | ||
|
|
||
| // Called when the host calls a guest function not handled by #[guest_function]. | ||
| // You usually don't need to modify this. | ||
| #[unsafe(no_mangle)] | ||
| pub fn guest_dispatch_function(function_call: FunctionCall) -> Result<Vec<u8>> { | ||
| let function_name = function_call.function_name; | ||
| bail!(ErrorCode::GuestFunctionNotFound => "{function_name}"); | ||
| } |
There was a problem hiding this comment.
I need to work on this so that these two functions are optional :-)
Initial draft for a scaffolding command to create a ready-to-compile/run hyperlight project (with guest). Currently just targets 0.13. Might be useful in the future to decouple the templating from the template, so we can have multiple versions etc etc, and releasing a new hyperlight version won't need a new cargo-hyperlight release.
I plan to include this command in main hyperlight repo docs/markdown in something like the README.md or getting-started.md docs.
I'm particularly looking for feedback on the actual templated code. I made it slightly longer than I initially intended, but I think it makes sense given it shows off a lot important hyperlight features. I also think it makes sense to add a wit host+guest to this command as well, but can do that later