Skip to content
This repository was archived by the owner on Dec 15, 2025. It is now read-only.

Commit b07c40e

Browse files
committed
fixed path handling issue; looking for services only happens in passed configuration directory
1 parent 8227949 commit b07c40e

File tree

3 files changed

+40
-24
lines changed

3 files changed

+40
-24
lines changed

src/app/client.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,25 @@ impl Client {
104104
let data = String::from_utf8(buffer)?;
105105
let data = data.trim_end();
106106

107-
// Parse the JSON-RPC response
108-
let response: JsonRpcResponse = encoder::from_str(data)?;
107+
// Parse the JSON-RPC response - improved error handling
108+
let response: JsonRpcResponse = match encoder::from_str(&data) {
109+
Ok(response) => response,
110+
Err(e) => {
111+
// If we can't parse the response as JSON-RPC, this is an error
112+
error!("Failed to parse JSON-RPC response: {}", e);
113+
error!("Raw response: {}", data);
114+
bail!("Invalid response from server: failed to parse JSON-RPC")
115+
}
116+
};
109117

110-
// Handle the response
118+
// Handle the response according to JSON-RPC 2.0 spec
111119
if let Some(error) = response.error {
120+
// Error response - has 'error' field
112121
bail!("RPC error ({}): {}", error.code, error.message);
113-
} else if let Some(result) = response.result {
114-
Ok(result)
115122
} else {
116-
bail!("Invalid JSON-RPC response: missing both result and error");
123+
// Success response - return result (which might be null)
124+
// This properly handles all success responses including null values
125+
Ok(response.result.unwrap_or(Value::Null))
117126
}
118127
}
119128

src/app/server.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,28 @@ pub struct Status {
8787
pub struct Api {
8888
zinit: ZInit,
8989
socket: PathBuf,
90-
// http_port removed as it's now in a separate binary
90+
config_dir: PathBuf, // Configuration directory path
9191
}
9292

9393
impl Api {
9494
pub fn new<P: AsRef<Path>>(zinit: ZInit, socket: P, _http_port: Option<u16>) -> Api {
9595
// _http_port parameter kept for backward compatibility but not used
96+
// Default to /etc/zinit if not specified
97+
let config_dir = PathBuf::from("/etc/zinit");
98+
9699
Api {
97100
zinit,
98101
socket: socket.as_ref().to_path_buf(),
102+
config_dir,
99103
}
100104
}
101105

106+
// Add a way to explicitly set the config directory
107+
pub fn with_config_dir<P: AsRef<Path>>(mut self, config_dir: P) -> Self {
108+
self.config_dir = config_dir.as_ref().to_path_buf();
109+
self
110+
}
111+
102112
// HTTP proxy functionality has been moved to a separate binary (zinit-http)
103113

104114
pub async fn serve(&self) -> Result<()> {
@@ -625,8 +635,11 @@ impl Api {
625635
}
626636

627637
async fn monitor<S: AsRef<str>>(name: S, zinit: ZInit) -> Result<Value> {
638+
// Use the existing working directory which should be set to the config dir
639+
// when Zinit is started with the -c flag (default /etc/zinit)
628640
let (name, service) = config::load(format!("{}.yaml", name.as_ref()))
629641
.context("failed to load service config")?;
642+
630643
zinit.monitor(name, service).await?;
631644
Ok(Value::Null)
632645
}
@@ -712,11 +725,11 @@ impl Api {
712725
bail!("Invalid service name: must not contain '/', '\\', or '.'");
713726
}
714727

715-
// Construct the file path
716-
let file_path = PathBuf::from(format!("{}.yaml", name));
728+
// Use the daemon's working directory which should be the config dir
729+
let file_path = format!("{}.yaml", name);
717730

718731
// Check if the service file already exists
719-
if file_path.exists() {
732+
if Path::new(&file_path).exists() {
720733
bail!("Service '{}' already exists", name);
721734
}
722735

@@ -745,11 +758,11 @@ impl Api {
745758
bail!("Invalid service name: must not contain '/', '\\', or '.'");
746759
}
747760

748-
// Construct the file path
749-
let file_path = PathBuf::from(format!("{}.yaml", name));
761+
// Use the daemon's working directory which should be the config dir
762+
let file_path = format!("{}.yaml", name);
750763

751764
// Check if the service file exists
752-
if !file_path.exists() {
765+
if !Path::new(&file_path).exists() {
753766
bail!("Service '{}' not found", name);
754767
}
755768

@@ -772,11 +785,11 @@ impl Api {
772785
bail!("Invalid service name: must not contain '/', '\\', or '.'");
773786
}
774787

775-
// Construct the file path
776-
let file_path = PathBuf::from(format!("{}.yaml", name));
788+
// Use the daemon's working directory which should be the config dir
789+
let file_path = format!("{}.yaml", name);
777790

778791
// Check if the service file exists
779-
if !file_path.exists() {
792+
if !Path::new(&file_path).exists() {
780793
bail!("Service '{}' not found", name);
781794
}
782795

src/bin/zinit-http.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,8 @@ async fn run_http_server(socket: &str, port: u16) -> Result<()> {
265265
.and_then(|p| p.get("name"))
266266
.and_then(|v| v.as_str())
267267
{
268-
// For monitoring, we need to check if the service file exists first
269-
let file_path = format!("{}.yaml", name);
270-
if !std::path::Path::new(&file_path).exists() {
271-
return Err((
272-
StatusCode::BAD_REQUEST,
273-
format!("Service file '{}' not found", file_path),
274-
));
275-
}
268+
// We don't need to manually check for file existence here as the zinit daemon will handle it
269+
// The actual path resolution is handled properly by the daemon in the monitor method
276270

277271
// Now we can call monitor
278272
client.monitor(name).await.map_err(|e| {

0 commit comments

Comments
 (0)