Skip to content

Commit

Permalink
feat: added deep invocation, refactored runtime/engine names
Browse files Browse the repository at this point in the history
  • Loading branch information
jsoverson committed Aug 24, 2023
1 parent 4668be7 commit 21dac6a
Show file tree
Hide file tree
Showing 76 changed files with 1,128 additions and 577 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ derive_builder = { version = "0.12", default-features = false }
dhat = { version = "0.3.2", default-features = false }
dialoguer = { version = "0.10", default-features = false }
dyn-clone = { version = "1.0", default-features = false }
either = { version = "1.9.0", default-features = false }
env_logger = { version = "0.10", default-features = false }
escargot = { version = "0.5", default-features = false }
futures = { version = "0.3", default-features = false, features = ["std"] }
Expand Down
1 change: 1 addition & 0 deletions crates/bins/wick/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ structured-output = { workspace = true }
regex = { workspace = true }
dhat = { workspace = true, optional = true }
once_cell = { workspace = true }
async-trait = { workspace = true }

[dev-dependencies]
test_bin = { workspace = true }
Expand Down
14 changes: 7 additions & 7 deletions crates/bins/wick/src/commands/config/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use anyhow::Result;
use clap::Args;
use serde_json::json;
use structured_output::StructuredOutput;
use wick_config::WickConfiguration;
use wick_host::Host;

use crate::utils::parse_config_string;
use crate::wick_host::build_component_host;
use crate::wick_host::build_host;

#[derive(Debug, Clone, Args)]
#[clap(rename_all = "kebab-case")]
Expand All @@ -24,15 +24,15 @@ pub(crate) async fn handle(
settings: wick_settings::Settings,
span: tracing::Span,
) -> Result<StructuredOutput> {
span.in_scope(|| debug!("Generate dotviz graph"));
span.in_scope(|| debug!("expand config"));
let root_config = parse_config_string(opts.component.with.as_deref())?;
let host = build_component_host(&opts.component.path, opts.oci, root_config, settings, None, None, span).await?;
let host = build_host(&opts.component.path, opts.oci, root_config, settings, None, None, span).await?;

let config = host.get_active_config();
let signature = host.get_signature(None, None)?;

let config = host.get_active_config()?;
let config = WickConfiguration::Component(config.clone());
let config_yaml = config.clone().into_v1_yaml()?;
let config_json = serde_json::to_value(&config)?;
let signature = host.get_signature()?;

let json = json!({"signature": signature, "config": config_json});
Ok(StructuredOutput::new(config_yaml, json))
Expand Down
59 changes: 45 additions & 14 deletions crates/bins/wick/src/commands/invoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ use serde_json::json;
use structured_output::StructuredOutput;
use wick_component_cli::options::DefaultCliOptions;
use wick_component_cli::parse_args;
use wick_packet::{InherentData, Packet, PacketStream};
use wick_host::Host;
use wick_packet::{Entity, InherentData, Invocation, Packet, PacketStream};

use crate::utils::{self, parse_config_string};
use crate::wick_host::build_component_host;
use crate::wick_host::build_host;

#[derive(Debug, Clone, Args)]
#[clap(rename_all = "kebab-case")]
Expand Down Expand Up @@ -57,24 +58,42 @@ pub(crate) async fn handle(
) -> Result<StructuredOutput> {
let root_config = parse_config_string(opts.component.with.as_deref())?;
let server_settings = DefaultCliOptions { ..Default::default() };
let host = build_component_host(

let host = build_host(
&opts.component.path,
opts.oci,
root_config,
settings,
opts.component.seed,
Some(server_settings),
span,
span.clone(),
)
.await?;
let operation = &opts.operation.operation_name;

let signature = host.get_signature()?;
let op_signature = signature.get_operation(operation).ok_or_else(|| {
let mut path_parts = opts.operation.operation_name.split("::").collect::<Vec<_>>();

if path_parts.is_empty() {
return Err(anyhow::anyhow!(
"Invalid operation name '{}', expected 'operation' or 'component::operation'",
opts.operation.operation_name
));
}

let (path_parts, target) = if path_parts.len() == 1 {
(None, Entity::local(path_parts[0]))
} else {
let op = path_parts.pop().unwrap();
let component = path_parts.pop().unwrap();

(Some(path_parts), Entity::operation(component, op))
};

let signature = host.get_signature(path_parts.as_deref(), Some(&target))?;

let op_signature = signature.get_operation(target.operation_id()).ok_or_else(|| {
anyhow::anyhow!(
"Could not invoke operation '{}', '{}' not found. Reported operations are [{}]",
operation,
operation,
"Operation '{}' not found, reported operations are [{}]",
target.operation_id(),
signature
.operations
.iter()
Expand All @@ -83,6 +102,7 @@ pub(crate) async fn handle(
.join(", ")
)
})?;

let op_config = parse_config_string(opts.operation.op_with.as_deref())?;

let check_stdin = if op_signature.inputs.is_empty() {
Expand Down Expand Up @@ -123,8 +143,13 @@ pub(crate) async fn handle(
// utils::print_stream_json(stream, &opts.filter, opts.short, opts.raw).await?;
// }
} else {
let args = parse_args(&opts.args, op_signature)
.map_err(|e| anyhow!("Failed to parse arguments for operation {}: {}", operation, e))?;
let args = parse_args(&opts.args, op_signature).map_err(|e| {
anyhow!(
"Failed to parse arguments for operation {}: {}",
target.operation_id(),
e
)
})?;
trace!(args= ?args, "parsed CLI arguments");
let mut packets = Vec::new();
let mut seen_ports = HashSet::new();
Expand All @@ -138,11 +163,17 @@ pub(crate) async fn handle(
debug!(cli_packets= ?packets, "wick invoke");
let stream = PacketStream::new(futures::stream::iter(packets));

let stream = host.request(operation, op_config, stream, inherent_data).await?;
let invocation = Invocation::new(Entity::server(host.namespace()), target, stream, inherent_data, &span);

let stream = host.invoke_deep(path_parts.as_deref(), invocation, op_config).await?;

utils::print_stream_json(stream, &opts.filter, opts.short, opts.raw).await?;
}
host.stop().await;

match host {
wick_host::WickHost::App(_) => {}
wick_host::WickHost::Component(host) => host.stop().await,
}

Ok(StructuredOutput::new("", json!({})))
}
4 changes: 2 additions & 2 deletions crates/bins/wick/src/commands/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde_json::json;
use structured_output::StructuredOutput;
use wick_component_cli::options::DefaultCliOptions;
use wick_config::WickConfiguration;
use wick_host::ComponentHostBuilder;
use wick_host::{ComponentHostBuilder, Host};
use wick_interface_types::Field;

use crate::utils::merge_config;
Expand Down Expand Up @@ -45,7 +45,7 @@ pub(crate) async fn handle(
let mut host = ComponentHostBuilder::default().manifest(config).span(span).build()?;

host.start_runtime(None).await?;
let mut signature = host.get_signature()?;
let mut signature = host.get_signature(None, None)?;

// If we have a name from the manifest, override the host id the component host generates.
if let Some(name) = manifest.name() {
Expand Down
9 changes: 5 additions & 4 deletions crates/bins/wick/src/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use serde_json::json;
use structured_output::StructuredOutput;
use tracing::Instrument;
use wick_config::WickConfiguration;
use wick_host::AppHostBuilder;
use wick_host::{AppHost, AppHostBuilder};

use crate::utils::{fetch_wick_config, parse_config_string, reconcile_fetch_options};
use crate::utils::{fetch_wick_config, fetch_wick_tree, parse_config_string, reconcile_fetch_options};

#[derive(Debug, Clone, Args)]
#[clap(rename_all = "kebab-case")]
Expand Down Expand Up @@ -51,7 +51,7 @@ pub(crate) async fn handle(
lockdown_config.set_env(env.clone());
let lockdown_config = lockdown_config.finish()?.try_lockdown_config()?;

let tree = WickConfiguration::fetch_tree(&opts.component.path, runtime_config, env, options.clone()).await?;
let tree = fetch_wick_tree(&opts.component.path, options.clone(), runtime_config, span.clone()).await?;
let mut flattened = tree.flatten();
wick_config::lockdown::assert_restrictions(&flattened, &lockdown_config)?;

Expand All @@ -66,11 +66,12 @@ pub(crate) async fn handle(

let mut host = AppHostBuilder::default()
.manifest(app_config.clone())
.runtime(AppHost::build_runtime(&app_config, opts.component.seed, span.clone()).await?)
.span(span.clone())
.build()?;

if !opts.dryrun {
host.start(opts.component.seed)?;
host.start()?;
span.in_scope(|| debug!("Waiting on triggers to finish..."));

host.wait_for_done().instrument(span.clone()).await?;
Expand Down
55 changes: 34 additions & 21 deletions crates/bins/wick/src/wick_host.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
use std::path::PathBuf;
use std::collections::HashMap;

use anyhow::Result;
use seeded_random::Seed;
use tracing::Span;
use wick_component_cli::options::DefaultCliOptions;
use wick_config::WickConfiguration;
use wick_host::{ComponentHost, ComponentHostBuilder};
use wick_host::{AppHost, AppHostBuilder, ComponentHostBuilder, WickHost};
use wick_packet::RuntimeConfig;

use crate::options::oci::OciOptions as WickOciOptions;
use crate::utils::{get_auth_for_scope, merge_config};

pub(crate) async fn build_component_host(
pub(crate) async fn build_host(
path: &str,
oci: WickOciOptions,
root_config: Option<RuntimeConfig>,
settings: wick_settings::Settings,
seed: Option<u64>,
server_settings: Option<DefaultCliOptions>,
span: Span,
) -> Result<ComponentHost> {
) -> Result<WickHost> {
let configured_creds = settings.credentials.iter().find(|c| path.starts_with(&c.scope));

let (username, password) = get_auth_for_scope(configured_creds, oci.username.as_deref(), oci.password.as_deref());
Expand All @@ -28,29 +28,42 @@ pub(crate) async fn build_component_host(
let mut fetch_opts: wick_oci_utils::OciOptions = oci.clone().into();
fetch_opts.set_username(username).set_password(password);

let pb = PathBuf::from(path);

if !pb.exists() {
fetch_opts.set_cache_dir(env.global().cache().clone());
} else {
let mut path_dir = pb.clone();
path_dir.pop();
fetch_opts.set_cache_dir(path_dir.join(env.local().cache()));
};
fetch_opts.set_cache_dir(env.global().cache().clone());

let mut manifest = WickConfiguration::fetch(path, fetch_opts).await?;
manifest.set_root_config(root_config);
let manifest = manifest.finish()?.try_component_config()?;
let host = match manifest.manifest() {
WickConfiguration::Component(_) => {
let manifest = manifest.finish()?.try_component_config()?;

let manifest = merge_config(&manifest, &oci, server_settings);
let manifest = merge_config(&manifest, &oci, server_settings);

let mut host = ComponentHostBuilder::default()
.id(manifest.name().map_or_else(|| "component".to_owned(), |s| s.clone()))
.manifest(manifest)
.span(span)
.build()?;
let mut host = ComponentHostBuilder::default()
.id(manifest.name().map_or_else(|| "component".to_owned(), |s| s.clone()))
.manifest(manifest)
.span(span)
.build()?;

host.start_runtime(seed.map(Seed::unsafe_new)).await?;
host.start_runtime(seed.map(Seed::unsafe_new)).await?;
WickHost::Component(host)
}
WickConfiguration::App(_) => {
let env: HashMap<String, String> = std::env::vars().collect();
manifest.set_env(env);
let app_config = manifest.finish()?.try_app_config()?;
let mut host = AppHostBuilder::default();
let host = host
.runtime(AppHost::build_runtime(&app_config, seed, span.clone()).await?)
.manifest(app_config)
.span(span)
.build()?;

WickHost::App(host)
}
_ => {
bail!("Invalid manifest type: {}", manifest.manifest().kind());
}
};

Ok(host)
}
1 change: 1 addition & 0 deletions crates/bins/wick/tests/invoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ static DIR: &str = "invoke";
#[rstest::rstest]
#[case("v1-wasmrs.toml")]
#[case("stdin.toml")]
#[case("app.toml")]
fn wick_invoke(#[case] file: &'static str) {
let kind = "unit";
let file = format!("tests/{}/{}/{}", DIR, kind, file);
Expand Down
59 changes: 59 additions & 0 deletions crates/bins/wick/tests/invoke/unit/app-cli.wick
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
kind: wick/component@v1
name: file-reader-cli-adapter
import:
- name: wasi_fs
component:
kind: wick/component/manifest@v1
ref: ../../../../../../examples/components/wasi-fs/component.wick
with:
root: '{{ ctx.root_config.root }}'
- name: log
component:
kind: wick/component/manifest@v1
ref: registry.candle.dev/common/log:0.2.0
component:
kind: wick/component/composite@v1
with:
- name: root
type: string
operations:
- name: main
inputs:
- name: args
type: 'string[]'
- name: interactive
type: cli::Interactive
outputs:
- name: code
type: u32
uses:
- name: GATE
operation: core::switch
with:
outputs:
- name: code
type: u32
cases:
- case: true
do: self::main::exit_ok
default: self::main::exit_err
flow:
- <>.args.1 -> wasi_fs::read_string -> log::string -> GATE.match
- GATE -> <>.code
operations:
- name: exit_ok
uses:
- name: SENDER
operation: core::sender
with:
output: 0
flow:
- SENDER.output -> <>.code
- name: exit_err
uses:
- name: SENDER
operation: core::sender
with:
output: 1
flow:
- SENDER.output -> <>.code
Loading

0 comments on commit 21dac6a

Please # to comment.