forked from domoticz/domoticz
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupdaterelease
More file actions
executable file
·295 lines (238 loc) · 8.55 KB
/
updaterelease
File metadata and controls
executable file
·295 lines (238 loc) · 8.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#!/bin/bash
# Domoticz Update Script
# Created by GizMoCuz, 2026, version 2.3
# Usage: ./update_domoticz [--no-backup]
readonly SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
readonly BACKUP_DIR="backups"
readonly MAX_BACKUPS=5
readonly DOWNLOAD_URL="https://www.domoticz.com/download.php"
readonly ARCHIVE_NAME="domoticz_update.tgz"
readonly CHANNEL_KEYWORD="release"
# List of required packages (can be extended as needed)
readonly REQUIRED_PACKAGES=(
"libmosquitto1"
# Add more packages here as needed
#"libusb-0.1"
#"libcurl4"
#"libssl3"
)
# Color output for better readability
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly NC='\033[0m' # No Color
# Logging functions
log_info() { echo -e "${GREEN}>>${NC} $*"; }
log_warn() { echo -e "${YELLOW}>>${NC} $*"; }
log_error() { echo -e "${RED}>>${NC} $*" >&2; }
die() {
local error_msg="$*"
log_error "$error_msg"
exit 1
}
# Returns 0 (true) if script has been updated and re-executed, 1 (false) otherwise
is_reexecuted() {
[[ "${DOMOTICZ_UPDATE_REEXEC:-}" == "1" ]]
}
# Check and install required package dependencies
check_dependencies() {
log_info "Checking package dependencies..."
local missing_packages=()
local pkg
# Check each required package
for pkg in "${REQUIRED_PACKAGES[@]}"; do
if ! dpkg -l | grep -q "^ii $pkg"; then
log_warn "Package '$pkg' is not installed"
missing_packages+=("$pkg")
else
log_info "Package '$pkg' is already installed"
fi
done
# Install missing packages if any
if [[ ${#missing_packages[@]} -gt 0 ]]; then
log_info "Installing missing packages: ${missing_packages[*]}"
# Update package list first
log_info "Updating package list..."
if ! sudo apt-get update -qq; then
log_warn "Failed to update package list, continuing anyway..."
fi
# Install missing packages
if ! sudo apt-get install -y "${missing_packages[@]}"; then
die "Failed to install required packages: ${missing_packages[*]}"
fi
log_info "Successfully installed: ${missing_packages[*]}"
else
log_info "All required packages are already installed"
fi
}
# Validate prerequisites
validate_environment() {
log_info "Validating environment..."
# Check we're in the correct directory
[[ "$SCRIPT_DIR" == "$PWD" ]] || die "Script must be run from Domoticz directory!"
# Check required commands
local required_cmds=(wget tar sudo openssl dpkg uname)
for cmd in "${required_cmds[@]}"; do
command -v "$cmd" >/dev/null 2>&1 || die "Required command '$cmd' not found!"
done
# Architecture checks
local mach arch openssl_ver
mach=$(uname -m)
arch=$(dpkg --print-architecture)
openssl_ver=$(openssl version | awk '{print $2}' | cut -d. -f1)
[[ "$mach" == "armv6l" ]] && die "ARMv6 is not supported. Please upgrade your hardware."
[[ "$arch" == "armhf" ]] && mach="armv7l"
[[ "$openssl_ver" -eq 3 ]] || die "OpenSSL version 3 required! (Found version $openssl_ver)"
# Export for use in download
export DETECTED_MACH="$mach"
export DETECTED_OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
log_info "Environment validation passed (arch: $DETECTED_MACH, OS: $DETECTED_OS)"
}
# Download latest version
download_update() {
log_info "Downloading latest $CHANNEL_KEYWORD version..."
if ! wget -4 -q --show-progress --progress=bar:force -O "$ARCHIVE_NAME" --no-check-certificate \
"${DOWNLOAD_URL}?channel=${CHANNEL_KEYWORD}&type=release&system=${DETECTED_OS}&machine=${DETECTED_MACH}"; then
die "Failed to download Domoticz $CHANNEL_KEYWORD version!"
fi
log_info "Download complete. Verifying archive integrity..."
if ! tar tzf "$ARCHIVE_NAME" >/dev/null 2>&1; then
rm -f "$ARCHIVE_NAME"
die "Downloaded archive is corrupted!"
fi
log_info "Archive integrity verified."
}
# Extract and re-execute updated script if needed
reexec_if_outdated() {
if is_reexecuted; then
return 0
fi
log_info "Checking for updated upgrade script..."
# Try to extract the script - use --no-anchored to match filename anywhere in archive
local updated_script
if ! updated_script=$(tar -zxf "$ARCHIVE_NAME" --no-anchored "$SCRIPT_NAME" -O 2>/dev/null); then
log_warn "Could not extract updated script from archive (may not exist)"
log_info "Continuing with current script..."
return 0
fi
# Compare the extracted script with the current one
if diff -q <(cat "$0") <(echo "$updated_script") >/dev/null 2>&1; then
log_info "Script is already up-to-date, continuing with current version..."
return 0
fi
log_info "Found updated script, re-executing..."
# Execute the new script with environment variable set
export DOMOTICZ_UPDATE_REEXEC=1
exec bash -c "$updated_script" "$SCRIPT_NAME" "$@"
}
# Create backup of current installation
create_backup() {
local timestamp
timestamp=$(date +%Y%m%d_%H%M%S)
local backup_file="$BACKUP_DIR/domoticz_backup_$timestamp.tar.gz"
log_info "Creating backup: $backup_file"
mkdir -p "$BACKUP_DIR"
if ! sudo tar --exclude="$BACKUP_DIR" --exclude='*.tgz' --exclude='*.gz' --exclude='update.log' -czf "$backup_file" .; then
die "Backup creation failed!"
fi
sudo chmod 644 "$backup_file"
# Cleanup old backups (keep only MAX_BACKUPS)
local old_backups
old_backups=$(find "$BACKUP_DIR" -name "domoticz_backup_*.tar.gz" -type f | sort -r | tail -n +$((MAX_BACKUPS + 1)))
if [[ -n "$old_backups" ]]; then
log_info "Removing old backups..."
echo "$old_backups" | xargs rm -f
fi
log_info "Backup complete."
}
# Stop Domoticz service
stop_service() {
log_info "Stopping Domoticz service..."
if ! sudo service domoticz.sh stop; then
log_warn "Failed to stop service (may not be running)"
fi
}
# Check if Domoticz service is running
is_service_running() {
# Check if domoticz process is running
if pgrep -x domoticz > /dev/null 2>&1; then
return 0
fi
# Also check via systemctl if available
if command -v systemctl > /dev/null 2>&1; then
local status
status=$(systemctl is-active domoticz.sh 2>/dev/null)
if [ "$status" = "active" ]; then
# Double-check it's not "active (exited)" by verifying process exists
if pgrep -x domoticz > /dev/null 2>&1; then
return 0
fi
fi
fi
return 1
}
# Start Domoticz service
start_service() {
log_info "Starting Domoticz service (please wait)..."
sudo service domoticz.sh start
log_info "Service started successfully."
}
# Install new version
install_update() {
log_info "Installing new version..."
if ! tar xfz "$ARCHIVE_NAME" --checkpoint=.100; then
die "Failed to extract update archive!"
fi
rm -f "$ARCHIVE_NAME"
log_info "Installation complete."
}
# Main execution
main() {
local skip_backup=false
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--no-backup|-nobackup)
skip_backup=true
shift
;;
*)
die "Unknown option: $1"
;;
esac
done
log_info "Starting Domoticz $CHANNEL_KEYWORD Update"
log_info "Script: $SCRIPT_NAME (Directory: $SCRIPT_DIR)"
# Validate environment first
validate_environment
# Check and install dependencies
check_dependencies
# Download and re-execute with updated script if needed (only on first run)
if ! is_reexecuted; then
download_update
reexec_if_outdated "$@"
# If we reach here, script is up-to-date, continue with installation
else
log_info "Running updated script - proceeding with installation..."
fi
# Ensure archive exists for installation
if [[ ! -f "$ARCHIVE_NAME" ]]; then
log_info "Archive not found, downloading..."
download_update
fi
# Stop service
stop_service
# Create backup unless skipped
if [[ "$skip_backup" == false ]]; then
create_backup
else
log_warn "Skipping backup as requested"
fi
# Install and start
install_update
start_service
log_info "Update completed successfully!"
}
# Run main function
main "$@"