187 lines
6.1 KiB
Bash
187 lines
6.1 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# httm is an interactive, file-level Time Machine-like tool for ZFS/btrfs/NILFS2
|
|
# at provides wrapper scripts that demonstrate how to use the httm command line:
|
|
# - bowie.bash displays the difference between unique snapshot versions and the live file.
|
|
# - equine.bash mount APFS snapshots for use with httm.
|
|
# - nicotine.bash converts unique snapshot file versions to a $git archive.
|
|
# - ounce.bash snapshots the datasets of files opened by another programs. only when you have file changes outstanding, uncommitted to a snapshot already
|
|
# - preview-bootstrap.bash bridges httm to fzf, handles the "Preview" window functionality.
|
|
# - zdbstat.bash prints the underlying zdb metadata for a ZFS object.
|
|
|
|
DEST=${1:-/etc/skel}
|
|
set -x
|
|
|
|
URL=raw.githubusercontent.com
|
|
USER=kimono-koans
|
|
APP="httm"
|
|
#TYPES=(deb deb-src)
|
|
TYPES=(deb)
|
|
TRANSPORT="https:/"
|
|
URI="${URL}/${USER}/ppa/main"
|
|
SUITES="./"
|
|
COMPONENTS=()
|
|
ARCHITECTURES=(amd64)
|
|
KEY_HOME=/usr/share/keyrings
|
|
KEY=${KEY_HOME}/"${USER}.gpg"
|
|
packages=(httm two-percent fzf)
|
|
|
|
sudo mkdir -p ${KEY_HOME}
|
|
wget -qO- ${TRANSPORT}/${URI}/${USER}/${APP}/main/deb.asc | sudo gpg --dearmor -o ${KEY}
|
|
|
|
# echo "deb [signed-by=/etc/apt/trusted.gpg.d/${KEY}] https://${URL}/${USER}/ppa/main ./" | sudo tee /etc/apt/sources.list-available/${APP}-ppa.list
|
|
# echo "deb-src [signed-by=/etc/apt/trusted.gpg.d/${KEY}] https://${URL}/${USER}/ppa/main ./" | sudo tee -a /etc/apt/sources.list-available/${APP}-ppa.list
|
|
|
|
conf_print_httm_sources() {
|
|
cat <<EOF
|
|
Enabled: yes
|
|
Types: ${TYPES[*]}
|
|
URIs: ${TRANSPORT}/${URI}
|
|
Suites: ${SUITES}
|
|
Components: ${COMPONENTS[*]}
|
|
Architectures: ${ARCHITECTURES[*]}
|
|
Signed-By: ${KEY}
|
|
EOF
|
|
}
|
|
conf_print_httm_sources | sudo tee /etc/apt/sources.list-available/httm-ppa.sources >/dev/null
|
|
sudo ln -sf /etc/apt/sources.list-available/${APP}-ppa.sources /etc/apt/sources.list.d/${APP}-ppa.sources
|
|
|
|
# Bypass apt-proxy for ${APP} packages
|
|
PROXY_FILE="/etc/apt/apt.conf.d/02proxy"
|
|
ENTRY="Acquire::http::Proxy { \"${URL}\" DIRECT; };"
|
|
|
|
echo "# Bypass apt-proxy for ${APP} packages"
|
|
|
|
# Check if the entry already exists in the file (if the file exists)
|
|
if [ -f "$PROXY_FILE" ] && grep -qF "${URL}" "$PROXY_FILE"; then
|
|
echo "Proxy bypass for ${URL} is already present."
|
|
else
|
|
# Append the entry, or create the file if it doesn't exist
|
|
echo "$ENTRY" | sudo tee -a "$PROXY_FILE" >/dev/null
|
|
echo "Added proxy bypass for ${URL}."
|
|
fi
|
|
|
|
sudo apt install -y --no-install-recommends "${packages[@]}"
|
|
|
|
# Using cargo
|
|
# https://crates.io/crates/httm
|
|
# curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
# latest="(wget -nv -O - "https://api.github.com/repos/kimono-koans/httm/releases/latest" 2>/dev/null | grep tag_name | cut -d: -f2 | cut -d'"' -f2)"
|
|
# cargo install --locked --git https://github.com/kimono-koans/httm.git --tag "$latest"
|
|
|
|
# httm --install-zsh-hot-keys puts a file in ${HOME} and includes it in the .zshrc
|
|
# httm: zsh hot keys script: source ~/.httm-key-bindings.zsh
|
|
# we put in the zshrc.d instead.
|
|
# Update with :r! curl -s https://raw.githubusercontent.com/kimono-koans/httm/refs/heads/master/scripts/httm-key-bindings.zsh
|
|
# httm/scripts/httm-key-bindings.zsh
|
|
cat <<"EOF" | sudo tee "${DEST}/.zshrc.d/008_httm-key-bindings.zsh"
|
|
# ___ ___ ___ ___
|
|
# /\__\ /\ \ /\ \ /\__\
|
|
# /:/ / \:\ \ \:\ \ /::| |
|
|
# /:/__/ \:\ \ \:\ \ /:|:| |
|
|
# /::\ \ ___ /::\ \ /::\ \ /:/|:|__|__
|
|
# /:/\:\ /\__\ /:/\:\__\ /:/\:\__\ /:/ |::::\__\
|
|
# \/__\:\/:/ / /:/ \/__/ /:/ \/__/ \/__/~~/:/ /
|
|
# \::/ / /:/ / /:/ / /:/ /
|
|
# /:/ / \/__/ \/__/ /:/ /
|
|
# /:/ / /:/ /
|
|
# \/__/ \/__/
|
|
#
|
|
# Copyright (c) 2023, Robert Swinford <robert.swinford<...at...>gmail.com>
|
|
#
|
|
# For the full copyright and license information, please view the LICENSE file
|
|
# that was distributed with this source code.
|
|
|
|
# ALT-d - Dynamically snap selected files's dataset
|
|
__httm-snapshot() {
|
|
command httm --snap 2>/dev/null "$1" || \
|
|
command sudo httm --snap "$1" || \
|
|
echo "httm snapshot widget quit with a snapshot error. Check you have the correct permissions to snapshot."; return 1
|
|
|
|
local ret=$?
|
|
echo
|
|
return $ret
|
|
}
|
|
|
|
httm-snapshot-widget() {
|
|
local input_file
|
|
local canonical_path
|
|
|
|
# requires an fzf function sourced to work properly
|
|
if [[ $( type "__fsel" 2>/dev/null | grep -q "function" ) -eq 0 ]]
|
|
then
|
|
# need canonical path for a httm snapshot
|
|
input_file="$(__fsel)"
|
|
[[ -z "$input_file" ]] || canonical_path="$(readlink -f $input_file)"
|
|
else
|
|
canonical_path="$PWD"
|
|
fi
|
|
|
|
[[ -z "$canonical_path" ]] || __httm-snapshot "$filename"
|
|
|
|
local ret=$?
|
|
zle reset-prompt
|
|
return $ret
|
|
|
|
}
|
|
zle -N httm-snapshot-widget
|
|
bindkey '\ed' httm-snapshot-widget
|
|
|
|
# ALT-m - browse for ZFS snapshots interactively
|
|
httm-lookup-widget() {
|
|
|
|
echo
|
|
command httm -r -R
|
|
|
|
local ret=$?
|
|
zle reset-prompt
|
|
return $ret
|
|
|
|
}
|
|
zle -N httm-lookup-widget
|
|
bindkey '\em' httm-lookup-widget
|
|
|
|
# ALT-s - select files on ZFS snapshots interactively
|
|
__httm-select() {
|
|
|
|
command httm -s -R | \
|
|
while read item; do
|
|
echo -n "${item}"
|
|
done
|
|
|
|
local ret=$?
|
|
echo
|
|
return $ret
|
|
|
|
}
|
|
|
|
httm-select-widget() {
|
|
LBUFFER="${LBUFFER}$(__httm-select)"
|
|
local ret=$?
|
|
zle reset-prompt
|
|
return $ret
|
|
}
|
|
zle -N httm-select-widget
|
|
bindkey '\es' httm-select-widget
|
|
EOF
|
|
|
|
# The ounce script (codename: "dimebag") is a wrapper for httm that automates
|
|
# snapshot creation with minimal mental overhead. It uses seccomp and eBPF to
|
|
# trace file modifications and automatically takes a snapshot before you edit
|
|
# a file, effectively providing non-periodic dynamic snapshots "auto-snapshot"
|
|
# behavior.
|
|
# To integrate ounce into your workflow, you can set up aliases in your shell
|
|
# (e.g., .zshrc):
|
|
conf_print_ounce_aliases() {
|
|
cat <<EOF
|
|
alias vim="ounce --trace vim"
|
|
alias emacs="ounce --trace emacs"
|
|
alias nano="ounce --trace nano"
|
|
alias rm="ounce rm"
|
|
EOF
|
|
}
|
|
# conf_print_ounce_aliases | tee ${DEST}/.zsh_aliases.d/010_httm-aliases >/dev/null
|
|
|
|
# request ZFS snapshot privileges
|
|
ounce --give-priv
|