thinknagent 0.1.20 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/thinknagent.sh DELETED
@@ -1,554 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ==============================================================================
3
- # ThinkNCollab Standalone Server Agent (thinknagent.sh)
4
- # Zero-dependency universal bash agent for Linux and macOS.
5
- # ==============================================================================
6
-
7
- set -eo pipefail
8
-
9
- if [[ -n "$SUDO_USER" ]]; then
10
- USER_HOME=$(getent passwd "$SUDO_USER" 2>/dev/null | cut -d: -f6 || eval echo "~$SUDO_USER")
11
- if [[ -f "${USER_HOME}/.thinknagent/config.json" ]]; then
12
- CONFIG_DIR="${USER_HOME}/.thinknagent"
13
- else
14
- CONFIG_DIR="${HOME}/.thinknagent"
15
- fi
16
- else
17
- CONFIG_DIR="${HOME}/.thinknagent"
18
- fi
19
-
20
- CONFIG_FILE="${CONFIG_DIR}/config.json"
21
- PID_FILE="${CONFIG_DIR}/agent.pid"
22
-
23
- mkdir -p "$CONFIG_DIR" 2>/dev/null || true
24
-
25
- # ── Colors & Helpers ──────────────────────────────────────────────────────────
26
- RED='\033[0;31m'
27
- GREEN='\033[0;32m'
28
- YELLOW='\033[1;33m'
29
- BLUE='\033[0;34m'
30
- NC='\033[0m'
31
-
32
- log_info() { echo -e "${BLUE}[thinknagent]${NC} $1"; }
33
- log_ok() { echo -e "${GREEN}[thinknagent]${NC} $1"; }
34
- log_warn() { echo -e "${YELLOW}[thinknagent]${NC} $1"; }
35
- log_err() { echo -e "${RED}[thinknagent] ERROR:${NC} $1"; }
36
-
37
- get_json_val() {
38
- local key="$1"
39
- if [[ -f "$CONFIG_FILE" ]]; then
40
- grep -o "\"$key\": *\"[^\"]*\"" "$CONFIG_FILE" | head -n1 | cut -d'"' -f4 || echo ""
41
- else
42
- echo ""
43
- fi
44
- }
45
-
46
- save_config() {
47
- local server="$1"
48
- local name="$2"
49
- local room="$3"
50
- local agentId="$4"
51
- local token="$5"
52
- local status="$6"
53
-
54
- cat > "$CONFIG_FILE" << EOF
55
- {
56
- "serverUrl": "$server",
57
- "name": "$name",
58
- "roomId": "$room",
59
- "agentId": "$agentId",
60
- "agentToken": "$token",
61
- "status": "$status",
62
- "updatedAt": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
63
- }
64
- EOF
65
- chmod 600 "$CONFIG_FILE"
66
- }
67
-
68
- # ── Metric Collectors (Native Linux / macOS) ──────────────────────────────────
69
- get_cpu_usage() {
70
- if [[ -f /proc/stat ]]; then
71
- read -r cpu user nice system idle iowait irq softirq steal guest guest_nice < /proc/stat
72
- local prev_idle=$idle
73
- local prev_total=$((user + nice + system + idle + iowait + irq + softirq + steal))
74
- sleep 0.5
75
- read -r cpu user nice system idle iowait irq softirq steal guest guest_nice < /proc/stat
76
- local idle_diff=$((idle - prev_idle))
77
- local total_diff=$(((user + nice + system + idle + iowait + irq + softirq + steal) - prev_total))
78
- if [[ $total_diff -gt 0 ]]; then
79
- awk "BEGIN {printf \"%.1f\", (1 - ($idle_diff / $total_diff)) * 100}"
80
- else
81
- echo "0.0"
82
- fi
83
- else
84
- ps -A -o %cpu | awk '{s+=$1} END {printf "%.1f", s}'
85
- fi
86
- }
87
-
88
- get_mem_info() {
89
- if [[ -f /proc/meminfo ]]; then
90
- local total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
91
- local free=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
92
- local used=$((total - free))
93
- local pct=$(awk "BEGIN {printf \"%.1f\", ($used / $total) * 100}")
94
- local total_bytes=$((total * 1024))
95
- local used_bytes=$((used * 1024))
96
- local free_bytes=$((free * 1024))
97
- echo "{\"total\": $total_bytes, \"used\": $used_bytes, \"free\": $free_bytes, \"usedPct\": $pct}"
98
- else
99
- echo "{\"total\": 17179869184, \"used\": 8589934592, \"free\": 8589934592, \"usedPct\": 50.0}"
100
- fi
101
- }
102
-
103
- get_cores() {
104
- if [[ -f /proc/cpuinfo ]]; then
105
- grep -c ^processor /proc/cpuinfo
106
- else
107
- sysctl -n hw.ncpu 2>/dev/null || echo "2"
108
- fi
109
- }
110
-
111
- get_load_avg() {
112
- if [[ -f /proc/loadavg ]]; then
113
- awk '{print $1}' /proc/loadavg
114
- else
115
- uptime | awk -F'load averages?: ' '{print $2}' | awk '{print $1}' | tr -d ',' || echo "0.0"
116
- fi
117
- }
118
-
119
- get_top_procs() {
120
- local procs_json="[]"
121
- if command -v ps >/dev/null 2>&1; then
122
- local list=$(ps -eo pid,pcpu,pmem,comm --sort=-pcpu 2>/dev/null | head -n 6 | tail -n 5 || ps -eo pid,%cpu,%mem,comm | head -n 6 | tail -n 5)
123
- local items=()
124
- while read -r pid cpu mem comm; do
125
- if [[ -n "$pid" && "$pid" != "PID" ]]; then
126
- items+=("{\"pid\": $pid, \"name\": \"$comm\", \"cpu\": $cpu, \"mem\": $mem}")
127
- fi
128
- done <<< "$list"
129
- local IFS=","
130
- procs_json="[${items[*]}]"
131
- fi
132
- echo "$procs_json"
133
- }
134
-
135
- get_disks() {
136
- local disk_items=()
137
- while read -r fs size used avail pct mount; do
138
- if [[ "$fs" != "Filesystem" && -n "$size" && "$size" =~ ^[0-9]+$ ]]; then
139
- local size_b=$((size * 1024))
140
- local used_b=$((used * 1024))
141
- local pct_num=$(echo "$pct" | tr -d '%')
142
- disk_items+=("{\"fs\": \"$fs\", \"mount\": \"$mount\", \"size\": $size_b, \"used\": $used_b, \"usedPct\": $pct_num}")
143
- fi
144
- done < <(df -k -P 2>/dev/null | tail -n +2)
145
- local IFS=","
146
- echo "[${disk_items[*]}]"
147
- }
148
-
149
- # ── Commands ──────────────────────────────────────────────────────────────────
150
-
151
- cmd_init() {
152
- local server=""
153
- local name="$(hostname)"
154
- local room=""
155
-
156
- while [[ $# -gt 0 ]]; do
157
- case $1 in
158
- --server) server="$2"; shift 2 ;;
159
- --name) name="$2"; shift 2 ;;
160
- --room) room="$2"; shift 2 ;;
161
- *) shift ;;
162
- esac
163
- done
164
-
165
- if [[ -z "$server" || -z "$room" ]]; then
166
- log_err "Missing arguments. Usage: thinknagent.sh init --server <url> --name <name> --room <roomId>"
167
- exit 1
168
- fi
169
-
170
- local existing_id=$(get_json_val "agentId")
171
- local agentId="${existing_id:-$(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "agent-$RANDOM-$RANDOM")}"
172
-
173
- log_info "Registering server with ThinkNCollab..."
174
- log_info "Server : $server"
175
- log_info "Node Name: $name"
176
- log_info "Room ID : $room"
177
- log_info "Agent ID : $agentId"
178
-
179
- local payload="{\"agentId\":\"$agentId\",\"name\":\"$name\",\"hostname\":\"$(hostname)\",\"version\":\"1.0.0-bash\",\"roomId\":\"$room\"}"
180
-
181
- local res=$(curl -s -X POST "${server}/devops/api/agent/register" \
182
- -H "Content-Type: application/json" \
183
- -d "$payload" || echo '{"error":"Connection failed"}')
184
-
185
- local status=$(echo "$res" | grep -o '"status":"[^"]*"' | cut -d'"' -f4 || echo "pending")
186
- save_config "$server" "$name" "$room" "$agentId" "" "$status"
187
-
188
- echo ""
189
- log_ok "Registration submitted! Status: $(echo "$status" | tr '[:lower:]' '[:upper:]')"
190
- log_info "Approve this server in your Room DevOps Wall: ${server}/devops/${room}"
191
- echo ""
192
- echo "Next step: Run './thinknagent.sh start' or install systemd service with './thinknagent.sh service'"
193
- }
194
-
195
- encrypt_e2ee() {
196
- local plaintext="$1"
197
- local pass="$2"
198
- if command -v openssl >/dev/null 2>&1; then
199
- local enc=$(echo -n "$plaintext" | openssl enc -aes-256-cbc -pbkdf2 -iter 10000 -k "$pass" -base64 -A 2>/dev/null)
200
- if [[ -n "$enc" ]]; then
201
- echo "e2ee:v1:${enc}"
202
- return
203
- fi
204
- fi
205
- echo "$plaintext"
206
- }
207
-
208
- get_logs_json() {
209
- local raw_logs=$(get_json_val "logs")
210
- local room_key=$(get_json_val "roomId")
211
- if [[ -z "$raw_logs" ]]; then
212
- echo "[]"
213
- return
214
- fi
215
- local paths=()
216
- for item in ${raw_logs//,/ }; do
217
- paths+=("$item")
218
- done
219
- local log_items=()
220
- for p in "${paths[@]}"; do
221
- p="${p/#\~/$HOME}"
222
- if [[ -f "$p" ]]; then
223
- local lines_arr=()
224
- while IFS= read -r line || [[ -n "$line" ]]; do
225
- local enc_line=$(encrypt_e2ee "$line" "$room_key")
226
- local clean_line=$(echo "$enc_line" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/ /g' | tr -d '\r')
227
- lines_arr+=("{\"ts\": $(date +%s%3N 2>/dev/null || echo "1724000000000"), \"text\": \"$clean_line\"}")
228
- done < <(tail -n 25 "$p" 2>/dev/null)
229
- local lines_str=$(IFS=,; echo "${lines_arr[*]}")
230
- log_items+=("{\"file\": \"$p\", \"lines\": [$lines_str]}")
231
- fi
232
- done
233
- local IFS=","
234
- echo "[${log_items[*]}]"
235
- }
236
-
237
- cmd_start() {
238
- local server=$(get_json_val "serverUrl")
239
- local agentId=$(get_json_val "agentId")
240
- local room=$(get_json_val "roomId")
241
- local token=$(get_json_val "agentToken")
242
- local name=$(get_json_val "name")
243
-
244
- if [[ -z "$server" || -z "$agentId" ]]; then
245
- log_err "Agent not initialized. Run './thinknagent.sh init --server <url> --name <name> --room <roomId>' first."
246
- exit 1
247
- fi
248
-
249
- log_info "Starting thinknagent telemetry poller (PID: $$)..."
250
- echo "$$" > "$PID_FILE"
251
-
252
- trap 'rm -f "$PID_FILE"; log_info "Agent stopped."; exit 0' SIGINT SIGTERM
253
-
254
- local cores=$(get_cores)
255
-
256
- while true; do
257
- if [[ -z "$token" ]]; then
258
- local status_res=$(curl -s "${server}/devops/api/agent/status/${agentId}" 2>/dev/null || echo '{}')
259
- local status=$(echo "$status_res" | grep -o '"status":"[^"]*"' | cut -d'"' -f4 || echo "")
260
- local new_token=$(echo "$status_res" | grep -o '"token":"[^"]*"' | cut -d'"' -f4 || echo "")
261
-
262
- if [[ "$status" == "approved" && -n "$new_token" ]]; then
263
- token="$new_token"
264
- save_config "$server" "$name" "$room" "$agentId" "$token" "approved"
265
- log_ok "Agent approved by room owner! Token acquired."
266
- else
267
- log_warn "Agent is pending approval in room. Waiting..."
268
- sleep 5
269
- continue
270
- fi
271
- fi
272
-
273
- local cpu=$(get_cpu_usage)
274
- local load=$(get_load_avg)
275
- local mem_json=$(get_mem_info)
276
- local disk_json=$(get_disks)
277
- local proc_json=$(get_top_procs)
278
- local logs_json=$(get_logs_json)
279
-
280
- local payload=$(cat << EOF
281
- {
282
- "agentId": "$agentId",
283
- "token": "$token",
284
- "cpu": { "usage": $cpu, "cores": $cores, "loadAvg": $load },
285
- "memory": $mem_json,
286
- "disk": $disk_json,
287
- "processes": { "total": $(ps -e | wc -l 2>/dev/null || echo "100"), "running": 1, "top": $proc_json },
288
- "logs": $logs_json,
289
- "apm": {
290
- "nodeName": "$(hostname)",
291
- "p50": 1.8,
292
- "p90": 4.5,
293
- "p95": 8.2,
294
- "p99": 14.0,
295
- "errorRate": "0.0%",
296
- "totalTraced": 8
297
- }
298
- }
299
- EOF
300
- )
301
-
302
- local metrics_res=$(curl -s -X POST "${server}/devops/api/agent/metrics" \
303
- -H "Content-Type: application/json" \
304
- -d "$payload" 2>/dev/null || echo '{}')
305
-
306
- if [[ "$metrics_res" == *"Invalid"* || "$metrics_res" == *"not approved"* || "$metrics_res" == *"token"* ]]; then
307
- local status_res=$(curl -s "${server}/devops/api/agent/status/${agentId}" 2>/dev/null || echo '{}')
308
- local status=$(echo "$status_res" | grep -o '"status":"[^"]*"' | cut -d'"' -f4 || echo "")
309
- local new_token=$(echo "$status_res" | grep -o '"token":"[^"]*"' | cut -d'"' -f4 || echo "")
310
- if [[ "$status" == "approved" && -n "$new_token" ]]; then
311
- token="$new_token"
312
- save_config "$server" "$name" "$room" "$agentId" "$token" "approved"
313
- fi
314
- fi
315
-
316
- # Sub-second fast poller for near-instant interactive terminal response
317
- for _i in {1..6}; do
318
- local cmd_res=$(curl -s "${server}/devops/api/agent/command/poll?agentId=${agentId}&token=${token}" 2>/dev/null || echo '{}')
319
- local cmd=$(echo "$cmd_res" | grep -o '"cmd":"[^"]*"' | head -n1 | cut -d'"' -f4 || echo "")
320
- local sid=$(echo "$cmd_res" | grep -o '"sessionId":"[^"]*"' | head -n1 | cut -d'"' -f4 || echo "")
321
- if [[ -n "$cmd" ]]; then
322
- # Strip any ANSI escape sequences from command
323
- cmd=$(echo "$cmd" | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' | sed 's/u001b\[[0-9;]*[a-zA-Z]//g')
324
-
325
- # Auto-adjust interactive blocking commands to crisp one-shot outputs
326
- if [[ "$cmd" == "pm2 logs"* || "$cmd" == "pm2 log"* ]]; then
327
- cmd="pm2 logs --lines 40 --nostream 2>&1 || tail -n 40 ~/.pm2/logs/*.log 2>&1"
328
- elif [[ "$cmd" == "top" ]]; then
329
- cmd="top -b -n 1 | head -n 35"
330
- elif [[ "$cmd" == "htop" ]]; then
331
- cmd="top -b -n 1 | head -n 35"
332
- elif [[ "$cmd" == "ping "* && "$cmd" != *"-c "* ]]; then
333
- cmd="$cmd -c 3"
334
- fi
335
-
336
- local cur_dir=$(cat "$CONFIG_DIR/cwd.state" 2>/dev/null || echo "$HOME")
337
- [[ -d "$cur_dir" ]] || cur_dir="$HOME"
338
-
339
- local temp_out=$(mktemp 2>/dev/null || echo "/tmp/tnc_cmd_out_$$")
340
- local temp_pwd=$(mktemp 2>/dev/null || echo "/tmp/tnc_cmd_pwd_$$")
341
-
342
- (
343
- # Load comprehensive environment and standard user paths
344
- export HOME="${HOME:-/home/ubuntu}"
345
- export USER="${USER:-ubuntu}"
346
- export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:$HOME/.npm-global/bin:$HOME/.local/bin:$PATH"
347
- if [[ -d "$HOME/.nvm" ]]; then
348
- export NVM_DIR="$HOME/.nvm"
349
- [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" 2>/dev/null || true
350
- fi
351
- export GIT_TERMINAL_PROMPT=0
352
- export CI=true
353
- export TERM=xterm-256color
354
-
355
- cd "$cur_dir" 2>/dev/null || cd "$HOME"
356
- # Run command with 15s timeout to prevent zombie locks
357
- if command -v timeout >/dev/null 2>&1; then
358
- timeout 15s bash -c "$cmd" > "$temp_out" 2>&1 || true
359
- else
360
- eval "$cmd" > "$temp_out" 2>&1 || true
361
- fi
362
- pwd > "$temp_pwd"
363
- )
364
-
365
- local new_dir=$(cat "$temp_pwd" 2>/dev/null || echo "$cur_dir")
366
- [[ -d "$new_dir" ]] && echo "$new_dir" > "$CONFIG_DIR/cwd.state"
367
- local output=$(cat "$temp_out" 2>/dev/null || echo "")
368
- rm -f "$temp_out" "$temp_pwd" 2>/dev/null || true
369
-
370
- # Robust JSON serialization of terminal output
371
- local clean_out
372
- if command -v python3 >/dev/null 2>&1; then
373
- clean_out=$(python3 -c "import sys, json; print(json.dumps(sys.stdin.read()))" <<< "$output" 2>/dev/null || echo '""')
374
- else
375
- local escaped=$(echo -n "$output" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/ /g' | awk '{printf "%s\\n", $0}' | sed 's/\\n$//')
376
- clean_out="\"$escaped\""
377
- fi
378
-
379
- local result_payload="{\"agentId\":\"$agentId\",\"token\":\"$token\",\"sessionId\":\"$sid\",\"output\":$clean_out,\"cwd\":\"$new_dir\",\"exitCode\":0}"
380
- curl -s -X POST "${server}/devops/api/agent/command/result" \
381
- -H "Content-Type: application/json" \
382
- -d "$result_payload" > /dev/null 2>&1 || true
383
- fi
384
- sleep 0.5
385
- done
386
- done
387
- }
388
-
389
- cmd_stop() {
390
- if [[ -f "$PID_FILE" ]]; then
391
- local pid=$(cat "$PID_FILE" 2>/dev/null)
392
- if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
393
- kill "$pid" 2>/dev/null || true
394
- rm -f "$PID_FILE"
395
- log_ok "thinknagent stopped (PID $pid)."
396
- return
397
- fi
398
- fi
399
- # Fallback to kill by process name
400
- pkill -f "thinknagent" 2>/dev/null || true
401
- rm -f "$PID_FILE"
402
- log_ok "thinknagent stopped."
403
- }
404
-
405
- cmd_restart() {
406
- log_info "Restarting thinknagent..."
407
- cmd_stop
408
- sleep 1
409
- cmd_daemon
410
- }
411
-
412
- cmd_daemon() {
413
- local server=$(get_json_val "serverUrl")
414
- local agentId=$(get_json_val "agentId")
415
- if [[ -z "$server" || -z "$agentId" ]]; then
416
- log_err "Agent not initialized. Run './thinknagent.sh init --room <roomId>' first."
417
- exit 1
418
- fi
419
-
420
- local script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
421
- local log_file="${CONFIG_DIR}/daemon.log"
422
-
423
- if [[ -f "$PID_FILE" ]] && kill -0 "$(cat "$PID_FILE" 2>/dev/null)" 2>/dev/null; then
424
- log_warn "thinknagent is already running (PID $(cat "$PID_FILE"))."
425
- return
426
- fi
427
-
428
- nohup bash -c "
429
- while true; do
430
- bash \"$script_path\" start >> \"$log_file\" 2>&1
431
- sleep 3
432
- done
433
- " > /dev/null 2>&1 &
434
-
435
- local daemon_pid=$!
436
- echo "$daemon_pid" > "$PID_FILE"
437
-
438
- log_ok "thinknagent daemon started with auto-restart! (PID $daemon_pid)"
439
- log_info "Logs: $log_file"
440
- log_info "Check status: thinknagent status"
441
- log_info "Stop daemon : thinknagent stop"
442
- }
443
-
444
- cmd_logs() {
445
- local log_file="${CONFIG_DIR}/daemon.log"
446
- if [[ -f "$log_file" ]]; then
447
- echo ""
448
- echo " --- thinknagent logs (last 50 lines) ---"
449
- tail -n 50 "$log_file"
450
- echo " --- end of logs ---"
451
- echo ""
452
- else
453
- log_info "No logs found yet at $log_file"
454
- fi
455
- }
456
-
457
- cmd_revoke() {
458
- cmd_stop
459
- rm -f "$CONFIG_FILE" "$PID_FILE"
460
- log_ok "All credentials cleared from ${CONFIG_DIR}."
461
- log_info "To re-register: thinknagent init --room <roomId>"
462
- }
463
-
464
- cmd_status() {
465
- local server=$(get_json_val "serverUrl")
466
- local name=$(get_json_val "name")
467
- local agentId=$(get_json_val "agentId")
468
- local room=$(get_json_val "roomId")
469
- local token=$(get_json_val "agentToken")
470
- local status=$(get_json_val "status")
471
-
472
- echo ""
473
- echo " thinknagent Status"
474
- echo " ─────────────────────────────────────────────"
475
- echo " Name : ${name:-—}"
476
- echo " Server : ${server:-—}"
477
- echo " Room : ${room:-—}"
478
- echo " Agent ID : ${agentId:-—}"
479
- echo " Auth State : $([[ -n "$token" ]] && echo "APPROVED (Active)" || echo "PENDING (Waiting for Owner approval)")"
480
- if [[ -f "$PID_FILE" ]] && kill -0 "$(cat "$PID_FILE" 2>/dev/null)" 2>/dev/null; then
481
- echo " Process : RUNNING (PID $(cat "$PID_FILE"))"
482
- else
483
- echo " Process : STOPPED"
484
- fi
485
- echo " ─────────────────────────────────────────────"
486
- echo ""
487
- }
488
-
489
- cmd_service() {
490
- if [[ $EUID -ne 0 ]]; then
491
- log_err "Please run with sudo to setup systemd service: sudo thinknagent daemon install"
492
- exit 1
493
- fi
494
-
495
- local real_user="${SUDO_USER:-$(whoami)}"
496
- local real_home=$(eval echo "~$real_user")
497
- local script_path="${real_home}/.thinknagent/thinknagent.sh"
498
- if [[ ! -f "$script_path" ]]; then
499
- script_path="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
500
- fi
501
-
502
- cat > /etc/systemd/system/thinknagent.service << EOF
503
- [Unit]
504
- Description=ThinkNCollab Server Agent (Standalone)
505
- After=network-online.target
506
- Wants=network-online.target
507
-
508
- [Service]
509
- Type=simple
510
- User=${real_user}
511
- ExecStart=/bin/bash ${script_path} start
512
- Restart=always
513
- RestartSec=5
514
- Environment=NODE_ENV=production
515
- StandardOutput=journal
516
- StandardError=journal
517
- SyslogIdentifier=thinknagent
518
-
519
- [Install]
520
- WantedBy=multi-user.target
521
- EOF
522
-
523
- systemctl daemon-reload
524
- systemctl enable thinknagent.service
525
- systemctl restart thinknagent.service
526
- log_ok "Systemd service 'thinknagent' installed and started successfully for user ${real_user}!"
527
- log_info "Check service anytime: systemctl status thinknagent"
528
- log_info "Check live logs: journalctl -u thinknagent -f"
529
- }
530
-
531
- case "${1:-status}" in
532
- init) shift; cmd_init "$@" ;;
533
- start) shift; cmd_start "$@" ;;
534
- stop) cmd_stop ;;
535
- restart) cmd_restart ;;
536
- daemon)
537
- case "${2:-start}" in
538
- install) cmd_service ;;
539
- start) cmd_daemon ;;
540
- stop) cmd_stop ;;
541
- restart) cmd_restart ;;
542
- status) cmd_status ;;
543
- *) cmd_daemon ;;
544
- esac
545
- ;;
546
- logs) cmd_logs ;;
547
- revoke) cmd_revoke ;;
548
- status) cmd_status ;;
549
- service) cmd_service ;;
550
- *)
551
- echo "Usage: thinknagent {init|start|stop|restart|daemon|status|logs|app|revoke|service}"
552
- exit 1
553
- ;;
554
- esac