[opensuse-autoinstall] Whats the purpose of classes? OR: How to modularize the XML profile?

Hello all, I've been using AutoYast successfully for a while now (incl. rules), but I never got to understand the purpose of classes or how exactly to use them... (even after reading the documentation about it :-) The docs about rules are quite nice, providing working examples. But for classes, I couldn't find a complete working example/setup. I have the following questions: 1) Until now, I came to understand that classes provide a way to include/merge external XML files. So how are they *different* from a set of XIncludes? 2) If they are different, how does a node know/decide which class it "belongs to" and thus, which XML files it is supposed to merge? Is there some kind of decision process like for rules? The reason I am asking these questions is that I would like to make a modular AutoYast profile XML. Currently, I have one giant_base.xml file plus some small amendments confX.xml, which are merged via rules.xml. My setup looks like this: /autoyast/ |--giant_base.xml |--conf1.xml |--conf2.xml | ... |--confN.xml `--rules `--rules.xml Unfortunately the giant_base.xml became too big to oversee things. What I would like to have is a more or less empty base.xml that simply imports all common parts from sub XMLs (i.e. I would like the partitioning section to have its own file, same with common software, networking stuff and so on). Once all common parts are included, the rules should merge the hardware/host specific changes. It should look like: /autoyast/ |--base_that_includes_common_stuff.xml |`--common | |--common_partitioning.xml | |--common_software.xml | ... | `--common_whatever.xml `--rules | `--rules.xml | ... How would one do this with AutoYast? Thanks for your help :-)

From the doc
... 6.2. Classes Classes represent configurations for groups of target systems. Unlike rules, classes have to be configured in the control file. Then classes can be assigned to target systems. ... So if a class definition exist in the autoinst.xml it will be loaded and the merge process start again. This means the selection is NOT done via the rules.xml So you could have a base autoinst.xml file which includes all common stuff like Example: project1.xml <classes config:type="list"> <class> <class_name>common</class_name> <configuration>partition.xml</configuration> </class> <class> <class_name>common</class_name> <configuration>software.xml</configuration> </class> <class> <class_name>common</class_name> <configuration>nfsclient.xml</configuration> </class> <class> <class_name>project1</class_name> <configuration>software.xml</configuration> </class> </classes> You could have a project2.xml with selects it unique settings from the class project2 but still using the common stuff. Of course in the rules.xml you must select which "project" will be used. This is my understanding. I tried to use Xincludes but failed and i never used classes. I use many small xml files which will be used to generated a autoinstall xml file before the node boots. Meaning i am using a configuration file which includes all required settings for a node and merge that stuff via a script to a final $(hostname).xml Example: The configuration: ... Default: Os = SLES11SP1 kernel = 32 Xml = Lvm.xml , Software.xml , Nfsclient.xml , post_script.xml MyNode1: Template = Default Xml = SpecialSoftware.xml Kernel = 64 MyNode2: Template = Default ... Will lead to a MyNode1.xml which is build of ALL xml named in Default: & MyNode1: but kernel type is 64bit. My rules.xml has has 2 entries: One to fetch the $(hostname).xml and another to include a generic script.xml. Hm, basically this logic could be implemented with classes right away and i would have no need to do a merge beforehand which can cause problems. Cheers Hajo -- To unsubscribe, e-mail: opensuse-autoinstall+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-autoinstall+owner@opensuse.org

Hello Hajo, thank you very much for your explanation. It confirmed my belief that "classes" are nothing else than a method to merge external XMLs, as --------- <class> <class_name>common</class_name> <configuration>partition.xml</configuration> </class> --------- simply fetches /<basedir>/classes/common/partition.xml to merge it. Really, the "class_name" tag is unnecessary, it just adds a subdir. Hence, I think that the term "class" as well as the docs saying "Classes represent configurations for groups of target systems" is misleading, because that is just *one specific* use case (amongst many others that do not really fit this description). On 09/26/2012 06:29 PM, Hans-Joachim Ehlers wrote:
From the doc
... 6.2. Classes Classes represent configurations for groups of target systems. Unlike rules, classes have to be configured in the control file. Then classes can be assigned to target systems. ...
So if a class definition exist in the autoinst.xml it will be loaded and the merge process start again. This means the selection is NOT done via the rules.xml
So you could have a base autoinst.xml file which includes all common stuff like
Example: project1.xml
<classes config:type="list"> <class> <class_name>common</class_name> <configuration>partition.xml</configuration> </class> <class> <class_name>common</class_name> <configuration>software.xml</configuration> </class> <class> <class_name>common</class_name> <configuration>nfsclient.xml</configuration> </class> <class> <class_name>project1</class_name> <configuration>software.xml</configuration> </class> </classes>
You could have a project2.xml with selects it unique settings from the class project2 but still using the common stuff. Of course in the rules.xml you must select which "project" will be used.
This is my understanding. I tried to use Xincludes but failed and i never used classes.
I use many small xml files which will be used to generated a autoinstall xml file before the node boots. Meaning i am using a configuration file which includes all required settings for a node and merge that stuff via a script to a final $(hostname).xml
Example:
The configuration: ... Default: Os = SLES11SP1 kernel = 32 Xml = Lvm.xml , Software.xml , Nfsclient.xml , post_script.xml
MyNode1: Template = Default Xml = SpecialSoftware.xml Kernel = 64
MyNode2: Template = Default
...
Will lead to a MyNode1.xml which is build of ALL xml named in Default: & MyNode1: but kernel type is 64bit. My rules.xml has has 2 entries: One to fetch the $(hostname).xml and another to include a generic script.xml.
Hm, basically this logic could be implemented with classes right away and i would have no need to do a merge beforehand which can cause problems.
Cheers Hajo

Ok, so I actually figured out that what I wanted to do is not possible with classes. My idea was to have a modular XML file like this: /autoyast/ |--base_that_includes_common_stuff_via_classes.xml |--classes | |--common | | |--common_partitioning.xml | | |--common_whatever.xml | | `--... | `--amendments | |--file_selected_via_rules.xml | `--... `--rules `--rules.xml Unfortunately, classes are merged AFTER rules were merged. Hence I cannot use classes to define a default profile (which is then amended via rules) because classes will overwrite the values written by rules. I guess I have to stick to my current layout, which is /autoyast/ |--giant_base.xml |--conf1.xml |--conf2.xml | ... |--confN.xml `--rules `--rules.xml Or does anyone have a suggestion how I can create a modular default profile? Thanks! On 09/27/2012 10:13 AM, Joschi Brauchle wrote:
Hello Hajo,
thank you very much for your explanation.
It confirmed my belief that "classes" are nothing else than a method to merge external XMLs, as --------- <class> <class_name>common</class_name> <configuration>partition.xml</configuration> </class> --------- simply fetches /<basedir>/classes/common/partition.xml to merge it. Really, the "class_name" tag is unnecessary, it just adds a subdir.
Hence, I think that the term "class" as well as the docs saying "Classes represent configurations for groups of target systems" is misleading, because that is just *one specific* use case (amongst many others that do not really fit this description).
On 09/26/2012 06:29 PM, Hans-Joachim Ehlers wrote:
From the doc
... 6.2. Classes Classes represent configurations for groups of target systems. Unlike rules, classes have to be configured in the control file. Then classes can be assigned to target systems. ...
So if a class definition exist in the autoinst.xml it will be loaded and the merge process start again. This means the selection is NOT done via the rules.xml
So you could have a base autoinst.xml file which includes all common stuff like
Example: project1.xml
<classes config:type="list"> <class> <class_name>common</class_name> <configuration>partition.xml</configuration> </class> <class> <class_name>common</class_name> <configuration>software.xml</configuration> </class> <class> <class_name>common</class_name> <configuration>nfsclient.xml</configuration> </class> <class> <class_name>project1</class_name> <configuration>software.xml</configuration> </class> </classes>
You could have a project2.xml with selects it unique settings from the class project2 but still using the common stuff. Of course in the rules.xml you must select which "project" will be used.
This is my understanding. I tried to use Xincludes but failed and i never used classes.
I use many small xml files which will be used to generated a autoinstall xml file before the node boots. Meaning i am using a configuration file which includes all required settings for a node and merge that stuff via a script to a final $(hostname).xml
Example:
The configuration: ... Default: Os = SLES11SP1 kernel = 32 Xml = Lvm.xml , Software.xml , Nfsclient.xml , post_script.xml
MyNode1: Template = Default Xml = SpecialSoftware.xml Kernel = 64
MyNode2: Template = Default
...
Will lead to a MyNode1.xml which is build of ALL xml named in Default: & MyNode1: but kernel type is 64bit. My rules.xml has has 2 entries: One to fetch the $(hostname).xml and another to include a generic script.xml.
Hm, basically this logic could be implemented with classes right away and i would have no need to do a merge beforehand which can cause problems.
Cheers Hajo

... via rules) because classes will overwrite the values written by rules. ????
What do you mean with "overwritten" . Autoyast will 'merge' the xml files. Depending of the section you might need a "dontmerge" entry. Of course i hope that the XML file order is not important for autoyast in case Classes and rules are used BUT from my experience entries within EACH xml file MUST be in a correct order. Sort example: a.xml has <user> U1 </user> <group> G1 G2 </group> b.xml has <group> G3 <group> Since a.xml is not sorted and depending what you merge order is ( a.xml with b.xml or b.xml with a.xml ) the desired result c.xml <user> U1 </user> <group> G1 G2 G3 </group> Will not be given. So ITS VERY IMPORTANT that entries within a xml file are sorted. The reference has hints on how to to do a merge to check if the desired result is given. Hth Hajo Reference - (xsltproc) http://suse.gansert.net/?p=38 - http://www.suse.de/~ug/autoyast_doc/rulesandclass.html#merging To sort a xml file i use the following: ( Provided by the Oliver Becker - The Author of the merge.xslt ) xsltproc --output ./MyFile.sorted.xml ./sortxslt ./MyFile.unsorted.xml With sortxslt like: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:param name="order" /> <xsl:output indent="yes" /> <xsl:template match="/*"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:for-each select="*"> <xsl:sort select="string-length(substring-before($order, name()))" /> <xsl:sort select="name()" /> <xsl:copy-of select="." /> </xsl:for-each> </xsl:copy> </xsl:template> </xsl:stylesheet> -- To unsubscribe, e-mail: opensuse-autoinstall+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-autoinstall+owner@opensuse.org

Hello Hajo, yes I am aware that XML entries must be sorted for merging to work correctly. Also you are right that I should not have used the term "overwritten". Consider the following scenario: By default, one wants to control the network via ifup, but for some machines Network manager should be used. The corresponding switch is: <networking> <managed config:type="boolean">true</managed> </networking> So if I put "managed=true" (shorthand notation) in a specific rule for some hosts and "managed=false" in a class file (designed to be a default value) for all other hosts, I will always end up with "managed=false". The reason is that the class is merged after the rule, overruling any previous value of the "managed" tag. Hence, when combining rules and classes, classes will overrule all settings done by rules which are not protected by a "dont_merge". Is that correct? If so, I cannot use classes to define "default" values which shall be changed by rules... On 09/27/2012 03:39 PM, Hans-Joachim Ehlers wrote:
... via rules) because classes will overwrite the values written by rules. ????
What do you mean with "overwritten" . Autoyast will 'merge' the xml files. Depending of the section you might need a "dontmerge" entry.
Of course i hope that the XML file order is not important for autoyast in case Classes and rules are used BUT from my experience entries within EACH xml file MUST be in a correct order.
Sort example:
a.xml has <user> U1 </user> <group> G1 G2 </group>
b.xml has <group> G3 <group>
Since a.xml is not sorted and depending what you merge order is ( a.xml with b.xml or b.xml with a.xml ) the desired result
c.xml <user> U1 </user>
<group> G1 G2 G3 </group>
Will not be given.
So ITS VERY IMPORTANT that entries within a xml file are sorted.
The reference has hints on how to to do a merge to check if the desired result is given.
Hth Hajo
Reference - (xsltproc) http://suse.gansert.net/?p=38 - http://www.suse.de/~ug/autoyast_doc/rulesandclass.html#merging
To sort a xml file i use the following: ( Provided by the Oliver Becker - The Author of the merge.xslt )
xsltproc --output ./MyFile.sorted.xml ./sortxslt ./MyFile.unsorted.xml
With sortxslt like:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="order" />
<xsl:output indent="yes" />
<xsl:template match="/*"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:for-each select="*"> <xsl:sort select="string-length(substring-before($order, name()))" /> <xsl:sort select="name()" /> <xsl:copy-of select="." /> </xsl:for-each> </xsl:copy> </xsl:template>
</xsl:stylesheet>
-- Dipl.-Ing. Joschi Brauchle, M.S. Institute for Communications Engineering (LNT) Technische Universitaet Muenchen (TUM) 80290 Munich, Germany Tel (work): +49 89 289-23474 Fax (work): +49 89 289-23490 E-mail: joschi.brauchle@tum.de Web: http://www.lnt.ei.tum.de/

Oh i understand. I would not define a standard but would check what autoyast uses as standard. Meaning the classes have only what is really required / must be set. For your example: If managed=true would be the default used by autoyast then you would have no entry for it in your class file. Of course you can have a <networking> section. So the rule could change the settings for certain hosts but during the class merge nothing would be "overwritten" To say it with other words. A default value will not be defined within a class file. Another way in case you would like to define a default within your class file. In your class you have for example a default ( true) for your networking definition which will be overwritten by a pre script. Example: ( not tested) ... # Change managed networking from true to false cp -av /tmp/profile/autoinst.xml /tmp/profile/modified.xml sed -i "/<networking>/,/<\/networking>/{/managed/s/true/false/}" /tmp/profile/modified.xml ... Note "dont_merge" would not help here since i assume that you would end up with something like: ... <networking> <managed config:type="boolean">true</managed> <managed config:type="boolean">false</managed> </networking> ... Does that makes sense ? Cheers Hajo -----Original Message----- From: Joschi Brauchle [mailto:joschi.brauchle@tum.de] Sent: Thursday, September 27, 2012 4:22 PM To: Hans-Joachim Ehlers Cc: opensuse-autoinstall@opensuse.org Subject: Re: [opensuse-autoinstall] Whats the purpose of classes? OR: How to modularize the XML profile? Hello Hajo, yes I am aware that XML entries must be sorted for merging to work correctly. Also you are right that I should not have used the term "overwritten". Consider the following scenario: By default, one wants to control the network via ifup, but for some machines Network manager should be used. The corresponding switch is: <networking> <managed config:type="boolean">true</managed> </networking> So if I put "managed=true" (shorthand notation) in a specific rule for some hosts and "managed=false" in a class file (designed to be a default value) for all other hosts, I will always end up with "managed=false". The reason is that the class is merged after the rule, overruling any previous value of the "managed" tag. Hence, when combining rules and classes, classes will overrule all settings done by rules which are not protected by a "dont_merge". Is that correct? If so, I cannot use classes to define "default" values which shall be changed by rules... .... -- To unsubscribe, e-mail: opensuse-autoinstall+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-autoinstall+owner@opensuse.org
participants (2)
-
Hans-Joachim Ehlers
-
Joschi Brauchle