Files
churn-universe/dev-packages/src/lib.rs
2025-01-10 21:40:25 +01:00

150 lines
4.4 KiB
Rust

use std::{
fs::{self},
io::{Cursor, Write},
path::PathBuf,
};
use anyhow::Context;
use bindings::{
component::churn_tasks::{http, process::Process},
exports::component::churn_tasks::task::Guest,
};
use flate2::bufread::GzDecoder;
use tar::Archive;
#[allow(warnings)]
mod bindings;
struct Component;
impl Guest for Component {
fn id() -> String {
"clank/dev-packages".into()
}
fn should_run() -> bool {
if !std::path::PathBuf::from("/usr/local/bin/starship").exists() {
return true;
};
if !std::path::PathBuf::from("/root/.bashrc").exists() {
return true;
};
if let Ok(content) = std::fs::read_to_string("/root/.bashrc") {
if !content.contains("starship") {
return true;
}
}
if !std::path::PathBuf::from("/usr/local/bin/zellij").exists() {
return true;
};
false
}
fn execute() {
println!("running dev-packages installation");
Process::new().run_process(
&[
"bash",
"-c",
"curl -sS https://starship.rs/install.sh | sh -s -- --force",
]
.into_iter()
.map(|i| i.to_string())
.collect::<Vec<_>>(),
);
println!("downloaded starship");
if !std::path::PathBuf::from("/root/.bashrc").exists() {
println!("appending to bashrc");
if let Ok(content) = std::fs::read_to_string("/root/.bashrc") {
if !content.contains("starship") {
let mut bashrc = std::fs::File::options()
.write(true)
.open("/root/.bashrc")
.expect("failed to open bash");
bashrc
.write_all(r#"eval "$(starship init bash)"#.as_bytes())
.expect("failed to write to bashrc file");
}
}
} else {
let mut bashrc = std::fs::File::create("/root/.bashrc").expect("failed to open bash");
bashrc
.write_all(r#"eval "$(starship init bash)""#.as_bytes())
.expect("failed to write to bashrc file");
}
println!("installing zellij");
if !PathBuf::from("/usr/local/bin/zellij").exists() {
if let Err(err) = install_zellij() {
panic!("failed to install zellij: {}", err);
}
}
}
}
fn install_zellij() -> anyhow::Result<()> {
let url = "https://github.com/zellij-org/zellij/releases/download/v0.41.2/zellij-x86_64-unknown-linux-musl.tar.gz";
// TODO: Until this is merged: https://github.com/bytecodealliance/wasmtime/pull/9582 we just spawn a runtime
println!("getting zellij");
let content = http::Client::new().get(url);
println!("creating tempdir");
let temp_dir = PathBuf::from("/tmp/zellij_install/");
if let Err(e) = std::fs::remove_dir_all(&temp_dir) {
println!("failed to remove tmp dir: {e}");
}
std::fs::create_dir_all(&temp_dir).context("creating tmp dir")?;
let mut zellij_archive = std::fs::File::create(temp_dir.join("zellij.tar.gz"))?;
zellij_archive.write_all(&content)?;
zellij_archive.flush()?;
Process::new().run_process(
&[
"tar",
"-xvf",
&temp_dir.join("zellij.tar.gz").display().to_string(),
"-C",
&temp_dir.display().to_string(),
]
.into_iter()
.map(|i| i.to_string())
.collect::<Vec<_>>(),
);
// Move binary to /usr/local/bin
println!("move binary");
let binary_path = temp_dir.join("zellij");
fs::File::create("/usr/local/bin/zellij")?;
fs::copy(&binary_path, "/usr/local/bin/zellij")?;
Process::new().run_process(
&["chmod", "+x", "/usr/local/bin/zellij"]
.into_iter()
.map(|i| i.to_string())
.collect::<Vec<_>>(),
);
// Set executable permissions using std::fs::Permissions
#[cfg(unix)]
{
//use std::os::unix::fs::PermissionsExt;
//let mut perms = fs::metadata("/usr/local/bin/zellij")?.permissions();
//perms.set_mode(0o755);
//fs::set_permissions("/usr/local/bin/zellij", perms)
// .context("Failed to set executable permissions")?;
}
Ok(())
}
bindings::export!(Component with_types_in bindings);