From cd61f41dcf4cc5023e2c5114ba6c42f7b067426d Mon Sep 17 00:00:00 2001 From: oddgrd <29732646+oddgrd@users.noreply.github.com> Date: Fri, 7 Jun 2024 12:33:06 +0200 Subject: [PATCH 1/8] feat: add state to resource response --- backends/src/resource.rs | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/backends/src/resource.rs b/backends/src/resource.rs index ae782cff5..cc15c86d6 100644 --- a/backends/src/resource.rs +++ b/backends/src/resource.rs @@ -1,4 +1,10 @@ +use std::str::FromStr; + use serde::{Deserialize, Serialize}; +use sqlx::{ + postgres::{PgArgumentBuffer, PgValueRef}, + Postgres, +}; /// Used by the runner service to send requests to control plane, where the requested resources /// will be provisioned. @@ -7,3 +13,51 @@ pub struct ResourceRequest { /// The resource input returned from the runtime::load call. pub resources: Vec>, } + +/// The resource state represents the stage of the provisioning process the resource is in. +#[derive( + Debug, Clone, PartialEq, Eq, strum::Display, strum::EnumString, Serialize, Deserialize, +)] +#[strum(serialize_all = "lowercase")] +pub enum ResourceState { + Authorizing, + Provisioning, + Failed, + Ready, + Deleting, + Deleted, +} + +impl sqlx::Type for ResourceState +where + str: sqlx::Type, +{ + fn type_info() -> ::TypeInfo { + >::type_info() + } +} + +impl<'q> sqlx::Encode<'q, sqlx::Postgres> for ResourceState { + fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> sqlx::encode::IsNull { + <&str as sqlx::Encode>::encode(&self.to_string(), buf) + } +} + +impl<'r> sqlx::Decode<'r, Postgres> for ResourceState { + fn decode(value: PgValueRef<'r>) -> Result { + let value = <&str as sqlx::Decode>::decode(value)?; + + let state = ResourceState::from_str(value)?; + Ok(state) + } +} + +/// Used by the runner service to send requests to control plane, where the requested resources +/// will be provisioned. +#[derive(Serialize, Deserialize)] +pub struct ResourceResponse { + /// The resource output returned from the control plane after provisioning. + pub resources: Vec>, + /// The state of the resource. + pub state: ResourceState, +} From 26e8b2147e0456c488d5898721c80947ee1664cb Mon Sep 17 00:00:00 2001 From: oddgrd <29732646+oddgrd@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:33:38 +0200 Subject: [PATCH 2/8] feat: move resourcestate to common, add state to db output --- cargo-shuttle/src/lib.rs | 4 +++ common/Cargo.toml | 2 +- common/src/resource.rs | 46 ++++++++++++++++++++++++++++++++-- deployer/src/deployment/run.rs | 4 ++- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/cargo-shuttle/src/lib.rs b/cargo-shuttle/src/lib.rs index 2662cfe0d..a7125949e 100644 --- a/cargo-shuttle/src/lib.rs +++ b/cargo-shuttle/src/lib.rs @@ -32,6 +32,7 @@ use ignore::overrides::OverrideBuilder; use ignore::WalkBuilder; use indicatif::ProgressBar; use indoc::{formatdoc, printdoc}; +use shuttle_common::resource::ResourceState; use shuttle_common::{ constants::{ API_URL_DEFAULT, DEFAULT_IDLE_MINUTES, EXAMPLES_REPO, EXECUTABLE_DIRNAME, @@ -1369,6 +1370,7 @@ impl Shuttle { *bytes = serde_json::to_vec(&ShuttleResourceOutput { output: res, custom: shuttle_resource.custom, + state: ResourceState::Ready }) .unwrap(); } @@ -1382,6 +1384,7 @@ impl Shuttle { *bytes = serde_json::to_vec(&ShuttleResourceOutput { output: secrets.clone(), custom: shuttle_resource.custom, + state: ResourceState::Ready }) .unwrap(); } @@ -1400,6 +1403,7 @@ impl Shuttle { *bytes = serde_json::to_vec(&ShuttleResourceOutput { output: res, custom: shuttle_resource.custom, + state: ResourceState::Ready }) .unwrap(); } diff --git a/common/Cargo.toml b/common/Cargo.toml index 89ea63a15..544a953bf 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -67,7 +67,7 @@ extract_propagation = [ ] models = ["async-trait", "reqwest", "service"] persist = ["sqlx", "rand"] -sqlx = ["dep:sqlx", "sqlx/sqlite"] +sqlx = ["dep:sqlx", "sqlx/sqlite", "sqlx/postgres"] service = ["chrono/serde", "display", "tracing", "tracing-subscriber", "uuid"] test-utils = ["wiremock"] tonic = ["dep:tonic"] diff --git a/common/src/resource.rs b/common/src/resource.rs index 0fdb65d0c..9005d71b2 100644 --- a/common/src/resource.rs +++ b/common/src/resource.rs @@ -40,6 +40,20 @@ pub enum ResourceInput { Custom(Value), } +/// The resource state represents the stage of the provisioning process the resource is in. +#[derive( + Debug, Clone, PartialEq, Eq, strum::Display, strum::EnumString, Serialize, Deserialize, +)] +#[strum(serialize_all = "lowercase")] +pub enum ResourceState { + Authorizing, + Provisioning, + Failed, + Ready, + Deleting, + Deleted, +} + /// Returned when provisioning a Shuttle resource #[derive(Serialize, Deserialize)] pub struct ShuttleResourceOutput { @@ -49,6 +63,9 @@ pub struct ShuttleResourceOutput { /// Arbitrary extra data in this resource pub custom: Value, + + /// The state of the resource. + pub state: ResourceState, } /// Common type to hold all the information we need for a generic resource @@ -136,11 +153,12 @@ mod _sqlx { use std::{borrow::Cow, str::FromStr}; use sqlx::{ + postgres::{PgArgumentBuffer, PgValueRef}, sqlite::{SqliteArgumentValue, SqliteValueRef}, - Database, Sqlite, + Database, Postgres, Sqlite, }; - use super::Type; + use super::{ResourceState, Type}; impl sqlx::Type for Type where @@ -166,6 +184,30 @@ mod _sqlx { Self::from_str(value).map_err(Into::into) } } + + impl sqlx::Type for ResourceState + where + str: sqlx::Type, + { + fn type_info() -> ::TypeInfo { + >::type_info() + } + } + + impl<'q> sqlx::Encode<'q, sqlx::Postgres> for ResourceState { + fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> sqlx::encode::IsNull { + <&str as sqlx::Encode>::encode(&self.to_string(), buf) + } + } + + impl<'r> sqlx::Decode<'r, Postgres> for ResourceState { + fn decode(value: PgValueRef<'r>) -> Result { + let value = <&str as sqlx::Decode>::decode(value)?; + + let state = ResourceState::from_str(value)?; + Ok(state) + } + } } #[cfg(test)] diff --git a/deployer/src/deployment/run.rs b/deployer/src/deployment/run.rs index c54df4ce1..fe79c206a 100644 --- a/deployer/src/deployment/run.rs +++ b/deployer/src/deployment/run.rs @@ -17,7 +17,7 @@ use shuttle_common::{ DEPLOYER_END_MSG_COMPLETED, DEPLOYER_END_MSG_CRASHED, DEPLOYER_END_MSG_STARTUP_ERR, DEPLOYER_END_MSG_STOPPED, DEPLOYER_RUNTIME_START_FAILED, DEPLOYER_RUNTIME_START_RESPONSE, }, - resource::{self, ResourceInput, Type}, + resource::{self, ResourceInput, ResourceState, Type}, DatabaseResource, DbInput, SecretStore, }; use shuttle_proto::{ @@ -536,6 +536,7 @@ async fn provision( *bytes = serde_json::to_vec(&ShuttleResourceOutput { output, custom: shuttle_resource.custom, + state: ResourceState::Ready }) .expect("to serialize struct"); } @@ -549,6 +550,7 @@ async fn provision( *bytes = serde_json::to_vec(&ShuttleResourceOutput { output: new_secrets.clone(), custom: shuttle_resource.custom, + state: ResourceState::Ready }) .expect("to serialize struct"); } From 559547f0b766357f3ad5ad9a48ebc0509903737a Mon Sep 17 00:00:00 2001 From: oddgrd <29732646+oddgrd@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:02:32 +0200 Subject: [PATCH 3/8] feat: remove resourcestate, response from backends --- backends/src/resource.rs | 54 ---------------------------------------- 1 file changed, 54 deletions(-) diff --git a/backends/src/resource.rs b/backends/src/resource.rs index cc15c86d6..ae782cff5 100644 --- a/backends/src/resource.rs +++ b/backends/src/resource.rs @@ -1,10 +1,4 @@ -use std::str::FromStr; - use serde::{Deserialize, Serialize}; -use sqlx::{ - postgres::{PgArgumentBuffer, PgValueRef}, - Postgres, -}; /// Used by the runner service to send requests to control plane, where the requested resources /// will be provisioned. @@ -13,51 +7,3 @@ pub struct ResourceRequest { /// The resource input returned from the runtime::load call. pub resources: Vec>, } - -/// The resource state represents the stage of the provisioning process the resource is in. -#[derive( - Debug, Clone, PartialEq, Eq, strum::Display, strum::EnumString, Serialize, Deserialize, -)] -#[strum(serialize_all = "lowercase")] -pub enum ResourceState { - Authorizing, - Provisioning, - Failed, - Ready, - Deleting, - Deleted, -} - -impl sqlx::Type for ResourceState -where - str: sqlx::Type, -{ - fn type_info() -> ::TypeInfo { - >::type_info() - } -} - -impl<'q> sqlx::Encode<'q, sqlx::Postgres> for ResourceState { - fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> sqlx::encode::IsNull { - <&str as sqlx::Encode>::encode(&self.to_string(), buf) - } -} - -impl<'r> sqlx::Decode<'r, Postgres> for ResourceState { - fn decode(value: PgValueRef<'r>) -> Result { - let value = <&str as sqlx::Decode>::decode(value)?; - - let state = ResourceState::from_str(value)?; - Ok(state) - } -} - -/// Used by the runner service to send requests to control plane, where the requested resources -/// will be provisioned. -#[derive(Serialize, Deserialize)] -pub struct ResourceResponse { - /// The resource output returned from the control plane after provisioning. - pub resources: Vec>, - /// The state of the resource. - pub state: ResourceState, -} From 7a5a4c6f277a8d2eda6a2993ef126164fafde6ee Mon Sep 17 00:00:00 2001 From: oddgrd <29732646+oddgrd@users.noreply.github.com> Date: Sun, 9 Jun 2024 13:11:25 +0200 Subject: [PATCH 4/8] feat: make res req clone --- backends/src/resource.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/src/resource.rs b/backends/src/resource.rs index ae782cff5..fd51a904d 100644 --- a/backends/src/resource.rs +++ b/backends/src/resource.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; /// Used by the runner service to send requests to control plane, where the requested resources /// will be provisioned. -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Clone)] pub struct ResourceRequest { /// The resource input returned from the runtime::load call. pub resources: Vec>, From c2a8ba9d0d2c17e2e0de96087c38c09674260f38 Mon Sep 17 00:00:00 2001 From: oddgrd <29732646+oddgrd@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:01:36 +0200 Subject: [PATCH 5/8] refactor: remove deleted state --- common/src/resource.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/common/src/resource.rs b/common/src/resource.rs index 9005d71b2..5c0537b2d 100644 --- a/common/src/resource.rs +++ b/common/src/resource.rs @@ -51,7 +51,6 @@ pub enum ResourceState { Failed, Ready, Deleting, - Deleted, } /// Returned when provisioning a Shuttle resource From b4f52bd919970f94b327e8956e3cf83f8eadd9c2 Mon Sep 17 00:00:00 2001 From: oddgrd <29732646+oddgrd@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:15:49 +0200 Subject: [PATCH 6/8] fix: make resourcestate optional --- cargo-shuttle/src/lib.rs | 7 +++---- common/src/resource.rs | 2 +- deployer/src/deployment/run.rs | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/cargo-shuttle/src/lib.rs b/cargo-shuttle/src/lib.rs index 8fa49d842..cdcd0db00 100644 --- a/cargo-shuttle/src/lib.rs +++ b/cargo-shuttle/src/lib.rs @@ -35,7 +35,6 @@ use indoc::{formatdoc, printdoc}; use shuttle_common::models::deployment::{ BuildMetaBeta, DeploymentRequestBuildArchiveBeta, DeploymentRequestImageBeta, }; -use shuttle_common::resource::ResourceState; use shuttle_common::{ constants::{ API_URL_DEFAULT, DEFAULT_IDLE_MINUTES, EXAMPLES_REPO, EXECUTABLE_DIRNAME, @@ -1373,7 +1372,7 @@ impl Shuttle { *bytes = serde_json::to_vec(&ShuttleResourceOutput { output: res, custom: shuttle_resource.custom, - state: ResourceState::Ready + state: None }) .unwrap(); } @@ -1387,7 +1386,7 @@ impl Shuttle { *bytes = serde_json::to_vec(&ShuttleResourceOutput { output: secrets.clone(), custom: shuttle_resource.custom, - state: ResourceState::Ready + state: None }) .unwrap(); } @@ -1406,7 +1405,7 @@ impl Shuttle { *bytes = serde_json::to_vec(&ShuttleResourceOutput { output: res, custom: shuttle_resource.custom, - state: ResourceState::Ready + state: None }) .unwrap(); } diff --git a/common/src/resource.rs b/common/src/resource.rs index 5c0537b2d..a0776232e 100644 --- a/common/src/resource.rs +++ b/common/src/resource.rs @@ -64,7 +64,7 @@ pub struct ShuttleResourceOutput { pub custom: Value, /// The state of the resource. - pub state: ResourceState, + pub state: Option, } /// Common type to hold all the information we need for a generic resource diff --git a/deployer/src/deployment/run.rs b/deployer/src/deployment/run.rs index fe79c206a..2ff424125 100644 --- a/deployer/src/deployment/run.rs +++ b/deployer/src/deployment/run.rs @@ -17,7 +17,7 @@ use shuttle_common::{ DEPLOYER_END_MSG_COMPLETED, DEPLOYER_END_MSG_CRASHED, DEPLOYER_END_MSG_STARTUP_ERR, DEPLOYER_END_MSG_STOPPED, DEPLOYER_RUNTIME_START_FAILED, DEPLOYER_RUNTIME_START_RESPONSE, }, - resource::{self, ResourceInput, ResourceState, Type}, + resource::{self, ResourceInput, Type}, DatabaseResource, DbInput, SecretStore, }; use shuttle_proto::{ @@ -536,7 +536,7 @@ async fn provision( *bytes = serde_json::to_vec(&ShuttleResourceOutput { output, custom: shuttle_resource.custom, - state: ResourceState::Ready + state: None }) .expect("to serialize struct"); } @@ -550,7 +550,7 @@ async fn provision( *bytes = serde_json::to_vec(&ShuttleResourceOutput { output: new_secrets.clone(), custom: shuttle_resource.custom, - state: ResourceState::Ready + state: None }) .expect("to serialize struct"); } From f8e4481259d33ecb393737b7e4d7c619fc4866c1 Mon Sep 17 00:00:00 2001 From: oddgrd <29732646+oddgrd@users.noreply.github.com> Date: Thu, 13 Jun 2024 17:54:06 +0200 Subject: [PATCH 7/8] feat: backend types for provisioning --- backends/src/resource.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/backends/src/resource.rs b/backends/src/resource.rs index fd51a904d..536fa99a8 100644 --- a/backends/src/resource.rs +++ b/backends/src/resource.rs @@ -3,7 +3,14 @@ use serde::{Deserialize, Serialize}; /// Used by the runner service to send requests to control plane, where the requested resources /// will be provisioned. #[derive(Serialize, Deserialize, Clone)] -pub struct ResourceRequest { +pub struct LoadResponse { /// The resource input returned from the runtime::load call. pub resources: Vec>, } + +/// Used by the control plane to return provisioned resource data to the runner. +#[derive(Serialize, Deserialize, Clone)] +pub struct ResourceResponse { + /// The resource output returned from provisioning. + pub resource: Vec, +} From a5835c06c1afd5ad80f65b027dd7437e9f8d4b0d Mon Sep 17 00:00:00 2001 From: oddgrd <29732646+oddgrd@users.noreply.github.com> Date: Thu, 13 Jun 2024 19:23:23 +0200 Subject: [PATCH 8/8] revert: remove loadresponse --- backends/src/resource.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/backends/src/resource.rs b/backends/src/resource.rs index 536fa99a8..3b6e0a8fc 100644 --- a/backends/src/resource.rs +++ b/backends/src/resource.rs @@ -1,13 +1,5 @@ use serde::{Deserialize, Serialize}; -/// Used by the runner service to send requests to control plane, where the requested resources -/// will be provisioned. -#[derive(Serialize, Deserialize, Clone)] -pub struct LoadResponse { - /// The resource input returned from the runtime::load call. - pub resources: Vec>, -} - /// Used by the control plane to return provisioned resource data to the runner. #[derive(Serialize, Deserialize, Clone)] pub struct ResourceResponse {