Skip to content

Commit a51d601

Browse files
committed
use hooks
Signed-off-by: Aminu 'Seun Joshua <[email protected]>
1 parent f72cda6 commit a51d601

File tree

11 files changed

+218
-68
lines changed

11 files changed

+218
-68
lines changed

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,13 @@ spin-oci = { path = "crates/oci" }
6464
spin-plugins = { path = "crates/plugins" }
6565
spin-runtime-factors = { path = "crates/runtime-factors" }
6666
spin-telemetry = { path = "crates/telemetry", features = [
67-
"tracing-log-compat",
67+
"tracing-log-compat",
6868
] }
6969
spin-templates = { path = "crates/templates" }
7070
spin-trigger = { path = "crates/trigger" }
7171
spin-trigger-http = { path = "crates/trigger-http" }
7272
spin-trigger-redis = { path = "crates/trigger-redis" }
73+
spin-variables = { path = "crates/variables" }
7374
terminal = { path = "crates/terminal" }
7475

7576
[target.'cfg(target_os = "linux")'.dependencies]
@@ -95,10 +96,10 @@ testing-framework = { path = "tests/testing-framework" }
9596
[build-dependencies]
9697
cargo-target-dep = { git = "https://github.com/fermyon/cargo-target-dep", rev = "482f269eceb7b1a7e8fc618bf8c082dd24979cf1" }
9798
vergen = { version = "^8.2.1", default-features = false, features = [
98-
"build",
99-
"git",
100-
"gitcl",
101-
"cargo",
99+
"build",
100+
"git",
101+
"gitcl",
102+
"cargo",
102103
] }
103104

104105
[features]
@@ -111,10 +112,10 @@ llm-cublas = ["llm", "spin-runtime-factors/llm-cublas"]
111112

112113
[workspace]
113114
members = [
114-
"crates/*",
115-
"tests/conformance-tests",
116-
"tests/runtime-tests",
117-
"tests/testing-framework",
115+
"crates/*",
116+
"tests/conformance-tests",
117+
"tests/runtime-tests",
118+
"tests/testing-framework",
118119
]
119120

120121
[workspace.dependencies]
@@ -186,4 +187,4 @@ blocks_in_conditions = "allow"
186187

187188
[[bin]]
188189
name = "spin"
189-
path = "src/bin/spin.rs"
190+
path = "src/bin/spin.rs"

crates/loader/src/local.rs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ use std::path::{Path, PathBuf};
33
use anyhow::{anyhow, bail, ensure, Context, Result};
44
use futures::{future::try_join_all, StreamExt};
55
use reqwest::Url;
6-
use spin_common::{env::env_key, paths::parent_dir, sloth, ui::quoted_path};
6+
use spin_common::{paths::parent_dir, sloth, ui::quoted_path};
77
use spin_locked_app::{
88
locked::{
99
self, ContentPath, ContentRef, LockedApp, LockedComponent, LockedComponentDependency,
1010
LockedComponentSource, LockedTrigger,
1111
},
1212
values::{ValuesMap, ValuesMapBuilder},
13-
Variable,
1413
};
1514
use spin_manifest::schema::v2::{self, AppManifest, KebabId, WasiFilesMount};
1615
use spin_outbound_networking_config::allowed_hosts::{
@@ -89,7 +88,7 @@ impl LocalLoader {
8988

9089
let variables = variables
9190
.into_iter()
92-
.map(|(name, v)| Self::env_checker((name.to_string(), locked_variable(v)?)))
91+
.map(|(name, v)| Ok((name.to_string(), locked_variable(v)?)))
9392
.collect::<Result<_>>()?;
9493

9594
let triggers = triggers
@@ -136,21 +135,6 @@ impl LocalLoader {
136135
})
137136
}
138137

139-
fn env_checker((key, val): (String, Variable)) -> anyhow::Result<(String, Variable)> {
140-
if val.default.is_none() {
141-
if std::env::var(env_key(None, key.as_ref())).is_err() {
142-
Err(anyhow::anyhow!(
143-
"Variable data not provided for {}",
144-
quoted_path(key)
145-
))
146-
} else {
147-
Ok((key, val))
148-
}
149-
} else {
150-
Ok((key, val))
151-
}
152-
}
153-
154138
// Load the given component into a LockedComponent, ready for execution.
155139
async fn load_component(
156140
&self,

crates/runtime-factors/src/build.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use spin_runtime_config::ResolvedRuntimeConfig;
88
use spin_trigger::cli::{
99
FactorsConfig, InitialKvSetterHook, KeyValueDefaultStoreSummaryHook, MaxInstanceMemoryHook,
1010
RuntimeFactorsBuilder, SqlStatementExecutorHook, SqliteDefaultStoreSummaryHook,
11-
StdioLoggingExecutorHooks,
11+
StdioLoggingExecutorHooks, VariableSorterExecutorHooks,
1212
};
1313

1414
/// A [`RuntimeFactorsBuilder`] for [`TriggerFactors`].
@@ -58,6 +58,9 @@ impl RuntimeFactorsBuilder for FactorsBuilder {
5858
executor.add_hooks(InitialKvSetterHook::new(args.key_values.clone()));
5959
executor.add_hooks(SqliteDefaultStoreSummaryHook);
6060
executor.add_hooks(KeyValueDefaultStoreSummaryHook);
61+
executor.add_hooks(VariableSorterExecutorHooks::new(
62+
runtime_config.toml.clone(),
63+
));
6164

6265
let max_instance_memory = args
6366
.max_instance_memory

crates/trigger/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ spin-factor-wasi = { path = "../factor-wasi" }
3232
spin-factors = { path = "../factors" }
3333
spin-factors-executor = { path = "../factors-executor" }
3434
spin-telemetry = { path = "../telemetry" }
35+
spin-variables = { path = "../variables" }
3536
tokio = { workspace = true, features = ["fs", "rt"] }
37+
toml = { workspace = true }
3638
tracing = { workspace = true }
3739

3840
[dev-dependencies]

crates/trigger/src/cli.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod max_instance_memory;
44
mod sqlite_statements;
55
mod stdio;
66
mod summary;
7+
mod variables;
78

89
use std::path::PathBuf;
910
use std::{future::Future, sync::Arc};
@@ -25,6 +26,7 @@ pub use sqlite_statements::SqlStatementExecutorHook;
2526
use stdio::FollowComponents;
2627
pub use stdio::StdioLoggingExecutorHooks;
2728
pub use summary::{KeyValueDefaultStoreSummaryHook, SqliteDefaultStoreSummaryHook};
29+
pub use variables::VariableSorterExecutorHooks;
2830

2931
pub const APP_LOG_DIR: &str = "APP_LOG_DIR";
3032
pub const SPIN_TRUNCATE_LOGS: &str = "SPIN_TRUNCATE_LOGS";
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use spin_core::async_trait;
2+
use spin_factors::RuntimeFactors;
3+
use spin_factors_executor::ExecutorHooks;
4+
use spin_variables::{VariableProviderConfiguration, VariableSourcer};
5+
6+
/// Implements TriggerHooks, sorting required variables
7+
pub struct VariableSorterExecutorHooks {
8+
table: toml::Table,
9+
}
10+
11+
impl VariableSorterExecutorHooks {
12+
pub fn new(table: toml::Table) -> Self {
13+
Self { table }
14+
}
15+
}
16+
17+
#[async_trait]
18+
impl<F: RuntimeFactors, U> ExecutorHooks<F, U> for VariableSorterExecutorHooks {
19+
async fn configure_app(
20+
&self,
21+
configured_app: &spin_factors::ConfiguredApp<F>,
22+
) -> anyhow::Result<()> {
23+
for (key, variable) in configured_app.app().variables() {
24+
self.variable_env_checker(key.clone(), variable.clone())?;
25+
}
26+
Ok(())
27+
}
28+
}
29+
30+
impl VariableSourcer for VariableSorterExecutorHooks {
31+
fn variable_env_checker(
32+
&self,
33+
key: String,
34+
val: spin_app::Variable,
35+
) -> anyhow::Result<(String, spin_app::Variable)> {
36+
let configs = spin_variables::variable_provider_config_from_toml(&self.table)?;
37+
38+
if let Some(config) = configs.into_iter().next() {
39+
let (dotenv_path, prefix) = match config {
40+
VariableProviderConfiguration::Env(env) => (env.dotenv_path, env.prefix),
41+
_ => (None, None),
42+
};
43+
return self.check(key, val, dotenv_path, prefix);
44+
}
45+
46+
Err(anyhow::anyhow!("No environment variable provider found"))
47+
}
48+
}

crates/variables/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ spin-common = { path = "../common" }
1818
spin-expressions = { path = "../expressions" }
1919
spin-factor-variables = { path = "../factor-variables" }
2020
spin-factors = { path = "../factors" }
21+
spin-locked-app = { path = "../locked-app" }
2122
spin-world = { path = "../world" }
2223
tokio = { workspace = true, features = ["rt-multi-thread"] }
2324
tracing = { workspace = true }

crates/variables/src/lib.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ mod env;
55
mod statik;
66
mod vault;
77

8+
use std::path::PathBuf;
9+
810
pub use azure_key_vault::*;
911
pub use env::*;
12+
use spin_common::{env::env_key, ui::quoted_path};
13+
use spin_locked_app::Variable;
1014
pub use statik::*;
1115
pub use vault::*;
1216

@@ -38,6 +42,24 @@ pub fn runtime_config_from_toml(table: &impl GetTomlValue) -> anyhow::Result<Run
3842
Ok(RuntimeConfig { providers })
3943
}
4044

45+
pub fn variable_provider_config_from_toml(
46+
table: &impl GetTomlValue,
47+
) -> anyhow::Result<Vec<VariableProviderConfiguration>> {
48+
if let Some(array) = table
49+
.get("variables_provider")
50+
.or_else(|| table.get("config_provider"))
51+
{
52+
array
53+
.clone()
54+
.try_into::<Vec<VariableProviderConfiguration>>()
55+
.map_err(|e| anyhow::anyhow!("Failed to parse variable provider configuration: {}", e))
56+
} else {
57+
Ok(vec![VariableProviderConfiguration::Env(
58+
EnvVariablesConfig::default(),
59+
)])
60+
}
61+
}
62+
4163
/// A runtime configuration used in the Spin CLI for one type of variable provider.
4264
#[derive(Debug, Deserialize)]
4365
#[serde(rename_all = "snake_case", tag = "type")]
@@ -70,3 +92,38 @@ impl VariableProviderConfiguration {
7092
Ok(provider)
7193
}
7294
}
95+
96+
pub trait VariableSourcer {
97+
fn variable_env_checker(
98+
&self,
99+
key: String,
100+
val: Variable,
101+
) -> anyhow::Result<(String, Variable)>;
102+
103+
fn check(
104+
&self,
105+
key: String,
106+
mut val: Variable,
107+
dotenv_path: Option<PathBuf>,
108+
prefix: Option<String>,
109+
) -> anyhow::Result<(String, Variable)> {
110+
if val.default.is_some() {
111+
return Ok((key, val));
112+
}
113+
114+
if let Some(path) = dotenv_path {
115+
_ = std::env::set_current_dir(path);
116+
}
117+
118+
match std::env::var(env_key(prefix, &key)) {
119+
Ok(v) => {
120+
val.default = Some(v);
121+
Ok((key, val))
122+
}
123+
Err(_) => Err(anyhow::anyhow!(
124+
"Variable data not provided for {}",
125+
quoted_path(key)
126+
)),
127+
}
128+
}
129+
}

0 commit comments

Comments
 (0)