8.12.2015

A Simple Ruby DSL

It's very easy to create a new language with ruby, here's a simple DSL
class SleepActivity

  def initialize(name)
    @name = name
  end

  def start(&block)
    sleep 1
    puts "#{@name} goes to bed"
    instance_eval &block if block_given?
  end

  def slumber(&block)
    sleep 1
    puts "#{@name} is starting to sleep"
    instance_eval &block if block_given?
  end

  def cycle(period, &block)
    sleep 1
    period.times do |time|
      puts "Sleep cycle #{time + 1}:"
      instance_eval &block if block_given?
    end
  end

  def awake(duration)
    sleep 1
    puts "Still awake for #{duration} minutes"
  end

  def light_sleep(duration)
    sleep 1
    puts "Sleeping lightly for #{duration} minutes"
  end

  def deep_sleep(duration)
    sleep 1
    puts "Sleeping deeply for #{duration} minutes"
  end

  def rem(duration)
    sleep 1
    puts "REM for #{duration} minutes"
  end

end

if $PROGRAM_NAME == __FILE__
  sleep_activity = SleepActivity.new("Sam")
  sleep_activity.start do
    awake 5
    slumber do
      cycle 5 do
        light_sleep 20
        deep_sleep 60
        rem 10
      end
    end
  end
end
Here's the output
samdc@mango:~/dev/ruby/projects/dsl$ ruby dsl_interpreter.rb 
Sam goes to bed
Still awake for 5 minutes
Sam is starting to sleep
Sleep cycle 1:
Sleeping lightly for 20 minutes
Sleeping deeply for 60 minutes
REM for 10 minutes
Sleep cycle 2:
Sleeping lightly for 20 minutes
Sleeping deeply for 60 minutes
REM for 10 minutes
Sleep cycle 3:
Sleeping lightly for 20 minutes
Sleeping deeply for 60 minutes
REM for 10 minutes
Sleep cycle 4:
Sleeping lightly for 20 minutes
Sleeping deeply for 60 minutes
REM for 10 minutes
Sleep cycle 5:
Sleeping lightly for 20 minutes
Sleeping deeply for 60 minutes
REM for 10 minutes

7.21.2015

Bash Cheat Sheet

1. Run a script with no output and in the background
$ ./my_script.sh > /dev/null 2>&1 &

2.  Run a script with no output and in the background and see the pid
$ ./my_script.sh > /dev/null 2>&1 & echo $!

3. Template script that loops thru and writes to a file
#!/bin/bash

# $1 - number of minutes
# $2 - task id
COUNTER=$(($1*60/5))
TOTAL=$COUNTER
echo Perfload will run for $1 minutes
echo "Perfload will run for $1 minutes" > /tmp/$2.log
until [  $COUNTER -eq 0 ]; do
    echo The counter is $COUNTER
    PROGRESS=$(echo "scale=2;($TOTAL - $COUNTER)*100/$TOTAL" | bc -l)
    echo "Perfload RUNNING $PROGRESS %" >> /tmp/$2.log
    let COUNTER-=1
    sleep 5
done
echo "Perfload SUCCESS" >> /tmp/$2.log


7.14.2015

Cisco Switch Cheat Sheet


sho lldp neighbors
sho cdp ne

switch-name# show mac address-table | i 0060.165c.f83e
* 2016     0060.165c.f83e    dynamic     ~~~      F    F  Eth1/22

switch-name# sho int description | grep 'yogi34 eth4b'
Eth8/19       eth    10G     yogi34 eth4b 90E2BA068BB1

switch-name# show interface ethernet 2/27 description
-------------------------------------------------------------------------------
Port          Type   Speed   Description
-------------------------------------------------------------------------------
Eth2/27       eth    10G     artemis59-eth3b 0060.1645.505a

switch-name(config)# config
switch-name(config)# int e8/19
switch-name(config-if)# inherit port-profile Apposite
switch-name(config-if)# exit
switch-name(config)# exit
switch-name# copy run startup-config

switch-name# show interface ethernet 1/28 switchport

# If missing VLANs, can set using...
switch-name(config-if)# switchport trunk allow vlan 2016,2030-2049

5.15.2015

Configure VLAN tagging via CLI

1. Create VLAN interface
# ip link add link eth4 name eth4.2030 type vlan id 2030

2. Assign IP
# ifconfig eth4.2030 11.0.20.1 netmask 255.255.240.0

3. Make sure new interface is enabled
# ifconfig eth4.2030 up

4. Check 
# ifconfig eth4.2030
eth4.2030 Link encap:Ethernet  HWaddr 90:E2:BA:6D:B5:95
          inet addr:11.0.20.1  Bcast:11.0.31.255  Mask:255.255.240.0
          inet6 addr: fe80::92e2:baff:fe6d:b595/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1046 (1.0 KiB)  TX bytes:468 (468.0 b)

5. Remove VLAN
# ip link delete eth4.2030

4.29.2015

Sync Clock Automatically on CentOS

Got it from here.
1. Install
# yum install ntp ntpdate ntp-doc

2. Turn on service
# chkconfig ntpd on

3. Sync one time
# ntpdate pool.ntp.org

4. Configure ntpd
# vi /etc/ntp.conf
Add public servers
server 0.rhel.pool.ntp.org
server 1.rhel.pool.ntp.org
server 2.rhel.pool.ntp.org

5. Start the NTP server. The following will continuously adjusts system time from upstream NTP server. No need to run ntpdate:
# /etc/init.d/ntpd start

3.12.2015

Ansible for Configuration Management and IT automation

Wow, Ansible is a great tool for configuration management and IT automation. I got this reference from here and here.
1. Install ansible on your workstation (machine which will be the controller)
$ sudo yum install ansible
$ ansible --version

2. Create env variable
$ export ANSIBLE_HOSTS=~/ansible/ansible_hosts

3. Create hosts file
$ echo -e "perf-c690\nperf-c691" > ~/ansible/ansible_hosts

4. Do a quick ping
$ ansible all -m ping --ask-pass

5. Now, let's create ssh keys
(Should typically run using your own user account, have used root here for convenience) 
# ssh-keygen -t rsa

6. Copy public key to the remote machines
$ ansible all -m copy -a "src=/root/.ssh/id_rsa.pub dest=/tmp/id_rsa.pub" --ask-pass -c paramiko

Warning: error message: "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"
Which means we need to install libselinux-python on the remote machine prior to copying the files there. We can use ansible to do that for us.

Install libselinux-python on remote machines
$ ansible all -m yum -a "name=libselinux-python state=latest" -u root --ask-pass -c paramiko

Now we can go back to copying the public key

7. Let's add the public key to the remote machines
$ ansible all -m shell -a "cat /tmp/id_rsa.pub >> /root/.ssh/authorized_keys" --ask-pass -c paramiko

8. Test if we actually don't need any password
$ ansible all -m shell -a "hostname"

9. Now we can do or install whatever on the remote machines, let's try installing expect
$ ansible all -m yum -a "name=expect state=latest" -u root

10. We can remotely reboot all machines at once
$ ansible all -a "/sbin/reboot" -u root

3.10.2015

Install Ruby via RVM on CentOS 6.5

Got install from here.
RVM best practices here.
How to use RVM gemsets here.
How to use Bundler here.
1. Install pre-requisites
# yum groupinstall -y development

2. Install RVM
# curl -L get.rvm.io | bash -s stable

3. Create system environment for RVM
# source /etc/profile.d/rvm.sh

4. Install Ruby
# rvm reload
# rvm install 2.2.1

5. Check version of ruby installed
# ruby --version

6. To see all rubies installed
# rvm list rubies
rvm rubies
=* ruby-2.2.1 [ x86_64 ]
# => - current
# =* - current && default
#  * - default

7. To set a Ruby version as the default
# rvm use 2.2.1 --default
Using /usr/local/rvm/gems/ruby-2.2.1

8. Shortcut - create a new gemset along with a fresh .rvmrc in our project directory
# cd projects/dev/phoenix
# rvm --rvmrc --create use 2.2.1@phoenix
ruby-2.2.1 - #gemset created /usr/local/rvm/gems/ruby-2.2.1@phoenix
ruby-2.2.1 - #generating phoenix wrappers..........
Using /usr/local/rvm/gems/ruby-2.2.1 with gemset phoenix

9. To ignore rmvrc warnings ...
# rvm rvmrc warning ignore all.rvmrcs

10. Now when we cd to our project directory we get a confirmation which ruby-version and gemset we are using...
dev]# cd phoenix/
Using: /usr/local/rvm/gems/ruby-2.2.1@phoenix

11. Let's make use of bundler to make it easy to track and install the exact gems and versions for our project
# gem install bundler

12. Create a Gemfile
# bundle init
Writing new Gemfile to /root/projects/dev/phoenix/Gemfile

13. Add gems to Gemfile
# vi Gemfile
source "https://rubygems.org"
# 1. de facto XML/HTML parsing library
gem 'nokogiri'

14. Now, let's install all gems we listed in the Gemfile
# bundle install

To create and use gemsets the longer way:
a. Create gemset
# rvm gemset create my_proj

b. Use the gemset
# rvm gemset use my_proj

c. Install a gem
# gem install package_name

d. Wipe all gems installed
# rvm gemset empty my_proj

e. Delete the gemset
# rvm gemset delete my_proj

f. Check your current gemset
# rvm gemset name