feat: add update command to CLI, relay, and client
This commit is contained in:
parent
835d20f734
commit
6345209538
9 changed files with 302 additions and 0 deletions
|
|
@ -401,6 +401,91 @@ pub async fn clipboard_set(
|
|||
}
|
||||
}
|
||||
|
||||
/// POST /relay/update — self-update the relay binary and restart the service
|
||||
pub async fn relay_update() -> impl IntoResponse {
|
||||
tokio::spawn(async {
|
||||
// Give the HTTP response time to be sent before we restart
|
||||
tokio::time::sleep(Duration::from_millis(800)).await;
|
||||
|
||||
let url = "https://agent-helios.me/downloads/helios-remote/helios-remote-relay-linux";
|
||||
let bytes = match reqwest::get(url).await {
|
||||
Ok(r) => match r.bytes().await {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
error!("relay update: failed to read response body: {e}");
|
||||
return;
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!("relay update: download failed: {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let exe = match std::env::current_exe() {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
error!("relay update: current_exe: {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let tmp = exe.with_extension("new");
|
||||
if let Err(e) = std::fs::write(&tmp, &bytes) {
|
||||
error!("relay update: write tmp failed: {e}");
|
||||
return;
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let _ = std::fs::set_permissions(&tmp, std::fs::Permissions::from_mode(0o755));
|
||||
}
|
||||
|
||||
if let Err(e) = std::fs::rename(&tmp, &exe) {
|
||||
error!("relay update: rename failed: {e}");
|
||||
return;
|
||||
}
|
||||
|
||||
let _ = std::process::Command::new("systemctl")
|
||||
.args(["restart", "helios-remote"])
|
||||
.spawn();
|
||||
});
|
||||
|
||||
(
|
||||
axum::http::StatusCode::OK,
|
||||
Json(serde_json::json!({ "ok": true, "message": "update triggered, relay restarting..." })),
|
||||
)
|
||||
}
|
||||
|
||||
/// POST /devices/:label/update — trigger client self-update
|
||||
pub async fn client_update(
|
||||
Path(label): Path<String>,
|
||||
State(state): State<AppState>,
|
||||
) -> impl IntoResponse {
|
||||
match dispatch_with_timeout(&state, &label, "update", |rid| {
|
||||
ServerMessage::UpdateRequest { request_id: rid }
|
||||
}, Duration::from_secs(60)).await {
|
||||
Ok(ClientMessage::UpdateResponse { success, message, .. }) => (
|
||||
StatusCode::OK,
|
||||
Json(serde_json::json!({ "success": success, "message": message })),
|
||||
).into_response(),
|
||||
Ok(ClientMessage::Ack { .. }) => (
|
||||
StatusCode::OK,
|
||||
Json(serde_json::json!({ "success": true, "message": "update acknowledged" })),
|
||||
).into_response(),
|
||||
Ok(ClientMessage::Error { message, .. }) => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Json(serde_json::json!({ "success": false, "message": message })),
|
||||
).into_response(),
|
||||
Ok(_) => (
|
||||
StatusCode::OK,
|
||||
Json(serde_json::json!({ "success": true, "message": "acknowledged" })),
|
||||
).into_response(),
|
||||
Err(e) => e.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
/// POST /devices/:label/inform
|
||||
pub async fn inform_user(
|
||||
Path(label): Path<String>,
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ async fn main() -> anyhow::Result<()> {
|
|||
.route("/devices/:label/run", post(api::run_program))
|
||||
.route("/devices/:label/clipboard", get(api::clipboard_get))
|
||||
.route("/devices/:label/clipboard", post(api::clipboard_set))
|
||||
.route("/relay/update", post(api::relay_update))
|
||||
.route("/devices/:label/update", post(api::client_update))
|
||||
.layer(middleware::from_fn_with_state(state.clone(), require_api_key));
|
||||
|
||||
let app = Router::new()
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ async fn handle_client_message(label: &str, msg: ClientMessage, state: &AppState
|
|||
| ClientMessage::DownloadResponse { request_id, .. }
|
||||
| ClientMessage::ClipboardGetResponse { request_id, .. }
|
||||
| ClientMessage::PromptResponse { request_id, .. }
|
||||
| ClientMessage::UpdateResponse { request_id, .. }
|
||||
| ClientMessage::Ack { request_id }
|
||||
| ClientMessage::Error { request_id, .. } => {
|
||||
let rid = *request_id;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue