-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathself-update.sh
208 lines (173 loc) · 7 KB
/
self-update.sh
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
#!/bin/bash
# Exit immediately if a command exits with a non-zero status
set -e
# Define variables
REPO_URL="https://github.com/lazerusrm/yolink-chekt/archive/refs/heads/main.zip"
APP_DIR="/opt/yolink-chekt"
CONFIG_FILE="$APP_DIR/config.yaml"
CONFIG_BACKUP="$APP_DIR/config.yaml.bak"
MAPPINGS_FILE="$APP_DIR/mappings.yaml"
MAPPINGS_BACKUP="$APP_DIR/mappings.yaml.bak"
DEVICES_FILE="$APP_DIR/devices.yaml"
DEVICES_BACKUP="$APP_DIR/devices.yaml.bak"
TEMPLATES_DIR="$APP_DIR/templates"
DOCKER_COMPOSE_FILE="$APP_DIR/docker-compose.yml"
LOG_FILE="/var/log/yolink-chekt-install.log"
# Redirect all output to log file
exec > >(tee -i "$LOG_FILE")
exec 2>&1
# Function to handle errors
handle_error() {
echo "Error: $1" >&2
exit 1
}
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to install a package using apt-get
install_package() {
PACKAGE_NAME="$1"
echo "Installing $PACKAGE_NAME..."
apt-get install -y "$PACKAGE_NAME" || handle_error "Failed to install $PACKAGE_NAME."
echo "$PACKAGE_NAME installed successfully."
}
# Function to install Docker using the official Docker installation script
install_docker() {
echo "Installing Docker..."
curl -fsSL https://get.docker.com -o get-docker.sh || handle_error "Failed to download Docker installation script."
sh get-docker.sh || handle_error "Failed to install Docker."
rm get-docker.sh
echo "Docker installed successfully."
}
# Function to install Docker Compose as a Docker plugin
install_docker_compose() {
echo "Installing Docker Compose..."
DOCKER_COMPOSE_VERSION="v2.20.3" # Specify the desired version
mkdir -p /usr/lib/docker/cli-plugins/
curl -SL "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-linux-x86_64" -o /usr/lib/docker/cli-plugins/docker-compose || handle_error "Failed to download Docker Compose."
chmod +x /usr/lib/docker/cli-plugins/docker-compose
ln -sf /usr/lib/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose || handle_error "Failed to create symlink for Docker Compose."
echo "Docker Compose installed successfully."
}
# Ensure the script is run as root
if [ "$EUID" -ne 0 ]; then
handle_error "This script must be run as root."
fi
# Update package list
echo "Updating package list..."
apt-get update || handle_error "Failed to update package list."
# Check and install required dependencies
DEPENDENCIES=("curl" "unzip" "rsync")
for pkg in "${DEPENDENCIES[@]}"; do
if ! command_exists "$pkg"; then
install_package "$pkg"
else
echo "$pkg is already installed."
fi
done
# Check and install Docker
if ! command_exists "docker"; then
install_docker
else
echo "Docker is already installed."
fi
# Check and install Docker Compose
if ! command_exists "docker-compose"; then
install_docker_compose
else
echo "Docker Compose is already installed."
fi
# Ensure Docker service is running
echo "Ensuring Docker service is running..."
systemctl enable docker || handle_error "Failed to enable Docker service."
systemctl start docker || handle_error "Failed to start Docker service."
echo "Docker service is running."
# Ensure the application directory exists
echo "Ensuring application directories exist..."
mkdir -p "$APP_DIR" || handle_error "Failed to create application directory."
# Set ownership and permissions for the application directory
echo "Setting ownership and permissions for $APP_DIR..."
chown -R root:root "$APP_DIR" || handle_error "Failed to set ownership for $APP_DIR."
chmod -R 755 "$APP_DIR" || handle_error "Failed to set permissions for $APP_DIR."
echo "Ownership and permissions set."
# Function to backup a file if it exists
backup_file() {
local FILE="$1"
local BACKUP="$2"
if [ -f "$FILE" ]; then
cp "$FILE" "$BACKUP" || handle_error "Failed to backup $(basename "$FILE")"
echo "$(basename "$FILE") backed up."
else
echo "Warning: $(basename "$FILE") does not exist. Skipping backup."
fi
}
# Function to restore a file from backup if backup exists
restore_file() {
local BACKUP="$1"
local FILE="$2"
if [ -f "$BACKUP" ]; then
mv "$BACKUP" "$FILE" || handle_error "Failed to restore $(basename "$FILE") from backup"
echo "$(basename "$FILE") restored."
else
echo "Warning: Backup not found. $(basename "$FILE") was not restored."
fi
}
# Backup current config files if they exist
backup_file "$CONFIG_FILE" "$CONFIG_BACKUP"
backup_file "$MAPPINGS_FILE" "$MAPPINGS_BACKUP"
backup_file "$DEVICES_FILE" "$DEVICES_BACKUP"
# Download and unzip the latest code from the repository
echo "Downloading latest code..."
curl -L "$REPO_URL" -o "$APP_DIR/repo.zip" || handle_error "Repository download failed."
echo "Unzipping latest code..."
unzip -o "$APP_DIR/repo.zip" -d "$APP_DIR" || handle_error "Unzip failed."
# Restore configuration files after update
restore_file "$CONFIG_BACKUP" "$CONFIG_FILE"
restore_file "$MAPPINGS_BACKUP" "$MAPPINGS_FILE"
restore_file "$DEVICES_BACKUP" "$DEVICES_FILE"
# Move extracted files while excluding config.yaml, mappings.yaml, and devices.yaml
echo "Updating application files..."
rsync -a --exclude='config.yaml' --exclude='mappings.yaml' --exclude='devices.yaml' "$APP_DIR/yolink-chekt-main/" "$APP_DIR/" || handle_error "Move extracted files failed."
# Set appropriate permissions for all files in APP_DIR
echo "Setting permissions for application files..."
chmod -R u+rwX,go+rX "$APP_DIR" || handle_error "Failed to set permissions for application files."
echo "Permissions set."
# Set appropriate permissions for the self-update script
chmod +x "$APP_DIR/self-update.sh" || handle_error "Setting executable permission failed."
# Clean up temporary files
echo "Cleaning up temporary files..."
rm -rf "$APP_DIR/yolink-chekt-main"
rm "$APP_DIR/repo.zip"
echo "Temporary files cleaned."
# Function to determine if Docker Compose services are already running
services_running() {
docker compose ps -q | grep -q .
}
# Navigate to the application directory
cd "$APP_DIR" || handle_error "Failed to navigate to $APP_DIR."
# Export to disable BuildKit (if necessary)
export DOCKER_BUILDKIT=0
echo "Docker BuildKit disabled."
# Rebuild Docker containers with the latest code
echo "Rebuilding Docker containers..."
if services_running; then
echo "Existing Docker containers detected. Restarting containers..."
docker compose down || handle_error "Docker Compose down failed."
else
echo "No existing Docker containers detected. Starting containers..."
fi
docker compose up --build -d || handle_error "Docker Compose up failed."
echo "Docker containers rebuilt and started."
# Check if the config.html file is in the container after the rebuild
container_name=$(docker ps --filter "name=yolink_chekt" --format '{{.Names}}')
if [ -z "$container_name" ]; then
handle_error "Service container not found."
fi
# Verify config.html inside container
if docker exec "$container_name" test -f "/app/templates/config.html"; then
echo "config.html successfully copied into the container."
else
handle_error "config.html not found in the container."
fi
echo "Installation/Update applied successfully!"