Roy Golan has uploaded a new change for review.

Change subject: core: [WIP] Manage OS properties in a repository
......................................................................

core: [WIP] Manage OS properties in a repository

Change-Id: I50384bf3b6763fa7a34badc2449e06242186a858
Signed-off-by: Roy Golan <rgo...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java
A 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OsRepositoryQuery.java
A backend/manager/modules/bll/src/main/resources/00-os.properties
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/MapBackedPreferences.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/OsRepository.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/OsRepositoryImpl.java
A 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/OsQueryParameters.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
A 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/OsLoader.java
A 
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/osinfo/OsInfoPreferencesLoader.java
10 files changed, 788 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/80/15080/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java
index 29e7545..7589af7 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/Backend.java
@@ -42,6 +42,7 @@
 import org.ovirt.engine.core.common.interfaces.ITagsHandler;
 import org.ovirt.engine.core.common.interfaces.VDSBrokerFrontend;
 import org.ovirt.engine.core.common.job.JobExecutionStatus;
+import org.ovirt.engine.core.common.osinfo.OsRepositoryImpl;
 import org.ovirt.engine.core.common.queries.ConfigurationValues;
 import org.ovirt.engine.core.common.queries.GetConfigurationValueParameters;
 import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
@@ -61,6 +62,7 @@
 import org.ovirt.engine.core.utils.ejb.EjbUtils;
 import org.ovirt.engine.core.utils.log.Log;
 import org.ovirt.engine.core.utils.log.LogFactory;
+import org.ovirt.engine.core.utils.osinfo.OsInfoPreferencesLoader;
 import org.ovirt.engine.core.utils.timer.SchedulerUtilQuartzImpl;
 
 // Here we use a Singleton Bean
@@ -208,6 +210,9 @@
                     sessionTimoutInterval,
                     sessionTimoutInterval, TimeUnit.MINUTES);
         }
+
+        initOsRepository();
+
         // Set start-up time
         _startedAt = DateTime.getNow();
 
@@ -567,5 +572,10 @@
         SchedulerUtilQuartzImpl.getInstance().triggerJob(poolMonitoringJobId);
     }
 
+    private void initOsRepository() {
+        OsInfoPreferencesLoader.INSTANCE.init();
+        
OsRepositoryImpl.INSTANCE.init(OsInfoPreferencesLoader.INSTANCE.getPreferences());
+    }
+
     private static final Log log = LogFactory.getLog(Backend.class);
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OsRepositoryQuery.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OsRepositoryQuery.java
new file mode 100644
index 0000000..c00126d
--- /dev/null
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/OsRepositoryQuery.java
@@ -0,0 +1,41 @@
+package org.ovirt.engine.core.bll;
+
+import org.ovirt.engine.core.common.osinfo.OsRepositoryImpl;
+import org.ovirt.engine.core.common.queries.OsQueryParameters;
+
+public class OsRepositoryQuery<P extends OsQueryParameters> extends 
QueriesCommandBase<P> {
+
+    public OsRepositoryQuery(P parameters) {
+        super(parameters);
+    }
+
+    @Override
+    protected void executeQueryCommand() {
+        switch (getParameters().getOsRepositoryVerb()) {
+            case GetOsName:
+                
setReturnValue(OsRepositoryImpl.INSTANCE.getOsName(getParameters().getOsId()));
+                break;
+            case Get64BitsOSs:
+                setReturnValue(OsRepositoryImpl.INSTANCE.get64bitOss());
+                break;
+            case GetOSIds:
+                setReturnValue(OsRepositoryImpl.INSTANCE.getOsIds());
+                break;
+            case GetlinuxOSs:
+                setReturnValue(OsRepositoryImpl.INSTANCE.getLinuxOSs());
+                break;
+            case GetMaxOsRam:
+                
setReturnValue(OsRepositoryImpl.INSTANCE.getMaximumRam(getParameters().getOsId(),
 null));
+                break;
+            case GetMinimumOsRam:
+                
setReturnValue(OsRepositoryImpl.INSTANCE.getMinimumRam(getParameters().getOsId(),
 null));
+                break;
+            case HasSpiceSupport:
+                
setReturnValue(OsRepositoryImpl.INSTANCE.hasSpiceSupport(getParameters().getOsId(),
 null));
+                break;
+            case GetNetworkDevices:
+                
setReturnValue(OsRepositoryImpl.INSTANCE.getNetworkDevices(getParameters().getOsId(),
 null));
+                break;
+        }
+    }
+}
diff --git a/backend/manager/modules/bll/src/main/resources/00-os.properties 
b/backend/manager/modules/bll/src/main/resources/00-os.properties
new file mode 100644
index 0000000..13b5eff
--- /dev/null
+++ b/backend/manager/modules/bll/src/main/resources/00-os.properties
@@ -0,0 +1,208 @@
+# 00-os.properties
+#
+# This is a configuration file for provisioning the engine OSs. Its features:
+#
+# * Value versions -
+#     values can be different per compatibility versions;
+#       os.rhel6.key.value = foo                 // a general version value
+#       os.rhel6.key.value.version.3.2 = bar     // 3.2 compatibility version 
value
+
+# * value overriding -
+#     Supports versions of configuration through file prefix
+#     e.g - all or some entries in this file can be overridden by entries in
+#       01-os.properties
+#
+# * Inheritance -
+#     Specify the 'derivedFrom' key and the os id to inherit all its values 
except id.
+#
+# * I18N -
+#     This file is also loaded as a String Bundle so name and description can
+#     contain non-ASCII values.
+#     This file is the default en-us locale while loading 
00-os_he-il.properties
+#     will contain Hebrew locale values e.g os.linux.name.value = 
&#x5DC;&#x5D9;&#x5E0;&#x5D5;&#x5E7;&#x5E1;
+#
+
+# for compatibility reasons and convenience an OS has an id.
+# note: every OS has a unique namespace for the native unique representation 
of the data.
+# i.e os.rhel6.somekey = val belongs only to rhel6 
+# Both engine and DWH rely on id value and not the os.{osid).*  
+os.default.id.value = 0
+
+# name is I18N if the one creates a 01-os_${LOCALE}.properties with the 
co-responding name property
+os.default.name.value = default OS
+
+# OS family values: Linux/Windows/Other
+os.default.family.value = Other
+
+# CPU architecture (*not* the bus width 64/32 bit). Currently only x86 is 
supported
+# but ppc7 is a work in progress and possibly arm someday as well
+os.default.cpuArchitecture.value = x86
+
+os.default.bus.value = 32
+os.default.resources.minimum.ram.value = 512
+os.default.resources.maximum.ram.value = 64000
+os.default.resources.minimum.disksize.value = 1
+os.default.resources.minimum.numberOsCpus.value = 1
+os.default.spiceSupport.value = true
+
+os.default_64.derivedFrom.value = default
+os.default_64.bus.value = 64
+os.default_64.resources.minimum.ram.value = 1024
+os.default_64.resources.recommended.ram.value = 2000
+
+os.default.devices.audio.value = ich6
+# See VmInterfaceType.java
+os.default.devices.network =  rtl8139, e1000, pv
+
+os.linux.id.value = 100
+os.linux.name.value = Linux
+os.linux.derivedFrom.value = default
+os.linux.description.value = General GNU/Linux
+os.linux.family.value = linux
+os.linux.devices.audio.value = ac97
+
+os.windows.id.value = 200
+os.windows.name.value = Windows
+os.windows.derivedFrom.value = default
+os.windows.description.value = default Windows OS
+os.windows.family.value = windows
+os.windows.devices.audio.value = ac97
+os.windows.sysprepPath.value = ""
+os.windows.productKey.value = ""
+
+
+# rhel3(9, OsType.Linux, false),
+os.rhel3.id.value = 9
+os.rhel3.name.value = Red Hat Enterprise Linux 3.x
+os.rhel3.derivedFrom.value = linux
+
+# rhel3x64(15, OsType.Linux, true),
+os.rhel3x64.id.value = 15
+os.rhel3x64.name.value = Red Hat Enterprise Linux 3.x x64
+os.rhel3x64.derivedFrom.value = linux
+
+# rhel4(8, OsType.Linux, false),
+os.rhel4.id.value = 8
+os.rhel4.name.value = Red Hat Enterprise Linux 4.x
+os.rhel4.derivedFrom.value = linux
+
+# RHEL4x64(14, OsType.Linux, true),
+os.rhel4x64.id.value = 14
+os.rhel4x64.name.value = Red Hat Enterprise Linux 4.x x64
+os.RHEL4x64.derivedFrom.value = rhel3x64
+
+# rhel5(7, OsType.Linux, false),
+os.rhel5.id.value = 7
+os.rhel5.name.value = Red Hat Enterprise Linux 5.x
+os.rhel5.derivedFrom.value = linux
+
+# rhel5x64(13, OsType.Linux, true),
+os.rhel5x64.id.value = 13
+os.rhel5x64.name.value = Red Hat Enterprise Linux 5.x x64
+os.rhel5x64.derivedFrom.value = rhel4x64
+os.rhel5x64.bus.value = 64
+
+# rhel6(18, OsType.Linux, false),
+os.rhel6.id.value = 18
+os.rhel6.name.value = Red Hat Enterprise Linux 6.x
+os.rhel6.derivedFrom.value = rhel5
+
+# rhel6x64(19, OsType.Linux, true),
+os.rhel6x64.id.value = 19
+os.rhel6x64.name.value = Red Hat Enterprise Linux 6.x x64
+os.rhel6x64.derivedFrom.value = rhel5x64
+
+
+# WindowsXP(1, OsType.Windows, false),
+os.windowsXP.id.value = 1
+os.windowsXP.name.value = windows XP
+os.windowsXP.derivedFrom.value = windows
+os.windowsXP.sysprepPath.value = /etc/ovirt-engine/sysprep/sysprep.xp
+os.windowsXP.productKey.value =
+os.windowsXP..isTimezoneTypeInteger.value = true
+
+
+# Windows2003(3, OsType.Windows, false),
+os.windows2003.id.value = 3
+os.windows2003.name.value = windows 2003
+os.windows2003.derivedFrom.value = windows
+os.windows2003.sysprepPath.value = /etc/ovirt-engine/sysprep/sysprep.2k3
+os.windows2003.productKey.value = 
+os.windows2003..isTimezoneTypeInteger.value = true
+
+# Windows2008(4, OsType.Windows, false),
+os.windows2008.id.value = 4
+os.windows2008.name.value = windows 2008
+os.windows2008.derivedFrom.value = windows2003
+os.windows2008.sysprepPath.value = /etc/ovirt-engine/sysprep/sysprep.2k8
+os.windows2008.productKey.value =
+
+# Windows2003x64(10, OsType.Windows, true),
+os.windows2003x64.id.value = 10
+os.windows2003x64.name.value = windows 2003 x64
+os.windows2003x64.derivedFrom.value = windows2003
+os.windows2003x64.bus.value = 64
+os.windows2003x64.sysprepPath.value = /etc/ovirt-engine/sysprep/sysprep.2k3
+os.windows2003x64.productKey.value =
+os.windows2003x64..isTimezoneTypeInteger.value = true
+
+# Windows7(11, OsType.Windows, false),false
+os.windows7.id.value = 11
+os.windows7.name.value = windows 7
+os.windows7.derivedFrom.value = windowsXp
+os.windows7.sysprepPath.value = /etc/ovirt-engine/sysprep/sysprep.w7
+os.windows7.productKey.value =
+
+# Windows7x64(12, OsType.Windows, true),
+os.windows7x64.id.value = 12
+os.windows7x64.name.value = windows 7
+os.windows7x64.derivedFrom.value = windows7
+os.windows7x64.sysprepPath.value = /etc/ovirt-engine/sysprep/sysprep.w7x64
+os.windows7x64.productKey.value =
+
+# Windows2008x64(16, OsType.Windows, true),
+os.windows2008x64.id.value = 16
+os.windows2008x64.name.value = windows2008 x64
+os.windows2008x64.derivedFrom.value = windows2003x64
+os.windows2008x64.sysprepPath.value = /etc/ovirt-engine/sysprep/sysprep.2k8x64
+os.windows2008x64.productKey.value =
+
+# os.windows2008R2x64.derivedFrom.value = windows2008
+os.windows2008R2x64.id.value =
+os.windows2008R2x64.name.value = windows 2008 R2 x64
+os.windows2008R2x64.derivedFrom.value = windows2008x64
+os.windows2008R2x64.productKey.value =
+
+# Windows8(20, OsType.Windows, false),
+os.windows8.id.value = 20
+os.windows8.name.value = windows 8
+os.windows8.derivedFrom.value = windows7
+os.windows8.sysprepPath.value = /etc/ovirt-engine/sysprep/sysprep.w8
+os.windows8.productKey.value =
+os.windows8.spiceSupport.value = false
+
+# Windows8x64(21, OsType.Windows, true),
+os.windows8x64.id.value = 21
+os.windows8x64.name.value = windows 8 x64
+os.windows8x64.derivedFrom.value = windows7x64
+os.windows8x64.sysprepPath.value = /etc/ovirt-engine/sysprep/sysprep.w8x64
+os.windows8x64.productKey.value =
+os.windows8x64.spiceSupport.value = false
+
+# Windows2012x64(23, OsType.Windows, true);
+os.windows2012x64.id.value = 23
+os.windows2012x64.name.value = windows 2012 x64
+os.windows2012x64.derivedFrom.value = windows2008x64
+os.windows2012x64.sysprepPath.value = /etc/ovirt-engine/sysprep/sysprep.2k12x64
+os.windows2012x64.productKey.value =
+os.windows2012x64.spiceSupport.value = false
+
+# OtherLinux(5, OsType.Linux, false),
+os.OtherLinux.id.value = 5
+os.OtherLinux.name.value = linux
+os.OtherLinux.derivedFrom.value = linux
+
+# Other(6, OsType.Other, false),
+os.Other.id.value = 6
+os.Other.name.value = Other
+os.Other.derivedFrom.value = default
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/MapBackedPreferences.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/MapBackedPreferences.java
new file mode 100644
index 0000000..f0b2a3b
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/MapBackedPreferences.java
@@ -0,0 +1,71 @@
+package org.ovirt.engine.core.common.osinfo;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.prefs.AbstractPreferences;
+
+public class MapBackedPreferences extends AbstractPreferences implements 
Serializable {
+
+    private static final long serialVersionUID = -6359144559146465048L;
+    HashMap<String, String> preferencesStore = new HashMap<String, String>();
+    ArrayList<String> childNodes = new ArrayList<String>();
+
+    /**
+     * Creates a preference node with the specified parent and the specified
+     * name relative to its parent.
+     *
+     * @see AbstractPreferences
+     */
+    public MapBackedPreferences(AbstractPreferences parent, String name) {
+        super(parent, name);
+    }
+
+    @Override
+    protected void putSpi(String key, String value) {
+        preferencesStore.put(key, value);
+    }
+
+    @Override
+    protected String getSpi(String key) {
+        return preferencesStore.get(key);
+    }
+
+    @Override
+    protected void removeSpi(String key) {
+        preferencesStore.remove(key);
+    }
+
+    @Override
+    protected void removeNodeSpi() {
+        throw new UnsupportedOperationException("Not supported for sake of 
simplicity, non blocking API");
+
+    }
+
+    @Override
+    protected String[] keysSpi() {
+        return preferencesStore.keySet().toArray(new 
String[preferencesStore.size()]);
+    }
+
+    @Override
+    protected String[] childrenNamesSpi() {
+        return childNodes.toArray(new String[childNodes.size()]);
+    }
+
+    @Override
+    protected AbstractPreferences childSpi(String name) {
+        childNodes.add(name);
+        return new MapBackedPreferences(this,name);
+    }
+
+    @Override
+    protected void syncSpi() {
+        throw new UnsupportedOperationException("This implementation doesn't 
support a backing store");
+    }
+
+    @Override
+    protected void flushSpi() {
+        throw new UnsupportedOperationException("This implementation doesn't 
support a backing store");
+    }
+
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/OsRepository.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/OsRepository.java
new file mode 100644
index 0000000..20032a5
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/OsRepository.java
@@ -0,0 +1,49 @@
+package org.ovirt.engine.core.common.osinfo;
+
+import org.ovirt.engine.core.compat.Version;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public interface OsRepository {
+
+    /**
+     * @return all loaded os ids
+     */
+    public ArrayList<Integer> getOsIds();
+
+    /**
+     * @return map of osId to the the os name
+     */
+    public HashMap<Integer, String> getOsNames();
+
+    public String getOsName(int osId);
+
+    public String getOsFamily(int osId);
+
+    public ArrayList<Integer> getLinuxOSs();
+
+    public ArrayList<Integer> get64bitOss();
+
+    public ArrayList<Integer> getWindowsOss();
+
+    public int getMinimumRam(int osId, Version version);
+
+    public int getMaximumRam(int osId, Version version);
+
+    public boolean hasSpiceSupport(int osId, Version version);
+
+    public String getSysprepPath(int osId, Version version);
+
+    public String getProductKey(int osId, Version version);
+
+    public boolean isLinux(int osId);
+
+    public boolean isWindows(int osId);
+
+    ArrayList<String> getNetworkDevices(int osId, Version version);
+
+    String getSoundDevice(int osId, Version version);
+
+    boolean isTimezoneValueIteger(int osId, Version version);
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/OsRepositoryImpl.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/OsRepositoryImpl.java
new file mode 100644
index 0000000..c876198
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/OsRepositoryImpl.java
@@ -0,0 +1,254 @@
+package org.ovirt.engine.core.common.osinfo;
+
+import org.ovirt.engine.core.compat.Version;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+/**
+ * This class is holding all Virtual OSs information.
+ */
+public enum OsRepositoryImpl implements OsRepository {
+
+    INSTANCE;
+
+    public static final String OS = "/os/";
+
+    /**
+     * the configuration tree holding all the os data.
+     */
+    private MapBackedPreferences preferences;
+    /**
+     * lookup table to get the os id from the uniqename and vise-versa
+     * os.rhel6.id.value = 8 means its id in the engine db is 8 and the unique 
name is "rhel6"
+     */
+    private Map<Integer,String> idToUnameLookup;
+
+    public void init(MapBackedPreferences preferences) {
+        INSTANCE.preferences = preferences;
+        buildIdToUnameLookup();
+    }
+
+    private void buildIdToUnameLookup() {
+        try {
+            String[] uniqueNames = preferences.node("/os").childrenNames();
+            idToUnameLookup = new HashMap<Integer, String>(uniqueNames.length);
+            for (String uniqueName :Arrays.asList(uniqueNames)) {
+                Preferences idNode = getKeyNode(uniqueName, "id");
+                if (idNode != null) {
+                    idToUnameLookup.put(idNode.getInt("value", 0),uniqueName);
+                }
+            }
+        } catch (BackingStoreException e) {
+             throw new RuntimeException("Failed to initialize Os Repository 
due to " + e);
+        }
+    }
+
+    @Override
+    public ArrayList<Integer> getOsIds() {
+        return new ArrayList<Integer>(idToUnameLookup.keySet());
+    }
+
+    @Override
+    public HashMap<Integer, String> getOsNames() {
+        HashMap<Integer,String> osNames = new HashMap<Integer, String>();
+        for (int osId: getOsIds()) {
+            Preferences nameNode = getKeyNode(idToUnameLookup.get(osId), 
"name");
+            if (nameNode != null) {
+                osNames.put(osId, nameNode.get(versionedValuePath(null), ""));
+            }
+        }
+        return osNames;
+    }
+
+    @Override
+    public String getOsName(int osId) {
+        return getOsNames().get(osId);
+    }
+
+    @Override
+    public String getOsFamily(int osId) {
+        return getKeyNode(idToUnameLookup.get(osId), 
"family").get(versionedValuePath(null),"");
+    }
+
+    @Override
+    public ArrayList<Integer> getLinuxOSs() {
+        ArrayList<Integer> oss = new ArrayList<Integer>();
+        for (int osId: getOsIds()) {
+            if (getOsFamily(osId).equalsIgnoreCase("linux")) {
+                oss.add(osId);
+            }
+        }
+        return oss;
+    }
+
+    @Override
+    public ArrayList<Integer> get64bitOss() {
+        ArrayList<Integer> oss = new ArrayList<Integer>();
+        for (int osId: getOsIds()) {
+            if (getKeyNode(idToUnameLookup.get(osId), "x86_64") != null) {
+                oss.add(osId);
+            }
+        }
+        return oss;
+    }
+
+    @Override
+    public ArrayList<Integer> getWindowsOss() {
+        ArrayList<Integer> oss = new ArrayList<Integer>();
+        for (int osId: getOsIds()) {
+            if (isWindows(osId)) {
+                oss.add(osId);
+            }
+        }
+        return oss;
+    }
+
+    @Override
+    public boolean isWindows(int osId) {
+        return getOsFamily(osId).equalsIgnoreCase("windows");
+    }
+
+    @Override
+    public ArrayList<String> getNetworkDevices(int osId, Version version) {
+        return trimElements(getKeyNode(idToUnameLookup.get(osId), 
"devices.network").get(versionedValuePath(version),"").split(","));
+    }
+
+    @Override
+    public boolean isLinux(int osId) {
+        return getOsFamily(osId).equalsIgnoreCase("windows");
+    }
+
+    @Override
+    public int getMinimumRam(int osId, Version version) {
+        return getKeyNode(idToUnameLookup.get(osId), 
"resources.minimum.ram").getInt(versionedValuePath(version), 0);
+    }
+
+    @Override
+    public int getMaximumRam(int osId, Version version) {
+        return getKeyNode(idToUnameLookup.get(osId), 
"resources.maximum.ram").getInt(versionedValuePath(version), 0);
+    }
+
+    @Override
+    public boolean hasSpiceSupport(int osId, Version version) {
+        return getKeyNode(idToUnameLookup.get(osId), 
"spiceSupport").getBoolean(versionedValuePath(version), false);
+    }
+
+    @Override
+    public String getSysprepPath(int osId, Version version) {
+        return 
getKeyNode(idToUnameLookup.get(osId),"sysprepPath").get(versionedValuePath(version),"");
+    }
+
+    @Override
+    public String getProductKey(int osId, Version version) {
+        return getKeyNode(idToUnameLookup.get(osId), 
"productKey").get(versionedValuePath(version),"");
+    }
+
+    @Override
+    public String getSoundDevice(int osId, Version version) {
+        return getKeyNode(idToUnameLookup.get(osId), 
"devices.audio").get(versionedValuePath(version),"");
+    }
+
+    @Override
+    public boolean isTimezoneValueIteger(int osId, Version version) {
+        return 
getKeyNode(idToUnameLookup.get(osId),"isTimezoneTypeInteger").getBoolean(versionedValuePath(version),false);
+    }
+
+    /**
+     *
+     * @param uniqeOsName is the os.{String} section of the key path.
+     *                    \e.g "rhel6" is the unique os name of 
os.rhel6.description key
+     * @param relativeKeyPath
+     * @return the node of the specified key for the given osId or its derived 
parent.
+     *         Essentially this method will recursively be called till no 
parent with the exact path is found.
+     *
+     */
+    private Preferences getKeyNode(String uniqeOsName, String relativeKeyPath) 
{
+        if (uniqeOsName == null) {
+            return null;
+        }
+        // first try direct OS node
+        try {
+            Preferences node = getNodeIfExist(uniqeOsName, relativeKeyPath);
+            if (node != null) {
+                return node;
+            } else {
+                // if not exist directly on the OS consult the one its derived 
from
+                return getKeyNode(preferences.node(OS + 
uniqeOsName).get("derivedFrom", null), relativeKeyPath);
+            }
+        } catch (BackingStoreException e) {
+            // our preferences impl should use storage to back the data 
structure
+            // throwing unchecked exception here to make sure this anomality 
is noticed
+            throw new RuntimeException(e);
+        }
+    }
+
+    private String stripKey(String key) {
+        if (key.indexOf(".") == -1) {
+            return key;
+        } else {
+            return key.substring(key.lastIndexOf(".") + 1);
+        }
+    }
+
+    private Preferences getNodeIfExist(String osId, String key) throws 
BackingStoreException {
+//        String pathName = "/os/" + osId + getKeyDirPath(key);
+        String pathName = "/os/" + osId + "/" + key;
+        if (preferences.nodeExists(pathName)) {
+            return preferences.node(pathName);
+        };
+        return null;
+    }
+
+    private String getKeyDirPath(String property) {
+        String[] split = property.split("\\.");
+        if (split.length > 1) {
+            StringBuilder sb = new StringBuilder();
+            // since we are interested in extracting a path,
+            // if the property ws a\b\c\d and we want a\b\c, stop
+            // the iteration before the last element
+            for (int i = 0; i < split.length-1; i++) {
+                if (!split[i].isEmpty()) {
+                    sb.append("/").append(split[i]);
+                }
+            }
+            return sb.toString();
+        } else {
+            return "";
+        }
+
+    }
+
+    private ArrayList<String> trimElements(String... elements) {
+        ArrayList<String> list = new ArrayList<String>(elements.length);
+        for (String e : elements) {
+            list.add(e.trim());
+        }
+        return list;
+    }
+
+    /**
+     * a key can have several values per version. a null version represents
+     * the default while other are specific one:
+     *   key.value = someval         // the default value. the path returend 
is "value"
+     *   key.value.3.1 = otherval    // the 3.1 version val. the path returned 
is "value.3.1"
+     *
+     *
+     * @param version
+     * @return the string representation of the value path.
+     *         for key.value.3.1 = otherval "value.3.1" should be returned.
+     */
+    private String versionedValuePath(Version version) {
+        return version == null || version == Version.ALL ? "value" : "value." 
+ version;
+    }
+
+    public static String osNameUpperCasedAndUnderscored(String name) {
+        // underscore position is the first digit or second camel-cased word
+        return name.replaceFirst("([A-Za-z0-9][a-z]*)([A-Z0-9])", 
"$1_$2").toUpperCase();
+    }
+
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/OsQueryParameters.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/OsQueryParameters.java
new file mode 100644
index 0000000..b7a7450
--- /dev/null
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/OsQueryParameters.java
@@ -0,0 +1,43 @@
+package org.ovirt.engine.core.common.queries;
+
+public class OsQueryParameters extends VdcQueryParametersBase {
+
+    private OsRepositoryVerb osRepositoryVerb;
+    private int osId;
+
+    public OsQueryParameters(OsRepositoryVerb verb) {
+        this.osRepositoryVerb = verb;
+    }
+
+    public OsQueryParameters(OsRepositoryVerb verb, int osId) {
+        this.osRepositoryVerb = verb;
+        setOsId(osId);
+    }
+
+    public int getOsId() {
+        return osId;
+    }
+
+    public void setOsId(int osId) {
+        this.osId = osId;
+    }
+
+    public OsRepositoryVerb getOsRepositoryVerb() {
+        return osRepositoryVerb;
+    }
+
+    public void setOsRepositoryVerb(OsRepositoryVerb osRepositoryVerb) {
+        this.osRepositoryVerb = osRepositoryVerb;
+    }
+
+    public enum OsRepositoryVerb {
+        HasSpiceSupport,
+        GetlinuxOSs,
+        Get64BitsOSs,
+        GetOSIds,
+        GetMinimumOsRam,
+        GetMaxOsRam,
+        GetNetworkDevices,
+        GetOsName
+    }
+}
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
index 609a89a..c0f642c 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java
@@ -236,6 +236,7 @@
     GetGlusterHooks,
 
     GetDefaultConfigurationVersion(VdcQueryAuthType.User),
+    OsRepository,
 
     // Default type instead of having to null check
     Unknown(VdcQueryAuthType.User);
diff --git 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/OsLoader.java
 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/OsLoader.java
new file mode 100644
index 0000000..5851ec3
--- /dev/null
+++ 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/OsLoader.java
@@ -0,0 +1,11 @@
+package org.ovirt.engine.core.utils;
+
+import java.nio.file.Path;
+import java.util.prefs.Preferences;
+
+public interface OsLoader {
+
+    void load(Path directoryPath) ;
+
+    Preferences getPreferences();
+}
diff --git 
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/osinfo/OsInfoPreferencesLoader.java
 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/osinfo/OsInfoPreferencesLoader.java
new file mode 100644
index 0000000..0d6d17d
--- /dev/null
+++ 
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/osinfo/OsInfoPreferencesLoader.java
@@ -0,0 +1,100 @@
+package org.ovirt.engine.core.utils.osinfo;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.Properties;
+import java.util.prefs.Preferences;
+
+import org.ovirt.engine.core.common.osinfo.MapBackedPreferences;
+import org.ovirt.engine.core.common.osinfo.OsRepositoryImpl;
+import org.ovirt.engine.core.utils.LocalConfig;
+import org.ovirt.engine.core.utils.OsLoader;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+public enum OsInfoPreferencesLoader implements OsLoader {
+
+    INSTANCE;
+
+    /**
+     * The source properties from which all values are loaded.
+     */
+    private Properties properties;
+    /**
+     * The configuration tree. See {@link java.util.prefs.Preferences}
+     */
+    private volatile MapBackedPreferences preferences;
+
+    private Log log = LogFactory.getLog(OsInfoPreferencesLoader.class);
+
+
+    public void init() {
+        String configPath = LocalConfig.getInstance().getUsrDir().getPath() + 
"/conf/oss.conf.d";
+        load(FileSystems.getDefault().getPath(configPath));
+    }
+
+    public void load(Path directoryPath) {
+        try(DirectoryStream<Path> dirStream = 
Files.newDirectoryStream(directoryPath, "*.properties")) {
+            for (Path path: dirStream) {
+                loadFile(path);
+            }
+        } catch (IOException e) {
+            //ignore
+        }
+    }
+
+    @Override
+    public MapBackedPreferences getPreferences() {
+        if (preferences == null) {
+            preferences = new MapBackedPreferences(null,"");
+            loadPreferencesFromProperties();
+        }
+        return preferences;
+    }
+
+    private void loadFile(Path path) {
+        try(BufferedReader reader = Files.newBufferedReader(path, 
StandardCharsets.UTF_8)) {
+            properties = new Properties(properties);
+            properties.load(reader);
+
+            log.info("Loaded file " + path);
+        } catch (IOException e) {
+            log.error("Failed loading file "  + path);
+        }
+
+    }
+
+    private String getParentPropertyPath(String property) {
+        String[] split = property.split("\\.");
+        String derivedFromOs = properties.getProperty(split[0] + "." + 
split[1] + ".derivedFrom");
+        return derivedFromOs == null ? null : "os." + derivedFromOs + "." + 
split[2];
+    }
+
+    private void loadPreferencesFromProperties() {
+        if (properties != null) {
+            for (String k : properties.stringPropertyNames()) {
+                Preferences node = preferences;
+                String[] split = k.split("\\.");
+                for (int i = 0; i < split.length-1; i++) {
+                    node = node.node(split[i]);
+                }
+                node.put(split[split.length-1],properties.getProperty(k));
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        INSTANCE.init();
+        OsRepositoryImpl.INSTANCE.init(INSTANCE.getPreferences());
+        for (Map.Entry<Integer,String> e 
:OsRepositoryImpl.INSTANCE.getOsNames().entrySet()) {
+            System.out.println(e);
+        }
+        System.out.println(OsRepositoryImpl.INSTANCE.getMaximumRam(100, null));
+    }
+}


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I50384bf3b6763fa7a34badc2449e06242186a858
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Roy Golan <rgo...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to