207 lines
6.7 KiB
Markdown
207 lines
6.7 KiB
Markdown
# Buildah Debug Implementation Plan
|
|
|
|
## Current State
|
|
|
|
1. The `Builder` struct already has a `debug` field and methods to get and set it (`debug()` and `set_debug()`).
|
|
2. There's a thread-local `DEBUG` variable with functions to get and set it.
|
|
3. The `execute_buildah_command` function checks the thread-local debug flag and outputs some debug information.
|
|
4. There's an unused `execute_buildah_command_with_debug` function that takes a `Builder` reference.
|
|
|
|
## Requirements
|
|
|
|
1. Use only the Builder's debug flag, not the thread-local debug flag.
|
|
2. When debug is true, output stdout/stderr regardless of whether the command succeeds or fails.
|
|
3. If debug is false but there's an error, still output all information.
|
|
|
|
## Implementation Plan
|
|
|
|
### 1. Keep the Existing Thread-Local DEBUG Variable
|
|
|
|
We'll keep the existing thread-local DEBUG variable that's already in the code:
|
|
|
|
```rust
|
|
// Thread-local storage for debug flag
|
|
thread_local! {
|
|
static DEBUG: std::cell::RefCell<bool> = std::cell::RefCell::new(false);
|
|
}
|
|
```
|
|
|
|
### 2. Modify the Builder Methods to Set/Clear the Thread-Local Debug Flag
|
|
|
|
We'll modify each Builder method to set the thread-local debug flag from the Builder's debug flag before calling `execute_buildah_command` and restore it afterward:
|
|
|
|
```rust
|
|
pub fn run(&self, command: &str) -> Result<CommandResult, BuildahError> {
|
|
if let Some(container_id) = &self.container_id {
|
|
// Save the current debug flag
|
|
let previous_debug = thread_local_debug();
|
|
|
|
// Set the thread-local debug flag from the Builder's debug flag
|
|
set_thread_local_debug(self.debug);
|
|
|
|
// Execute the command
|
|
let result = execute_buildah_command(&["run", container_id, "sh", "-c", command]);
|
|
|
|
// Restore the previous debug flag
|
|
set_thread_local_debug(previous_debug);
|
|
|
|
result
|
|
} else {
|
|
Err(BuildahError::Other("No container ID available".to_string()))
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Keep the Existing execute_buildah_command Function
|
|
|
|
The existing `execute_buildah_command` function already checks the thread-local debug flag, so we don't need to modify it:
|
|
|
|
```rust
|
|
pub fn execute_buildah_command(args: &[&str]) -> Result<CommandResult, BuildahError> {
|
|
// Get the debug flag from thread-local storage
|
|
let debug = thread_local_debug();
|
|
|
|
if debug {
|
|
println!("Executing buildah command: buildah {}", args.join(" "));
|
|
}
|
|
|
|
// ... rest of the function ...
|
|
}
|
|
```
|
|
|
|
### 4. Update the execute_buildah_command Function to Output stdout/stderr
|
|
|
|
We need to modify the `execute_buildah_command` function to output stdout/stderr when debug is true, regardless of success/failure:
|
|
|
|
```rust
|
|
pub fn execute_buildah_command(args: &[&str]) -> Result<CommandResult, BuildahError> {
|
|
// Get the debug flag from thread-local storage
|
|
let debug = thread_local_debug();
|
|
|
|
if debug {
|
|
println!("Executing buildah command: buildah {}", args.join(" "));
|
|
}
|
|
|
|
let output = Command::new("buildah")
|
|
.args(args)
|
|
.output();
|
|
|
|
match output {
|
|
Ok(output) => {
|
|
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
|
|
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
|
|
|
|
let result = CommandResult {
|
|
stdout,
|
|
stderr,
|
|
success: output.status.success(),
|
|
code: output.status.code().unwrap_or(-1),
|
|
};
|
|
|
|
// Always output stdout/stderr when debug is true
|
|
if debug {
|
|
if !result.stdout.is_empty() {
|
|
println!("Command stdout: {}", result.stdout);
|
|
}
|
|
|
|
if !result.stderr.is_empty() {
|
|
println!("Command stderr: {}", result.stderr);
|
|
}
|
|
|
|
if result.success {
|
|
println!("Command succeeded with code {}", result.code);
|
|
} else {
|
|
println!("Command failed with code {}", result.code);
|
|
}
|
|
}
|
|
|
|
if result.success {
|
|
Ok(result)
|
|
} else {
|
|
// If command failed and debug is false, output stderr
|
|
if !debug {
|
|
println!("Command failed with code {}: {}", result.code, result.stderr.trim());
|
|
}
|
|
Err(BuildahError::CommandFailed(format!("Command failed with code {}: {}",
|
|
result.code, result.stderr.trim())))
|
|
}
|
|
},
|
|
Err(e) => {
|
|
// Always output error information
|
|
println!("Command execution failed: {}", e);
|
|
Err(BuildahError::CommandExecutionFailed(e))
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 5. Handle Static Methods
|
|
|
|
For static methods, we'll just call `execute_buildah_command` directly, which will use the thread-local debug flag:
|
|
|
|
```rust
|
|
pub fn images() -> Result<Vec<Image>, BuildahError> {
|
|
let result = execute_buildah_command(&["images", "--json"])?;
|
|
// Rest of the method...
|
|
}
|
|
```
|
|
|
|
If we want to support debugging in static methods, we could add an optional debug parameter:
|
|
|
|
```rust
|
|
pub fn images(debug: bool) -> Result<Vec<Image>, BuildahError> {
|
|
// Save the current debug flag
|
|
let previous_debug = thread_local_debug();
|
|
|
|
// Set the thread-local debug flag
|
|
set_thread_local_debug(debug);
|
|
|
|
// Execute the command
|
|
let result = execute_buildah_command(&["images", "--json"]);
|
|
|
|
// Restore the previous debug flag
|
|
set_thread_local_debug(previous_debug);
|
|
|
|
// Process the result
|
|
match result {
|
|
Ok(cmd_result) => {
|
|
// Parse JSON and return images...
|
|
},
|
|
Err(e) => Err(e),
|
|
}
|
|
}
|
|
|
|
// Backward compatibility method
|
|
pub fn images() -> Result<Vec<Image>, BuildahError> {
|
|
Self::images(false)
|
|
}
|
|
```
|
|
|
|
### 6. Update Rhai Bindings
|
|
|
|
We still need to update the Rhai bindings to expose the debug functionality:
|
|
|
|
```rust
|
|
// Add a debug getter and setter
|
|
engine.register_get("debug", |builder: &mut Builder| builder.debug());
|
|
engine.register_set("debug", |builder: &mut Builder, debug: bool| { builder.set_debug(debug); });
|
|
```
|
|
|
|
### 7. Remove Unused Code
|
|
|
|
We can remove the unused `execute_buildah_command_with_debug` function.
|
|
|
|
## Implementation Flow
|
|
|
|
1. Modify the `execute_buildah_command` function to output stdout/stderr when debug is true
|
|
2. Update all Builder methods to set/restore the thread-local debug flag
|
|
3. Update static methods to optionally accept a debug parameter
|
|
4. Update Rhai bindings to expose the debug functionality
|
|
5. Remove unused code
|
|
|
|
## Benefits
|
|
|
|
1. Minimal changes to the existing codebase
|
|
2. No changes to function signatures
|
|
3. Backward compatibility with existing code
|
|
4. Improved debugging capabilities |