feat(install): add --container-only flag to install command
- Add --container-only flag to create container without completing full installation - Exit immediately after container creation - Useful for manual setup or debugging installation issues
This commit is contained in:
parent
d1cb6b758c
commit
dfe5162f66
2 changed files with 88 additions and 4 deletions
|
|
@ -84,7 +84,7 @@ pub async fn run() -> Result<()> {
|
|||
}
|
||||
"install" => {
|
||||
if args.len() < 3 {
|
||||
eprintln!("Usage: botserver install <component> [--container] [--tenant <name>]");
|
||||
eprintln!("Usage: botserver install <component> [--container] [--container-only] [--tenant <name>]");
|
||||
return Ok(());
|
||||
}
|
||||
let component = &args[2];
|
||||
|
|
@ -99,17 +99,26 @@ pub async fn run() -> Result<()> {
|
|||
} else {
|
||||
InstallMode::Local
|
||||
};
|
||||
let container_only = args.contains(&"--container-only".to_string());
|
||||
let tenant = if let Some(idx) = args.iter().position(|a| a == "--tenant") {
|
||||
args.get(idx + 1).cloned()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let pm = PackageManager::new(mode, tenant)?;
|
||||
let result = pm.install(component).await?;
|
||||
println!("* Component '{}' installed successfully", component);
|
||||
let pm = PackageManager::new(mode.clone(), tenant)?;
|
||||
|
||||
let result = if container_only && mode == InstallMode::Container {
|
||||
Some(pm.install_container_only(component)?)
|
||||
} else {
|
||||
pm.install(component).await?
|
||||
};
|
||||
|
||||
if let Some(install_result) = result {
|
||||
install_result.print();
|
||||
if container_only {
|
||||
println!("\n* Container created successfully (--container-only mode)");
|
||||
println!("* Run without --container-only to complete installation");
|
||||
}
|
||||
}
|
||||
}
|
||||
"remove" => {
|
||||
|
|
|
|||
|
|
@ -163,6 +163,72 @@ impl PackageManager {
|
|||
self.run_commands(post_cmds, "local", &component.name)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn install_container_only(&self, component_name: &str) -> Result<InstallResult> {
|
||||
let container_name = format!("{}-{}", self.tenant, component_name);
|
||||
|
||||
let _ = safe_lxd(&["init", "--auto"]);
|
||||
|
||||
let images = [
|
||||
"ubuntu:24.04",
|
||||
"ubuntu:22.04",
|
||||
"images:debian/12",
|
||||
"images:debian/11",
|
||||
];
|
||||
|
||||
let mut last_error = String::new();
|
||||
let mut success = false;
|
||||
|
||||
for image in &images {
|
||||
info!("Attempting to create container with image: {}", image);
|
||||
let output = safe_lxc(&[
|
||||
"launch",
|
||||
image,
|
||||
&container_name,
|
||||
"-c",
|
||||
"security.privileged=true",
|
||||
]);
|
||||
|
||||
let output = match output {
|
||||
Some(o) => o,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
if output.status.success() {
|
||||
info!("Successfully created container with image: {}", image);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
last_error = String::from_utf8_lossy(&output.stderr).to_string();
|
||||
warn!("Failed to create container with {}: {}", image, last_error);
|
||||
|
||||
let _ = safe_lxc(&["delete", &container_name, "--force"]);
|
||||
}
|
||||
|
||||
if !success {
|
||||
return Err(anyhow::anyhow!(
|
||||
"LXC container creation failed with all images. Last error: {}",
|
||||
last_error
|
||||
));
|
||||
}
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_secs(15));
|
||||
|
||||
let container_ip = Self::get_container_ip(&container_name)?;
|
||||
|
||||
info!("Container '{}' created successfully at IP: {}", container_name, container_ip);
|
||||
|
||||
Ok(InstallResult {
|
||||
component: component_name.to_string(),
|
||||
container_name: container_name.clone(),
|
||||
container_ip: container_ip.clone(),
|
||||
ports: vec![],
|
||||
env_vars: std::collections::HashMap::new(),
|
||||
connection_info: format!(
|
||||
"Container '{}' created successfully at IP: {}\nRun without --container-only to complete installation.",
|
||||
container_name, container_ip
|
||||
),
|
||||
})
|
||||
}
|
||||
pub fn install_container(&self, component: &ComponentConfig) -> Result<InstallResult> {
|
||||
let container_name = format!("{}-{}", self.tenant, component.name);
|
||||
|
||||
|
|
@ -216,6 +282,15 @@ impl PackageManager {
|
|||
"mkdir -p /opt/gbo/bin /opt/gbo/data /opt/gbo/conf /opt/gbo/logs",
|
||||
)?;
|
||||
|
||||
self.exec_in_container(
|
||||
&container_name,
|
||||
"echo 'nameserver 8.8.8.8' > /etc/resolv.conf",
|
||||
)?;
|
||||
self.exec_in_container(
|
||||
&container_name,
|
||||
"echo 'nameserver 8.8.4.4' >> /etc/resolv.conf",
|
||||
)?;
|
||||
|
||||
self.exec_in_container(&container_name, "apt-get update -qq")?;
|
||||
self.exec_in_container(
|
||||
&container_name,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue