Implement git clone approach for nixos-rebuild
Replace direct directory access with git clone/pull approach: - Add git configuration options (url, branch, working_dir) to NixOS module - Update SystemConfig and AgentCommand to use git parameters - Implement ensure_git_repository() method for clone/pull operations - Agent clones nixosbox to /var/lib/cm-dashboard/nixos-config - Maintains security while solving permission denied issues The agent now manages its own copy of the configuration without needing access to /home/cm directory.
This commit is contained in:
@@ -232,9 +232,9 @@ impl Agent {
|
||||
error!("Failed to execute service control: {}", e);
|
||||
}
|
||||
}
|
||||
AgentCommand::SystemRebuild { nixos_path } => {
|
||||
info!("Processing SystemRebuild command with path: {}", nixos_path);
|
||||
if let Err(e) = self.handle_system_rebuild(&nixos_path).await {
|
||||
AgentCommand::SystemRebuild { git_url, git_branch, working_dir } => {
|
||||
info!("Processing SystemRebuild command: {} @ {} -> {}", git_url, git_branch, working_dir);
|
||||
if let Err(e) = self.handle_system_rebuild(&git_url, &git_branch, &working_dir).await {
|
||||
error!("Failed to execute system rebuild: {}", e);
|
||||
}
|
||||
}
|
||||
@@ -281,9 +281,9 @@ impl Agent {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Handle NixOS system rebuild commands
|
||||
async fn handle_system_rebuild(&self, nixos_path: &str) -> Result<()> {
|
||||
info!("Starting NixOS system rebuild from path: {}", nixos_path);
|
||||
/// Handle NixOS system rebuild commands with git clone approach
|
||||
async fn handle_system_rebuild(&self, git_url: &str, git_branch: &str, working_dir: &str) -> Result<()> {
|
||||
info!("Starting NixOS system rebuild: {} @ {} -> {}", git_url, git_branch, working_dir);
|
||||
|
||||
// Enable maintenance mode before rebuild
|
||||
let maintenance_file = "/tmp/cm-maintenance";
|
||||
@@ -293,15 +293,23 @@ impl Agent {
|
||||
info!("Maintenance mode enabled");
|
||||
}
|
||||
|
||||
// Change to nixos directory and execute rebuild as cm user
|
||||
let output = tokio::process::Command::new("sudo")
|
||||
.arg("-u")
|
||||
.arg("cm")
|
||||
.arg("nixos-rebuild")
|
||||
.arg("switch")
|
||||
.current_dir(nixos_path)
|
||||
.output()
|
||||
.await;
|
||||
// Clone or update repository
|
||||
let git_result = self.ensure_git_repository(git_url, git_branch, working_dir).await;
|
||||
|
||||
// Execute nixos-rebuild if git operation succeeded
|
||||
let rebuild_result = if git_result.is_ok() {
|
||||
info!("Git repository ready, executing nixos-rebuild");
|
||||
tokio::process::Command::new("sudo")
|
||||
.arg("-u")
|
||||
.arg("cm")
|
||||
.arg("nixos-rebuild")
|
||||
.arg("switch")
|
||||
.current_dir(working_dir)
|
||||
.output()
|
||||
.await
|
||||
} else {
|
||||
return git_result.and_then(|_| unreachable!());
|
||||
};
|
||||
|
||||
// Always try to remove maintenance mode file
|
||||
if let Err(e) = tokio::fs::remove_file(maintenance_file).await {
|
||||
@@ -313,7 +321,7 @@ impl Agent {
|
||||
}
|
||||
|
||||
// Check rebuild result
|
||||
match output {
|
||||
match rebuild_result {
|
||||
Ok(output) => {
|
||||
if output.status.success() {
|
||||
info!("NixOS rebuild completed successfully");
|
||||
@@ -335,4 +343,54 @@ impl Agent {
|
||||
info!("System rebuild completed, triggering metric refresh");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Ensure git repository is cloned and up to date
|
||||
async fn ensure_git_repository(&self, git_url: &str, git_branch: &str, working_dir: &str) -> Result<()> {
|
||||
use std::path::Path;
|
||||
|
||||
let git_dir = Path::new(working_dir).join(".git");
|
||||
|
||||
if git_dir.exists() {
|
||||
info!("Git repository exists, updating to latest {}", git_branch);
|
||||
|
||||
// Pull latest changes
|
||||
let output = tokio::process::Command::new("git")
|
||||
.arg("pull")
|
||||
.arg("origin")
|
||||
.arg(git_branch)
|
||||
.current_dir(working_dir)
|
||||
.output()
|
||||
.await?;
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
error!("Git pull failed: {}", stderr);
|
||||
return Err(anyhow::anyhow!("Git pull failed: {}", stderr));
|
||||
}
|
||||
|
||||
info!("Git repository updated successfully");
|
||||
} else {
|
||||
info!("Cloning git repository from {} (branch: {})", git_url, git_branch);
|
||||
|
||||
// Clone repository
|
||||
let output = tokio::process::Command::new("git")
|
||||
.arg("clone")
|
||||
.arg("--branch")
|
||||
.arg(git_branch)
|
||||
.arg(git_url)
|
||||
.arg(working_dir)
|
||||
.output()
|
||||
.await?;
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
error!("Git clone failed: {}", stderr);
|
||||
return Err(anyhow::anyhow!("Git clone failed: {}", stderr));
|
||||
}
|
||||
|
||||
info!("Git repository cloned successfully");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,9 @@ pub enum AgentCommand {
|
||||
},
|
||||
/// Rebuild NixOS system
|
||||
SystemRebuild {
|
||||
nixos_path: String, // Path to nixosbox directory
|
||||
git_url: String,
|
||||
git_branch: String,
|
||||
working_dir: String,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user