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/1056965 Signed-off-by: Roy Golan <rgo...@redhat.com> --- M backend/manager/dependencies/pom.xml A backend/manager/dependencies/src/main/modules/org/antlr/antlr4-runtime/main/module.xml M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/osinfo/OsRepository.java M backend/manager/modules/utils/exclude-filters.xml 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/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/main/modules/org/ovirt/engine/core/utils/main/module.xml M backend/manager/modules/utils/src/test/resources/osinfo.conf.d/00-osinfo-test.properties M pom.xml 11 files changed, 321 insertions(+), 5 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/19/34819/1 diff --git a/backend/manager/dependencies/pom.xml b/backend/manager/dependencies/pom.xml index be4821d..d21ee5e 100644 --- a/backend/manager/dependencies/pom.xml +++ b/backend/manager/dependencies/pom.xml @@ -321,6 +321,10 @@ <version>${batik.version}</version> </dependency> + <dependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + </dependency> </dependencies> <build> @@ -634,6 +638,12 @@ <moduleName>org.apache.xmlgraphics.batik</moduleName> </module> + <module> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <moduleName>org.antlr.antlr4-runtime</moduleName> + </module> + </modules> </configuration> </plugin> diff --git a/backend/manager/dependencies/src/main/modules/org/antlr/antlr4-runtime/main/module.xml b/backend/manager/dependencies/src/main/modules/org/antlr/antlr4-runtime/main/module.xml new file mode 100644 index 0000000..f665c8c --- /dev/null +++ b/backend/manager/dependencies/src/main/modules/org/antlr/antlr4-runtime/main/module.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<module xmlns="urn:jboss:module:1.1" name="org.antlr.antlr4-runtime"> + + <resources> + <resource-root path="antlr4-runtime.jar"/> + </resources> + + <dependencies> + <module name="org.slf4j"/> + </dependencies> + +</module> 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 83e18cd..2fc9356 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 diff --git a/backend/manager/modules/utils/exclude-filters.xml b/backend/manager/modules/utils/exclude-filters.xml index 8322d93..5d529b6 100644 --- a/backend/manager/modules/utils/exclude-filters.xml +++ b/backend/manager/modules/utils/exclude-filters.xml @@ -64,4 +64,17 @@ <Bug code="UrF"/> </Match> + <!-- + ignore all warning on these classes as they are auto generated by antlr + --> + <Match> + <Class name="org.ovirt.engine.core.utils.osinfo.OsinfoParser" /> + </Match> + <Match> + <Class name="org.ovirt.engine.core.utils.osinfo.OsinfoParser$CommentContext" /> + </Match> + <Match> + <Class name="org.ovirt.engine.core.utils.osinfo.OsinfoLexer" /> + </Match> + </FindBugsFilter> diff --git a/backend/manager/modules/utils/pom.xml b/backend/manager/modules/utils/pom.xml index 9fa5b20..3129dc1 100644 --- a/backend/manager/modules/utils/pom.xml +++ b/backend/manager/modules/utils/pom.xml @@ -158,6 +158,10 @@ <version>${openstack-client.version}</version> </dependency> + <dependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + </dependency> </dependencies> <build> @@ -184,6 +188,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>${antlr.version}</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..db474bf --- /dev/null +++ b/backend/manager/modules/utils/src/main/antlr4/org/ovirt/engine/core/utils/osinfo/Osinfo.g4 @@ -0,0 +1,207 @@ +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 + | 'cpu.unsupported' stringValue + | '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 + | DOT 'hyperv.enabled' booleanValue + ) + ; + +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/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..31f024d --- /dev/null +++ b/backend/manager/modules/utils/src/main/java/org/ovirt/engine/core/utils/osinfo/OsinfoPropertiesParser.java @@ -0,0 +1,48 @@ +package org.ovirt.engine.core.utils.osinfo; + +import java.io.IOException; + +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; + +public class OsinfoPropertiesParser { + + /** + * 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) { + throw new RuntimeException("osinfo properties syntax error: " + + ("line " + line + ":" + charPositionInLine + " " + msg)); + } + }; + } +} diff --git a/backend/manager/modules/utils/src/main/modules/org/ovirt/engine/core/utils/main/module.xml b/backend/manager/modules/utils/src/main/modules/org/ovirt/engine/core/utils/main/module.xml index f174cb3..6ffd05e 100644 --- a/backend/manager/modules/utils/src/main/modules/org/ovirt/engine/core/utils/main/module.xml +++ b/backend/manager/modules/utils/src/main/modules/org/ovirt/engine/core/utils/main/module.xml @@ -31,6 +31,7 @@ <module name="org.postgresql"/> <module name="org.springframework"/> <module name="org.slf4j"/> + <module name="org.antlr.antlr4-runtime"/> </dependencies> </module> 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/pom.xml b/pom.xml index e251f5c..11401a5 100644 --- a/pom.xml +++ b/pom.xml @@ -113,6 +113,7 @@ <!-- https://jira.codehaus.org/browse/MGWT-350 --> <gwt-maven-plugin.workingRefresh.version>2.4.0</gwt-maven-plugin.workingRefresh.version> <cdi.api.version>1.0-SP4</cdi.api.version> + <antlr.version>4.2.2</antlr.version> </properties> <dependencyManagement> <dependencies> @@ -332,6 +333,11 @@ <version>${cdi.api.version}</version> <scope>provided</scope> </dependency> + <dependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>${antlr.version}</version> + </dependency> </dependencies> </dependencyManagement> <dependencies> -- To view, visit http://gerrit.ovirt.org/34819 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie33bf9446857e15d13221271120a3ff2b400350c Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: ovirt-engine-3.5 Gerrit-Owner: Roy Golan <rgo...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches