rancid in a push configuration?
john heasley
heas at shrubbery.net
Tue Jul 31 04:29:18 UTC 2001
Mon, Jul 30, 2001 at 11:44:07PM -0400, Andrew Partan:
> > Not a bad suggestion. I used to be at Cisco, actually, and we had our own
> > Expect libraries which you could use to log in and execute commands on
> > remote routers. That was extremely handy.
>
> That is basically what clogin is.
> --asp
attached are the two samples. we're not quite ready for a 2.2 release.
-------------- next part --------------
##
## Copyright (C) 1997-2001 by Henry Kilmer.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed without
## fee for non-commerical purposes provided that this copyright notice is
## preserved intact on all copies and modified copies.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
## or its effect upon hardware, computer systems, other software, or
## anything else.
#
# this expect snipit is sourced by clogin (-s option) to load a configuration
# file (named <routername>-confg into nvram from an rcp/tftp host. this is an
# _example_ as it not guaranteed to work for all applications. PLEASE test
# for your environment.
#
# it expects the following variables via the -E option:
# rcphost ='host to rcp from' such as 'foo.org' or '192.168.0.1'
# confgpath ='path under /tftpboot where configs are held'
#
# the config file is expected to be routername-confg, where routername is the
# name as grok'd from the router's cmd-line prompt
#
# example usage:
# % clogin -s ./cisco-load.exp -Ercphost=foo.shrubbery.net router
# router
# loading router config from foo.shrubbery.net
#
# keep in mind that it is important to NOT polute the global variable space.
# particularly, do not use variables used within clogin. this may result in
# indeterministic results. an easy way to avoid this is to use a variable
# name prefix (like 'E' or '_').
#
# useful variables from clogin global space:
# router router name as provided on the cmd-line
# prompt cmd-line prompt as determined by clogin
#
# note: the tcl/expect parser is extremely stoopid. comment lines are NOT
# completely ignored!! so, a '{' or '}' in a comment might produce
# unexpected results.
##
# log_user 1
# exp_internal 1
# sometimes this is a bit slow. note: this overrides clogin -t
set timeout 90
# take rcp host from -Ercphost='foo'
if ([info exists Ercphost]) {
#puts "CONFGHOST == $Ercphost"
set confghost [string tolower $Ercphost]
} else {
send_error "ERROR: -Ercphost= was not set on the command-line.\n"
exit
}
#
# logout of the router
#
proc logout { ecode } {
global prompt
send "quit\r"
expect {
"$prompt" { logout $ecode }
timeout { send_error "Error: timeout waiting for EOF after quit\n"}
eof {
send_user "\n"
exit $ecode }
}
}
#
# erase the nvram
#
proc erase { } {
global prompt
send "\r"
expect $prompt {}
send "write erase\r"
expect {
-re " Continue\[^\n\]\*confirm\]" {
send "\r"
exp_continue }
"$prompt" { }
timeout {
send_error "Error: timeout waiting for write erase.\n"
logout 1 }
eof { logout 1 }
}
}
#
# load a config via rcp into nvram
#
proc doload { confghost routername config retry } {
global prompt
# send a return just to be sure we have a prompt.
send "\r"
expect "$prompt"
# start the copy and send the host to load from
# use tftp if retry == 1
if { $retry == 0 } {
send "copy tftp startup-config\r"
} else {
send "copy rcp startup-config\r"
}
expect {
timeout {
send_error "\nError: timeout exceeded waiting for rcp/tftp host prompt\r"
logout 1 }
"mbiguous command" {
if { $retry == 0 } {
send "copy tftp: startup-config\r"
} else {
send "copy rcp: startup-config\r"
}
exp_continue }
-re "Host or network .*\]\?" {
send "host\r"
exp_continue }
"\]\?" {
send "$confghost\r" }
}
#
# fill in the rest of the blanks. username (12.0), filename, dest, etc.
#
expect {
-re "Source username .\*\]\?" {
send "$routername\r";
exp_continue }
-re "Source filename .\*\]\?" {
send "$config\r";
exp_continue }
-re "Name of configur.\*\]\?" {
send "$config\r";
exp_continue }
-re "Destination filename .\*\]\?" {
send "startup-config\r";
exp_continue }
-re "Configure using .\*confirm\]" { send "\r" }
"proceed\? \\\[" { send "yes\r" }
-re "Do you want to over write.\*confirm\]" { send "\r" }
-re "Accessing (rcp|tftp):" { }
timeout {
send_error "\n\tError: timeout exceeded while matching load prompts\n";
send "" }
}
expect {
timeout {
send_error "Error: timeout exceeded while loading config\n"
logout 1 }
-re "\[^\n\]*Connection refused" {
send_error "Error: $expect_out(0,string)\n"
logout 1 }
-re "\[^\n\]*Destination unreachable" {
send_error "Error: $expect_out(0,string)\n"
logout 1 }
-re "\[^\n\]*Permission denied" {
send_error "Error: $expect_out(0,string)\n"
logout 1 }
-re "\[^\n]*No such file or directory" {
send_error "Error: $expect_out(0,string)\n"
logout 1 }
-re "\[^\n]*Error copying\[^\n]*Not enough space on device\[^\n]*\r" {
send_error "Error: $expect_out(0,string)\n"
if { $retry == 2 } {
# erase stomps ssh rsa key
# send_user "erasing nvram\n"
# erase
send_user "retrying load\n"
doload $confghost $routername $config 1
} elseif { $retry == 1 } {
# erase stomps ssh rsa key
# send_user "erasing nvram\n"
# erase
send_user "retrying load with tftp.\n"
doload $confghost $routername $config 0
} else {
send_error "Error: $expect_out(0,string)\n"
logout 1
} }
-re "\[^\n]*.*configuration is too large.*\n" {
send_error "Error: $expect_out(0,string)\n"
expect {
-re "\[^\n]*Truncate config.*:" { send "no\r" }
}
logout 1 }
-re "\[^\n]*Error (opening|copying).*\r" {
send_error "Error: $expect_out(0,string)\n"
logout 1 }
-nocase -re "\[^\n]* error\[^a-z\n]+\[^\n]*" {
send_error "$expect_out(0,string)\n"
logout 1 }
"\n" { exp_continue }
-re "^\[^ ]*\#" {
send_user "load successful.\n"
}
}
return 0;
}
send_user "loading $router config from $confghost\n";
# look for router hostname in prompt (ie: deal with fqdn)
send "\r"
expect {
timeout {
send_error "Error: did not receive prompt\n"
exit }
"\n" { exp_continue }
-re "^(\[^ ]*)\#" {
set routername $expect_out(1,string) }
}
# deal with config subdir? from Econfgpath
if ([info exists confgpath]) {
set config "$confgpath/$routername-confg"
} else {
set config "$routername-confg"
}
# load the config
if { [doload $confghost $routername $config 1] != 0 } {
logout 1
}
logout 0
# these were my original transcripts of performing loads. it is a useful
# example of info you may collect to get an idea of what needs to be handled
# in the expect{}s
#
# pdx-oob#
# pdx-oob#copy rcp start
# Address of remote host [255.255.255.255]? 205.238.52.35
# Name of configuration file [a]? pdx-oob-confg
# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
#
# Connected to 205.238.52.35
# Loading 8131 byte file pdx-oob-confg: !!!! [OK]
# Compressing configuration from 8131 bytes to 3886 bytes
# [OK]
# pdx-oob#
#
# 12.0S-isms
# pao2#cop rcp sta
# Address or name of remote host []? eng0
# Translating "eng0"...domain server (205.238.52.46) [OK]
#
# Source username [pao2]?
# Source filename []? pao2-confg
# Destination filename [startup-config]?
# Warning: Copying this config directly into the nvram from a network server may
# cause damage the the startup config. It is advisable to copy the file
# into the running config first, and then save it using copy run start.
# Do you wish to proceed? [no]: yes
# Accessing rcp://pao2@eng0/pao2-confg...
# Connected to 205.238.52.35
# Loading 30138 byte file pao2-confg: !!!!!! [OK]
#
# 30138 bytes copied in 2.576 secs (15069 bytes/sec)
# pao2#
# OR IS IT
# sea0#cop rcp sta
# Address or name of remote host []? eng0
# Source username [sea0]?
# Source filename []? sea0-confg
# Destination filename [startup-config]?
# Accessing rcp://sea0@eng0/sea0-confg...!!!!!!!!!!!!!!!!!!
# 89794 bytes copied in 0.704 secs
# sea0#q
# Connection closed by foreign host.
# pdx-oob#copy rcp start
# Address of remote host [255.255.255.255]? 205.238.52.35
# Name of configuration file [a]? pdx-oob-confg
# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
#
# Connected to 205.238.52.35
# Loading 8131 byte file pdx-oob-confg: !!!! [OK]
# Compressing configuration from 8131 bytes to 3886 bytes
# [OK]
# pdx-oob#copy rcp start
# Address of remote host [205.238.52.35]? 205.238.52.35
# Name of configuration file [pdx-oob-confg]? pdx-oob-confg
# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
#
# Connected to 205.238.52.35
# %rcp: /tftpboot/pdx-oob-confg: No such file or directory
# pdx-oob#
#
# pdx-oob#copy rcp start
# Address of remote host [205.238.52.35]? 205.238.52.35
# Name of configuration file [pdx-oob-confg]? pdx-oob-confg
# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
#
# Connected to 205.238.52.35
# %rcp: /tftpboot/pdx-oob-confg: Permission denied
# pdx-oob#
#
# *** response from filtered pkt
# pdx-oob#copy rcp sta
# Address of remote host [205.238.52.35]? 205.238.1.94
# Name of configuration file [pdx-oob-confg]?
# Configure using pdx-oob-confg from 205.238.1.94? [confirm]
# % Destination unreachable; gateway or host down
#
# pdx-oob#
#
# *** response from host w/o rcp daemon
# pdx-oob#cop rcp sta
# Address of remote host [205.238.52.35]? 205.238.1.66
# Name of configuration file [pdx-oob-confg]?
# Configure using pdx-oob-confg from 205.238.1.66? [confirm]
# % Connection refused by remote host
#
# pdx-oob#
#
-------------- next part --------------
##
## Copyright (C) 1997-2001 by Henry Kilmer.
## All rights reserved.
##
## This software may be freely copied, modified and redistributed without
## fee for non-commerical purposes provided that this copyright notice is
## preserved intact on all copies and modified copies.
##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
## or its effect upon hardware, computer systems, other software, or
## anything else.
#
# this expect snipit is sourced by clogin (-s option) to issue a reload
# command on a cisco router. it DOES NOT save the config if it has been
# modified. this is an _example_ as it not guaranteed to work for all
# applications. PLEASE test for your environment.
#
# it expects the following variables via the -E option:
# reload_arg ='command argument' such as 'at 05:00' or 'cancel
#
# eg usage:
# % clogin -s cisco-reload.exp -Ereload_arg='at 01:00' router
# router
# Reload scheduled for 01:00:00 UTC Sat Jun 23 2001 (in 7 hours and 16 minutes)
# % clogin -s cisco-reload.exp -Ereload_arg='at cancel' router
# router
# % Ambiguous command: "reload at cancel"
#
# % clogin -s cisco-reload.exp -Ereload_arg='cancel' router
# router
# SHUTDOWN ABORTED
#
#
# keep in mind that it is important to NOT polute the global variable space.
# particularly, do not use variables used within clogin. this may result in
# indeterministic results. an easy way to avoid this is to use a variable
# name prefix (like 'E' or '_').
#
# useful variables from clogin global space:
# router router name as provided on the cmd-line
# prompt cmd-line prompt as determined by clogin
#
# note: the tcl/expect parser is extremely stoopid. comment lines are NOT
# completely ignored!! so, a '{' or '}' in a comment might produce
# unexpected results.
##
# exp_internal 1
# log_user 1
# take reload command from -Ereload_arg='at 05:00'
if ([info exists Ereload_arg]) {
#puts "reload_arg == $Ereload_arg"
set reloadcmd "reload $Ereload_arg"
} else {
send_error "ERROR: -Ereload_arg= was not set on the command-line.\n"
exit
}
#send_user "$router\n"
send "\r"
expect {
timeout { send_error "Error: did not receive prompt\n"
exit }
-re "^.*$prompt" { send "$reloadcmd\r"
expect * {} }
}
# look for response
expect {
-re "configuration has been modified.*no.:" { send "no\r";
exp_continue }
-re "Reload scheduled .*\r" { set sched $expect_out(0,string)
exp_continue }
-re "SHUTDOWN ABORTED" { set sched $expect_out(0,string) }
-re "Proceed with .*confirm\]" { send "\r" }
-re "\n.*No reload " { set sched "no reload scheduled"
send "\r" }
-re "% Ambig\[^\n\r]*" { set sched $expect_out(0,string) }
}
send "\r"
expect "$prompt"
if ([info exists sched]) {
send_user "\t$sched\n"
}
send "quit\r"
expect {
timeout { send_error "Error: timeout waiting for EOF after quit\n"}
eof { exit 0 }
}
## dennis#reload in ?
## Delay before reload (mmm or hhh:mm)
##
## dennis#reload in 100:10
##
## System configuration has been modified. Save? [yes/no]: no
## Reload scheduled in 100 hours and 9 minutes
## Proceed with reload? [confirm]
## dennis#reload ca
## dennis#reload cancel
## dennis#
##
##
## ***
## *** --- SHUTDOWN ABORTED ---
## ***
##
## dennis#wr
## Building configuration...
## [OK]
## dennis#reload in 100:10
## Reload scheduled in 100 hours and 10 minutes
## Proceed with reload? [confirm]
## dennis#rel
## dennis#reload can
## dennis#reload cancel
## dennis#
##
##
## ***
## *** --- SHUTDOWN ABORTED ---
## ***
## System configuration has been modified. Save? [yes/no]: no
## Reload scheduled for 11:51:48 PST Thu Dec 10 1998 (in 299 hours and 59 minutes)
## Proceed with reload? [confirm]
## ultra#reload can
## ultra#
##
##
## ***
## *** --- SHUTDOWN ABORTED ---
## ***
## ultra# reload at 8:10 10 dec
##
## System configuration has been modified. Save? [yes/no]: no
## Reload scheduled for 08:10:00 PST Thu Dec 10 1998 (in 296 hours and 17 minutes)
## Proceed with reload? [confirm]
## ultra#
##
More information about the Rancid-discuss
mailing list