Πέμπτη 22 Οκτωβρίου 2015

Migrating a linux machine from LVM to normal partitions

Before shutting down your system, copy the output of your current fstab in order to mount your partitions:

# cat /etc/fstab
Boot from a live cd (I used an ubuntu 14.04)
You 've got to mount somewhere the original filesystem in order to copy it, preferably as read-only:
Assuming our old disk is /dev/sda with 3 partitions (all of them LVM):
# mkdir /mnt/olddisk /mnt/olddisk/oldboot /mnt/olddisk/oldroot /mnt/olddisk/oldvar 
# mount -o ro /dev/mapper/vg1-lv_XXX /mnt/olddisk/oldboot
# mount -o ro /dev/mapper/vg1-lv_XXY /mnt/olddisk/oldroot
# mount -o ro /dev/mapper/vg1-lv_XXZ  /mnt/olddisk/oldvar
Your old fstab should look like this
# cat /mnt/olddisk/oldroot/etc/fstab
/dev/mapper/vg1-lv_XXX   /                       ext3    defaults        1 1
/dev/mapper/vg1-lv_XXY  /boot                   ext3    defaults        1 2
/dev/mapper/vg1-lv_XXZ  /var                  ext3    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
/dev/mapper/vg1-lv_swap      swap                    swap    defaults        0 
You should first check the inode size of your old disk because after migrating a disk with inode size 128 to a disk with inode size 256 which is the default now, grub won't install, you will get an error (The file /boot/grub/stage1 not read correctly, Error 2: Bad File or Directory Type)!
# tune2fs -l /dev/sda1 | grep -i 'inode size'
Inode size:           128
Fdisk your new disk (/dev/sdb)
I used 2 partitions, sdb1 for the the whole filesystem and of course a small swap sdb2 partition
# fdisk /dev/sdb
After creating both partitions, give sda1 the bootable flag (a) and change the system id to sdb2 (t, 82).

Format the partitions:
# mkfs.ext3 /dev/sdb1 -I 128
# mkswap /dev/sdb2
Label the partition makes it more convenient for configuring grub and fstab later:
I labeled it "root"
# e2label /dev/sdb1 root
Mount and prepare the filesystem on new disk:
# mkdir /mnt/newdisk
# mount /dev/sdb1 /mnt/newdisk
# cd /mnt/newdisk; mkdir {dev,mnt,boot,opt,usr,var,tmp,home,data}
Create and configure permissions on /proc, /dev and /sys folders:
# mkdir /mnt/newdisk/{proc,dev,sys}
# chmod -w /mnt/newdisk/proc
# chmod go+w /mnt/newdisk/dev
# chmod +t /mnt/newdisk/dev
copy all data from all olddisk mountpoints excluding /dev, /proc and /sys
# rsync -avz /mnt/olddisk/oldboot /mnt/newdisk --exclude dev --exclude proc --exclude selinux --exclude sys
# rsync -avz /mnt/olddisk/oldroot /mnt/newdisk --exclude dev --exclude proc --exclude selinux --exclude sys
....
Adjust some important permissions:
# chmod +t /mnt/newdisk/tmp
# chmod go+rw /mnt/newdisk/tmp
Installing grub on new disk requires chrooting:
# mount -o bind /dev /mnt/newdisk/dev
# chroot /mnt/newdisk
# grub
> root (hd1,0)
> setup (hd1)
> quit
Note that hd1 is /dev/sdb1 in our case

Fix grub:
# nano /boot/grub/grub.conf
change the line containing the image(s):
 /boot/vmlinuz-3.2.0-4-686-pae ro root=/dev/mapper/vg1-lv_XXX
  to
  /boot/vmlinuz-3.2.0-4-686-pae ro root=LABEL=root
or by UUID:
/boot/vmlinuz-3.2.0-4-686-pae ro root=UUID=a53bee3f-3a18-45b3-9b7a-8e8e0f2b3e1b 
you can get your UUID by:
# blkid /dev/sda1
Configure fstab:
# nano /etc/fstab
/dev/sda1    /                       ext3    defaults        1 1
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
/dev/sda2       swap                    swap    defaults        0 0
I removed all LVM mounts, and configured one mount for my root filesystem, and a second one for swap
You could use disk UUID instead of /dev/sdax:
UUID=a53bee3f-3a18-45b3-9b7a-8e8e0f2b3e1b /                       ext3    defaults        1 1
UUID=83a41156-85aa-4c40-a6db-b20d42fcb444       swap                    swap    defaults        0 0
Exit chroot after saving your fstab:
# exit

Δευτέρα 9 Μαρτίου 2015

Getting a SIP call whenever an IFTTT recipe is triggered

In my previous post I explained how to run a custom script triggered by an IFTTT reipe.
In this post I will explain how to get a SIP call when an IFTTT action is triggered.

I assume you have created the recipe, linked Dropbox and configured incrontab as explained here.

Requirements:
-A cli SIP client, pjsua (from the pjsip library) is perfect for this job
-expect package (in order to "talk" to pjsua with spawn)
-festival package (this includes text2wave for text-to-speech)

I didn't find pjsip as a package for Debian, so I had to download it from http://www.pjsip.org and compile it manually, it's straightforward (configure-make dep-make).
pjsua is located inside the /pjsip-apps folder so you may either copy it somewhere convenient or create a soflink in order to run it.

Create your pjsip conf file (this may depend on your SIP provider) and paste:

--null-audio
--registrar sip:your.sip.provider.com
--realm=*
--id sip:sipuser@your.sip.provider.com
--username sipuser
--password yourpass
--auto-play
--max-calls 1

You may at first check that you can make a SIP call:
pjsua sip:1234567890@your.sip.provider.com --config-file /home/bob/pjsip.conf 

Then edit your script.sh file: (I found this script somewhere on the web and did slight modifications to it)

#! /bin/bash

EXPECT=/usr/bin/expect
SOUNDFILE=/tmp/alert.wav
TEXT2WAVE=/usr/bin/text2wave
DURATION=20
MESSAGE="Monitoring Alert"
PJSUACONFIG=/home/bob/pjsip.conf
CALLNUMB=1234567890

locked=false
 while [[ $locked == false ]]; do
     if [[ ! -f /tmp/caller.lock ]]; then
         touch /tmp/caller.lock
         locked=true
     else
         sleep 5
     fi
 done

# Generating the message
$TEXT2WAVE -o $SOUNDFILE -f 8000 << EOF
$MESSAGE
EOF

$EXPECT << EOF
spawn pjsua sip:$CALLNUMB@your.sip.provider.com --config-file $PJSUACONFIG --play-file $SOUNDFILE --duration $DURATION
expect "VAD re-enabled"
sleep 1
send "q\n"
EOF

# Cleaning up
rm $SOUNDFILE

# Removing the lock file and IFTTT file
rm /tmp/caller.lock
rm /home/bob/Dropbox/IFTTT/runme*

That's it!


Using IFTTT recipe to run a shell script

Requirements:

-an IFTTT account
-a Dropbpx account linked to your IFTTT account
-a server running linux (mine runs Debian linux).
- incrontab package, available on most linux distros.

First of all, install Dropbox on your linux box. You may find instructions here:
https://www.dropbox.com/install?os=lnx
Run Dropbox and create a folder named IFTTT on your home Dropbox folder.

mkdir ~/Dropbox/IFTTT

Then, you have to create your IFTTT recipe at ifttt.com. You may use whatever "this" statement you wish. On "that" statement you chose Dropbox, and create a file. Give a name to your file, for my example I use "runme". In the content you may put whatever you want. In Dropbox folder path you use IFTTT.

Create your script file on your home folder named "script.sh" and make it executable: chmod +x script.sh. Make sure your script executes properly:

./script.sh

Add the user that has both rights to run the script and to write into the Dropbox folder in the incrontab allow list:

echo bob >/etc/incron.allow

Then modify your incrontab. This package continuously checks a folder for changes. In my example it will check my IFTTT folder for modifications.

incrontab -e

inside your incrontab file paste:

/home/bob/Dropbox/IFTTT/ IN_MODIFY,IN_CREATE,IN_MOVED_TO /home/bob/script.sh

Checking that incrond is working:

Open a new terminal window and run:
sudo tail -f /var/log/syslog | grep incrond

Then, create a file inside your /home/bob/Dropbox/IFTTT folder:

touch /home/bob/Dropbox/IFTTT/lala

You will instantly see on your logs:

Mar  9 15:50:03 linuxbox2 incrond[361]: (bob) CMD (/home/bob/script.sh)

This means that your script just triggered and will trigger every time your recipe runs!