Skip to content

Commit

Permalink
feat(flatimage): integrate flatimage using remote files
Browse files Browse the repository at this point in the history
  • Loading branch information
QaidVoid committed Oct 30, 2024
1 parent 4b7fd4f commit e94d480
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 36 deletions.
4 changes: 2 additions & 2 deletions src/core/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ pub static INSTALL_TRACK_PATH: LazyLock<PathBuf> =
pub static PACKAGES_PATH: LazyLock<PathBuf> =
LazyLock::new(|| build_path(&CONFIG.soar_path).unwrap().join("packages"));

pub const APPIMAGE_MAGIC_OFFSET: u64 = 8;
pub const APPIMAGE_MAGIC_BYTES: [u8; 4] = [0x41, 0x49, 0x02, 0x00];
pub const ELF_MAGIC_BYTES: [u8; 4] = [0x7f, 0x45, 0x4c, 0x46];
pub const APPIMAGE_MAGIC_BYTES: [u8; 4] = [0x41, 0x49, 0x02, 0x00];
pub const FLATIMAGE_MAGIC_BYTES: [u8; 4] = [0x46, 0x49, 0x02, 0x00];

pub const CAP_SYS_ADMIN: i32 = 21;
pub const CAP_MKNOD: i32 = 27;
29 changes: 29 additions & 0 deletions src/core/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::{
fs::File,
io::{BufReader, Read},
};

use super::constant::{APPIMAGE_MAGIC_BYTES, ELF_MAGIC_BYTES, FLATIMAGE_MAGIC_BYTES};

pub enum FileType {
AppImage,
FlatImage,
ELF,
Unknown,
}

pub fn get_file_type(file: &mut BufReader<File>) -> FileType {
let mut magic_bytes = [0u8; 12];
if file.read_exact(&mut magic_bytes).is_ok() {
if magic_bytes[8..] == APPIMAGE_MAGIC_BYTES {
return FileType::AppImage;
} else if magic_bytes[8..] == FLATIMAGE_MAGIC_BYTES {
return FileType::FlatImage;
} else if magic_bytes[..4] == ELF_MAGIC_BYTES {
return FileType::ELF;
} else {
return FileType::Unknown;
}
}
FileType::Unknown
}
1 change: 1 addition & 0 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod color;
pub mod config;
pub mod constant;
pub mod file;
pub mod health;
pub mod log;
pub mod util;
31 changes: 9 additions & 22 deletions src/registry/package/appimage.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{
collections::HashSet,
fs::File,
io::{BufReader, BufWriter, Read, Seek, SeekFrom, Write},
io::{BufReader, BufWriter, Read, Seek, Write},
path::{Path, PathBuf},
};

Expand All @@ -13,7 +13,7 @@ use tokio::{fs, try_join};
use crate::{
core::{
color::{Color, ColorExt},
constant::{APPIMAGE_MAGIC_BYTES, APPIMAGE_MAGIC_OFFSET, BIN_PATH, PACKAGES_PATH},
constant::{BIN_PATH, PACKAGES_PATH},
util::{download, home_data_path},
},
error, info,
Expand Down Expand Up @@ -78,16 +78,6 @@ fn normalize_image(image: DynamicImage) -> DynamicImage {
}
}

fn is_appimage(file: &mut BufReader<File>) -> bool {
if file.seek(SeekFrom::Start(APPIMAGE_MAGIC_OFFSET)).is_ok() {
let mut magic_bytes = [0_u8; 4];
if file.read_exact(&mut magic_bytes).is_ok() {
return APPIMAGE_MAGIC_BYTES == magic_bytes;
}
}
false
}

async fn create_symlink(from: &Path, to: &Path) -> Result<()> {
if to.is_symlink() {
if to.exists() && !to.read_link()?.starts_with(&*PACKAGES_PATH) {
Expand Down Expand Up @@ -146,14 +136,12 @@ pub async fn remove_applinks(name: &str, bin_name: &str, file_path: &Path) -> Re
Ok(())
}

pub async fn integrate_appimage(package: &Package, file_path: &Path) -> Result<bool> {
let mut file = BufReader::new(File::open(file_path)?);

if !is_appimage(&mut file) {
return Ok(false);
}

let offset = find_offset(&mut file).await?;
pub async fn integrate_appimage(
file: &mut BufReader<File>,
package: &Package,
file_path: &Path,
) -> Result<bool> {
let offset = find_offset(file).await?;
let squashfs = FilesystemReader::from_reader_with_offset(file, offset)?;

let home_data = home_data_path();
Expand Down Expand Up @@ -301,8 +289,7 @@ async fn process_desktop(
Ok(())
}

// TODO: use this if the package don't contain the required files
pub async fn _use_remote_files(package: &Package, file_path: &Path) -> Result<()> {
pub async fn integrate_using_remote_files(package: &Package, file_path: &Path) -> Result<()> {
let home_data = home_data_path();
let data_path = Path::new(&home_data);

Expand Down
51 changes: 39 additions & 12 deletions src/registry/package/install.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
use std::{fs::Permissions, io::Write, os::unix::fs::PermissionsExt, path::PathBuf, sync::Arc};
use std::{
fs::{File, Permissions},
io::{BufReader, Write},
os::unix::fs::PermissionsExt,
path::PathBuf,
sync::Arc,
};

use anyhow::{Context, Result};
use futures::StreamExt;
Expand All @@ -9,6 +15,7 @@ use crate::{
core::{
color::{Color, ColorExt},
constant::{BIN_PATH, PACKAGES_PATH},
file::{get_file_type, FileType},
util::{calculate_checksum, format_bytes, validate_checksum},
},
registry::{
Expand All @@ -18,7 +25,7 @@ use crate::{
warn,
};

use super::ResolvedPackage;
use super::{appimage::integrate_using_remote_files, ResolvedPackage};

pub struct Installer {
resolved_package: ResolvedPackage,
Expand Down Expand Up @@ -202,16 +209,36 @@ impl Installer {
self.save_file().await?;
self.symlink_bin(&installed_packages).await?;

let ai_integrated = integrate_appimage(package, &self.install_path).await?;
if ai_integrated {
setup_portable_dir(
&package.bin_name,
&self.install_path,
portable,
portable_home,
portable_config,
)
.await?;
let mut file = BufReader::new(File::open(&self.install_path)?);
let file_type = get_file_type(&mut file);

match file_type {
FileType::AppImage => {
if integrate_appimage(&mut file, package, &self.install_path)
.await
.is_ok()
{
setup_portable_dir(
&package.bin_name,
&self.install_path,
portable,
portable_home,
portable_config,
)
.await?;
} else {
warn!("{}: Failed to integrate AppImage", prefix);
};
}
FileType::FlatImage => {
if integrate_using_remote_files(package, &self.install_path)
.await
.is_err()
{
warn!("{}: Failed to integrate FlatImage", prefix);
};
}
_ => {}
}

{
Expand Down

0 comments on commit e94d480

Please sign in to comment.