add start stop remove container

This commit is contained in:
beckerinj
2022-12-17 01:27:06 -05:00
parent 839af15311
commit be58cec1c9
11 changed files with 404 additions and 90 deletions
+194 -47
View File
@@ -194,53 +194,6 @@ impl State {
Ok(new_deployment)
}
pub async fn deploy(&self, deployment_id: &str, user: &RequestUser) -> anyhow::Result<Update> {
let mut deployment = self
.get_deployment_check_permissions(deployment_id, user, PermissionLevel::Write)
.await?;
if let Some(build_id) = &deployment.build_id {
let build = self.db.get_build(build_id).await?;
let image = if let Some(docker_account) = &build.docker_account {
if deployment.docker_run_args.docker_account.is_none() {
deployment.docker_run_args.docker_account = Some(docker_account.to_string())
}
format!("{docker_account}/{}", to_monitor_name(&build.name))
} else {
to_monitor_name(&build.name)
};
let version = if let Some(version) = &deployment.build_version {
version.to_string()
} else {
"latest".to_string()
};
deployment.docker_run_args.image = format!("{image}:{version}");
};
let server = self.db.get_server(&deployment.server_id).await?;
let mut update = Update {
target: UpdateTarget::Deployment(deployment_id.to_string()),
operation: Operation::DeployDeployment,
start_ts: unix_timestamp_ms() as i64,
status: UpdateStatus::InProgress,
operator: user.id.clone(),
success: true,
// version: deployment.docker_run_args.,
..Default::default()
};
update.id = self.add_update(update.clone()).await?;
let deploy_log = self.periphery.deploy(&server, &deployment).await?;
update.success = deploy_log.success;
update.logs.push(deploy_log);
update.status = UpdateStatus::Complete;
update.end_ts = Some(unix_timestamp_ms() as i64);
self.update_update(update.clone()).await?;
Ok(update)
}
pub async fn reclone_deployment(
&self,
deployment_id: &str,
@@ -281,4 +234,198 @@ impl State {
Ok(update)
}
pub async fn deploy_container(
&self,
deployment_id: &str,
user: &RequestUser,
) -> anyhow::Result<Update> {
let mut deployment = self
.get_deployment_check_permissions(deployment_id, user, PermissionLevel::Write)
.await?;
if let Some(build_id) = &deployment.build_id {
let build = self.db.get_build(build_id).await?;
let image = if let Some(docker_account) = &build.docker_account {
if deployment.docker_run_args.docker_account.is_none() {
deployment.docker_run_args.docker_account = Some(docker_account.to_string())
}
format!("{docker_account}/{}", to_monitor_name(&build.name))
} else {
to_monitor_name(&build.name)
};
let version = if let Some(version) = &deployment.build_version {
version.to_string()
} else {
"latest".to_string()
};
deployment.docker_run_args.image = format!("{image}:{version}");
};
let server = self.db.get_server(&deployment.server_id).await?;
let mut update = Update {
target: UpdateTarget::Deployment(deployment_id.to_string()),
operation: Operation::DeployContainer,
start_ts: unix_timestamp_ms() as i64,
status: UpdateStatus::InProgress,
operator: user.id.clone(),
success: true,
..Default::default()
};
update.id = self.add_update(update.clone()).await?;
let deploy_log = self.periphery.deploy(&server, &deployment).await?;
update.success = deploy_log.success;
update.logs.push(deploy_log);
update.status = UpdateStatus::Complete;
update.end_ts = Some(unix_timestamp_ms() as i64);
self.update_update(update.clone()).await?;
Ok(update)
}
pub async fn start_container(
&self,
deployment_id: &str,
user: &RequestUser,
) -> anyhow::Result<Update> {
let start_ts = unix_timestamp_ms() as i64;
let deployment = self
.get_deployment_check_permissions(deployment_id, user, PermissionLevel::Write)
.await?;
let server = self.db.get_server(&deployment.server_id).await?;
let mut update = Update {
target: UpdateTarget::Deployment(deployment_id.to_string()),
operation: Operation::StartContainer,
start_ts,
status: UpdateStatus::InProgress,
success: true,
operator: user.id.clone(),
..Default::default()
};
update.id = self.add_update(update.clone()).await?;
let log = self
.periphery
.container_start(&server, &deployment.name)
.await;
update.success = match log {
Ok(log) => {
let success = log.success;
update.logs.push(log);
success
}
Err(e) => {
update
.logs
.push(Log::error("start container", format!("{e:#?}")));
false
}
};
update.end_ts = Some(unix_timestamp_ms() as i64);
update.status = UpdateStatus::Complete;
self.update_update(update.clone()).await?;
Ok(update)
}
pub async fn stop_container(
&self,
deployment_id: &str,
user: &RequestUser,
) -> anyhow::Result<Update> {
let start_ts = unix_timestamp_ms() as i64;
let deployment = self
.get_deployment_check_permissions(deployment_id, user, PermissionLevel::Write)
.await?;
let server = self.db.get_server(&deployment.server_id).await?;
let mut update = Update {
target: UpdateTarget::Deployment(deployment_id.to_string()),
operation: Operation::StopContainer,
start_ts,
status: UpdateStatus::InProgress,
success: true,
operator: user.id.clone(),
..Default::default()
};
update.id = self.add_update(update.clone()).await?;
let log = self
.periphery
.container_stop(&server, &deployment.name)
.await;
update.success = match log {
Ok(log) => {
let success = log.success;
update.logs.push(log);
success
}
Err(e) => {
update
.logs
.push(Log::error("stop container", format!("{e:#?}")));
false
}
};
update.end_ts = Some(unix_timestamp_ms() as i64);
update.status = UpdateStatus::Complete;
self.update_update(update.clone()).await?;
Ok(update)
}
pub async fn remove_container(
&self,
deployment_id: &str,
user: &RequestUser,
) -> anyhow::Result<Update> {
let start_ts = unix_timestamp_ms() as i64;
let deployment = self
.get_deployment_check_permissions(deployment_id, user, PermissionLevel::Write)
.await?;
let server = self.db.get_server(&deployment.server_id).await?;
let mut update = Update {
target: UpdateTarget::Deployment(deployment_id.to_string()),
operation: Operation::RemoveContainer,
start_ts,
status: UpdateStatus::InProgress,
success: true,
operator: user.id.clone(),
..Default::default()
};
update.id = self.add_update(update.clone()).await?;
let log = self
.periphery
.container_remove(&server, &deployment.name)
.await;
update.success = match log {
Ok(log) => {
let success = log.success;
update.logs.push(log);
success
}
Err(e) => {
update
.logs
.push(Log::error("remove container", format!("{e:#?}")));
false
}
};
update.end_ts = Some(unix_timestamp_ms() as i64);
update.status = UpdateStatus::Complete;
self.update_update(update.clone()).await?;
Ok(update)
}
}
+53 -4
View File
@@ -1,9 +1,10 @@
use anyhow::{anyhow, Context};
use async_timing_util::unix_timestamp_ms;
use diff::Diff;
use helpers::to_monitor_name;
use types::{
traits::Permissioned, Log, Operation, PermissionLevel, Procedure, ProcedureStage, Update,
UpdateTarget,
traits::Permissioned, Log, Operation, PermissionLevel, Procedure, ProcedureOperation::*,
ProcedureStage, Update, UpdateStatus, UpdateTarget,
};
use crate::{auth::RequestUser, state::State};
@@ -105,13 +106,51 @@ impl State {
pub async fn update_procedure(
&self,
new_procedure: Procedure,
mut new_procedure: Procedure,
user: &RequestUser,
) -> anyhow::Result<Procedure> {
let current_procedure = self
.get_procedure_check_permissions(&new_procedure.id, user, PermissionLevel::Write)
.await?;
todo!()
let start_ts = unix_timestamp_ms() as i64;
// none of these should be changed through this method
new_procedure.name = current_procedure.name.clone();
new_procedure.permissions = current_procedure.permissions.clone();
new_procedure.created_at = current_procedure.created_at;
new_procedure.updated_at = start_ts;
// check to make sure no stages have been added that user does not have access to
self.db
.procedures
.update_one(
&new_procedure.id,
mungos::Update::Regular(new_procedure.clone()),
)
.await
.context("failed at update one deployment")?;
let diff = current_procedure.diff(&new_procedure);
let update = Update {
operation: Operation::UpdateProcedure,
target: UpdateTarget::Procedure(new_procedure.id.clone()),
end_ts: Some(start_ts),
start_ts,
status: UpdateStatus::Complete,
logs: vec![Log::simple(
"procedure update",
serde_json::to_string_pretty(&diff).unwrap(),
)],
operator: user.id.clone(),
success: true,
..Default::default()
};
self.add_update(update).await?;
Ok(new_procedure)
}
pub async fn run_procedure(&self, id: &str, user: &RequestUser) -> anyhow::Result<Vec<Update>> {
@@ -125,6 +164,16 @@ impl State {
} in procedure.stages
{
match operation {
StartContainer => {}
StopContainer => {}
RemoveContainer => {}
DeployContainer => {}
RecloneDeployment => {}
BuildBuild => {}
RecloneBuild => {}
PruneImagesServer => {}
_ => {}
}
}
+56 -14
View File
@@ -114,20 +114,6 @@ pub fn router() -> Router {
},
),
)
.route(
"/:id/deploy",
post(
|Extension(state): StateExtension,
Extension(user): RequestUserExtension,
Path(deployment_id): Path<DeploymentId>| async move {
let update = state
.deploy(&deployment_id.id, &user)
.await
.map_err(handle_anyhow_error)?;
response!(Json(update))
},
),
)
.route(
"/:id/reclone",
post(
@@ -142,6 +128,62 @@ pub fn router() -> Router {
},
),
)
.route(
"/:id/deploy",
post(
|Extension(state): StateExtension,
Extension(user): RequestUserExtension,
Path(deployment_id): Path<DeploymentId>| async move {
let update = state
.deploy_container(&deployment_id.id, &user)
.await
.map_err(handle_anyhow_error)?;
response!(Json(update))
},
),
)
.route(
"/:id/start_container",
post(
|Extension(state): StateExtension,
Extension(user): RequestUserExtension,
Path(deployment_id): Path<DeploymentId>| async move {
let update = state
.start_container(&deployment_id.id, &user)
.await
.map_err(handle_anyhow_error)?;
response!(Json(update))
},
),
)
.route(
"/:id/stop_container",
post(
|Extension(state): StateExtension,
Extension(user): RequestUserExtension,
Path(deployment_id): Path<DeploymentId>| async move {
let update = state
.stop_container(&deployment_id.id, &user)
.await
.map_err(handle_anyhow_error)?;
response!(Json(update))
},
),
)
.route(
"/:id/remove_container",
post(
|Extension(state): StateExtension,
Extension(user): RequestUserExtension,
Path(deployment_id): Path<DeploymentId>| async move {
let update = state
.remove_container(&deployment_id.id, &user)
.await
.map_err(handle_anyhow_error)?;
response!(Json(update))
},
),
)
}
impl State {