Improve packaging (#328)

* Add gpgui-helper (#326)

* Add packaging
This commit is contained in:
Kevin Yue
2024-02-26 10:33:39 -05:00
committed by GitHub
parent 5767c252b7
commit 47776d54d9
70 changed files with 5161 additions and 313 deletions

View File

@@ -1,15 +1,33 @@
use std::{borrow::Cow, ops::ControlFlow, sync::Arc};
use std::{
borrow::Cow,
fs::{File, Permissions},
io::BufReader,
ops::ControlFlow,
os::unix::fs::PermissionsExt,
path::PathBuf,
sync::Arc,
};
use anyhow::bail;
use axum::{
body::Bytes,
extract::{
ws::{self, CloseFrame, Message, WebSocket},
State, WebSocketUpgrade,
},
http::StatusCode,
response::IntoResponse,
};
use futures::{SinkExt, StreamExt};
use gpapi::service::event::WsEvent;
use gpapi::{
service::{event::WsEvent, request::UpdateGuiRequest},
utils::checksum::verify_checksum,
GP_GUI_BINARY,
};
use log::{info, warn};
use tar::Archive;
use tokio::fs;
use xz2::read::XzDecoder;
use crate::ws_server::WsServerContext;
@@ -25,6 +43,68 @@ pub(crate) async fn auth_data(State(ctx): State<Arc<WsServerContext>>, body: Str
ctx.send_event(WsEvent::AuthData(body)).await;
}
pub async fn update_gui(State(ctx): State<Arc<WsServerContext>>, body: Bytes) -> Result<(), StatusCode> {
let payload = match ctx.decrypt::<UpdateGuiRequest>(body.to_vec()) {
Ok(payload) => payload,
Err(err) => {
warn!("Failed to decrypt update payload: {}", err);
return Err(StatusCode::BAD_REQUEST);
}
};
info!("Update GUI: {:?}", payload);
let UpdateGuiRequest { path, checksum } = payload;
info!("Verifying checksum");
verify_checksum(&path, &checksum).map_err(|err| {
warn!("Failed to verify checksum: {}", err);
StatusCode::BAD_REQUEST
})?;
info!("Installing GUI");
install_gui(&path).await.map_err(|err| {
warn!("Failed to install GUI: {}", err);
StatusCode::INTERNAL_SERVER_ERROR
})?;
Ok(())
}
// Unpack GPGUI archive, gpgui_2.0.0_{arch}.bin.tar.xz and install it
async fn install_gui(src: &str) -> anyhow::Result<()> {
let path = PathBuf::from(GP_GUI_BINARY);
let Some(dir) = path.parent() else {
bail!("Failed to get parent directory of GUI binary");
};
fs::create_dir_all(dir).await?;
// Unpack the archive
info!("Unpacking GUI archive");
let tar = XzDecoder::new(BufReader::new(File::open(src)?));
let mut ar = Archive::new(tar);
for entry in ar.entries()? {
let mut entry = entry?;
let path = entry.path()?;
if let Some(name) = path.file_name() {
let name = name.to_string_lossy();
if name == "gpgui" {
let mut file = File::create(GP_GUI_BINARY)?;
std::io::copy(&mut entry, &mut file)?;
break;
}
}
}
// Make the binary executable
fs::set_permissions(GP_GUI_BINARY, Permissions::from_mode(0o755)).await?;
Ok(())
}
pub(crate) async fn ws_handler(ws: WebSocketUpgrade, State(ctx): State<Arc<WsServerContext>>) -> impl IntoResponse {
ws.on_upgrade(move |socket| handle_socket(socket, ctx))
}