* [Cluster-devel] [resource-agents][PATCH 0/2] rgmanager: ra2rng.xsl et al.: cross-package schema extension @ 2013-12-16 12:38 Jan Pokorný 2013-12-16 12:38 ` [Cluster-devel] [PATCH 1/2] rgmanager: ra2rng.xsl et al.: obsolete 1 pass in ccs_update_schema Jan Pokorný 2013-12-16 12:38 ` [Cluster-devel] [PATCH 2/2] rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata Jan Pokorný 0 siblings, 2 replies; 7+ messages in thread From: Jan Pokorný @ 2013-12-16 12:38 UTC (permalink / raw) To: cluster-devel.redhat.com Both changes require (though not strictly as backward compatibility is pursued) corresponding changes in cluster.git (ccs_update_schema script), which will follow shortly. Jan Pokorn? (2): rgmanager: ra2rng.xsl et al.: obsolete 1 pass in ccs_update_schema rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata rgmanager/src/resources/Makefile.am | 28 ++- rgmanager/src/resources/ra2ref.xsl | 4 + rgmanager/src/resources/ra2rng-postprocess.xsl | 265 +++++++++++++++++++++++++ rgmanager/src/resources/ra2rng.xsl | 54 ++++- rgmanager/src/resources/resources.rng.mid | 4 +- rgmanager/src/resources/resources.rng.tail | 7 +- 6 files changed, 341 insertions(+), 21 deletions(-) create mode 100644 rgmanager/src/resources/ra2rng-postprocess.xsl -- 1.8.1.4 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Cluster-devel] [PATCH 1/2] rgmanager: ra2rng.xsl et al.: obsolete 1 pass in ccs_update_schema 2013-12-16 12:38 [Cluster-devel] [resource-agents][PATCH 0/2] rgmanager: ra2rng.xsl et al.: cross-package schema extension Jan Pokorný @ 2013-12-16 12:38 ` Jan Pokorný 2013-12-16 12:38 ` [Cluster-devel] [PATCH 2/2] rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata Jan Pokorný 1 sibling, 0 replies; 7+ messages in thread From: Jan Pokorný @ 2013-12-16 12:38 UTC (permalink / raw) To: cluster-devel.redhat.com ... in a backward-compatible way, which is done by wrapping the output of this as-of-now obsoleted pass by element from explicit non-RelaxNG namespace, which is then, in the validation phase, completely skipped. Separate patch for cluster.git to actually remove the pass in question will be provided, but thanks to this backward compatibility, it is not strictly required -- only informative notes about possibility of outdated cman package will possibly occur. The corresponding pass is also removed directly in the local Makefile mirroring the part of ccs_update_schema functionality so the resulting resources.rng does not contain the now-redundant references. [ It's nice to see how smart the design of Relax NG, allowing for such define-ala-mixin, is. ] NB: the change "optional" -> "zeroOrMore" is because previously "optional" was previously pointless (as is chaining '?' + '*' in regexp), but now the nested "zeroOrMore" is promoted from the definition of CHILDREN block up to its user (the other users were already using "zeroOrMore" also before descending to such symbol, which was another pointless thing, FWIW) Signed-off-by: Jan Pokorn? <jpokorny@redhat.com> --- rgmanager/src/resources/Makefile.am | 13 ++++----- rgmanager/src/resources/ra2ref.xsl | 4 +++ rgmanager/src/resources/ra2rng.xsl | 42 +++++++++++++++++++++++++++--- rgmanager/src/resources/resources.rng.mid | 4 +-- rgmanager/src/resources/resources.rng.tail | 7 ++--- 5 files changed, 54 insertions(+), 16 deletions(-) diff --git a/rgmanager/src/resources/Makefile.am b/rgmanager/src/resources/Makefile.am index 7719f81..caeb947 100644 --- a/rgmanager/src/resources/Makefile.am +++ b/rgmanager/src/resources/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved. +# Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -96,6 +96,12 @@ ras-validation: $(RESOURCES) $(TARGET) $(DTD) # # resources.rng.* should never be distributed by themselves. # +# NOTE: resources.rng.mid and resources.rng.tail not joined for +# compatibility with obsolete 2-passes-logic of +# ccs_update_schema script from external cman package +# +# XXX: race-prone in parallel make +# resources.rng: $(RESOURCES) $(TARGET) utils/config-utils.sh resources.rng: $(XSL) $(RESRNG) rm -f resources.rng @@ -106,11 +112,6 @@ resources.rng: $(XSL) $(RESRNG) bash ./$$f meta-data | xsltproc ra2rng.xsl - >> resources.rng; \ done cat resources.rng.mid >> resources.rng - @echo Generating per-resource RelaxNG reference information... - @for f in $(RESOURCES) $(TARGET); do \ - echo " ./$$f"; \ - bash ./$$f meta-data | xsltproc ra2ref.xsl - >> resources.rng; \ - done cat resources.rng.tail >> resources.rng utils/config-utils.sh: diff --git a/rgmanager/src/resources/ra2ref.xsl b/rgmanager/src/resources/ra2ref.xsl index 6e61073..a4b84c0 100644 --- a/rgmanager/src/resources/ra2ref.xsl +++ b/rgmanager/src/resources/ra2ref.xsl @@ -1,10 +1,14 @@ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" indent="yes"/> +<xsl:message>NOTE: if you see this, there is some chance you are using outdated cman package</xsl:message> <xsl:template name="capitalize"> <xsl:param name="value"/> <xsl:variable name="normalized" select="translate($value, '_abcdefghijklmnopqrstuvwrxyz', '-ABCDEFGHIJKLMNOPQRSTUVWRXYZ')"/> <xsl:value-of select="$normalized"/> </xsl:template> +<xsl:template match="/resource-agent[1]"> + <!-- NOTE: if you see this, there is some chance you are using outdated cman package --> + <ref name="<xsl:call-template name="capitalize"><xsl:with-param name="value" select="@name"/></xsl:call-template>"/></xsl:template> <xsl:template match="/resource-agent"> <ref name="<xsl:call-template name="capitalize"><xsl:with-param name="value" select="@name"/></xsl:call-template>"/></xsl:template> </xsl:stylesheet> diff --git a/rgmanager/src/resources/ra2rng.xsl b/rgmanager/src/resources/ra2rng.xsl index 3cb098d..5b9a307 100644 --- a/rgmanager/src/resources/ra2rng.xsl +++ b/rgmanager/src/resources/ra2rng.xsl @@ -7,6 +7,7 @@ <xsl:param name="global-init-indent" select="' '"/> <xsl:param name="global-indent" select="' '"/> +<xsl:param name="global-ra-children-elem" select="'CHILDREN'"/> <!-- @@ -471,6 +472,10 @@ <xsl:template match="/resource-agent"> <xsl:value-of select="$NL"/> + <!-- + first define per-RA element itself... + --> + <!-- define name=... (start) --> <xsl:variable name="capitalized"> <xsl:call-template name="capitalize"> @@ -666,18 +671,18 @@ <!-- optional (start) --> <xsl:call-template name="tag-start"> - <xsl:with-param name="name" select="'optional'"/> + <xsl:with-param name="name" select="'zeroOrMore'"/> <xsl:with-param name="indented" select="concat($global-init-indent, $global-indent)"/> </xsl:call-template> <xsl:value-of select="$NL"/> - <!-- ref name="CHILDREN" --> + <!-- ref name="CHILDREN" (or equiv.) --> <xsl:call-template name="tag"> <xsl:with-param name="name" select="'ref'"/> <xsl:with-param name="attrs" select="concat( - 'name=', $Q, 'CHILDREN', $Q)"/> + 'name=', $Q, $global-ra-children-elem, $Q)"/> <xsl:with-param name="indented" select="concat($global-init-indent, $global-indent, @@ -687,7 +692,7 @@ <!-- optional (end) --> <xsl:call-template name="tag-end"> - <xsl:with-param name="name" select="'optional'"/> + <xsl:with-param name="name" select="'zeroOrMore'"/> <xsl:with-param name="indented" select="concat($global-init-indent, $global-indent)"/> @@ -708,6 +713,35 @@ </xsl:call-template> <xsl:value-of select="$NLNL"/> + <!-- + ...then add a reference to such defined symbol to CHILDREN (or equiv.) + --> + + <!-- define name="CHILDREN" (or equiv.; start) --> + <xsl:call-template name="tag-start"> + <xsl:with-param name="name" select="'define'"/> + <xsl:with-param name="attrs" select="concat( + 'name=', $Q, $global-ra-children-elem, $Q, $SP, + 'combine=', $Q, 'choice', $Q)"/> + </xsl:call-template> + <xsl:value-of select="$NL"/> + + <!-- ref name="$capitalized" --> + <xsl:call-template name="tag"> + <xsl:with-param name="name" select="'ref'"/> + <xsl:with-param name="attrs" select="concat( + 'name=', $Q, $capitalized, $Q)"/> + <xsl:with-param name="indented" + select="$global-init-indent"/> + </xsl:call-template> + <xsl:value-of select="$NL"/> + + <!-- define (end) --> + <xsl:call-template name="tag-end"> + <xsl:with-param name="name" select="'define'"/> + </xsl:call-template> + <xsl:value-of select="$NLNL"/> + </xsl:template> </xsl:stylesheet> diff --git a/rgmanager/src/resources/resources.rng.mid b/rgmanager/src/resources/resources.rng.mid index cc2dff3..3276eb5 100644 --- a/rgmanager/src/resources/resources.rng.mid +++ b/rgmanager/src/resources/resources.rng.mid @@ -1,3 +1 @@ - <define name="CHILDREN"> - <zeroOrMore> - <choice> + <rha:ignore> diff --git a/rgmanager/src/resources/resources.rng.tail b/rgmanager/src/resources/resources.rng.tail index d0f41ce..4a1ea22 100644 --- a/rgmanager/src/resources/resources.rng.tail +++ b/rgmanager/src/resources/resources.rng.tail @@ -1,7 +1,8 @@ - <ref name="RESOURCEACTION"/> - </choice> - </zeroOrMore> + </rha:ignore> + + <define name="CHILDREN" combine="choice"> + <ref name="RESOURCEACTION"/> </define> <define name="RESOURCECOMMONPARAMS" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> -- 1.8.1.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Cluster-devel] [PATCH 2/2] rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata 2013-12-16 12:38 [Cluster-devel] [resource-agents][PATCH 0/2] rgmanager: ra2rng.xsl et al.: cross-package schema extension Jan Pokorný 2013-12-16 12:38 ` [Cluster-devel] [PATCH 1/2] rgmanager: ra2rng.xsl et al.: obsolete 1 pass in ccs_update_schema Jan Pokorný @ 2013-12-16 12:38 ` Jan Pokorný 2013-12-16 12:48 ` Jan Pokorný 2013-12-16 12:58 ` [Cluster-devel] [PATCH] " Jan Pokorný 1 sibling, 2 replies; 7+ messages in thread From: Jan Pokorný @ 2013-12-16 12:38 UTC (permalink / raw) To: cluster-devel.redhat.com As with previous change, the reflection of this change is yet to come to cluster.git (ccs_update_schema script) via a separate patch. Note that this effectively adds requirement for xmllint/libxml2, but it is required by xsltproc/libxslt already anyway. Also note that this provision to schema generation will not work properly until libxslt bugfix [1] is propagated to the target deployment. [1] https://mail.gnome.org/archives/xslt/2013-December/msg00001.html Signed-off-by: Jan Pokorn? <jpokorny@redhat.com> --- rgmanager/src/resources/Makefile.am | 15 +- rgmanager/src/resources/ra2rng-postprocess.xsl | 265 +++++++++++++++++++++++++ rgmanager/src/resources/ra2rng.xsl | 12 ++ 3 files changed, 287 insertions(+), 5 deletions(-) create mode 100644 rgmanager/src/resources/ra2rng-postprocess.xsl diff --git a/rgmanager/src/resources/Makefile.am b/rgmanager/src/resources/Makefile.am index caeb947..00435f7 100644 --- a/rgmanager/src/resources/Makefile.am +++ b/rgmanager/src/resources/Makefile.am @@ -105,12 +105,17 @@ ras-validation: $(RESOURCES) $(TARGET) $(DTD) resources.rng: $(RESOURCES) $(TARGET) utils/config-utils.sh resources.rng: $(XSL) $(RESRNG) rm -f resources.rng - cat resources.rng.head >> resources.rng @echo Generating per-resource RelaxNG information... - @for f in $(RESOURCES) $(TARGET); do \ - echo " ./$$f"; \ - bash ./$$f meta-data | xsltproc ra2rng.xsl - >> resources.rng; \ - done + cat resources.rng.head >> resources.rng + @{ echo '<rha:wrap xmlns:rha="http://redhat.com/~pkennedy/annotation_namespace/cluster_conf_annot_namespace">'; \ + for f in $(RESOURCES) $(TARGET); do \ + echo " ./$$f" >&2; \ + bash ./$$f meta-data | xsltproc ra2rng.xsl -; \ + done; \ + echo '</rha:wrap>'; } \ + | xsltproc ra2rng-postprocess.xsl - \ + | xmllint --xpath '/*[local-name() = "wrap"]/node()' - \ + >> resources.rng cat resources.rng.mid >> resources.rng cat resources.rng.tail >> resources.rng diff --git a/rgmanager/src/resources/ra2rng-postprocess.xsl b/rgmanager/src/resources/ra2rng-postprocess.xsl new file mode 100644 index 0000000..066efb3 --- /dev/null +++ b/rgmanager/src/resources/ra2rng-postprocess.xsl @@ -0,0 +1,265 @@ +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:int="__internal__" + xmlns:rha="http://redhat.com/~pkennedy/annotation_namespace/cluster_conf_annot_namespace" + exclude-result-prefixes="int"> + +<xsl:param name="global-init-indent" select="' '"/> +<xsl:param name="global-indent" select="' '"/> +<xsl:param name="global-radefine-all" select="'CHILDREN'"/> +<xsl:param name="global-radefine-except" + select="concat($global-radefine-all, '-EXCEPT-')"/> + + +<!-- + helper definitions + --> + +<xsl:variable name="SP" select="' '"/> +<xsl:variable name="NL" select="'
'"/> +<xsl:variable name="NLNL" select="'

'"/> + +<!-- NOTES: + - radefine + := define[element] + - restrictingradefine + := define[element and rha:restriction] + and in this context also: ^- and @rha:type = 'forbid-childelem' + NOTE: element is currently insignificant, as currently + it is implied by the other constraints + - forbidchildradefine + := radefines forbidden to be referred to from restrictingradefines + (as per particular RAs metadada and in turn intermediate + rha:restriction annotation) + - forbidstring + := for restrictingradefine denotes concatenation of respective + forbidchildradefines' (ordered!) names (see limitation below + and also refer to get-forbidstring named template) + - revmap + := map using 'key' xslt facility defined reversely, but + serving for lookups as implied by the particular name + (i.e., not viceversa, "rev" part is already applied) + - limitation: 5+ forbidchildradefines per restrictingradefine + (currently 5 atmost, and can be scaled further + by brainless extension of concat's if needed) + --> +<xsl:key name="revmap-forbidstring-to-restrictingradefines" + match="define[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]" + use="concat( + rha:restriction[ + @rha:type = 'forbid-childelem' + ][1]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][2]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][3]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][4]/@rha:value + )"/> + +<!-- xsl:key name="revmap-forbidchildradefine-to-restrictingradefines" + match="define[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]" + use="//define[ + /element/@name = current()/rha:restriction[ + @rha:type = 'forbid-childelem' + ]@rha:value + ]"/--> + +<xsl:key name="revmap-radefine-to-forbidchildradefines" + match="define[ + element/@name + ]" + use="//define[rha:restriction[ + @rha:type = 'forbid-childelem' + and + @rha:value = current()/element/@name + ]]"/> + +<xsl:template name="get-forbidstring"> + <xsl:param name="radefine"/> + <xsl:value-of select="concat( + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][1]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][2]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][3]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][4]/@rha:value + )"/> +</xsl:template> + +<xsl:variable name="all-radefines" + select="//define[ + element/@name + ]"/> + +<xsl:variable name="all-restrictingradefines" + select="$all-radefines[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]"/> + + +<!-- + proceed + --> + +<!-- start with and use identity by default... --> + +<xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> +</xsl:template> + +<!-- ...unless a special case of restrictingradefine, which needs + $global-radefine-all reference rewritten to custom + $global-radefine-except$forbidstring... --> + +<xsl:template match="@*|node()" mode="rewrite"> + <xsl:copy> + <xsl:apply-templates select="@*|node()" mode="rewrite"/> + </xsl:copy> +</xsl:template> + +<xsl:template match="ref/@name[. = 'CHILDREN']" + mode="rewrite"> + <!-- NOTE: forbidstring evaluated anew as we do a traversal-based + template application rather than procedural one + (as there is generally not a direct link parent-child) --> + <xsl:variable name="forbidstring"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="ancestor::define[last()]"/> + </xsl:call-template> + </xsl:variable> + <xsl:attribute name="{name()}"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring)"/> + </xsl:attribute> +</xsl:template> + +<!-- ... which is triggered amongst others in the following core logic + matching any radefine --> + +<xsl:template match="define[ + element/@name + ]"> + <xsl:variable name="forbidstring"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="."/> + </xsl:call-template> + </xsl:variable> + <xsl:variable name="self" select="."/> + + <!-- identity modulo rha:restriction + rewrite or not as per above --> + <xsl:copy> + <xsl:choose> + <xsl:when test="$forbidstring != ''"> + <xsl:apply-templates select="@*|*[ + name() != 'rha:restriction' + ]|processing-instruction()|comment()" + mode="rewrite"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates select="@*|*[ + name() != 'rha:restriction' + ]|processing-instruction()|comment()"/> + </xsl:otherwise> + </xsl:choose> + </xsl:copy> + + <!-- if we know that $global-radefine-except$forbidstring is not + defined by us (set of all radefines is set of all + restrictingradefines for this very $forbidstring) AND it is + the first restrictingradefine for particular forbidchildradefines + (virtually an ordered set, as concatenation keeps ordering), + define empty $global-radefine-except$forbidstring symbol, just + for the sake of being defined@all (otherwise it couldn't be + resolved when no such forbidchildradefine existed) --> + <xsl:if test="$forbidstring != '' + and + count( + key( + 'revmap-radefine-to-forbidchildradefines', + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring + )[1] + ) + ) = count($all-radefines) + and + generate-id( + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring + ) + ) = generate-id()"> + <xsl:value-of select="concat($NL, $global-init-indent)"/> + <xsl:element name="define"> + <xsl:attribute name="name"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring)"/> + </xsl:attribute> + <xsl:attribute name="combine"> + <xsl:value-of select="'choice'"/> + </xsl:attribute> + </xsl:element> + </xsl:if> + + <!-- state the membership of the current radefine in all various + $global-radefine-except$forbidstring'ish sets by the means of + "combining definition" feature of Relax NG (similar to what is + already done with $global-radefine-all themselves) --> + <xsl:for-each select="$all-restrictingradefines"> + <!-- $forbidstring use here always a bug, but cannot be redefined --> + <xsl:variable name="forbidstring-other"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="."/> + </xsl:call-template> + </xsl:variable> + <!-- access via the first item below is because this is the only + guaranteed to exist --> + <xsl:if test="not( + key( + 'revmap-radefine-to-forbidchildradefines', + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring-other + )[1] + )[generate-id() = generate-id($self)] + )"> + <xsl:value-of select="concat($NL, $global-init-indent)"/> + <xsl:element name="define"> + <xsl:attribute name="name"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring-other)"/> + </xsl:attribute> + <xsl:attribute name="combine"> + <xsl:value-of select="'choice'"/> + </xsl:attribute> + <xsl:element name="ref"> + <xsl:attribute name="name"> + <xsl:value-of select="$self/@name"/> + </xsl:attribute> + </xsl:element> + </xsl:element> + </xsl:if> + </xsl:for-each> + +</xsl:template> + +</xsl:stylesheet> diff --git a/rgmanager/src/resources/ra2rng.xsl b/rgmanager/src/resources/ra2rng.xsl index 5b9a307..71df682 100644 --- a/rgmanager/src/resources/ra2rng.xsl +++ b/rgmanager/src/resources/ra2rng.xsl @@ -489,6 +489,18 @@ </xsl:call-template> <xsl:value-of select="$NL"/> + <xsl:for-each select="special[@tag='rgmanager']/child[@forbid='1']"> + <xsl:call-template name="tag"> + <xsl:with-param name="name" select="'rha:restriction'"/> + <xsl:with-param name="attrs" select="concat( + 'rha:type=', $Q, 'forbid-childelem', $Q, $SP, + 'rha:value=', $Q, @type, $Q)"/> + <xsl:with-param name="indented" + select="$global-init-indent"/> + </xsl:call-template> + <xsl:value-of select="$NL"/> + </xsl:for-each> + <!-- element name=... rha:description=... (start) --> <xsl:call-template name="tag-start"> <xsl:with-param name="name" select="'element'"/> -- 1.8.1.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Cluster-devel] [PATCH 2/2] rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata 2013-12-16 12:38 ` [Cluster-devel] [PATCH 2/2] rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata Jan Pokorný @ 2013-12-16 12:48 ` Jan Pokorný 2013-12-16 12:58 ` [Cluster-devel] [PATCH] " Jan Pokorný 1 sibling, 0 replies; 7+ messages in thread From: Jan Pokorný @ 2013-12-16 12:48 UTC (permalink / raw) To: cluster-devel.redhat.com On 16/12/13 13:38 +0100, Jan Pokorn? wrote: > Also note that this provision to schema generation will not work > properly until libxslt bugfix [1] is propagated to the target > deployment. > > [1] https://mail.gnome.org/archives/xslt/2013-December/msg00001.html Filed as https://bugzilla.redhat.com/show_bug.cgi?id=1043485 -- Jan ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Cluster-devel] [PATCH] rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata 2013-12-16 12:38 ` [Cluster-devel] [PATCH 2/2] rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata Jan Pokorný 2013-12-16 12:48 ` Jan Pokorný @ 2013-12-16 12:58 ` Jan Pokorný 2013-12-16 15:35 ` [Cluster-devel] [PATCHv3 2/2] " Jan Pokorný 1 sibling, 1 reply; 7+ messages in thread From: Jan Pokorný @ 2013-12-16 12:58 UTC (permalink / raw) To: cluster-devel.redhat.com As with previous change, the reflection of this change is yet to come to cluster.git (ccs_update_schema script) via a separate patch. There is a new file included in "DIST", ra2rng-postprocess.xsl, that is to be appended to a pipe with original ra2rng.xsl (both with xsltproc as an effective actor, indeed), that in turn now requires some extra decoration as can be found also in the respective Makefile.am. Note that this effectively adds requirement for xmllint/libxml2, but it is required by xsltproc/libxslt already anyway. Also note that this provision to schema generation will not work properly until libxslt bugfix [1] is propagated to the target deployment. [1] https://mail.gnome.org/archives/xslt/2013-December/msg00001.html Signed-off-by: Jan Pokorn? <jpokorny@redhat.com> --- rgmanager/src/resources/Makefile.am | 17 +- rgmanager/src/resources/ra2rng-postprocess.xsl | 265 +++++++++++++++++++++++++ rgmanager/src/resources/ra2rng.xsl | 12 ++ 3 files changed, 288 insertions(+), 6 deletions(-) create mode 100644 rgmanager/src/resources/ra2rng-postprocess.xsl diff --git a/rgmanager/src/resources/Makefile.am b/rgmanager/src/resources/Makefile.am index caeb947..af350a9 100644 --- a/rgmanager/src/resources/Makefile.am +++ b/rgmanager/src/resources/Makefile.am @@ -41,7 +41,7 @@ HELPERS = ocf-shellfuncs svclib_nfslock \ DTD = ra-api-1-modified.dtd -XSL = ra2man.xsl ra2ref.xsl ra2rng.xsl +XSL = ra2man.xsl ra2ref.xsl ra2rng.xsl ra2rng-postprocess.xsl RESRNG = resources.rng.head resources.rng.mid resources.rng.tail @@ -105,12 +105,17 @@ ras-validation: $(RESOURCES) $(TARGET) $(DTD) resources.rng: $(RESOURCES) $(TARGET) utils/config-utils.sh resources.rng: $(XSL) $(RESRNG) rm -f resources.rng - cat resources.rng.head >> resources.rng @echo Generating per-resource RelaxNG information... - @for f in $(RESOURCES) $(TARGET); do \ - echo " ./$$f"; \ - bash ./$$f meta-data | xsltproc ra2rng.xsl - >> resources.rng; \ - done + cat resources.rng.head >> resources.rng + @{ echo '<rha:wrap xmlns:rha="http://redhat.com/~pkennedy/annotation_namespace/cluster_conf_annot_namespace">'; \ + for f in $(RESOURCES) $(TARGET); do \ + echo " ./$$f" >&2; \ + bash ./$$f meta-data | xsltproc ra2rng.xsl -; \ + done; \ + echo '</rha:wrap>'; } \ + | xsltproc ra2rng-postprocess.xsl - \ + | xmllint --xpath '/*[local-name() = "wrap"]/node()' - \ + >> resources.rng cat resources.rng.mid >> resources.rng cat resources.rng.tail >> resources.rng diff --git a/rgmanager/src/resources/ra2rng-postprocess.xsl b/rgmanager/src/resources/ra2rng-postprocess.xsl new file mode 100644 index 0000000..066efb3 --- /dev/null +++ b/rgmanager/src/resources/ra2rng-postprocess.xsl @@ -0,0 +1,265 @@ +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:int="__internal__" + xmlns:rha="http://redhat.com/~pkennedy/annotation_namespace/cluster_conf_annot_namespace" + exclude-result-prefixes="int"> + +<xsl:param name="global-init-indent" select="' '"/> +<xsl:param name="global-indent" select="' '"/> +<xsl:param name="global-radefine-all" select="'CHILDREN'"/> +<xsl:param name="global-radefine-except" + select="concat($global-radefine-all, '-EXCEPT-')"/> + + +<!-- + helper definitions + --> + +<xsl:variable name="SP" select="' '"/> +<xsl:variable name="NL" select="'
'"/> +<xsl:variable name="NLNL" select="'

'"/> + +<!-- NOTES: + - radefine + := define[element] + - restrictingradefine + := define[element and rha:restriction] + and in this context also: ^- and @rha:type = 'forbid-childelem' + NOTE: element is currently insignificant, as currently + it is implied by the other constraints + - forbidchildradefine + := radefines forbidden to be referred to from restrictingradefines + (as per particular RAs metadada and in turn intermediate + rha:restriction annotation) + - forbidstring + := for restrictingradefine denotes concatenation of respective + forbidchildradefines' (ordered!) names (see limitation below + and also refer to get-forbidstring named template) + - revmap + := map using 'key' xslt facility defined reversely, but + serving for lookups as implied by the particular name + (i.e., not viceversa, "rev" part is already applied) + - limitation: 5+ forbidchildradefines per restrictingradefine + (currently 5 atmost, and can be scaled further + by brainless extension of concat's if needed) + --> +<xsl:key name="revmap-forbidstring-to-restrictingradefines" + match="define[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]" + use="concat( + rha:restriction[ + @rha:type = 'forbid-childelem' + ][1]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][2]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][3]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][4]/@rha:value + )"/> + +<!-- xsl:key name="revmap-forbidchildradefine-to-restrictingradefines" + match="define[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]" + use="//define[ + /element/@name = current()/rha:restriction[ + @rha:type = 'forbid-childelem' + ]@rha:value + ]"/--> + +<xsl:key name="revmap-radefine-to-forbidchildradefines" + match="define[ + element/@name + ]" + use="//define[rha:restriction[ + @rha:type = 'forbid-childelem' + and + @rha:value = current()/element/@name + ]]"/> + +<xsl:template name="get-forbidstring"> + <xsl:param name="radefine"/> + <xsl:value-of select="concat( + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][1]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][2]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][3]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][4]/@rha:value + )"/> +</xsl:template> + +<xsl:variable name="all-radefines" + select="//define[ + element/@name + ]"/> + +<xsl:variable name="all-restrictingradefines" + select="$all-radefines[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]"/> + + +<!-- + proceed + --> + +<!-- start with and use identity by default... --> + +<xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> +</xsl:template> + +<!-- ...unless a special case of restrictingradefine, which needs + $global-radefine-all reference rewritten to custom + $global-radefine-except$forbidstring... --> + +<xsl:template match="@*|node()" mode="rewrite"> + <xsl:copy> + <xsl:apply-templates select="@*|node()" mode="rewrite"/> + </xsl:copy> +</xsl:template> + +<xsl:template match="ref/@name[. = 'CHILDREN']" + mode="rewrite"> + <!-- NOTE: forbidstring evaluated anew as we do a traversal-based + template application rather than procedural one + (as there is generally not a direct link parent-child) --> + <xsl:variable name="forbidstring"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="ancestor::define[last()]"/> + </xsl:call-template> + </xsl:variable> + <xsl:attribute name="{name()}"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring)"/> + </xsl:attribute> +</xsl:template> + +<!-- ... which is triggered amongst others in the following core logic + matching any radefine --> + +<xsl:template match="define[ + element/@name + ]"> + <xsl:variable name="forbidstring"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="."/> + </xsl:call-template> + </xsl:variable> + <xsl:variable name="self" select="."/> + + <!-- identity modulo rha:restriction + rewrite or not as per above --> + <xsl:copy> + <xsl:choose> + <xsl:when test="$forbidstring != ''"> + <xsl:apply-templates select="@*|*[ + name() != 'rha:restriction' + ]|processing-instruction()|comment()" + mode="rewrite"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates select="@*|*[ + name() != 'rha:restriction' + ]|processing-instruction()|comment()"/> + </xsl:otherwise> + </xsl:choose> + </xsl:copy> + + <!-- if we know that $global-radefine-except$forbidstring is not + defined by us (set of all radefines is set of all + restrictingradefines for this very $forbidstring) AND it is + the first restrictingradefine for particular forbidchildradefines + (virtually an ordered set, as concatenation keeps ordering), + define empty $global-radefine-except$forbidstring symbol, just + for the sake of being defined@all (otherwise it couldn't be + resolved when no such forbidchildradefine existed) --> + <xsl:if test="$forbidstring != '' + and + count( + key( + 'revmap-radefine-to-forbidchildradefines', + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring + )[1] + ) + ) = count($all-radefines) + and + generate-id( + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring + ) + ) = generate-id()"> + <xsl:value-of select="concat($NL, $global-init-indent)"/> + <xsl:element name="define"> + <xsl:attribute name="name"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring)"/> + </xsl:attribute> + <xsl:attribute name="combine"> + <xsl:value-of select="'choice'"/> + </xsl:attribute> + </xsl:element> + </xsl:if> + + <!-- state the membership of the current radefine in all various + $global-radefine-except$forbidstring'ish sets by the means of + "combining definition" feature of Relax NG (similar to what is + already done with $global-radefine-all themselves) --> + <xsl:for-each select="$all-restrictingradefines"> + <!-- $forbidstring use here always a bug, but cannot be redefined --> + <xsl:variable name="forbidstring-other"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="."/> + </xsl:call-template> + </xsl:variable> + <!-- access via the first item below is because this is the only + guaranteed to exist --> + <xsl:if test="not( + key( + 'revmap-radefine-to-forbidchildradefines', + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring-other + )[1] + )[generate-id() = generate-id($self)] + )"> + <xsl:value-of select="concat($NL, $global-init-indent)"/> + <xsl:element name="define"> + <xsl:attribute name="name"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring-other)"/> + </xsl:attribute> + <xsl:attribute name="combine"> + <xsl:value-of select="'choice'"/> + </xsl:attribute> + <xsl:element name="ref"> + <xsl:attribute name="name"> + <xsl:value-of select="$self/@name"/> + </xsl:attribute> + </xsl:element> + </xsl:element> + </xsl:if> + </xsl:for-each> + +</xsl:template> + +</xsl:stylesheet> diff --git a/rgmanager/src/resources/ra2rng.xsl b/rgmanager/src/resources/ra2rng.xsl index 5b9a307..71df682 100644 --- a/rgmanager/src/resources/ra2rng.xsl +++ b/rgmanager/src/resources/ra2rng.xsl @@ -489,6 +489,18 @@ </xsl:call-template> <xsl:value-of select="$NL"/> + <xsl:for-each select="special[@tag='rgmanager']/child[@forbid='1']"> + <xsl:call-template name="tag"> + <xsl:with-param name="name" select="'rha:restriction'"/> + <xsl:with-param name="attrs" select="concat( + 'rha:type=', $Q, 'forbid-childelem', $Q, $SP, + 'rha:value=', $Q, @type, $Q)"/> + <xsl:with-param name="indented" + select="$global-init-indent"/> + </xsl:call-template> + <xsl:value-of select="$NL"/> + </xsl:for-each> + <!-- element name=... rha:description=... (start) --> <xsl:call-template name="tag-start"> <xsl:with-param name="name" select="'element'"/> -- 1.8.1.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Cluster-devel] [PATCHv3 2/2] rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata 2013-12-16 12:58 ` [Cluster-devel] [PATCH] " Jan Pokorný @ 2013-12-16 15:35 ` Jan Pokorný 2013-12-16 16:57 ` [Cluster-devel] [PATCHv4 " Jan Pokorný 0 siblings, 1 reply; 7+ messages in thread From: Jan Pokorný @ 2013-12-16 15:35 UTC (permalink / raw) To: cluster-devel.redhat.com As with previous change, the reflection of this change is yet to come to cluster.git (ccs_update_schema script) via a separate patch. There is a new file included in "DIST", ra2rng-postprocess.xsl, that is to be appended to a pipe with original ra2rng.xsl (both with xsltproc as an effective actor, indeed), that in turn now requires some extra decoration as can be found also in the respective Makefile.am. Also note that this provision to schema generation will not work properly until libxslt bugfix [1] is propagated to the target deployment. [1] https://mail.gnome.org/archives/xslt/2013-December/msg00001.html Signed-off-by: Jan Pokorn? <jpokorny@redhat.com> --- rgmanager/src/resources/Makefile.am | 22 +- rgmanager/src/resources/ra2rng-postprocess.xsl | 267 +++++++++++++++++++++++++ rgmanager/src/resources/ra2rng.xsl | 12 ++ 3 files changed, 293 insertions(+), 8 deletions(-) create mode 100644 rgmanager/src/resources/ra2rng-postprocess.xsl diff --git a/rgmanager/src/resources/Makefile.am b/rgmanager/src/resources/Makefile.am index caeb947..58da177 100644 --- a/rgmanager/src/resources/Makefile.am +++ b/rgmanager/src/resources/Makefile.am @@ -41,7 +41,7 @@ HELPERS = ocf-shellfuncs svclib_nfslock \ DTD = ra-api-1-modified.dtd -XSL = ra2man.xsl ra2ref.xsl ra2rng.xsl +XSL = ra2man.xsl ra2ref.xsl ra2rng.xsl ra2rng-postprocess.xsl RESRNG = resources.rng.head resources.rng.mid resources.rng.tail @@ -99,20 +99,26 @@ ras-validation: $(RESOURCES) $(TARGET) $(DTD) # NOTE: resources.rng.mid and resources.rng.tail not joined for # compatibility with obsolete 2-passes-logic of # ccs_update_schema script from external cman package +# (new logic part behaves just like this recipe) # # XXX: race-prone in parallel make # resources.rng: $(RESOURCES) $(TARGET) utils/config-utils.sh resources.rng: $(XSL) $(RESRNG) rm -f resources.rng - cat resources.rng.head >> resources.rng @echo Generating per-resource RelaxNG information... - @for f in $(RESOURCES) $(TARGET); do \ - echo " ./$$f"; \ - bash ./$$f meta-data | xsltproc ra2rng.xsl - >> resources.rng; \ - done - cat resources.rng.mid >> resources.rng - cat resources.rng.tail >> resources.rng + cat resources.rng.head >> resources.rng + @{ echo '<rha:wrap xmlns:rha="http://redhat.com/~pkennedy/annotation_namespace/cluster_conf_annot_namespace">'; \ + for f in $(RESOURCES) $(TARGET); do \ + echo " ./$$f" >&2; \ + bash ./$$f meta-data | xsltproc ra2rng.xsl -; \ + done; \ + echo '</rha:wrap>'; } \ + | xsltproc ra2rng-postprocess.xsl - \ + | sed -e '/\s*<[\/]\?rha:wrap[^>]*>\s*/d' \ + >> resources.rng + @sed -ne '/<\/rha:ignore>/bx;d;:x;n;p;bx' resources.rng.tail \ + >> resources.rng utils/config-utils.sh: make -C utils config-utils.sh diff --git a/rgmanager/src/resources/ra2rng-postprocess.xsl b/rgmanager/src/resources/ra2rng-postprocess.xsl new file mode 100644 index 0000000..ddb627d --- /dev/null +++ b/rgmanager/src/resources/ra2rng-postprocess.xsl @@ -0,0 +1,267 @@ +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:int="__internal__" + xmlns:rha="http://redhat.com/~pkennedy/annotation_namespace/cluster_conf_annot_namespace" + exclude-result-prefixes="int"> + +<xsl:output omit-xml-declaration="yes"/> + +<xsl:param name="global-init-indent" select="' '"/> +<xsl:param name="global-indent" select="' '"/> +<xsl:param name="global-radefine-all" select="'CHILDREN'"/> +<xsl:param name="global-radefine-except" + select="concat($global-radefine-all, '-EXCEPT-')"/> + + +<!-- + helper definitions + --> + +<xsl:variable name="SP" select="' '"/> +<xsl:variable name="NL" select="'
'"/> +<xsl:variable name="NLNL" select="'

'"/> + +<!-- NOTES: + - radefine + := define[element] + - restrictingradefine + := define[element and rha:restriction] + and in this context also: ^- and @rha:type = 'forbid-childelem' + NOTE: element is currently insignificant, as currently + it is implied by the other constraints + - forbidchildradefine + := radefines forbidden to be referred to from restrictingradefines + (as per particular RAs metadada and in turn intermediate + rha:restriction annotation) + - forbidstring + := for restrictingradefine denotes concatenation of respective + forbidchildradefines' (ordered!) names (see limitation below + and also refer to get-forbidstring named template) + - revmap + := map using 'key' xslt facility defined reversely, but + serving for lookups as implied by the particular name + (i.e., not viceversa, "rev" part is already applied) + - limitation: 5+ forbidchildradefines per restrictingradefine + (currently 5 atmost, and can be scaled further + by brainless extension of concat's if needed) + --> +<xsl:key name="revmap-forbidstring-to-restrictingradefines" + match="define[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]" + use="concat( + rha:restriction[ + @rha:type = 'forbid-childelem' + ][1]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][2]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][3]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][4]/@rha:value + )"/> + +<!-- xsl:key name="revmap-forbidchildradefine-to-restrictingradefines" + match="define[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]" + use="//define[ + /element/@name = current()/rha:restriction[ + @rha:type = 'forbid-childelem' + ]@rha:value + ]"/--> + +<xsl:key name="revmap-radefine-to-forbidchildradefines" + match="define[ + element/@name + ]" + use="//define[rha:restriction[ + @rha:type = 'forbid-childelem' + and + @rha:value = current()/element/@name + ]]"/> + +<xsl:template name="get-forbidstring"> + <xsl:param name="radefine"/> + <xsl:value-of select="concat( + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][1]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][2]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][3]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][4]/@rha:value + )"/> +</xsl:template> + +<xsl:variable name="all-radefines" + select="//define[ + element/@name + ]"/> + +<xsl:variable name="all-restrictingradefines" + select="$all-radefines[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]"/> + + +<!-- + proceed + --> + +<!-- start with and use identity by default... --> + +<xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> +</xsl:template> + +<!-- ...unless a special case of restrictingradefine, which needs + $global-radefine-all reference rewritten to custom + $global-radefine-except$forbidstring... --> + +<xsl:template match="@*|node()" mode="rewrite"> + <xsl:copy> + <xsl:apply-templates select="@*|node()" mode="rewrite"/> + </xsl:copy> +</xsl:template> + +<xsl:template match="ref/@name[. = 'CHILDREN']" + mode="rewrite"> + <!-- NOTE: forbidstring evaluated anew as we do a traversal-based + template application rather than procedural one + (as there is generally not a direct link parent-child) --> + <xsl:variable name="forbidstring"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="ancestor::define[last()]"/> + </xsl:call-template> + </xsl:variable> + <xsl:attribute name="{name()}"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring)"/> + </xsl:attribute> +</xsl:template> + +<!-- ... which is triggered amongst others in the following core logic + matching any radefine --> + +<xsl:template match="define[ + element/@name + ]"> + <xsl:variable name="forbidstring"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="."/> + </xsl:call-template> + </xsl:variable> + <xsl:variable name="self" select="."/> + + <!-- identity modulo rha:restriction + rewrite or not as per above --> + <xsl:copy> + <xsl:choose> + <xsl:when test="$forbidstring != ''"> + <xsl:apply-templates select="@*|*[ + name() != 'rha:restriction' + ]|processing-instruction()|comment()" + mode="rewrite"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates select="@*|*[ + name() != 'rha:restriction' + ]|processing-instruction()|comment()"/> + </xsl:otherwise> + </xsl:choose> + </xsl:copy> + + <!-- if we know that $global-radefine-except$forbidstring is not + defined by us (set of all radefines is set of all + restrictingradefines for this very $forbidstring) AND it is + the first restrictingradefine for particular forbidchildradefines + (virtually an ordered set, as concatenation keeps ordering), + define empty $global-radefine-except$forbidstring symbol, just + for the sake of being defined@all (otherwise it couldn't be + resolved when no such forbidchildradefine existed) --> + <xsl:if test="$forbidstring != '' + and + count( + key( + 'revmap-radefine-to-forbidchildradefines', + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring + )[1] + ) + ) = count($all-radefines) + and + generate-id( + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring + ) + ) = generate-id()"> + <xsl:value-of select="concat($NL, $global-init-indent)"/> + <xsl:element name="define"> + <xsl:attribute name="name"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring)"/> + </xsl:attribute> + <xsl:attribute name="combine"> + <xsl:value-of select="'choice'"/> + </xsl:attribute> + </xsl:element> + </xsl:if> + + <!-- state the membership of the current radefine in all various + $global-radefine-except$forbidstring'ish sets by the means of + "combining definition" feature of Relax NG (similar to what is + already done with $global-radefine-all themselves) --> + <xsl:for-each select="$all-restrictingradefines"> + <!-- $forbidstring use here always a bug, but cannot be redefined --> + <xsl:variable name="forbidstring-other"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="."/> + </xsl:call-template> + </xsl:variable> + <!-- access via the first item below is because this is the only + guaranteed to exist --> + <xsl:if test="not( + key( + 'revmap-radefine-to-forbidchildradefines', + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring-other + )[1] + )[generate-id() = generate-id($self)] + )"> + <xsl:value-of select="concat($NL, $global-init-indent)"/> + <xsl:element name="define"> + <xsl:attribute name="name"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring-other)"/> + </xsl:attribute> + <xsl:attribute name="combine"> + <xsl:value-of select="'choice'"/> + </xsl:attribute> + <xsl:element name="ref"> + <xsl:attribute name="name"> + <xsl:value-of select="$self/@name"/> + </xsl:attribute> + </xsl:element> + </xsl:element> + </xsl:if> + </xsl:for-each> + +</xsl:template> + +</xsl:stylesheet> diff --git a/rgmanager/src/resources/ra2rng.xsl b/rgmanager/src/resources/ra2rng.xsl index 5b9a307..71df682 100644 --- a/rgmanager/src/resources/ra2rng.xsl +++ b/rgmanager/src/resources/ra2rng.xsl @@ -489,6 +489,18 @@ </xsl:call-template> <xsl:value-of select="$NL"/> + <xsl:for-each select="special[@tag='rgmanager']/child[@forbid='1']"> + <xsl:call-template name="tag"> + <xsl:with-param name="name" select="'rha:restriction'"/> + <xsl:with-param name="attrs" select="concat( + 'rha:type=', $Q, 'forbid-childelem', $Q, $SP, + 'rha:value=', $Q, @type, $Q)"/> + <xsl:with-param name="indented" + select="$global-init-indent"/> + </xsl:call-template> + <xsl:value-of select="$NL"/> + </xsl:for-each> + <!-- element name=... rha:description=... (start) --> <xsl:call-template name="tag-start"> <xsl:with-param name="name" select="'element'"/> -- 1.8.1.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Cluster-devel] [PATCHv4 2/2] rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata 2013-12-16 15:35 ` [Cluster-devel] [PATCHv3 2/2] " Jan Pokorný @ 2013-12-16 16:57 ` Jan Pokorný 0 siblings, 0 replies; 7+ messages in thread From: Jan Pokorný @ 2013-12-16 16:57 UTC (permalink / raw) To: cluster-devel.redhat.com As with previous change, the reflection of this change is yet to come to cluster.git (ccs_update_schema script) via a separate patch. There is a new file included in "DIST", ra2rng-postprocess.xsl, that is to be appended to a pipe with original ra2rng.xsl (both with xsltproc as an effective actor, indeed), that in turn now requires some extra decoration as can be found also in the respective Makefile.am. In netfs.sh, the order of forbidden children in metadata now follows alphabetical ordering, which is in-line with other such occurrences in RAs metadata. Also note that this provision to schema generation will not work properly until libxslt bugfix [1] is propagated to the target deployment. [1] https://mail.gnome.org/archives/xslt/2013-December/msg00001.html Signed-off-by: Jan Pokorn? <jpokorny@redhat.com> --- rgmanager/src/resources/Makefile.am | 22 +- rgmanager/src/resources/netfs.sh | 2 +- rgmanager/src/resources/ra2rng-postprocess.xsl | 290 +++++++++++++++++++++++++ rgmanager/src/resources/ra2rng.xsl | 12 + 4 files changed, 317 insertions(+), 9 deletions(-) create mode 100644 rgmanager/src/resources/ra2rng-postprocess.xsl diff --git a/rgmanager/src/resources/Makefile.am b/rgmanager/src/resources/Makefile.am index caeb947..d26861c 100644 --- a/rgmanager/src/resources/Makefile.am +++ b/rgmanager/src/resources/Makefile.am @@ -41,7 +41,7 @@ HELPERS = ocf-shellfuncs svclib_nfslock \ DTD = ra-api-1-modified.dtd -XSL = ra2man.xsl ra2ref.xsl ra2rng.xsl +XSL = ra2man.xsl ra2ref.xsl ra2rng.xsl ra2rng-postprocess.xsl RESRNG = resources.rng.head resources.rng.mid resources.rng.tail @@ -99,20 +99,26 @@ ras-validation: $(RESOURCES) $(TARGET) $(DTD) # NOTE: resources.rng.mid and resources.rng.tail not joined for # compatibility with obsolete 2-passes-logic of # ccs_update_schema script from external cman package +# (new logic part behaves just like this recipe) # # XXX: race-prone in parallel make # resources.rng: $(RESOURCES) $(TARGET) utils/config-utils.sh resources.rng: $(XSL) $(RESRNG) rm -f resources.rng - cat resources.rng.head >> resources.rng @echo Generating per-resource RelaxNG information... - @for f in $(RESOURCES) $(TARGET); do \ - echo " ./$$f"; \ - bash ./$$f meta-data | xsltproc ra2rng.xsl - >> resources.rng; \ - done - cat resources.rng.mid >> resources.rng - cat resources.rng.tail >> resources.rng + cat resources.rng.head >> resources.rng + @{ echo '<rha:wrap xmlns:rha="http://redhat.com/~pkennedy/annotation_namespace/cluster_conf_annot_namespace">'; \ + for f in $(RESOURCES) $(TARGET); do \ + echo " ./$$f" >&2; \ + bash ./$$f meta-data | xsltproc ra2rng.xsl -; \ + done; \ + echo '</rha:wrap>'; } \ + | xsltproc ra2rng-postprocess.xsl - \ + | sed -e '/\s*<[\/]\?rha:wrap[^>]*>\s*/d' \ + >> resources.rng + sed -ne '/<\/rha:ignore>/bI;d;:I;n;p;bI' resources.rng.tail \ + >> resources.rng utils/config-utils.sh: make -C utils config-utils.sh diff --git a/rgmanager/src/resources/netfs.sh b/rgmanager/src/resources/netfs.sh index 5dad993..46ad3b1 100755 --- a/rgmanager/src/resources/netfs.sh +++ b/rgmanager/src/resources/netfs.sh @@ -173,8 +173,8 @@ do_metadata() </actions> <special tag="rgmanager"> - <child type="nfsexport" forbid="1"/> <child type="nfsclient" forbid="1"/> + <child type="nfsexport" forbid="1"/> </special> </resource-agent> EOT diff --git a/rgmanager/src/resources/ra2rng-postprocess.xsl b/rgmanager/src/resources/ra2rng-postprocess.xsl new file mode 100644 index 0000000..3772ab2 --- /dev/null +++ b/rgmanager/src/resources/ra2rng-postprocess.xsl @@ -0,0 +1,290 @@ +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:int="__internal__" + xmlns:rha="http://redhat.com/~pkennedy/annotation_namespace/cluster_conf_annot_namespace" + exclude-result-prefixes="int"> + +<xsl:output omit-xml-declaration="yes"/> + +<xsl:param name="global-init-indent" select="' '"/> +<xsl:param name="global-indent" select="' '"/> +<xsl:param name="global-radefine-all" select="'CHILDREN'"/> +<xsl:param name="global-radefine-except" + select="concat($global-radefine-all, '-EXCEPT-')"/> + + +<!-- + helper definitions + --> + +<xsl:variable name="SP" select="' '"/> +<xsl:variable name="NL" select="'
'"/> +<xsl:variable name="NLNL" select="'

'"/> + +<!-- NOTES: + - radefine + := define[element] + - restrictingradefine + := define[element and rha:restriction] + and in this context also: ^- and @rha:type = 'forbid-childelem' + NOTE: element is currently insignificant, as currently + it is implied by the other constraints + - forbidchildradefine + := radefines forbidden to be referred to from restrictingradefines + (as per particular RAs metadada and in turn intermediate + rha:restriction annotation) + - forbidstring + := for restrictingradefine denotes concatenation of respective + forbidchildradefines' (ordered!) names (see limitation below + and also refer to get-forbidstring named template) + - revmap + := map using 'key' xslt facility defined reversely, but + serving for lookups as implied by the particular name + (i.e., not viceversa, "rev" part is already applied) + - limitation: currently utmost 4 forbidchildradefines per + restrictingradefine, but can be scaled further + by brainless extension of concat's if needed + --> +<xsl:key name="revmap-forbidstring-to-restrictingradefines" + match="define[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]" + use="concat( + rha:restriction[ + @rha:type = 'forbid-childelem' + ][1]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][2]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][3]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][4]/@rha:value + )"/> + +<!-- xsl:key name="revmap-forbidchildradefine-to-restrictingradefines" + match="define[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]" + use="//define[ + /element/@name = current()/rha:restriction[ + @rha:type = 'forbid-childelem' + ]@rha:value + ]"/--> + +<xsl:key name="revmap-radefine-to-forbidchildradefines" + match="define[ + element/@name + ]" + use="//define[rha:restriction[ + @rha:type = 'forbid-childelem' + and + @rha:value = current()/element/@name + ]]"/> + +<xsl:variable name="all-radefines" + select="//define[ + element/@name + ]"/> + +<xsl:variable name="all-restrictingradefines" + select="$all-radefines[rha:restriction[ + @rha:type = 'forbid-childelem' + ]]"/> + +<xsl:variable name="all-unique-restrictingradefines" + select="$all-restrictingradefines[ + generate-id( + key( + 'revmap-forbidstring-to-restrictingradefines', + concat( + rha:restriction[ + @rha:type = 'forbid-childelem' + ][1]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][2]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][3]/@rha:value, + rha:restriction[ + @rha:type = 'forbid-childelem' + ][4]/@rha:value + ) + ) + ) = generate-id() + ]"/> + +<xsl:template name="get-forbidstring"> + <xsl:param name="radefine"/> + <xsl:value-of select="concat( + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][1]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][2]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][3]/@rha:value, + $radefine/rha:restriction[ + @rha:type = 'forbid-childelem' + ][4]/@rha:value + )"/> +</xsl:template> + + +<!-- + proceed + --> + +<!-- start with and use identity by default... --> + +<xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> +</xsl:template> + +<!-- ...unless a special case of restrictingradefine, which needs + $global-radefine-all reference rewritten to custom + $global-radefine-except$forbidstring... --> + +<xsl:template match="@*|node()" mode="rewrite"> + <xsl:copy> + <xsl:apply-templates select="@*|node()" mode="rewrite"/> + </xsl:copy> +</xsl:template> + +<xsl:template match="ref/@name[. = 'CHILDREN']" + mode="rewrite"> + <!-- NOTE: forbidstring evaluated anew as we do a traversal-based + template application rather than procedural one + (as there is generally not a direct link parent-child) --> + <xsl:variable name="forbidstring"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="ancestor::define[last()]"/> + </xsl:call-template> + </xsl:variable> + <xsl:attribute name="{name()}"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring)"/> + </xsl:attribute> +</xsl:template> + +<!-- ... which is triggered amongst others in the following core logic + matching any radefine --> + +<xsl:template match="define[ + element/@name + ]"> + <xsl:variable name="forbidstring"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="."/> + </xsl:call-template> + </xsl:variable> + <xsl:variable name="self" select="."/> + + <!-- identity modulo rha:restriction + rewrite or not as per above --> + <xsl:copy> + <xsl:choose> + <xsl:when test="$forbidstring != ''"> + <xsl:apply-templates select="@*|*[ + name() != 'rha:restriction' + ]|processing-instruction()|comment()" + mode="rewrite"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates select="@*|*[ + name() != 'rha:restriction' + ]|processing-instruction()|comment()"/> + </xsl:otherwise> + </xsl:choose> + </xsl:copy> + + <!-- if we know that $global-radefine-except$forbidstring is not + defined by us (set of all radefines is set of all + restrictingradefines for this very $forbidstring) AND it is + the first restrictingradefine for particular forbidchildradefines + (virtually an ordered set, as concatenation keeps ordering), + define empty $global-radefine-except$forbidstring symbol, just + for the sake of being defined@all (otherwise it couldn't be + resolved when no such forbidchildradefine existed) --> + <xsl:if test="$forbidstring != '' + and + count( + key( + 'revmap-radefine-to-forbidchildradefines', + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring + )[1] + ) + ) = count($all-radefines) + and + generate-id( + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring + ) + ) = generate-id()"> + <xsl:value-of select="concat($NL, $global-init-indent)"/> + <xsl:element name="define"> + <xsl:attribute name="name"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring)"/> + </xsl:attribute> + <xsl:attribute name="combine"> + <xsl:value-of select="'choice'"/> + </xsl:attribute> + </xsl:element> + </xsl:if> + + <!-- state the membership of the current radefine in all various + $global-radefine-except$forbidstring'ish sets by the means of + "combining definition" feature of Relax NG (similar to what is + already done with $global-radefine-all themselves) --> + <xsl:for-each select="$all-unique-restrictingradefines"> + <!-- $forbidstring use here always a bug, but cannot be redefined --> + <xsl:variable name="forbidstring-other"> + <xsl:call-template name="get-forbidstring"> + <xsl:with-param name="radefine" + select="."/> + </xsl:call-template> + </xsl:variable> + <!-- access via the first item below is because this is the only + guaranteed to exist --> + <xsl:if test="not( + key( + 'revmap-radefine-to-forbidchildradefines', + key( + 'revmap-forbidstring-to-restrictingradefines', + $forbidstring-other + )[1] + )[generate-id() = generate-id($self)] + )"> + <xsl:value-of select="concat($NL, $global-init-indent)"/> + <xsl:element name="define"> + <xsl:attribute name="name"> + <xsl:value-of select="concat($global-radefine-except, + $forbidstring-other)"/> + </xsl:attribute> + <xsl:attribute name="combine"> + <xsl:value-of select="'choice'"/> + </xsl:attribute> + <xsl:element name="ref"> + <xsl:attribute name="name"> + <xsl:value-of select="$self/@name"/> + </xsl:attribute> + </xsl:element> + </xsl:element> + </xsl:if> + </xsl:for-each> + +</xsl:template> + +</xsl:stylesheet> diff --git a/rgmanager/src/resources/ra2rng.xsl b/rgmanager/src/resources/ra2rng.xsl index 5b9a307..71df682 100644 --- a/rgmanager/src/resources/ra2rng.xsl +++ b/rgmanager/src/resources/ra2rng.xsl @@ -489,6 +489,18 @@ </xsl:call-template> <xsl:value-of select="$NL"/> + <xsl:for-each select="special[@tag='rgmanager']/child[@forbid='1']"> + <xsl:call-template name="tag"> + <xsl:with-param name="name" select="'rha:restriction'"/> + <xsl:with-param name="attrs" select="concat( + 'rha:type=', $Q, 'forbid-childelem', $Q, $SP, + 'rha:value=', $Q, @type, $Q)"/> + <xsl:with-param name="indented" + select="$global-init-indent"/> + </xsl:call-template> + <xsl:value-of select="$NL"/> + </xsl:for-each> + <!-- element name=... rha:description=... (start) --> <xsl:call-template name="tag-start"> <xsl:with-param name="name" select="'element'"/> -- 1.8.1.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-12-16 16:57 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-12-16 12:38 [Cluster-devel] [resource-agents][PATCH 0/2] rgmanager: ra2rng.xsl et al.: cross-package schema extension Jan Pokorný 2013-12-16 12:38 ` [Cluster-devel] [PATCH 1/2] rgmanager: ra2rng.xsl et al.: obsolete 1 pass in ccs_update_schema Jan Pokorný 2013-12-16 12:38 ` [Cluster-devel] [PATCH 2/2] rgmanager: ra2rng.xsl et al.: enforce "forbid child" from RA metadata Jan Pokorný 2013-12-16 12:48 ` Jan Pokorný 2013-12-16 12:58 ` [Cluster-devel] [PATCH] " Jan Pokorný 2013-12-16 15:35 ` [Cluster-devel] [PATCHv3 2/2] " Jan Pokorný 2013-12-16 16:57 ` [Cluster-devel] [PATCHv4 " Jan Pokorný
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).