Sunday, December 14, 2014

Share internet with Virtual RaspberryPI using QEMU

In this article I'm going to show you, how to share host OS internet with emulated raspberry Pi.

Note: I'm on Ubuntu 12.04

Pre-requisites:
 Follow this article and brought your virtual RaspberryPI,  it will have IP but you can't access Internet from RaspberryPI. Ok no worry, that's what this article about. Now shutdown the RaspberryPI, and  do the following in your host OS:

Install brctl, tunctl & libvirt
    brctl — ethernet bridge administration
      sudo apt-get install bridge-utils

    tunctl — create and manage persistent TUN/TAP interfaces
      sudo apt-get install uml-utilities
   

    libvirt — visualization management system. This will automatically setup a DHCP server and a bridge(virbr0).
      sudo apt-get install qemu-kvm libvirt-bin

make sure, dns server & bridge automattically configured:

root@unknown:~# ps -ef | grep dns
121       1377     1  0 Dec13 ?        00:00:00 /usr/sbin/dnsmasq -u libvirt-dnsmasq --strict-order --bind-interfaces --pid-file=/var/run/libvirt/network/default.pid --conf-file= --except-interface lo --listen-address 192.168.122.1 --dhcp-range 192.168.122.2,192.168.122.254 --dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases --dhcp-lease-max=253 --dhcp-no-override

root@unknown:~# ifconfig virbr0
virbr0    Link encap:Ethernet  HWaddr 62:80:41:0f:0b:56  
          inet addr:192.168.122.1  Bcast:192.168.122.255  Mask:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:619 errors:0 dropped:0 overruns:0 frame:0
          TX packets:685 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:44276 (44.2 KB)  TX bytes:51576 (51.5 KB)  

root@unknown:~# brctl show
bridge name bridge id  STP enabled interfaces 
virbr0  8000.000000000000 yes  

How to:  
  1. Bind eth0 to virbr0
  2. create a tap interface and make it up
  3. Bind tap0 to virbr0
  4. make sure it binded succesfully
  5. Brought up the Raspberry Pi with tap0
root@unknown:~# brctl addif virbr0 eth0
root@unknown:~# tunctl -t tap0 && ifconfig tap0 up
Set 'tap0' persistent and owned by uid 0
root@unknown:~# brctl addif virbr0 tap0
root@unknown:~# ifconfig
eth0      Link encap:Ethernet  HWaddr 48:84:3c:c6:33:34  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:20070 errors:0 dropped:0 overruns:0 frame:0
          TX packets:20070 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1697375 (1.6 MB)  TX bytes:1697375 (1.6 MB)

tap0      Link encap:Ethernet  HWaddr 1a:98:19:c5:4b:a8  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

virbr0    Link encap:Ethernet  HWaddr 78:84:3c:e6:38:98  
          inet addr:192.168.122.1  Bcast:192.168.122.255  Mask:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:619 errors:0 dropped:0 overruns:0 frame:0
          TX packets:685 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:44276 (44.2 KB)  TX bytes:51576 (51.5 KB)

wlan0     Link encap:Ethernet  HWaddr cd:af:76:c4:6d:99  
          inet addr:192.168.1.5  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: ff70::ceff:78dd:fdc1:6d95/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1338984 errors:0 dropped:0 overruns:0 frame:0
          TX packets:997145 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1521507128 (1.5 GB)  TX bytes:142971835 (142.9 MB)

root@unknown:~# brctl show
bridge name bridge id  STP enabled interfaces
virbr0  8000.1a9819c54ba8 yes  eth0
       tap0
root@unknown:~# qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" -hda 2014-09-09-wheezy-raspbian.img -net nic,macaddr=00:16:3e:00:00:01 -net tap,ifname=tap0,script=no,downscript=no

RaspberryPI interface set to DHCP:
pi@vrpi:~$ cat /etc/network/interfaces 
auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
pi@vrpi:~$ 
Screenshot of Virtual-Raspberry-Pi:

Sunday, July 20, 2014

Simple shell script for bulk image compression

The following script help you to compress bulk image.

Usage and documentation  can be found at GitHub:
#!/bin/bash

#imagemagick is required
if ! hash convert 2>/dev/null; then
   echo "imagemagick is required.if debian run 'sudo apt-get install imagemagick'"
   exit 1
fi 

#
## Display help text 
#
usage() {
echo -n "  Usage: $0"
cat <<"EOF" 
 [-R] [-f] [-d ] [-n ] [-e ] [-q ]
    where:
      -d 
        directory path need to be scaned default value .
      -R
        recursivly scan directories
      -n 
        file name default * 
      -e 
        file extention default jpg
      -q 
        quality of image default 50
      -f 
        forcefully compress all
      --size n[cwbkMG]
        File uses n units of space. The following suffixes can be used:

            `b'    for 512-byte blocks (this is the default if no suffix  is used)
            `c'    for bytes
            `w'    for two-byte words
            `k'    for Kilobytes (units of 1024 bytes)
            `M'    for Megabytes (units of 1048576 bytes)
            `G'    for Gigabytes (units of 1073741824 bytes)
      --resize geometry
        Format of geometry: [WIDTHxHEIGHT | PERCENTAGE]
        Resize image based on width/height or percentage
          WIDTH/HEIGHT - positive integer
          PERCENTAGE - Eg. 50%
          
          1024x - will automatically determine height to keep dimension
          x576 - will automatically determine width to keep dimension
      --log filename
        option log file name 
EOF
  exit 1
}

#
## Display progress bar
#
progressBar() {
  if [ "$#" -eq 2 ]; then
    local total=$1
    local inprogress=$2
    local column=$(($(stty size | cut -d' ' -f2)-7))
    local progressed=$(( ($inprogress*100)/$total )) #formula used (inprogress/total)*100
    local fills=$(( ($column*$progressed)/100 ))

    echo -n "["
    for i in $(seq 1 $fills); do echo -n "="; done; #completed %
    echo -n ">"
    fills=$fills-1
    for i in $( seq 1 $(( $column-$fills )) ); do echo -n " "; done; #uncompleted %
    echo -n "]$progressed%"
    
    #ignore \r at complete
    if [ "$progressed" -ne 100 ]; then
      echo -ne '\r'
    fi
  fi
}

dir="."
name="*"
ext="jpg"
quality=50
recursive=' -maxdepth 1'
log=""
forceful=0
size=""
resize=""
declare -i count

TEMP=`getopt -q -o d:e:q:Rf --long log:,size:,resize: -- "$@"`

if [ $? -ne 0 ]
then
  usage
fi

# Note the quotes around `$TEMP’: they are essential!
eval set -- "$TEMP"

while [ $# -gt 0 ]
do
  case "$1" in
    -d) dir=$2; shift;;
    -e) ext=$2; shift;;
    -q) quality=$2; shift;;
    -n) name=$2; shift;;
 --log) log=$2; shift;;
--size) size="-size $2"; shift;;
--resize) resize="-resize \"$2\""; shift;;
    -R) recursive="";;
    -f) forceful=1;;
    --) shift; break;;
    *) usage;;
  esac
  shift;
done
(
IFS=$'\n'
#compress the image
cmd="find $dir $recursive $size ! -path . -type f -name '$name.$ext'"
files=($(eval $cmd))

if [ "" != "$log" ]; then
  echo -e "\n########$(date)#########\n" >> $log
fi
for index in ${!files[@]} 
do
  file=${files[$index]}
  cmd="convert $resize -quality $quality% \"$file\" \"$file\""
  if [ 1 -eq "$forceful" ]; then
    count=$count+1
    $(eval $cmd)
    progressBar ${#files[@]} $(($index+1))
    if [ "" != "$log" ]; then
       echo $cmd >> $log 
    fi
  else
    image=$(basename ${file})
    read -p "Do you want to compress '$image'?[y/n] " -n 1 -r
    echo    # (optional) move to a new line
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
      count=$count+1
      $(eval $cmd)
      if [ "" != "$log" ]; then
        echo $cmd >> $log 
      fi
    fi
  fi
done
echo "$count file(s) compressed out of ${#files[@]}"
) 


Sample command:
compress -R

   will recursively scan all jpg file and compress down to 50%

compress -R -f -e png --size +521k

    will recursively compress all png files which are greater than 512k size

compress -R -f -e png --size -521k

   will recursively compress all png files which are less than 512k size

compress -R -f -d "/home/pictures/" -n "nature*" -e "png" -q 70