From b43f8126a24fbb298225816d3b78d7669619b544 Mon Sep 17 00:00:00 2001
From: Fulvio Galeazzi <fulvio.galeazzi@garr.it>
Date: Fri, 6 Oct 2023 11:21:33 +0000
Subject: [PATCH] 2023-10-06:  FG;  Aggiunto opzioni allo script: seleziona
 immagini sulla base del nome, forza download, esegui scrittura su Glance (di
 default, NON scrive).

---
 README.md        | 26 ++++++++-------
 update-images.py | 85 +++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 83 insertions(+), 28 deletions(-)

diff --git a/README.md b/README.md
index b067f7a..38c8bb3 100644
--- a/README.md
+++ b/README.md
@@ -5,17 +5,18 @@ This script automates the process of updating images of operating systems in Ope
 
 ### Currently the supported OS are:
 
-- CentOS 7
-- CentOS 8
-- Debian 9
+- CentOS 8stream
+- Debian 9stream
 - Debian 10
 - Debian 11
-- Fedora 32
-- Fedora 33
-- Fedora 34
-- Ubuntu 16.04
+- Debian 12
+- Fedora 37
+- Fedora 38
+- RockyLinux 8
+- RockyLinux 9
 - Ubuntu 18.04
 - Ubuntu 20.04
+- Ubuntu 22.04
 
 Installation
 ------------
@@ -36,11 +37,11 @@ Source the `admin` credentials to gain access to `OpenStack` commands:
 
 Execute the script
 
-	$ python3 update-images.py
+	$ python3 update-images.py [-v] [-p <patterns>] [-f] [-w]
 
 ### Execution example
 
-	$ python3 update-images.py
+	$ python3 update-images.py -w
 	Download...
 	From: http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2
 	To:   downloads/centos7-1505262668.qcow2
@@ -73,9 +74,10 @@ After updating the images, update the simplestreams catalog:
 Pipeline
 --------
 
-1. Fetch from config.yaml the url
-2. Download locally (in 'download' folder) the updated qcow2 of specified operating system
-3. Upload the qcow2 image on glance using openstack-cli commands
+1. Fetch from config.yaml the url: filter by name using -p switch
+2. Download locally (in 'download' folder) the updated qcow2 of specified
+   operating system: force download with -f switch
+3. Upload the qcow2 image on glance using openstack-cli commands: requires -w switch
 
 Notes
 -----
diff --git a/update-images.py b/update-images.py
index c796384..5a9d1f8 100755
--- a/update-images.py
+++ b/update-images.py
@@ -8,6 +8,7 @@ import os
 from pprint import pprint
 import shade
 import subprocess
+import argparse
 
 from tqdm import tqdm
 
@@ -28,6 +29,33 @@ def download_from_url(url, output_file):
     pbar.close()
     return file_size
 
+#####
+
+parser = argparse.ArgumentParser(
+    description="Download and update cloud images.")
+parser.add_argument("-p", "--patterns",
+                    help="Comma-separated string of patterns matching desired image names")
+parser.add_argument("-f", "--force",
+                    help="Ignore times, force download", action='store_true')
+parser.add_argument("-w", "--write",
+                    help="Update OpenStack Glance, write image (default=false)",
+                    action='store_true')
+parser.add_argument("-v", "--verbose",
+                    help="Set VERBOSE logging level", action='store_true')
+opts = parser.parse_args()
+
+namePatterns = []
+if opts.patterns:
+    namePatterns = opts.patterns.lower().split(',')
+    print("INFO: only select images matching following string:",namePatterns)
+
+if opts.force:
+    print("INFO: force option is set, force download images")
+if opts.write:
+    print("INFO: write option is set, update Glance")
+else:
+    print("INFO: write option NOT set, not updating Glance")
+    
 config = None
 with open('config.yml') as fh_config:
     config = yaml.safe_load(fh_config)
@@ -40,20 +68,37 @@ if not os.path.isdir(download_dir):
 openstack_cloud_connection = shade.openstack_cloud()
 
 for image_key in sorted(config['images'].keys()):
-    print("=== Image name: {}".format(image_key))
+    doThis = 1
+    if len(namePatterns):
+        doThis = 0
+        for np in namePatterns:
+            thisName = config['images'][image_key]['name']
+            if np in thisName.lower():
+                print("=== Found image name: {}".format(thisName))
+                doThis = 1
+    if doThis:
+        print("=== Process Image key: {}".format(image_key))
+    else:
+        print("=== Skip    Image key: {}".format(image_key))
+        continue
+    
     if not 'url' in config['images'][image_key]:
-        print("skipping...")
+        print("skipping... ",config['images'][image_key],"no URL provided")
         continue
     url = config['images'][image_key]['url']
     request_response = requests_session.head(url, allow_redirects=True)
     request_response.raise_for_status()
 
     http_last_modified = request_response.headers['Last-Modified']
-    last_modified_time  = datetime.datetime.strptime(http_last_modified, '%a, %d %b %Y %H:%M:%S GMT')
+    last_modified_time  = datetime.datetime.strptime(http_last_modified,
+                                                     '%a, %d %b %Y %H:%M:%S GMT')
     image_name = config['images'][image_key]['name']
 
     image = openstack_cloud_connection.get_image(name_or_id=image_name)
-    download = False
+    if opts.force:
+        download = True
+    else:
+        download = False
     dateNow = datetime.datetime.now()
     dateNowStr = dateNow.strftime("%Y/%m/%d")
     descNewImg = "%s: downloaded from %s" % (dateNowStr, url)
@@ -67,12 +112,16 @@ for image_key in sorted(config['images'].keys()):
 
         if last_modified_time > last_update:
             download = True
+        else:
+            print("  --- not downloading (image update time)")
 
         if 'metadata' in image and 'last_modified' in image['metadata']:
             last_modified_from_image = datetime.datetime.strptime(image['metadata']['last_modified'], '%Y-%m-%d %H:%M:%S')
 
             if last_modified_time > last_modified_from_image:
                 download = True
+            else:
+                print("  --- not downloading (image metadata)")
 
         if download:
             # Add to description field
@@ -82,9 +131,12 @@ for image_key in sorted(config['images'].keys()):
                 descOldImg = "%s \n %s" % (descOldImg, descCur)
             # Rename image, update description, set image as private
             image_name_old = "%s %s" % (image_name, dateNowStr)
-            print ("Rename old image, set private, update description: \n \t openstack image set --private --property description=\"{}\" --name \"{}\" {}".format(descOldImg[:30], image_name_old, image['id']))
-            subprocess.call("openstack image set --private --property description=\"{}\" --name \"{}\" {}".format(descOldImg, image_name_old, image['id']), shell=True)
-
+            if opts.write:
+                print ("Rename old image, set private, update description: \n \t openstack image set --private --property description=\"{}\" --name \"{}\" {}".format(descOldImg[:30], image_name_old, image['id']))
+                subprocess.call("openstack image set --private --property description=\"{}\" --name \"{}\" {}".format(descOldImg, image_name_old, image['id']), shell=True)
+            else:
+                print ("WRITE_UNSET: would rename old image, set private, update description: \n \t openstack image set --private --property description=\"{}\" --name \"{}\" {}".format(descOldImg[:30], image_name_old, image['id']))
+                
     if download:
         download_image_file = download_dir
         download_image_file += image_key
@@ -115,12 +167,13 @@ for image_key in sorted(config['images'].keys()):
             argsDict.update({'meta':tagDict})
         print("Args dictionary: {}".format(argsDict))
 
-        time0 = int(time.time())
-        openstack_cloud_connection.create_image(image_name,
-                                                filename=download_image_file,
-                                                disk_format=config['images'][image_key]['disk_format'],
-                                                description=descNewImg,
-                                                **argsDict,
-                                                wait=True,is_public=True)
-        time1 = int(time.time())
-        print("Uploaded to Glance in {} seconds".format(time1-time0))
+        if opts.write:
+            time0 = int(time.time())
+            openstack_cloud_connection.create_image(image_name,
+                                                    filename=download_image_file,
+                                                    disk_format=config['images'][image_key]['disk_format'],
+                                                    description=descNewImg,
+                                                    **argsDict,
+                                                    wait=True,is_public=True)
+            time1 = int(time.time())
+            print("Uploaded to Glance in {} seconds".format(time1-time0))
-- 
GitLab