Author SHA1 Message Date
andrew ceb21b44d5 AI generated code suggestions
Sync GitHub / sync (push) Successful in 34s
2026-07-25 22:04:45 -04:00
andrew 09dffc3933 new docker scripts, pull and heal.
Sync GitHub / sync (push) Successful in 40s
2026-07-24 23:43:31 -04:00
andrew aa0da565e1 setting up automatic sync from Gitea to GitHub
Sync GitHub / sync (push) Successful in 9s
2026-06-14 11:05:28 -04:00
5 changed files with 422 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
name: Sync GitHub
on:
push:
branches:
- '**'
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configure Git
run: |
git config --global user.name "Andrew Sync"
git config --global user.email "sync@digitaladapt.com"
- name: Add GitHub Remote
env:
SYNC_TOKEN: ${{ secrets.SYNC_GITHUB_TOKEN }}
SYNC_TARGET: ${{ vars.SYNC_GITHUB_TARGET }}
run: |
git remote add github "https://digitaladapt:${SYNC_TOKEN}@github.com/$SYNC_TARGET"
- name: Push Current Branch
run: |
git push github HEAD:${GITHUB_REF_NAME}
- name: Push Tags
run: |
git push github --tags
+238
View File
@@ -0,0 +1,238 @@
# Script Review Notes - Improvements & Observations
**Branch:** `review-improvements`
**Date:** 2026-07-20
---
## 📋 Summary Table
| File | Lines | Type | Overall Rating | Key Issues |
|------|-------|------|----------------|------------|
| `4-private-ip.sh` | 6 | Simple | ⭐⭐⭐⭐ | Minor - uses deprecated shell syntax |
| `4-public-ip.sh` | 44 | IP Lookup | ⭐⭐⭐⭐ | Medium - fallback order could be optimized |
| `6-public-ip.sh` | 47 | IPv6 Lookup | ⭐⭐⭐⭐ | Medium - similar to IPv4, duplicated code |
| `cloudflare.sh` | 253 | API Wrapper | ⭐⭐⭐ | High - security concerns with tokens in args |
| `discord.sh` | 242 | Discord Sender | ⭐⭐⭐⭐ | Low - well documented, minor tweaks needed |
| `git-prompt.sh` | 672 | Git Prompt | ⭐⭐⭐ | Medium - large file, some edge cases |
| `Dynv6.ps1` | 145 | Powershell DDNS | ⭐⭐⭐⭐ | Low - clean PowerShell code |
| `delay.sh` | 20 | Utility | ⭐⭐ | High - uses `bc`, poor error handling |
| `df.sh` | 13 | Wrapper | ⭐⭐⭐⭐ | Medium - relies on external script |
| `domain-check.sh` | 49 | DNS Checker | ⭐⭐⭐ | Medium - regex fragile, missing error handling |
| `dynv6.sh` | 114 | Bash DDNS | ⭐⭐⭐ | Medium - backticks vs `$()` inconsistency |
| `fetch-all.sh` | 52 | Git Fetch | ⭐⭐⭐⭐ | Low - clean and functional |
| `list-all.sh` | 52 | Git List | ⭐⭐⭐⭐ | Low - mirror of fetch-all.sh |
| `pull-all.sh` | 52 | Git Pull | ⭐⭐⭐⭐ | Medium - could check branch upstream first |
| `status-all.sh` | 110 | Git Status | ⭐⭐⭐ | High - complex regex matching, colors hardcoded |
| `upgrade.sh` | 21 | System Upgrade | ⭐⭐ | High - runs as root by default, no dry-run |
| `thermal.sh` | 48 | Thermal Monitor | ⭐⭐⭐ | Medium - assumes `/sys/thermal/*` exists |
| `ssh-ident` | 1029 | SSH Manager | ⭐⭐⭐ | Medium - Python-heavy, dependencies |
---
## 📝 Detailed Notes by File
### IP & Network Tools
#### `4-private-ip.sh`
```bash
ip -4 addr list scope global | sed -n 's/.*inet \([0-9\.]\+\).*/\1/p' | head -n 1
```
**Observations:**
- ✅ Very concise and functional
- ⚠️ Uses `sed` with regex that may fail on some edge cases
- ⚠️ Comments out alternative (longer) method without explanation
**Suggestions:**
1. Add a fallback using `/usr/sbin/ip6tables` or similar as backup
2. Consider: `ip -4 addr show | awk '/inet / {print $2; exit}'`
3. Remove commented-out code with note
---
#### `4-public-ip.sh` & `6-public-ip.sh`
**Observations:**
- ✅ Good fallback chain (dig → curl → wget)
- ⚠️ Uses `-4` flag consistently but no graceful degradation if all fail
- ⚠️ Error messages could be more descriptive
**Suggestions:**
1. Add timeout to curl/wget calls: `curl --connect-timeout 5 ...`
2. Consider caching the last known IP with TTL
3. Add metrics/counter for success rate
4. In `6-public-ip.sh`, consider using both IPv4 and IPv6 APIs simultaneously
---
### API & Service Integration
#### `cloudflare.sh`
**Observations:**
- ✅ Handles `-c`, `-f`, `-q`, `-t` flags well
- ⚠️ **Security**: Token/zone defaults loaded from config, but overrides via positional args
- ⚠️ Large file (253 lines) - could be modularized
**Suggestions:**
1. Add `--dry-run` flag for testing before commits
2. Consider storing the resolved IP in a temp file to avoid repeated lookups
3. Add retry logic with exponential backoff for failed API calls
4. Parse JSON response more robustly using `jq --argjson ...` pattern
---
#### `discord.sh`
**Observations:**
- ✅ Excellent color palette support
- ✅ Handles message splitting for long messages
- ⚠️ ANSI escape codes embedded in strings may need escaping
**Suggestions:**
1. Consider creating a helper function to build the JSON payload
2. Add optional rate-limit header handling (`--wait=true`)
3. Log retry attempts if webhook fails
---
### Git Utilities
#### `fetch-all.sh`, `list-all.sh`, `pull-all.sh`
**Observations:**
- ✅ Clean, consistent patterns
- ⚠️ `-l` flag description says "follow symbolic links" but sets `-H` (which is actually "follow hardlinks only")
- ⚠️ `checkHidden` uses glob pattern that may not work as expected
**Suggestions:**
1. Fix help text: `-L = follow symlinks`, `-H = follow hardlinks`
2. Consider adding option to exclude specific paths
3. Add progress bar or counter for large repo counts
---
#### `status-all.sh`
**Observations:**
- ✅ Very detailed status reporting with colors
- ⚠️ Complex regex matching against git output - fragile across versions
- ⚠️ Colors hardcoded as escape sequences
**Suggestions:**
1. Use `GIT_PS1_SHOWCOLORHINTS` env var to toggle color rendering
2. Extract common status patterns into variables/regex constants
3. Add option for "quiet" or "verbose" output modes
---
### System & Hardware Tools
#### `upgrade.sh`
**Observations:**
- ⚠️ Runs apt commands as root immediately
- ⚠️ No dry-run mode to preview changes
- ⚠️ Could lock filesystem during update
**Suggestions:**
1. Add `--dry-run` flag that just updates without installing
2. Wrap in flock: `flock -n /var/lock/apt.lock apt update ...`
3. Create pre/post hooks directory for custom steps
4. Report disk space usage before/after
---
#### `thermal.sh`
**Observations:**
- ✅ Clean temperature reading loop
- ⚠️ Assumes `/sys/class/thermal/*/* -path '*/thermal_*' -name 'temp'` structure
**Suggestions:**
1. Add graceful handling for systems without thermal sensors
2. Consider configurable alert thresholds per zone
3. Add optional Discord/Pushover notification on alert
---
### Utilities
#### `delay.sh`
```bash
for i in $(seq 1 50); do sleep "${slice}"; echo -n '.'; done
```
**Observations:**
- ⚠️ Requires `bc` for floating-point math (not always available)
- ⚠️ Output dots could be suppressed with flag
- ⚠️ Default range of 1-60 seconds is arbitrary
**Suggestions:**
1. Add `--no-output` flag
2. Consider using pure bash arithmetic: `sleep $(awk "BEGIN {printf \"%.3f\", $seconds/50}")`
3. Add support for millisecond precision
---
#### `dynv6.sh`
**Observations:**
- ✅ Modular design with scope/device options
- ⚠️ Uses backticks instead of `$()` (legacy style)
- ⚠️ Error handling minimal
**Suggestions:**
1. Convert to `$()` for POSIX compliance
2. Add `--test-mode` that validates credentials without updating
3. Consider storing last IP in config file for trend analysis
---
### Large/Complex Files
#### `git-prompt.sh` (672 lines)
- ✅ Feature-rich prompt customization
- ⚠️ Requires careful review due to length
- ⚠e Many conditional branches with edge cases
**Quick Wins:**
1. Consider extracting sub-functions into separate files
2. Add unit tests for key functions
3. Document what each environment variable does
---
#### `ssh-ident` (1029 lines - Python)
- ✅ Sophisticated SSH agent management
- ⚠️ Requires Python 2.6+ (very broad compatibility)
- ⚠️ Large monolithic file
**Suggestions:**
1. Consider packaging as standalone module
2. Add `--config-file` override for testing
3. Document batch mode behavior more clearly
---
## 🎯 Priority Improvements
### High Priority (Security/Reliability)
1. **cloudflare.sh**: Add timeout and retry logic to API calls
2. **upgrade.sh**: Implement dry-run and file locking
3. All IP lookup scripts: Add timeouts and fallback chains
### Medium Priority (Maintainability)
4. Convert `dynv6.sh` backticks to `$()` syntax
5. Extract common patterns from git-* utilities
6. Add unit tests for critical functions
### Low Priority (Nice-to-Have)
7. Create shared base classes/modules for IP lookups
8. Add logging framework across all scripts
9. Consider creating a "master" config file template
---
## 📦 Files to Investigate Further
- `ssh-ident` - Check Python version requirements in production
- `git-prompt.sh` - Verify compatibility with modern git versions
- `cloudflare.sh` - Test error handling for rate-limited responses
---
*Generated on branch: review-improvements*
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
set -euo pipefail
notify() {
local color="$1"
local msg="$2"
local hostname=$(hostname)
echo "$msg"
ntfy pub -T "${color}_square" -t "Docker Health on ${hostname}" docker "$msg" >/dev/null 2>&1 || true
}
declare -A compose_projects
declare -a standalone_containers
# Find unhealthy containers
while read -r container; do
health=$(docker inspect \
--format '{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' \
"$container")
# Ignore missing health checks and containers still starting
if [[ "$health" != "unhealthy" ]]; then
continue
fi
project_dir=$(docker inspect \
--format '{{index .Config.Labels "com.docker.compose.project.working_dir"}}' \
"$container")
if [[ -n "$project_dir" && "$project_dir" != "<no value>" ]]; then
compose_projects["$project_dir"]+="$container "
else
standalone_containers+=("$container")
fi
done < <(docker ps -q)
# Restart compose projects once each
for project_dir in "${!compose_projects[@]}"; do
containers="${compose_projects[$project_dir]}"
notify "orange" "Unhealthy containers in $(basename "$project_dir"): $containers"
if [[ -f "$project_dir/compose.yaml" ]]; then
if docker compose \
--project-directory "$project_dir" \
up -d --force-recreate; then
notify "green" "Recovery succeeded: $(basename "$project_dir")"
else
notify "red" "Recovery FAILED: $(basename "$project_dir")"
fi
else
notify "black" "Missing compose.yaml in $project_dir"
fi
done
# Restart standalone containers
for container in "${standalone_containers[@]}"; do
notify "orange" "Unhealthy standalone container $container"
if docker restart "$container" >/dev/null; then
notify "green" "Recovery succeeded: $container"
else
notify "red" "Recovery FAILED: $container"
fi
done
Executable
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
# perform a "docker compose pull" on each location specified (recursively), or current location if none specified.
#
# will only search symbolic links when passed "-l" option, must be before any locations
# will only search hidden directories when passed "-h" option, must be before any locations
# pull-all.sh [-l][-h] # current location implied
# pull-all.sh [-l][-h] ~/my-projects /var/group-projects
# check for "-l" and "-h" in command prompt
followLinks="-H"
checkHidden="*/.*/*compose.yaml"
while getopts "lh" option; do
case $option in
l)
followLinks="-L"
;;
h)
checkHidden=""
;;
esac
done
shift "$((OPTIND-1))"
if [[ "-H" == "$followLinks" ]]; then
echo "use -l to follow symbolic links"
fi
if [[ -n "$checkHidden" ]]; then
echo "use -h to check hidden directories"
fi
# function to process each location
function process_docker_pull () {
startedIn=`pwd`
location=$(realpath $(dirname "$@"))
line="--- --- --- --- --- --- --- --- ---"
# use "--" to tell printf there are no more commands, only strings to print
printf -- "--- docker compose pull %s %s ---\n" "$location" "${line:${#location}}"
cd "$location"
# populate $runningServices[]
mapfile -t runningServices < <(
docker compose ps --services --status running
)
quietDocker=$(docker compose pull --ignore-buildable --ignore-pull-failures)
if docker compose up -d --dry-run | grep -q "Recreate"; then
# Only restart services that were already running
if ((${#runningServices[@]} > 0)); then
echo "restarting the following services: ${runningServices[@]}"
quietDocker=$(docker compose up -d "${runningServices[@]}")
else
echo "updates downloaded, no services were running"
fi
else
messageSuffix=""
if ((${#runningServices[@]} > 0)); then
messageSuffix=", services already current: ${runningServices[@]}"
fi
echo "no changes detected$messageSuffix"
fi
cd "$startedIn"
}
# find all folders named ".git" under given locations,
# and call process_git_pull on each location that was found.
# we then work on the folder that contained the ".git" folder.
find "$followLinks" "$@" -type f \( -name 'compose.yaml' -o -name 'docker-compose.yaml' \) -not -path "$checkHidden" | sort | while read -r file; do process_docker_pull "$file"; done
+6
View File
@@ -66,6 +66,12 @@ Plug 'airblade/vim-gitgutter'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
" twig support (php templating)
Plug 'lumiliet/vim-twig'
" AnsiEsc to make editing colorful files better
Plug 'powerman/vim-plugin-AnsiEsc'
call plug#end()
" config git-gutter