forked from github-starred/komodo
* start 1.19.4 * deploy 1.19.4-dev-1 * try smaller binaries with cargo strip * deploy 1.19.4-dev-2 * smaller binaries with cargo strip * Fix Submit Dialog Button Behavior with 500 Errors on Duplicate Names (#819) * Implement enhanced error handling and messaging for resource creation * Implement improved error handling for resource creation across alerter, build, and sync * Implement error handling improvements for resource copying and validation feedback * Adjust error handling for resource creation to distinguish validation errors from unexpected system errors * Refactor resource creation error handling by removing redundant match statements and simplifying the error propagation in multiple API modules. * fmt * bump indexmap * fix account selector showing empty when account no longer found * clean up theme logic, ensure monaco and others get up to date current theme * enforce disable_non_admin_create for tags. Clean up status code responses * update server cache concurrency controller * deploy 1.19.4-dev-3 * Allow signing in by pressing enter (#830) * Improve dialog overflow handling to prevent clipping of content (#828) * Add Email notification entry to community.md (#824) * Add clickable file path to show/hide file contents in StackInfo (#827) * add clickable file path to show/hide file contents in StackInfo Also added CopyButton due to the new functionality making the file path not selectable. * Move clicking interaction to CardHeader * Avoid sync edge cases of having toggle show function capturing showContents from outside Co-authored-by: Maxwell Becker <49575486+mbecker20@users.noreply.github.com> * Format previous change * Add `default_show_contents` to `handleToggleShow` --------- Co-authored-by: Maxwell Becker <49575486+mbecker20@users.noreply.github.com> * deploy 1.19.4-dev-4 * avoid stake info ShowHideButton double toggle * Allow multiple simultaneous Action runs for use with Args * deploy 1.19.4-dev-5 * feat: persist all table sorting states including unsorted (#832) - Always save sorting state to localStorage, even when empty/unsorted - Fixes issue where 'unsorted' state was not persisted across page reloads - Ensures consistent and predictable sorting behavior for all DataTable components * autofocus on login username field (#837) * Fix unnecessary auth queries flooding console on login page (#842) * Refactor authentication error handling to use serror::Result and status codes * Enable user query only when JWT is present * Enable query execution in useRead only if JWT is present * Revert backend auth changes - keep PR focused on frontend only * Fix unnecessary API queries to unreachable servers flooding console (#843) * Implement server availability checks in various components * Refactor server availability check to ensure only healthy servers are identified * cargo fmt * fmt * Auth error handling with status codes (#841) * Refactor authentication error handling to use serror::Result and status codes * Refactor error messages * Refactor authentication error handling to include status codes and improve error messages * clean up * clean * fmt * invalid user id also UNAUTHORIZED * deploy 1.19.4-dev-6 * deploy 1.19.4-dev-7 --------- Co-authored-by: Marcel Pfennig <82059270+MP-Tool@users.noreply.github.com> Co-authored-by: jack <45038833+jackra1n@users.noreply.github.com> Co-authored-by: Guten <ywzhaifei@gmail.com> Co-authored-by: Paulo Roberto Albuquerque <paulora2405@gmail.com> Co-authored-by: Lorenzo Farnararo <2814802+baldarn@users.noreply.github.com>
215 lines
5.0 KiB
Rust
215 lines
5.0 KiB
Rust
use komodo_client::{
|
|
api::execute::*,
|
|
entities::{
|
|
permission::PermissionLevel,
|
|
stack::{Stack, StackActionState},
|
|
update::{Log, Update},
|
|
user::User,
|
|
},
|
|
};
|
|
use periphery_client::{PeripheryClient, api::compose::*};
|
|
|
|
use crate::{
|
|
helpers::{periphery_client, update::update_update},
|
|
monitor::update_cache_for_server,
|
|
state::action_states,
|
|
};
|
|
|
|
use super::get_stack_and_server;
|
|
|
|
pub trait ExecuteCompose {
|
|
type Extras;
|
|
|
|
async fn execute(
|
|
periphery: PeripheryClient,
|
|
stack: Stack,
|
|
services: Vec<String>,
|
|
extras: Self::Extras,
|
|
) -> anyhow::Result<Log>;
|
|
}
|
|
|
|
pub async fn execute_compose<T: ExecuteCompose>(
|
|
stack: &str,
|
|
services: Vec<String>,
|
|
user: &User,
|
|
set_in_progress: impl Fn(&mut StackActionState),
|
|
mut update: Update,
|
|
extras: T::Extras,
|
|
) -> anyhow::Result<Update> {
|
|
let (stack, server) = get_stack_and_server(
|
|
stack,
|
|
user,
|
|
PermissionLevel::Execute.into(),
|
|
true,
|
|
)
|
|
.await?;
|
|
|
|
// get the action state for the stack (or insert default).
|
|
let action_state =
|
|
action_states().stack.get_or_insert_default(&stack.id).await;
|
|
|
|
// Will check to ensure stack not already busy before updating, and return Err if so.
|
|
// The returned guard will set the action state back to default when dropped.
|
|
let _action_guard = action_state.update(set_in_progress)?;
|
|
|
|
// Send update here for frontend to recheck action state
|
|
update_update(update.clone()).await?;
|
|
|
|
let periphery = periphery_client(&server)?;
|
|
|
|
if !services.is_empty() {
|
|
update.logs.push(Log::simple(
|
|
"Service/s",
|
|
format!(
|
|
"Execution requested for Stack service/s {}",
|
|
services.join(", ")
|
|
),
|
|
))
|
|
}
|
|
|
|
update
|
|
.logs
|
|
.push(T::execute(periphery, stack, services, extras).await?);
|
|
|
|
// Ensure cached stack state up to date by updating server cache
|
|
update_cache_for_server(&server, true).await;
|
|
|
|
update.finalize();
|
|
update_update(update.clone()).await?;
|
|
|
|
Ok(update)
|
|
}
|
|
|
|
fn service_args(services: &[String]) -> String {
|
|
if !services.is_empty() {
|
|
format!(" {}", services.join(" "))
|
|
} else {
|
|
String::new()
|
|
}
|
|
}
|
|
|
|
impl ExecuteCompose for StartStack {
|
|
type Extras = ();
|
|
async fn execute(
|
|
periphery: PeripheryClient,
|
|
stack: Stack,
|
|
services: Vec<String>,
|
|
_: Self::Extras,
|
|
) -> anyhow::Result<Log> {
|
|
let service_args = service_args(&services);
|
|
periphery
|
|
.request(ComposeExecution {
|
|
project: stack.project_name(false),
|
|
command: format!("start{service_args}"),
|
|
})
|
|
.await
|
|
}
|
|
}
|
|
|
|
impl ExecuteCompose for RestartStack {
|
|
type Extras = ();
|
|
async fn execute(
|
|
periphery: PeripheryClient,
|
|
stack: Stack,
|
|
services: Vec<String>,
|
|
_: Self::Extras,
|
|
) -> anyhow::Result<Log> {
|
|
let service_args = service_args(&services);
|
|
periphery
|
|
.request(ComposeExecution {
|
|
project: stack.project_name(false),
|
|
command: format!("restart{service_args}"),
|
|
})
|
|
.await
|
|
}
|
|
}
|
|
|
|
impl ExecuteCompose for PauseStack {
|
|
type Extras = ();
|
|
async fn execute(
|
|
periphery: PeripheryClient,
|
|
stack: Stack,
|
|
services: Vec<String>,
|
|
_: Self::Extras,
|
|
) -> anyhow::Result<Log> {
|
|
let service_args = service_args(&services);
|
|
periphery
|
|
.request(ComposeExecution {
|
|
project: stack.project_name(false),
|
|
command: format!("pause{service_args}"),
|
|
})
|
|
.await
|
|
}
|
|
}
|
|
|
|
impl ExecuteCompose for UnpauseStack {
|
|
type Extras = ();
|
|
async fn execute(
|
|
periphery: PeripheryClient,
|
|
stack: Stack,
|
|
services: Vec<String>,
|
|
_: Self::Extras,
|
|
) -> anyhow::Result<Log> {
|
|
let service_args = service_args(&services);
|
|
periphery
|
|
.request(ComposeExecution {
|
|
project: stack.project_name(false),
|
|
command: format!("unpause{service_args}"),
|
|
})
|
|
.await
|
|
}
|
|
}
|
|
|
|
impl ExecuteCompose for StopStack {
|
|
type Extras = Option<i32>;
|
|
async fn execute(
|
|
periphery: PeripheryClient,
|
|
stack: Stack,
|
|
services: Vec<String>,
|
|
timeout: Self::Extras,
|
|
) -> anyhow::Result<Log> {
|
|
let service_args = service_args(&services);
|
|
let maybe_timeout = maybe_timeout(timeout);
|
|
periphery
|
|
.request(ComposeExecution {
|
|
project: stack.project_name(false),
|
|
command: format!("stop{maybe_timeout}{service_args}"),
|
|
})
|
|
.await
|
|
}
|
|
}
|
|
|
|
impl ExecuteCompose for DestroyStack {
|
|
type Extras = (Option<i32>, bool);
|
|
async fn execute(
|
|
periphery: PeripheryClient,
|
|
stack: Stack,
|
|
services: Vec<String>,
|
|
(timeout, remove_orphans): Self::Extras,
|
|
) -> anyhow::Result<Log> {
|
|
let service_args = service_args(&services);
|
|
let maybe_timeout = maybe_timeout(timeout);
|
|
let maybe_remove_orphans = if remove_orphans {
|
|
" --remove-orphans"
|
|
} else {
|
|
""
|
|
};
|
|
periphery
|
|
.request(ComposeExecution {
|
|
project: stack.project_name(false),
|
|
command: format!(
|
|
"down{maybe_timeout}{maybe_remove_orphans}{service_args}"
|
|
),
|
|
})
|
|
.await
|
|
}
|
|
}
|
|
|
|
pub fn maybe_timeout(timeout: Option<i32>) -> String {
|
|
if let Some(timeout) = timeout {
|
|
format!(" --timeout {timeout}")
|
|
} else {
|
|
String::new()
|
|
}
|
|
}
|