mirror of
https://github.com/kellymichels/zscripts-token-savers
synced 2026-10-07 07:18:18 +00:00
* feat(bash): native bash port of all z-scripts for Linux/macOS/WSL Full port: zhelpers.sh library (jq config, ssh, http/tcp, archive builder, build-version, motd, port-kill), all commands (zstart/zkill/zrestart/zstop, zdeploy with 5 kind handlers, zec2/zec2online/zrepair, zbackup/zbackup_ec2/ zsync/zbackup_and_sync, zstart_docker, zsetup_mail, setup_backup_schedule via cron), Unix-path zconfig.example.json, and a bash/README.md. Verified: bash -n clean on all scripts; archive exclusions, config semantics, and zec2 tested against the real config and live server from Git Bash. Needs a Linux/macOS/WSL shakedown for lsof/rsync/nohup paths before merging. * chore: pin line endings (.gitattributes) - bash LF, powershell CRLF * docs(readme): point Linux/macOS/WSL users at the bash port * fix(bash): don't run the Windows venv python.exe on WSL/Linux/macOS zstart's venv detection fell back to .venv/Scripts/python.exe (a Windows binary) whenever it existed. On a Windows-built project accessed from WSL that file sits on the mount and looks executable, so it got picked and failed with 'exec format error' instead of falling through to python3. Guard that branch to Windows-family shells (msys/cygwin), where a .exe can actually run. Verified on WSL: zstart --detached now backgrounds a stdlib app via python3, serves HTTP 200, logs to /tmp/zstart-<key>.log, and zkill terminates it and frees the port. * feat(bash): add token-usage tracking to the bash port (#6) Adds z_track_start/z_track_stop + z_record to zhelpers.sh and wires z_track_start into every command script. Each run now captures its own output volume (FIFO+tee, ANSI stripped), prints the '--- N lines / N chars / ~N tokens est. (Claude Code) ---' footer, and appends one JSONL row per top-level run in the same shape as the PowerShell tokens.jsonl. A nested-run guard keeps zrestart from double-counting its zkill/zstart children. Data dir precedence: $ZTOKENS_DATA, config ztokens.dataDir, sibling ../../ztokens/data, else ~/.ztokens/data. Docs + example config updated. Verified on WSL (isolated data dir): single run records correctly; nested zrestart produces one combined record, not three; est = round(chars/3.5).
108 lines
4.0 KiB
Bash
108 lines
4.0 KiB
Bash
#!/usr/bin/env bash
|
|
# Evomedia.net Token Savers — https://github.com/kellymichels/zscripts-token-savers
|
|
# Created by Kelly Michels · dev@evomedia.net
|
|
# Licensed under the MIT License. See LICENSE.
|
|
#
|
|
# zsetup_mail — create admin@ and noreply@ mailboxes in a docker-mailserver
|
|
# container on the server, and print the DNS records + SMTP/IMAP settings to use.
|
|
#
|
|
# Usage:
|
|
# zsetup_mail --domain yourdomain.com [--mail-host mail.yourdomain.com] [--host <ip>] [--pem <path>]
|
|
|
|
set -uo pipefail
|
|
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/zhelpers.sh"
|
|
z_track_start "$@"
|
|
z_need_config
|
|
z_require ssh
|
|
|
|
domain=""; mail_host=""; ec2_host=""; pem=""
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--domain) domain="${2:-}"; shift 2 ;;
|
|
--mail-host) mail_host="${2:-}"; shift 2 ;;
|
|
--host) ec2_host="${2:-}"; shift 2 ;;
|
|
--pem) pem="${2:-}"; shift 2 ;;
|
|
*) err "Unknown option: $1"; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
[ -n "$ec2_host" ] || ec2_host="$(zec2_ip)"
|
|
[ -n "$pem" ] || pem="$(zec2_pem)"
|
|
|
|
if [ -z "$domain" ]; then
|
|
printf '\n'; warn "Usage: zsetup_mail --domain yourdomain.com [--mail-host mail.yourdomain.com]"
|
|
dim " Creates admin@ and noreply@ mailboxes on the server's mailserver container."
|
|
exit 1
|
|
fi
|
|
[ -n "$mail_host" ] || mail_host="mail.$domain"
|
|
|
|
info "=== Mail Setup Utility ==="
|
|
[ -f "$pem" ] || { err "PEM key not found: $pem"; exit 1; }
|
|
dim "Using PEM Key: $pem"
|
|
dim "Target Host : $ec2_host"
|
|
dim "Domain Name : $domain"
|
|
|
|
gen_password() {
|
|
LC_ALL=C tr -dc 'a-zA-Z0-9!@#%^&*' < /dev/urandom | head -c 16
|
|
}
|
|
admin_pw="$(gen_password)"
|
|
noreply_pw="$(gen_password)"
|
|
|
|
remote() {
|
|
ssh -o ConnectTimeout=15 -o StrictHostKeyChecking=no -i "$pem" "$(zec2_user)@$ec2_host" "$1"
|
|
}
|
|
|
|
printf '\n'; warn "[1/3] Connecting to the mail server to provision mailboxes..."
|
|
|
|
dim "Adding email account: admin@$domain..."
|
|
if remote "sudo docker exec mailserver setup email add admin@$domain '$admin_pw'"; then
|
|
ok "Account admin@$domain added successfully."
|
|
else
|
|
warn "Could not add admin account (it might already exist or docker setup failed)."
|
|
fi
|
|
|
|
dim "Adding email account: noreply@$domain..."
|
|
if remote "sudo docker exec mailserver setup email add noreply@$domain '$noreply_pw'"; then
|
|
ok "Account noreply@$domain added successfully."
|
|
else
|
|
warn "Could not add noreply account (it might already exist or docker setup failed)."
|
|
fi
|
|
|
|
printf '\n'; warn "[2/3] DNS Configuration Requirements"
|
|
dim "Add or update the following records in your DNS zone for ${domain}:"
|
|
info "--------------------------------------------------------------------------------"
|
|
printf '%s\n' "1. MX Record (Inbound mail routing):"
|
|
ok " - Name : (leave blank or @)"
|
|
ok " - Type : MX"
|
|
warn " - Value : 10 $mail_host"
|
|
printf '%s\n' "2. TXT Record (SPF authorization):"
|
|
ok " - Name : (leave blank or @)"
|
|
ok " - Type : TXT"
|
|
warn " - Value : \"v=spf1 mx ~all\""
|
|
printf '%s\n' "3. A Record for Webmail:"
|
|
ok " - Name : webmail"
|
|
ok " - Type : A"
|
|
warn " - Value : $ec2_host"
|
|
printf '%s\n' "4. A Record for Mail Admin:"
|
|
ok " - Name : mail-admin"
|
|
ok " - Type : A"
|
|
warn " - Value : $ec2_host"
|
|
info "--------------------------------------------------------------------------------"
|
|
|
|
printf '\n'; warn "[3/3] Application Connection Credentials"
|
|
dim "Use these connection settings in your app config or .env:"
|
|
info "--------------------------------------------------------------------------------"
|
|
printf '%s\n' "SMTP Hostname : $mail_host"
|
|
printf '%s\n' "SMTP Port (STARTTLS) : 587"
|
|
printf '%s\n' "SMTP Port (SSL/TLS) : 465"
|
|
printf '%s\n' "IMAP Hostname : $mail_host"
|
|
printf '%s\n' "IMAP Port (SSL/TLS) : 993"
|
|
info "--------------------------------------------------------------------------------"
|
|
ok "Email User 1 : admin@$domain"
|
|
warn "Password : $admin_pw"
|
|
printf '\n'
|
|
ok "Email User 2 : noreply@$domain"
|
|
warn "Password : $noreply_pw"
|
|
info "--------------------------------------------------------------------------------"
|
|
ok "Completed successfully!"
|