Skip to content

Commit

Permalink
fix: beta local run resource fixes (#1876)
Browse files Browse the repository at this point in the history
* wip: local run resource fixes

* feat(shared-db): only request postgres if no local_uri

* fix: don't request shared db if local_uri provided

* fix: always request shared db in deployment

* nit

* nit
  • Loading branch information
jonaro00 authored Sep 25, 2024
1 parent 243daff commit 793f2b1
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 39 deletions.
21 changes: 11 additions & 10 deletions cargo-shuttle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ impl Shuttle {
Command::Account => self.account().await,
Command::Login(login_args) => self.login(login_args, args.offline).await,
Command::Logout(logout_args) => self.logout(logout_args).await,
Command::Feedback => self.feedback(),
Command::Feedback => feedback(),
Command::Run(run_args) => {
if self.beta {
self.local_run_beta(run_args, args.debug).await
Expand Down Expand Up @@ -774,14 +774,6 @@ impl Shuttle {
self.ctx.load_local(project_args)
}

/// Provide feedback on GitHub.
fn feedback(&self) -> Result<()> {
let _ = webbrowser::open(SHUTTLE_GH_ISSUE_URL);
println!("If your browser did not open automatically, go to {SHUTTLE_GH_ISSUE_URL}");

Ok(())
}

async fn account(&self) -> Result<()> {
let client = self.client.as_ref().unwrap();
let user = client.get_current_user_beta().await?;
Expand Down Expand Up @@ -2358,7 +2350,9 @@ impl Shuttle {
}
}

eprintln!("Packing files...");
if self.beta {
eprintln!("Packing files...");
}
let archive = self.make_archive(args.secret_args.secrets.clone(), self.beta)?;

if let Some(path) = args.output_archive {
Expand Down Expand Up @@ -3237,6 +3231,13 @@ fn create_spinner() -> ProgressBar {
pb
}

fn feedback() -> Result<()> {
let _ = webbrowser::open(SHUTTLE_GH_ISSUE_URL);
eprintln!("If your browser did not open automatically, go to {SHUTTLE_GH_ISSUE_URL}");

Ok(())
}

async fn update_cargo_shuttle(preview: bool) -> Result<()> {
if preview {
let _ = tokio::process::Command::new("cargo")
Expand Down
38 changes: 21 additions & 17 deletions cargo-shuttle/src/provisioner_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ pub mod beta {
};
use shuttle_common::{
database,
models::resource::get_resource_tables_beta,
resource::{
self, ProvisionResourceRequestBeta, ResourceResponseBeta, ResourceState,
ResourceTypeBeta,
Expand Down Expand Up @@ -577,13 +578,16 @@ pub mod beta {
) -> Result<Vec<u8>> {
Ok(match (method, uri) {
(Method::GET, "/projects/proj_LOCAL/resources/secrets") => {
serde_json::to_vec(&ResourceResponseBeta {
let response = ResourceResponseBeta {
r#type: ResourceTypeBeta::Secrets,
state: ResourceState::Ready,
config: serde_json::Value::Null,
output: serde_json::to_value(&state.secrets).unwrap(),
})
.unwrap()
};
let table =
get_resource_tables_beta(&[response.clone()], "local service", false, true);
println!("{table}");
serde_json::to_vec(&response).unwrap()
}
(Method::POST, "/projects/proj_LOCAL/resources") => {
let prov = LocalProvisioner::new().unwrap();
Expand All @@ -595,20 +599,16 @@ pub mod beta {
let config: DbInput =
serde_json::from_value(shuttle_resource.config.clone())
.context("deserializing resource config")?;
let res = match config.local_uri {
Some(local_uri) => DatabaseResource::ConnectionString(local_uri),
None => DatabaseResource::Info(
prov.provision_database(Request::new(DatabaseRequest {
project_name: state.project_name.clone(),
db_type: Some(database::Type::Shared(database::SharedEngine::Postgres).into()),
db_name: config.db_name,
}))
.await
.context("Failed to start database container. Make sure that a Docker engine is running.")?
.into_inner()
.into(),
),
};
let res = DatabaseResource::Info(
prov.provision_database(Request::new(DatabaseRequest {
project_name: state.project_name.clone(),
db_type: Some(database::Type::Shared(database::SharedEngine::Postgres).into()),
db_name: config.db_name,
}))
.await
.context("Failed to start database container. Make sure that a Docker engine is running.")?
.into_inner()
.into());
ResourceResponseBeta {
r#type: shuttle_resource.r#type,
state: resource::ResourceState::Ready,
Expand Down Expand Up @@ -638,6 +638,10 @@ pub mod beta {
other => unimplemented!("Resource {other} not supported yet"),
};

let table =
get_resource_tables_beta(&[response.clone()], "local service", false, true);
println!("{table}");

serde_json::to_vec(&response).unwrap()
}
_ => bail!("Received unsupported resource request"),
Expand Down
1 change: 1 addition & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ pub struct DatabaseInfoBeta {
role_password: String,
database_name: String,
port: String,
#[serde(alias = "hostname_shuttle")] // compatibility to parse from a `DatabaseInfo`
hostname: String,
/// The RDS instance name, which is required for deleting provisioned RDS instances, it's
/// optional because it isn't needed for shared PG deletion.
Expand Down
2 changes: 1 addition & 1 deletion common/src/models/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,5 +277,5 @@ fn get_secrets_table_beta(
table.add_row(vec![key]);
}

format!("These secrets can be accessed by {service_name}\n{table}\n")
format!("These secrets can be accessed by {service_name}\n{table}")
}
40 changes: 31 additions & 9 deletions resources/shared-db/src/postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use serde::{Deserialize, Serialize};
use shuttle_service::{
database,
resource::{ProvisionResourceRequest, ShuttleResourceOutput, Type},
DatabaseResource, DbInput, Error, IntoResource, ResourceFactory, ResourceInputBuilder,
DatabaseResource, DbInput, Environment, Error, IntoResource, ResourceFactory,
ResourceInputBuilder,
};

#[cfg(any(feature = "diesel-async-bb8", feature = "diesel-async-deadpool"))]
Expand Down Expand Up @@ -33,17 +34,38 @@ impl Postgres {
}
}

/// Conditionally request a Shuttle resource
#[derive(Serialize, Deserialize)]
#[serde(untagged)]
pub enum MaybeRequest {
Request(ProvisionResourceRequest),
NotRequest(DatabaseResource),
}

#[async_trait]
impl ResourceInputBuilder for Postgres {
type Input = ProvisionResourceRequest;
type Input = MaybeRequest;
type Output = OutputWrapper;

async fn build(self, _factory: &ResourceFactory) -> Result<Self::Input, Error> {
Ok(ProvisionResourceRequest::new(
Type::Database(database::Type::Shared(database::SharedEngine::Postgres)),
serde_json::to_value(self.0).unwrap(),
serde_json::Value::Null,
))
async fn build(self, factory: &ResourceFactory) -> Result<Self::Input, Error> {
let md = factory.get_metadata();
Ok(match md.env {
Environment::Deployment => MaybeRequest::Request(ProvisionResourceRequest::new(
Type::Database(database::Type::Shared(database::SharedEngine::Postgres)),
serde_json::to_value(self.0).unwrap(),
serde_json::Value::Null,
)),
Environment::Local => match self.0.local_uri {
Some(local_uri) => {
MaybeRequest::NotRequest(DatabaseResource::ConnectionString(local_uri))
}
None => MaybeRequest::Request(ProvisionResourceRequest::new(
Type::Database(database::Type::Shared(database::SharedEngine::Postgres)),
serde_json::to_value(self.0).unwrap(),
serde_json::Value::Null,
)),
},
})
}
}

Expand All @@ -62,7 +84,7 @@ impl IntoResource<String> for OutputWrapper {
Self::Beta(o) => o,
};
Ok(match output {
DatabaseResource::ConnectionString(s) => s.clone(),
DatabaseResource::ConnectionString(s) => s,
DatabaseResource::Info(info) => info.connection_string_shuttle(),
})
}
Expand Down
5 changes: 3 additions & 2 deletions runtime/src/beta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct BetaEnvArgs {
ip: IpAddr,
/// Port to open service on
port: u16,
/// Port to open health check on
/// Optional port to open health check on
healthz_port: Option<u16>,
/// Where to reach the required Shuttle API endpoints (mainly for provisioning)
api_url: String,
Expand Down Expand Up @@ -89,7 +89,8 @@ pub async fn start(loader: impl Loader + Send + 'static, runner: impl Runner + S
// start a health check server if requested
if let Some(healthz_port) = healthz_port {
trace!("Starting health check server on port {healthz_port}");
tokio::task::spawn(async move {
tokio::spawn(async move {
// light hyper server
let make_service = make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(|_req| async move {
trace!("Receivied health check");
Expand Down

0 comments on commit 793f2b1

Please sign in to comment.