easy-devops 0.1.0
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/LICENSE +21 -0
- package/README.md +325 -0
- package/cli/index.js +91 -0
- package/cli/managers/domain-manager.js +451 -0
- package/cli/managers/nginx-manager.js +329 -0
- package/cli/managers/node-manager.js +275 -0
- package/cli/managers/ssl-manager.js +397 -0
- package/cli/menus/.gitkeep +0 -0
- package/cli/menus/dashboard.js +223 -0
- package/cli/menus/domains.js +5 -0
- package/cli/menus/nginx.js +5 -0
- package/cli/menus/nodejs.js +5 -0
- package/cli/menus/settings.js +83 -0
- package/cli/menus/ssl.js +5 -0
- package/core/config.js +37 -0
- package/core/db.js +30 -0
- package/core/detector.js +257 -0
- package/core/nginx-conf-generator.js +309 -0
- package/core/shell.js +151 -0
- package/dashboard/lib/.gitkeep +0 -0
- package/dashboard/lib/cert-reader.js +59 -0
- package/dashboard/lib/domains-db.js +51 -0
- package/dashboard/lib/nginx-conf-generator.js +16 -0
- package/dashboard/lib/nginx-service.js +282 -0
- package/dashboard/public/js/app.js +486 -0
- package/dashboard/routes/.gitkeep +0 -0
- package/dashboard/routes/auth.js +30 -0
- package/dashboard/routes/domains.js +300 -0
- package/dashboard/routes/nginx.js +151 -0
- package/dashboard/routes/settings.js +78 -0
- package/dashboard/routes/ssl.js +105 -0
- package/dashboard/server.js +79 -0
- package/dashboard/views/index.ejs +327 -0
- package/dashboard/views/partials/domain-form.ejs +229 -0
- package/dashboard/views/partials/domains-panel.ejs +66 -0
- package/dashboard/views/partials/login.ejs +50 -0
- package/dashboard/views/partials/nginx-panel.ejs +90 -0
- package/dashboard/views/partials/overview.ejs +67 -0
- package/dashboard/views/partials/settings-panel.ejs +37 -0
- package/dashboard/views/partials/sidebar.ejs +45 -0
- package/dashboard/views/partials/ssl-panel.ejs +53 -0
- package/data/.gitkeep +0 -0
- package/install.bat +41 -0
- package/install.ps1 +653 -0
- package/install.sh +452 -0
- package/lib/installer/.gitkeep +0 -0
- package/lib/installer/detect.sh +88 -0
- package/lib/installer/node-versions.sh +109 -0
- package/lib/installer/nvm-bootstrap.sh +77 -0
- package/lib/installer/picker.sh +163 -0
- package/lib/installer/progress.sh +25 -0
- package/package.json +67 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# nvm-bootstrap.sh — Download, install, and activate nvm
|
|
3
|
+
# Sourced by install.sh; not executed directly.
|
|
4
|
+
# Requires: progress.sh sourced first (uses step_* helpers).
|
|
5
|
+
#
|
|
6
|
+
# Functions:
|
|
7
|
+
# bootstrap_nvm — install nvm if absent, then source it into the current session
|
|
8
|
+
#
|
|
9
|
+
# Respects:
|
|
10
|
+
# NVM_DIR (default: ~/.nvm)
|
|
11
|
+
|
|
12
|
+
bootstrap_nvm() {
|
|
13
|
+
local nvm_dir="${NVM_DIR:-$HOME/.nvm}"
|
|
14
|
+
local nvm_install_url="https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/install.sh"
|
|
15
|
+
|
|
16
|
+
# ------------------------------------------------------------------
|
|
17
|
+
# Step 1: Install nvm if not already present
|
|
18
|
+
# ------------------------------------------------------------------
|
|
19
|
+
if [ -f "$nvm_dir/nvm.sh" ]; then
|
|
20
|
+
step_done "nvm already installed at $nvm_dir — skipping download"
|
|
21
|
+
else
|
|
22
|
+
step_running "Downloading and installing nvm…"
|
|
23
|
+
|
|
24
|
+
local install_ok=false
|
|
25
|
+
if command -v curl >/dev/null 2>&1; then
|
|
26
|
+
if curl -fsSL --max-time 60 "$nvm_install_url" | bash >/dev/null 2>&1; then
|
|
27
|
+
install_ok=true
|
|
28
|
+
fi
|
|
29
|
+
fi
|
|
30
|
+
if [ "$install_ok" = "false" ] && command -v wget >/dev/null 2>&1; then
|
|
31
|
+
if wget -qO- --timeout=60 "$nvm_install_url" | bash >/dev/null 2>&1; then
|
|
32
|
+
install_ok=true
|
|
33
|
+
fi
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
if [ "$install_ok" = "false" ]; then
|
|
37
|
+
step_failed "nvm download failed"
|
|
38
|
+
printf '\nManual recovery:\n' >&2
|
|
39
|
+
printf ' curl -o- %s | bash\n' "$nvm_install_url" >&2
|
|
40
|
+
printf ' Then run: source ~/.nvm/nvm.sh\n' >&2
|
|
41
|
+
return 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
step_done "nvm installed at $nvm_dir"
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# ------------------------------------------------------------------
|
|
48
|
+
# Step 2: Source nvm into the current shell session
|
|
49
|
+
# ------------------------------------------------------------------
|
|
50
|
+
# shellcheck source=/dev/null
|
|
51
|
+
if [ -f "$nvm_dir/nvm.sh" ]; then
|
|
52
|
+
export NVM_DIR="$nvm_dir"
|
|
53
|
+
. "$nvm_dir/nvm.sh"
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Verify nvm command is now available
|
|
57
|
+
if ! command -v nvm >/dev/null 2>&1; then
|
|
58
|
+
# nvm is a function, not a binary; try sourcing from common shell rc files
|
|
59
|
+
for rc in "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.profile" "$HOME/.zshrc"; do
|
|
60
|
+
if [ -f "$rc" ]; then
|
|
61
|
+
# shellcheck source=/dev/null
|
|
62
|
+
. "$rc" 2>/dev/null || true
|
|
63
|
+
command -v nvm >/dev/null 2>&1 && break
|
|
64
|
+
fi
|
|
65
|
+
done
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
if ! command -v nvm >/dev/null 2>&1; then
|
|
69
|
+
step_failed "nvm command not available after install"
|
|
70
|
+
printf '\nManual recovery:\n' >&2
|
|
71
|
+
printf ' source ~/.nvm/nvm.sh\n' >&2
|
|
72
|
+
printf ' Then re-run: bash install.sh\n' >&2
|
|
73
|
+
return 1
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
step_done "nvm is active in this session"
|
|
77
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# picker.sh — Interactive Node.js version picker
|
|
3
|
+
# Sourced by install.sh; not executed directly.
|
|
4
|
+
# Requires: node-versions.sh sourced first (uses NODE_RELEASES global array).
|
|
5
|
+
#
|
|
6
|
+
# Functions:
|
|
7
|
+
# pick_version [current_version]
|
|
8
|
+
#
|
|
9
|
+
# Uses NODE_RELEASES global array (set by fetch_node_versions).
|
|
10
|
+
# Sets PICKED_VERSION to the chosen version string (e.g., "20.11.1").
|
|
11
|
+
# Returns 2 if the user cancels (presses q / Ctrl-C).
|
|
12
|
+
|
|
13
|
+
pick_version() {
|
|
14
|
+
local current_ver="${1:-}"
|
|
15
|
+
local count="${#NODE_RELEASES[@]}"
|
|
16
|
+
|
|
17
|
+
if [ "$count" -eq 0 ]; then
|
|
18
|
+
printf 'Error: No Node.js releases available to pick from.\n' >&2
|
|
19
|
+
return 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Build display labels (mark currently installed version)
|
|
23
|
+
PICKER_LABELS=()
|
|
24
|
+
local i
|
|
25
|
+
for (( i=0; i<count; i++ )); do
|
|
26
|
+
local entry="${NODE_RELEASES[$i]}"
|
|
27
|
+
local ver label
|
|
28
|
+
ver="$( printf '%s' "$entry" | cut -d'|' -f1)"
|
|
29
|
+
label="$( printf '%s' "$entry" | cut -d'|' -f4)"
|
|
30
|
+
if [ -n "$current_ver" ] && [ "$ver" = "$current_ver" ]; then
|
|
31
|
+
PICKER_LABELS+=("${label} [currently installed]")
|
|
32
|
+
else
|
|
33
|
+
PICKER_LABELS+=("$label")
|
|
34
|
+
fi
|
|
35
|
+
done
|
|
36
|
+
|
|
37
|
+
# ------------------------------------------------------------------
|
|
38
|
+
# TTY path: arrow-key picker using stty raw + ANSI escape codes
|
|
39
|
+
# ------------------------------------------------------------------
|
|
40
|
+
if [ -t 0 ] && [ -t 1 ]; then
|
|
41
|
+
_pick_tty
|
|
42
|
+
return $?
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# ------------------------------------------------------------------
|
|
46
|
+
# Non-TTY / scripted path: numbered select list
|
|
47
|
+
# ------------------------------------------------------------------
|
|
48
|
+
_pick_numbered
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Internal: TTY arrow-key picker
|
|
52
|
+
_pick_tty() {
|
|
53
|
+
local count="${#PICKER_LABELS[@]}"
|
|
54
|
+
local selected=0
|
|
55
|
+
|
|
56
|
+
# ANSI sequences
|
|
57
|
+
local CLEAR_LINE BOLD RESET HIGHLIGHT
|
|
58
|
+
CLEAR_LINE="\033[2K\r"
|
|
59
|
+
BOLD="\033[1m"
|
|
60
|
+
RESET="\033[0m"
|
|
61
|
+
HIGHLIGHT="\033[7m"
|
|
62
|
+
|
|
63
|
+
# Hide cursor
|
|
64
|
+
printf '\033[?25l'
|
|
65
|
+
|
|
66
|
+
# Save terminal state and restore on exit
|
|
67
|
+
local old_stty
|
|
68
|
+
old_stty="$(stty -g 2>/dev/null || true)"
|
|
69
|
+
|
|
70
|
+
# Cleanup function
|
|
71
|
+
_tty_cleanup() {
|
|
72
|
+
stty "$old_stty" 2>/dev/null || true
|
|
73
|
+
printf '\033[?25h' # show cursor
|
|
74
|
+
}
|
|
75
|
+
trap '_tty_cleanup; return 2' INT TERM
|
|
76
|
+
|
|
77
|
+
printf '\nSelect a Node.js version (up/down arrows, Enter to confirm, q to quit):\n\n'
|
|
78
|
+
|
|
79
|
+
# Draw initial list
|
|
80
|
+
local j
|
|
81
|
+
for (( j=0; j<count; j++ )); do
|
|
82
|
+
if [ "$j" -eq "$selected" ]; then
|
|
83
|
+
printf " ${HIGHLIGHT}${BOLD}> %s${RESET}\n" "${PICKER_LABELS[$j]}"
|
|
84
|
+
else
|
|
85
|
+
printf " %s\n" "${PICKER_LABELS[$j]}"
|
|
86
|
+
fi
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
# Enable raw mode for single-key reading
|
|
90
|
+
stty raw -echo 2>/dev/null || true
|
|
91
|
+
|
|
92
|
+
while true; do
|
|
93
|
+
local ch seq1 seq2
|
|
94
|
+
IFS= read -r -s -n1 ch 2>/dev/null || true
|
|
95
|
+
|
|
96
|
+
if [ "$ch" = $'\x1b' ]; then
|
|
97
|
+
IFS= read -r -s -n1 -t 0.1 seq1 2>/dev/null || seq1=""
|
|
98
|
+
IFS= read -r -s -n1 -t 0.1 seq2 2>/dev/null || seq2=""
|
|
99
|
+
if [ "$seq1" = "[" ]; then
|
|
100
|
+
case "$seq2" in
|
|
101
|
+
A) [ "$selected" -gt 0 ] && selected=$(( selected - 1 )) ;;
|
|
102
|
+
B) [ "$selected" -lt $(( count - 1 )) ] && selected=$(( selected + 1 )) ;;
|
|
103
|
+
esac
|
|
104
|
+
fi
|
|
105
|
+
elif [ "$ch" = $'\n' ] || [ "$ch" = $'\r' ] || [ -z "$ch" ]; then
|
|
106
|
+
break
|
|
107
|
+
elif [ "$ch" = "q" ] || [ "$ch" = "Q" ]; then
|
|
108
|
+
_tty_cleanup
|
|
109
|
+
trap - INT TERM
|
|
110
|
+
printf '\n'
|
|
111
|
+
return 2
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# Redraw: move cursor up count lines
|
|
115
|
+
local k
|
|
116
|
+
for (( k=0; k<count; k++ )); do
|
|
117
|
+
printf "${CLEAR_LINE}\033[1A"
|
|
118
|
+
done
|
|
119
|
+
printf "${CLEAR_LINE}"
|
|
120
|
+
for (( k=0; k<count; k++ )); do
|
|
121
|
+
if [ "$k" -eq "$selected" ]; then
|
|
122
|
+
printf " ${HIGHLIGHT}${BOLD}> %s${RESET}\n" "${PICKER_LABELS[$k]}"
|
|
123
|
+
else
|
|
124
|
+
printf " %s\n" "${PICKER_LABELS[$k]}"
|
|
125
|
+
fi
|
|
126
|
+
done
|
|
127
|
+
done
|
|
128
|
+
|
|
129
|
+
_tty_cleanup
|
|
130
|
+
trap - INT TERM
|
|
131
|
+
printf '\n'
|
|
132
|
+
|
|
133
|
+
PICKED_VERSION="$(printf '%s' "${NODE_RELEASES[$selected]}" | cut -d'|' -f1)"
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# Internal: numbered list fallback (non-TTY)
|
|
137
|
+
_pick_numbered() {
|
|
138
|
+
local count="${#PICKER_LABELS[@]}"
|
|
139
|
+
|
|
140
|
+
printf '\nAvailable Node.js versions:\n\n'
|
|
141
|
+
local j
|
|
142
|
+
for (( j=0; j<count; j++ )); do
|
|
143
|
+
printf ' %d) %s\n' $(( j + 1 )) "${PICKER_LABELS[$j]}"
|
|
144
|
+
done
|
|
145
|
+
printf '\n'
|
|
146
|
+
|
|
147
|
+
local choice
|
|
148
|
+
while true; do
|
|
149
|
+
printf 'Enter number (1-%d), or q to quit: ' "$count"
|
|
150
|
+
IFS= read -r choice
|
|
151
|
+
if [ "$choice" = "q" ] || [ "$choice" = "Q" ]; then
|
|
152
|
+
return 2
|
|
153
|
+
fi
|
|
154
|
+
if printf '%s' "$choice" | grep -qE '^[0-9]+$'; then
|
|
155
|
+
if [ "$choice" -ge 1 ] && [ "$choice" -le "$count" ]; then
|
|
156
|
+
local idx=$(( choice - 1 ))
|
|
157
|
+
PICKED_VERSION="$(printf '%s' "${NODE_RELEASES[$idx]}" | cut -d'|' -f1)"
|
|
158
|
+
return 0
|
|
159
|
+
fi
|
|
160
|
+
fi
|
|
161
|
+
printf 'Invalid selection. Please enter a number between 1 and %d.\n' "$count" >&2
|
|
162
|
+
done
|
|
163
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# progress.sh — Step progress display helpers
|
|
3
|
+
# Sourced by install.sh; not executed directly.
|
|
4
|
+
#
|
|
5
|
+
# Functions:
|
|
6
|
+
# step_pending <label> — print "[ ] <label>" to stdout
|
|
7
|
+
# step_running <label> — print "[→] <label>" to stdout
|
|
8
|
+
# step_done <label> — print "[✓] <label>" to stdout
|
|
9
|
+
# step_failed <label> — print "[✗] <label>" to stderr
|
|
10
|
+
|
|
11
|
+
step_pending() {
|
|
12
|
+
printf '[ ] %s\n' "$1"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
step_running() {
|
|
16
|
+
printf '[→] %s\n' "$1"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
step_done() {
|
|
20
|
+
printf '[✓] %s\n' "$1"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
step_failed() {
|
|
24
|
+
printf '[✗] %s\n' "$1" >&2
|
|
25
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "easy-devops",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A unified DevOps management tool with CLI and web dashboard for managing Nginx, SSL certificates, and Node.js on Linux and Windows servers.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"devops",
|
|
7
|
+
"nginx",
|
|
8
|
+
"ssl",
|
|
9
|
+
"certbot",
|
|
10
|
+
"letsencrypt",
|
|
11
|
+
"nodejs",
|
|
12
|
+
"dashboard",
|
|
13
|
+
"cli",
|
|
14
|
+
"server-management",
|
|
15
|
+
"reverse-proxy",
|
|
16
|
+
"certificate-management",
|
|
17
|
+
"sysadmin"
|
|
18
|
+
],
|
|
19
|
+
"author": {
|
|
20
|
+
"name": "Omar Farghaly",
|
|
21
|
+
"url": "https://github.com/omar00050"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/omar00050/Easy-DevOps.git"
|
|
27
|
+
},
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/omar00050/Easy-DevOps/issues"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/omar00050/Easy-DevOps#readme",
|
|
32
|
+
"type": "module",
|
|
33
|
+
"main": "cli/index.js",
|
|
34
|
+
"bin": {
|
|
35
|
+
"easy-devops": "cli/index.js"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"cli/",
|
|
39
|
+
"core/",
|
|
40
|
+
"dashboard/",
|
|
41
|
+
"lib/",
|
|
42
|
+
"data/.gitkeep",
|
|
43
|
+
"install.bat",
|
|
44
|
+
"install.ps1",
|
|
45
|
+
"install.sh"
|
|
46
|
+
],
|
|
47
|
+
"scripts": {
|
|
48
|
+
"start": "node cli/index.js",
|
|
49
|
+
"test": "echo \" no test specified\"",
|
|
50
|
+
"dashboard": "node dashboard/server.js",
|
|
51
|
+
"system-info": "node cli/index.js system-info"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=18.0.0"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"chalk": "^5.3.0",
|
|
58
|
+
"cli-table3": "^0.6.5",
|
|
59
|
+
"ejs": "^5.0.1",
|
|
60
|
+
"express": "^5.2.1",
|
|
61
|
+
"express-session": "^1.17.3",
|
|
62
|
+
"good.db": "^2.4.6",
|
|
63
|
+
"inquirer": "^9.2.12",
|
|
64
|
+
"ora": "^7.0.1",
|
|
65
|
+
"socket.io": "^4.8.3"
|
|
66
|
+
}
|
|
67
|
+
}
|