installer sockets

This commit is contained in:
Ward from fusion-voyager-3 2024-07-10 12:50:48 +03:00
parent b6bdb4ca96
commit 3d509b0afc
7 changed files with 326 additions and 112 deletions

View File

@ -8,22 +8,13 @@
</component>
<component name="ChangeListManager">
<list default="true" id="df2ca9e1-e07d-43f4-bc68-0a6113fc1fa2" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/src/bin/apt/apt_full_upgrade/main.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/bin/apt/apt_update/main.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/lib/apt_update_progress_socket/mod.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/lib/lib.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/lib/apt_install_progress_socket/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/apt_package_row/imp.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/apt_package_row/imp.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/apt_package_row/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/apt_package_row/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/apt_update/main.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/apt_update_page/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/apt_update_page/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/apt_update_page/process.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/apt_update_page/process.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/build_ui/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/build_ui/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/config.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/config.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/main.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pika_unixsocket_tools/lib.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib/pika_unixsocket_tools/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/style.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/style.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/bin/apt/apt_full_upgrade/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/apt/apt_full_upgrade/main.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/bin/gui/apt_update_page/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/apt_update_page/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/bin/gui/apt_update_page/process.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/apt_update_page/process.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/lib/lib.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib/lib.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/lib/pika_unixsocket_tools/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib/pika_unixsocket_tools/mod.rs" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -61,7 +52,7 @@
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.rust.reset.selective.auto.import": "true",
"git-widget-placeholder": "master",
"last_opened_file_path": "/home/ward/RustroverProjects/pika-idk-manager/src",
"last_opened_file_path": "/home/ward/RustroverProjects/pika-idk-manager/src/lib",
"node.js.detected.package.eslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
@ -73,6 +64,7 @@
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/src/lib" />
<recent name="$PROJECT_DIR$/src" />
</key>
<key name="MoveFile.RECENT_KEYS">
@ -146,7 +138,7 @@
<workItem from="1720502207843" duration="3142000" />
<workItem from="1720556059466" duration="12649000" />
<workItem from="1720594302708" duration="52000" />
<workItem from="1720597532937" duration="2752000" />
<workItem from="1720597532937" duration="6243000" />
</task>
<servers />
</component>

View File

@ -1 +1,66 @@
fn main() {}
use rust_apt::new_cache;
use rust_apt::progress::{AcquireProgress, InstallProgress};
use tokio::runtime::Runtime;
use pika_unixsocket_tools::apt_update_progress_socket::AptUpdateProgressSocket;
use pika_unixsocket_tools::apt_install_progress_socket::AptInstallProgressSocket;
use pika_unixsocket_tools::pika_unixsocket_tools::*;
fn main() {
let cache = new_cache!().unwrap();
let percent_socket_path = "/tmp/pika_apt_upgrade_percent.sock";
let status_socket_path = "/tmp/pika_apt_upgrade_status.sock";
let pkg = cache.get("neovim").unwrap();
let mut acquire_progress = AcquireProgress::new(AptUpdateProgressSocket::new(
percent_socket_path,
status_socket_path,
));
let mut install_progress = InstallProgress::new(AptInstallProgressSocket::new(
percent_socket_path,
status_socket_path,
));
pkg.mark_install(true, true);
pkg.protect();
cache.resolve(true).unwrap();
match cache.get_archives(&mut acquire_progress) {
Ok(_) => {
Runtime::new()
.unwrap()
.block_on(send_successful_to_socket(percent_socket_path));
Runtime::new()
.unwrap()
.block_on(send_successful_to_socket(status_socket_path));
}
Err(e) => {
Runtime::new()
.unwrap()
.block_on(send_failed_to_socket(percent_socket_path));
Runtime::new()
.unwrap()
.block_on(send_failed_to_socket(status_socket_path));
panic!("{}", e.to_string())
}
};
match cache.do_install(&mut install_progress) {
Ok(_) => {
Runtime::new()
.unwrap()
.block_on(send_successful_to_socket(percent_socket_path));
Runtime::new()
.unwrap()
.block_on(send_successful_to_socket(status_socket_path));
}
Err(e) => {
Runtime::new()
.unwrap()
.block_on(send_failed_to_socket(percent_socket_path));
Runtime::new()
.unwrap()
.block_on(send_failed_to_socket(status_socket_path));
panic!("{}", e.to_string())
}
};
}

View File

@ -53,13 +53,13 @@ pub fn apt_update_page(
thread::spawn(move || {
Runtime::new()
.unwrap()
.block_on(update_percent_socket_server(update_percent_sender));
.block_on(start_socket_server(update_percent_sender, "/tmp/pika_apt_update_percent.sock"));
});
thread::spawn(move || {
Runtime::new()
.unwrap()
.block_on(update_status_socket_server(update_status_sender));
.block_on(start_socket_server(update_status_sender, "/tmp/pika_apt_update_status.sock"));
});
thread::spawn(move || {
@ -387,92 +387,3 @@ fn set_all_apt_row_marks_to(parent_listbox: &impl IsA<ListBox>, value: bool) {
child_counter = next_child
}
}
async fn update_percent_socket_server(buffer_sender: async_channel::Sender<String>) {
// Path to the Unix socket file
let socket_path = "/tmp/pika_apt_update_percent.sock";
// Remove the socket file if it already exists
if Path::new(socket_path).exists() {
fs::remove_file(socket_path).expect("Could not remove existing socket file");
}
// Bind the Unix listener to the socket path
let listener = UnixListener::bind(socket_path).expect("Could not bind");
println!("Server listening on {}", socket_path);
// Loop to accept incoming connections
loop {
// Accept an incoming connection
match listener.accept().await {
Ok((stream, _)) => {
// Handle the connection in a separate task
task::spawn(handle_client(stream, buffer_sender.clone()));
}
Err(e) => {
// Print error message if a connection fails
eprintln!("Connection failed: {}", e);
}
}
}
}
async fn update_status_socket_server(buffer_sender: async_channel::Sender<String>) {
// Path to the Unix socket file
let socket_path = "/tmp/pika_apt_update_status.sock";
// Remove the socket file if it already exists
if Path::new(socket_path).exists() {
fs::remove_file(socket_path).expect("Could not remove existing socket file");
}
// Bind the Unix listener to the socket path
let listener = UnixListener::bind(socket_path).expect("Could not bind");
println!("Server listening on {}", socket_path);
// Loop to accept incoming connections
loop {
// Accept an incoming connection
match listener.accept().await {
Ok((stream, _)) => {
// Handle the connection in a separate task
task::spawn(handle_client(stream, buffer_sender.clone()));
}
Err(e) => {
// Print error message if a connection fails
eprintln!("Connection failed: {}", e);
}
}
}
}
async fn get_upgradable_socket_server(buffer_sender: async_channel::Sender<String>) {
// Path to the Unix socket file
let socket_path = "/tmp/pika_apt_get_upgradable.sock";
// Remove the socket file if it already exists
if Path::new(socket_path).exists() {
fs::remove_file(socket_path).expect("Could not remove existing socket file");
}
// Bind the Unix listener to the socket path
let listener = UnixListener::bind(socket_path).expect("Could not bind");
println!("Server listening on {}", socket_path);
// Loop to accept incoming connections
loop {
// Accept an incoming connection
match listener.accept().await {
Ok((stream, _)) => {
// Handle the connection in a separate task
task::spawn(handle_client(stream, buffer_sender.clone()));
}
Err(e) => {
// Print error message if a connection fails
eprintln!("Connection failed: {}", e);
}
}
}
}

View File

@ -5,8 +5,11 @@ use gtk::glib::*;
use gtk::*;
use pretty_bytes::converter::convert;
use serde_json::{Value};
use std::{fs::*};
use std::{fs::*, thread};
use std::path::Path;
use std::process::Command;
use tokio::runtime::Runtime;
use pika_unixsocket_tools::pika_unixsocket_tools::start_socket_server;
struct AptChangesInfo {
package_count: u64,
@ -174,7 +177,115 @@ fn apt_confirm_window(excluded_updates_vec: &Vec<String>, window: adw::Applicati
std::fs::write(json_file_path, serde_json::to_string_pretty(&excluded_updates_values_json).unwrap()).expect("Failed to write to json file");
}
apt_confirm_dialog.present();
//apt_confirm_dialog.present();
apt_full_upgrade_from_socket(window);
}
fn apt_full_upgrade_from_socket(window: adw::ApplicationWindow) {
let (upgrade_percent_sender, upgrade_percent_receiver) = async_channel::unbounded::<String>();
let upgrade_percent_sender = upgrade_percent_sender.clone();
let (upgrade_status_sender, upgrade_status_receiver) = async_channel::unbounded::<String>();
let upgrade_status_sender = upgrade_status_sender.clone();
let upgrade_status_sender_clone0 = upgrade_status_sender.clone();
thread::spawn(move || {
Runtime::new()
.unwrap()
.block_on(start_socket_server(upgrade_percent_sender, "/tmp/pika_apt_upgrade_percent.sock"));
});
thread::spawn(move || {
Runtime::new()
.unwrap()
.block_on(start_socket_server(upgrade_status_sender, "/tmp/pika_apt_upgrade_status.sock"));
});
thread::spawn(move || {
let apt_upgrade_command = Command::new("pkexec")
.args(["/home/ward/RustroverProjects/pika-idk-manager/target/debug/apt_full_upgrade"])
.status()
.unwrap();
match apt_upgrade_command.code().unwrap() {
0 => {
upgrade_status_sender_clone0
.send_blocking("FN_OVERRIDE_SUCCESSFUL".to_owned())
.unwrap()
}
53 => {}
_ => {
upgrade_status_sender_clone0
.send_blocking(t!("upgrade_status_error_perms").to_string())
.unwrap();
upgrade_status_sender_clone0
.send_blocking("FN_OVERRIDE_FAILED".to_owned())
.unwrap()
}
}
});
let apt_upgrade_dialog_child_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
let apt_upgrade_dialog_progress_bar = gtk::ProgressBar::builder()
.show_text(true)
.hexpand(true)
.build();
let apt_upgrade_dialog_spinner = gtk::Spinner::builder()
.hexpand(true)
.valign(Align::Start)
.halign(Align::Center)
.spinning(true)
.height_request(128)
.width_request(128)
.build();
apt_upgrade_dialog_child_box.append(&apt_upgrade_dialog_spinner);
apt_upgrade_dialog_child_box.append(&apt_upgrade_dialog_progress_bar);
let apt_upgrade_dialog = adw::MessageDialog::builder()
.transient_for(&window)
.extra_child(&apt_upgrade_dialog_child_box)
.heading(t!("apt_upgrade_dialog_heading"))
.hide_on_close(true)
.width_request(500)
.build();
let upgrade_percent_server_context = MainContext::default();
// The main loop executes the asynchronous block
upgrade_percent_server_context.spawn_local(clone!(@weak apt_upgrade_dialog_progress_bar, @weak apt_upgrade_dialog => async move {
while let Ok(state) = upgrade_percent_receiver.recv().await {
match state.as_ref() {
"FN_OVERRIDE_SUCCESSFUL" => {}
_ => {
apt_upgrade_dialog_progress_bar.set_fraction(state.parse::<f64>().unwrap()/100.0)
}
}
}
}));
let upgrade_status_server_context = MainContext::default();
// The main loop executes the asynchronous block
upgrade_status_server_context.spawn_local(
clone!(@weak apt_upgrade_dialog, @weak apt_upgrade_dialog_child_box => async move {
while let Ok(state) = upgrade_status_receiver.recv().await {
match state.as_ref() {
"FN_OVERRIDE_SUCCESSFUL" => {
apt_upgrade_dialog.close();
}
"FN_OVERRIDE_FAILED" => {
apt_upgrade_dialog_child_box.set_visible(false);
apt_upgrade_dialog.set_title(Some(&t!("apt_upgrade_dialog_status_failed").to_string()));
apt_upgrade_dialog.set_response_enabled("apt_upgrade_dialog_ok", true);
}
_ => apt_upgrade_dialog.set_body(&state)
}
}
}),
);
apt_upgrade_dialog.present();
}
fn create_color_badge(

View File

@ -0,0 +1,104 @@
use crate::pika_unixsocket_tools::*;
use rust_apt::progress::{DynAcquireProgress, DynInstallProgress};
use rust_apt::raw::{AcqTextStatus, ItemDesc, PkgAcquire};
use std::process::exit;
use tokio::io::{AsyncWriteExt};
use tokio::net::UnixStream;
use tokio::runtime::Runtime;
pub struct AptInstallProgressSocket<'a> {
pkgname: String,
steps_done: u64,
total_steps: u64,
action: String,
percent_socket_path: &'a str,
status_socket_path: &'a str,
}
impl<'a> AptInstallProgressSocket<'a> {
/// Returns a new default progress instance.
pub fn new(percent_socket_path: &'a str, status_socket_path: &'a str) -> Self {
let mut progress = Self {
pkgname: String::new(),
steps_done: 0,
total_steps: 0,
action: String::new(),
percent_socket_path: percent_socket_path,
status_socket_path: status_socket_path,
};
progress
}
}
impl<'a> DynInstallProgress for AptInstallProgressSocket<'a> {
fn status_changed(
&mut self,
pkgname: String,
steps_done: u64,
total_steps: u64,
action: String
) {
let progress_percent: f32 =
(steps_done as f32 * 100.0) / total_steps as f32;
Runtime::new().unwrap().block_on(send_progress_percent(
progress_percent,
self.percent_socket_path,
));
Runtime::new().unwrap().block_on(send_progress_status(
&action,
self.status_socket_path,
));
}
fn error(
&mut self,
pkgname: String,
steps_done: u64,
total_steps: u64,
error: String
) {
let message = format!(
"dpkg failure on {}: {}",
pkgname,
error
);
eprintln!("{}", &message);
Runtime::new()
.unwrap()
.block_on(send_progress_status(&message, self.status_socket_path));
Runtime::new()
.unwrap()
.block_on(send_failed_to_socket(self.percent_socket_path));
Runtime::new()
.unwrap()
.block_on(send_failed_to_socket(self.status_socket_path));
exit(53)
}
}
async fn send_progress_percent(progress_f32: f32, socket_path: &str) {
// Connect to the Unix socket
let mut stream = UnixStream::connect(socket_path)
.await
.expect("Could not connect to server");
let message = progress_f32.to_string();
// Send the message to the server
stream
.write_all(message.as_bytes())
.await
.expect("Failed to write to stream");
}
async fn send_progress_status(message: &str, socket_path: &str) {
// Connect to the Unix socket
let mut stream = UnixStream::connect(socket_path)
.await
.expect("Could not connect to server");
// Send the message to the server
stream
.write_all(message.as_bytes())
.await
.expect("Failed to write to stream");
}

View File

@ -1,2 +1,3 @@
pub mod pika_unixsocket_tools;
pub mod apt_install_progress_socket;
pub mod apt_update_progress_socket;

View File

@ -1,5 +1,8 @@
use std::fs;
use std::path::Path;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::UnixStream;
use tokio::net::{UnixListener, UnixStream};
use tokio::task;
pub async fn send_successful_to_socket(socket_path: &str) {
// Connect to the Unix socket
@ -50,3 +53,30 @@ pub async fn handle_client(mut stream: UnixStream, buffer_sender: async_channel:
}
}
}
pub async fn start_socket_server(buffer_sender: async_channel::Sender<String>, socket_path: &str) {
// Remove the socket file if it already exists
if Path::new(socket_path).exists() {
fs::remove_file(socket_path).expect("Could not remove existing socket file");
}
// Bind the Unix listener to the socket path
let listener = UnixListener::bind(socket_path).expect("Could not bind");
println!("Server listening on {}", socket_path);
// Loop to accept incoming connections
loop {
// Accept an incoming connection
match listener.accept().await {
Ok((stream, _)) => {
// Handle the connection in a separate task
task::spawn(handle_client(stream, buffer_sender.clone()));
}
Err(e) => {
// Print error message if a connection fails
eprintln!("Connection failed: {}", e);
}
}
}
}