Skip to content

Commit

Permalink
feat: improve shell (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphaelcoeffic authored Nov 8, 2024
1 parent 92c2815 commit 3e9c4a2
Show file tree
Hide file tree
Showing 10 changed files with 355 additions and 44 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
nix
image_builder/base.tar.xz
base.tar.xz
base.sha256
72 changes: 72 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions image_builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ ureq = { version = "2.10.1", default-features = false, features = ["tls", "nativ
rustix = { workspace = true, features = ["runtime"] }
tar = { workspace = true }
tempfile = { workspace = true }
sha2 = "0.10.8"
2 changes: 2 additions & 0 deletions image_builder/src/debug-shell/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@
netcat-openbsd
procps
sngrep
sqlite
strace
tcpdump
util-linux
vim
xz
zsh
zsh-prezto
zsh-autosuggestions
zsh-completions
zsh-fast-syntax-highlighting
Expand Down
61 changes: 61 additions & 0 deletions image_builder/src/etc/zshrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# set usual editor
export VISUAL=vim
export EDITOR=vim
alias e=$EDITOR

# -- zsh modules
autoload -Uz compinit

ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets pattern cursor line)
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=40
ZSH_AUTOSUGGEST_STRATEGY=(match_prev_cmd)

# prevent prezto dependency loader
pmodload() {}

zstyle ':prezto:*:*' color yes
zstyle ':prezto:module:editor' key-bindings emacs
zstyle ':prezto:module:editor' dot-expansion yes
zstyle ':prezto:module:utility' safe-ops no

BASE_SHARE=/nix/.base/share
SITE_FUNCTIONS=$BASE_SHARE/zsh/site-functions
PRETZO_MODULES=$BASE_SHARE/zsh-prezto/modules

# -- prezto modules
source $PRETZO_MODULES/helper/init.zsh
fpath+=( $PRETZO_MODULES/helper )
source $PRETZO_MODULES/environment/init.zsh
fpath+=( $PRETZO_MODULES/environment )
source $PRETZO_MODULES/terminal/init.zsh
fpath+=( $PRETZO_MODULES/terminal )
source $PRETZO_MODULES/editor/init.zsh
fpath+=( $PRETZO_MODULES/editor )
source $PRETZO_MODULES/utility/init.zsh
fpath+=( $PRETZO_MODULES/utility )

# -- some extras
source $SITE_FUNCTIONS/fast-syntax-highlighting.plugin.zsh
source $BASE_SHARE/zsh-autosuggestions/zsh-autosuggestions.zsh

source $PRETZO_MODULES/completion/init.zsh
fpath+=( $PRETZO_MODULES/completion )

unsetopt EXTENDED_GLOB
unsetopt MENU_COMPLETE

setopt AUTO_CD
setopt AUTO_MENU
setopt CDABLE_VARS
setopt CLOBBER
setopt MULTIOS
setopt PUSHDSILENT

HISTFILE="${XDG_CACHE_HOME:-$HOME/.cache}/.zsh_history"
HISTSIZE=10000 # in memory
SAVEHIST=10000 # persistent
bindkey -e # emacs keymap

# help stuff
# echo "Welcome to the dive shell!"

51 changes: 42 additions & 9 deletions image_builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustix::{
runtime::{fork, Fork},
thread::{unshare, Pid, UnshareFlags},
};
use sha2::{Digest, Sha256};
use tar::Archive;
use tempfile::tempdir;

Expand All @@ -34,6 +35,9 @@ static FLAKE_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/src/debug-shell");
// Break compilation if 'flake.nix' does not exist
static _FLAKE_NIX_GUARD_: &str = include_str!("debug-shell/flake.nix");

static STATIC_FILES: &[(&str, &str)] =
&[("/nix/etc/.zshrc", include_str!("etc/zshrc"))];

type PostProcessFn = Box<dyn Fn(&Path) -> Result<()>>;

pub struct BaseImageBuilder {
Expand Down Expand Up @@ -82,11 +86,7 @@ impl BaseImageBuilder {
where
P: AsRef<Path>,
{
let output = output.as_ref();
let archive_suffix = if compress { "tar.xz" } else { "tar" };
let archive_name = format!("{}.{}", output.display(), archive_suffix);

self.package_output.replace(PathBuf::from(archive_name));
self.package_output.replace(PathBuf::from(output.as_ref()));
self.compress = compress;
self
}
Expand All @@ -112,8 +112,28 @@ impl BaseImageBuilder {
if build_status.is_err() {
return Self::BUILD_FAILED;
}

let base_path = build_status.unwrap();

// copy static files (zshrc, etc)
let mut hasher = Sha256::new();
hasher.update(base_path.as_os_str().as_encoded_bytes());

if let Err(err) = STATIC_FILES.iter().try_for_each(|(dest, content)| {
hasher.update(content);
fs::write(dest, content)
}) {
log::error!("failed to copy static files: {err}");
return Self::POST_PROCESS_FAILED;
}

let hash = hasher.finalize();
if let Err(err) =
fs::write("/nix/.base.sha256", format!("{:x}\n", hash))
{
log::error!("failed to write hash file: {err}");
return Self::POST_PROCESS_FAILED;
}

if let Err(err) = self.do_post_process(&base_path) {
log::error!("post process failed: {}", err);
return Self::POST_PROCESS_FAILED;
Expand Down Expand Up @@ -200,12 +220,15 @@ impl BaseImageBuilder {
let nix_set = read_nix_paths("/nix")?;

let mut tar_cmd = Command::new("tar");
let archive_suffix = if self.compress { "tar.xz" } else { "tar" };
let archive_name = format!("{}.{}", output.display(), archive_suffix);

tar_cmd.args([
"--directory=/nix",
"--exclude=var/nix/*",
"-c",
"-f",
&format!("{}", output.display()),
&archive_name,
]);

if self.compress {
Expand All @@ -220,7 +243,7 @@ impl BaseImageBuilder {
let path_env = format!("{current_path}/nix/.base/bin");

tar_cmd
.args([".bin", ".base", "etc", "var/nix"])
.args([".bin", ".base", ".base.sha256", "etc", "var/nix"])
.args(nix_set.union(&base_set).map(|p| "store/".to_owned() + p))
.env("PATH", path_env);

Expand All @@ -234,6 +257,10 @@ impl BaseImageBuilder {
}
}

let sha256_name = format!("{}.sha256", output.display());
fs::copy("/nix/.base.sha256", sha256_name)
.context("could not copy hash file")?;

Ok(())
}
}
Expand Down Expand Up @@ -287,7 +314,13 @@ where
fn chmod_apply(path: &Path, func: fn(u32) -> u32) -> Result<(), io::Error> {
let metadata = fs::metadata(path)?;
let mode = metadata.permissions().mode();
fs::set_permissions(path, fs::Permissions::from_mode(func(mode)))
let new_mode = func(mode);

if new_mode != mode {
fs::set_permissions(path, fs::Permissions::from_mode(new_mode))
} else {
Ok(())
}
}

// fix permissions recursively
Expand Down
Loading

0 comments on commit 3e9c4a2

Please sign in to comment.