Juan Hernandez has uploaded a new change for review.

Change subject: packaging: Find and check JVM during setup (#834436)
......................................................................

packaging: Find and check JVM during setup (#834436)

https://bugzilla.redhat.com/834436

We used to have a hardcoded setting in the engine.conf.defaults file for
the location of the Java virtual machine. This patch changes the
engine-setup tool so that it will try to find a suitable JVM (suitable means
OpenJDK 1.7 at the moment) automatically. The location of the JVM will
then be written to the JAVA_HOME configuration parameter in the
/etc/sysconfig/ovirt-engine  file.

Change-Id: Ib279ea8111825ec35a25f9ba6ee37b481ed4354f
Signed-off-by: Juan Hernandez <[email protected]>
---
M packaging/fedora/setup/basedefs.py
M packaging/fedora/setup/common_utils.py
M packaging/fedora/setup/engine-setup.py
M packaging/fedora/setup/output_messages.py
4 files changed, 133 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/49/7549/1

diff --git a/packaging/fedora/setup/basedefs.py 
b/packaging/fedora/setup/basedefs.py
index 0a12e6b..2bf431d 100644
--- a/packaging/fedora/setup/basedefs.py
+++ b/packaging/fedora/setup/basedefs.py
@@ -174,3 +174,14 @@
 ovirt-engine-userportal
 ovirt-engine-webadmin-portal
 """
+
+# The list of directories where java virtual machines will be searched
+# for:
+JAVA_SEARCH_DIRS = [
+    "/usr/lib/jvm",
+]
+
+# Supported java virtual machines should give an string matching this regular
+# expresion when given the -version option (the current value means OpenJDK 7):
+JAVA_VERSION_EXPR = r"1\.7\.0_[0-9]*-icedtea"
+
diff --git a/packaging/fedora/setup/common_utils.py 
b/packaging/fedora/setup/common_utils.py
index 357b63d..6d55ffb 100755
--- a/packaging/fedora/setup/common_utils.py
+++ b/packaging/fedora/setup/common_utils.py
@@ -919,12 +919,15 @@
 
     return (values["fqdn"], values["httpPort"], values["httpsPort"])
 
-def editEngineSysconfig(proxyEnabled, dbUrl, dbUser, fqdn, http, https):
+def editEngineSysconfig(proxyEnabled, dbUrl, dbUser, fqdn, http, https, 
javaHome):
     # Load the file:
     logging.debug("Loading text file handler")
     handler = TextConfigFileHandler(basedefs.FILE_ENGINE_SYSCONFIG)
     handler.open()
 
+    # Save the Java home:
+    handler.editParam("JAVA_HOME", javaHome)
+
     handler.editParam("ENGINE_DB_DRIVER", "org.postgresql.Driver")
     handler.editParam("ENGINE_DB_URL", dbUrl)
     handler.editParam("ENGINE_DB_USER", dbUser)
diff --git a/packaging/fedora/setup/engine-setup.py 
b/packaging/fedora/setup/engine-setup.py
index 820145c..0bc91a6 100755
--- a/packaging/fedora/setup/engine-setup.py
+++ b/packaging/fedora/setup/engine-setup.py
@@ -21,6 +21,7 @@
 import common_utils as utils
 import engine_validators as validate
 import random
+import subprocess
 import tempfile
 from optparse import OptionParser, OptionGroup
 from setup_controller import Controller
@@ -125,6 +126,8 @@
                         'condition_match' : [],
                         'steps'           : [ { 'title'     : 
output_messages.INFO_CONFIG_OVIRT_ENGINE,
                                                 'functions' : 
[setMaxSharedMemory] },
+                                              { 'title'     : 
output_messages.INFO_FIND_JAVA,
+                                                'functions' : [findJava]},
                                               { 'title'     : 
output_messages.INFO_CREATE_CA,
                                                 'functions' : [_createCA]},
                                               { 'title'     : 
output_messages.INFO_UPD_JBOSS_CONF,
@@ -1877,7 +1880,8 @@
                               dbUser=utils.getDbUser(),
                               fqdn=controller.CONF["HOST_FQDN"],
                               http=controller.CONF["HTTP_PORT"],
-                              https=controller.CONF["HTTPS_PORT"])
+                              https=controller.CONF["HTTPS_PORT"],
+                              javaHome=controller.CONF["JAVA_HOME"])
 
 def startRhevmDbRelatedServices():
     """
@@ -1895,6 +1899,115 @@
         logging.warn("Failed to start rhevm-notifierd")
         controller.MESSAGES.append(output_messages.ERR_FAILED_START_SERVICE % 
"rhevm-notifierd")
 
+def isJavaVersionSupported(version):
+    # Check that the version matches the expected regular expression:
+    match = re.search(basedefs.JAVA_VERSION_EXPR, version)
+    if not match:
+        logging.debug("Java version \"%s\" doesn't match regular expression 
\"%s\"." % (version, basedefs.JAVA_VERSION_EXPR))
+        return False
+
+    # If we are here it is an acceptable java version:
+    return True
+
+def isJavaExecutable(path):
+    # Check that the name:
+    if not path.endswith("/bin/java"):
+        return False
+
+    # Check that it is not a symbolic link:
+    if os.path.islink(path):
+        logging.debug("Ignoring \"%s\" because it is a symlink." % path)
+        return False
+
+    # Check that it is executable:
+    if not os.access(path, os.X_OK):
+        logging.debug("Ignoring \"%s\" because it isn't executable." % path)
+        return False
+
+    # Invoke it to see what is the version number:
+    process = subprocess.Popen([path, "-version"], stdout=subprocess.PIPE, 
stderr=subprocess.PIPE)
+    output, errors = process.communicate()
+    result = process.wait()
+    if result != 0:
+        logging.debug("Ignoring \"%s\" because it returns exit code %d." % 
(path, result))
+        return False
+
+    # Try to find the version number in the error output (the java
+    # command writes it to stderr, not to stdout):
+    match = re.search('java version "([^"]*)"', errors)
+    if not match:
+        logging.debug("Ignoring \"%s\" because it doesn't provide the version 
number." % path)
+        return False
+    version = match.group(1)
+
+    # Check that the version is supported:
+    if not isJavaVersionSupported(version):
+        logging.debug("Ignoring \"%s\" because the java version \"%s\" is not 
supported." % (path, version))
+        return False
+
+    # It passed all the checks, so it is a java virtual machine:
+    return True
+
+def isLinkTo(link, path):
+    # Do nothing if it is not a link:
+    if not os.path.islink(link):
+        return False
+
+    # Make the target an absolute path:
+    target = os.readlink(link)
+    if not target.startswith("/"):
+        target = os.path.join(os.path.dirname(link), target)
+
+    # Compare the target with the given path:
+    return target == path
+
+def findJava():
+    # Try to find java executables:
+    javaPaths = []
+    for javaSearchDir in basedefs.JAVA_SEARCH_DIRS:
+        for parentDir, childrenDirs, childrenFiles in os.walk(javaSearchDir):
+            for childrenFile in childrenFiles:
+                childrenPath = os.path.join(parentDir, childrenFile)
+                if isJavaExecutable(childrenPath):
+                    javaPaths.append(childrenPath)
+
+    # We prefer JRE over JDK, mainly because it is more stable, I mean,
+    # a JRE will be always present if there is a JDK, but not the other
+    # way around:
+    javaPaths.sort(key=lambda path: not path.endswith("/jre/bin/java"))
+
+    # We need at least one value in the list:
+    if not javaPaths:
+        logging.error("Can't find any supported java virtual machine.")
+        raise Exception(output_messages.ERR_EXP_CANT_FIND_SUPPORTED_JAVA)
+
+    # Calculate the home directory of the Java virtual machine:
+    javaPath = javaPaths[0]
+    javaBin = os.path.dirname(javaPath)
+    javaHome = os.path.dirname(javaBin)
+
+    # Check if there are symbolic links in the same search path, and then
+    # replace with one of them (this is to avoid having a micro verion in the
+    # name that will break when the package is updated):
+    javaHomeLinks = []
+    for javaSearchDir in basedefs.JAVA_SEARCH_DIRS:
+        for parentDir, childrenDirs, childrenFiles in os.walk(javaSearchDir):
+            for childrenDir in childrenDirs:
+                childrenPath = os.path.join(parentDir, childrenDir)
+                if isLinkTo(childrenPath, javaHome):
+                    javaHomeLinks.append(childrenPath)
+
+    # We prefer the shorter link:
+    javaHomeLinks.sort(key=lambda path: len(path))
+
+    # Replace the java home with the first link:
+    if javaHomeLinks:
+        javaHome = javaHomeLinks[0]
+
+    # Save the result:
+    logging.debug("Java home is \"%s\"." % javaHome)
+    controller.CONF["JAVA_HOME"] = javaHome
+
 def isSecondRun():
     keystore = os.path.join(basedefs.DIR_OVIRT_PKI, ".keystore")
 
diff --git a/packaging/fedora/setup/output_messages.py 
b/packaging/fedora/setup/output_messages.py
index 516a4eb..a98fd9a 100644
--- a/packaging/fedora/setup/output_messages.py
+++ b/packaging/fedora/setup/output_messages.py
@@ -31,6 +31,7 @@
 INFO_SET_DB_CONFIGURATION="Setting Database Configuration"
 INFO_CONFIG_OVIRT_ENGINE="Configuring oVirt-engine"
 INFO_CONFIG_HTTPD="Configuring HTTPD"
+INFO_FIND_JAVA="Configuring Java Virtual Machine"
 INFO_CREATE_CA="Creating CA"
 INFO_CREATE_DB="Creating Database"
 INFO_UPGRADE_DB="Upgrading Database Schema"
@@ -391,6 +392,9 @@
 # edit ssl.conf
 ERR_EXP_UPD_HTTPD_SSL_CONFIG="Failed updating ssl configuration file %s"
 
+# Search of Java virtual machines:
+ERR_EXP_CANT_FIND_SUPPORTED_JAVA="Error: Can't find any supported Java virtual 
machine"
+
 # create ovirt-engine.conf
 ERR_CREATE_OVIRT_HTTPD_CONF="Failed creating ovirt-engine.conf file %s"
 


--
To view, visit http://gerrit.ovirt.org/7549
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib279ea8111825ec35a25f9ba6ee37b481ed4354f
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Juan Hernandez <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to