11-23-2013 06:41 AM
What im trying to do:
1. Have the switch do a showtech every 2 hours
2. Send the showtech to flash
3. The first showtech will be techinfo1.txt
4. The second will be techinfo2.txt
5. The next showtech will overwrite techinfo1.txt
6. The next showtech will overwrite techinfo2.txt and so forth.
Is this possible? In the direction of regexpressions possibly?
Write now I have it appending to flash in one file and than once it hits a certain file size, clearing the file and restarting it. I don't like doing it like that.
::cisco::eem::event_register_timer cron name tech1 cron_entry 0 */2 ***
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
array set arr_einfo [event_reqinfo]
set x = file size flash:techinfo.txt
if {$x > 5242880}
file delete flash:techinfo.txt
else{
if [catch {cli_open} result] {
error $result $errorInfo
} else {
array set cli1 $result
}
if [catch {cli_exec $cli1(fd) "enable"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_exec $cli1(fd) "show tech-support | append flash:techinfo.txt"} _cli_result] {
error $_cli_result $errorInfo
}
}
catch {cli_close $cli1(fd) $cli1(tty_id)} result
Credit to Joseph Clark for the applet converter
Solved! Go to Solution.
11-25-2013 06:53 AM
You can use file mtime for this:
set filename "flash:techinfo2.txt"
set now [clock seconds]
if { [file exists $filename] && [expr $now - [file mtime $filename]] < 14400 } {
set filename "flash:techinfo1.txt"
}
# Send your output to $filename
12-09-2013 02:02 PM
Your whole script is in a function that you never call. Just remove the lines:
proc get_tech {} {
And the last '}' in the file.
12-23-2013 12:25 PM
EEM Safe Tcl blocks the mtime command. Try adding this line above the mtime line:
array set stat [file stat $filename]
Then change the mtime check to:
[expr $now - $stat(mtime)] < 14400
12-30-2013 08:31 AM
You still have that array set line in there. Do this. Replace the line starting with "array set" with these lines:
if { [file exists $filename] } {
file stat $filename sarr
if { [expr $now - $sarr(mtime)] < 14400 } {
set filename "newtech.txt"
}
}
12-30-2013 03:50 PM
You first have to make sure you set filename appropriately before you send the output of show tech to it. I'm not sure you're doing that in your current script. Then for rotation, this should work:
set filename "flash:tech1.txt"
set nfilename "flash:text2.txt"
if { [file exists $filename] } {
cli_exec $cli(fd) "copy $filename $nfilename"
}
cli_exec $cli(fd) "show tech | redirect $filename"
If the policy is already running every two hours, flash:tech1.txt will contain the latest stuff, and flash:tech2.txt will contain the previous run.
01-01-2014 09:59 PM
This line:
cli_exec $cli1(fd) "show tech | redirect $filename" _cli_result
Should be:
cli_exec $cli1(fd) "show tech | redirect $filename"
Or:
if { [catch {cli_exec $cli1(fd) "show tech | redirect $filename"} _cli_result] } {
error $_cli_result $errorInfo
}
You'll also need to set file prompt quiet to remove the prompting:
if { [file exists $filename] } {
cli_exec $cli1(fd) "config t"
cli_exec $cli1(fd) "file prompt quiet"
cli_exec $cli1(fd) "do copy $filename $nfilename"
cli_exec $cli1(fd) "no file prompt quiet"
cli_exec $cli1(fd) "end"
}
01-02-2014 11:53 AM
The file prompt quiet suppresses the prompt, and thus the timeout problem should go away (unless, of course, it takes more than 20 seconds to generate the show tech). If you still need more time, you'll need to add a maxrun argument to the end of your event registration line (e.g., maxrun 60).
01-06-2014 12:03 PM
Weird. The "do" copy worked in my test. Okay, change your if block to this:
if { [file exists $filename] } {
cli_exec $cli1(fd) "config t"
cli_exec $cli1(fd) "file prompt quiet"
cli_exec $cli1(fd) "end"
cli_exec $cli1(fd) "copy $filename $nfilename"
cli_exec $cli1(fd) "config t"
cli_exec $cli1(fd) "no file prompt quiet"
cli_exec $cli1(fd) "end"
}
01-13-2014 12:05 PM
The redirect is likely triggering another prompt. After the copy, add:
cli_exec $cli1(fd) "delete /force $filename"
11-25-2013 06:53 AM
You can use file mtime for this:
set filename "flash:techinfo2.txt"
set now [clock seconds]
if { [file exists $filename] && [expr $now - [file mtime $filename]] < 14400 } {
set filename "flash:techinfo1.txt"
}
# Send your output to $filename
12-09-2013 09:48 AM
Thanks for your response Joe.
Right now this is what I have. I will be using an applet countdown to trigger it but for now I am trying to run it manually.
Below is the script. When I run it I am not getting any file created in flash.
::cisco::eem::event_register_none
#Namespace Imports
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
proc get_tech {} {
array set arr_einfo [event_reqinfo]
#Set Variable Filename
set filename "flash:oldtech.txt"
#set timer in seconds allowing it to be used for relative time calculations
set now [clock seconds]
#Send Showtech Output to Flash Filename Variable
if [catch {cli_exec $cli1(fd) "show tech-support | flash:$filename"} _cli_result] {
error $_cli_result $errorInfo
}
if [catch {cli_open} result] {
error $result $errorInfo
} else {
array set cli1 $result
}
#Determine File Name Through Age Comparison
if { [file exists $filename] && [expr $now - [file mtime $filename]] < 14400 } {
set filename "flash:newtech.txt"
}
catch {cli_close $cli1(fd) $cli1(tty_id)} result
}
I turned on logging and this is what I get:
Switch#event manager run showtech.tcl
Switch#
*Dec 9 10:44:36.737: cli_history_entry_add: free_hist_list size=0, hist_list size=7
*Dec 9 10:44:36.737: check_eem_cli_policy_handler: command_string=event manager run showtech.tcl
*Dec 9 10:44:36.737: check_eem_cli_policy_handler: num_matches = 0, response_code = 1
*Dec 9 10:44:36.737: fh_fd_none_event_match: parameters = , sync = 1, get_tty = 1, tty_buf = 0
*Dec 9 10:44:36.737: none_conn_tm_alloc: ptp=0x3A4FF4D4
*Dec 9 10:44:36.737: fh_fd_none_event_match: publish_timer=0x349E7480, ptp=0x3A
Switch#4FF4D4, max_delay=30000
*Dec 9 10:44:36.737: none_conn_tm_add: re=0x3A500854, ptp=0x3A4FF4D4
*Dec 9 10:44:36.737: fh_fd_none_event_match: re = 0x3A500854, num_matches = 1
*Dec 9 10:44:36.737: fh_send_server_sig_hndlr: received a pulse from none on node0/0 with fdid: 11
*Dec 9 10:44:36.737: fh_send_none_fd_msg: msg_type=64
*Dec 9 10:44:36.737: fh_send_none_fd_msg: sval=0
*Dec 9 10:44:36.737: fh_send_server_sig_hndlr: received FH_MSG_EVENT_PUBLISH_SYNC
*Dec 9 10:44:36.737: EEM: server processe
Switch#s multi events: timewin=1, sync_flag=1, ec_index=0, cmp_occ=1
*Dec 9 10:44:36.737: EEM: ctx=5:(5,1,1)
*Dec 9 10:44:36.737: EEM: server processes multi events: corr_res=1, cur_tcnt=1, cmp_tcnt=1
*Dec 9 10:44:36.737: fh_schedule_policy: prev_epc=0x0; epc=0x3A48397C
*Dec 9 10:44:36.737: EEM server schedules scripts
*Dec 9 10:44:36.737: EEM server schedules one event: policy_type=script epc=3A48397C.
*Dec 9 10:44:36.737: EEM: server schedules a policy: policyname=tmpsys:/eem_policy/showtech.tcl
*D
Switch#ec 9 10:44:36.738: spawn script tmpsys:/eem_policy/showtech.tcl
*Dec 9 10:44:36.738: EEM policy tmpsys:/eem_policy/showtech.tcl has been scheduled to run
*Dec 9 10:44:36.738: fh_spawn: -FMRUN -FMSAFE tmpsys:/lib/tcl/base.tcl tmpsys:/eem_policy/showtech.tcl
*Dec 9 10:44:36.738: fh_tcl_spawn: argc=5, argstr=-FMRUN, stdin=0, stdout=0,stderr=0, priority=4, eid=5
*Dec 9 10:44:36.738: pid for spawned process is 224. fdid: 11 sn: 4 jobid: 7
*Dec 9 10:44:36.739: fh_tcl_get_mode: mode = 1, StartupScript
Switch#= tmpsys:/lib/tcl/base.tcl, RealScript = tmpsys:/eem_policy/showtech.tcl
*Dec 9 10:44:36.739: fh_set_tclpath_global: tcl_library is set to tmpsys:/lib/tcl
*Dec 9 10:44:36.739: fh_set_tclpath_global: auto_path is set to tmpsys:/eem_lib_user tmpsys:/eem_lib_system
*Dec 9 10:44:36.747: fh_io_msg: received FH_MSG_API_INIT; jobid=22, processid=224, client=12, job name=EEM TCL Proc
*Dec 9 10:44:36.747: fh_register_evreg_cmds: tctx=35173CE4, dummy=1
*Dec 9 10:44:36.748: fh_tcl_compile_policy: evaluating
Switch# policy: startup_scriptname=tmpsys:/lib/tcl/base.tcl, real_scriptname=tmpsys:/eem_policy/showtech.tcl
*Dec 9 10:44:36.749: fh_tcl_slave_interp_init: interp=3A2FE728, tctx=35173CE4, fh_mode=1, real=tmpsys:/eem_policy/showtech.tcl, curr=showtech.tcl
*Dec 9 10:44:36.754: fh_register_evreg_cmds: tctx=35173CE4, dummy=1
*Dec 9 10:44:36.995: fh_server: fh_io_msg: received msg FH_MSG_API_CLOSE from client 12 pclient 12
*Dec 9 10:44:36.995: fh_io_msg: received FH_MSG_API_CLOSE client=12
*Dec 9 10:44:36.99
Switch#6: fh_tcl_assoc_data_delproc: freeing tctx=0x35173CE4
*Dec 9 10:44:37.010: received SIGCHLD pulse from child death pid=224
*Dec 9 10:44:37.010: received pulse from child death code=1; epc=0x3A48397C
*Dec 9 10:44:37.010: EEM policy showtech.tcl has completed with normal exit status of 0x0 exec_status=2 event_completion=0
*Dec 9 10:44:37.010: fh_send_none_fd_msg: msg_type=18
*Dec 9 10:44:37.010: fh_fd_none_publish_done: rc=0, re=3A500854
*Dec 9 10:44:37.010: fh_fd_none_publish_done: rc=0, publish
Switch#_expired=0
*Dec 9 10:44:37.010: sid=5, ptp=0x3A4FF4D4, connp=0x3A3B34C8
*Dec 9 10:44:37.010: none_conn_tm_remove: re=0x3A500854, ptp=0x3A4FF4D4
*Dec 9 10:44:37.010: fh_fd_none_conn_tm_free: ptp=0x3A4FF4D4
*Dec 9 10:44:37.010: fh_send_none_fd_msg: sval=0
*Dec 9 10:44:37.010: EEM: server decrements in use thread: jobid=7 rule id=1 in use thread=0.
*Dec 9 10:44:37.010: fh_schedule_policy: prev_epc=0x3A48397C; epc=0x0
*Dec 9 10:44:37.010: EEM server schedules scripts
*Dec 9 10:44:37.010: EEM
Switch#server schedules sync same source events:fdid=11; sn=4.
*Dec 9 10:44:37.010: fh_fd_match_event: re=0x3A500854, policyname=showtech.tcl, parameters=, get_tty=1
12-09-2013 02:02 PM
Your whole script is in a function that you never call. Just remove the lines:
proc get_tech {} {
And the last '}' in the file.
05-09-2014 07:08 AM
The script has been working as it should be it fills the bootflash with the deleted files which makes sense.
I modified the CLI section of the script to squeeze the bootflash but now it is not working.
I turned on debugging for all event manager and im not seeing any output at all
This is the CLI portion with changes:
if { [file exists $filename] } {delete
cli_exec $cli1(fd) "config t"
cli_exec $cli1(fd) "file prompt quiet"
cli_exec $cli1(fd) "end"
cli_exec $cli1(fd) "delete /force $nfilename"
cli_exec $cli1(fd) "copy $filename $nfilename"
cli_exec $cli1(fd) "delete /force $filename"
cli_exec $cli1(fd) "squeeze bootflash:"
cli_exec $cli1(fd) "config t"
cli_exec $cli1(fd) "no file prompt quiet"
cli_exec $cli1(fd) "end"
}
Does it look off to anyone?
05-09-2014 07:19 AM
First, run all of these commands manually to see what prompts you may get. If you're getting any prompts, you will need to handle them. Next, squeeze can take a few seconds, so you may need to increase your maxrun time for this policy to something like 45 or 60 seconds.
05-09-2014 07:30 AM
Yes, i did that and noticed that squeeze bootflash prompts twice
All deleted files will be removed. Continue? [confirm]
Squeeze operation may take a while. Continue? [confirm]
That's why I nested it in the CLI commands while the fileprompt quiet was still on. and then shut the file prompt after.
The runtime I had also increased previously.
Thanks for the quick reply
05-09-2014 07:37 AM
So if you run ALL of the commands including file prompt quiet, and the prompting still occurs, then you need to use cli_write to send the squeeze command and cli_read_pattern to wait for the prompt. When you get the prompt, use cli_write again to send the appropriate response. You can use cli_exec again when you are sure the result will be the router prompt.
05-14-2014 09:00 AM
Thanks,
When I manually run the script using cli command "event manager run showtech.tcl" , nothing at all is happening.
I turned on "debug event manager tcl cli" and then ran the script again.. no output in terminal.
I then turned on all event manager debuging and ran the script..still no output.
This is the script:
::cisco::eem::event_register_none maxrun 2200
#Namespace Imports
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
array set arr_einfo [event_reqinfo]
#Pass CLI Commands
if [catch {cli_open} result] {
error $result $errorInfo
} else {
array set cli1 $result
}
if [catch {cli_exec $cli1(fd) "enable"} _cli_result] {
error $_cli_result $errorInfo
}
#Set Variables
set filename "flash:newtech.txt"
set nfilename "flash:oldtech.txt"
#Copy New File to Old at Next Instance
if { [file exists $filename] } {delete
cli_exec $cli1(fd) "config t"
cli_exec $cli1(fd) "file prompt quiet"
cli_exec $cli1(fd) "end"
cli_exec $cli1(fd) "delete /force $nfilename"
cli_exec $cli1(fd) "copy $filename $nfilename"
cli_exec $cli1(fd) "delete /force $filename"
cli_exec $cli1(fd) "config t"
cli_exec $cli1(fd) "no file prompt quiet"
cli_exec $cli1(fd) "end"
cli_write $cli1(fd) "squeeze bootflash:"
cli_read_pattern $cli1(fd) "confirm"
cli_write $cli1(fd) "confirm"
cli_read_pattern $cli1(fd) "confirm"
cli_write $cli1(fd) "confirm"
}
#Pipe Show-Technology to Set Variable
cli_exec $cli1(fd) "show tech | redirect $filename"
catch {cli_close $cli1(fd) $cli1(tty_id)} result
05-25-2014 01:23 PM
Sounds to me like either you didn't enable "term mon" or you are not logging at debug level to the monitor output. Make sure you have the following configured:
logging monitor debug
Then make sure you run "term mon" on your VTY. If you do that, you should see some output from the debugs when you run the policy.
12-23-2013 11:20 AM
Thanks. I've been debugging and testing and am hung up on this:
Switch#event manager run showtech.tcl
not allowed to invoke subcommand mtime of file
while executing
"error $msg"
(procedure "::safe::Subset" line 46)
invoked from within
"file mtime $filename"
invoked from within
"$slave eval $Contents"
(procedure "eval_script" line 7)
invoked from within
"eval_script slave $scriptname"
invoked from within
"if {$security_level == 1} { #untrusted script
interp create -safe slave
interp share {} stdin slave
interp share {} stdout slave
..."
(file "tmpsys:/lib/tcl/base.tcl" line 50)
Tcl policy execute failed: not allowed to invoke subcommand mtime of file
This is how the script currently looks:
::cisco::eem::event_register_none
#Namespace Imports
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
array set arr_einfo [event_reqinfo]
#Pass CLI Commands
if [catch {cli_open} result] {
error $result $errorInfo
} else {
array set cli1 $result
}
if [catch {cli_exec $cli1(fd) "enable"} _cli_result] {
error $_cli_result $errorInfo
}
#set timer in seconds allowing it to be used for relative time calculations
set now [clock seconds]
#Set Variable Filename
set filename "oldtech.txt"
#Determine File Name Through Age Comparison
if { [file exists $filename] && [expr $now - [file mtime $filename]] < 14400 } {
set filename "newtech.txt"
}
#Send Showtech Output to Flash Filename Variable
if [catch {cli_exec $cli1(fd) "show tech-support | redirect flash:$filename"} _cli_result] {
error $_cli_result $errorInfo
}
catch {cli_close $cli1(fd) $cli1(tty_id)} result
12-23-2013 12:25 PM
EEM Safe Tcl blocks the mtime command. Try adding this line above the mtime line:
array set stat [file stat $filename]
Then change the mtime check to:
[expr $now - $stat(mtime)] < 14400
12-26-2013 08:38 AM
That was correct.
Thanks for the help thus far.
The array set stat should be [file state filename VARname]
For the file name I first tried mtime because the script appeared to want it in the arguments.
That was not correct because it wants a directory or file to check which makes sense.
I then tested it with oldtech.txt. This seems to be in the correct direction.
It's complaining about the mtime in the arguments array again.
Any ideas?
Switch#event manager run showtech.tcl
can't read "stat(mtime)": no such element in array
while executing
"expr $now - $stat(mtime)"
invoked from within
"$slave eval $Contents"
(procedure "eval_script" line 7)
invoked from within
"eval_script slave $scriptname"
invoked from within
"if {$security_level == 1} { #untrusted script
interp create -safe slave
interp share {} stdin slave
interp share {} stdout slave
..."
(file "tmpsys:/lib/tcl/base.tcl" line 50)
Tcl policy execute failed: can't read "stat(mtime)": no such element in array
Here's where I am at:
#Determine File Name Through Age Comparison
array set stat [file stat oldtech.txt $filename]
if { [file exists $filename] && [expr $now - $stat(mtime)] < 14400 } {
set filename "newtech.txt"
}
12-28-2013 08:15 AM
I confused Perl and Tcl behavior. Perl returns the array, but Tcl allows you to fetch one stat parameter at a time. So you want:
[expr $now - [file stat $filename mtime]]
12-30-2013 06:19 AM
Thanks Joe.
I am still having the arguments error that I encountered troubleshooting earlier.
Switch#event manager run showtech.tcl
wrong # args: should be "file stat name varName"
while invoking
"file stat oldtech.txt"
invoked from within
"::interp invokehidden slave file stat oldtech.txt"
("eval" body line 1)
invoked from within
"eval ::interp invokehidden $slave $command $subcommand [lrange $args 1 end"
(procedure "::safe::Subset" line 42)
invoked from within
"file stat $filename"
invoked from within
"$slave eval $Contents"
(procedure "eval_script" line 7)
invoked from within
"eval_script slave $scriptname"
invoked from within
"if {$security_level == 1} { #untrusted script
interp create -safe slave
interp share {} stdin slave
interp share {} stdout slave
..."
(file "tmpsys:/lib/tcl/base.tcl" line 50)
Tcl policy execute failed: wrong # args: should be "file stat name varName"
Current script from switch
Switch#show event manager policy registered detailed showtech.tcl
::cisco::eem::event_register_none
#Namespace Imports
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
array set arr_einfo [event_reqinfo]
#Pass CLI Commands
if [catch {cli_open} result] {
error $result $errorInfo
} else {
array set cli1 $result
}
if [catch {cli_exec $cli1(fd) "enable"} _cli_result] {
error $_cli_result $errorInfo
}
#set timer in seconds allowing it to be used for relative time calculations
set now [clock seconds]
#Set Variable Filename
set filename "oldtech.txt"
#Determine File Name Through Age Comparison
array set stat [file stat $filename]
if { [file exists $filename] && [expr $now - [file stat $filename mtime]]
< 14400 } {
set filename "newtech.txt"
}
#Send Showtech Output to Flash Filename Variable
if [catch {cli_exec $cli1(fd) "show tech-support | redirect flash:$filename"} _cli_result] {
error $_cli_result $errorInfo
}
catch {cli_close $cli1(fd) $cli1(tty_id)} result
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide