diff --git a/Cargo.lock b/Cargo.lock index 8a9a5586f..c1794accd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5184,6 +5184,7 @@ dependencies = [ "indexmap", "percent-encoding", "serde", + "spin-app", "spin-testing", "tracing", ] diff --git a/crates/app/src/lib.rs b/crates/app/src/lib.rs index cdb80ae86..3f874917f 100644 --- a/crates/app/src/lib.rs +++ b/crates/app/src/lib.rs @@ -24,6 +24,15 @@ pub use host_component::DynamicHostComponent; pub use locked::Variable; pub use metadata::MetadataKey; +/// MetadataKey for extracting the application name. +pub const APP_NAME_KEY: MetadataKey = MetadataKey::new("name"); +/// MetadataKey for extracting the application version. +pub const APP_VERSION_KEY: MetadataKey = MetadataKey::new("version"); +/// MetadataKey for extracting the bindle version. +pub const BINDLE_VERSION_KEY: MetadataKey = MetadataKey::new("bindle_version"); +/// MetadataKey for extracting the OCI image digest. +pub const OCI_IMAGE_DIGEST_KEY: MetadataKey = MetadataKey::new("oci_image_digest"); + /// A trait for implementing the low-level operations needed to load an [`App`]. // TODO(lann): Should this migrate to spin-loader? #[async_trait] diff --git a/crates/http/Cargo.toml b/crates/http/Cargo.toml index 9d4013c00..3b790be20 100644 --- a/crates/http/Cargo.toml +++ b/crates/http/Cargo.toml @@ -12,6 +12,7 @@ indexmap = "1" percent-encoding = "2" serde = { version = "1.0", features = ["derive"] } tracing = { workspace = true } +spin-app = { path = "../app" } [dev-dependencies] spin-testing = { path = "../testing" } diff --git a/crates/http/src/app_info.rs b/crates/http/src/app_info.rs new file mode 100644 index 000000000..658b2fbc9 --- /dev/null +++ b/crates/http/src/app_info.rs @@ -0,0 +1,31 @@ +use serde::{Deserialize, Serialize}; +use spin_app::{App, APP_NAME_KEY, APP_VERSION_KEY, BINDLE_VERSION_KEY, OCI_IMAGE_DIGEST_KEY}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct AppInfo { + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub version: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub bindle_version: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub oci_image_digest: Option, +} + +impl AppInfo { + pub fn new(app: &App) -> Self { + let name = app + .get_metadata(APP_NAME_KEY) + .unwrap_or_default() + .unwrap_or_default(); + let version = app.get_metadata(APP_VERSION_KEY).unwrap_or_default(); + let bindle_version = app.get_metadata(BINDLE_VERSION_KEY).unwrap_or_default(); + let oci_image_digest = app.get_metadata(OCI_IMAGE_DIGEST_KEY).unwrap_or_default(); + Self { + name, + version, + bindle_version, + oci_image_digest, + } + } +} diff --git a/crates/http/src/lib.rs b/crates/http/src/lib.rs index ddbf52473..15eccbe06 100644 --- a/crates/http/src/lib.rs +++ b/crates/http/src/lib.rs @@ -1,3 +1,4 @@ +pub mod app_info; pub mod config; pub mod routes; pub mod wagi; diff --git a/crates/trigger-http/src/lib.rs b/crates/trigger-http/src/lib.rs index 4f0ce9181..26194ba83 100644 --- a/crates/trigger-http/src/lib.rs +++ b/crates/trigger-http/src/lib.rs @@ -27,13 +27,11 @@ use serde::{Deserialize, Serialize}; use spin_app::{AppComponent, MetadataKey}; use spin_core::Engine; use spin_http::{ + app_info::AppInfo, config::{HttpExecutorType, HttpTriggerConfig}, routes::{RoutePattern, Router}, }; -use spin_trigger::{ - locked::{BINDLE_VERSION_KEY, DESCRIPTION_KEY, VERSION_KEY}, - EitherInstancePre, TriggerAppEngine, TriggerExecutor, -}; +use spin_trigger::{locked::DESCRIPTION_KEY, EitherInstancePre, TriggerAppEngine, TriggerExecutor}; use tls_listener::TlsListener; use tokio::net::{TcpListener, TcpStream}; use tokio_rustls::server::TlsStream; @@ -269,11 +267,7 @@ impl HttpTrigger { /// Returns spin status information. fn app_info(&self) -> Result> { - let info = AppInfo { - name: self.engine.app_name.clone(), - version: self.engine.app().get_metadata(VERSION_KEY)?, - bindle_version: self.engine.app().get_metadata(BINDLE_VERSION_KEY)?, - }; + let info = AppInfo::new(self.engine.app()); let body = serde_json::to_vec_pretty(&info)?; Ok(Response::builder() .header("content-type", "application/json") @@ -366,15 +360,6 @@ impl HttpTrigger { } } -#[derive(Debug, Serialize, Deserialize)] -pub struct AppInfo { - pub name: String, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub version: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub bindle_version: Option, -} - fn parse_listen_addr(addr: &str) -> anyhow::Result { let addrs: Vec = addr.to_socket_addrs()?.collect(); // Prefer 127.0.0.1 over e.g. [::1] because CHANGE IS HARD