From: Jan Provaznik <jprovazn(a)redhat.com>
We need to do some operations with template such as validation
or basic editing.
Since template is warehouse/imagefactory object, we don't have
model in conductor for this. This patch adds at least basic class
where we can put all required operations (instead of having this in controller).
A template XML is validated against relax NG schema, disadvatage is that error
messages are sometimes not very user friendly.
It's partially similar to a model so I think it makes sense to put this
into app/models intead of app/utils.
---
src/app/controllers/images_controller.rb | 3 +
src/app/models/template_xml.rb | 40 +++++
src/app/util/template-rng.xml | 238 ++++++++++++++++++++++++++++++
3 files changed, 281 insertions(+), 0 deletions(-)
create mode 100644 src/app/models/template_xml.rb
create mode 100644 src/app/util/template-rng.xml
diff --git a/src/app/controllers/images_controller.rb
b/src/app/controllers/images_controller.rb
index 514e842..38d9f72 100644
--- a/src/app/controllers/images_controller.rb
+++ b/src/app/controllers/images_controller.rb
@@ -16,6 +16,8 @@
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at
http://www.gnu.org/copyleft/gpl.html.
+require 'app/util/temlate_xml'
+
class ImagesController < ApplicationController
before_filter :require_user
@@ -106,6 +108,7 @@ class ImagesController < ApplicationController
end
begin
+ tpl = TemplateXML.new(xml_source)
doc = Nokogiri::XML(xml_source) { |config| config.strict }
add_template_name(doc, @name)
@xml = doc.to_xml
diff --git a/src/app/models/template_xml.rb b/src/app/models/template_xml.rb
new file mode 100644
index 0000000..f7cb7c8
--- /dev/null
+++ b/src/app/models/template_xml.rb
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2011 Red Hat, Inc.
+# Written by Scott Seago <sseago(a)redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at
http://www.gnu.org/copyleft/gpl.html.
+
+
+class TemplateXML
+ attr_reader :errors, :doc
+
+ def initialize(xmlstr)
+ @errors = []
+ @xml = Nokogiri::XML(xmlstr) { |config| config.strict }
+ @relax_file = "#{::Rails.root.to_s}/app/util/template-rng.xml"
+ end
+
+ def validate
+ xsd = Nokogiri::XML::RelaxNG(File.read(@relax_file))
+ @errors = xsd.validate((a)xml).map {|err| err.message}
+ @errors << 'Name is not set' if
doc.xpath('/template/name').text.empty?
+ @errors.empty?
+ end
+
+ def to_xml
+ @xml.to_xml
+ end
+end
diff --git a/src/app/util/template-rng.xml b/src/app/util/template-rng.xml
new file mode 100644
index 0000000..07eb627
--- /dev/null
+++ b/src/app/util/template-rng.xml
@@ -0,0 +1,238 @@
+<?xml version="1.0"?>
+<!-- A Relax NG schema for the TDL (template description language) format -->
+<grammar
xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <start>
+ <ref name='template'/>
+ </start>
+
+ <define name='template'>
+ <element name='template'>
+ <optional>
+ <attribute name='version'>
+ <text/>
+ </attribute>
+ </optional>
+ <interleave>
+ <element name='name'>
+ <text/>
+ </element>
+ <element name='os'>
+ <interleave>
+ <element name='name'>
+ <text/>
+ </element>
+ <element name='version'>
+ <text/>
+ </element>
+ <element name='arch'>
+ <choice>
+ <value>i386</value>
+ <value>x86_64</value>
+ </choice>
+ </element>
+ <element name='install'>
+ <choice>
+ <ref name='url'/>
+ <ref name='iso'/>
+ </choice>
+ </element>
+ <optional>
+ <element name='rootpw'>
+ <text/>
+ </element>
+ </optional>
+ <optional>
+ <element name='key'>
+ <text/>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+ <optional>
+ <element name='description'>
+ <text/>
+ </element>
+ </optional>
+ <optional>
+ <element name='packages'>
+ <zeroOrMore>
+ <element name='package'>
+ <attribute name='name'>
+ <text/>
+ </attribute>
+ <interleave>
+ <optional>
+ <element name='repository'>
+ <text/>
+ </element>
+ </optional>
+ <optional>
+ <element name='file'>
+ <text/>
+ </element>
+ </optional>
+ <optional>
+ <element name='arguments'>
+ <text/>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+ </zeroOrMore>
+ </element>
+ </optional>
+ <optional>
+ <element name='files'>
+ <zeroOrMore>
+ <element name='file'>
+ <attribute name='name'>
+ <text/>
+ </attribute>
+ <choice>
+ <ref name='rawtype'/>
+ <ref name='base64type'/>
+ </choice>
+ </element>
+ </zeroOrMore>
+ </element>
+ </optional>
+ <optional>
+ <element name='commands'>
+ <zeroOrMore>
+ <element name='command'>
+ <attribute name='name'>
+ <text/>
+ </attribute>
+ <choice>
+ <ref name='rawtype'/>
+ <ref name='base64type'/>
+ </choice>
+ </element>
+ </zeroOrMore>
+ </element>
+ </optional>
+ <optional>
+ <element name='repositories'>
+ <zeroOrMore>
+ <element name='repository'>
+ <attribute name='name'>
+ <text/>
+ </attribute>
+ <interleave>
+ <element name='url'>
+ <text/>
+ </element>
+ <optional>
+ <element name='signed'>
+ <ref name='bool'/>
+ </element>
+ </optional>
+ <optional>
+ <element name='persisted'>
+ <ref name='bool'/>
+ </element>
+ </optional>
+ <optional>
+ <interleave>
+ <element name='clientcert'>
+ <text/>
+ </element>
+ <optional>
+ <element name='clientkey'>
+ <text/>
+ </element>
+ </optional>
+ </interleave>
+ </optional>
+ <optional>
+ <interleave>
+ <element name='sslverify'>
+ <ref name='bool'/>
+ </element>
+ <element name='cacert'>
+ <text/>
+ </element>
+ </interleave>
+ </optional>
+ </interleave>
+ </element>
+ </zeroOrMore>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+
+ <define name='url'>
+ <attribute name='type'>
+ <value>url</value>
+ </attribute>
+ <element name='url'>
+ <text/>
+ </element>
+ </define>
+
+ <define name='iso'>
+ <attribute name='type'>
+ <value>iso</value>
+ </attribute>
+ <interleave>
+ <element name='iso'>
+ <text/>
+ </element>
+ <optional>
+ <choice>
+ <element name='md5sum'>
+ <text/>
+ </element>
+ <element name='sha1sum'>
+ <text/>
+ </element>
+ <element name='sha256sum'>
+ <text/>
+ </element>
+ </choice>
+ </optional>
+ </interleave>
+ </define>
+
+ <define name='bool'>
+ <choice>
+ <data type="string">
+ <param name="pattern">[Tt][Rr][Uu][Ee]</param>
+ </data>
+ <data type="string">
+ <param name="pattern">[Ff][Aa][Ll][Ss][Ee]</param>
+ </data>
+ <data type="string">
+ <param name="pattern">[Yy][Ee][Ss]</param>
+ </data>
+ <data type="string">
+ <param name="pattern">[Nn][Oo]</param>
+ </data>
+ </choice>
+ </define>
+
+ <define name='rawtype'>
+ <optional>
+ <attribute name='type'>
+ <value>raw</value>
+ </attribute>
+ </optional>
+ <text/>
+ </define>
+
+ <define name='base64'>
+ <data type="string">
+ <param name="pattern">[a-zA-Z0-9+/]+={0,2}</param>
+ </data>
+ </define>
+
+ <define name='base64type'>
+ <attribute name='type'>
+ <value>base64</value>
+ </attribute>
+ <ref name='base64'/>
+ </define>
+
+</grammar>
--
1.7.6