Lazy commit
This commit is contained in:
50
cradle/usr/local/bin/dao.sh
Executable file
50
cradle/usr/local/bin/dao.sh
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
# ---
|
||||
# @file_name: dao.sh
|
||||
# @version: 1.0.0
|
||||
# @description: main dao handler
|
||||
# @author: Jamie Albert (empty_produce)
|
||||
# @author_contact: <mailto:empty.produce@flatmail.me>
|
||||
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
|
||||
# Copyright (C) 2025, Jamie Albert
|
||||
# ---
|
||||
set -euo pipefail
|
||||
|
||||
# ---
|
||||
# shellcheck disable=1091
|
||||
# ---
|
||||
setup() {
|
||||
. /usr/local/share/dao/libs/libs_dao.sh
|
||||
. /usr/local/share/dao/config/dao.conf
|
||||
}
|
||||
|
||||
declare -g COMMAND=$1
|
||||
shift
|
||||
|
||||
main() {
|
||||
setup
|
||||
case "${COMMAND}" in
|
||||
update)
|
||||
"${DAO_SCRIPTS_DIR}/on_demand/update.sh" "$@"
|
||||
;;
|
||||
transfer)
|
||||
"${DAO_SCRIPTS_DIR}/on_demand/transfer.sh" "$@"
|
||||
;;
|
||||
pwgen)
|
||||
"${DAO_SCRIPTS_DIR}/on_demand/pwgen.sh" "$@"
|
||||
;;
|
||||
mount)
|
||||
"${DAO_SCRIPTS_DIR}/always/mount.sh" "$@"
|
||||
;;
|
||||
firewall)
|
||||
"${DAO_SCRIPTS_DIR}/reboot/firewall.sh" "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: dao {update|transfer|pwgen|mount|firewall} [args]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,117 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# ---
|
||||
# @file_name: jade.sh
|
||||
# @version: 1.3.1
|
||||
# @description: Lazy script for modifying docker files
|
||||
# @author: Jamie Albert (empty_produce)
|
||||
# @author_contact: <mailto:empty.produce@flatmail.me>
|
||||
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
|
||||
# Copyright (C) 2025, Jamie Albert
|
||||
# ---
|
||||
set -euo pipefail
|
||||
|
||||
# ---
|
||||
# @return_code: [2] Unable to source.
|
||||
# shellcheck disable=2015,1090,1091
|
||||
# ---
|
||||
setup() {
|
||||
. /usr/local/share/cradle/libs/libs_cradle.sh
|
||||
declare -r conf="./usr/local/share/cradle/config/jade.conf"
|
||||
[[ -f "${conf}" ]] && . "${conf}" || cradle::error 2 "unable to source '${conf}'"
|
||||
}
|
||||
|
||||
# ---
|
||||
# @return_code: [3] Download failed.
|
||||
# ---
|
||||
download_file() {
|
||||
scp -q "${REMOTE_HOST}:${REMOTE_PATH}" "$LOCAL_PATH" || cradle::error 3 'Download failed'
|
||||
cradle::info "Downloaded: $LOCAL_PATH"
|
||||
}
|
||||
|
||||
# ---
|
||||
# @return_code: [4] Local file missing.
|
||||
# @return_code: [5] Failed to create remote backup.
|
||||
# @return_code: [6] Upload failed.
|
||||
# ---
|
||||
upload_file() {
|
||||
[[ -f "$LOCAL_PATH" ]] || cradle::error 4 "Local file missing: $LOCAL_PATH"
|
||||
ssh -q "${REMOTE_HOST}" "[[ -f '${REMOTE_PATH}' ]] && cp -f '${REMOTE_PATH}' '${REMOTE_PATH}.bak'" || cradle::error 5 'Failed to create remote backup'
|
||||
scp -q "$LOCAL_PATH" "${REMOTE_HOST}:${REMOTE_PATH}" || cradle::error 6 'Upload failed'
|
||||
cradle::info "Uploaded: $LOCAL_PATH"
|
||||
cradle::info "Remote file backed up to: ${REMOTE_PATH}.bak"
|
||||
}
|
||||
|
||||
# ---
|
||||
# @return_code: [7] Editor command not found.
|
||||
# @return_code: [3] Download failed (inherited from download_file).
|
||||
# ---
|
||||
edit_file() {
|
||||
download_file
|
||||
if ! command -v "$EDITOR" >/dev/null; then
|
||||
cradle::error 7 "Editor not found: '$EDITOR'"
|
||||
fi
|
||||
"$EDITOR" "$LOCAL_PATH"
|
||||
}
|
||||
|
||||
# ---
|
||||
# @return_code: [6] Upload failed (inherited from upload_file).
|
||||
# @return_code: [8] Remote docker compose up failed.
|
||||
# ---
|
||||
upload_compose() {
|
||||
upload_file
|
||||
ssh -q "${REMOTE_HOST}" \
|
||||
"cd '$(dirname "$REMOTE_PATH")' && exec docker compose up -d --remove-orphans" \
|
||||
|| cradle::error 8 'Remote docker compose up failed'
|
||||
cradle::info 'Remote docker compose up -d completed'
|
||||
}
|
||||
|
||||
# ---
|
||||
# @return_code: [9] Remote docker compose down failed.
|
||||
# @return_code: [6] Upload failed (inherited from upload_file).
|
||||
# @return_code: [11] Remote docker compose up failed during restart.
|
||||
# ---
|
||||
upload_restart() {
|
||||
ssh -q "${REMOTE_HOST}" \
|
||||
"cd '$(dirname "$REMOTE_PATH")' && exec docker compose down" \
|
||||
|| cradle::error 9 'Remote docker compose down failed'
|
||||
upload_file
|
||||
ssh -q "${REMOTE_HOST}" \
|
||||
"cd '$(dirname "$REMOTE_PATH")' && exec docker compose up -d --remove-orphans" \
|
||||
|| cradle::error 11 'Remote docker compose up failed during restart'
|
||||
cradle::info 'Remote docker compose restart completed'
|
||||
}
|
||||
|
||||
# ---
|
||||
# @return_code: [10] Unknown command-line option.
|
||||
# @return_code: [12] Required tool 'scp' not found.
|
||||
# @return_code: [13] Required tool 'ssh' not found.
|
||||
# @return_code: [14] Unexpected execution mode.
|
||||
# @return_code: [N] Errors from called functions (e.g., download_file, upload_file, etc.).
|
||||
# ---
|
||||
main() {
|
||||
setup
|
||||
declare mode=''
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-d) mode='download' ; shift ;;
|
||||
-u) mode='upload' ; shift ;;
|
||||
-uc) mode='up' ; shift ;;
|
||||
-ur) mode='restart' ; shift ;;
|
||||
*) cradle::error 10 "Unknown option: $1 (use -d, -u, -uc, -ur)" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
command -v scp >/dev/null || cradle::error 12 "'scp' not found"
|
||||
command -v ssh >/dev/null || cradle::error 13 "'ssh' not found"
|
||||
|
||||
case "$mode" in
|
||||
download) download_file ;;
|
||||
upload) upload_file ;;
|
||||
up) upload_compose ;;
|
||||
restart) upload_restart ;;
|
||||
'') edit_file ;;
|
||||
*) cradle::error 14 "Unexpected mode: $mode" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,139 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# ---
|
||||
# @file_name: jau.sh
|
||||
# @version: 1.0.0
|
||||
# @description: Full system update handler for Fedora-based systems with DNF and Flatpak
|
||||
# @author: Jamie Albert (empty_produce)
|
||||
# @author_contact: <mailto:empty.produce@flatmail.me>
|
||||
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
|
||||
# Copyright (C) 2025, Jamie Albert
|
||||
# ---
|
||||
set -euo pipefail
|
||||
|
||||
# ---
|
||||
# @description: Perform initial setup checks. Verifies required base commands (dnf, sudo) are available.
|
||||
# @return_code: [2] Required tool 'sudo' not found.
|
||||
# @return_code: [3] Required tool 'dnf' not found.
|
||||
# shellcheck disable=1091,1090
|
||||
# ---
|
||||
setup() {
|
||||
. /usr/local/share/cradle/libs/libs_cradle.sh
|
||||
|
||||
command -v sudo >/dev/null || cradle::error 2 "sudo not found"
|
||||
sudo sh -c 'command -v dnf >/dev/null' || cradle::error 3 "dnf not found (script requires a DNF-based system)"
|
||||
}
|
||||
|
||||
# ---
|
||||
# @description: Install package if missing.
|
||||
# @arg: $1 - The name of the package/command to check and install.
|
||||
# @return_code: [1] General cradle::error (inherits from set -e).
|
||||
# @return_code: [4] Failed to install the specified package.
|
||||
# ---
|
||||
install_if_missing() {
|
||||
declare pkg="$1"
|
||||
if ! command -v "$pkg" &>/dev/null; then
|
||||
cradle::info "Installing missing dependency: $pkg"
|
||||
sudo dnf install -y "$pkg" || cradle::error 4 "Failed to install $pkg"
|
||||
else
|
||||
cradle::info "Dependency satisfied: $pkg"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---
|
||||
# @description: Refresh DNF cache and update all packages.
|
||||
# @return_code: [1] General cradle::error (inherits from set -e).
|
||||
# @return_code: [5] Failed to refresh DNF cache.
|
||||
# @return_code: [6] DNF update failed.
|
||||
# ---
|
||||
run_dnf_update() {
|
||||
cradle::info "Refreshing DNF cache..."
|
||||
sudo dnf -y makecache --refresh || cradle::error 5 "Failed to refresh DNF cache"
|
||||
|
||||
cradle::info "Updating all packages..."
|
||||
sudo dnf -y update || cradle::error 6 "DNF update failed"
|
||||
}
|
||||
|
||||
# ---
|
||||
# @description: Handle leftover RPM configuration files.
|
||||
# @return_code: [1] General cradle::error (inherits from set -e).
|
||||
# @return_code: [7] rpmconf execution failed.
|
||||
# ---
|
||||
handle_rpmconf() {
|
||||
if command -v rpmconf &>/dev/null; then
|
||||
cradle::info "Handling leftover RPM configuration files..."
|
||||
sudo rpmconf -a || cradle::error 7 "rpmconf execution failed"
|
||||
else
|
||||
cradle::info "rpmconf not available; skipping config file handling"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---
|
||||
# @description: Install security updates if any exist.
|
||||
# @return_code: [1] General cradle::error (inherits from set -e).
|
||||
# @return_code: [8] Security update failed.
|
||||
# ---
|
||||
install_security_updates() {
|
||||
cradle::info "Checking for security updates..."
|
||||
# dnf check-update returns 100 if updates are available, 1 on error, 0 if not.
|
||||
# We only want to proceed if it returns 100 (success with updates) or 0 (no updates).
|
||||
# Using || true prevents set -e from triggering on exit code 100.
|
||||
if sudo dnf check-update --security &>/dev/null || [[ $? -eq 100 ]]; then
|
||||
cradle::info "Installing security updates..."
|
||||
sudo dnf -y update --security || cradle::error 8 "Security update failed"
|
||||
else
|
||||
cradle::info "No security updates available."
|
||||
fi
|
||||
}
|
||||
|
||||
# ---
|
||||
# @description: Remove unused packages and clean cache.
|
||||
# @return_code: [1] General cradle::error (inherits from set -e).
|
||||
# @return_code: [9] DNF autoremove failed.
|
||||
# @return_code: [10] DNF clean failed.
|
||||
# ---
|
||||
cleanup_packages() {
|
||||
cradle::info "Removing unused dependencies..."
|
||||
sudo dnf -y autoremove || cradle::error 9 "DNF autoremove failed"
|
||||
|
||||
cradle::info "Cleaning cached package data..."
|
||||
sudo dnf clean all || cradle::error 10 "DNF clean failed"
|
||||
}
|
||||
|
||||
# ---
|
||||
# @description: Update Flatpak applications and remove unused runtimes.
|
||||
# @return_code: [1] General cradle::error (inherits from set -e).
|
||||
# @return_code: [11] Flatpak update failed.
|
||||
# @return_code: [12] Flatpak cleanup failed.
|
||||
# ---
|
||||
update_flatpak() {
|
||||
if command -v flatpak &>/dev/null; then
|
||||
cradle::info "Updating Flatpak applications..."
|
||||
flatpak update -y || cradle::error 11 "Flatpak update failed"
|
||||
|
||||
cradle::info "Removing unused Flatpak runtimes..."
|
||||
flatpak uninstall --unused -y || cradle::error 12 "Flatpak cleanup failed"
|
||||
else
|
||||
cradle::info "Flatpak not installed; skipping Flatpak updates"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---
|
||||
# @description: Main routine.
|
||||
# @arg: $@ - Command-line arguments (currently unused).
|
||||
# @return_code: [1] General cradle::error (inherits from set -e).
|
||||
# @return_code: [N] Errors from called functions (e.g., setup, install_if_missing, etc.).
|
||||
# ---
|
||||
main() {
|
||||
setup
|
||||
cradle::info "Starting system updates..."
|
||||
install_if_missing rpmconf
|
||||
install_if_missing flatpak
|
||||
run_dnf_update
|
||||
handle_rpmconf
|
||||
install_security_updates
|
||||
cleanup_packages
|
||||
update_flatpak
|
||||
cradle::info "System updates completed successfully."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
210
cradle/usr/local/bin/prompt.sh
Executable file
210
cradle/usr/local/bin/prompt.sh
Executable file
@@ -0,0 +1,210 @@
|
||||
#!/usr/bin/env bash
|
||||
# ---
|
||||
# @file_name: prompt.sh
|
||||
# @version: 1.0.1
|
||||
# @description: a prompt
|
||||
# @author: Jamie Albert (empty_produce)
|
||||
# @author_contact: <mailto:empty.produce@flatmail.me>
|
||||
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
|
||||
# Copyright (C) 2025, Jamie Albert
|
||||
# ---
|
||||
|
||||
# Shell options configuration
|
||||
shopt -s histappend
|
||||
shopt -s cmdhist
|
||||
shopt -s histreedit
|
||||
shopt -s histverify
|
||||
shopt -s interactive_comments
|
||||
shopt -s checkwinsize
|
||||
shopt -s globstar
|
||||
shopt -s nocaseglob
|
||||
shopt -s dirspell
|
||||
shopt -s cdspell
|
||||
shopt -u autocd
|
||||
|
||||
if [[ $- =~ "i" ]]; then
|
||||
bind "set completion-ignore-case on"
|
||||
bind "set show-all-if-ambiguous on"
|
||||
bind "set mark-symlinked-directories on"
|
||||
fi
|
||||
|
||||
# Configuration
|
||||
_prompt_input_symbol="❯"
|
||||
_prompt_nerd_symbol=""
|
||||
_prompt_hostname="ssh"
|
||||
_prompt_separator=" "
|
||||
_prompt_wrapper="[]"
|
||||
_prompt_success_color="106"
|
||||
_prompt_fail_color="203"
|
||||
_prompt_user_color="109"
|
||||
_prompt_sudo_color="72"
|
||||
_prompt_info_color="172"
|
||||
_prompt_input_color="254"
|
||||
|
||||
# Git module configuration
|
||||
_git_nerd_symbol=""
|
||||
_git_module_symbol="git:"
|
||||
_git_module_color="38"
|
||||
|
||||
# Pyenv module configuration
|
||||
_pyenv_nerd_symbol=""
|
||||
_pyenv_module_symbol="pyenv:"
|
||||
_pyenv_module_color="66"
|
||||
|
||||
# Readonly module configuration
|
||||
_readonly_nerd_symbol=""
|
||||
_readonly_module_symbol="ro:"
|
||||
_readonly_module_color="196"
|
||||
|
||||
# Screen module configuration
|
||||
_screen_nerd_symbol=""
|
||||
_screen_module_symbol="scr:"
|
||||
_screen_module_color="33"
|
||||
|
||||
# shellcheck disable=1091
|
||||
#. /usr/local/share/dao/config/dao.conf
|
||||
|
||||
# --- Aliases
|
||||
alias count='find . -type f | wc -l'
|
||||
alias cdd='cd /home/jamie/dao'
|
||||
alias dnf='sudo dnf'
|
||||
alias hist='history|grep'
|
||||
alias ll="ls -laFh"
|
||||
alias la='ls -A'
|
||||
alias li='la | grep -i'
|
||||
alias lh='ll -d .*'
|
||||
alias mkdir='mkdir -p'
|
||||
alias nano='nano -W'
|
||||
alias sc='sudo systemctl'
|
||||
alias xclipc='xclip -sel c'
|
||||
|
||||
# Environment settings
|
||||
declare -g HISTTIMEFORMAT='%F %T '
|
||||
declare -g PROMPT_DIRTRIM="2"
|
||||
[[ -z "$LC_CTYPE" && -z "$LC_ALL" ]] && declare -g LC_CTYPE="${LANG%%:*}"
|
||||
[[ -z "$HISTFILE" ]] && declare -g HISTFILE="$HOME/.bash_history"
|
||||
declare -x HISTCONTROL=ignorespace
|
||||
declare -x HISTFILESIZE=10000
|
||||
declare -x HISTSIZE=${HISTFILESIZE}
|
||||
|
||||
# Color function for prompt
|
||||
_prompt_color() {
|
||||
[[ ${1} != "-" ]] && local _fg="38;5;${1}"
|
||||
echo -ne "\[\033[${_fg}m\]"
|
||||
}
|
||||
|
||||
# Generate prompt segments
|
||||
_prompt_generate() {
|
||||
local OLD_IFS="${IFS}"
|
||||
IFS="|"
|
||||
read -ra _params <<<"$1"
|
||||
IFS="${OLD_IFS}"
|
||||
|
||||
local _separator=""
|
||||
[[ ${_prompt_seg} -gt 1 ]] && _separator="${_prompt_separator}"
|
||||
_prompt_information+="${_separator}$(_prompt_color "${_params[1]}")${_params[0]}\[\e[0m\]"
|
||||
((_prompt_seg += 1))
|
||||
}
|
||||
|
||||
# Screen module pre function
|
||||
_screen_pre() {
|
||||
if [[ ${TERM} == "screen"* ]]; then
|
||||
_prompt_generate "${_screen_nerd_symbol}|${_screen_module_color}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Git module post function
|
||||
_git_post() {
|
||||
if git status --porcelain &>/dev/null; then
|
||||
local _unsafe_ref
|
||||
_unsafe_ref=$(command git symbolic-ref -q HEAD 2>/dev/null)
|
||||
local _stripped_ref="${_unsafe_ref##refs/heads/}"
|
||||
local _clean_ref="${_stripped_ref//[^a-zA-Z0-9\/]/-}"
|
||||
if [[ -n ${_clean_ref} ]]; then
|
||||
_prompt_generate "${_prompt_wrapper:0:1}${_git_nerd_symbol} ${_clean_ref}${_prompt_wrapper:1:1}|${_git_module_color}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Pyenv module post function
|
||||
_pyenv_post() {
|
||||
if [[ -n ${VIRTUAL_ENV} ]]; then
|
||||
local _pyenv_version
|
||||
_pyenv_version="$(python --version | cut -d " " -f2)"
|
||||
[[ -z ${_pyenv_version} ]] && _pyenv_version=$(python3 --version | cut -d " " -f2)
|
||||
if [[ -n ${_pyenv_version} ]]; then
|
||||
_prompt_generate "${_prompt_wrapper:0:1}${_pyenv_nerd_symbol} ${_pyenv_version}${_prompt_wrapper:1:1}|${_pyenv_module_color}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Readonly module post function
|
||||
_readonly_post() {
|
||||
if [[ ! -w "$(pwd)" ]]; then
|
||||
_prompt_generate "${_prompt_wrapper:0:1}${_readonly_nerd_symbol}${_prompt_wrapper:1:1}|${_readonly_module_color}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Build the main prompt
|
||||
_prompt_build() {
|
||||
local _last_status="$?"
|
||||
local _gen_uh
|
||||
local -gi _prompt_seg=1
|
||||
|
||||
# Run module pre functions
|
||||
if command -v _screen_pre >/dev/null; then
|
||||
_screen_pre
|
||||
fi
|
||||
|
||||
# User and hostname
|
||||
local _user_color="${_prompt_user_color}"
|
||||
sudo -n uptime 2>&1 | grep -q "load" && _user_color="${_prompt_sudo_color}"
|
||||
|
||||
_gen_uh="${USER}"
|
||||
{ [[ ${_prompt_hostname} == "all" ]]; } || { [[ ${_prompt_hostname} == "ssh" && -n ${SSH_CLIENT} ]]; } && _gen_uh="${_gen_uh}@${HOSTNAME}"
|
||||
_prompt_generate "${_gen_uh}|${_user_color}"
|
||||
|
||||
# Current directory
|
||||
_prompt_generate "${_prompt_wrapper:0:1}$(pwd | sed "s|^${HOME}|~|")${_prompt_wrapper:1:1}|${_prompt_info_color}"
|
||||
|
||||
# Error status
|
||||
[[ ${_last_status} -ne 0 ]] && _prompt_generate "${_prompt_wrapper:0:1}${_last_status}${_prompt_wrapper:1:1}|${_prompt_fail_color}"
|
||||
|
||||
# Run module post functions
|
||||
if command -v _git_post >/dev/null; then
|
||||
_git_post
|
||||
fi
|
||||
if command -v _pyenv_post >/dev/null; then
|
||||
_pyenv_post
|
||||
fi
|
||||
if command -v _readonly_post >/dev/null; then
|
||||
_readonly_post
|
||||
fi
|
||||
|
||||
# Final prompt symbol
|
||||
if [[ ${_last_status} -ne 0 ]]; then
|
||||
_prompt_status_color=${_prompt_fail_color}
|
||||
else
|
||||
_prompt_status_color=${_prompt_success_color}
|
||||
fi
|
||||
|
||||
_prompt_information+="$(_prompt_color "${_prompt_status_color}")\n${_prompt_nerd_symbol}\[\e[0m\]"
|
||||
|
||||
PS1="${_prompt_information} "
|
||||
unset _prompt_information _prompt_seg
|
||||
}
|
||||
|
||||
# Initialize prompt
|
||||
_prompt_init() {
|
||||
# Add to PROMPT_COMMAND
|
||||
if [[ -z ${PROMPT_COMMAND} ]]; then
|
||||
PROMPT_COMMAND="_prompt_build"
|
||||
else
|
||||
PROMPT_COMMAND="_prompt_build;${PROMPT_COMMAND}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Initialize when sourced
|
||||
if [[ ${BASH_SOURCE[0]} != "${0}" ]]; then
|
||||
_prompt_init
|
||||
fi
|
||||
@@ -1,65 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# ---
|
||||
# @file_name: pwgen.sh
|
||||
# @version: 1.0.1
|
||||
# @description: Generate a passphrase
|
||||
# @author: Jamie Albert (empty_produce)
|
||||
# @author_contact: <mailto:empty.produce@flatmail.me>
|
||||
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
|
||||
# Copyright (C) 2025, Jamie Albert
|
||||
# ---
|
||||
set -euo pipefail
|
||||
|
||||
declare -gr WORD_LIST='/usr/share/dict/japg.list'
|
||||
declare -gr DEFAULT_DELIM='-'
|
||||
declare -gi DEFAULT_WORDS=5
|
||||
|
||||
|
||||
# ---
|
||||
# @return_code: [2] Word-list file not found.
|
||||
# @return_code: [3] Required tool 'xclip' not found.
|
||||
# shellcheck disable=1091,1090
|
||||
# ---
|
||||
setup() {
|
||||
. /usr/local/share/cradle/libs/libs_cradle.sh
|
||||
[[ -f "${WORD_LIST}" ]] || cradle::error 2 "Word-list not found: $WORD_LIST"
|
||||
command -v xclip >/dev/null || cradle::error 3 "xclip not found (install xclip)"
|
||||
}
|
||||
|
||||
# ---
|
||||
# @arg: $1 - Number of words (optional, defaults to DEFAULT_WORDS).
|
||||
# @arg: $2 - Delimiter (optional, defaults to DEFAULT_DELIM).
|
||||
# @return_code: [1] General cradle::error (inherits from set -e).
|
||||
# @return_code: [4] Invalid number of words provided.
|
||||
# @return_code: [2] Word-list not found (inherited from setup).
|
||||
# @return_code: [3] xclip not found (inherited from setup).
|
||||
# ---
|
||||
main() {
|
||||
setup
|
||||
|
||||
declare num_words="${1:-$DEFAULT_WORDS}"
|
||||
declare delim="${2:-$DEFAULT_DELIM}"
|
||||
|
||||
[[ "${num_words}" =~ ^[1-9][0-9]*$ ]] || cradle::error 4 "num_words must be a positive integer"
|
||||
|
||||
declare -a words
|
||||
mapfile -t words < <(shuf -n "$num_words" "$WORD_LIST") || cradle::error 1 "Failed to read words from list"
|
||||
|
||||
declare i
|
||||
for i in "${!words[@]}"; do
|
||||
words[i]="${words[i]^}"
|
||||
done
|
||||
|
||||
declare dig_idx=$(( RANDOM % num_words ))
|
||||
words[dig_idx]+=$(( RANDOM % 10 ))
|
||||
|
||||
declare pass
|
||||
IFS="$delim"
|
||||
printf -v pass '%s' "${words[*]}" || cradle::error 1 "Failed to construct passphrase"
|
||||
|
||||
printf '%s' "$pass" | xclip -selection clipboard || cradle::error 1 "Failed to copy passphrase to clipboard"
|
||||
cradle::info "Generated password: $pass"
|
||||
cradle::info "Password copied to clipboard."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,80 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
CHECK_INTERVAL=30
|
||||
LOG_FILE="/var/log/rclone_mount_monitor.log"
|
||||
|
||||
# Common rclone mount options for all mounts
|
||||
BASE_RCLONE_OPTS=(
|
||||
--vfs-cache-mode writes
|
||||
--cache-dir /tmp/rclone-cache
|
||||
--dir-cache-time 5m
|
||||
--poll-interval 1m
|
||||
--timeout 1h
|
||||
--low-level-retries 10
|
||||
--retries 3
|
||||
)
|
||||
|
||||
# Additional options for crypt mounts
|
||||
CRYPT_RCLONE_OPTS=(
|
||||
--buffer-size 64M
|
||||
--transfers 4
|
||||
)
|
||||
|
||||
# Generic mount function
|
||||
rclone_mount() {
|
||||
declare remote="$1" mount_point="$2" mount_name="$3" is_crypt="$4"
|
||||
echo "[$(date)] Mounting $mount_name..." >> "$LOG_FILE"
|
||||
|
||||
# Build options array based on mount type
|
||||
declare opts_array=("${BASE_RCLONE_OPTS[@]}")
|
||||
[[ "$is_crypt" == "true" ]] && opts_array+=("${CRYPT_RCLONE_OPTS[@]}")
|
||||
|
||||
/usr/bin/rclone mount "$remote:" "$mount_point" "${opts_array[@]}" &
|
||||
}
|
||||
|
||||
# Mount configurations: remote:mount_point:name:is_crypt
|
||||
MOUNTS=(
|
||||
"koofr:/home/jamie/dao/storage/koofr:koofr:false"
|
||||
"koofr_vault:/home/jamie/dao/storage/vault:vault:true"
|
||||
)
|
||||
|
||||
# Check if mount is active
|
||||
is_mounted() {
|
||||
declare mount_point="$1"
|
||||
findmnt -rn "$mount_point" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
# Mount with error handling
|
||||
mount_with_check() {
|
||||
declare remote="$1"
|
||||
declare mount_point="$2"
|
||||
declare mount_name="$3"
|
||||
declare is_crypt="$4"
|
||||
|
||||
if ! is_mounted "$mount_point"; then
|
||||
echo "[$(date)] $mount_name is not mounted, attempting to remount..." >> "$LOG_FILE"
|
||||
rclone_mount "$remote" "$mount_point" "$mount_name" "$is_crypt" || {
|
||||
echo "[$(date)] Failed to mount $mount_name." >> "$LOG_FILE"
|
||||
return 1
|
||||
}
|
||||
echo "[$(date)] Successfully mounted $mount_name." >> "$LOG_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main monitoring loop
|
||||
main() {
|
||||
echo "[$(date)] Starting rclone mount monitor..." >> "$LOG_FILE"
|
||||
|
||||
while true; do
|
||||
for mount_config in "${MOUNTS[@]}"; do
|
||||
IFS=':' read -r remote mount_point mount_name is_crypt <<< "$mount_config"
|
||||
mount_with_check "$remote" "$mount_point" "$mount_name" "$is_crypt"
|
||||
done
|
||||
|
||||
sleep "$CHECK_INTERVAL"
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
43
cradle/usr/local/share/bash-completion/completions/dao.sh
Normal file
43
cradle/usr/local/share/bash-completion/completions/dao.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
# Bash completion for dao command
|
||||
|
||||
_dao_completion() {
|
||||
local cur commands
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
|
||||
mapfile -t commands < <(printf "update\ntransfer\npwgen\nmount\n")
|
||||
|
||||
case "${COMP_CWORD}" in
|
||||
1)
|
||||
mapfile -t COMPREPLY < <(compgen -W "${commands[*]}" -- "${cur}")
|
||||
;;
|
||||
2)
|
||||
case "${COMP_WORDS[1]}" in
|
||||
pwgen)
|
||||
mapfile -t COMPREPLY < <(compgen -W "3 4 5 6 7 8 9 10" -- "${cur}")
|
||||
;;
|
||||
transfer)
|
||||
mapfile -t COMPREPLY < <(compgen -W "-d -u -uc -ur" -- "${cur}")
|
||||
;;
|
||||
*) ;;
|
||||
esac
|
||||
;;
|
||||
3)
|
||||
case "${COMP_WORDS[1]}" in
|
||||
pwgen)
|
||||
if [[ "${COMP_WORDS[2]}" =~ ^[0-9]+$ ]]; then
|
||||
mapfile -t COMPREPLY < <(compgen -W "- _ . space" -- "${cur}")
|
||||
fi
|
||||
;;
|
||||
*) ;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
complete -F _dao_completion dao.sh
|
||||
@@ -1,4 +0,0 @@
|
||||
REMOTE_HOST="root@hephaestus"
|
||||
REMOTE_PATH="/home/oc/docker_config/compose.yml"
|
||||
LOCAL_PATH="/tmp/${REMOTE_PATH##*/}"
|
||||
EDITOR="codium"
|
||||
13
cradle/usr/local/share/dao/config/dao.conf
Normal file
13
cradle/usr/local/share/dao/config/dao.conf
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
# -- dao.sh
|
||||
DAO_USER="jamie"
|
||||
DAO_USER_HOME="/home/${DAO_USER}"
|
||||
DAO_INSTALL_DIR="${DAO_USER_HOME}/dao"
|
||||
DAO_SCRIPTS_DIR="${DAO_INSTALL_DIR}/scripts"
|
||||
DAO_STORAGE_DIR="${DAO_INSTALL_DIR}/storage"
|
||||
|
||||
# --- jade.sh
|
||||
JADE_REMOTE_HOST="root@hephaestus"
|
||||
JADE_REMOTE_PATH="/home/oc/docker_config/compose.yml"
|
||||
JADE_LOCAL_PATH="/tmp/${JADE_REMOTE_PATH##*/}"
|
||||
JADE_EDITOR="codium"
|
||||
@@ -16,7 +16,7 @@ readonly GREEN=$'\033[0;38;5;108m'
|
||||
readonly YELLOW=$'\033[1;38;5;214m'
|
||||
readonly NC=$'\033[0m'
|
||||
|
||||
cradle::error() {
|
||||
dao::error() {
|
||||
declare error_msg exit_code="${1}"
|
||||
shift
|
||||
printf -v error_msg 'error[%d]: %s\n' "${exit_code}" "$*"
|
||||
@@ -24,13 +24,13 @@ cradle::error() {
|
||||
exit "${exit_code}"
|
||||
}
|
||||
|
||||
cradle::info() {
|
||||
dao::info() {
|
||||
declare info_msg
|
||||
printf -v info_msg '%s\n' "$*"
|
||||
echo -ne "${GREEN}[i]${NC}: ${info_msg}"
|
||||
}
|
||||
|
||||
cradle::warn() {
|
||||
dao::warn() {
|
||||
declare warn_msg
|
||||
printf -v warn_msg '%s\n' "$*"
|
||||
echo -ne "${YELLOW}[w]${NC}: ${warn_msg}"
|
||||
Reference in New Issue
Block a user