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

Commit 8227949

Browse files
committed
remove legacy protocol; only JSON-RPC support from now on
1 parent 6552000 commit 8227949

File tree

2 files changed

+264
-487
lines changed

2 files changed

+264
-487
lines changed

src/app/client.rs

Lines changed: 28 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -60,23 +60,10 @@ impl Client {
6060

6161
// Send a JSON-RPC request and return the result
6262
async fn jsonrpc_request(&self, method: &str, params: Option<Value>) -> Result<Value> {
63-
// First try JSON-RPC
64-
let result = self.try_jsonrpc(method, params.clone()).await;
65-
66-
// If JSON-RPC fails, try legacy protocol
67-
if let Err(e) = &result {
68-
if e.to_string().contains("Invalid JSON-RPC response")
69-
|| e.to_string().contains("Failed to parse")
70-
{
71-
debug!("JSON-RPC failed, trying legacy protocol: {}", e);
72-
return self.try_legacy_protocol(method, params).await;
73-
}
74-
}
75-
76-
result
63+
self.try_jsonrpc(method, params).await
7764
}
7865

79-
// Try using JSON-RPC protocol
66+
// Use JSON-RPC protocol
8067
async fn try_jsonrpc(&self, method: &str, params: Option<Value>) -> Result<Value> {
8168
// Get a unique ID for this request
8269
let id = self.next_id.fetch_add(1, Ordering::SeqCst);
@@ -130,216 +117,42 @@ impl Client {
130117
}
131118
}
132119

133-
// Try to use the legacy protocol as a fallback
134-
async fn try_legacy_protocol(&self, method: &str, params: Option<Value>) -> Result<Value> {
135-
// Convert JSON-RPC method and params to legacy command
136-
let cmd = match method {
137-
"service.list" => "list".to_string(),
138-
"system.shutdown" => "shutdown".to_string(),
139-
"system.reboot" => "reboot".to_string(),
140-
"service.status" => {
141-
if let Some(params) = params {
142-
if let Some(name) = params.get("name").and_then(|v| v.as_str()) {
143-
format!("status {}", name)
144-
} else {
145-
bail!("Missing or invalid 'name' parameter");
146-
}
147-
} else {
148-
bail!("Missing parameters");
149-
}
150-
}
151-
"service.start" => {
152-
if let Some(params) = params {
153-
if let Some(name) = params.get("name").and_then(|v| v.as_str()) {
154-
format!("start {}", name)
155-
} else {
156-
bail!("Missing or invalid 'name' parameter");
157-
}
158-
} else {
159-
bail!("Missing parameters");
160-
}
161-
}
162-
"service.stop" => {
163-
if let Some(params) = params {
164-
if let Some(name) = params.get("name").and_then(|v| v.as_str()) {
165-
format!("stop {}", name)
166-
} else {
167-
bail!("Missing or invalid 'name' parameter");
168-
}
169-
} else {
170-
bail!("Missing parameters");
171-
}
172-
}
173-
"service.forget" => {
174-
if let Some(params) = params {
175-
if let Some(name) = params.get("name").and_then(|v| v.as_str()) {
176-
format!("forget {}", name)
177-
} else {
178-
bail!("Missing or invalid 'name' parameter");
179-
}
180-
} else {
181-
bail!("Missing parameters");
182-
}
183-
}
184-
"service.monitor" => {
185-
if let Some(params) = params {
186-
if let Some(name) = params.get("name").and_then(|v| v.as_str()) {
187-
format!("monitor {}", name)
188-
} else {
189-
bail!("Missing or invalid 'name' parameter");
190-
}
191-
} else {
192-
bail!("Missing parameters");
193-
}
194-
}
195-
"service.kill" => {
196-
if let Some(params) = params {
197-
if let Some(name) = params.get("name").and_then(|v| v.as_str()) {
198-
if let Some(signal) = params.get("signal").and_then(|v| v.as_str()) {
199-
format!("kill {} {}", name, signal)
200-
} else {
201-
bail!("Missing or invalid 'signal' parameter");
202-
}
203-
} else {
204-
bail!("Missing or invalid 'name' parameter");
205-
}
206-
} else {
207-
bail!("Missing parameters");
208-
}
209-
}
210-
"service.create" => {
211-
// The legacy protocol doesn't directly support service creation
212-
bail!("Service creation not supported in legacy protocol");
213-
}
214-
"service.delete" => {
215-
// The legacy protocol doesn't directly support service deletion
216-
bail!("Service deletion not supported in legacy protocol");
217-
}
218-
"service.get" => {
219-
// The legacy protocol doesn't directly support getting service config
220-
bail!("Getting service configuration not supported in legacy protocol");
221-
}
222-
"rpc.discover" => {
223-
// This is a JSON-RPC specific method with no legacy equivalent
224-
bail!("RPC discovery not supported in legacy protocol");
225-
}
226-
"service.restart" => {
227-
if let Some(params) = params {
228-
if let Some(name) = params.get("name").and_then(|v| v.as_str()) {
229-
format!("restart {}", name)
230-
} else {
231-
bail!("Missing or invalid 'name' parameter");
232-
}
233-
} else {
234-
bail!("Missing parameters");
235-
}
236-
}
237-
"log" => {
238-
if let Some(params) = params {
239-
if let Some(filter) = params.get("filter").and_then(|v| v.as_str()) {
240-
if let Some(snapshot) = params.get("snapshot").and_then(|v| v.as_bool()) {
241-
if snapshot {
242-
format!("log snapshot {}", filter)
243-
} else {
244-
format!("log {}", filter)
245-
}
246-
} else {
247-
format!("log {}", filter)
248-
}
249-
} else {
250-
"log".to_string()
251-
}
252-
} else {
253-
"log".to_string()
254-
}
255-
}
256-
_ => bail!("Unsupported method for legacy protocol: {}", method),
257-
};
258-
259-
// Use the command method to send the legacy command
260-
self.command(&cmd).await
261-
}
262-
263-
// Command method for the legacy protocol
264-
async fn command(&self, c: &str) -> Result<Value> {
265-
let mut con = BufStream::new(self.connect().await?);
266-
267-
let _ = con.write(c.as_bytes()).await?;
268-
let _ = con.write(b"\n").await?;
269-
con.flush().await?;
270-
271-
let mut buffer = Vec::new();
272-
let mut temp_buf = [0u8; 1024];
273-
274-
loop {
275-
let n = con.read(&mut temp_buf).await?;
276-
if n == 0 {
277-
break; // Connection closed
278-
}
279-
280-
buffer.extend_from_slice(&temp_buf[..n]);
281-
282-
// Check if the buffer ends with a newline
283-
if buffer.ends_with(b"\n") {
284-
break;
285-
}
286-
}
287-
288-
// Convert to string and trim the trailing newline
289-
let data = String::from_utf8(buffer)?;
290-
let data = data.trim_end();
291-
let response: ZinitResponse = encoder::from_str(data)?;
292-
293-
match response.state {
294-
ZinitState::Ok => Ok(response.body),
295-
ZinitState::Error => {
296-
let err: String = encoder::from_value(response.body)?;
297-
bail!(err)
298-
}
299-
}
300-
}
120+
// JSON-RPC is now the only supported protocol
121+
// Legacy command method has been removed
301122

302123
pub async fn logs<O: tokio::io::AsyncWrite + Unpin, S: AsRef<str>>(
303124
&self,
304125
mut out: O,
305126
filter: Option<S>,
306127
follow: bool,
307128
) -> Result<()> {
308-
// For now, keep using the original log command since it's a special case
309-
let mut con = self.connect().await?;
310-
if follow {
311-
// default behavior of log with no extra arguments
312-
// is to stream all logs
313-
con.write_all(b"log\n").await?;
129+
// Convert to JSON-RPC params
130+
let params = if let Some(ref filter) = filter {
131+
serde_json::json!({
132+
"filter": filter.as_ref(),
133+
"snapshot": !follow
134+
})
314135
} else {
315-
// adding a snapshot subcmd will make it auto terminate
316-
// immediate after
317-
con.write_all(b"log snapshot\n").await?;
318-
}
319-
con.flush().await?;
320-
match filter {
321-
None => tokio::io::copy(&mut con, &mut out).await?,
322-
Some(filter) => {
323-
let filter = format!("{}:", filter.as_ref());
324-
let mut stream = BufStream::new(con);
325-
loop {
326-
let mut line = String::new();
327-
match stream.read_line(&mut line).await {
328-
Ok(0) => break,
329-
Ok(_) => {}
330-
Err(err) => {
331-
bail!("failed to read stream: {}", err);
332-
}
333-
}
334-
335-
if line[4..].starts_with(&filter) {
336-
let _ = out.write_all(line.as_bytes()).await;
337-
}
338-
}
339-
0
340-
}
136+
serde_json::json!({
137+
"snapshot": !follow
138+
})
341139
};
342140

141+
// Make a JSON-RPC request to the log method
142+
let response = self.jsonrpc_request("log", Some(params)).await?;
143+
144+
// Write the log data to the output
145+
if let Some(logs) = response.as_array() {
146+
for log in logs {
147+
if let Some(log_str) = log.as_str() {
148+
out.write_all(log_str.as_bytes()).await?;
149+
out.write_all(b"\n").await?;
150+
}
151+
}
152+
} else if let Some(log_str) = response.as_str() {
153+
out.write_all(log_str.as_bytes()).await?;
154+
}
155+
343156
Ok(())
344157
}
345158

0 commit comments

Comments
 (0)