-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathauto_update.sh
More file actions
340 lines (287 loc) · 11.8 KB
/
auto_update.sh
File metadata and controls
340 lines (287 loc) · 11.8 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
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#!/bin/bash
# Configuration
IMAGE_NAME="payramapp/payram"
TAG="develop"
TESTNET_CONTAINER="payram-testnet"
MAINNET_CONTAINER="payram-mainnet"
TESTNET_BACKUP_DIR="/home/ubuntu/db_dump/testnet"
MAINNET_BACKUP_DIR="/home/ubuntu/db_dump/mainnet"
FORCE_RESTART=$1 # Pass "force" as the argument to force restart
LOCK_FILE="/tmp/payram_restart.lock"
SLACK_WEBHOOK="" # Add your Slack webhook URL here for notifications
# Log file
LOG_FILE="/home/ubuntu/automate_update/payram_restart.log"
exec > >(tee -a $LOG_FILE) 2>&1
log_message() {
echo "-------- $1"
}
# Function to send Slack notifications
send_slack_notification() {
local message="$1"
local status="${2:-info}" # Status: info, success, error
# Only send if webhook is configured
if [ -z "$SLACK_WEBHOOK" ]; then
return 0
fi
# Set color based on status
local color=""
case "$status" in
success) color="good" ;;
error) color="danger" ;;
*) color="#36a64f" ;;
esac
# Send to Slack
curl -s -X POST "$SLACK_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{
\"attachments\": [{
\"color\": \"$color\",
\"text\": \"$message\",
\"footer\": \"Payram Update Script\",
\"ts\": $(date +%s)
}]
}" > /dev/null 2>&1
}
log_message "Starting Payram Core restart script at $(date)"
# Check if the script is already running (lock file mechanism)
if [ -f "$LOCK_FILE" ]; then
log_message "Another instance of the script is running. Exiting."
exit 1
fi
# Create a lock file
touch "$LOCK_FILE"
# Function to clean up the lock file
cleanup() {
rm -f "$LOCK_FILE"
}
trap cleanup EXIT # Ensure the lock file is removed when the script exits
# Function to check for a valid digest
validate_digest() {
local digest=$1
if [ -z "$digest" ] || [ "$digest" == "null" ]; then
log_message "Invalid digest: $digest"
return 1
else
return 0
fi
}
# Function to get remote digest from Docker Hub API
get_remote_digest_api() {
local image=$1
local tag=$2
# Extract namespace and repo from image name (format: namespace/repo)
local namespace=$(echo "$image" | cut -d'/' -f1)
local repo=$(echo "$image" | cut -d'/' -f2)
log_message "Attempting to fetch remote digest via Docker Hub API..." >&2
# Call Docker Hub API
local api_response=$(curl -s "https://registry.hub.docker.com/v2/repositories/$namespace/$repo/tags/$tag/" 2>/dev/null)
if [ -z "$api_response" ]; then
log_message "API call failed: No response received" >&2
return 1
fi
# Parse digest from JSON response without jq (extract the tag digest field - the last one)
local digest=$(echo "$api_response" | grep -o '"digest":"sha256:[^"]*"' | tail -1 | sed 's/"digest":"//;s/"//')
if [ -z "$digest" ]; then
log_message "API call failed: Could not parse digest from response" >&2
return 1
fi
echo "$digest"
return 0
}
# Force Restart Logic
if [ "$FORCE_RESTART" == "force" ]; then
log_message "Force restart detected. Proceeding to restart without digest check."
else
log_message "Comparing local and remote digests for $IMAGE_NAME:$TAG..."
# Step 1: Get local digest
local_digest=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE_NAME:$TAG" 2>/dev/null | cut -d'@' -f2 | tr -d ' ')
if ! validate_digest "$local_digest"; then
log_message "Error: Unable to fetch a valid local digest. Exiting."
exit 1
fi
log_message "Local digest: $local_digest"
# Get remote digest via Docker Hub API (only method - no fallback)
remote_digest=$(get_remote_digest_api "$IMAGE_NAME" "$TAG")
# If API failed, exit cleanly - don't proceed with update
if [ $? -ne 0 ] || ! validate_digest "$remote_digest"; then
log_message "Error: Unable to fetch remote digest from Docker Hub API. Will retry on next run."
exit 0
fi
log_message "Remote digest: $remote_digest"
# Step 4: Compare the local and remote digests
if [ "$local_digest" == "$remote_digest" ]; then
log_message "No new image detected for $IMAGE_NAME:$TAG. Exiting."
exit 0
else
log_message "New image detected! Remote digest: $remote_digest, Local digest: $local_digest"
send_slack_notification "🔔 *Update Found!*\n\nNew image detected for \`$IMAGE_NAME:$TAG\`\nStarting update process..." "info"
fi
fi
# Track update status for final notification
TESTNET_STATUS="❌"
MAINNET_STATUS="❌"
TESTNET_BACKUP_SUCCESS=false
MAINNET_BACKUP_SUCCESS=false
# Process Testnet Container - Backup and Stop
if docker ps -a --format '{{.Names}}' | grep -q "^$TESTNET_CONTAINER$"; then
log_message "Processing $TESTNET_CONTAINER..."
# Backup testnet database
log_message "Taking backup of testnet database..."
mkdir -p $TESTNET_BACKUP_DIR
PGPASSWORD='LGJQ\<ZV.gEpNE8*' pg_dump -U payram -h 104.154.78.29 -p 5432 -F c -d payram -f $TESTNET_BACKUP_DIR/payram_testnet_dump_$(date -u +"%Y-%m-%dT%H:%M:%SZ").backup
if [ $? -eq 0 ]; then
log_message "Testnet database backup successful."
TESTNET_BACKUP_SUCCESS=true
# Stop and remove testnet container
log_message "Stopping $TESTNET_CONTAINER..."
docker stop $TESTNET_CONTAINER
log_message "Removing $TESTNET_CONTAINER container..."
docker rm $TESTNET_CONTAINER
else
log_message "ERROR: Testnet database backup failed! Skipping testnet update."
send_slack_notification "⚠️ *Testnet Backup Failed*\n\nDatabase backup failed for testnet. Stopped updating testnet." "error"
TESTNET_STATUS="❌"
fi
else
log_message "$TESTNET_CONTAINER not found, skipping..."
TESTNET_STATUS="⏭️"
fi
# Process Mainnet Container - Backup and Stop
if docker ps -a --format '{{.Names}}' | grep -q "^$MAINNET_CONTAINER$"; then
log_message "Processing $MAINNET_CONTAINER..."
# Backup mainnet database
log_message "Taking backup of mainnet database..."
mkdir -p $MAINNET_BACKUP_DIR
PGPASSWORD='payram123' pg_dump -U payram -h localhost -p 9005 -F c -d payram -f $MAINNET_BACKUP_DIR/payram_mainnet_dump_$(date -u +"%Y-%m-%dT%H:%M:%SZ").backup
if [ $? -eq 0 ]; then
log_message "Mainnet database backup successful."
MAINNET_BACKUP_SUCCESS=true
# Stop and remove mainnet container
log_message "Stopping $MAINNET_CONTAINER..."
docker stop $MAINNET_CONTAINER
log_message "Removing $MAINNET_CONTAINER container..."
docker rm $MAINNET_CONTAINER
else
log_message "ERROR: Mainnet database backup failed! Skipping mainnet update."
send_slack_notification "⚠️ *Mainnet Backup Failed*\n\nDatabase backup failed for mainnet. Stopped updating mainnet." "error"
MAINNET_STATUS="❌"
fi
else
log_message "$MAINNET_CONTAINER not found, skipping..."
MAINNET_STATUS="⏭️"
fi
# Remove old image and pull new one (if any container was backed up successfully)
if [ "$TESTNET_BACKUP_SUCCESS" = true ] || [ "$MAINNET_BACKUP_SUCCESS" = true ]; then
# Generate Swagger Documentation
log_message "Generating Swagger documentation..."
sudo bash /home/ubuntu/automate_update/generate_swagger_files.sh
if [ $? -eq 0 ]; then
log_message "Swagger documentation generated successfully."
# Clone docs for testnet and mainnet
log_message "Creating separate docs for testnet and mainnet..."
rm -rf /home/ubuntu/testnetdocs /home/ubuntu/mainnetdocs
cp -r /home/ubuntu/docs /home/ubuntu/testnetdocs
cp -r /home/ubuntu/docs /home/ubuntu/mainnetdocs
# Update swagger.json host for testnet
log_message "Updating testnet swagger host..."
sed -i 's/"host": "localhost:8080"/"host": "testnet.resuefas.vip:8443"/' /home/ubuntu/testnetdocs/swagger.json
# Update swagger.json host for mainnet
log_message "Updating mainnet swagger host..."
sed -i 's/"host": "localhost:8080"/"host": "mainnet.resuefas.vip:8443"/' /home/ubuntu/mainnetdocs/swagger.json
# Clean up the original docs folder
log_message "Cleaning up original docs folder..."
rm -rf /home/ubuntu/docs
log_message "Documentation setup complete."
else
log_message "WARNING: Swagger generation failed, continuing with deployment..."
fi
log_message "Removing old image..."
docker rmi $IMAGE_NAME:$TAG 2>/dev/null
log_message "Pulling new image $IMAGE_NAME:$TAG..."
docker pull $IMAGE_NAME:$TAG
if [ $? -ne 0 ]; then
log_message "ERROR: Failed to pull new image."
send_slack_notification "❌ *Update Failed!*\n\nFailed to pull new image for \`$IMAGE_NAME:$TAG\`\nContainers are stopped!" "error"
exit 1
fi
log_message "New image pulled successfully."
send_slack_notification "✅ *Image Pulled Successfully*\n\nNew image downloaded. Starting containers..." "success"
fi
# Start Testnet Container (if backup was successful)
if [ "$TESTNET_BACKUP_SUCCESS" = true ]; then
log_message "Starting $TESTNET_CONTAINER..."
docker run -d \
--name $TESTNET_CONTAINER \
--publish 8001:8080 \
--publish 8002:8443 \
--publish 8003:80 \
--publish 8004:443 \
--publish 8005:5432 \
-e AES_KEY="932732708e8b3beea4ddfa02841f2c82bfef0b24d73067a98e324d1f28200876" \
-e SSL_CERT_PATH="/etc/letsencrypt/live/testnet.resuefas.vip" \
-e BLOCKCHAIN_NETWORK_TYPE="testnet" \
-e SERVER="DEVELOPMENT" \
-e BACKEND_URL="https://testnet.resuefas.vip:8443" \
-e POSTGRES_DATABASE="payram" \
-e POSTGRES_HOST="104.154.78.29" \
-e POSTGRES_PASSWORD="LGJQ\<ZV.gEpNE8*" \
-e POSTGRES_USERNAME="payram" \
-e PAYMENTS_APP_SERVER_URL="https://develop.payments.betora.vip" \
-v /home/ubuntu/.payram-core:/root/payram \
-v /home/ubuntu/.payram-core/db/postgres:/var/lib/payram/db/postgres \
-v /home/ubuntu/.payram-core/log/supervisord:/var/log \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /home/ubuntu/testnetdocs:/docs \
$IMAGE_NAME:$TAG
if [ $? -eq 0 ]; then
log_message "$TESTNET_CONTAINER is running."
TESTNET_STATUS="✅"
else
log_message "ERROR: Failed to start $TESTNET_CONTAINER"
send_slack_notification "⚠️ *Testnet Start Failed*\n\nFailed to start \`$TESTNET_CONTAINER\` container" "error"
fi
fi
# Start Mainnet Container (if backup was successful)
if [ "$MAINNET_BACKUP_SUCCESS" = true ]; then
log_message "Starting $MAINNET_CONTAINER..."
docker run -d \
--name $MAINNET_CONTAINER \
--publish 9001:8080 \
--publish 9002:8443 \
--publish 9003:80 \
--publish 9004:443 \
--publish 9005:5432 \
-e AES_KEY="932732708e8b3beea4ddfa02841f2c82bfef0b24d73067a98e324d1f28200876" \
-e SSL_CERT_PATH="/etc/letsencrypt/live/mainnet.resuefas.vip" \
-e BLOCKCHAIN_NETWORK_TYPE="mainnet" \
-e SERVER="PRODUCTION" \
-e POSTGRES_HOST="localhost" \
-e POSTGRES_PORT="5432" \
-e POSTGRES_DATABASE="payram" \
-e POSTGRES_USERNAME="payram" \
-e POSTGRES_PASSWORD="payram123" \
-v /home/ubuntu/.mainnet/data:/root/payram \
-v /home/ubuntu/.mainnet/log/supervisord:/var/log \
-v /home/ubuntu/.mainnet/db/postgres:/var/lib/payram/db/postgres \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /home/ubuntu/mainnetdocs:/docs \
$IMAGE_NAME:$TAG
if [ $? -eq 0 ]; then
log_message "$MAINNET_CONTAINER is running."
MAINNET_STATUS="✅"
else
log_message "ERROR: Failed to start $MAINNET_CONTAINER"
send_slack_notification "⚠️ *Mainnet Start Failed*\n\nFailed to start \`$MAINNET_CONTAINER\` container" "error"
fi
fi
log_message "Container processing completed."
# Send final status notification
if [ "$TESTNET_STATUS" == "✅" ] || [ "$MAINNET_STATUS" == "✅" ]; then
send_slack_notification "🎉 *Update Completed!*\n\n*Status:*\n• Testnet: $TESTNET_STATUS\n• Mainnet: $MAINNET_STATUS\n\nImage: \`$IMAGE_NAME:$TAG\`" "success"
elif [ "$FORCE_RESTART" == "force" ]; then
send_slack_notification "🔄 *Force Restart Completed*\n\n*Status:*\n• Testnet: $TESTNET_STATUS\n• Mainnet: $MAINNET_STATUS" "info"
fi
# Perform cleanup explicitly after the docker run command
cleanup
# Correct use of docker prune command (after cleanup)
docker image prune -f