Roy Golan has uploaded a new change for review.
Change subject: core: validate osinfo properties files - fail backend on error
......................................................................
core: validate osinfo properties files - fail backend on error
validate the osinfo properties files by the order of loading.
on-error, a RuntimeException is thrown, which should fail the backend
from loading.
The parsing itself is implemented using ANTLR parser and lexer
generator and the Osinfo.g4 grammar file.
Osinfo.g4
grammar file that expresses the syntax of the properties file and
except for unique validation needs should be the only place to be
changed when needed.
OsinfoPreferencesParser.java
the tool to parse a property file with and match is against the syntax
OsinfoPreferencesParser.parse("path/to/file")
Change-Id: Ie33bf9446857e15d13221271120a3ff2b400350c
Bug-url: https://bugzilla.redhat.com/1093002
Signed-off-by: Roy Golan <[email protected]>
---
M
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/OsRepository.java
M backend/manager/modules/utils/pom.xml
A
backend/manager/modules/utils/src/main/antlr4/org/ovirt/engine/core/utils/osinfo/Osinfo.g4
M
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/OsRepositoryImpl.java
M
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/osinfo/OsInfoPreferencesLoader.java
A
backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/osinfo/OsinfoPropertiesParser.java
M
backend/manager/modules/utils/src/test/resources/osinfo.conf.d/00-osinfo-test.properties
M packaging/conf/osinfo-defaults.properties
8 files changed, 299 insertions(+), 7 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/82/30782/1
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
index 0701038..b048535 100644
---
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
@@ -21,7 +21,6 @@
public final static int DEFAULT_X86_OS = 0;
public final static int DEFAULT_PPC_OS = 1001;
- public final static int OLD_OTHER_ID = 6;
/*
* This value is used to enable the auto selection of an appropriate OS
when
@@ -30,6 +29,12 @@
public final static int AUTO_SELECT_OS = -1;
/**
+ * validate the repo values and structure. if something is wrong the
application is expected to
+ * shutdown with an very informative error, stating the invalid input,
expected values and/or way to overcome that
+ * throws IllegalStateException if the one or more values isn't valid and
will likely to cause application error
+ */
+ public void validateRepo() throws IllegalStateException;
+ /**
* @return all loaded os ids
*/
public ArrayList<Integer> getOsIds();
diff --git a/backend/manager/modules/utils/pom.xml
b/backend/manager/modules/utils/pom.xml
index f0d3503..8a7acf3 100644
--- a/backend/manager/modules/utils/pom.xml
+++ b/backend/manager/modules/utils/pom.xml
@@ -165,6 +165,11 @@
<version>${openstack-client.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4-runtime</artifactId>
+ <version>4.2.2</version>
+ </dependency>
</dependencies>
<build>
@@ -191,6 +196,21 @@
<groupId>org.ovirt.engine</groupId>
<artifactId>jboss-modules-maven-plugin</artifactId>
</plugin>
+
+ <!-- Generate osinfo parser from grammer file-->
+ <plugin>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4-maven-plugin</artifactId>
+ <version>4.2.2</version>
+ <executions>
+ <execution>
+ <id>antlr</id>
+ <goals>
+ <goal>antlr4</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
<profiles>
diff --git
a/backend/manager/modules/utils/src/main/antlr4/org/ovirt/engine/core/utils/osinfo/Osinfo.g4
b/backend/manager/modules/utils/src/main/antlr4/org/ovirt/engine/core/utils/osinfo/Osinfo.g4
new file mode 100644
index 0000000..673fc95
--- /dev/null
+++
b/backend/manager/modules/utils/src/main/antlr4/org/ovirt/engine/core/utils/osinfo/Osinfo.g4
@@ -0,0 +1,205 @@
+grammar Osinfo;
+
+
+parse
+ :
+ ((osRecord | compatibilityRecord | comment) (EOL|EOF))*
+ ;
+
+
+osRecord
+ :
+ 'os' DOT OS_UNIQUE_NAME '.' attribute
+ ;
+
+compatibilityRecord
+ :
+ 'backwardCompatibility' '.' OS_UNIQUE_NAME WS* EQUALS WS* INT
+ ;
+
+comment
+ :
+ LineComment
+ ;
+
+attribute
+ :
+ ID intValue
+ | NAME stringValue
+ | DESCRIPTION stringValue
+ | 'derivedFrom' stringValue
+ | 'family' stringValue
+ | 'cpuArchitecture' archValue
+ | 'bus' busValue
+ | 'sysprepPath' stringValue
+ | 'productKey' stringValue
+ | 'isTimezoneTypeInteger' booleanValue
+ | resources
+ | devices
+ ;
+
+resources
+ :
+ 'resources'
+ ( DOT 'minimum' DOT ('ram'|'disksize'|'numberOfCpus') intValue
+ | DOT 'maximum' DOT ('ram'|'disksize'|'numberOfCpus') intValue
+ )+
+ ;
+
+devices
+ :
+ 'devices'
+ ( DOT DISPLAY_PROTOCOLS displayValue
+ | DOT 'watchdog.models' watchdogValue
+ | DOT 'network' networkValue
+ | DOT 'network.hotplugSupport' booleanValue
+ | DOT 'disk.hotpluggableInterfaces' hardwareInterfacesValue
+ | DOT 'balloon.enabled' booleanValue
+ | DOT 'audio' audioValue
+ | DOT 'cdInterface' cdInterfaceValue
+ | DOT 'diskInterfaces' hardwareInterfacesValue
+ | DOT 'maxPciDevices' intValue
+ )
+ ;
+
+intValue
+ :
+ valueSpecifier (INT | bus_width )
+ ;
+
+stringValue
+ :
+ valueSpecifier rest_of_line
+ ;
+
+rest_of_line
+ :
+ ~EOL*
+ ;
+
+booleanValue
+ :
+ valueSpecifier ('true' | 'false')
+ ;
+
+archValue
+ :
+ valueSpecifier ('x86_64' | 'ppc64')
+ ;
+
+busValue
+ :
+ valueSpecifier bus_width
+ ;
+
+displayValue
+ :
+ valueSpecifier DISPLAY_PROTOCOLS_TYPE(',' WS* DISPLAY_PROTOCOLS_TYPE )*
+ ;
+
+
+watchdogValue
+ :
+ valueSpecifier ('i6300esb')
+ ;
+
+networkValue
+ :
+ valueSpecifier NETWORK_DEVICE_TYPE (',' WS* NETWORK_DEVICE_TYPE)*
+ ;
+
+
+audioValue
+ :
+ valueSpecifier ('ich6' | 'ac97')
+ ;
+
+cdInterfaceValue
+ :
+ valueSpecifier ('ide' | 'scsi')
+ ;
+
+
+hardwareInterfacesValue
+ :
+ valueSpecifier HARDWARE_INTERFACE_TYPE* (',' WS* HARDWARE_INTERFACE_TYPE)*
+ ;
+
+valueSpecifier
+ :
+ VALUE (DOT VERSION)* WS* EQUALS WS*
+ ;
+
+
+//keywords
+OS : 'os' ;
+BACKWARDCOMPATIBILITY : 'backwardCompatibility' ;
+ID : 'id' ;
+NAME : 'name' ;
+DESCRIPTION : 'description' ;
+DERIVEDFROM : 'derivedFrom' ;
+FAMILY : 'family' ;
+CPUARCHITECTURE : 'cpuArchitecture' ;
+BUS : 'bus' ;
+RESOURCES : 'resources' ;
+MINIMUM : 'minimum' ;
+RAM : 'ram' ;
+DISKSIZE : 'disksize' ;
+NUMBEROFCPUS : 'numberOfCpus' ;
+MAXIMUM : 'maximum' ;
+DEVICES : 'devices' ;
+DISPLAY_PROTOCOLS : 'display.protocols' ;
+WATCHDOG_MODELS : 'watchdog.models' ;
+NETWORK : 'network' ;
+NETWORK_HOTPLUGSUPPORT : 'network.hotplugSupport' ;
+DISK_HOTPLUGGABLEINTERFACES : 'disk.hotpluggableInterfaces' ;
+BALLOON_ENABLED : 'balloon.enabled' ;
+AUDIO : 'audio' ;
+CDINTERFACE : 'cdInterface' ;
+DISKINTERFACES : 'diskInterfaces' ;
+MAXPCIDEVICES : 'maxPciDevices' ;
+TRUE : 'true' ;
+FALSE : 'false' ;
+X86_64 : 'x86_64' ;
+PPC64 : 'ppc64' ;
+COMMA : ',' ;
+I6300ESB : 'i6300esb' ;
+ICH6 : 'ich6' ;
+AC97 : 'ac97' ;
+IDE : 'ide' ;
+SCSI : 'scsi' ;
+
+DISPLAY_PROTOCOLS_TYPE
+ :
+ 'vnc/cirrus' | 'qxl/qxl' | 'vnc/vga'
+ ;
+
+NETWORK_DEVICE_TYPE
+ :
+ 'rtl8139_pv' | 'rtl8139' | 'e1000' | 'pv' | 'spaprVlan'
+ ;
+
+HARDWARE_INTERFACE_TYPE
+ :
+ 'IDE' | 'VirtIO' | 'VirtIO_SCSI' | 'SPAPR_VSCSI'
+ ;
+
+
+INT : DIGIT+ ;
+bus_width: '32' | '64' ;
+
+fragment DIGIT : [0-9] ;
+fragment CHAR : [a-zA-Z0-9_] ;
+DOT: '.' ;
+VALUE: '.value' ;
+VERSION: '3' '.' '0'..'5' ;
+OS_UNIQUE_NAME : CHAR+ ;
+EQUALS : '=' ;
+WS : [ \t] ;
+TEXT: [a-zA-Z0-9\\\/${}]+ ;
+LineComment
+ :
+ '#' ~[\r\n]*
+ ;
+
+EOL : [\r\n]+ ;
diff --git
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/OsRepositoryImpl.java
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/OsRepositoryImpl.java
index 64c32b0..3b71111 100644
---
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/OsRepositoryImpl.java
+++
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/OsRepositoryImpl.java
@@ -57,12 +57,21 @@
emptyNode = preferences.node("emptyNode");
buildIdToUnameLookup();
buildBackCompatMapping();
- validateTree();
+ validateRepo();
if (log.isDebugEnabled()) {
log.debugFormat("Osinfo Repository:\n {0}", toString());
}
}
+ @Override public void validateRepo() throws IllegalStateException {
+ validateValues()
+ validateTree();
+ }
+
+ private void validateValues() {
+
+ }
+
private void validateTree() {
try {
String[] uniqueNames = preferences.node("/os").childrenNames();
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
index fabf0f2..1b285bb 100644
---
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
@@ -53,6 +53,8 @@
Arrays.sort(files);
for (File file : files) {
+ log.info("Loading file " + file.getPath());
+ OsinfoPropertiesParser.parse(file.getAbsolutePath());
loadFile(file.toPath());
}
}
@@ -71,8 +73,6 @@
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);
}
diff --git
a/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/osinfo/OsinfoPropertiesParser.java
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/osinfo/OsinfoPropertiesParser.java
new file mode 100644
index 0000000..8c650c8
--- /dev/null
+++
b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/osinfo/OsinfoPropertiesParser.java
@@ -0,0 +1,52 @@
+package org.ovirt.engine.core.utils.osinfo;
+
+import org.antlr.v4.runtime.ANTLRFileStream;
+import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.BufferedTokenStream;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.antlr.v4.runtime.misc.NotNull;
+import org.antlr.v4.runtime.misc.Nullable;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.ovirt.engine.core.utils.log.Log;
+import org.ovirt.engine.core.utils.log.LogFactory;
+
+import java.io.IOException;
+
+public class OsinfoPropertiesParser {
+
+ private static Log log = LogFactory.getLog(OsinfoPropertiesParser.class);
+
+ /**
+ * walk the parse tree which is auto-generated by antlr from the Osinfo.g4
grammar file. walking the parse
+ * tree will throw an exception in case the file structure doesn't follow
the grammar.
+ *
+ * @param path
+ */
+ public static void parse(String path) {
+ ParseTreeWalker walker = new ParseTreeWalker();
+ OsinfoLexer osinfoLexer;
+ try {
+ osinfoLexer = new OsinfoLexer(new ANTLRFileStream(path));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ OsinfoParser osinfoParser = new OsinfoParser(new
BufferedTokenStream(osinfoLexer));
+ osinfoParser.addErrorListener(getListener());
+ walker.walk(new OsinfoBaseListener(), osinfoParser.parse());
+ }
+
+ private static BaseErrorListener getListener() {
+ return new BaseErrorListener() {
+ @Override public void syntaxError(@NotNull Recognizer<?, ?>
recognizer,
+ @Nullable Object offendingSymbol,
+ int line,
+ int charPositionInLine,
+ @NotNull String msg,
+ @Nullable RecognitionException e) {
+ log.error("line " + line + ":" + charPositionInLine + " " +
msg);
+ throw new RuntimeException("parsing error");
+ }
+ };
+ }
+}
diff --git
a/backend/manager/modules/utils/src/test/resources/osinfo.conf.d/00-osinfo-test.properties
b/backend/manager/modules/utils/src/test/resources/osinfo.conf.d/00-osinfo-test.properties
index cba9de6..fbfa514 100644
---
a/backend/manager/modules/utils/src/test/resources/osinfo.conf.d/00-osinfo-test.properties
+++
b/backend/manager/modules/utils/src/test/resources/osinfo.conf.d/00-osinfo-test.properties
@@ -1,11 +1,11 @@
os.default.id.value = 0
os.default.name.value = default OS
os.default.family.value = Other
-os.default.cpuArchitecture.value = x86
+os.default.cpuArchitecture.value = x86_64
os.default.bus.value = 32
os.default.resources.minimum.ram.value = 512
os.default.resources.maximum.ram.value = 64000
os.default.resources.maximum.ram.value.3.1 = 32000
os.default.resources.minimum.disksize.value = 1
-os.default.resources.minimum.numberOsCpus.value = 1
+os.default.resources.minimum.numberOfCpus.value = 1
os.default.devices.display.protocols.value = vnc/cirrus
diff --git a/packaging/conf/osinfo-defaults.properties
b/packaging/conf/osinfo-defaults.properties
index bf579b7..b33978e 100644
--- a/packaging/conf/osinfo-defaults.properties
+++ b/packaging/conf/osinfo-defaults.properties
@@ -47,10 +47,11 @@
os.other.cpuArchitecture.value = x86_64
os.other.bus.value = 32
+os.other.bus.value.3.4 = 32
os.other.resources.minimum.ram.value = 256
os.other.resources.maximum.ram.value = 64000
os.other.resources.minimum.disksize.value = 1
-os.other.resources.minimum.numberOsCpus.value = 1
+os.other.resources.minimum.numberOfCpus.value = 1
os.other.devices.display.protocols.value = qxl/qxl,vnc/cirrus
os.other.devices.watchdog.models.value = i6300esb
--
To view, visit http://gerrit.ovirt.org/30782
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie33bf9446857e15d13221271120a3ff2b400350c
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Roy Golan <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches