Switching

last person joined: 20 hours ago 

Ask questions and share experiences about EX and QFX portfolios and all switching solutions across your data center, campus, and branch locations.
  • 1.  Dual root, but different JUNOS versions

    Posted 12-12-2012 09:54

    All,

     

    I have five EX4200 switches in a Virtual Chassis (VC) configuration running 12.1R3.5.  During a recent power outtage, one of those 5 switches did boot boot properly from it's active root partition, it booted from its backup root partition.  It turned out that the backup root partition had JUNOS 11.4 installed, so the switch did not properly rejoin the VC.

     

    My question is: What steps do I need to take to make sure the active and backup root partitions have the same JUNOS version?  If they don't, how do I copy the latest JUNOS to BOTH root partitions?

     

    Thank you,

    RER



  • 2.  RE: Dual root, but different JUNOS versions

     
    Posted 12-13-2012 06:10

    hi,

     

    to check Junos versions on both partions:

     

    admin@EX> show system snapshot media internal
    Information for snapshot on       internal (/dev/da0s1a) (backup)
    Creation date: Apr 25 00:48:48 2012
    JUNOS version on snapshot:
      jbase  : 10.4R9.2
      jcrypto-ex: 10.4R9.2
      jdocs-ex: 10.4R9.2
      jkernel-ex: 10.4R9.2
      jroute-ex: 10.4R9.2
      jswitch-ex: 10.4R9.2
      jweb-ex: 10.4R9.2
      jpfe-ex42x: 10.4R9.2
    Information for snapshot on       internal (/dev/da0s2a) (primary)
    Creation date: May 2 15:56:11 2012
    JUNOS version on snapshot:
      jbase  : ex-11.4R2.14
      jcrypto-ex: 11.4R2.14
      jdocs-ex: 11.4R2.14
      jroute-ex: 11.4R2.14
      jswitch-ex: 11.4R2.14
      jweb-ex: 11.4R2.14

     

    to copy software to alternate partition & check results: boot from primary and request software snapshot:

     

    admin@EX> request system snapshot slice alternate
    Formatting alternate root (/dev/da0s1a)...
    Copying '/dev/da0s2a' to '/dev/da0s1a' .. (this may take a few minutes)
    The following filesystems were archived: /
    
    admin@EX> show system snapshot media internal
    Information for snapshot on       internal (/dev/da0s1a) (backup)
    Creation date: Nov 16 18:04:49 2012
    JUNOS version on snapshot:
      jbase  : ex-11.4R2.14
      jcrypto-ex: 11.4R2.14
      jdocs-ex: 11.4R2.14
      jroute-ex: 11.4R2.14
      jswitch-ex: 11.4R2.14
      jweb-ex: 11.4R2.14
    Information for snapshot on       internal (/dev/da0s2a) (primary)
    Creation date: May 2 15:56:11 2012
    JUNOS version on snapshot:
      jbase  : ex-11.4R2.14
      jcrypto-ex: 11.4R2.14
      jdocs-ex: 11.4R2.14
      jroute-ex: 11.4R2.14
      jswitch-ex: 11.4R2.14
      jweb-ex: 11.4R2.14

     

    jtb

     

     



  • 3.  RE: Dual root, but different JUNOS versions

    Posted 03-11-2013 13:31

    Is there a way to catch when the partitions are not the same via a SNMP OID via polling or a trap?

     

    We've seen the error "WARNING: JUNOS versions running on dual partitions are not same" in the logs but tht's it.



  • 4.  RE: Dual root, but different JUNOS versions

     
    Posted 03-12-2013 05:16

    Hi,

     

     

    I'm not aware of any such OID, but maybe you can find something useful using this resource:

     

    https://www.juniper.net/techpubs/en_US/release-independent/junos/mibs/mibs.html

     

    However, you can use event policy to match on that specific string and generate an action afterwards.



  • 5.  RE: Dual root, but different JUNOS versions

    Posted 03-16-2013 23:10

    Can you point me to a good resource on event policies or provide an example?  Not much experience with JUNOS here.



  • 6.  RE: Dual root, but different JUNOS versions

    Posted 03-24-2013 20:47

    To add to what jtb mentioned, you can snapshot to all members in a virtual chassis by running request system snapshot slice alternate all-members.  That way you can ensure all members in a chassis have a consistent version of Junos.

     

    More details can be found at http://www.juniper.net/techpubs/en_US/junos/topics/task/installation/ex-series-software-upgrading-nssu-fixed-virtual-chassis-cli.html.



  • 7.  RE: Dual root, but different JUNOS versions

    Posted 19 days ago

    Hello Erdem

    Have you found a solution for monitoring this issue?

    We have the same problem..



    ------------------------------
    ANDREAS WESTERGAARD ANDERSEN
    ------------------------------



  • 8.  RE: Dual root, but different JUNOS versions

     
    Posted 19 days ago
    Edited by asharp 15 days ago

    A few approaches that come to mind for this are.

    1. SLAX/Python event-script, could be scheduled to run daily and check if there is a discrepancy between the partitions, and if there is to trigger  a snapshot.
    2. SLAX/Python snmp-script to check if there is a discrepancy and return an OID for the state.  Although this does require Junos 15.1 or higher.

    It could also be possible to implement a solution off-box as well, which could be driven by a number of options using Junos PyEZ Python library which could be leveraged by an off-box Python script, or via a tool such as Ansible/Salt, or even off-box SLAX using JUISE.

    I did take a look at this in more detail and the following is a script that I have written that demonstrates some of this.  With the approach shown below it should be good for some early versions of Junos as well, I suspect that it will probably work for Junos 9.6 and higher, although I only tested it with 12.1.

    It shows examples of sending SNMP traps, and also updating OIDs in the Juniper Utility MIB that could then be polled without too much effort.  Or, with minimal changes it could just as easily send to syslog.

    This is a SLAX example, but the same approach could be written using Python, it would depend on the version of Junos and the capabilities.

    In this example I was using a couple of SRX setup in a cluster, and each node of the cluster has dual partitions, so the approach would be similar for other device types.

    With this event-script, the script was copied to both nodes of the cluster and stored as /var/db/scripts/event/snapshot-check.slax

    I added the event script to the configuration, and setup a timer event and policy for the event-script within the script itself, so that there is less configuration that needs to be applied.  But the event-definition could be removed from the script, and instead an event policy could be configured instead.

    Example:

    show configuration event-options
    event-script {
        file snapshot-check.slax;
    }
    
    With the above configuration applied, the event-policy defined within the script
    is now active used, as shown by the CLI command below.
    
    show event-options event-scripts policies
    ## Last changed: 2024-04-09 16:24:15 UTC
    event-options {
        generate-event {
            every-hour time-interval 3600;
        }
        policy snapshot-check {
            events every-hour;
            then {
                event-script snapshot-check.slax;
            }
        }
    }


    With this in place, the script is executed every hour.  Don't forget that if the script is modified, then it will be necessary to reload the script via the CLI, e.g. request system scripts event-scripts reload

    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";
    
    var $event-definition = {
        <event-options> {
            <generate-event> {
                <name> "every-hour";
                <time-interval> "3600";
            }
            <policy> {
                <name> "snapshot-check";
                <events> "every-hour";
                <then> {
                    <event-script> {
                        <name> "snapshot-check.slax";
                    }
                }
            }
        }
    }
    
    match / {
        <event-script-results> {
            /* check only 1 instance running */
            if(not(jcs:dampen("snapshot-check", 1, 1))) {
                expr jcs:syslog("external.notice", "snapshot-check", "dampen exit OK.");
                <xsl:message terminate="yes">;
            }
    
            /* open connection */
            var $conn = jcs:open();
            if ($conn/..//xnm:error) {
                call rpc_failure($rpc = $conn/.., $message = "Error connecting on mgd on this RE");
                <xsl:message terminate="yes">;
            }
    
            /* define rpc */
            var $get-snapshot-info-rpc = {
                <get-snapshot-information> {
                    <media> "internal";
                }
            }
    
            /* get snapshot info */
            var $get-snapshot-results = jcs:execute($conn, $get-snapshot-info-rpc);
            if ($get-snapshot-results/..//xnm:error) {
                call rpc_failure($rpc = $get-snapshot-results/.., $message = "Error collecting snapshot information!");
            }
    
            /* parse results */
            for-each ($get-snapshot-results/multi-routing-engine-item) {
                if (re-name == "node0") {
                    /* check for primary and backup partition */
                    if (count(./snapshot-information/snapshot-medium) != 2) {
    
                        /* update utility mib */
                        call snmp_update(
                            $connection = $conn,
                            $instance = "node0",
                            $obj-type = "string",
                            $obj-value = "Only one parition found!"
                        );
    
                        call snmp_update(
                            $connection = $conn,
                            $instance = "node0_status",
                            $obj-type = "integer",
                            $obj-value = 1
                        );
    
                        /* generate a trap */
                        var $requestSnmpTrapNode0 = <request-snmp-generate-trap> {
                            <trap> "jnxEventTrap";
                            <variable-bindings> "jnxEventTrapDescr[0]=Event-Trap, "
                            _ "jnxEventAvAttribute[1]=event, "
                            _ "jnxEventAvValue[1]=NODE0-SNAPSHOT-ALARM, "
                            _ "jnxEventAvAttribute[2]=Desc, "
                            _ "jnxEventAvValue[2]=Not enough partitions, "
                            _ "jnxEventAvAttribute[3]=status-value, "
                            _ "jnxEventAvValue[3]=" _ 1;
                        }
                        var $res_trap_node0 = jcs:execute($conn, $requestSnmpTrapNode0);
    
                    } else {
                        /* check version on primary and backup */
                        if (./snapshot-information/software-version[1]/package[package-name="junos"]/package-version !=
                            ./snapshot-information/software-version[2]/package[package-name="junos"]/package-version) {
    
                            /* update utility mib */
                            call snmp_update(
                                $connection = $conn,
                                $instance = "node0",
                                $obj-type = "string",
                                $obj-value = "Version mismatch between partitions!"
                            );
    
                            call snmp_update(
                                $connection = $conn,
                                $instance = "node0_status",
                                $obj-type = "integer",
                                $obj-value = 1
                            );
    
                            /* generate a trap */
                            var $requestSnmpTrapNode0 = <request-snmp-generate-trap> {
                                <trap> "jnxEventTrap";
                                <variable-bindings> "jnxEventTrapDescr[0]=Event-Trap, "
                                _ "jnxEventAvAttribute[1]=event, "
                                _ "jnxEventAvValue[1]=NODE0-SNAPSHOT-ALARM, "
                                _ "jnxEventAvAttribute[2]=Desc, "
                                _ "jnxEventAvValue[2]=Version mismatch, "
                                _ "jnxEventAvAttribute[3]=status-value, "
                                _ "jnxEventAvValue[3]=" _ 1;
                            }
                            var $res_trap_node0 = jcs:execute($conn, $requestSnmpTrapNode0);
                        } else {
                            /* update utility mib */
                            call snmp_update(
                                $connection = $conn,
                                $instance = "node0",
                                $obj-type = "string",
                                $obj-value = "Both partitions have same version " _ 
                                ./snapshot-information/software-version[1]/package[package-name="junos"]/package-version
                            );
    
                            call snmp_update(
                                $connection = $conn,
                                $instance = "node0_status",
                                $obj-type = "integer",
                                $obj-value = 0
                            );
                        }
                    }
                }
                if (re-name == "node1") {
                    if (count(./snapshot-information/snapshot-medium) != 2) {
                        /* update utility mib */
                        call snmp_update(
                            $connection = $conn,
                            $instance = "node1",
                            $obj-type = "string",
                            $obj-value = "Only one parition found!"
                        );
    
                        call snmp_update(
                            $connection = $conn,
                            $instance = "node1_status",
                            $obj-type = "integer",
                            $obj-value = 1
                        );
    
                        /* generate a trap */
                        var $requestSnmpTrapNode1 = <request-snmp-generate-trap> {
                            <trap> "jnxEventTrap";
                            <variable-bindings> "jnxEventTrapDescr[0]=Event-Trap, "
                            _ "jnxEventAvAttribute[1]=event, "
                            _ "jnxEventAvValue[1]=NODE1-SNAPSHOT-ALARM, "
                            _ "jnxEventAvAttribute[2]=Desc, "
                            _ "jnxEventAvValue[2]=Not enough partitions, "
                            _ "jnxEventAvAttribute[3]=status-value, "
                            _ "jnxEventAvValue[3]=" _ 1;
                        }
                        var $res_trap_node1 = jcs:execute($conn, $requestSnmpTrapNode1);
    
                    } else {
                        if (./snapshot-information/software-version[1]/package[package-name="junos"]/package-version !=
                            ./snapshot-information/software-version[2]/package[package-name="junos"]/package-version) {
    
                            /* update utility mib */
                            call snmp_update(
                                $connection = $conn,
                                $instance = "node1",
                                $obj-type = "string",
                                $obj-value = "Version mismatch between partitions!"
                            );
    
                            call snmp_update(
                                $connection = $conn,
                                $instance = "node1_status",
                                $obj-type = "integer",
                                $obj-value = 1
                            );
    
                            /* generate a trap */
                            var $requestSnmpTrapNode1 = <request-snmp-generate-trap> {
                                <trap> "jnxEventTrap";
                                <variable-bindings> "jnxEventTrapDescr[0]=Event-Trap, "
                                _ "jnxEventAvAttribute[1]=event, "
                                _ "jnxEventAvValue[1]=NODE1-SNAPSHOT-ALARM, "
                                _ "jnxEventAvAttribute[2]=Desc, "
                                _ "jnxEventAvValue[2]=Version mismatch, "
                                _ "jnxEventAvAttribute[3]=status-value, "
                                _ "jnxEventAvValue[3]=" _ 1;
                            }
                            var $res_trap_node1 = jcs:execute($conn, $requestSnmpTrapNode1);
                        } else {
                            /* update utility mib */
                            call snmp_update(
                                $connection = $conn,
                                $instance = "node1",
                                $obj-type = "string",
                                $obj-value = "Both partitions have same version " _ 
                                ./snapshot-information/software-version[1]/package[package-name="junos"]/package-version
                            );
    
                            call snmp_update(
                                $connection = $conn,
                                $instance = "node1_status",
                                $obj-type = "integer",
                                $obj-value = 0
                            );
                        }
                    }
                }
            }
            expr jcs:close($conn);
        }
    }
    
    /* syslog */
    template rpc_failure($rpc, $message = "Following errors occurred while trying to gather data:") {
        expr jcs:syslog("daemon.error", $message);
        for-each ($rpc//xnm:error) {
            expr jcs:syslog("daemon.error", message);
        }
    }
    
    /* snmp utility mib */
    template snmp_update($connection, $instance, $obj-type, $obj-value) {
        var $rpc = {
            <request-snmp-utility-mib-set> {
                <instance> $instance;
                <object-type> $obj-type;
                <object-value> $obj-value;
            }
        }
        var $result = jcs:execute($connection, $rpc);
        if ($result/..//xnm:error) {
            call rpc_failure($rpc = $result/.., $message = "Error updating utility mib!");
        }
    }
    

    So the script does a few things and repeats the actions for each of nodes of the cluster. Some of the features are described here:

    1. jcs:dampen() used to prevent the script being executed multiple times at the same time.
    2. Make RPC to get-snapshot-information, this is equivalent to "show system snapshot media internal".
    3. Iterate through the response for each routing-engine, e.g. node0 and node1
    4. Verify that each node has 2 partitions (primary and backup)
    5. Verify that the partitions on each node have the same junos version present.
    6. Send snmp traps when either step 4 or step 5 are not true.
    7. Update the Juniper utility mib with a status value [0|1] where 0 is good, and 1 is bad for each node.
    8. Update the Juniper utility mib with a status string describing the state of the snapshots for each node.

    Based on that the expected state would be, that the utility MIB is updated with the following information that could be retrieved via SNMP. e.g.

    show snmp mib walk jnxUtil
    jnxUtilIntegerValue.110.111.100.101.48.95.115.116.97.116.117.115 = 0
    jnxUtilIntegerValue.110.111.100.101.49.95.115.116.97.116.117.115 = 0
    jnxUtilIntegerTime.110.111.100.101.48.95.115.116.97.116.117.115 = 07 e8 04 09  0e 16 15 00  2b 00 00
    jnxUtilIntegerTime.110.111.100.101.49.95.115.116.97.116.117.115 = 07 e8 04 09  0e 16 16 00  2b 00 00
    jnxUtilStringValue.110.111.100.101.48 = Both partitions have same version 12.1X46-D86-domestic
    jnxUtilStringValue.110.111.100.101.49 = Both partitions have same version 12.1X46-D86-domestic
    jnxUtilStringTime.110.111.100.101.48 = 07 e8 04 09  0e 16 15 00  2b 00 00
    jnxUtilStringTime.110.111.100.101.49 = 07 e8 04 09  0e 16 16 00  2b 00 00
    
    or using ascii output
    show snmp mib walk jnxUtil ascii
    jnxUtilIntegerValue."node0_status" = 0
    jnxUtilIntegerValue."node1_status" = 0
    jnxUtilIntegerTime."node0_status" = 07 e8 04 09  0e 16 15 00  2b 00 00
    jnxUtilIntegerTime."node1_status" = 07 e8 04 09  0e 16 16 00  2b 00 00
    jnxUtilStringValue."node0" = Both partitions have same version 12.1X46-D86-domestic
    jnxUtilStringValue."node1" = Both partitions have same version 12.1X46-D86-domestic
    jnxUtilStringTime."node0" = 07 e8 04 09  0e 16 15 00  2b 00 00
    jnxUtilStringTime."node1" = 07 e8 04 09  0e 16 16 00  2b 00 00

    I don't have an example of the SNMP trap that was sent, but it shouldn't be too difficult to see how the event trap is defined., and the MIB file can be found below,

    https://www.juniper.net/documentation/en_US/junos/topics/reference/mibs/mib-jnx-event.txt

    Regards


    ------------------------------
    Andy Sharp
    ------------------------------