How to setup Python fabric on CentOS

Python Fabric is a very good automation tool specially when you have access to a Linux machine via SSH.

This example was tested on CentOS 6.6 docker image:
(Note: You will need epel repository configured on your machine, if its a centos box you can install it by typing: yum install epel-release
So lets start configuring Fabric:

[[email protected] /]# yum search fabric
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirror.synergyworks.co.uk
* epel: mirror.bytemark.co.uk
* extras: repo.bigstepcloud.com
* updates: centos.hyve.com
fabric.noarch : A simple Pythonic remote deployment tool
[[email protected] /]# yum install fabric

This should install fabric for you.

Now if you haven’t setup SSH key pair on your remote machine that you would like to control via Fabric, you can run the following on your current machine to create key pair, once done copy the public part of the key to authorized_keys file on the remote server:


[[email protected] /]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.

Now for this example I have created another docker instance that is running openssh-server and is configured to accept keys. I have already copied the public key to the other docker instance, so I can log into the second docker instance without providing the password. So lets write the fabfile and run remote commands using Fabric:

[[email protected] ~]# cat fabfile.py
from fabric.api import *

def hostname():
run("hostname")
[[email protected] ~]# fab -H 172.17.0.3 hostname
[172.17.0.3] Executing task 'hostname'
[172.17.0.3] run: hostname
[172.17.0.3] out: edf6ac0f4d24
[172.17.0.3] out:
Done.
Disconnecting from 172.17.0.3... done.

In the above case 172.17.0.3 is my second docker instance. Lets try to run another command remotely … how about getting the contents of hosts file. So all we need to do is to add another function in the fab file and call the function for the desired host:

[[email protected] ~]# cat fabfile.py
from fabric.api import *

def hostname():
run("hostname")

def hostsfile():
run("cat /etc/hosts")
[[email protected] ~]# fab -H 172.17.0.3 hostsfile
[172.17.0.3] Executing task 'hostsfile'
[172.17.0.3] run: cat /etc/hosts
[172.17.0.3] out: 172.17.0.3 edf6ac0f4d24
[172.17.0.3] out: 127.0.0.1 localhost
[172.17.0.3] out: ::1 localhost ip6-localhost ip6-loopback
[172.17.0.3] out: fe00::0 ip6-localnet
[172.17.0.3] out: ff00::0 ip6-mcastprefix
[172.17.0.3] out: ff02::1 ip6-allnodes
[172.17.0.3] out: ff02::2 ip6-allrouters
[172.17.0.3] out:
Done.
Disconnecting from 172.17.0.3... done.

So fabric is lovely little tool to run remote commands on the server. Ofcourse you can use SSH to do all these tasks, but fabric provides you a way of managing scripts (for remote servers) in an efficient and reliable manner.

How to create partition and logical volume on the partition in Linux

Find the disk you are trying to create partition on by typing:

[email protected]: fdisk -l
Disk /dev/sda: 53.7 GB, 53687091200 bytes
255 heads, 63 sectors/track, 6527 cylinders, total 104857600 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00056a89

Device Boot Start End Blocks Id System
/dev/sda1 * 2048 58720255 29359104 83 Linux
/dev/sda2 58722302 62912511 2095105 5 Extended
/dev/sda3 62912512 104857599 20972544 83 Linux
/dev/sda5 58722304 62912511 2095104 82 Linux swap / Solaris

Disk /dev/sdb: 53.7 GB, 53687091200 bytes
255 heads, 63 sectors/track, 6527 cylinders, total 104857600 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0007dccf

Device Boot Start End Blocks Id System
/dev/sdb1 2048 52430847 26214400 83 Linux
/dev/sdb2 52430848 104857599 26213376 83 Linux

Disk /dev/sdc: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/sdc doesn't contain a valid partition table

You will your disk listed and may have a warning besides it that this disk doesn’t contain parition.

You can quickly create partition on the desired disk by typing:

[email protected]:~# fdisk /dev/sdc
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x0f878caa.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): m
Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the DOS compatibility flag
d delete a partition
l list known partition types
m print this menu
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)

Command (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-41943039, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039):
Using default value 41943039

Command (m for help): w

The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Once the partition is created if you would like you can create file system on it or maybe create a logical volume group:

[email protected]:~# vgcreate vm /dev/sdc1
No physical volume label read from /dev/sdc1
Physical volume "/dev/sdc1" successfully created
Volume group "vm" successfully created
[email protected]:~# lvcreate -L 5G -n Vol1 vm
Logical volume "Vol1" created
[email protected]:~# lvs
LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert
Vol1 vm -wi-a---- 5.00g

There you can see we have new logical volume that we just created.

How to check if a TCP port is open or closed

You can easily test if the port is open or closed on a remote server in Windows or Linux via telnet client:

(This command is same for Linux and Windows machine, as long as you have the telnet client installed in your machine)

[[email protected] /]# telnet simplenotes.io 80
Trying simplenotes.io
Connected to simplenotes.io.
Escape character is '^]'.

In Linux you may also use netcat command or known as “nc”, you can simply install this by typing the following in CentOS terminal:

yum install nc

To test the port you can type:

[[email protected] /]# nc -v -z simplenotes.io 80
Connection to simplenotes.io 80 port [tcp/http] succeeded!
[[email protected] /]# nc -v -z simplenotes.io 81
nc: connect to simplenotes.io port 81 (tcp) failed: No route to host

How to pass arguments to a bash script

You can simply pass arguments to a bash script by typing the name of the script followed by arguments separated by space.
Script:

#!/bin/bash
# $1 for first argument
# $2 for second argument and so on
# For arg number greater than 9 wrap it around with curly brackets e.g. ${10}

#This will print first two arguments.
echo $1 $2

Output:

[[email protected] ~]# ./sample 1 2
1 2

If you need pass string (containing spaces) as an argument, wrap it around in quotes e.g.
./sample "My First Argument" "SecondArg"