Search This Blog

Showing posts with label scripting. Show all posts
Showing posts with label scripting. Show all posts

Tuesday, July 16, 2013

Ways to parse tmsh output and automate task on F5

Problem

How to parse the output from tmsh shell.
How to write your own scripts to automate manual or complex actions on the F5 load balancer.

Solution

By default the 'show' action generate human readable output. With the additional option 'field-fmt' you can generate more machine-readable format that is more suitable for parsing.
 
lbal1(Active)(tmos.ltm.virtual)# show vs_1.1.1.1

Ltm::Virtual Server: vs_1.1.1.1
---------------------------------------------------------
Status
  Availability     : available
  State            : enabled
  Reason           : The virtual server is available
  CMP              : enabled
  CMP Mode         : all-cpus


Traffic                    ClientSide  Ephemeral  General
  Bits In                       89.1G          0        -
  Bits Out                       1.1T          0        -
  Packets In                    89.5M          0        -
  Packets Out                  124.7M          0        -
  Current Connections              54          0        -
  Maximum Connections             334          0        -
  Total Connections              2.6M          0        -
  Min Conn Duration/msec            -          -      367
  Max Conn Duration/msec            -          -   186.4M
  Mean Conn Duration/msec           -          -    84.1K
  Total Requests                    -          -     6.0M

 
lbal1(Active)(tmos.ltm.virtual)# show vs_1.1.1.1 field-fmt
ltm virtual vs_1.1.1.1 {
    clientside.bits-in 89.1G
    clientside.bits-out 1.1T
    clientside.cur-conns 67
    clientside.max-conns 334
    clientside.pkts-in 89.5M
    clientside.pkts-out 124.7M
    clientside.tot-conns 2.6M
    cs-max-conn-dur 186.4M
    cs-mean-conn-dur 76.7K
    cs-min-conn-dur 367
    ephemeral.bits-in 0
    ephemeral.bits-out 0
    ephemeral.cur-conns 0
    ephemeral.max-conns 0
    ephemeral.pkts-in 0
    ephemeral.pkts-out 0
    ephemeral.tot-conns 0
    name vs_95.138.158.17
    tot-requests 6.0M
    virtual-server.cmp-enable-mode all-cpus
    virtual-server.cmp-enabled enabled
    virtual-server.status.availability-state available
    virtual-server.status.enabled-state enabled
    virtual-server.status.status-reason The virtual server is available
}

To create your own scripts you can use grep to parse the output above or take it to the next level and write a native script in TCL using the tmsh API.

References
  1. https://devcentral.f5.com/wiki/TMSH.ConfigSearch.ashx
  2. https://devcentral.f5.com/community/group/aft/1180665/asg/53
  3. https://devcentral.f5.com/wiki/TMSH.tmsh__get_config.ashx
  4. https://devcentral.f5.com/wiki/TMSH.tmsh__get_status.ashx

Wednesday, April 3, 2013

Powershell as Bash substitute on Windows

In Linux we have Bash shell that can be used to interact with the system or help to execute routine commands. There are couple of other alternatives in Windows. The cmd.exe is one of the interpreters that comes with every Windows since years.

A new one I'm learning is powershell.exe. The good part about powershell is that it provides many commands like in Linux that have the same name buy maybe a slightly different syntax  For a nice comparison list between the standard bash and powershell commands please take a look at BASH and PowerShell Quick Reference.

Problem

What is the Linux Path variable in powershell.

Solution

The variable is called $env:path.
 
PS C:\Users\radoslaw> echo $env:path
%SystemRoot%\system32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\AMD APP\bi
n\x86_64;C:\Program Files (x86)\AMD APP\bin\x86;C:\Windows\system32;C:\Windows;
C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program
 Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files (x86)\Git\cm
d;c:\Python27;c:\HP\DriveKey;C:\Program Files (x86)\PuTTY;C:\Ruby193\bin

You can modify it when navigating to:
Start - Computer - Properties - Advance system settings - Advanced-Environment Variables -System variables - Path
Problem

How to use 'curl' from powershell.

Solution

You can install cygwin on Windows. Add to the system PATH the cygwin bin directory. Alternatively you can use this command below to download a file.

 
PS C:\Users\radoslaw\tmp> (New-Object System.Net.WebClient).DownloadFile("http://python-distribute.org/distribute_setup.py", "tmp\distribute_setup.py")
PS C:\Users\radoslaw\tmp> ls

    Directory: C:\Users\radoslaw\tmp

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---          4/3/2013   9:12 PM      17319 distribute_setup.py
-a---          4/3/2013   8:20 PM      85929 get-pip.py

References
  1. http://www.cs.wright.edu/~pmateti/Courses/233/Labs/Scripting/bashVsPowerShellTable.html

Tuesday, October 30, 2012

How to install parallel Linux tool on Ubuntu or Debian

Parallel is a quite new tool created under the GNU foundation  As its name says it helps to execute jobs in parallel on one or many computers.

Problem

How to install parallel tool on Ubuntu 12.04 Precise [2]

Solution

As the package hasn't been debianised in Ubuntu yet we have to install it using the old school methods.

Follow link [3] and download the appropriate package. Once downloaded install it using dpkg.

wget http://download.opensuse.org/repositories/home:/tange/xUbuntu_12.04/all/parallel_20110422-1_all.deb
dpkg -i parallel_20110422-1_all.deb
type  -a parallel                                                                       22:51:35
parallel is /usr/bin/parallel

References
  1. http://www.gnu.org/software/parallel/
  2. https://wiki.ubuntu.com/DevelopmentCodeNames
  3. https://build.opensuse.org/package/show?package=parallel&project=home%3Atange

Sunday, August 19, 2012

Problem runing ssh or scp from a python script using the paramiko module

Paramiko project [1] is a native SSH Python library for scritpting. It provides an extensible API that allows you to imitate a SSH session, control it and later as well as execute commands.

I tried to use it to implement one of my Rackconnect scritps:
  • create a cloud server, let's call it a bastion server 
  • connect to bastion server over SSH 
  • execute ssh command from bastion against other cloud server (10.178.7.217/ServiceNet) or
  • execute scp command to copy a file from bastion to a cloud server over local ServiceNet 
I failed with my first attempt to solve this problem. I discovered that the SSH session doesn't have a tty attached to it.

First attempt.
Below is the error message I always got.

$ python -u example_paramiko_notty.py

 test 1
 cmd pwd; ls; date

stdout : /root
stdout : check_rackconnect.sh
stdout : Sun Aug 19 19:04:03 UTC 2012

 test 2
 cmd scp -q  -o NumberOfPasswordPrompts=1 -o StrictHostKeyChecking=no /root/check_rackconnect.sh root@10.178.7.217:~/; echo $? done.

stdout : 1 done.
stderr : lost connection

 test 3
 cmd scp -q -v -o NumberOfPasswordPrompts=1 -o StrictHostKeyChecking=no /root/check_rackconnect.sh root@10.178.7.217:~/; echo $? done.

stdout : 1 done.
stderr : Executing: program /usr/bin/ssh host 10.178.7.217, user root, command scp -v -t ~/
stderr : OpenSSH_5.3p1 Debian-3ubuntu3, OpenSSL 0.9.8k 25 Mar 2009
stderr : debug1: Reading configuration data /etc/ssh/ssh_config
stderr : debug1: Applying options for *
stderr : debug1: Connecting to 10.178.7.217 [10.178.7.217] port 22.
stderr : debug1: Connection established.
stderr : debug1: permanently_set_uid: 0/0
stderr : debug1: identity file /root/.ssh/identity type -1
stderr : debug1: identity file /root/.ssh/id_rsa type -1
stderr : debug1: identity file /root/.ssh/id_dsa type -1
stderr : debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3p1 Debian-3ubuntu3
stderr : debug1: match: OpenSSH_5.3p1 Debian-3ubuntu3 pat OpenSSH*
stderr : debug1: Enabling compatibility mode for protocol 2.0
stderr : debug1: Local version string SSH-2.0-OpenSSH_5.3p1 Debian-3ubuntu3
stderr : debug1: SSH2_MSG_KEXINIT sent
stderr : debug1: SSH2_MSG_KEXINIT received
stderr : debug1: kex: server-client aes128-ctr hmac-md5 none
stderr : debug1: kex: client-server aes128-ctr hmac-md5 none
stderr : debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024 1024 8192) sent
stderr : debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
stderr : debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
stderr : debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
stderr : debug1: Host '10.178.7.217' is known and matches the RSA host key.
stderr : debug1: Found key in /root/.ssh/known_hosts:5
stderr : debug1: ssh_rsa_verify: signature correct
stderr : debug1: SSH2_MSG_NEWKEYS sent
stderr : debug1: expecting SSH2_MSG_NEWKEYS
stderr : debug1: SSH2_MSG_NEWKEYS received
stderr : debug1: SSH2_MSG_SERVICE_REQUEST sent
stderr : debug1: SSH2_MSG_SERVICE_ACCEPT received
stderr : debug1: Authentications that can continue: publickey,password
stderr : debug1: Next authentication method: publickey
stderr : debug1: Trying private key: /root/.ssh/identity
stderr : debug1: Trying private key: /root/.ssh/id_rsa
stderr : debug1: Trying private key: /root/.ssh/id_dsa
stderr : debug1: Next authentication method: password
stderr : debug1: read_passphrase: can't open /dev/tty: No such device or address
stderr : debug1: Authentications that can continue: publickey,password
stderr : debug1: No more authentication methods to try.
stderr : Permission denied (publickey,password).
stderr : lost connection

The problems is that the exec_command() function [2] doens't open a SSH session that has a terminal attached. I couldn't find a working solution using it so I have written and to use invoke_shell() function [3] instead. Most of the code was inspired and copied from an example found here [4].Below is my working script.

Second attempt This is the output when we run it this time.

$ python -u example_paramiko_with_tty.py 

 test 2
 cmd scp -q  -o NumberOfPasswordPrompts=1 -o StrictHostKeyChecking=no /root/check_rackconnect.sh root@10.178.7.217:~/; echo $? done.

Linux rctest 2.6.32-31-server #61-Ubuntu SMP Fri Apr 8 19:44:42 UTC 2011 x86_64 GNU/Linux
Ubuntu 10.04 LTS

Welcome to the Ubuntu Server!
 * Documentation:  http://www.ubuntu.com/server/doc
Last login: Sun Aug 19 19:47:09 2012 from bbb.rrr.com

root@rctest:~# 
/root/check_rackconnect.sh root@10.178.7.217:~/; echo $? done.no  

root@10.178.7.217's password: 

0 done.
root@rctest:~# 
command was successful:True

As we can see the invoke_shell() function is very different from the exec_command() one. To make it work we have to deal with all the terminal outputs and make sure we sent the command string at a right time. We can see as well as that with default terminal settings the output is not showing all text. We can see only part of the overlapped command string we sent in line #11

References
  1. http://www.lag.net/paramiko/
  2. http://www.lag.net/paramiko/docs/paramiko.SSHClient-class.html#exec_command
  3. http://www.lag.net/paramiko/docs/paramiko.SSHClient-class.html#invoke_shell
  4. http://stackoverflow.com/questions/1911690/nested-ssh-session-with-paramiko

  5. Others interesting links
  6. http://www.minvolai.com/blog/2009/09/how-to-ssh-in-python-using-paramiko/
  7. http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

Sunday, July 29, 2012

How to clean and delete multiple cloud servers after a failed test

The best think about open cloud API is that it is easy accessible and can be easily scripted around. For exmaple during one of my tests I created multiple cloud servers but my job failed and didn't delete them before the exception was thrownd.

Problem

How to extract cloud server names from the log file and how to delted all of them from the accout.

$ python performance-single-cs.py-t 1 -s 25 -u user -k key  run | tee log.$(date +%s).txt
$ cat log*.txt
[ 1][  ] starting test nr 1, creating 25 cloud server, please wait ...
[ 1][ 1] created image: {'flavor': 1, 'image': 112, 'name': 'test7945'}
[ 1][ 2] created image: {'flavor': 1, 'image': 112, 'name': 'test7948'}
[ 1][ 3] created image: {'flavor': 1, 'image': 112, 'name': 'test7951'}
[ 1][ 4] created image: {'flavor': 1, 'image': 112, 'name': 'test7954'}
[ 1][ 5] created image: {'flavor': 1, 'image': 112, 'name': 'test7958'}
[ 1][ 6] created image: {'flavor': 1, 'image': 112, 'name': 'test7961'}
[ 1][ 7] created image: {'flavor': 1, 'image': 112, 'name': 'test7965'}
[ 1][ 8] created image: {'flavor': 1, 'image': 112, 'name': 'test7969'}
[ 1][ 9] created image: {'flavor': 1, 'image': 112, 'name': 'test7972'}
[ 1][10] created image: {'flavor': 1, 'image': 112, 'name': 'test7976'}
[ 1][11] created image: {'flavor': 1, 'image': 112, 'name': 'test8050'}
[ 1][12] created image: {'flavor': 1, 'image': 112, 'name': 'test8054'}
[ 1][13] created image: {'flavor': 1, 'image': 112, 'name': 'test8059'}
[ 1][14] created image: {'flavor': 1, 'image': 112, 'name': 'test8063'}
[ 1][15] created image: {'flavor': 1, 'image': 112, 'name': 'test8068'}
[ 1][16] created image: {'flavor': 1, 'image': 112, 'name': 'test8072'}
[ 1][17] created image: {'flavor': 1, 'image': 112, 'name': 'test8077'}
[ 1][18] created image: {'flavor': 1, 'image': 112, 'name': 'test8082'}
[ 1][19] created image: {'flavor': 1, 'image': 112, 'name': 'test8086'}
[ 1][20] created image: {'flavor': 1, 'image': 112, 'name': 'test8091'}
[ 1][21] created image: {'flavor': 1, 'image': 112, 'name': 'test8117'}
[ 1][22] created image: {'flavor': 1, 'image': 112, 'name': 'test8192'}
[ 1][23] created image: {'flavor': 1, 'image': 112, 'name': 'test8197'}
[ 1][24] created image: {'flavor': 1, 'image': 112, 'name': 'test8202'}
[ 1][25] created image: {'flavor': 1, 'image': 112, 'name': 'test8208'}
[ 1][ 1] cloud server build [test7945] created in 298.427304 seconds / 4.9737884 minutes
[ 1][ 2] cloud server build [test7948] created in 298.331735 seconds / 4.97219558333 minutes
[ 1][ 3] cloud server build [test7951] created in 298.268271 seconds / 4.97113785 minutes
[ 1][ 4] cloud server build [test7954] created in 298.469954 seconds / 4.97449923333 minutes
[ 1][ 5] cloud server build [test7958] created in 298.202301 seconds / 4.97003835 minutes
[ 1][ 6] cloud server build [test7961] created in 297.702382 seconds / 4.96170636667 minutes
[ 1][ 7] cloud server build [test7965] created in 298.051012 seconds / 4.96751686667 minutes
[ 1][ 8] cloud server build [test7969] created in 297.3658 seconds / 4.95609666667 minutes
[ 1][ 9] cloud server build [test7972] created in 296.993362 seconds / 4.94988936667 minutes
[ 1][10] cloud server build [test7976] created in 296.810522 seconds / 4.94684203333 minutes
[ 1][11] cloud server build [test8050] created in 226.269396 seconds / 3.7711566 minutes
[ 1][12] cloud server build [test8054] created in 226.051247 seconds / 3.76752078333 minutes
[ 1][14] cloud server build [test8063] created in 225.04139 seconds / 3.75068983333 minutes
[ 1][15] cloud server build [test8068] created in 224.326799 seconds / 3.73877998333 minutes
[ 1][16] cloud server build [test8072] created in 223.051956 seconds / 3.7175326 minutes
[ 1][17] cloud server build [test8077] created in 221.830032 seconds / 3.6971672 minutes
[ 1][18] cloud server build [test8082] created in 219.514883 seconds / 3.65858138333 minutes
[ 1][19] cloud server build [test8086] created in 218.35139 seconds / 3.63918983333 minutes
[ 1][20] cloud server build [test8091] created in 216.172884 seconds / 3.6028814 minutes
[ 1][21] cloud server build [test8117] created in 193.915105 seconds / 3.23191841667 minutes
[ 1][13] cloud server build [test8059] created in 328.421036 seconds / 5.47368393333 minutes
[ 1][22] cloud server build [test8192] created in 197.893329 seconds / 3.29822215 minutes
[ 1][23] cloud server build [test8197] created in 196.71745 seconds / 3.27862416667 minutes
[ 1][24] cloud server build [test8202] created in 263.305984 seconds / 4.38843306667 minutes
[ 1][25] cloud server build [test8208] created in 260.425359 seconds / 4.34042265 minutes

Solution

For a single log file

$ cat log.*.txt | grep "image':" | cut -d':' -f5 | tr '}' ' ' | grep -v created > tmp
echo > 'set -x' >  delete-all-cs.sh
cat tmp | xargs -I cs_name echo 'cloudservers --username user --apikey key delete cs_name' >> delete-all-cs.sh
bash delete-all-cs.sh

When we have multiple log files

$ cat << END > aux_script.sh
cat $1 | grep "image':" | cut -d':' -f5 | tr '}' ' ' | grep -v created > tmp
cat tmp | xargs -I cs_name echo 'cloudservers --username user --apikey key delete cs_name' >> delete-all-cs.sh
END

$ for i in log.*.txt ; do echo $i; ./aux_script.sh $i;  done
$ bash -x delete-all-cs.sh

Summary and results discussion

The solution with 'xargs' works pretty well for relatively small number of servers to delete. As each cloud server is deleted in a single cloudserver run there is no parallelism involved.

An interesting solution could be built with a help of a parallel tool [3]. It could allow us to execute multiple commands in parallel and achieve a much better timing results. Of course to make it work we would have to take into consideration the API limitations and design some workarounds it.

References
  1. https://github.com/rtomaszewski/cloud-performance
  2. http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct- argument-lists-utility/
  3. https://savannah.gnu.org/projects/parallel/

Friday, December 30, 2011

How effectively use Linux system tools to find out the default Linux kernel I/O scheduler

In many troubleshooting situation we overview and check large numbers of logs generated by one or another application. Kernel is nothing special here. The kernel log files can  usually be found under /var/log/kern.log.

Problem
How to find out and confirm all names of the used io kernel scheduler in the last several reboots.

Solution
$ zcat kern.log.3.gz  | egrep 'io scheduler.*\(default\)' 
Oct  8 22:20:16 udesktop kernel: [    0.888090] io scheduler cfq registered (default)
Oct 10 20:30:33 udesktop kernel: [    0.688367] io scheduler cfq registered (default)
Nov  3 23:31:05 udesktop kernel: [    0.872053] io scheduler cfq registered (default)

$ zcat kern.log.1.gz  | egrep 'io scheduler.*\(default\)' | sed -r 's/ +/ /g' | cut -d' ' -f10 | sort | uniq
cfg

Explanation
We first grep for the names of the configured io scheduler. Next we pars it trought sed to repalce all multi space string with a single space and at the end we cut of the scheduler name.

References
Choosing an I/O Scheduler for Red Hat® Enterprise Linux® 4 and the 2.6 Kernel
http://www.redhat.com/magazine/008jun05/features/schedulers/

Sunday, April 24, 2011

Less tricks in linux on the bash command line

Some tricks that is worth to know when working on the linux bash cli that can save you a lot of time.

1. To tell less to normal print the raw control character of your stream you can use the '-r' or '-R' options.

$ ls -la --color | less -X 
total 3284
drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 ESC[0mESC[01;34m.ESC[0m
drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ESC[01;34m..ESC[0m
drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 ESC[01;34m.adobeESC[0m
drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 ESC[01;34m.ankiESC[0m

$ ls -la --color | less -X -r
total 3284
drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 .
drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ..
drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 .adobe
drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 .anki

2. To list only #n lines from the input with or without the raw characters being interpreted.

$ ls -la --color | cat -t | head -10
total 3284
drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 ^[[0m^[[01;34m.^[[0m
drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ^[[01;34m..^[[0m
drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 ^[[01;34m.adobe^[[0m
drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 ^[[01;34m.anki^[[0m

$ ls -la --color | head -10
total 3284
drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 .
drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ..
drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 .adobe
drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 .anki

3. To list files with line numbers.

$ less -N -X /etc/init.d/networking 
      1 #!/bin/sh -e
      2 ### BEGIN INIT INFO
      3 # Provides:          networking
      4 # Required-Start:    

$ ls -la --color | cat -n -t | head -5
     1 total 3284
     2 drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 ^[[0m^[[01;34m.^[[0m
     3 drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ^[[01;34m..^[[0m
     4 drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 ^[[01;34m.adobe^[[0m
     5 drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 ^[[01;34m.anki^[[0m

$ ls -la --color | cat -n | head -5
     1 total 3284
     2 drwxr-xr-x 90 radoslaw radoslaw   4096 2011-04-24 10:22 .
     3 drwxr-xr-x  4 root     root       4096 2010-08-02 20:37 ..
     4 drwx------  5 radoslaw radoslaw   4096 2011-01-31 12:18 .adobe
     5 drwxr-xr-x  4 radoslaw radoslaw   4096 2009-11-07 20:53 .anki

Reference:

Saturday, November 7, 2009

Linux trick with grep tool

Command line tools are like grep are very useful when working a lot with text files.

One unknown feature is the --color options which shows you in different colour the matching string grep found.

user@host:~$ egrep '(vmx|svm)' --color=always /proc/cpuinfo
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts pni dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm lahf_lm ida tpr_shadow vnmi flexpriority

Wednesday, November 4, 2009

Bash commands statistics

Looking for some MySQL & performance stuff is found on the page from Alexey N. Kovyrin something interested :).

To see, what are you doing on our Linux box, type the following code on bash console:

$ history 1000 | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head

150 ls
30 for
26 du
20 tar
19 java
19 strace
...