From 6360dc54a71b8ae3a0ad1af47e946a5873ceb8d1 Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Wed, 25 Sep 2024 16:53:55 -0700 Subject: [PATCH] chore(toolchain): remove requirement to be signed in for toolchain tasks --- packages/cli/src/commands/db/instance.rs | 15 +-- packages/cli/src/commands/deploy.rs | 8 +- packages/cli/src/commands/mod.rs | 16 +-- .../cli/src/commands/{login.rs => sign_in.rs} | 18 +-- .../src/commands/{logout.rs => sign_out.rs} | 9 +- packages/toolchain/src/backend/database.rs | 18 ++- packages/toolchain/src/config/meta.rs | 109 ++++-------------- .../check_state.rs} | 9 +- packages/toolchain/src/tasks/auth/mod.rs | 4 + .../src/tasks/{unlink.rs => auth/sign_out.rs} | 7 +- .../start_sign_in.rs} | 2 +- .../wait_for_sign_in.rs} | 7 +- packages/toolchain/src/tasks/backend/mod.rs | 2 + .../{backend_start.rs => backend/start.rs} | 2 +- .../{backend_stop.rs => backend/stop.rs} | 6 +- .../toolchain/src/tasks/deploy/backend.rs | 3 + .../toolchain/src/tasks/game_server/mod.rs | 2 + .../start.rs} | 6 +- .../stop.rs} | 8 +- .../toolchain/src/tasks/get_bootstrap_data.rs | 85 +++++++------- packages/toolchain/src/tasks/mod.rs | 40 +++---- packages/toolchain/src/tasks/postgres/mod.rs | 4 + .../{postgres_reset.rs => postgres/reset.rs} | 2 +- .../{postgres_start.rs => postgres/start.rs} | 2 +- .../status.rs} | 2 +- .../{postgres_stop.rs => postgres/stop.rs} | 2 +- packages/toolchain/src/toolchain_ctx.rs | 20 +++- 27 files changed, 197 insertions(+), 211 deletions(-) rename packages/cli/src/commands/{login.rs => sign_in.rs} (73%) rename packages/cli/src/commands/{logout.rs => sign_out.rs} (71%) rename packages/toolchain/src/tasks/{check_login_state.rs => auth/check_state.rs} (68%) create mode 100644 packages/toolchain/src/tasks/auth/mod.rs rename packages/toolchain/src/tasks/{unlink.rs => auth/sign_out.rs} (77%) rename packages/toolchain/src/tasks/{start_device_link.rs => auth/start_sign_in.rs} (97%) rename packages/toolchain/src/tasks/{wait_for_login.rs => auth/wait_for_sign_in.rs} (89%) create mode 100644 packages/toolchain/src/tasks/backend/mod.rs rename packages/toolchain/src/tasks/{backend_start.rs => backend/start.rs} (99%) rename packages/toolchain/src/tasks/{backend_stop.rs => backend/stop.rs} (84%) create mode 100644 packages/toolchain/src/tasks/game_server/mod.rs rename packages/toolchain/src/tasks/{game_server_start.rs => game_server/start.rs} (89%) rename packages/toolchain/src/tasks/{game_server_stop.rs => game_server/stop.rs} (77%) create mode 100644 packages/toolchain/src/tasks/postgres/mod.rs rename packages/toolchain/src/tasks/{postgres_reset.rs => postgres/reset.rs} (96%) rename packages/toolchain/src/tasks/{postgres_start.rs => postgres/start.rs} (96%) rename packages/toolchain/src/tasks/{postgres_status.rs => postgres/status.rs} (96%) rename packages/toolchain/src/tasks/{postgres_stop.rs => postgres/stop.rs} (96%) diff --git a/packages/cli/src/commands/db/instance.rs b/packages/cli/src/commands/db/instance.rs index 2403d03a..7ad60d68 100644 --- a/packages/cli/src/commands/db/instance.rs +++ b/packages/cli/src/commands/db/instance.rs @@ -2,10 +2,7 @@ use clap::Parser; use clap::Subcommand; use serde::Serialize; use std::process::ExitCode; -use toolchain::tasks::postgres_reset; -use toolchain::tasks::postgres_start; -use toolchain::tasks::postgres_status; -use toolchain::tasks::postgres_stop; +use toolchain::tasks; use crate::util::task::run_task; use crate::util::task::run_task_simple; @@ -38,7 +35,7 @@ pub struct StartOpts {} impl StartOpts { pub async fn execute(&self) -> ExitCode { - run_task_simple::(postgres_start::Input {}).await + run_task_simple::(tasks::postgres::start::Input {}).await } } @@ -49,7 +46,7 @@ pub struct StopOpts {} impl StopOpts { pub async fn execute(&self) -> ExitCode { - run_task_simple::(postgres_stop::Input {}).await + run_task_simple::(tasks::postgres::stop::Input {}).await } } @@ -60,9 +57,9 @@ pub struct StatusOpts {} impl StatusOpts { pub async fn execute(&self) -> ExitCode { - match run_task::( + match run_task::( TaskOutputStyle::PlainNoResult, - postgres_status::Input {}, + tasks::postgres::status::Input {}, ) .await { @@ -85,6 +82,6 @@ pub struct ResetOpts {} impl ResetOpts { pub async fn execute(&self) -> ExitCode { - run_task_simple::(postgres_reset::Input {}).await + run_task_simple::(tasks::postgres::reset::Input {}).await } } diff --git a/packages/cli/src/commands/deploy.rs b/packages/cli/src/commands/deploy.rs index 0c531c7b..75b068f7 100644 --- a/packages/cli/src/commands/deploy.rs +++ b/packages/cli/src/commands/deploy.rs @@ -30,9 +30,13 @@ impl Opts { return ExitCode::FAILURE; } }; + let Some(cloud_data) = bootstrap_data.cloud else { + eprintln!("Not signed in"); + return ExitCode::FAILURE; + }; // Find environment - let environment = match bootstrap_data + let environment = match cloud_data .envs .iter() .find(|env| env.slug == self.environment) @@ -43,7 +47,7 @@ impl Opts { "Environment '{}' not found. Available environments:", self.environment ); - for env in &bootstrap_data.envs { + for env in &cloud_data.envs { eprintln!("- {}", env.slug); } return ExitCode::FAILURE; diff --git a/packages/cli/src/commands/mod.rs b/packages/cli/src/commands/mod.rs index bd357ad4..a4830012 100644 --- a/packages/cli/src/commands/mod.rs +++ b/packages/cli/src/commands/mod.rs @@ -6,9 +6,9 @@ pub mod db; pub mod deploy; pub mod dev; pub mod init; -pub mod login; -pub mod logout; pub mod module; +pub mod sign_in; +pub mod sign_out; pub mod task; use clap::Parser; @@ -16,9 +16,11 @@ use std::process::ExitCode; #[derive(Parser)] pub enum SubCommand { - Init(login::Opts), - Login(login::Opts), - Logout(logout::Opts), + Init(init::Opts), + #[clap(alias = "login")] + Signin(sign_in::Opts), + #[clap(alias = "logout")] + Signout(sign_out::Opts), Dev(dev::Opts), Deploy(deploy::Opts), Config { @@ -52,8 +54,8 @@ impl SubCommand { pub async fn execute(&self) -> ExitCode { match self { SubCommand::Init(opts) => opts.execute().await, - SubCommand::Login(opts) => opts.execute().await, - SubCommand::Logout(opts) => opts.execute().await, + SubCommand::Signin(opts) => opts.execute().await, + SubCommand::Signout(opts) => opts.execute().await, SubCommand::Dev(opts) => opts.execute().await, SubCommand::Deploy(opts) => opts.execute().await, SubCommand::Config { subcommand } => subcommand.execute().await, diff --git a/packages/cli/src/commands/login.rs b/packages/cli/src/commands/sign_in.rs similarity index 73% rename from packages/cli/src/commands/login.rs rename to packages/cli/src/commands/sign_in.rs index 03e55dc0..b212cc3e 100644 --- a/packages/cli/src/commands/login.rs +++ b/packages/cli/src/commands/sign_in.rs @@ -1,6 +1,6 @@ use clap::Parser; use std::process::ExitCode; -use toolchain::tasks::{check_login_state, start_device_link, wait_for_login}; +use toolchain::tasks; use crate::util::task::{run_task, TaskOutputStyle}; @@ -14,15 +14,15 @@ pub struct Opts { impl Opts { pub async fn execute(&self) -> ExitCode { // Check if linked - match run_task::( + match run_task::( TaskOutputStyle::None, - check_login_state::Input {}, + tasks::auth::check_state::Input {}, ) .await { Ok(output) => { - if output.logged_in { - eprintln!("Already logged in. Sign out with `rivet unlink`."); + if output.signed_in { + eprintln!("Already logged in. Sign out with `rivet logout`."); return ExitCode::SUCCESS; } } @@ -33,9 +33,9 @@ impl Opts { } // Start device link - let device_link_output = match run_task::( + let device_link_output = match run_task::( TaskOutputStyle::None, - start_device_link::Input { + tasks::auth::start_sign_in::Input { api_endpoint: self.api_endpoint.clone(), }, ) @@ -50,9 +50,9 @@ impl Opts { eprintln!("{}", device_link_output.device_link_url); // Wait for finish - match run_task::( + match run_task::( TaskOutputStyle::None, - wait_for_login::Input { + tasks::auth::wait_for_sign_in::Input { api_endpoint: self.api_endpoint.clone(), device_link_token: device_link_output.device_link_token, }, diff --git a/packages/cli/src/commands/logout.rs b/packages/cli/src/commands/sign_out.rs similarity index 71% rename from packages/cli/src/commands/logout.rs rename to packages/cli/src/commands/sign_out.rs index de170d3a..bece83a8 100644 --- a/packages/cli/src/commands/logout.rs +++ b/packages/cli/src/commands/sign_out.rs @@ -1,6 +1,6 @@ use clap::Parser; use std::process::ExitCode; -use toolchain::tasks::unlink; +use toolchain::tasks; use crate::util::task::{run_task, TaskOutputStyle}; @@ -10,7 +10,12 @@ pub struct Opts {} impl Opts { pub async fn execute(&self) -> ExitCode { - match run_task::(TaskOutputStyle::None, unlink::Input {}).await { + match run_task::( + TaskOutputStyle::None, + tasks::auth::sign_out::Input {}, + ) + .await + { Ok(_) => { eprintln!("Logged out"); ExitCode::SUCCESS diff --git a/packages/toolchain/src/backend/database.rs b/packages/toolchain/src/backend/database.rs index 4fe16777..c2e65c6c 100644 --- a/packages/toolchain/src/backend/database.rs +++ b/packages/toolchain/src/backend/database.rs @@ -19,8 +19,15 @@ pub async fn provision_database( .await?; // Fetch remote DB URL - let mut env_config = config::meta::mutate_project(&paths::data_dir()?, |config| { - config.environments.entry(env_id).or_default().clone() + let mut env_config = config::meta::try_mutate_project(&paths::data_dir()?, |config| { + Ok(config + .cloud + .as_mut() + .context("config.cloud")? + .environments + .entry(env_id) + .or_default() + .clone()) }) .await?; @@ -39,7 +46,12 @@ pub async fn provision_database( // Update cache config::meta::try_mutate_project(&paths::data_dir()?, |config| { - config.environments.insert(env_id, env_config.clone()); + config + .cloud + .as_mut() + .context("config.cloud")? + .environments + .insert(env_id, env_config.clone()); Ok(()) }) .await?; diff --git a/packages/toolchain/src/config/meta.rs b/packages/toolchain/src/config/meta.rs index 855190ea..d1057ade 100644 --- a/packages/toolchain/src/config/meta.rs +++ b/packages/toolchain/src/config/meta.rs @@ -8,17 +8,12 @@ use uuid::Uuid; use crate::paths; /// Config stored in {data_dir}/meta.json. Used to store persistent data, such as tokens & cache. -#[derive(Serialize, Deserialize)] +#[derive(Default, Serialize, Deserialize)] pub struct Meta { - pub cluster: Cluster, - pub tokens: Tokens, - pub environments: HashMap, - - /// Stores the state for all of the processes. + /// If signed in to Rivet, this will include relevant information. /// - /// Key is the key in the `ProcessManager` config. - #[serde(default)] - pub processes: HashMap, + /// If not signed in, will be None. + pub cloud: Option, /// Port which the dev server is running on for plugins. #[serde(default)] @@ -29,28 +24,26 @@ pub struct Meta { pub editor_port: Option, } -impl Meta { - fn new(api_endpoint: String, cloud_token: String) -> Self { - Meta { - cluster: Cluster { api_endpoint }, - tokens: Tokens { cloud: cloud_token }, - environments: HashMap::new(), - processes: HashMap::new(), - backend_port: None, - editor_port: None, - } - } -} - -#[derive(Default, Serialize, Deserialize)] -pub struct Cluster { +#[derive(Serialize, Deserialize)] +pub struct Cloud { + /// Rivet API endpoint to connect to. pub api_endpoint: String, -} -#[derive(Serialize, Deserialize)] -pub struct Tokens { /// Cloud token used to authenticate all API requests. - pub cloud: String, + pub cloud_token: String, + + /// Cache of all environments for this game. + pub environments: HashMap, +} + +impl Cloud { + pub fn new(api_endpoint: String, cloud_token: String) -> Self { + Self { + api_endpoint, + cloud_token, + environments: HashMap::new(), + } + } } #[derive(Default, Clone, Serialize, Deserialize)] @@ -65,14 +58,6 @@ pub struct Backend { pub db_url: Option, } -#[derive(Default, Clone, Serialize, Deserialize)] -pub struct ProcessState { - /// ID of the running process. - /// - /// This is not the same as the PID. - pub process_id: Option, -} - lazy_static! { /// List of all meta paths cached in memory. /// @@ -115,9 +100,7 @@ pub async fn try_read_project Result, T>( let mut meta = match fs::read_to_string(&meta_path).await { Result::Ok(config) => serde_json::from_str::(&config) .context(format!("deserialize meta ({})", meta_path.display()))?, - Err(err) if err.kind() == std::io::ErrorKind::NotFound => { - bail!("project not initialized") - } + Err(err) if err.kind() == std::io::ErrorKind::NotFound => Meta::default(), Err(err) => return Err(err.into()), }; @@ -152,9 +135,7 @@ pub async fn try_mutate_project Result, T>( let mut meta = match fs::read_to_string(&meta_path).await { Result::Ok(config) => serde_json::from_str::(&config) .context(format!("deserialize meta ({})", meta_path.display()))?, - Err(err) if err.kind() == std::io::ErrorKind::NotFound => { - bail!("project not initialized") - } + Err(err) if err.kind() == std::io::ErrorKind::NotFound => Meta::default(), Err(err) => return Err(err.into()), }; @@ -180,47 +161,3 @@ pub async fn mutate_project T, T>( ) -> Result { try_mutate_project(base_data_dir, |x| Ok(cb(x))).await } - -pub async fn has_project(base_data_dir: &PathBuf) -> Result { - let meta_path = paths::meta_config_file(base_data_dir)?; - let has_project = fs::try_exists(&meta_path).await?; - Ok(has_project) -} - -pub async fn insert_project( - base_data_dir: &PathBuf, - api_endpoint: String, - cloud_token: String, -) -> Result<()> { - // Build and serialize - let meta = Meta::new(api_endpoint, cloud_token); - let json_str = serde_json::to_string(&meta)?; - - // Write meta - // - // This will replace the existing meta - let _write_guard = META_FILE_LOCK.lock().await; - let path = paths::meta_config_file(base_data_dir)?; - if let Some(parent) = path.parent() { - fs::create_dir_all(parent).await?; - } - fs::write(path, json_str).await?; - - Ok(()) -} - -pub async fn delete_project(base_data_dir: &PathBuf) -> Result<()> { - let path = paths::meta_config_file(base_data_dir)?; - - // Lock all resources - let mut global_meta = META.lock().await; - let _write_guard = META_FILE_LOCK.lock().await; - - // Delete from cache - global_meta.remove(&path); - - // Delete file - fs::remove_file(&path).await?; - - Ok(()) -} diff --git a/packages/toolchain/src/tasks/check_login_state.rs b/packages/toolchain/src/tasks/auth/check_state.rs similarity index 68% rename from packages/toolchain/src/tasks/check_login_state.rs rename to packages/toolchain/src/tasks/auth/check_state.rs index 78b1fde2..655e8a33 100644 --- a/packages/toolchain/src/tasks/check_login_state.rs +++ b/packages/toolchain/src/tasks/auth/check_state.rs @@ -8,7 +8,7 @@ pub struct Input {} #[derive(Serialize)] pub struct Output { - pub logged_in: bool, + pub signed_in: bool, } pub struct Task; @@ -18,11 +18,12 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "check_login_state" + "auth.check_state" } async fn run(_task: task::TaskCtx, _input: Input) -> Result { - let logged_in = config::meta::has_project(&paths::data_dir()?).await?; - Ok(Output { logged_in }) + let signed_in = + config::meta::read_project(&paths::data_dir()?, |meta| meta.cloud.is_some()).await?; + Ok(Output { signed_in }) } } diff --git a/packages/toolchain/src/tasks/auth/mod.rs b/packages/toolchain/src/tasks/auth/mod.rs new file mode 100644 index 00000000..bc4772ab --- /dev/null +++ b/packages/toolchain/src/tasks/auth/mod.rs @@ -0,0 +1,4 @@ +pub mod check_state; +pub mod sign_out; +pub mod start_sign_in; +pub mod wait_for_sign_in; diff --git a/packages/toolchain/src/tasks/unlink.rs b/packages/toolchain/src/tasks/auth/sign_out.rs similarity index 77% rename from packages/toolchain/src/tasks/unlink.rs rename to packages/toolchain/src/tasks/auth/sign_out.rs index f1af7c82..a007087c 100644 --- a/packages/toolchain/src/tasks/unlink.rs +++ b/packages/toolchain/src/tasks/auth/sign_out.rs @@ -16,11 +16,14 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "unlink" + "auth.sign_out" } async fn run(_task: task::TaskCtx, _input: Self::Input) -> Result { - config::meta::delete_project(&paths::data_dir()?).await?; + config::meta::mutate_project(&paths::data_dir()?, |meta| { + meta.cloud = None; + }) + .await?; Ok(Output {}) } } diff --git a/packages/toolchain/src/tasks/start_device_link.rs b/packages/toolchain/src/tasks/auth/start_sign_in.rs similarity index 97% rename from packages/toolchain/src/tasks/start_device_link.rs rename to packages/toolchain/src/tasks/auth/start_sign_in.rs index 1b172220..5930deeb 100644 --- a/packages/toolchain/src/tasks/start_device_link.rs +++ b/packages/toolchain/src/tasks/auth/start_sign_in.rs @@ -22,7 +22,7 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "start_device_link" + "auth.start_sign_in" } async fn run(_task: task::TaskCtx, input: Self::Input) -> Result { diff --git a/packages/toolchain/src/tasks/wait_for_login.rs b/packages/toolchain/src/tasks/auth/wait_for_sign_in.rs similarity index 89% rename from packages/toolchain/src/tasks/wait_for_login.rs rename to packages/toolchain/src/tasks/auth/wait_for_sign_in.rs index 2966d39e..6a98b8a3 100644 --- a/packages/toolchain/src/tasks/wait_for_login.rs +++ b/packages/toolchain/src/tasks/auth/wait_for_sign_in.rs @@ -20,7 +20,7 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "wait_for_login" + "auth.wait_for_sign_in" } async fn run(_task: task::TaskCtx, input: Self::Input) -> Result { @@ -64,7 +64,10 @@ impl task::Task for Task { ) .await?; - config::meta::insert_project(&paths::data_dir()?, input.api_endpoint, token).await?; + config::meta::mutate_project(&paths::data_dir()?, |meta| { + meta.cloud = Some(config::meta::Cloud::new(input.api_endpoint, token)) + }) + .await?; Ok(Output {}) } diff --git a/packages/toolchain/src/tasks/backend/mod.rs b/packages/toolchain/src/tasks/backend/mod.rs new file mode 100644 index 00000000..99457f5f --- /dev/null +++ b/packages/toolchain/src/tasks/backend/mod.rs @@ -0,0 +1,2 @@ +pub mod start; +pub mod stop; diff --git a/packages/toolchain/src/tasks/backend_start.rs b/packages/toolchain/src/tasks/backend/start.rs similarity index 99% rename from packages/toolchain/src/tasks/backend_start.rs rename to packages/toolchain/src/tasks/backend/start.rs index dc1ebb8f..3e21103d 100644 --- a/packages/toolchain/src/tasks/backend_start.rs +++ b/packages/toolchain/src/tasks/backend/start.rs @@ -30,7 +30,7 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "backend_start" + "backend.start" } async fn run(task: task::TaskCtx, _input: Self::Input) -> Result { diff --git a/packages/toolchain/src/tasks/backend_stop.rs b/packages/toolchain/src/tasks/backend/stop.rs similarity index 84% rename from packages/toolchain/src/tasks/backend_stop.rs rename to packages/toolchain/src/tasks/backend/stop.rs index 8caa7d3f..7a3725e2 100644 --- a/packages/toolchain/src/tasks/backend_stop.rs +++ b/packages/toolchain/src/tasks/backend/stop.rs @@ -16,13 +16,11 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "backend_stop" + "backend.stop" } async fn run(_task: task::TaskCtx, _input: Self::Input) -> Result { - backend::PROCESS_MANAGER_DEV - .stop() - .await?; + backend::PROCESS_MANAGER_DEV.stop().await?; Ok(Output {}) } } diff --git a/packages/toolchain/src/tasks/deploy/backend.rs b/packages/toolchain/src/tasks/deploy/backend.rs index 5ceddc99..e7bdafb4 100644 --- a/packages/toolchain/src/tasks/deploy/backend.rs +++ b/packages/toolchain/src/tasks/deploy/backend.rs @@ -62,6 +62,9 @@ pub async fn deploy(ctx: &ToolchainCtx, task: task::TaskCtx, opts: DeployOpts) - let db_url = config::meta::try_read_project(&paths::data_dir()?, |config| { let env_config = config + .cloud + .as_ref() + .context("config.cloud")? .environments .get(&opts.env.id) .context("could not find environment")?; diff --git a/packages/toolchain/src/tasks/game_server/mod.rs b/packages/toolchain/src/tasks/game_server/mod.rs new file mode 100644 index 00000000..99457f5f --- /dev/null +++ b/packages/toolchain/src/tasks/game_server/mod.rs @@ -0,0 +1,2 @@ +pub mod start; +pub mod stop; diff --git a/packages/toolchain/src/tasks/game_server_start.rs b/packages/toolchain/src/tasks/game_server/start.rs similarity index 89% rename from packages/toolchain/src/tasks/game_server_start.rs rename to packages/toolchain/src/tasks/game_server/start.rs index 6ea6ff09..f1277fc6 100644 --- a/packages/toolchain/src/tasks/game_server_start.rs +++ b/packages/toolchain/src/tasks/game_server/start.rs @@ -1,9 +1,7 @@ use anyhow::*; use serde::{Deserialize, Serialize}; -use crate::{ - util::{process_manager::CommandOpts, task}, -}; +use crate::util::{process_manager::CommandOpts, task}; #[derive(Deserialize)] pub struct Input { @@ -24,7 +22,7 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "game_server_start" + "game_server.start" } async fn run(task: task::TaskCtx, input: Self::Input) -> Result { diff --git a/packages/toolchain/src/tasks/game_server_stop.rs b/packages/toolchain/src/tasks/game_server/stop.rs similarity index 77% rename from packages/toolchain/src/tasks/game_server_stop.rs rename to packages/toolchain/src/tasks/game_server/stop.rs index 7faa478b..cffef569 100644 --- a/packages/toolchain/src/tasks/game_server_stop.rs +++ b/packages/toolchain/src/tasks/game_server/stop.rs @@ -1,7 +1,7 @@ use anyhow::*; use serde::{Deserialize, Serialize}; -use crate::{util::task}; +use crate::util::task; #[derive(Deserialize)] pub struct Input {} @@ -16,13 +16,11 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "game_server_stop" + "game_server.stop" } async fn run(_task: task::TaskCtx, _input: Self::Input) -> Result { - crate::game_server::PROCESS_MANAGER - .stop() - .await?; + crate::game_server::PROCESS_MANAGER.stop().await?; Ok(Output {}) } } diff --git a/packages/toolchain/src/tasks/get_bootstrap_data.rs b/packages/toolchain/src/tasks/get_bootstrap_data.rs index d22c304c..839b87e0 100644 --- a/packages/toolchain/src/tasks/get_bootstrap_data.rs +++ b/packages/toolchain/src/tasks/get_bootstrap_data.rs @@ -1,4 +1,5 @@ use anyhow::*; +use futures_util::{StreamExt, TryStreamExt}; use rivet_api::{apis, models}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -11,6 +12,11 @@ pub struct Input {} #[derive(Serialize)] pub struct Output { + pub cloud: Option, +} + +#[derive(Serialize)] +pub struct CloudData { pub token: String, pub api_endpoint: String, pub game_id: String, @@ -29,48 +35,47 @@ impl task::Task for Task { } async fn run(_task: task::TaskCtx, _input: Self::Input) -> Result { - let ctx = crate::toolchain_ctx::load().await?; - - // HACK: Map ns to temporary env data structure - // Get or create backend project - let envs = apis::cloud_games_api::cloud_games_get_game_by_id( - &ctx.openapi_config_cloud, - &ctx.game_id.to_string(), - None, - ) - .await? - .game - .namespaces - .into_iter() - .map(crate::game::TEMPEnvironment::from) - .collect::>(); + let cloud = if let Some(ctx) = crate::toolchain_ctx::try_load().await? { + // HACK: Map ns to temporary env data structure + // Get or create backend project + let envs = apis::cloud_games_api::cloud_games_get_game_by_id( + &ctx.openapi_config_cloud, + &ctx.game_id.to_string(), + None, + ) + .await? + .game + .namespaces + .into_iter() + .map(crate::game::TEMPEnvironment::from) + .collect::>(); - let mut backends = HashMap::new(); - for env in &envs { - let backend = backend::get_or_create_backend(&ctx, env.id).await?; - backends.insert(env.id, backend); - } + // Get all backends in parallel + let backends = futures_util::stream::iter(envs.iter().cloned()) + .map({ + |env| { + let ctx = ctx.clone(); + async move { + let backend = backend::get_or_create_backend(&ctx, env.id).await?; + Result::<_, anyhow::Error>::Ok((env.id, backend)) + } + } + }) + .buffer_unordered(4) + .try_collect::>() + .await?; - // TODO: This causes a weird compilation error in gdext - // // Get all backends in parallel - // let backends = futures_util::stream::iter(envs.iter()) - // .map(|env| { - // let ctx = ctx.clone(); - // async move { - // let backend = backend::get_or_create_backend(&ctx, env.id).await?; - // Result::Ok((env.id, backend)) - // } - // }) - // .buffer_unordered(4) - // .try_collect::>() - // .await?; + Some(CloudData { + token: ctx.access_token.clone(), + api_endpoint: ctx.api_endpoint.clone(), + game_id: ctx.game_id.clone(), + envs, + backends, + }) + } else { + None + }; - Ok(Output { - token: ctx.access_token.clone(), - api_endpoint: ctx.api_endpoint.clone(), - game_id: ctx.game_id.clone(), - envs, - backends, - }) + Ok(Output { cloud }) } } diff --git a/packages/toolchain/src/tasks/mod.rs b/packages/toolchain/src/tasks/mod.rs index 4b919c94..0b56ba94 100644 --- a/packages/toolchain/src/tasks/mod.rs +++ b/packages/toolchain/src/tasks/mod.rs @@ -1,39 +1,31 @@ -pub mod backend_start; -pub mod backend_stop; -pub mod check_login_state; +pub mod auth; +pub mod backend; pub mod deploy; pub mod exec_command; -pub mod game_server_start; -pub mod game_server_stop; +pub mod game_server; pub mod get_bootstrap_data; pub mod get_settings_paths; pub mod open; -pub mod postgres_reset; -pub mod postgres_start; -pub mod postgres_status; -pub mod postgres_stop; +pub mod postgres; pub mod show_term; -pub mod start_device_link; -pub mod unlink; -pub mod wait_for_login; crate::task_registry!( - backend_start::Task, - backend_stop::Task, - check_login_state::Task, + auth::check_state::Task, + auth::sign_out::Task, + auth::start_sign_in::Task, + auth::wait_for_sign_in::Task, + backend::start::Task, + backend::stop::Task, deploy::Task, exec_command::Task, - game_server_start::Task, - game_server_stop::Task, + game_server::start::Task, + game_server::stop::Task, get_bootstrap_data::Task, get_settings_paths::Task, open::Task, - postgres_reset::Task, - postgres_start::Task, - postgres_status::Task, - postgres_stop::Task, + postgres::reset::Task, + postgres::start::Task, + postgres::status::Task, + postgres::stop::Task, show_term::Task, - start_device_link::Task, - unlink::Task, - wait_for_login::Task, ); diff --git a/packages/toolchain/src/tasks/postgres/mod.rs b/packages/toolchain/src/tasks/postgres/mod.rs new file mode 100644 index 00000000..43f3c97e --- /dev/null +++ b/packages/toolchain/src/tasks/postgres/mod.rs @@ -0,0 +1,4 @@ +pub mod reset; +pub mod start; +pub mod status; +pub mod stop; diff --git a/packages/toolchain/src/tasks/postgres_reset.rs b/packages/toolchain/src/tasks/postgres/reset.rs similarity index 96% rename from packages/toolchain/src/tasks/postgres_reset.rs rename to packages/toolchain/src/tasks/postgres/reset.rs index 17655271..e38a56dc 100644 --- a/packages/toolchain/src/tasks/postgres_reset.rs +++ b/packages/toolchain/src/tasks/postgres/reset.rs @@ -16,7 +16,7 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "postgres_start" + "postgres.reset" } async fn run(_task: task::TaskCtx, _input: Self::Input) -> Result { diff --git a/packages/toolchain/src/tasks/postgres_start.rs b/packages/toolchain/src/tasks/postgres/start.rs similarity index 96% rename from packages/toolchain/src/tasks/postgres_start.rs rename to packages/toolchain/src/tasks/postgres/start.rs index 10b1beb7..01e8c37b 100644 --- a/packages/toolchain/src/tasks/postgres_start.rs +++ b/packages/toolchain/src/tasks/postgres/start.rs @@ -16,7 +16,7 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "postgres_start" + "postgres.start" } async fn run(_task: task::TaskCtx, _input: Self::Input) -> Result { diff --git a/packages/toolchain/src/tasks/postgres_status.rs b/packages/toolchain/src/tasks/postgres/status.rs similarity index 96% rename from packages/toolchain/src/tasks/postgres_status.rs rename to packages/toolchain/src/tasks/postgres/status.rs index 85f82639..c9b23e52 100644 --- a/packages/toolchain/src/tasks/postgres_status.rs +++ b/packages/toolchain/src/tasks/postgres/status.rs @@ -18,7 +18,7 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "postgres_status" + "postgres.status" } async fn run(_task: task::TaskCtx, _input: Self::Input) -> Result { diff --git a/packages/toolchain/src/tasks/postgres_stop.rs b/packages/toolchain/src/tasks/postgres/stop.rs similarity index 96% rename from packages/toolchain/src/tasks/postgres_stop.rs rename to packages/toolchain/src/tasks/postgres/stop.rs index 1449e401..d080dfb9 100644 --- a/packages/toolchain/src/tasks/postgres_stop.rs +++ b/packages/toolchain/src/tasks/postgres/stop.rs @@ -16,7 +16,7 @@ impl task::Task for Task { type Output = Output; fn name() -> &'static str { - "postgres_stop" + "postgres.stop" } async fn run(_task: task::TaskCtx, _input: Self::Input) -> Result { diff --git a/packages/toolchain/src/toolchain_ctx.rs b/packages/toolchain/src/toolchain_ctx.rs index c15396cc..bd4c12ed 100644 --- a/packages/toolchain/src/toolchain_ctx.rs +++ b/packages/toolchain/src/toolchain_ctx.rs @@ -30,9 +30,25 @@ pub struct CtxInner { pub openapi_config_cloud: apis::configuration::Configuration, } +pub async fn try_load() -> Result> { + let data = config::meta::read_project(&paths::data_dir()?, |x| { + x.cloud + .as_ref() + .map(|cloud| (cloud.api_endpoint.clone(), cloud.cloud_token.clone())) + }) + .await?; + if let Some((api_endpoint, token)) = data { + let ctx = init(api_endpoint, token).await?; + Ok(Some(ctx)) + } else { + Ok(None) + } +} + pub async fn load() -> Result { - let (api_endpoint, token) = config::meta::read_project(&paths::data_dir()?, |x| { - (x.cluster.api_endpoint.clone(), x.tokens.cloud.clone()) + let (api_endpoint, token) = config::meta::try_read_project(&paths::data_dir()?, |x| { + let cloud = x.cloud.as_ref().context("not signed in")?; + Ok((cloud.api_endpoint.clone(), cloud.cloud_token.clone())) }) .await?; init(api_endpoint, token).await