To generate a persistent or transient change, follow these steps:
You must include either the XSLT or SLAX boilerplate in all commit scripts. For detailed information about this boilerplate, see Boilerplate for Commit Scripts.
XSLT Boilerplate
<?xml version="1.0" standalone="yes"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:junos="http://xml.juniper.net/junos/*/junos"
xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm"
xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0">
<xsl:import href="../import/junos.xsl"/>
<xsl:template match="configuration">
<!- - ... insert your code here ... - ->
</xsl:template>
</xsl:stylesheet>
SLAX Boilerplate
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";
match configuration {
/*
* Insert your code here.
*/
}
For example, the following XSLT programming instructions select each SONET/SDH interface that does not have the MPLS protocol family enabled:
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-')]/unit">
<xsl:if test="not(family/mpls)">
In SLAX, the for-each and if constructs look like this:
for-each (interfaces/interface[starts-with(name, 'so-')]/unit) {
if (not(family/mpls)) {
For more information about how to use programming instructions, including examples and pseudocode, see Programming Instructions. For information about writing your scripts in SLAX instead of XSLT, see Understanding SLAX.
The <jcs:emit-change> template allows for more efficient, less error-prone scripting because you can define the content of the change without specifying the complete XML hierarchy for the affected statement. Instead, the XML hierarchy is defined in the XPath expression contained in the script’s programming instruction.
Consider the following examples. Both of the persistent change examples have the same result, even though they place the unit statement in different locations in the <xsl:for-each> and <xsl:if> programming instructions. In both cases, the script searches for SONET/SDH interfaces that do not have the MPLS protocol family enabled, adds the family mpls statement at the [edit interfaces so-fpc/pic/port unit logical-unit-number] hierarchy level, and emits a warning message stating that the configuration has been changed. Likewise, both of the transient change examples have the same result. They both set Point-to-Point Protocol (PPP) encapsulation on all SONET/SDH interface that have IP version 4 (IPv4) enabled.
Persistent Change Generated with the <jcs:emit-change> Template
In this example, the content of the persistent change (contained in the content parameter) is specified without including the complete XML hierarchy. Instead, the XPath expression in the <xsl:for-each> programming instruction sets the context for the change.
The message parameter is also included. This parameter causes the <jcs:emit-change> template to call the <xnm:warning> template, which sends a warning notification to the CLI. The message parameter automatically includes the current hierarchy information in the warning message. (For more information about the parameters available with the <jcs:emit-change> template, see <jcs:emit-change> Template.)
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-')]/unit">
<xsl:if test="not(family/mpls)">
<xsl:call-template name="jcs:emit-change">
<xsl:with-param name="content">
<family>
<mpls/>
</family>
</xsl:with-param>
<xsl:with-param name="message">
<xsl:text>Adding 'family mpls' to SONET interface.</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
Persistent Change Generated with the <change> Element
In this example, the complete XML hierarchy leading to the affected statement must be included as child elements of the <change> element.
This example includes the current hierarchy information in the warning message by referencing the <jcs:edit-path> and <jcs:statement> templates. For more information about warning messages, see Generating a Custom Warning, Error, or System Log Message.
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-')]">
<xsl:if test="not(unit/family/mpls)">
<change>
<interfaces>
<interface>
<name><xsl:value-of select="name"/></name>
<unit>
<name><xsl:value-of select="unit/name"/></name>
<family>
<mpls/>
</family>
</unit>
</interface>
</interfaces>
</change>
<xnm:warning>
<xsl:call-template name="jcs:edit-path"/>
<xsl:call-template name="jcs:statement">
<xsl:with-param name="dot" select="unit/name"/>
</xsl:call-template>
<message>Adding 'family mpls' to SONET interface.</message>
</xnm:warning>
</xsl:if>
</xsl:for-each>
Transient Change Generated with the <jcs:emit-change> Template
In this example, the content of the transient change (contained in the content parameter) is specified without including the complete XML hierarchy. Instead, the XPath expression in the <xsl:for-each> programming instruction sets the context of the change. The and operator in the XPath expression means both operands are true when converted to Booleans; the second operand is not evaluated if the first operand is false.
The tag parameter is included with 'transient-change' selected. Without the tag parameter, the <jcs:emit-change> template generates a persistent change by default. (For more information about the parameters available with the <jcs:emit-change> template, see <jcs:emit-change> Template.)
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-') and unit/family/inet]">
<xsl:call-template name="jcs:emit-change">
<xsl:with-param name="tag" select="'transient-change'"/>
<xsl:with-param name="content">
<encapsulation>ppp</encapsulation>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
Transient Change Generated with the <transient-change> Element
In this example, the complete XML hierarchy leading to the affected statement must be included as child elements of the <transient-change> element.
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-') and unit/family/inet]">
<transient-change>
<interfaces>
<interface>
<name><xsl:value-of select="name"/></name>
<encapsulation>ppp</encapsulation>
</interface>
</interfaces>
</transient-change>
</xsl:for-each>
If a platform has dual Routing Engines and you want the script to take effect on both Routing Engines, you must copy the script to the /var/db/scripts/commit directory on each Routing Engine. The commit synchronize command does not automatically copy the scripts from one Routing Engine directory into the other Routing Engine directory.
- [edit system scripts commit]
-
file filename;
- [edit system scripts commit]
-
allow-transients;
If all the commit scripts run without errors, any persistent changes are loaded into the candidate configuration and then the checkout configuration. Any transient changes are loaded into the checkout configuration only. The commit process then continues with the normal process of validating the configuration and propagating changes to the affected processes on the routing platform.
To display the configuration with both persistent and transient changes, issue the show | display commit-scripts configuration mode command:
[edit]
user@host# show | display commit-scripts
To display the configuration with persistent changes only, issue the show | display commit-scripts no-transients configuration mode command:
[edit]
user@host# show | display commit-scripts no-transients
Persistent changes work like the load merge command in that they cause the software to merge the incoming configuration into the current candidate configuration. If the existing configuration and the persistent change contain conflicting statements, the statements in the persistent change override those in the existing configuration. Transient changes work like the load update command in that they cause the software to replace only the configuration that has changed.