Skip to content

Commit 88c877d

Browse files
oddgrdbrokad
andauthored
Feat: revive via gateway endpoint (#460)
* feat: revive via gateway api initial commit * feat: cleanup, document gateway testing * refactor: use post for revive endpoint Co-authored-by: Damien <[email protected]> * feat: send task to global queue Co-authored-by: Damien <[email protected]>
1 parent 5fbf7c9 commit 88c877d

File tree

5 files changed

+40
-52
lines changed

5 files changed

+40
-52
lines changed

gateway/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# shuttle-gateway
2+
3+
## Tests
4+
To run the tests for gateway, follow the steps in [contributing](https://github.com/shuttle-hq/shuttle/blob/main/CONTRIBUTING.md) to set up your local environment. Then, from the root of the repository, run:
5+
6+
```bash
7+
SHUTTLE_TESTS_RUNTIME_IMAGE=public.ecr.aws/shuttle-dev/deployer:latest SHUTTLE_TESTS_NETWORK=shuttle-dev_user-net cargo test --package shuttle-gateway --all-features -- --nocapture
8+
```

gateway/src/api/latest.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use axum::body::{Body, BoxBody};
55
use axum::extract::{Extension, Path};
66
use axum::http::Request;
77
use axum::response::Response;
8-
use axum::routing::{any, get};
8+
use axum::routing::{any, get, post};
99
use axum::{Json as AxumJson, Router};
1010
use http::StatusCode;
1111
use serde::{Deserialize, Serialize};
12+
use shuttle_common::models::error::ErrorKind;
1213
use shuttle_common::models::{project, user};
1314
use tokio::sync::mpsc::Sender;
1415
use tower_http::trace::TraceLayer;
@@ -153,6 +154,16 @@ async fn get_status(Extension(sender): Extension<Sender<BoxedTask>>) -> Response
153154
.unwrap()
154155
}
155156

157+
async fn revive_projects(
158+
_: Admin,
159+
Extension(service): Extension<Arc<GatewayService>>,
160+
Extension(sender): Extension<Sender<BoxedTask>>,
161+
) -> Result<(), Error> {
162+
crate::project::exec::revive(service, sender)
163+
.await
164+
.map_err(|_| Error::from_kind(ErrorKind::Internal))
165+
}
166+
156167
pub fn make_api(service: Arc<GatewayService>, sender: Sender<BoxedTask>) -> Router<Body> {
157168
debug!("making api route");
158169

@@ -167,6 +178,7 @@ pub fn make_api(service: Arc<GatewayService>, sender: Sender<BoxedTask>) -> Rout
167178
)
168179
.route("/users/:account_name", get(get_user).post(post_user))
169180
.route("/projects/:project/*any", any(route_project))
181+
.route("/admin/revive", post(revive_projects))
170182
.layer(Extension(service))
171183
.layer(Extension(sender))
172184
.layer(

gateway/src/args.rs

-14
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ pub struct Args {
1919
pub enum Commands {
2020
Start(StartArgs),
2121
Init(InitArgs),
22-
Exec(ExecCmds),
2322
}
2423

2524
#[derive(clap::Args, Debug, Clone)]
@@ -44,19 +43,6 @@ pub struct InitArgs {
4443
pub key: Option<Key>,
4544
}
4645

47-
#[derive(clap::Args, Debug, Clone)]
48-
pub struct ExecCmds {
49-
#[command(flatten)]
50-
pub context: ContextArgs,
51-
#[command(subcommand)]
52-
pub command: ExecCmd,
53-
}
54-
55-
#[derive(Subcommand, Debug, Clone)]
56-
pub enum ExecCmd {
57-
Revive,
58-
}
59-
6046
#[derive(clap::Args, Debug, Clone)]
6147
pub struct ContextArgs {
6248
/// Default image to deploy user runtimes into

gateway/src/main.rs

+1-15
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use clap::Parser;
22
use futures::prelude::*;
33
use opentelemetry::global;
4-
use shuttle_gateway::args::{Args, Commands, ExecCmd, ExecCmds, InitArgs};
4+
use shuttle_gateway::args::{Args, Commands, InitArgs};
55
use shuttle_gateway::auth::Key;
6-
use shuttle_gateway::project;
76
use shuttle_gateway::proxy::make_proxy;
87
use shuttle_gateway::service::{GatewayService, MIGRATIONS};
98
use shuttle_gateway::task;
@@ -60,7 +59,6 @@ async fn main() -> io::Result<()> {
6059
match args.command {
6160
Commands::Start(start_args) => start(db, start_args).await,
6261
Commands::Init(init_args) => init(db, init_args).await,
63-
Commands::Exec(exec_cmd) => exec(db, exec_cmd).await,
6462
}
6563
}
6664

@@ -160,15 +158,3 @@ async fn init(db: SqlitePool, args: InitArgs) -> io::Result<()> {
160158
println!("`{}` created as super user with key: {key}", args.name);
161159
Ok(())
162160
}
163-
164-
async fn exec(db: SqlitePool, exec_cmd: ExecCmds) -> io::Result<()> {
165-
let gateway = GatewayService::init(exec_cmd.context.clone(), db).await;
166-
167-
match exec_cmd.command {
168-
ExecCmd::Revive => project::exec::revive(gateway)
169-
.await
170-
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?,
171-
};
172-
173-
Ok(())
174-
}

gateway/src/project.rs

+18-22
Original file line numberDiff line numberDiff line change
@@ -838,21 +838,23 @@ where
838838
}
839839

840840
pub mod exec {
841+
841842
use std::sync::Arc;
842843

843844
use bollard::service::ContainerState;
845+
use tokio::sync::mpsc::Sender;
844846

845847
use crate::{
846848
service::GatewayService,
847-
task::{self, TaskResult},
849+
task::{self, BoxedTask, TaskResult},
848850
};
849851

850852
use super::*;
851853

852-
pub async fn revive(gateway: GatewayService) -> Result<(), ProjectError> {
853-
let mut mutations = Vec::new();
854-
let gateway = Arc::new(gateway);
855-
854+
pub async fn revive(
855+
gateway: Arc<GatewayService>,
856+
sender: Sender<BoxedTask>,
857+
) -> Result<(), ProjectError> {
856858
for (project_name, account_name) in gateway
857859
.iter_projects()
858860
.await
@@ -873,30 +875,24 @@ pub mod exec {
873875
..
874876
}) = container.state
875877
{
876-
mutations.push((
877-
project_name.clone(),
878-
gateway
879-
.new_task()
880-
.project(project_name)
881-
.account(account_name)
882-
.and_then(task::run(|ctx| async move {
883-
TaskResult::Done(Project::Stopped(ProjectStopped {
884-
container: ctx.state.container().unwrap(),
885-
}))
878+
debug!("{} will be revived", project_name.clone());
879+
_ = gateway
880+
.new_task()
881+
.project(project_name)
882+
.account(account_name)
883+
.and_then(task::run(|ctx| async move {
884+
TaskResult::Done(Project::Stopped(ProjectStopped {
885+
container: ctx.state.container().unwrap(),
886886
}))
887-
.build(),
888-
));
887+
}))
888+
.send(&sender)
889+
.await;
889890
}
890891
}
891892
}
892893
}
893894
}
894895

895-
for (project_name, mut work) in mutations {
896-
debug!(?project_name, "project will be revived");
897-
while let TaskResult::Pending(_) = work.poll(()).await {}
898-
}
899-
900896
Ok(())
901897
}
902898
}

0 commit comments

Comments
 (0)