[libvirt] [jenkins-ci PATCH v2 03/12] lcitool: Add tool configuration handling

Andrea Bolognani abologna at redhat.com
Thu Jul 12 15:19:20 UTC 2018


The on-disk configuration format and its behavior
are fully backwards compatible with the previous
implementation.

Signed-off-by: Andrea Bolognani <abologna at redhat.com>
---
 guests/lcitool | 112 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

diff --git a/guests/lcitool b/guests/lcitool
index 1cba8ad..e03b388 100755
--- a/guests/lcitool
+++ b/guests/lcitool
@@ -18,6 +18,10 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 import argparse
+import crypt
+import os
+import random
+import string
 import sys
 import textwrap
 
@@ -32,9 +36,117 @@ class Error(Exception):
     def __init__(self, message):
         self.message = message
 
+class Util:
+
+    @staticmethod
+    def mksalt():
+        alphabeth = string.ascii_letters + string.digits
+        salt = "".join(random.choice(alphabeth) for x in range(0, 16))
+        return "$6${}$".format(salt)
+
+class Config:
+
+    def _get_config_file(self, name):
+        try:
+            config_dir = os.environ["XDG_CONFIG_HOME"]
+        except KeyError:
+            config_dir = os.path.join(os.environ["HOME"], ".config/")
+        config_dir = os.path.join(config_dir, "lcitool/")
+
+        # Create the directory if it doesn't already exist
+        if not os.path.exists(config_dir):
+            try:
+                os.mkdir(config_dir)
+            except:
+                raise Error(
+                    "Can't create configuration directory ({})".format(
+                        config_dir,
+                    )
+                )
+
+        return os.path.join(config_dir, name)
+
+    def get_flavor(self):
+        flavor_file = self._get_config_file("flavor")
+
+        try:
+            with open(flavor_file, "r") as f:
+                flavor = f.readline().strip()
+        except:
+            # If the flavor has not been configured, we choose the default
+            # and store it on disk to ensure consistent behavior from now on
+            flavor = "test"
+            try:
+                with open(flavor_file, "w") as f:
+                    f.write("{}\n".format(flavor))
+            except:
+                raise Error(
+                    "Can't write flavor file ({})".format(
+                        flavor_file,
+                    )
+                )
+
+        if flavor != "test" and flavor != "jenkins":
+            raise Error("Invalid flavor '{}'".format(flavor))
+
+        return flavor
+
+    def get_vault_password_file(self):
+        vault_pass_file = None
+
+        # The vault password is only needed for the jenkins flavor, but in
+        # that case we want to make sure there's *something* in there
+        if self.get_flavor() != "test":
+            vault_pass_file = self._get_config_file("vault-password")
+
+            try:
+                with open(vault_pass_file, 'r') as f:
+                    if len(f.readline().strip()) == 0:
+                        raise ValueError
+            except:
+                raise Error(
+                    "Missing or invalid vault password file ({})".format(
+                        vault_pass_file,
+                    )
+                )
+
+        return vault_pass_file
+
+    def get_root_password_file(self):
+        root_pass_file = self._get_config_file("root-password")
+        root_hash_file = self._get_config_file(".root-password.hash")
+
+        try:
+            with open(root_pass_file, "r") as f:
+                root_pass = f.readline().strip()
+        except:
+            raise Error(
+                "Missing or invalid root password file ({})".format(
+                    root_pass_file,
+                )
+            )
+
+        # The hash will be different every time we run, but that doesn't
+        # matter - it will still validate the correct root password
+        root_hash = crypt.crypt(root_pass, Util.mksalt())
+
+        try:
+            with open(root_hash_file, "w") as f:
+                f.write("{}\n".format(root_hash))
+        except:
+            raise Error(
+                "Can't write hashed root password file ({})".format(
+                    root_hash_file,
+                )
+            )
+
+        return root_hash_file
+
 class Application:
 
     def __init__(self):
+        self._config = Config()
+
         self._parser = argparse.ArgumentParser(
             conflict_handler = "resolve",
             formatter_class = argparse.RawDescriptionHelpFormatter,
-- 
2.17.1




More information about the libvir-list mailing list