From 4db56ba7f96a3cbb127599e5dc627cc8095f9b73 Mon Sep 17 00:00:00 2001 From: chesedo Date: Wed, 15 Mar 2023 11:34:28 +0200 Subject: [PATCH 1/7] refactor: send claim to provisioner --- Cargo.lock | 1 + deployer/src/deployment/run.rs | 18 +++++++++++++----- deployer/src/runtime_manager.rs | 15 +++++++++++++-- gateway/src/project.rs | 2 +- proto/Cargo.toml | 3 ++- proto/src/lib.rs | 20 +++++++++++++++----- runtime/Cargo.toml | 2 +- runtime/src/alpha/args.rs | 6 +++++- runtime/src/alpha/mod.rs | 17 ++++++++++++++--- runtime/src/provisioner_factory.rs | 17 ++++++++++++----- runtime/tests/integration/helpers.rs | 3 ++- 11 files changed, 79 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index edc521e1c..720580d54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4750,6 +4750,7 @@ dependencies = [ "tokio", "tonic", "tonic-build", + "tower", "tracing", ] diff --git a/deployer/src/deployment/run.rs b/deployer/src/deployment/run.rs index 766cfe923..193e5e23c 100644 --- a/deployer/src/deployment/run.rs +++ b/deployer/src/deployment/run.rs @@ -8,7 +8,10 @@ use std::{ use async_trait::async_trait; use opentelemetry::global; use portpicker::pick_unused_port; -use shuttle_common::{claims::Claim, storage_manager::ArtifactsStorageManager}; +use shuttle_common::{ + claims::{Claim, ClaimService, InjectPropagation}, + storage_manager::ArtifactsStorageManager, +}; use shuttle_proto::runtime::{ runtime_client::RuntimeClient, LoadRequest, StartRequest, StopReason, SubscribeStopRequest, @@ -214,7 +217,6 @@ impl Built { kill_old_deployments.await?; - info!("got handle for deployment"); // Execute loaded service load( self.service_name.clone(), @@ -222,6 +224,7 @@ impl Built { executable_path.clone(), secret_getter, runtime_client.clone(), + self.claim, ) .await?; @@ -243,7 +246,8 @@ async fn load( service_id: Uuid, executable_path: PathBuf, secret_getter: impl SecretGetter, - mut runtime_client: RuntimeClient, + mut runtime_client: RuntimeClient>>, + claim: Option, ) -> Result<()> { info!( "loading project from: {}", @@ -262,7 +266,7 @@ async fn load( .map(|secret| (secret.key, secret.value)); let secrets = HashMap::from_iter(secrets); - let load_request = tonic::Request::new(LoadRequest { + let mut load_request = tonic::Request::new(LoadRequest { path: executable_path .into_os_string() .into_string() @@ -271,6 +275,10 @@ async fn load( secrets, }); + if let Some(claim) = claim { + load_request.extensions_mut().insert(claim); + } + debug!("loading service"); let response = runtime_client.load(load_request).await; @@ -297,7 +305,7 @@ async fn load( async fn run( id: Uuid, service_name: String, - mut runtime_client: RuntimeClient, + mut runtime_client: RuntimeClient>>, address: SocketAddr, deployment_updater: impl DeploymentUpdater, cleanup: impl FnOnce(SubscribeStopResponse) + Send + 'static, diff --git a/deployer/src/runtime_manager.rs b/deployer/src/runtime_manager.rs index 825a4ade5..0624cad52 100644 --- a/deployer/src/runtime_manager.rs +++ b/deployer/src/runtime_manager.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, path::PathBuf, sync::Arc}; use anyhow::Context; +use shuttle_common::claims::{ClaimService, InjectPropagation}; use shuttle_proto::runtime::{ self, runtime_client::RuntimeClient, StopRequest, SubscribeLogsRequest, }; @@ -13,7 +14,17 @@ use crate::deployment::deploy_layer; const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); -type Runtimes = Arc)>>>; +type Runtimes = Arc< + std::sync::Mutex< + HashMap< + Uuid, + ( + process::Child, + RuntimeClient>>, + ), + >, + >, +>; /// Manager that can start up mutliple runtimes. This is needed so that two runtimes can be up when a new deployment is made: /// One runtime for the new deployment being loaded; another for the currently active deployment @@ -43,7 +54,7 @@ impl RuntimeManager { &mut self, id: Uuid, alpha_runtime_path: Option, - ) -> anyhow::Result> { + ) -> anyhow::Result>>> { trace!("making new client"); let port = portpicker::pick_unused_port().context("failed to find available port")?; diff --git a/gateway/src/project.rs b/gateway/src/project.rs index efc13ddf9..54e955935 100644 --- a/gateway/src/project.rs +++ b/gateway/src/project.rs @@ -717,7 +717,7 @@ impl ProjectCreating { auth_uri, ], "Env": [ - "RUST_LOG=debug,shuttle=trace", + "RUST_LOG=debug,shuttle=trace,h2=warn", ] }) }); diff --git a/proto/Cargo.toml b/proto/Cargo.toml index eb633ae31..2a03c17b6 100644 --- a/proto/Cargo.toml +++ b/proto/Cargo.toml @@ -15,11 +15,12 @@ prost = "0.11.2" prost-types = { workspace = true } tokio = { version = "1.22.0", features = ["process"] } tonic = { workspace = true } +tower = { workspace = true } tracing = { workspace = true } [dependencies.shuttle-common] workspace = true -features = ["error", "service", "wasm"] +features = ["claims", "error", "service", "wasm"] [build-dependencies] tonic-build = "0.8.3" diff --git a/proto/src/lib.rs b/proto/src/lib.rs index fd2e81caf..2c1bf9063 100644 --- a/proto/src/lib.rs +++ b/proto/src/lib.rs @@ -104,9 +104,13 @@ pub mod runtime { use anyhow::Context; use chrono::DateTime; use prost_types::Timestamp; - use shuttle_common::ParseError; + use shuttle_common::{ + claims::{ClaimLayer, ClaimService, InjectPropagation, InjectPropagationLayer}, + database, ParseError, + }; use tokio::process; use tonic::transport::{Channel, Endpoint}; + use tower::ServiceBuilder; use tracing::info; pub enum StorageManagerType { @@ -208,7 +212,10 @@ pub mod runtime { provisioner_address: &str, port: u16, get_runtime_executable: impl FnOnce() -> PathBuf, - ) -> anyhow::Result<(process::Child, runtime_client::RuntimeClient)> { + ) -> anyhow::Result<( + process::Child, + runtime_client::RuntimeClient>>, + )> { let (storage_manager_type, storage_manager_path) = match storage_manager_type { StorageManagerType::Artifacts(path) => ("artifacts", path), StorageManagerType::WorkingDir(path) => ("working-dir", path), @@ -247,9 +254,12 @@ pub mod runtime { .context("creating runtime client endpoint")? .connect_timeout(Duration::from_secs(5)); - let runtime_client = runtime_client::RuntimeClient::connect(conn) - .await - .context("connecting runtime client")?; + let channel = conn.connect().await.context("connecting runtime client")?; + let channel = ServiceBuilder::new() + .layer(ClaimLayer) + .layer(InjectPropagationLayer) + .service(channel); + let runtime_client = runtime_client::RuntimeClient::new(channel); Ok((runtime, runtime_client)) } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 632c5ee16..58840a9dd 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -41,7 +41,7 @@ wasmtime-wasi = { version = "4.0.0", optional = true } [dependencies.shuttle-common] workspace = true -features = ["claims"] +features = ["claims", "backend"] [dependencies.shuttle-proto] workspace = true diff --git a/runtime/src/alpha/args.rs b/runtime/src/alpha/args.rs index 77af08cbd..21afa20f6 100644 --- a/runtime/src/alpha/args.rs +++ b/runtime/src/alpha/args.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use clap::{Parser, ValueEnum}; -use tonic::transport::Endpoint; +use tonic::transport::{Endpoint, Uri}; #[derive(Parser, Debug)] #[command(version)] @@ -21,6 +21,10 @@ pub struct Args { /// Path to use for storage manager #[arg(long)] pub storage_manager_path: PathBuf, + + /// Address to reach the authentication service at + #[arg(long, default_value = "http://127.0.0.1:8008")] + pub auth_uri: Uri, } #[derive(Clone, Debug, ValueEnum)] diff --git a/runtime/src/alpha/mod.rs b/runtime/src/alpha/mod.rs index a00054092..4bbc97d49 100644 --- a/runtime/src/alpha/mod.rs +++ b/runtime/src/alpha/mod.rs @@ -13,7 +13,11 @@ use async_trait::async_trait; use clap::Parser; use core::future::Future; use shuttle_common::{ - claims::{ClaimLayer, InjectPropagationLayer}, + backends::{ + auth::{AuthPublicKey, JwtAuthenticationLayer}, + tracing::ExtractPropagationLayer, + }, + claims::{Claim, ClaimLayer, InjectPropagationLayer}, storage_manager::{ArtifactsStorageManager, StorageManager, WorkingDirStorageManager}, }; use shuttle_proto::{ @@ -50,8 +54,12 @@ pub async fn start(loader: impl Loader + Send + 'static) { let addr = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), args.port); let provisioner_address = args.provisioner_address; - let mut server_builder = - Server::builder().http2_keepalive_interval(Some(Duration::from_secs(60))); + let mut server_builder = Server::builder() + .http2_keepalive_interval(Some(Duration::from_secs(60))) + .layer(JwtAuthenticationLayer::new(AuthPublicKey::new( + args.auth_uri, + ))) + .layer(ExtractPropagationLayer); // We wrap the StorageManager trait object in an Arc rather than a Box, since we need // to clone it in the `ProvisionerFactory::new` call in the alpha runtime `load` method. @@ -158,6 +166,8 @@ where S: Service + Send + 'static, { async fn load(&self, request: Request) -> Result, Status> { + let claim = request.extensions().get::().map(Clone::clone); + let LoadRequest { path, secrets, @@ -190,6 +200,7 @@ where secrets, self.storage_manager.clone(), self.env, + claim, ); trace!("got factory"); diff --git a/runtime/src/provisioner_factory.rs b/runtime/src/provisioner_factory.rs index a2ccba6b3..7c21332c0 100644 --- a/runtime/src/provisioner_factory.rs +++ b/runtime/src/provisioner_factory.rs @@ -2,7 +2,7 @@ use std::{collections::BTreeMap, path::PathBuf, sync::Arc}; use async_trait::async_trait; use shuttle_common::{ - claims::{ClaimService, InjectPropagation}, + claims::{Claim, ClaimService, InjectPropagation}, database, storage_manager::StorageManager, DatabaseReadyInfo, @@ -22,6 +22,7 @@ pub struct ProvisionerFactory { info: Option, secrets: BTreeMap, env: Environment, + claim: Option, } impl ProvisionerFactory { @@ -31,6 +32,7 @@ impl ProvisionerFactory { secrets: BTreeMap, storage_manager: Arc, env: Environment, + claim: Option, ) -> Self { Self { provisioner_client, @@ -39,6 +41,7 @@ impl ProvisionerFactory { info: None, secrets, env, + claim, } } } @@ -63,6 +66,10 @@ impl Factory for ProvisionerFactory { db_type: Some(db_type), }); + if let Some(claim) = &self.claim { + request.extensions_mut().insert(claim.clone()); + } + let response = self .provisioner_client .provision_database(request) @@ -88,6 +95,10 @@ impl Factory for ProvisionerFactory { self.service_name.clone() } + fn get_environment(&self) -> shuttle_service::Environment { + self.env + } + fn get_build_path(&self) -> Result { self.storage_manager .service_build_path(self.service_name.as_str()) @@ -99,8 +110,4 @@ impl Factory for ProvisionerFactory { .service_storage_path(self.service_name.as_str()) .map_err(Into::into) } - - fn get_environment(&self) -> shuttle_service::Environment { - self.env - } } diff --git a/runtime/tests/integration/helpers.rs b/runtime/tests/integration/helpers.rs index 3b13eff51..c31babee0 100644 --- a/runtime/tests/integration/helpers.rs +++ b/runtime/tests/integration/helpers.rs @@ -6,6 +6,7 @@ use std::{ use anyhow::Result; use async_trait::async_trait; +use shuttle_common::claims::{ClaimService, InjectPropagation}; use shuttle_proto::{ provisioner::{ provisioner_server::{Provisioner, ProvisionerServer}, @@ -20,7 +21,7 @@ use tonic::{ }; pub struct TestRuntime { - pub runtime_client: RuntimeClient, + pub runtime_client: RuntimeClient>>, pub bin_path: String, pub service_name: String, pub runtime_address: SocketAddr, From ce5f25e1e5e695158128e11a056a0c00239c2071 Mon Sep 17 00:00:00 2001 From: chesedo Date: Wed, 15 Mar 2023 13:55:04 +0200 Subject: [PATCH 2/7] feat: recording of provisioned resources This returns provisioned resources from runtime so that they can be recorded by deployer. Closes #ENG-252. --- common/Cargo.toml | 9 ++-- common/src/database.rs | 6 +-- common/src/lib.rs | 1 + common/src/models/mod.rs | 1 - common/src/models/service.rs | 10 +--- common/src/{models => }/resource.rs | 23 +++++++-- deployer/src/deployment/deploy_layer.rs | 21 +++++++- deployer/src/deployment/mod.rs | 20 ++++++-- deployer/src/deployment/run.rs | 61 +++++++++++++++++------- deployer/src/lib.rs | 1 + deployer/src/persistence/resource/mod.rs | 15 ++++-- proto/runtime.proto | 2 + proto/src/lib.rs | 2 +- runtime/src/alpha/mod.rs | 28 +++++++++++ runtime/src/next/mod.rs | 1 + runtime/src/provisioner_factory.rs | 35 +++++++++----- 16 files changed, 176 insertions(+), 60 deletions(-) rename common/src/{models => }/resource.rs (62%) diff --git a/common/Cargo.toml b/common/Cargo.toml index c7678719a..c062390de 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -31,7 +31,7 @@ reqwest = { version = "0.11.13", optional = true } rmp-serde = { version = "1.1.1", optional = true } rustrict = { version = "0.5.5", optional = true } serde = { workspace = true, features = ["derive", "std"] } -serde_json = { workspace = true, optional = true } +serde_json = { workspace = true } strum = { workspace = true, features = ["derive"], optional = true } thiserror = { workspace = true, optional = true } tonic = { version = "0.8.3", optional = true } @@ -47,10 +47,10 @@ uuid = { workspace = true, features = ["v4", "serde"], optional = true } backend = ["async-trait", "axum/matched-path", "claims", "hyper/client", "opentelemetry-otlp", "thiserror", "tower-http", "tracing-subscriber/env-filter", "tracing-subscriber/fmt", "ttl_cache"] claims = ["bytes", "chrono/clock", "headers", "http", "http-body", "jsonwebtoken", "opentelemetry", "opentelemetry-http", "pin-project", "tower", "tracing", "tracing-opentelemetry"] display = ["chrono/clock", "comfy-table", "crossterm"] -error = ["prost-types", "serde_json", "thiserror", "uuid"] -models = ["anyhow", "async-trait", "display", "http", "reqwest", "serde_json", "service"] +error = ["prost-types", "thiserror", "uuid"] +models = ["anyhow", "async-trait", "display", "http", "reqwest", "service"] service = ["chrono/serde", "once_cell", "rustrict", "serde/derive", "strum", "uuid"] -tracing = ["serde_json"] +tracing = [] wasm = ["chrono/clock", "http-serde", "http", "rmp-serde", "tracing", "tracing-subscriber"] [dev-dependencies] @@ -59,7 +59,6 @@ base64 = "0.13.1" cap-std = "1.0.2" hyper = { workspace = true } ring = { workspace = true } -serde_json = { workspace = true } tokio = { version = "1.22.0", features = ["macros", "rt-multi-thread"] } tower = { workspace = true, features = ["util"] } tracing-fluent-assertions = "0.3.0" diff --git a/common/src/database.rs b/common/src/database.rs index c1617b47d..1d3956ea0 100644 --- a/common/src/database.rs +++ b/common/src/database.rs @@ -3,14 +3,14 @@ use std::fmt::Display; use serde::{Deserialize, Serialize}; use strum::Display; -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)] #[serde(rename_all = "lowercase")] pub enum Type { AwsRds(AwsRdsEngine), Shared(SharedEngine), } -#[derive(Clone, Debug, Deserialize, Display, Serialize)] +#[derive(Clone, Debug, Deserialize, Display, Serialize, Eq, PartialEq)] #[serde(rename_all = "lowercase")] #[strum(serialize_all = "lowercase")] pub enum AwsRdsEngine { @@ -19,7 +19,7 @@ pub enum AwsRdsEngine { MariaDB, } -#[derive(Clone, Debug, Deserialize, Display, Serialize)] +#[derive(Clone, Debug, Deserialize, Display, Serialize, Eq, PartialEq)] #[serde(rename_all = "lowercase")] #[strum(serialize_all = "lowercase")] pub enum SharedEngine { diff --git a/common/src/lib.rs b/common/src/lib.rs index a68067084..6afac4432 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -12,6 +12,7 @@ pub mod log; pub mod models; #[cfg(feature = "service")] pub mod project; +pub mod resource; #[cfg(feature = "service")] pub mod storage_manager; #[cfg(feature = "tracing")] diff --git a/common/src/models/mod.rs b/common/src/models/mod.rs index 328a33cf8..463e04192 100644 --- a/common/src/models/mod.rs +++ b/common/src/models/mod.rs @@ -1,7 +1,6 @@ pub mod deployment; pub mod error; pub mod project; -pub mod resource; pub mod secret; pub mod service; pub mod stats; diff --git a/common/src/models/service.rs b/common/src/models/service.rs index 2dfef55a6..68d569050 100644 --- a/common/src/models/service.rs +++ b/common/src/models/service.rs @@ -1,6 +1,6 @@ use crate::{ - models::{deployment, resource, resource::ResourceInfo, secret}, - DatabaseReadyInfo, + models::{deployment, secret}, + resource::{self, ResourceInfo}, }; use comfy_table::{ @@ -34,12 +34,6 @@ pub struct Summary { pub uri: String, } -impl ResourceInfo for DatabaseReadyInfo { - fn connection_string_public(&self) -> String { - self.connection_string_public() - } -} - impl Display for Detailed { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let deploys = get_deployments_table(&self.deployments, &self.name); diff --git a/common/src/models/resource.rs b/common/src/resource.rs similarity index 62% rename from common/src/models/resource.rs rename to common/src/resource.rs index 3b97bfb75..67021bd9b 100644 --- a/common/src/models/resource.rs +++ b/common/src/resource.rs @@ -2,13 +2,11 @@ use std::fmt::Display; use serde::{Deserialize, Serialize}; use serde_json::Value; -use uuid::Uuid; use crate::{database, DatabaseReadyInfo}; -#[derive(Deserialize, Serialize)] +#[derive(Clone, Deserialize, Serialize)] pub struct Response { - pub service_id: Uuid, pub r#type: Type, pub data: Value, } @@ -17,9 +15,22 @@ pub struct Response { pub trait ResourceInfo { /// String to connect to this resource from a public location fn connection_string_public(&self) -> String; + + /// String to connect to this resource from within shuttle + fn connection_string_private(&self) -> String; +} + +impl ResourceInfo for DatabaseReadyInfo { + fn connection_string_public(&self) -> String { + self.connection_string_public() + } + + fn connection_string_private(&self) -> String { + self.connection_string_private() + } } -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)] #[serde(rename_all = "lowercase")] pub enum Type { Database(database::Type), @@ -33,6 +44,10 @@ impl Response { } } } + + pub fn into_bytes(self) -> Vec { + serde_json::to_vec(&self).expect("to turn resource into a vec") + } } impl Display for Type { diff --git a/deployer/src/deployment/deploy_layer.rs b/deployer/src/deployment/deploy_layer.rs index a46441950..c89847af3 100644 --- a/deployer/src/deployment/deploy_layer.rs +++ b/deployer/src/deployment/deploy_layer.rs @@ -310,7 +310,10 @@ mod tests { time::Duration, }; - use crate::{persistence::DeploymentUpdater, RuntimeManager}; + use crate::{ + persistence::{DeploymentUpdater, Resource, ResourceManager}, + RuntimeManager, + }; use async_trait::async_trait; use axum::body::Bytes; use ctor::ctor; @@ -553,6 +556,21 @@ mod tests { } } + #[derive(Clone)] + struct StubResourceManager; + + #[async_trait::async_trait] + impl ResourceManager for StubResourceManager { + type Err = std::io::Error; + + async fn insert_resource(&self, _resource: &Resource) -> Result<(), Self::Err> { + Ok(()) + } + async fn get_resources(&self, _service_id: &Uuid) -> Result, Self::Err> { + Ok(Vec::new()) + } + } + async fn test_states(id: &Uuid, expected_states: Vec) { loop { let states = RECORDER.lock().unwrap().get_deployment_states(id); @@ -861,6 +879,7 @@ mod tests { .active_deployment_getter(StubActiveDeploymentGetter) .artifacts_path(PathBuf::from("/tmp")) .secret_getter(StubSecretGetter) + .resource_manager(StubResourceManager) .runtime(get_runtime_manager()) .deployment_updater(StubDeploymentUpdater) .queue_client(StubBuildQueueClient) diff --git a/deployer/src/deployment/mod.rs b/deployer/src/deployment/mod.rs index 09ceeaba2..fe5aca313 100644 --- a/deployer/src/deployment/mod.rs +++ b/deployer/src/deployment/mod.rs @@ -12,7 +12,7 @@ use tracing::{instrument, Span}; use tracing_opentelemetry::OpenTelemetrySpanExt; use crate::{ - persistence::{DeploymentUpdater, SecretGetter, SecretRecorder, State}, + persistence::{DeploymentUpdater, ResourceManager, SecretGetter, SecretRecorder, State}, RuntimeManager, }; use tokio::sync::{mpsc, Mutex}; @@ -23,7 +23,7 @@ use self::{deploy_layer::LogRecorder, gateway_client::BuildQueueClient}; const QUEUE_BUFFER_SIZE: usize = 100; const RUN_BUFFER_SIZE: usize = 100; -pub struct DeploymentManagerBuilder { +pub struct DeploymentManagerBuilder { build_log_recorder: Option, secret_recorder: Option, active_deployment_getter: Option, @@ -31,16 +31,18 @@ pub struct DeploymentManagerBuilder { runtime_manager: Option>>, deployment_updater: Option, secret_getter: Option, + resource_manager: Option, queue_client: Option, } -impl DeploymentManagerBuilder +impl DeploymentManagerBuilder where LR: LogRecorder, SR: SecretRecorder, ADG: ActiveDeploymentsGetter, DU: DeploymentUpdater, SG: SecretGetter, + RM: ResourceManager, QC: BuildQueueClient, { pub fn build_log_recorder(mut self, build_log_recorder: LR) -> Self { @@ -79,6 +81,12 @@ where self } + pub fn resource_manager(mut self, resource_manager: RM) -> Self { + self.resource_manager = Some(resource_manager); + + self + } + pub fn runtime(mut self, runtime_manager: Arc>) -> Self { self.runtime_manager = Some(runtime_manager); @@ -110,6 +118,7 @@ where .deployment_updater .expect("a deployment updater to be set"); let secret_getter = self.secret_getter.expect("a secret getter to be set"); + let resource_manager = self.resource_manager.expect("a resource manager to be set"); let (queue_send, queue_recv) = mpsc::channel(QUEUE_BUFFER_SIZE); let (run_send, run_recv) = mpsc::channel(RUN_BUFFER_SIZE); @@ -132,6 +141,7 @@ where deployment_updater, active_deployment_getter, secret_getter, + resource_manager, storage_manager.clone(), )); @@ -169,7 +179,8 @@ pub struct DeploymentManager { impl DeploymentManager { /// Create a new deployment manager. Manages one or more 'pipelines' for /// processing service building, loading, and deployment. - pub fn builder() -> DeploymentManagerBuilder { + pub fn builder( + ) -> DeploymentManagerBuilder { DeploymentManagerBuilder { build_log_recorder: None, secret_recorder: None, @@ -178,6 +189,7 @@ impl DeploymentManager { runtime_manager: None, deployment_updater: None, secret_getter: None, + resource_manager: None, queue_client: None, } } diff --git a/deployer/src/deployment/run.rs b/deployer/src/deployment/run.rs index 193e5e23c..7529314d1 100644 --- a/deployer/src/deployment/run.rs +++ b/deployer/src/deployment/run.rs @@ -10,6 +10,7 @@ use opentelemetry::global; use portpicker::pick_unused_port; use shuttle_common::{ claims::{Claim, ClaimService, InjectPropagation}, + resource, storage_manager::ArtifactsStorageManager, }; @@ -26,7 +27,7 @@ use uuid::Uuid; use super::{RunReceiver, State}; use crate::{ error::{Error, Result}, - persistence::{DeploymentUpdater, SecretGetter}, + persistence::{DeploymentUpdater, Resource, ResourceManager, SecretGetter}, RuntimeManager, }; @@ -38,6 +39,7 @@ pub async fn task( deployment_updater: impl DeploymentUpdater, active_deployment_getter: impl ActiveDeploymentsGetter, secret_getter: impl SecretGetter, + resource_manager: impl ResourceManager, storage_manager: ArtifactsStorageManager, ) { info!("Run task started"); @@ -49,6 +51,7 @@ pub async fn task( let deployment_updater = deployment_updater.clone(); let secret_getter = secret_getter.clone(); + let resource_manager = resource_manager.clone(); let storage_manager = storage_manager.clone(); let old_deployments_killer = kill_old_deployments( @@ -82,6 +85,7 @@ pub async fn task( .handle( storage_manager, secret_getter, + resource_manager, runtime_manager, deployment_updater, old_deployments_killer, @@ -174,12 +178,13 @@ pub struct Built { } impl Built { - #[instrument(skip(self, storage_manager, secret_getter, runtime_manager, deployment_updater, kill_old_deployments, cleanup), fields(id = %self.id, state = %State::Loading))] + #[instrument(skip(self, storage_manager, secret_getter, resource_manager, runtime_manager, deployment_updater, kill_old_deployments, cleanup), fields(id = %self.id, state = %State::Loading))] #[allow(clippy::too_many_arguments)] async fn handle( self, storage_manager: ArtifactsStorageManager, secret_getter: impl SecretGetter, + resource_manager: impl ResourceManager, runtime_manager: Arc>, deployment_updater: impl DeploymentUpdater, kill_old_deployments: impl futures::Future>, @@ -223,6 +228,7 @@ impl Built { self.service_id, executable_path.clone(), secret_getter, + resource_manager, runtime_client.clone(), self.claim, ) @@ -246,6 +252,7 @@ async fn load( service_id: Uuid, executable_path: PathBuf, secret_getter: impl SecretGetter, + resource_manager: impl ResourceManager, mut runtime_client: RuntimeClient>>, claim: Option, ) -> Result<()> { @@ -287,6 +294,19 @@ async fn load( let response = response.into_inner(); info!(?response, "loading response"); + for resource in response.resources { + let resource: resource::Response = serde_json::from_slice(&resource).unwrap(); + let resource = Resource { + service_id, + r#type: resource.r#type.into(), + data: resource.data, + }; + resource_manager + .insert_resource(&resource) + .await + .expect("to add resource to persistence"); + } + if response.success { Ok(()) } else { @@ -384,7 +404,7 @@ mod tests { use uuid::Uuid; use crate::{ - persistence::{DeploymentUpdater, Secret, SecretGetter}, + persistence::{DeploymentUpdater, Resource, ResourceManager, Secret, SecretGetter}, RuntimeManager, }; @@ -460,8 +480,19 @@ mod tests { } } - fn get_secret_getter() -> StubSecretGetter { - StubSecretGetter + #[derive(Clone)] + struct StubResourceManager; + + #[async_trait] + impl ResourceManager for StubResourceManager { + type Err = std::io::Error; + + async fn insert_resource(&self, _resource: &Resource) -> Result<(), Self::Err> { + Ok(()) + } + async fn get_resources(&self, _service_id: &Uuid) -> Result, Self::Err> { + Ok(Vec::new()) + } } #[derive(Clone)] @@ -496,12 +527,11 @@ mod tests { _ => panic!("expected stop due to request"), }; - let secret_getter = get_secret_getter(); - built .handle( storage_manager, - secret_getter, + StubSecretGetter, + StubResourceManager, runtime_manager.clone(), StubDeploymentUpdater, kill_old_deployments(), @@ -537,12 +567,11 @@ mod tests { _ => panic!("expected stop due to self end"), }; - let secret_getter = get_secret_getter(); - built .handle( storage_manager, - secret_getter, + StubSecretGetter, + StubResourceManager, runtime_manager.clone(), StubDeploymentUpdater, kill_old_deployments(), @@ -577,12 +606,11 @@ mod tests { (_, mes) => panic!("expected stop due to crash: {mes}"), }; - let secret_getter = get_secret_getter(); - built .handle( storage_manager, - secret_getter, + StubSecretGetter, + StubResourceManager, runtime_manager.clone(), StubDeploymentUpdater, kill_old_deployments(), @@ -609,12 +637,11 @@ mod tests { let handle_cleanup = |_result| panic!("service should never be started"); - let secret_getter = get_secret_getter(); - built .handle( storage_manager, - secret_getter, + StubSecretGetter, + StubResourceManager, runtime_manager.clone(), StubDeploymentUpdater, kill_old_deployments(), diff --git a/deployer/src/lib.rs b/deployer/src/lib.rs index dc689820c..73912cb76 100644 --- a/deployer/src/lib.rs +++ b/deployer/src/lib.rs @@ -37,6 +37,7 @@ pub async fn start( .runtime(runtime_manager) .deployment_updater(persistence.clone()) .secret_getter(persistence.clone()) + .resource_manager(persistence.clone()) .queue_client(GatewayClient::new(args.gateway_uri)) .build(); diff --git a/deployer/src/persistence/resource/mod.rs b/deployer/src/persistence/resource/mod.rs index 20069563d..36fcff4e4 100644 --- a/deployer/src/persistence/resource/mod.rs +++ b/deployer/src/persistence/resource/mod.rs @@ -25,10 +25,9 @@ pub struct Resource { pub data: serde_json::Value, } -impl From for shuttle_common::models::resource::Response { +impl From for shuttle_common::resource::Response { fn from(resource: Resource) -> Self { - shuttle_common::models::resource::Response { - service_id: resource.service_id, + shuttle_common::resource::Response { r#type: resource.r#type.into(), data: resource.data, } @@ -40,7 +39,7 @@ pub enum Type { Database(DatabaseType), } -impl From for shuttle_common::models::resource::Type { +impl From for shuttle_common::resource::Type { fn from(r#type: Type) -> Self { match r#type { Type::Database(r#type) => Self::Database(r#type.into()), @@ -48,6 +47,14 @@ impl From for shuttle_common::models::resource::Type { } } +impl From for Type { + fn from(r#type: shuttle_common::resource::Type) -> Self { + match r#type { + shuttle_common::resource::Type::Database(r#type) => Self::Database(r#type.into()), + } + } +} + impl Display for Type { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/proto/runtime.proto b/proto/runtime.proto index 57a4895df..2be6c9d81 100644 --- a/proto/runtime.proto +++ b/proto/runtime.proto @@ -36,6 +36,8 @@ message LoadResponse { bool success = 1; // Error message if not successful string message = 2; + // Which resources where requested + repeated bytes resources = 10; } message StartRequest { diff --git a/proto/src/lib.rs b/proto/src/lib.rs index 2c1bf9063..283e358d2 100644 --- a/proto/src/lib.rs +++ b/proto/src/lib.rs @@ -106,7 +106,7 @@ pub mod runtime { use prost_types::Timestamp; use shuttle_common::{ claims::{ClaimLayer, ClaimService, InjectPropagation, InjectPropagationLayer}, - database, ParseError, + ParseError, }; use tokio::process; use tonic::transport::{Channel, Endpoint}; diff --git a/runtime/src/alpha/mod.rs b/runtime/src/alpha/mod.rs index 4bbc97d49..149c7232a 100644 --- a/runtime/src/alpha/mod.rs +++ b/runtime/src/alpha/mod.rs @@ -18,6 +18,7 @@ use shuttle_common::{ tracing::ExtractPropagationLayer, }, claims::{Claim, ClaimLayer, InjectPropagationLayer}, + resource, storage_manager::{ArtifactsStorageManager, StorageManager, WorkingDirStorageManager}, }; use shuttle_proto::{ @@ -194,6 +195,8 @@ where let service_name = ServiceName::from_str(service_name.as_str()) .map_err(|err| Status::from_error(Box::new(err)))?; + let resources: Arc>> = Default::default(); + let factory = ProvisionerFactory::new( provisioner_client, service_name, @@ -201,6 +204,7 @@ where self.storage_manager.clone(), self.env, claim, + resources.clone(), ); trace!("got factory"); @@ -218,11 +222,26 @@ where let message = LoadResponse { success: false, message: error.to_string(), + resources: resources + .lock() + .await + .clone() + .into_iter() + .map(resource::Response::into_bytes) + .collect(), }; return Ok(Response::new(message)); } }, Err(error) => { + let resources = resources + .lock() + .await + .clone() + .into_iter() + .map(resource::Response::into_bytes) + .collect(); + if error.is_panic() { let panic = error.into_panic(); let msg = panic @@ -235,6 +254,7 @@ where let message = LoadResponse { success: false, message: msg, + resources, }; return Ok(Response::new(message)); } else { @@ -242,6 +262,7 @@ where let message = LoadResponse { success: false, message: error.to_string(), + resources, }; return Ok(Response::new(message)); } @@ -253,6 +274,13 @@ where let message = LoadResponse { success: true, message: String::new(), + resources: resources + .lock() + .await + .clone() + .into_iter() + .map(resource::Response::into_bytes) + .collect(), }; Ok(Response::new(message)) } diff --git a/runtime/src/next/mod.rs b/runtime/src/next/mod.rs index 8b4152b51..7a6a6bbce 100644 --- a/runtime/src/next/mod.rs +++ b/runtime/src/next/mod.rs @@ -92,6 +92,7 @@ impl Runtime for AxumWasm { let message = LoadResponse { success: true, message: String::new(), + resources: Vec::new(), }; Ok(tonic::Response::new(message)) diff --git a/runtime/src/provisioner_factory.rs b/runtime/src/provisioner_factory.rs index 7c21332c0..87d2f3a12 100644 --- a/runtime/src/provisioner_factory.rs +++ b/runtime/src/provisioner_factory.rs @@ -4,13 +4,13 @@ use async_trait::async_trait; use shuttle_common::{ claims::{Claim, ClaimService, InjectPropagation}, database, + resource::{self, ResourceInfo}, storage_manager::StorageManager, DatabaseReadyInfo, }; -use shuttle_proto::provisioner::{ - database_request::DbType, provisioner_client::ProvisionerClient, DatabaseRequest, -}; +use shuttle_proto::provisioner::{provisioner_client::ProvisionerClient, DatabaseRequest}; use shuttle_service::{Environment, Factory, ServiceName}; +use tokio::sync::Mutex; use tonic::{transport::Channel, Request}; use tracing::{debug, info, trace}; @@ -19,10 +19,10 @@ pub struct ProvisionerFactory { service_name: ServiceName, storage_manager: Arc, provisioner_client: ProvisionerClient>>, - info: Option, secrets: BTreeMap, env: Environment, claim: Option, + resources: Arc>>, } impl ProvisionerFactory { @@ -33,15 +33,16 @@ impl ProvisionerFactory { storage_manager: Arc, env: Environment, claim: Option, + resources: Arc>>, ) -> Self { Self { provisioner_client, service_name, storage_manager, - info: None, secrets, env, claim, + resources, } } } @@ -54,16 +55,22 @@ impl Factory for ProvisionerFactory { ) -> Result { info!("Provisioning a {db_type}. This can take a while..."); - if let Some(ref info) = self.info { + if let Some(info) = self + .resources + .lock() + .await + .iter() + .find(|resource| resource.r#type == resource::Type::Database(db_type.clone())) + { debug!("A database has already been provisioned for this deployment, so reusing it"); - return Ok(info.connection_string_private()); - } - let db_type: DbType = db_type.into(); + let resource = info.get_resource_info(); + return Ok(resource.connection_string_private()); + } - let request = Request::new(DatabaseRequest { + let mut request = Request::new(DatabaseRequest { project_name: self.service_name.to_string(), - db_type: Some(db_type), + db_type: Some(db_type.clone().into()), }); if let Some(claim) = &self.claim { @@ -80,10 +87,14 @@ impl Factory for ProvisionerFactory { let info: DatabaseReadyInfo = response.into(); let conn_str = info.connection_string_private(); - self.info = Some(info); + self.resources.lock().await.push(resource::Response { + r#type: resource::Type::Database(db_type), + data: serde_json::to_value(&info).expect("to convert DB info"), + }); info!("Done provisioning database"); trace!("giving a DB connection string: {}", conn_str); + Ok(conn_str) } From 9f19e5fb1c89efdbe0ff39ffdbf17af0ef97ce29 Mon Sep 17 00:00:00 2001 From: chesedo Date: Wed, 15 Mar 2023 15:16:28 +0200 Subject: [PATCH 3/7] refactor: restore resources for idle containers waking up --- cargo-shuttle/src/lib.rs | 1 + common/src/resource.rs | 4 ++++ deployer/src/deployment/run.rs | 15 +++++++++++++++ proto/runtime.proto | 5 ++++- runtime/src/alpha/mod.rs | 8 +++++++- runtime/tests/integration/loader.rs | 1 + 6 files changed, 32 insertions(+), 2 deletions(-) diff --git a/cargo-shuttle/src/lib.rs b/cargo-shuttle/src/lib.rs index ee118d331..567bbb6b4 100644 --- a/cargo-shuttle/src/lib.rs +++ b/cargo-shuttle/src/lib.rs @@ -543,6 +543,7 @@ impl Shuttle { .into_string() .expect("to convert path to string"), service_name: service_name.clone(), + resources: Default::default(), secrets, }); trace!("loading service"); diff --git a/common/src/resource.rs b/common/src/resource.rs index 67021bd9b..976020729 100644 --- a/common/src/resource.rs +++ b/common/src/resource.rs @@ -48,6 +48,10 @@ impl Response { pub fn into_bytes(self) -> Vec { serde_json::to_vec(&self).expect("to turn resource into a vec") } + + pub fn from_bytes(bytes: Vec) -> Self { + serde_json::from_slice(&bytes).expect("to turn bytes into a resource") + } } impl Display for Type { diff --git a/deployer/src/deployment/run.rs b/deployer/src/deployment/run.rs index 7529314d1..5978b7ba4 100644 --- a/deployer/src/deployment/run.rs +++ b/deployer/src/deployment/run.rs @@ -265,6 +265,20 @@ async fn load( .unwrap_or_default() ); + // Get resources from cache when a claim is not set (ie an idl project is started) + let resources = if claim.is_none() { + resource_manager + .get_resources(&service_id) + .await + .unwrap() + .into_iter() + .map(resource::Response::from) + .map(resource::Response::into_bytes) + .collect() + } else { + Default::default() + }; + let secrets = secret_getter .get_secrets(&service_id) .await @@ -279,6 +293,7 @@ async fn load( .into_string() .unwrap_or_default(), service_name: service_name.clone(), + resources, secrets, }); diff --git a/proto/runtime.proto b/proto/runtime.proto index 2be6c9d81..2dee8806a 100644 --- a/proto/runtime.proto +++ b/proto/runtime.proto @@ -27,8 +27,11 @@ message LoadRequest { // Path to compiled file to load for service string path = 2; + // A cache of resource details to use instead when asked + repeated bytes resources = 10; + // Secrets that belong to this deployment - map secrets = 10; + map secrets = 20; } message LoadResponse { diff --git a/runtime/src/alpha/mod.rs b/runtime/src/alpha/mod.rs index 149c7232a..828ee421e 100644 --- a/runtime/src/alpha/mod.rs +++ b/runtime/src/alpha/mod.rs @@ -171,6 +171,7 @@ where let LoadRequest { path, + resources, secrets, service_name, } = request.into_inner(); @@ -195,7 +196,12 @@ where let service_name = ServiceName::from_str(service_name.as_str()) .map_err(|err| Status::from_error(Box::new(err)))?; - let resources: Arc>> = Default::default(); + let resources = resources + .into_iter() + .map(resource::Response::from_bytes) + .collect(); + let resources: Arc>> = + Arc::new(tokio::sync::Mutex::new(resources)); let factory = ProvisionerFactory::new( provisioner_client, diff --git a/runtime/tests/integration/loader.rs b/runtime/tests/integration/loader.rs index fb62d6878..32abc0c04 100644 --- a/runtime/tests/integration/loader.rs +++ b/runtime/tests/integration/loader.rs @@ -17,6 +17,7 @@ async fn bind_panic() { let load_request = tonic::Request::new(LoadRequest { path: bin_path, service_name, + resources: Default::default(), secrets, }); From f89c2823d11a5d2e7aaff86966bc62c449669e57 Mon Sep 17 00:00:00 2001 From: chesedo Date: Wed, 15 Mar 2023 16:00:09 +0200 Subject: [PATCH 4/7] tests: next tests using wrong folder --- common/Cargo.toml | 4 ++-- common/src/lib.rs | 1 - runtime/tests/resources/axum-wasm-expanded/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/common/Cargo.toml b/common/Cargo.toml index c062390de..ec5b0af67 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -32,7 +32,7 @@ rmp-serde = { version = "1.1.1", optional = true } rustrict = { version = "0.5.5", optional = true } serde = { workspace = true, features = ["derive", "std"] } serde_json = { workspace = true } -strum = { workspace = true, features = ["derive"], optional = true } +strum = { workspace = true, features = ["derive"] } thiserror = { workspace = true, optional = true } tonic = { version = "0.8.3", optional = true } tower = { workspace = true, optional = true } @@ -49,7 +49,7 @@ claims = ["bytes", "chrono/clock", "headers", "http", "http-body", "jsonwebtoken display = ["chrono/clock", "comfy-table", "crossterm"] error = ["prost-types", "thiserror", "uuid"] models = ["anyhow", "async-trait", "display", "http", "reqwest", "service"] -service = ["chrono/serde", "once_cell", "rustrict", "serde/derive", "strum", "uuid"] +service = ["chrono/serde", "once_cell", "rustrict", "serde/derive", "uuid"] tracing = [] wasm = ["chrono/clock", "http-serde", "http", "rmp-serde", "tracing", "tracing-subscriber"] diff --git a/common/src/lib.rs b/common/src/lib.rs index 6afac4432..9d8162e9b 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -2,7 +2,6 @@ pub mod backends; #[cfg(feature = "claims")] pub mod claims; -#[cfg(feature = "service")] pub mod database; #[cfg(feature = "service")] pub mod deployment; diff --git a/runtime/tests/resources/axum-wasm-expanded/Cargo.toml b/runtime/tests/resources/axum-wasm-expanded/Cargo.toml index 7972f7b6c..45f77cbe1 100644 --- a/runtime/tests/resources/axum-wasm-expanded/Cargo.toml +++ b/runtime/tests/resources/axum-wasm-expanded/Cargo.toml @@ -10,5 +10,5 @@ crate-type = [ "cdylib" ] [dependencies] futures = "0.3.25" -shuttle-next = { path = "../../../../next" } +shuttle-next = { path = "../../../../services/shuttle-next" } tracing = "0.1.37" From f366170e9c1db42bd1e95854a1c69f8d40847beb Mon Sep 17 00:00:00 2001 From: chesedo Date: Wed, 15 Mar 2023 16:03:45 +0200 Subject: [PATCH 5/7] tests: swap rocket for the more stable poem --- cargo-shuttle/tests/integration/run.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cargo-shuttle/tests/integration/run.rs b/cargo-shuttle/tests/integration/run.rs index cc2244520..eab40488a 100644 --- a/cargo-shuttle/tests/integration/run.rs +++ b/cargo-shuttle/tests/integration/run.rs @@ -92,6 +92,7 @@ async fn rocket_secrets() { // This example uses a shared Postgres. Thus local runs should create a docker container for it. #[tokio::test(flavor = "multi_thread")] +#[ignore] async fn rocket_postgres() { let url = cargo_shuttle_run("../examples/rocket/postgres", false).await; let client = reqwest::Client::new(); @@ -281,7 +282,6 @@ async fn poem_hello_world() { // This example uses a shared Postgres. Thus local runs should create a docker container for it. #[tokio::test(flavor = "multi_thread")] -#[ignore] async fn poem_postgres() { let url = cargo_shuttle_run("../examples/poem/postgres", false).await; let client = reqwest::Client::new(); From 7d73adbdd9329f31a31a10a02a7c71c683612772 Mon Sep 17 00:00:00 2001 From: chesedo Date: Thu, 16 Mar 2023 08:13:00 +0200 Subject: [PATCH 6/7] refactor: pass auth_uri to runtime --- cargo-shuttle/src/lib.rs | 1 + deployer/src/deployment/deploy_layer.rs | 2 +- deployer/src/deployment/run.rs | 2 +- deployer/src/main.rs | 1 + deployer/src/runtime_manager.rs | 4 ++++ proto/src/lib.rs | 11 +++++++++-- runtime/tests/integration/helpers.rs | 1 + 7 files changed, 18 insertions(+), 4 deletions(-) diff --git a/cargo-shuttle/src/lib.rs b/cargo-shuttle/src/lib.rs index 567bbb6b4..dcfa746c6 100644 --- a/cargo-shuttle/src/lib.rs +++ b/cargo-shuttle/src/lib.rs @@ -527,6 +527,7 @@ impl Shuttle { is_wasm, runtime::StorageManagerType::WorkingDir(working_directory.to_path_buf()), &format!("http://localhost:{}", run_args.port + 1), + None, run_args.port + 2, runtime_path, ) diff --git a/deployer/src/deployment/deploy_layer.rs b/deployer/src/deployment/deploy_layer.rs index c89847af3..f38823a13 100644 --- a/deployer/src/deployment/deploy_layer.rs +++ b/deployer/src/deployment/deploy_layer.rs @@ -470,7 +470,7 @@ mod tests { let path = tmp_dir.into_path(); let (tx, _rx) = crossbeam_channel::unbounded(); - RuntimeManager::new(path, format!("http://{}", provisioner_addr), tx) + RuntimeManager::new(path, format!("http://{}", provisioner_addr), None, tx) } #[async_trait::async_trait] diff --git a/deployer/src/deployment/run.rs b/deployer/src/deployment/run.rs index 5978b7ba4..b3ae00815 100644 --- a/deployer/src/deployment/run.rs +++ b/deployer/src/deployment/run.rs @@ -480,7 +480,7 @@ mod tests { } }); - RuntimeManager::new(path, format!("http://{}", provisioner_addr), tx) + RuntimeManager::new(path, format!("http://{}", provisioner_addr), None, tx) } #[derive(Clone)] diff --git a/deployer/src/main.rs b/deployer/src/main.rs index 8a249cb63..11d178b1a 100644 --- a/deployer/src/main.rs +++ b/deployer/src/main.rs @@ -24,6 +24,7 @@ async fn main() { let runtime_manager = RuntimeManager::new( args.artifacts_path.clone(), args.provisioner_address.uri().to_string(), + Some(args.auth_uri.to_string()), persistence.get_log_sender(), ); diff --git a/deployer/src/runtime_manager.rs b/deployer/src/runtime_manager.rs index 0624cad52..7199f664c 100644 --- a/deployer/src/runtime_manager.rs +++ b/deployer/src/runtime_manager.rs @@ -33,6 +33,7 @@ pub struct RuntimeManager { runtimes: Runtimes, artifacts_path: PathBuf, provisioner_address: String, + auth_uri: Option, log_sender: crossbeam_channel::Sender, } @@ -40,12 +41,14 @@ impl RuntimeManager { pub fn new( artifacts_path: PathBuf, provisioner_address: String, + auth_uri: Option, log_sender: crossbeam_channel::Sender, ) -> Arc> { Arc::new(Mutex::new(Self { runtimes: Default::default(), artifacts_path, provisioner_address, + auth_uri, log_sender, })) } @@ -108,6 +111,7 @@ impl RuntimeManager { is_next, runtime::StorageManagerType::Artifacts(self.artifacts_path.clone()), &self.provisioner_address, + self.auth_uri.as_ref(), port, get_runtime_executable, ) diff --git a/proto/src/lib.rs b/proto/src/lib.rs index 283e358d2..6f8602591 100644 --- a/proto/src/lib.rs +++ b/proto/src/lib.rs @@ -210,6 +210,7 @@ pub mod runtime { wasm: bool, storage_manager_type: StorageManagerType, provisioner_address: &str, + auth_uri: Option<&String>, port: u16, get_runtime_executable: impl FnOnce() -> PathBuf, ) -> anyhow::Result<( @@ -228,7 +229,7 @@ pub mod runtime { let args = if wasm { vec!["--port", port] } else { - vec![ + let mut args = vec![ "--port", port, "--provisioner-address", @@ -237,7 +238,13 @@ pub mod runtime { storage_manager_type, "--storage-manager-path", storage_manager_path, - ] + ]; + + if let Some(auth_uri) = auth_uri { + args.append(&mut vec!["--auth-uri", auth_uri]); + } + + args }; let runtime = process::Command::new(runtime_executable_path) diff --git a/runtime/tests/integration/helpers.rs b/runtime/tests/integration/helpers.rs index c31babee0..0f2330237 100644 --- a/runtime/tests/integration/helpers.rs +++ b/runtime/tests/integration/helpers.rs @@ -55,6 +55,7 @@ pub async fn spawn_runtime(project_path: String, service_name: &str) -> Result Date: Thu, 16 Mar 2023 08:21:55 +0200 Subject: [PATCH 7/7] misc: update all patches --- .circleci/config.yml | 5 +- CONTRIBUTING.md | 17 ++++++- e2e/tests/integration/helpers/mod.rs | 76 +++++++++++++++++++++++++--- 3 files changed, 89 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 646569151..f21e0a9e5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -88,14 +88,17 @@ commands: cat\<< EOF > ~/.cargo/config.toml [patch.crates-io] shuttle-service = { path = "$PWD/service" } + shuttle-runtime = { path = "$PWD/runtime" } + shuttle-aws-rds = { path = "$PWD/resources/aws-rds" } shuttle-persist = { path = "$PWD/resources/persist" } - shuttle-runtime = { path = "$PWD/runtime" } shuttle-shared-db = { path = "$PWD/resources/shared-db" } shuttle-secrets = { path = "$PWD/resources/secrets" } shuttle-static-folder = { path = "$PWD/resources/static-folder" } + shuttle-axum = { path = "$PWD/services/shuttle-axum" } shuttle-actix-web = { path = "$PWD/services/shuttle-actix-web" } + shuttle-next = { path = "$PWD/services/shuttle-next" } shuttle-poem = { path = "$PWD/services/shuttle-poem" } shuttle-poise = { path = "$PWD/services/shuttle-poise" } shuttle-rocket = { path = "$PWD/services/shuttle-rocket" } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c60695da7..e4569995c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,13 +56,26 @@ In order to test local changes to the library crates, you may want to add the be ```toml [patch.crates-io] shuttle-service = { path = "[base]/shuttle/service" } -shuttle-common = { path = "[base]/shuttle/common" } -shuttle-proto = { path = "[base]/shuttle/proto" } +shuttle-runtime = { path = "[base]/shuttle/runtime" } + shuttle-aws-rds = { path = "[base]/shuttle/resources/aws-rds" } shuttle-persist = { path = "[base]/shuttle/resources/persist" } shuttle-shared-db = { path = "[base]/shuttle/resources/shared-db" } shuttle-secrets = { path = "[base]/shuttle/resources/secrets" } shuttle-static-folder = { path = "[base]/shuttle/resources/static-folder" } + +shuttle-axum = { path = "[base]/shuttle/services/shuttle-axum" } +shuttle-actix-web = { path = "[base]/shuttle/services/shuttle-actix-web" } +shuttle-next = { path = "[base]/shuttle/services/shuttle-next" } +shuttle-poem = { path = "[base]/shuttle/services/shuttle-poem" } +shuttle-poise = { path = "[base]/shuttle/services/shuttle-poise" } +shuttle-rocket = { path = "[base]/shuttle/services/shuttle-rocket" } +shuttle-salvo = { path = "[base]/shuttle/services/shuttle-salvo" } +shuttle-serenity = { path = "[base]/shuttle/services/shuttle-serenity" } +shuttle-thruster = { path = "[base]/shuttle/services/shuttle-thruster" } +shuttle-tide = { path = "[base]/shuttle/services/shuttle-tide" } +shuttle-tower = { path = "[base]/shuttle/services/shuttle-tower" } +shuttle-warp = { path = "[base]/shuttle/services/shuttle-warp" } ``` Before we can login to our local instance of shuttle, we need to create a user. diff --git a/e2e/tests/integration/helpers/mod.rs b/e2e/tests/integration/helpers/mod.rs index 45a4e1dab..fe6e1e6c1 100644 --- a/e2e/tests/integration/helpers/mod.rs +++ b/e2e/tests/integration/helpers/mod.rs @@ -38,13 +38,29 @@ impl TempCargoHome { write!( config, r#"[patch.crates-io] -shuttle-service = {{ path = "{}" }} -shuttle-aws-rds = {{ path = "{}" }} -shuttle-persist = {{ path = "{}" }} -shuttle-shared-db = {{ path = "{}" }} -shuttle-secrets = {{ path = "{}" }} -shuttle-static-folder = {{ path = "{}" }}"#, +shuttle-service = { path = "{}" } +shuttle-runtime = { path = "{}" } + +shuttle-aws-rds = { path = "{}" } +shuttle-persist = { path = "{}" } +shuttle-shared-db = { path = "{}" } +shuttle-secrets = { path = "{}" } +shuttle-static-folder = { path = "{}" } + +shuttle-axum = { path = "{}" } +shuttle-actix-web = { path = "{}" } +shuttle-next = { path = "{}" } +shuttle-poem = { path = "{}" } +shuttle-poise = { path = "{}" } +shuttle-rocket = { path = "{}" } +shuttle-salvo = { path = "{}" } +shuttle-serenity = { path = "{}" } +shuttle-thruster = { path = "{}" } +shuttle-tide = { path = "{}" } +shuttle-tower = { path = "{}" } +shuttle-warp = { path = "{}" }"#, WORKSPACE_ROOT.join("service").display(), + WORKSPACE_ROOT.join("runtime").display(), WORKSPACE_ROOT.join("resources").join("aws-rds").display(), WORKSPACE_ROOT.join("resources").join("persist").display(), WORKSPACE_ROOT.join("resources").join("shared-db").display(), @@ -53,6 +69,54 @@ shuttle-static-folder = {{ path = "{}" }}"#, .join("resources") .join("static-folder") .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-axum") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-actix-web") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-next") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-poem") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-poise") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-rocket") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-salvo") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-serenity") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-thruster") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-tide") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-tower") + .display(), + WORKSPACE_ROOT + .join("services") + .join("shuttle-warp") + .display(), ) .unwrap();