Skip to content

Commit

Permalink
feat: working open vscode ide and check install extension
Browse files Browse the repository at this point in the history
  • Loading branch information
batleforc committed Jan 4, 2025
1 parent bba973d commit b070e6c
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 5 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions apps/dev_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ default-run = "dev_cli"
helper = { path = "../../libs/helper" }
tool_tracing = { path = "../../libs/tool_tracing" }
devfile = { path = "../../libs/devfile" }
vscode = { path = "../../libs/vscode" }
crd = { path = "../../libs/crd" }
tokio = { workspace = true }
tracing = { workspace = true }
k8s-openapi = { workspace = true }
Expand Down
158 changes: 155 additions & 3 deletions apps/dev_cli/src/code/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
use clap::Subcommand;
use crd::dev_work_space::DevWorkspace;
use devfile::lifecycle::{
ask_if_pod_should_up::ask_if_pod_should_up, find_pod_by_ws_name::find_pod_by_ws_name,
start_stop::start_stop_devworkspace, wait_for_status::wait_for_status,
};
use helper::{select_pod::select_pod, Helper};
use vscode::{extensions::Extensions, healthcheck, open_code};

#[derive(Subcommand)]
#[derive(Subcommand, Debug)]
#[command(
name = "Code",
about = "Handle the code subcommand",
Expand All @@ -9,7 +16,7 @@ use clap::Subcommand;
pub enum Code {
/// Open the selected workspace in vscode
Open {
/// The name of the container to spawn the vscode in
/// The name of the container to spawn the vscode in, by default it will use the first one
#[arg(long)]
name: Option<String>,

Expand Down Expand Up @@ -43,5 +50,150 @@ pub enum Code {

impl Code {
/// Run the subcommand
pub async fn run(&self) {}
#[tracing::instrument(level = "trace")]
pub async fn run(&self) {
match self {
Code::Open {
name,
port,
path,
workspace_name,
namespace,
context,
} => {
Self::open(
name.clone(),
*port,
path.clone(),
workspace_name.clone(),
namespace.clone(),
context.clone(),
)
.await;
}
Code::Check { install } => {
Self::check(*install).await;
}
}
}

#[tracing::instrument(level = "trace")]
pub async fn check(install: bool) {
// Check if the needed extensions are installed
let extensions = Extensions::new();
let missing_extensions = extensions.check_missing_extensions();
match missing_extensions {
Ok(missing_extensions) => {
if missing_extensions.is_empty() {
tracing::info!("All mandatory extensions are installed");
} else {
tracing::info!("Missing extensions: {:?}", missing_extensions);
if install {
for extension in missing_extensions {
tracing::info!("Installing extension: {}", extension);
match extensions.install_extension(&extension) {
Ok(_) => {
tracing::info!("Extension {} installed", extension);
}
Err(err) => {
tracing::error!("Error: {:?}", err);
}
};
}
}
}
}
Err(err) => {
tracing::error!("Error: {:?}", err);
}
}
}

#[tracing::instrument(level = "trace")]
pub async fn open(
name: Option<String>,
port: u16,
path: String,
workspace_name: String,
namespace: Option<String>,
context: Option<String>,
) {
tracing::info!("Opening workspace {} in vscode, please dont kill this terminal or the workspaces will close itself due to inactivity", workspace_name);
let client = match Helper::get_client().await {
Some(client) => client,
None => return,
};
let pod = match find_pod_by_ws_name(
client.clone(),
Some(workspace_name.clone()),
namespace.clone(),
)
.await
{
Some(pod) => pod,
None => {
if ask_if_pod_should_up().await {
start_stop_devworkspace(
client.clone(),
workspace_name.clone(),
namespace.clone(),
true,
)
.await;
if wait_for_status(
Helper::get_api::<DevWorkspace>(client.clone(), namespace.clone()),
workspace_name.clone(),
"Running".to_string(),
2000,
150, // Fail after 5 minutes
)
.await
.is_none()
{
return;
}
match find_pod_by_ws_name(
client.clone(),
Some(workspace_name.clone()),
namespace,
)
.await
{
Some(pod) => pod,
None => return,
}
} else {
return;
}
}
};
let container_name = match select_pod(name, pod.clone()) {
Some(container_name) => container_name,
None => return,
};

let open_code = open_code::OpenCode {
context,
pod_name: Some(pod.metadata.name.clone().unwrap()),
namespace: Some(pod.metadata.namespace.clone().unwrap()),
container_name: Some(container_name),
container_image: Some(
pod.spec.clone().unwrap().containers[0]
.image
.clone()
.unwrap(),
),
path: Some(path),
};
tracing::info!("Opening VsCode");
open_code.open();
tracing::info!("Healthcheck started");
healthcheck::healthcheck(
client,
pod.metadata.name.unwrap(),
port,
pod.metadata.namespace,
)
.await;
}
}
4 changes: 2 additions & 2 deletions apps/dev_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ async fn main() {
println!("Namespace: {:?}", namespace);
println!("Workspace name: {:?}", workspace_name);
}
Some(Commands::Code { code: _ }) => {
println!("Code command");
Some(Commands::Code { code }) => {
code.as_ref().unwrap().run().await;
}
None => tracing::info!("No command provided"),
};
Expand Down
1 change: 1 addition & 0 deletions libs/helper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::collections::HashMap;
use tokio::io::AsyncReadExt;

pub mod error;
pub mod select_pod;

#[derive(Clone, Debug)]
pub struct Helper {}
Expand Down
34 changes: 34 additions & 0 deletions libs/helper/src/select_pod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use k8s_openapi::api::core::v1::Pod;

#[tracing::instrument(level = "trace")]
pub fn select_pod(target_name: Option<String>, pod: Pod) -> Option<String> {
match target_name {
Some(container_named) => {
if !pod
.spec
.clone()
.unwrap()
.containers
.into_iter()
.any(|c| c.name == container_named)
{
tracing::error!(
"Pod does not have container : {}",
container_named.to_string()
);
return None;
}
Some(container_named)
}
None => match pod.spec.unwrap().containers.first() {
Some(container) => {
tracing::info!("Using first container : {}", container.name.to_string());
Some(container.name.to_string())
}
None => {
tracing::error!("No container in the pod ? what did you do?");
return None;
}
},
}
}

0 comments on commit b070e6c

Please sign in to comment.