dx/dxkit/commands/hosts.command.sh

203 lines
No EOL
4.8 KiB
Bash

#!/usr/bin/env bash
# commands/hosts.command.sh
#
# Manages /etc/hosts entries for the project.
#
# Usage:
# dx hosts sync — write project entries to /etc/hosts (requires root)
# dx hosts remove — remove project entries from /etc/hosts (requires root)
# dx hosts list — show current /etc/hosts entries for this project
# dx hosts preview — preview entries that would be written
#
# Also accessible via:
# dx network hosts <subcommand>
# ============================================
# Lifecycle
# ============================================
function cmd::hosts::on_load() {
flag::register \
--debug
}
# ============================================
# Public entrypoint
# ============================================
function cmd::hosts::run() {
local subcmd="${1:-help}"
shift || true
case "$subcmd" in
sync) cmd::hosts::sync "$@" ;;
remove) cmd::hosts::remove "$@" ;;
list) cmd::hosts::list "$@" ;;
preview) cmd::hosts::preview "$@" ;;
help) cmd::hosts::help ;;
*)
log::error "Unknown subcommand: '${subcmd}'"
cmd::hosts::help
return 1
;;
esac
}
# ============================================
# Help
# ============================================
function cmd::hosts::help() {
cat <<EOF
Usage: dx hosts <subcommand>
Manages /etc/hosts entries for ${PROJECT_NAME}.
Subcommands:
sync Write project entries to /etc/hosts (requires root)
remove Remove project entries from /etc/hosts (requires root)
list Show current entries in /etc/hosts for this project
preview Preview entries that would be written
Examples:
dx hosts sync
dx hosts remove
dx hosts list
dx hosts preview
EOF
}
# ============================================
# Sync
# ============================================
function cmd::hosts::sync() {
local hosts_file
hosts_file="$(platform::hosts_file)"
platform::require_privileges || {
log::warn "$(platform::elevation_fail)"
log::error "Could not sync hosts — permission denied"
return 1
}
local block
block="$(cmd::hosts::_build_block)"
[[ -f "$hosts_file" ]] || touch "$hosts_file" || return 1
local tmp
tmp="$(fs::replace_block \
"$hosts_file" \
"$(cmd::hosts::_marker)" \
"$(cmd::hosts::_end_marker)" \
"$block"
)" || return 1
fs::write_file "$tmp" "$hosts_file"
log::success "Hosts synced for ${PROJECT_NAME}"
cmd::hosts::_show_entries "$block"
}
# ============================================
# Remove
# ============================================
function cmd::hosts::remove() {
local hosts_file
hosts_file="$(platform::hosts_file)"
platform::require_privileges || {
log::warn "$(platform::elevation_fail)"
log::error "Could not remove hosts — permission denied"
return 1
}
if ! grep -q "$(cmd::hosts::_marker)" "$hosts_file" 2>/dev/null; then
log::info "No entries found for ${PROJECT_NAME} in $(platform::hosts_file)"
return 0
fi
local tmp
tmp="$(fs::replace_block \
"$hosts_file" \
"$(cmd::hosts::_marker)" \
"$(cmd::hosts::_end_marker)" \
""
)" || return 1
fs::write_file "$tmp" "$hosts_file"
log::success "Hosts entries removed for ${PROJECT_NAME}"
}
# ============================================
# List
# ============================================
function cmd::hosts::list() {
local hosts_file
hosts_file="$(platform::hosts_file)"
if ! grep -q "$(cmd::hosts::_marker)" "$hosts_file" 2>/dev/null; then
log::info "No entries found for ${PROJECT_NAME} in ${hosts_file}"
return 0
fi
log::info "Current entries for ${PROJECT_NAME} in ${hosts_file}:"
printf "\n"
# Extract block between markers
awk "/$(cmd::hosts::_marker)/,/$(cmd::hosts::_end_marker)/" "$hosts_file" \
| grep -v "^#"
printf "\n"
}
# ============================================
# Preview
# ============================================
function cmd::hosts::preview() {
log::info "Entries that would be written for ${PROJECT_NAME}:"
printf "\n"
cmd::hosts::_generate_entries
printf "\n"
}
# ============================================
# Private
# ============================================
function cmd::hosts::_marker() { echo "# >>> ${PROJECT_NAME} >>>"; }
function cmd::hosts::_end_marker() { echo "# <<< ${PROJECT_NAME} <<<"; }
function cmd::hosts::_generate_entries() {
local ip="127.0.0.1"
local domains=(
"$DOMAIN"
"$BACKEND_DOMAIN"
)
for domain in "${domains[@]}"; do
echo "${ip} ${domain}"
done
}
function cmd::hosts::_build_block() {
local entries
entries="$(cmd::hosts::_generate_entries | tr -d '\r')"
printf "%s\n%s\n%s" \
"$(cmd::hosts::_marker)" \
"$entries" \
"$(cmd::hosts::_end_marker)"
}
function cmd::hosts::_show_entries() {
local entries="$1"
printf "\n"
echo "$entries"
printf "\n"
}