The on-disk configuration format and its behavior
are fully backwards compatible with the previous
implementation.
Signed-off-by: Andrea Bolognani <abologna@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
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Jul 12, 2018 at 05:19:20PM +0200, Andrea Bolognani wrote:
> The on-disk configuration format and its behavior
> are fully backwards compatible with the previous
> implementation.
>
> Signed-off-by: Andrea Bolognani <abologna@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:
And it's generally discouraged to use a bare except because it catches
BaseException. Be at least as specific as Exception, and here
specifically, perhaps catch IOError.
> + # 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":
More pythonic would be "flavor not in ('test', '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
>
> --
> libvir-list mailing list
> libvir-list@redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Tue, 2018-07-17 at 11:40 +0200, Katerina Koukiou wrote:
> On Thu, Jul 12, 2018 at 05:19:20PM +0200, Andrea Bolognani wrote:
> > + try:
> > + with open(flavor_file, "r") as f:
> > + flavor = f.readline().strip()
> > + except:
>
> And it's generally discouraged to use a bare except because it catches
> BaseException. Be at least as specific as Exception, and here
> specifically, perhaps catch IOError.
Okay, I've done some reading about Exception vs BaseException and
I think I see now why you would want to catch the former but not
the latter.
Catching IOError specifically doesn't seem too useful here,
though, because it would still result in an Error being raised
and the program ultimately exiting. Or am I missing something?
> > + if flavor != "test" and flavor != "jenkins":
>
> More pythonic would be "flavor not in ('test', 'jenkins')"
Okay.
--
Andrea Bolognani / Red Hat / Virtualization
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2026 Red Hat, Inc.