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:
parent
864cafd61f
commit
b3c67f4b7f
@ -232,9 +232,9 @@ impl Agent {
|
|||||||
error!("Failed to execute service control: {}", e);
|
error!("Failed to execute service control: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AgentCommand::SystemRebuild { nixos_path } => {
|
AgentCommand::SystemRebuild { git_url, git_branch, working_dir } => {
|
||||||
info!("Processing SystemRebuild command with path: {}", nixos_path);
|
info!("Processing SystemRebuild command: {} @ {} -> {}", git_url, git_branch, working_dir);
|
||||||
if let Err(e) = self.handle_system_rebuild(&nixos_path).await {
|
if let Err(e) = self.handle_system_rebuild(&git_url, &git_branch, &working_dir).await {
|
||||||
error!("Failed to execute system rebuild: {}", e);
|
error!("Failed to execute system rebuild: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,9 +281,9 @@ impl Agent {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle NixOS system rebuild commands
|
/// Handle NixOS system rebuild commands with git clone approach
|
||||||
async fn handle_system_rebuild(&self, nixos_path: &str) -> Result<()> {
|
async fn handle_system_rebuild(&self, git_url: &str, git_branch: &str, working_dir: &str) -> Result<()> {
|
||||||
info!("Starting NixOS system rebuild from path: {}", nixos_path);
|
info!("Starting NixOS system rebuild: {} @ {} -> {}", git_url, git_branch, working_dir);
|
||||||
|
|
||||||
// Enable maintenance mode before rebuild
|
// Enable maintenance mode before rebuild
|
||||||
let maintenance_file = "/tmp/cm-maintenance";
|
let maintenance_file = "/tmp/cm-maintenance";
|
||||||
@ -293,15 +293,23 @@ impl Agent {
|
|||||||
info!("Maintenance mode enabled");
|
info!("Maintenance mode enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change to nixos directory and execute rebuild as cm user
|
// Clone or update repository
|
||||||
let output = tokio::process::Command::new("sudo")
|
let git_result = self.ensure_git_repository(git_url, git_branch, working_dir).await;
|
||||||
.arg("-u")
|
|
||||||
.arg("cm")
|
// Execute nixos-rebuild if git operation succeeded
|
||||||
.arg("nixos-rebuild")
|
let rebuild_result = if git_result.is_ok() {
|
||||||
.arg("switch")
|
info!("Git repository ready, executing nixos-rebuild");
|
||||||
.current_dir(nixos_path)
|
tokio::process::Command::new("sudo")
|
||||||
.output()
|
.arg("-u")
|
||||||
.await;
|
.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
|
// Always try to remove maintenance mode file
|
||||||
if let Err(e) = tokio::fs::remove_file(maintenance_file).await {
|
if let Err(e) = tokio::fs::remove_file(maintenance_file).await {
|
||||||
@ -313,7 +321,7 @@ impl Agent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check rebuild result
|
// Check rebuild result
|
||||||
match output {
|
match rebuild_result {
|
||||||
Ok(output) => {
|
Ok(output) => {
|
||||||
if output.status.success() {
|
if output.status.success() {
|
||||||
info!("NixOS rebuild completed successfully");
|
info!("NixOS rebuild completed successfully");
|
||||||
@ -335,4 +343,54 @@ impl Agent {
|
|||||||
info!("System rebuild completed, triggering metric refresh");
|
info!("System rebuild completed, triggering metric refresh");
|
||||||
Ok(())
|
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
|
/// Rebuild NixOS system
|
||||||
SystemRebuild {
|
SystemRebuild {
|
||||||
nixos_path: String, // Path to nixosbox directory
|
git_url: String,
|
||||||
|
git_branch: String,
|
||||||
|
working_dir: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,7 @@ pub struct Dashboard {
|
|||||||
terminal: Option<Terminal<CrosstermBackend<io::Stdout>>>,
|
terminal: Option<Terminal<CrosstermBackend<io::Stdout>>>,
|
||||||
headless: bool,
|
headless: bool,
|
||||||
initial_commands_sent: std::collections::HashSet<String>,
|
initial_commands_sent: std::collections::HashSet<String>,
|
||||||
|
config: DashboardConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dashboard {
|
impl Dashboard {
|
||||||
@ -132,6 +133,7 @@ impl Dashboard {
|
|||||||
terminal,
|
terminal,
|
||||||
headless,
|
headless,
|
||||||
initial_commands_sent: std::collections::HashSet::new(),
|
initial_commands_sent: std::collections::HashSet::new(),
|
||||||
|
config,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,8 +299,10 @@ impl Dashboard {
|
|||||||
}
|
}
|
||||||
UiCommand::SystemRebuild { hostname } => {
|
UiCommand::SystemRebuild { hostname } => {
|
||||||
info!("Sending system rebuild command to {}", hostname);
|
info!("Sending system rebuild command to {}", hostname);
|
||||||
let agent_command = AgentCommand::SystemRebuild {
|
let agent_command = AgentCommand::SystemRebuild {
|
||||||
nixos_path: "/home/cm/nixosbox".to_string(), // Fixed path per requirements
|
git_url: self.config.system.nixos_config_git_url.clone(),
|
||||||
|
git_branch: self.config.system.nixos_config_branch.clone(),
|
||||||
|
working_dir: self.config.system.nixos_config_working_dir.clone(),
|
||||||
};
|
};
|
||||||
self.zmq_command_sender.send_command(&hostname, agent_command).await?;
|
self.zmq_command_sender.send_command(&hostname, agent_command).await?;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,9 @@ pub enum AgentCommand {
|
|||||||
},
|
},
|
||||||
/// Rebuild NixOS system
|
/// Rebuild NixOS system
|
||||||
SystemRebuild {
|
SystemRebuild {
|
||||||
nixos_path: String, // Path to nixosbox directory
|
git_url: String,
|
||||||
|
git_branch: String,
|
||||||
|
working_dir: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use std::path::Path;
|
|||||||
pub struct DashboardConfig {
|
pub struct DashboardConfig {
|
||||||
pub zmq: ZmqConfig,
|
pub zmq: ZmqConfig,
|
||||||
pub hosts: HostsConfig,
|
pub hosts: HostsConfig,
|
||||||
|
pub system: SystemConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ZMQ consumer configuration
|
/// ZMQ consumer configuration
|
||||||
@ -21,6 +22,14 @@ pub struct HostsConfig {
|
|||||||
pub predefined_hosts: Vec<String>,
|
pub predefined_hosts: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// System configuration
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct SystemConfig {
|
||||||
|
pub nixos_config_git_url: String,
|
||||||
|
pub nixos_config_branch: String,
|
||||||
|
pub nixos_config_working_dir: String,
|
||||||
|
}
|
||||||
|
|
||||||
impl DashboardConfig {
|
impl DashboardConfig {
|
||||||
pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
|
pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user