mirror of
https://github.com/moghtech/komodo.git
synced 2026-03-11 17:44:19 -05:00
* add some network stuff to container summary * improve settings tables UI * periphery build supports additional tags * fix variable container sizing * alert types newline wrap * plumbing for Stack resource * plumbing for Stack resource * mount stack api * stack resource sync * get remote compose file * support image_name and image_tag * add server config placeholders. default server config address * configure image name and image tag * deployment work with build image_name and image_tag * stack UI * fe builds * configure registry provider and account * implement periphery stack api * stack poll interval * add UI provider management * deploy stacks * build push commit hash tag. * Destroy stack * update default core port to 9120 * remove git_account alias * finish stack (and container) api * frontend builds * cant cancel server based builds * fix * use git pull -f * 9120 * start UI updates (#15) * fix From<Stack> for CloneArgs * remove unused imports * UI Updates (#16) * cleanup dashboard charts for resources * bring back solid scrollbars * enable sidebar scrolling * remove alerts from all resources * pass jwt secret * stacks dont delete the target * parse services from yaml * stacks deploy * close * looking good * closer * destroy stack when file missing. onboard stacks * figure out stack container name matching * get stack state correct * work with service views * UI Updates - Sidebar, Topbar Alerts, and All Resources page (#17) * move sidebar to use fixed positioning instead of sticky * add alert details dialog to topbar alerts * cleanup all resources page layout * ensure resource links don't propagate clicks * periphery support passing env with --env-file * StackServicePage * default run_directory to ./ for clarify * add stack webhook listeners * add default compose name of stack name * stacks controlled with project name * migrate to dotenvy * add stack to dashboard * remove deploying / destroying stack services * update config files * fix getting service logs * git / docker provider management api * implement passing git / registry token from db * rename system user Github to Git Webhook * seperate deployed and latest services on stack info * add stack service level operations * UI Updates - Update Shadcn/UI components, prevent navbar menu layout shift (#20) * add dashboard pie for resource syncs * dashboard items same height * update shadcn components * ensure centered following sheet update * cleanup layout, prevent navbar menu layout shifts * add manual filter, fix toast call * guard webhooks * remove deployed_message, latest_message from StackListItemInfo * stop all containers on server correctly * support multiple compose files * cache all containers networks images projects * remove project missing from db cache * work on sync deploy stuff * rework deployment sync deploy to support stacks. they can depend on each other. * UI Updates - Remove topbar transparency, pretty status badges, tidy resource page layout with a 'back' button (#21) * remove topbar transparency * cleanup unused * responsive dashboard * better mobile header * dont need to calc 64px less since header is using position fixed * add status badge component * update status badges * further simplify layout * allow undefined status as prop * use new status badges for alerts * update status badges for all resources * undo layout change * tidy up resource page layout, add back button * no need for button wrapper * remove unused * build cancel log * update ts types * fix fe type changes * fe tweaks * remove on build logs * core refresh cache immediately on startup * jwt_ttl * canonicalize run directory on host * update canonicalize error message * core use docker-compose * fix incorrect project missing, add status string to stack info * remove entries in "after" that aren't deploying * fix dockerfiel * build custom tag postfix * sync fixes * ensure UpdateGitProviderAccount doesn't change id * ensure UpdateDockerRegistryAccount doesn't change id * configure providers in the UI * add // comment support to env, conversions * add updates for provider deletes * improve sync pending deploy log * add more deployment actions * add backward compat with v1.12 for clone repo * stack deploy format * fe * alert menus clone when click resource link * rename stacks * don't close on click * snake case stack state, in line with deployment state * sync redeploy stack if newer hash (optional behind resource field 'latest_hash') * remove nav to tree * RefreshStack/Sync debug instruments * improve inline UI docs * implement resource base_permission backend * plumbing for Repo build * build repos * write env file repos * add latest hash / message to build info * add optional hash to update * keep built_hash updated * add backend for build / repo latest hash management * remove unused resources * clean up repo dirs after cache update * fix repo info deser error * add build / repo git status * fix page layouts * improve layout responsive * most config incline docs * add descriptions for all resource types * default local auth false * fix omnibar arrow keys issue * add compose file to example config * image registry * dashboard display no resources messge * update deps. * show when no config * resource sync use config git_provider * fix networks * fix deploy error due to after * update lots of docs * fix server stat charts not working * update screenshots * update changelog * add a disclaimer * remove file paths docs stuff * build repo * v1.13 - Komodo * update docs for cli * fill out the compose example more --------- Co-authored-by: Karamvir Singh <67458484+karamvirsingh98@users.noreply.github.com>
212 lines
5.6 KiB
Rust
212 lines
5.6 KiB
Rust
use std::time::Duration;
|
|
|
|
use anyhow::{anyhow, Context};
|
|
use formatting::muted;
|
|
use monitor_client::entities::{
|
|
builder::{AwsBuilderConfig, Builder, BuilderConfig},
|
|
monitor_timestamp,
|
|
server::Server,
|
|
server_template::aws::AwsServerTemplateConfig,
|
|
update::{Log, Update},
|
|
Version,
|
|
};
|
|
use periphery_client::{
|
|
api::{self, GetVersionResponse},
|
|
PeripheryClient,
|
|
};
|
|
|
|
use crate::{
|
|
cloud::{
|
|
aws::ec2::{
|
|
launch_ec2_instance, terminate_ec2_instance_with_retry,
|
|
Ec2Instance,
|
|
},
|
|
BuildCleanupData,
|
|
},
|
|
config::core_config,
|
|
helpers::update::update_update,
|
|
resource,
|
|
};
|
|
|
|
use super::periphery_client;
|
|
|
|
const BUILDER_POLL_RATE_SECS: u64 = 2;
|
|
const BUILDER_POLL_MAX_TRIES: usize = 30;
|
|
|
|
#[instrument(skip_all, fields(builder_id = builder.id, update_id = update.id))]
|
|
pub async fn get_builder_periphery(
|
|
// build: &Build,
|
|
resource_name: String,
|
|
version: Option<Version>,
|
|
builder: Builder,
|
|
update: &mut Update,
|
|
) -> anyhow::Result<(PeripheryClient, BuildCleanupData)> {
|
|
match builder.config {
|
|
BuilderConfig::Server(config) => {
|
|
if config.server_id.is_empty() {
|
|
return Err(anyhow!("builder has not configured a server"));
|
|
}
|
|
let server = resource::get::<Server>(&config.server_id).await?;
|
|
let periphery = periphery_client(&server)?;
|
|
Ok((
|
|
periphery,
|
|
BuildCleanupData::Server {
|
|
repo_name: resource_name,
|
|
},
|
|
))
|
|
}
|
|
BuilderConfig::Aws(config) => {
|
|
get_aws_builder(&resource_name, version, config, update).await
|
|
}
|
|
}
|
|
}
|
|
|
|
#[instrument(skip_all, fields(resource_name, update_id = update.id))]
|
|
async fn get_aws_builder(
|
|
resource_name: &str,
|
|
version: Option<Version>,
|
|
config: AwsBuilderConfig,
|
|
update: &mut Update,
|
|
) -> anyhow::Result<(PeripheryClient, BuildCleanupData)> {
|
|
let start_create_ts = monitor_timestamp();
|
|
|
|
let version = version.map(|v| format!("-v{v}")).unwrap_or_default();
|
|
let instance_name = format!("BUILDER-{resource_name}{version}");
|
|
let Ec2Instance { instance_id, ip } = launch_ec2_instance(
|
|
&instance_name,
|
|
AwsServerTemplateConfig::from_builder_config(&config),
|
|
)
|
|
.await?;
|
|
|
|
info!("ec2 instance launched");
|
|
|
|
let log = Log {
|
|
stage: "start build instance".to_string(),
|
|
success: true,
|
|
stdout: start_aws_builder_log(&instance_id, &ip, &config),
|
|
start_ts: start_create_ts,
|
|
end_ts: monitor_timestamp(),
|
|
..Default::default()
|
|
};
|
|
|
|
update.logs.push(log);
|
|
|
|
update_update(update.clone()).await?;
|
|
|
|
let periphery_address = format!("http://{ip}:{}", config.port);
|
|
let periphery =
|
|
PeripheryClient::new(&periphery_address, &core_config().passkey);
|
|
|
|
let start_connect_ts = monitor_timestamp();
|
|
let mut res = Ok(GetVersionResponse {
|
|
version: String::new(),
|
|
});
|
|
for _ in 0..BUILDER_POLL_MAX_TRIES {
|
|
let version = periphery
|
|
.request(api::GetVersion {})
|
|
.await
|
|
.context("failed to reach periphery client on builder");
|
|
if let Ok(GetVersionResponse { version }) = &version {
|
|
let connect_log = Log {
|
|
stage: "build instance connected".to_string(),
|
|
success: true,
|
|
stdout: format!(
|
|
"established contact with periphery on builder\nperiphery version: v{}",
|
|
version
|
|
),
|
|
start_ts: start_connect_ts,
|
|
end_ts: monitor_timestamp(),
|
|
..Default::default()
|
|
};
|
|
update.logs.push(connect_log);
|
|
update_update(update.clone()).await?;
|
|
return Ok((
|
|
periphery,
|
|
BuildCleanupData::Aws {
|
|
instance_id,
|
|
region: config.region,
|
|
},
|
|
));
|
|
}
|
|
res = version;
|
|
tokio::time::sleep(Duration::from_secs(BUILDER_POLL_RATE_SECS))
|
|
.await;
|
|
}
|
|
|
|
// Spawn terminate task in failure case (if loop is passed without return)
|
|
tokio::spawn(async move {
|
|
let _ =
|
|
terminate_ec2_instance_with_retry(config.region, &instance_id)
|
|
.await;
|
|
});
|
|
|
|
// Unwrap is safe, only way to get here is after check Ok / early return, so it must be err
|
|
Err(
|
|
res.err().unwrap().context(
|
|
"failed to start usable builder. terminating instance.",
|
|
),
|
|
)
|
|
}
|
|
|
|
#[instrument(skip(periphery, update))]
|
|
pub async fn cleanup_builder_instance(
|
|
periphery: PeripheryClient,
|
|
cleanup_data: BuildCleanupData,
|
|
update: &mut Update,
|
|
) {
|
|
match cleanup_data {
|
|
BuildCleanupData::Server { repo_name } => {
|
|
let _ = periphery
|
|
.request(api::git::DeleteRepo { name: repo_name })
|
|
.await;
|
|
}
|
|
BuildCleanupData::Aws {
|
|
instance_id,
|
|
region,
|
|
} => {
|
|
let _instance_id = instance_id.clone();
|
|
tokio::spawn(async move {
|
|
let _ =
|
|
terminate_ec2_instance_with_retry(region, &_instance_id)
|
|
.await;
|
|
});
|
|
update.push_simple_log(
|
|
"terminate instance",
|
|
format!("termination queued for instance id {instance_id}"),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn start_aws_builder_log(
|
|
instance_id: &str,
|
|
ip: &str,
|
|
config: &AwsBuilderConfig,
|
|
) -> String {
|
|
let AwsBuilderConfig {
|
|
ami_id,
|
|
instance_type,
|
|
volume_gb,
|
|
subnet_id,
|
|
assign_public_ip,
|
|
security_group_ids,
|
|
use_public_ip,
|
|
..
|
|
} = config;
|
|
|
|
let readable_sec_group_ids = security_group_ids.join(", ");
|
|
|
|
[
|
|
format!("{}: {instance_id}", muted("instance id")),
|
|
format!("{}: {ip}", muted("ip")),
|
|
format!("{}: {ami_id}", muted("ami id")),
|
|
format!("{}: {instance_type}", muted("instance type")),
|
|
format!("{}: {volume_gb} GB", muted("volume size")),
|
|
format!("{}: {subnet_id}", muted("subnet id")),
|
|
format!("{}: {readable_sec_group_ids}", muted("security groups")),
|
|
format!("{}: {assign_public_ip}", muted("assign public ip")),
|
|
format!("{}: {use_public_ip}", muted("use public ip")),
|
|
]
|
|
.join("\n")
|
|
}
|