first commit
This commit is contained in:
142
BadAI/badai
Normal file
142
BadAI/badai
Normal file
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env bash
|
||||
# DuckAI command-line tool
|
||||
# Usage: duckai restart [--sleep N]
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
sleep_time=3 # Default sleep time in seconds
|
||||
|
||||
# Parse arguments
|
||||
if [[ "$1" == "restart" ]]; then
|
||||
name=""
|
||||
if [[ "$2" == "--sleep" && -n "$3" && "$3" =~ ^[0-9]+$ ]]; then
|
||||
sleep_time="$3"
|
||||
name="$4"
|
||||
elif [[ -n "$2" ]]; then
|
||||
name="$2"
|
||||
fi
|
||||
|
||||
echo "Reloading systemd user daemon..."
|
||||
systemctl --user daemon-reload
|
||||
|
||||
if [[ -n "$name" ]]; then
|
||||
# Riavvia servizio specifico
|
||||
# Cerca container
|
||||
container_file=""
|
||||
for file in ~/.config/containers/systemd/*.container; do
|
||||
if [[ -f "$file" ]]; then
|
||||
if [[ "$(basename "$file")" =~ ^99_ ]]; then continue; fi
|
||||
service_name=$(basename "$file" .container)
|
||||
display_name=$(echo "$service_name" | sed 's/^[0-9]*_//')
|
||||
if [[ "$display_name" == "$name" ]]; then
|
||||
container_file="$file"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [[ -n "$container_file" ]]; then
|
||||
service_name=$(basename "$container_file" .container)
|
||||
echo "Restarting container $name..."
|
||||
if systemctl --user restart "$service_name" 2>/dev/null; then
|
||||
echo " ✓ $name restarted successfully"
|
||||
else
|
||||
echo " ✗ Failed to restart $name"
|
||||
fi
|
||||
else
|
||||
# Cerca network
|
||||
network_file=""
|
||||
for file in ~/.config/containers/systemd/*.network; do
|
||||
if [[ -f "$file" ]]; then
|
||||
if [[ "$(basename "$file")" =~ ^99_ ]]; then continue; fi
|
||||
service_name=$(basename "$file" .network)-network
|
||||
display_name=$(echo "$service_name" | sed 's/^[0-9]*_//')
|
||||
if [[ "$display_name" == "$name" ]]; then
|
||||
network_file="$file"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [[ -n "$network_file" ]]; then
|
||||
service_name=$(basename "$network_file" .network)-network
|
||||
echo "Restarting network $name..."
|
||||
if systemctl --user try-restart "$service_name" 2>/dev/null || systemctl --user start "$service_name" 2>/dev/null; then
|
||||
echo " ✓ $name restarted successfully"
|
||||
else
|
||||
echo " ✗ Failed to restart $name"
|
||||
fi
|
||||
else
|
||||
echo "Service $name not found."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# Riavvia nginx
|
||||
nginx_file=""
|
||||
for file in ~/.config/containers/systemd/*nginx*.container; do
|
||||
if [[ -f "$file" ]]; then
|
||||
nginx_file="$file"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ -n "$nginx_file" ]]; then
|
||||
service_name=$(basename "$nginx_file" .container)
|
||||
echo "Restarting nginx..."
|
||||
if systemctl --user restart "$service_name" 2>/dev/null; then
|
||||
echo " ✓ nginx restarted successfully"
|
||||
else
|
||||
echo " ✗ Failed to restart nginx"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Riavvia tutti
|
||||
echo "Restarting all quadlet networks..."
|
||||
for file in ~/.config/containers/systemd/*.network; do
|
||||
if [[ -f "$file" ]]; then
|
||||
if [[ "$(basename "$file")" =~ ^99_ ]]; then continue; fi
|
||||
service_name=$(basename "$file" .network)-network
|
||||
display_name=$(echo "$service_name" | sed 's/^[0-9]*_//')
|
||||
echo "Restarting $display_name..."
|
||||
if systemctl --user try-restart "$service_name" 2>/dev/null || systemctl --user start "$service_name" 2>/dev/null; then
|
||||
echo " ✓ $display_name restarted successfully"
|
||||
else
|
||||
echo " ✗ Failed to restart $display_name"
|
||||
fi
|
||||
sleep "$sleep_time"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Restarting all quadlet containers..."
|
||||
for file in ~/.config/containers/systemd/*.container; do
|
||||
if [[ -f "$file" ]]; then
|
||||
if [[ "$(basename "$file")" =~ ^99_ ]]; then continue; fi
|
||||
service_name=$(basename "$file" .container)
|
||||
display_name=$(echo "$service_name" | sed 's/^[0-9]*_//')
|
||||
echo "Restarting $display_name..."
|
||||
if systemctl --user restart "$service_name" 2>/dev/null; then
|
||||
echo " ✓ $display_name restarted successfully"
|
||||
else
|
||||
echo " ✗ Failed to restart $display_name"
|
||||
fi
|
||||
sleep "$sleep_time"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "All services restarted successfully."
|
||||
fi
|
||||
elif [[ "$1" == "help" || -z "$1" ]]; then
|
||||
cat <<'EOF'
|
||||
D U C K A I - C O M M A N D L I N E
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Usage: duckai <command> [options]
|
||||
|
||||
Commands:
|
||||
restart [--sleep N] [name] Restart all quadlet containers and networks, or a specific one by name (without prefix), reload systemd user daemon
|
||||
help Show this help message
|
||||
|
||||
Options:
|
||||
--sleep N Sleep N seconds between restarts (default: 3)
|
||||
EOF
|
||||
else
|
||||
echo "Unknown command: $1"
|
||||
echo "Use 'duckai help' for usage."
|
||||
fi
|
||||
213
BadAI/badai.go
Normal file
213
BadAI/badai.go
Normal file
@@ -0,0 +1,213 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
printHelp()
|
||||
return
|
||||
}
|
||||
|
||||
command := os.Args[1]
|
||||
|
||||
switch command {
|
||||
case "restart":
|
||||
name := ""
|
||||
if len(os.Args) > 2 {
|
||||
if os.Args[2] == "--sleep" && len(os.Args) > 3 {
|
||||
// Ignora per ora, ma in handleRestart parsare
|
||||
} else {
|
||||
name = os.Args[2]
|
||||
}
|
||||
}
|
||||
handleRestart(name)
|
||||
case "help":
|
||||
printHelp()
|
||||
default:
|
||||
fmt.Printf("Unknown command: %s\n", command)
|
||||
fmt.Println("Use 'duckai help' for usage.")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func handleRestart(name string) {
|
||||
sleepTime := 3
|
||||
args := os.Args[2:]
|
||||
if len(args) > 0 && args[0] == "--sleep" && len(args) > 1 {
|
||||
if s, err := strconv.Atoi(args[1]); err == nil {
|
||||
sleepTime = s
|
||||
}
|
||||
if len(args) > 2 {
|
||||
name = args[2]
|
||||
}
|
||||
} else if name == "" && len(args) > 0 {
|
||||
name = args[0]
|
||||
}
|
||||
|
||||
fmt.Println("Reloading systemd user daemon...")
|
||||
runCommand("systemctl", "--user", "daemon-reload")
|
||||
|
||||
if name != "" {
|
||||
// Riavvia servizio specifico
|
||||
containerFile := findServiceFile("*.container", name)
|
||||
if containerFile != "" {
|
||||
serviceName := strings.TrimSuffix(filepath.Base(containerFile), ".container")
|
||||
fmt.Printf("Restarting container %s...\n", name)
|
||||
if runCommand("systemctl", "--user", "restart", serviceName) {
|
||||
fmt.Printf(" ✓ %s restarted successfully\n", name)
|
||||
} else {
|
||||
fmt.Printf(" ✗ Failed to restart %s\n", name)
|
||||
}
|
||||
} else {
|
||||
networkFile := findServiceFile("*.network", name)
|
||||
if networkFile != "" {
|
||||
serviceName := strings.TrimSuffix(filepath.Base(networkFile), ".network") + "-network"
|
||||
fmt.Printf("Restarting network %s...\n", name)
|
||||
if runCommand("systemctl", "--user", "try-restart", serviceName) || runCommand("systemctl", "--user", "start", serviceName) {
|
||||
fmt.Printf(" ✓ %s restarted successfully\n", name)
|
||||
} else {
|
||||
fmt.Printf(" ✗ Failed to restart %s\n", name)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("Service %s not found.\n", name)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
// Riavvia nginx
|
||||
restartNginx()
|
||||
} else {
|
||||
fmt.Println("Restarting all quadlet networks...")
|
||||
restartNetworks(sleepTime)
|
||||
|
||||
fmt.Println("Restarting all quadlet containers...")
|
||||
restartContainers(sleepTime)
|
||||
|
||||
fmt.Println("All services restarted successfully.")
|
||||
}
|
||||
}
|
||||
|
||||
func findServiceFile(pattern, name string) string {
|
||||
home, _ := os.UserHomeDir()
|
||||
dir := filepath.Join(home, ".config", "containers", "systemd")
|
||||
files, _ := filepath.Glob(filepath.Join(dir, pattern))
|
||||
re := regexp.MustCompile(`^[0-9]+_`)
|
||||
for _, file := range files {
|
||||
if strings.HasPrefix(filepath.Base(file), "99_") {
|
||||
continue
|
||||
}
|
||||
serviceName := strings.TrimSuffix(filepath.Base(file), filepath.Ext(file))
|
||||
if pattern == "*.network" {
|
||||
serviceName += "-network"
|
||||
}
|
||||
displayName := re.ReplaceAllString(serviceName, "")
|
||||
if displayName == name {
|
||||
return file
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
home, _ := os.UserHomeDir()
|
||||
dir := filepath.Join(home, ".config", "containers", "systemd")
|
||||
files, _ := filepath.Glob(filepath.Join(dir, pattern))
|
||||
re := regexp.MustCompile(`^[0-9]+_`)
|
||||
for _, file := range files {
|
||||
if strings.HasPrefix(filepath.Base(file), "99_") {
|
||||
continue
|
||||
}
|
||||
serviceName := strings.TrimSuffix(filepath.Base(file), filepath.Ext(file))
|
||||
if pattern == "*.network" {
|
||||
serviceName += "-network"
|
||||
}
|
||||
displayName := re.ReplaceAllString(serviceName, "")
|
||||
if displayName == name {
|
||||
return file
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func restartNetworks(sleepTime int) {
|
||||
home, _ := os.UserHomeDir()
|
||||
dir := filepath.Join(home, ".config", "containers", "systemd")
|
||||
files, _ := filepath.Glob(filepath.Join(dir, "*.network"))
|
||||
re := regexp.MustCompile(`^[0-9]+_`)
|
||||
for _, file := range files {
|
||||
if strings.HasPrefix(filepath.Base(file), "99_") {
|
||||
continue
|
||||
}
|
||||
serviceName := strings.TrimSuffix(filepath.Base(file), ".network") + "-network"
|
||||
displayName := re.ReplaceAllString(serviceName, "")
|
||||
fmt.Printf("Restarting %s...\n", displayName)
|
||||
if runCommand("systemctl", "--user", "try-restart", serviceName) || runCommand("systemctl", "--user", "start", serviceName) {
|
||||
fmt.Printf(" ✓ %s restarted successfully\n", displayName)
|
||||
} else {
|
||||
fmt.Printf(" ✗ Failed to restart %s\n", displayName)
|
||||
}
|
||||
time.Sleep(time.Duration(sleepTime) * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func restartContainers(sleepTime int) {
|
||||
home, _ := os.UserHomeDir()
|
||||
dir := filepath.Join(home, ".config", "containers", "systemd")
|
||||
files, _ := filepath.Glob(filepath.Join(dir, "*.container"))
|
||||
re := regexp.MustCompile(`^[0-9]+_`)
|
||||
for _, file := range files {
|
||||
if strings.HasPrefix(filepath.Base(file), "99_") {
|
||||
continue
|
||||
}
|
||||
serviceName := strings.TrimSuffix(filepath.Base(file), ".container")
|
||||
displayName := re.ReplaceAllString(serviceName, "")
|
||||
fmt.Printf("Restarting %s...\n", displayName)
|
||||
if runCommand("systemctl", "--user", "restart", serviceName) {
|
||||
fmt.Printf(" ✓ %s restarted successfully\n", displayName)
|
||||
} else {
|
||||
fmt.Printf(" ✗ Failed to restart %s\n", displayName)
|
||||
}
|
||||
time.Sleep(time.Duration(sleepTime) * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func restartNginx() {
|
||||
home, _ := os.UserHomeDir()
|
||||
dir := filepath.Join(home, ".config", "containers", "systemd")
|
||||
files, _ := filepath.Glob(filepath.Join(dir, "*nginx*.container"))
|
||||
if len(files) > 0 {
|
||||
serviceName := strings.TrimSuffix(filepath.Base(files[0]), ".container")
|
||||
fmt.Println("Restarting nginx...")
|
||||
if runCommand("systemctl", "--user", "restart", serviceName) {
|
||||
fmt.Println(" ✓ nginx restarted successfully")
|
||||
} else {
|
||||
fmt.Println(" ✗ Failed to restart nginx")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func runCommand(name string, args ...string) bool {
|
||||
cmd := exec.Command(name, args...)
|
||||
err := cmd.Run()
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func printHelp() {
|
||||
fmt.Println(`D U C K A I - C O M M A N D L I N E
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Usage: duckai <command> [options]
|
||||
|
||||
Commands:
|
||||
restart [--sleep N] [name] Restart all quadlet containers and networks, or a specific one by name (without prefix), reload systemd user daemon
|
||||
help Show this help message
|
||||
|
||||
Options:
|
||||
--sleep N Sleep N seconds between restarts (default: 3)`)
|
||||
}
|
||||
100
BadAI/banner.sh
Normal file
100
BadAI/banner.sh
Normal file
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env bash
|
||||
# Lightweight banner for BadAI host system — Ubuntu with AMDGPU drivers
|
||||
|
||||
oem_info() {
|
||||
local v="" m="" d lv lm
|
||||
for d in /sys/class/dmi/id /sys/devices/virtual/dmi/id; do
|
||||
[[ -r "$d/sys_vendor" ]] && v=$(<"$d/sys_vendor")
|
||||
[[ -r "$d/product_name" ]] && m=$(<"$d/product_name")
|
||||
[[ -n "$v" || -n "$m" ]] && break
|
||||
done
|
||||
# ARM/SBC fallback
|
||||
if [[ -z "$v" && -z "$m" && -r /proc/device-tree/model ]]; then
|
||||
tr -d '\0' </proc/device-tree/model
|
||||
return
|
||||
fi
|
||||
lv=$(printf '%s' "$v" | tr '[:upper:]' '[:lower:]')
|
||||
lm=$(printf '%s' "$m" | tr '[:upper:]' '[:lower:]')
|
||||
if [[ -n "$m" && "$lm" == "$lv "* ]]; then
|
||||
printf '%s\n' "$m"
|
||||
else
|
||||
printf '%s %s\n' "${v:-Unknown}" "${m:-Unknown}"
|
||||
fi
|
||||
}
|
||||
|
||||
gpu_name() {
|
||||
local name=""
|
||||
if command -v lspci >/dev/null 2>&1; then
|
||||
name=$(lspci -nn 2>/dev/null | grep -Ei 'vga|display|gpu' | grep -i amd | head -n1 | cut -d: -f3-)
|
||||
fi
|
||||
name=$(printf '%s' "$name" | sed -e 's/^[[:space:]]\+//' -e 's/[[:space:]]\+$//' -e 's/[[:space:]]\{2,\}/ /g')
|
||||
printf '%s\n' "${name:-Unknown AMD GPU}"
|
||||
}
|
||||
|
||||
ubuntu_version() {
|
||||
lsb_release -d 2>/dev/null | cut -f2 || uname -a
|
||||
}
|
||||
|
||||
system_load() {
|
||||
uptime | awk -F'load average:' '{ print $2 }' | sed 's/,//g'
|
||||
}
|
||||
|
||||
memory_usage() {
|
||||
free -h | awk 'NR==2{printf "%.0f%%", $3*100/$2 }'
|
||||
}
|
||||
|
||||
updates_info() {
|
||||
if command -v apt >/dev/null 2>&1; then
|
||||
local upgradable=$(apt list --upgradable 2>/dev/null | grep -v '^Listing' | grep -c '^[^/]*$')
|
||||
local security=$(apt list --upgradable 2>/dev/null | grep -c 'security')
|
||||
printf '%d updates can be applied immediately.\n' "$upgradable"
|
||||
if [[ $security -gt 0 ]]; then
|
||||
printf '%d additional security updates can be applied.\n' "$security"
|
||||
fi
|
||||
else
|
||||
printf 'Updates info not available.\n'
|
||||
fi
|
||||
}
|
||||
|
||||
MACHINE="$(oem_info)"
|
||||
GPU="$(gpu_name)"
|
||||
UBUNTU_VER="$(ubuntu_version)"
|
||||
LOAD="$(system_load)"
|
||||
MEM="$(memory_usage)"
|
||||
|
||||
echo
|
||||
cat <<'ASCII'
|
||||
|
||||
__________ .___ _____ .___
|
||||
\______ \_____ __| _/ / _ \ | |
|
||||
| | _/\__ \ / __ | / /_\ \| |
|
||||
| | \ / __ \_/ /_/ | / | \ |
|
||||
|______ /(____ /\____ | \____|__ /___|
|
||||
\/ \/ \/ \/
|
||||
|
||||
|
||||
B A D A I - H O S T ( U B U N T U , A M D G P U )
|
||||
|
||||
ASCII
|
||||
|
||||
echo "--------------------------------------------------------------------------------"
|
||||
printf 'Machine: %s\n' "$MACHINE"
|
||||
printf 'GPU : %s\n' "$GPU"
|
||||
printf 'OS : %s\n' "$UBUNTU_VER"
|
||||
printf 'Load : %s\n' "$LOAD"
|
||||
printf 'Memory : %s\n' "$MEM"
|
||||
|
||||
echo
|
||||
echo "--------------------------------------------------------------------------------"
|
||||
updates_info
|
||||
|
||||
echo
|
||||
echo "--------------------------------------------------------------------------------"
|
||||
printf 'Usage:\n'
|
||||
printf ' - %-24s → %s\n' "podman ps" "List running containers"
|
||||
printf ' - %-24s → %s\n' "podman logs <name>" "View container logs"
|
||||
printf ' - %-24s → %s\n' "podman exec -it <name> bash" "Access container shell"
|
||||
printf ' - %-24s → %s\n' "radentop" "Monitor AMD GPU usage (if installed)"
|
||||
printf ' - %-24s → %s\n' "htop" "Monitor system processes and resources"
|
||||
printf ' - %-24s → %s\n' "duckai restart" "Restart all services"
|
||||
printf ' - %-24s → %s\n' "duckai help" "Show DuckAI commands"
|
||||
Reference in New Issue
Block a user