CISYNCR: Automating Cloud Images
CISYNCR is designed to automate the retrieval and management of Ubuntu cloud images for the amd64
architecture.
Features
- Automated retrieval of SHA256 checksums.
- Filters for
amd64
architecture. - Automated download of the latest Ubuntu cloud images.
- Integrity verification using SHA256 checksums.
- Logging and updating a MySQL database.
- Telegram notifications for updates.
Prerequisites
- Bash shell
- curl
- MySQL client
- Access to a Telegram bot for notifications
Setup and Usage
Get the
cisyncr-ubuntu.sh
anddatabase.sql
file.- Make the script executable and import database.
1 2
chmod +x ubuntu-cisyncr.sh mysql < database.sql
- Update the configuration section at the beginning of the script with your specific details.
- Execute the script:
1
./cisyncr-ubuntu.sh
Files
cisyncr-ubuntu.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
#!/bin/bash
# Configuration variables
TELEGRAM_BOT_TOKEN="0987654321:TOKEN"
TELEGRAM_CHAT_ID="-123456789"
MYSQL_USER="user"
MYSQL_PASS="pass"
MYSQL_HOST="host"
MYSQL_DB="ubuntu_cloud_images"
BASE_URL="https://cloud-images.ubuntu.com"
DESTINATION_PATH="images"
mkdir $DESTINATION_PATH
# Function to send Telegram alert
send_telegram() {
local message=$1
curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" -d chat_id=$TELEGRAM_CHAT_ID -d text="$message" > /dev/null
}
# Function to check and download Ubuntu images
check_and_download_ubuntu() {
local version=$1
# Fetch SHA256SUMS file
curl -s -O $BASE_URL/$version/current/SHA256SUMS
# Filter out unwanted architectures
sed -i '/ppc64el\|arm64\|i386\|s390x\|armhf\|powerpc\|uefi/d' SHA256SUMS
echo "Filtered contents of SHA256SUMS for $version:"
cat SHA256SUMS
echo "--------------------------"
# Extract line with .img that contains both "amd64" and "cloudimg" from SHA256SUMS
IMG_SUM_LINE=$(grep "\.img" SHA256SUMS | grep "amd64" | grep "cloudimg")
# If no matching .img found, then check for just "amd64" and ".img"
if [[ -z "$IMG_SUM_LINE" ]]; then
IMG_SUM_LINE=$(grep "\.img" SHA256SUMS | grep "amd64")
fi
# If still no matching .img found, log an error and exit this function iteration
if [[ -z "$IMG_SUM_LINE" ]]; then
echo "No suitable .img found for $version. Skipping..."
send_telegram "No suitable .img found for $version. Please check the source!"
return
fi
echo "Extracted suitable .img line: $IMG_SUM_LINE"
# Split checksum and filename
CHECKSUM=$(echo $IMG_SUM_LINE | awk '{print $1}')
IMG_FILE=$(echo $IMG_SUM_LINE | awk '{print $2}'|sed 's/*//g')
# Check if image exists
if [[ -f "$DESTINATION_PATH/$IMG_FILE" ]]; then
LOCAL_CHECKSUM=$(sha256sum "$DESTINATION_PATH/$IMG_FILE" | awk '{print $1}')
if [[ "$LOCAL_CHECKSUM" == "$CHECKSUM" ]]; then
echo "File $IMG_FILE is up-to-date."
# Update the last check timestamp for this image
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASS $MYSQL_DB -e "UPDATE images SET last_check_timestamp=NOW() WHERE filename='$IMG_FILE';"
return
else
# If there's a new version, mark the old one as not current
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASS $MYSQL_DB -e "UPDATE images SET current_version=false WHERE filename='$IMG_FILE';"
fi
else
echo "File $IMG_FILE not found locally. Downloading..."
fi
# Download .img file
curl -s -O $BASE_URL/$version/current/$IMG_FILE
# Verify the checksum
echo "$CHECKSUM $IMG_FILE" | sha256sum --check -
if [[ $? -eq 0 ]]; then
# Move file if integrity is confirmed
mv $IMG_FILE $DESTINATION_PATH/
# Log to database
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASS $MYSQL_DB -e "INSERT INTO images (operating_system, distribution, distro_version, filename, current_version, genesis_timestamp) VALUES ('Linux', 'Ubuntu', '$version', '$IMG_FILE', true, NOW()) ON DUPLICATE KEY UPDATE current_version=true, last_check_timestamp=NOW();"
# Send Telegram alert
send_telegram "File $IMG_FILE has been downloaded, verified, and moved successfully."
else
# Notify about the mismatch
send_telegram "Checksum verification failed for $IMG_FILE. The file has not been moved."
fi
}
# Check and download for specified Ubuntu versions
for version in "focal" "bionic" "xenial" "trusty"; do
check_and_download_ubuntu $version
done
Set up your MySQL database using the following dump:
database.sql
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
-- MySQL dump 10.19 Distrib 10.3.38-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost Database: ubuntu_cisyncr
-- ------------------------------------------------------
-- Server version 10.3.38-MariaDB-0ubuntu0.20.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `images`
--
DROP TABLE IF EXISTS `images`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `images` (
`image_id` int(11) NOT NULL AUTO_INCREMENT,
`operating_system` varchar(255) NOT NULL,
`distribution` varchar(255) NOT NULL,
`distro_version` varchar(255) NOT NULL,
`filename` varchar(255) NOT NULL,
`current_version` tinyint(1) DEFAULT NULL,
`genesis_timestamp` datetime NOT NULL,
`last_check_timestamp` datetime DEFAULT NULL,
PRIMARY KEY (`image_id`)
) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `images`
--
LOCK TABLES `images` WRITE;
/*!40000 ALTER TABLE `images` DISABLE KEYS */;
INSERT INTO `images` VALUES (14,'Linux','Ubuntu','focal','focal-server-cloudimg-amd64.img',0,'2023-09-10 23:58:18','2023-09-11 00:07:13'),(15,'Linux','Ubuntu','bionic','bionic-server-cloudimg-amd64.img',0,'2023-09-10 23:58:30','2023-09-26 18:04:03'),(16,'Linux','Ubuntu','xenial','xenial-server-cloudimg-amd64-disk1.img',0,'2023-09-10 23:58:41','2023-09-26 18:04:06'),(17,'Linux','Ubuntu','trusty','trusty-server-cloudimg-amd64-disk1.img',0,'2023-09-10 23:58:50','2023-09-11 00:07:21'),(18,'Linux','Ubuntu','focal','focal-server-cloudimg-amd64.img',0,'2023-09-10 23:59:46','2023-09-11 00:07:13'),(19,'Linux','Ubuntu','bionic','bionic-server-cloudimg-amd64.img',0,'2023-09-10 23:59:59','2023-09-26 18:04:03'),(20,'Linux','Ubuntu','xenial','xenial-server-cloudimg-amd64-disk1.img',0,'2023-09-11 00:00:57','2023-09-26 18:04:06'),(21,'Linux','Ubuntu','trusty','trusty-server-cloudimg-amd64-disk1.img',0,'2023-09-11 00:01:06','2023-09-11 00:07:21'),(22,'Linux','Ubuntu','focal','focal-server-cloudimg-amd64.img',0,'2023-09-11 00:02:36','2023-09-11 00:07:13'),(23,'Linux','Ubuntu','bionic','bionic-server-cloudimg-amd64.img',1,'2023-09-11 00:02:49','2023-09-26 18:04:03'),(24,'Linux','Ubuntu','xenial','xenial-server-cloudimg-amd64-disk1.img',1,'2023-09-11 00:03:01','2023-09-26 18:04:06'),(25,'Linux','Ubuntu','trusty','trusty-server-cloudimg-amd64-disk1.img',1,'2023-09-11 00:03:10','2023-09-11 00:07:21'),(26,'Linux','CentOS','8','CentOS-8-ec2-8.4.2105-20210603.0.x86_64.qcow2\">CentOS-8-ec2-8.4.2105-20210603.0.x86_64.qcow2',1,'2023-09-11 00:19:46','2023-09-11 00:19:54'),(27,'Linux','CentOS','9-stream','CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2',0,'2023-09-11 01:16:41','2023-09-11 02:14:26'),(28,'Linux','CentOS','9-stream','CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2',0,'2023-09-11 01:22:20','2023-09-11 02:14:26'),(29,'Linux','CentOS','9-stream','CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2',0,'2023-09-11 01:31:41','2023-09-11 02:14:26'),(30,'Linux','CentOS','9-stream','CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2\nCentOS-Stream-GenericCloud-9-latest.x86_64.qcow2',1,'2023-09-11 04:35:05',NULL),(31,'Linux','CentOS','8-stream','CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2\nCentOS-Stream-GenericCloud-8-latest.x86_64.qcow2',1,'2023-09-11 04:35:55',NULL),(32,'Linux','CentOS','8','CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2',1,'2023-09-11 04:36:34',NULL),(33,'Linux','CentOS','9-stream','CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2\nCentOS-Stream-GenericCloud-9-latest.x86_64.qcow2',1,'2023-09-11 04:39:00',NULL),(34,'Linux','CentOS','9-stream','CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2',0,'2023-09-11 04:40:41',NULL),(35,'Linux','CentOS','9-stream','CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2',1,'2023-09-11 04:43:27',NULL),(36,'Linux','CentOS','9-stream','CentOS-Stream-GenericCloud-9-20230904.0.x86_64.qcow2',0,'2023-09-11 05:01:21',NULL),(37,'Linux','Ubuntu','focal','focal-server-cloudimg-amd64.img',1,'2023-09-26 18:03:58',NULL),(38,'Linux','Ubuntu','trusty','trusty-server-cloudimg-amd64-disk1.img',1,'2023-09-26 18:04:15',NULL);
/*!40000 ALTER TABLE `images` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2023-09-26 18:14:55
This post is licensed under CC BY 4.0 by the author.