30 Jul 2009

Selectable area for screenshots on gnome

Install required software:

$ sudo apt-get install zenity scrot xclip


Script for capturing screen areas (change targets at the beginning of the file):
#!/bin/bash

targetdir=/home/public-www/tmp/
targeturi=http://wunderlin.net/tmp/
icon=/usr/share/icons/gnome/22x22/apps/applets-screenshooter.png

# ask for filename
file=$(zenity --title="Screenshot" --width=800 --window-icon=$icon \
--text="Filename:" --filename="$targetdir" --file-selection)

if [[ "$file" == ".png" || -z "$file" ]]; then exit 1; fi

scrot --select "$file"

uri=$(echo "$file" | sed -e 's|'$targetdir'||')

echo "$targeturi$uri" | xclip -i -selection clip-board
# zenity --info --text="$targeturi$uri" --title="Screenshot URL" --window-icon=$icon
echo $file;

exit 0;


Steps for creating a custom hotkey to launch any application in GNOME:
  1. Open "gconf-editor" as the user as you're logged in in GNOME
  2. Go to "apps" -> "metacity" -> "keybinding_commands"
  3. Double click on e.g. "command_1"
  4. Type in the name of the application you want to launch, e.g. "gcalctool", the GNOME calculator
  5. Go to "apps" -> "metacity" -> "global_keybindings"
  6. Double click on e.g. "run_command_1"
  7. Type in e.g. <Control><Alt>c
  8. Note the < and > for the special function keys
  9. DONE! Close the gconf-editor and press CTRL-ALT-c and the calculator should come up

21 Jul 2009

Convert vmdk to vdi files

I am moving away from VMWare Server to VirtualBox. VMWare 2's web interface at first excited me, then I have realized that it depends on platform specific browser plugins. The result is an everywhere available control interface (as long as you have installed the plugin) with the awefull slowness of a web interface. So why not just install a client application which integrates into the platform, is fast and reliable I ask.


VirtualBox seems to fit my needs for a software testing server much better than Vmware Server 2.x.

Migration involves converting VMWare's vmdk disk images to VirtualBox's vdi images. Vmdk images are often split into several files (snapshots, 2GB size limit on NTFS) and mus therefore usually be consolidated into one file again.

Instructions below require some software packages to be installed, on a debian system:

$ sudo apt-get install qemu virtualbox-ose
And vmware must be installed of course. In the example below «multipart.vmdk» is the base file of the vmware image (usually some multipart-S00N.vmdk files would reside in the same directory), «flattened.vdi» is the result and can be used with VirtualBox.

#!/usr/bin/env bash
# $Id$

# debug=1

bin=(vmware-vdiskmanager \
vmware-vdiskmanager \
vmware-vdiskmanager \
qemu-img \
VBoxManage)
cmd=("%s -R %s " \
"%s -d %s " \
"%s -r %s -t 0 %s" \
"%s convert %s -O raw %s" \
"%s convertdd %s %s")
msg_ok=("1. Consistency check." \
"2. Defragment." \
"3. Flattened vmdk files into 1 file: flattened.vmdk" \
"4. Converted flattened.vmdk into raw image." \
"5. Converted raw image into a VirtualBox image (vdi).")
msg_nok=("Failed consistency check of vmware image." \
"Failed to defragment vmware image." \
"Failed to flatten vmdk file." \
"Failed to convert vmdk into raw image." \
"Failed to convert raw image into vdi.")
file_src=("%s.vmdk" "%s.vmdk" "%s.vmdk" "%s-flattened.vmdk" "%s-flattened.bin")
file_dst=("" "" "%s-flattened.vmdk" "%s-flattened.bin" "%s.vdi")

# parameter check
if [[ ! -z "$1" ]]; then
file=$(echo "$1" | sed -e 's/\.vmdk$//')
else
echo "usage: $0 <vmwareimage.vmdk>"
exit 1
fi

# check for required binaries
function isexecutable {
if [[ ! -x "$(which $1)" ]]; then
echo "'$1' is eighter not in your \$PATH, not executable or"
echo "not installed, aborting."
exit 2
fi
}
for (( c=0; c < ${#bin[@]}; c++ )); do
isexecutable "${bin[$c]}"
done

function err {
echo $1
exit 3
}

# run command
function runpart {
exec="$1"
msg_succcess="$2"
msg_error="$3"

echo "$msg_succcess "
echo " executing: $exec"
a=$($exec 2>&1) # && echo "$msg_succcess ($a)" || err "$msg_error"
if [[ $? = 0 ]]; then
echo " $a"
else
echo " Failed execution, aborting."
exit 4
fi
}

echo "Clenaing up ..."
[ -f $(printf "%s-flattened.vmdk" "$file") ] && \
rm $(printf "%s-flattened.vmdk" "$file")
[ -f $(printf "%s-flattened.bin" "$file") ] && \
rm $(printf "%s-flattened.bin" "$file")
[ -f $(printf "%s.vdi" "$file") ] && \
rm $(printf "%s.vdi" "$file")

cat <<EOT
Converting $file.vmdk to $file.vdi. This will take some time ...

EOT

#run all parts
for (( c=0; c < ${#bin[@]}; c++ )); do
from=$(printf "${file_src[$c]}" "$file")
to=$(printf "${file_dst[$c]}" "$file")
if [[ -z "$to" ]]; then
cm=$(printf "${cmd[$c]}" "${bin[$c]}" "$from")
else
cm=$(printf "${cmd[$c]}" "${bin[$c]}" "$from" "$to")
fi

if [[ -n $debug ]]; then
echo "$cm"
echo " ${msg_ok[$c]}"
echo " ${msg_nok[$c]}"
echo ""
continue;
fi

runpart "$cm" "${msg_ok[$c]}" "${msg_nok[$c]}"
done

cat <<EOT
Done. you may delete the following files:
$(printf "${file_dst[2]}" "$file")
$(printf "${file_dst[3]}" "$file")

EOT

exit 0;


That's it, «flattened.vdi» is the disk image for VirtualBox.

Most of the infos were found in the following thread in the VirtualBox forum.

17 Jul 2009

ies4linux on Ubuntu Jaunty

Installing ies4linux on Jaunty is not so straight forward. I have only managed to install IE6 and flash so far (IE1 - IE7 would be available in the same package).

First of all, wine and cabextract are needed:
$ sudo apt-get install -y wine cabextract

then download the ies4 linux package:

cd /tmp
wget http://www.tatanka.com.br/ies4linux/downloads/ies4linux-latest.tar.gz
tar zxvf ies4linux-latest.tar.gz
cd ies4linux-*


The version check of wine is looking for re/0\.9\.*/ but wine hited version 1.* some weeks ago, this version check doesn't work, I have disabled it since we are using defenately a newer version. Edit «lib/functions.sh» and comment out the line with wine version check (~ line 36):
--- lib/functions.sh-dist 2009-07-17 17:39:55.283279400 +0200
+++ lib/functions.sh 2009-07-17 17:39:59.917574880 +0200
@@ -33,7 +33,7 @@
# Find where wine is
function find_wine {
which wine &> /dev/null || error $MSG_ERROR_INSTALL_WINE
- wine --version 2>&1 | grep -q "0.9." || warning $MSG_WARNING_OLDWINE
+ # wine --version 2>&1 | grep -q "0.9." || warning $MSG_WARNING_OLDWINE
}

# check for cabextract


Now the installer should work and you can install ies4linux (ie6 + flash + msfonts) to your $HOME directory:

./ies4linux  \
--basedir ~/ies4linux --bindir ~/bin \
--no-desktop-icon --install-corefonts --no-gui


The «--help» and «--full-help» command line arguments do not expose all commandline parameters. All options can be found in the ./ies4linux shell script:
# Get command-line options
while [ $# -gt 0 ]; do
case "$1" in
--install-ie6 | --install-flash) shift;;
--install-ie55) export INSTALLIE55=1; shift ;;
--install-ie5) export INSTALLIE5=1; shift ;;
--install-ie2) export INSTALLIE2=1; shift ;;
--install-ie15) export INSTALLIE15=1; shift ;;
--install-ie1) export INSTALLIE1=1; shift ;;

--install-ie7|--beta-install-ie7) export INSTALLIE7=1; shift ;;
--hack-ie7-proxy-settings) export HACK_IE7_PROXY=1; shift ;;

--no-ie6) export INSTALLIE6=0; shift ;;
--no-flash) export INSTALLFLASH=0; shift ;;
--no-desktop-icon) export CREATE_DESKTOP_ICON=0; shift ;;
--no-menu-icon) export CREATE_MENU_ICON=0; shift ;;
--install-corefonts) export INSTALLCOREFONTS=1; shift ;;

--basedir) export BASEDIR="$2"; shift 2 ;;
--bindir) export BINDIR="$2"; shift 2 ;;
--downloaddir) export DOWNLOADDIR="$2"; changeddownloaddir=1; shift 2 ;;
--wget-flags) export WGETFLAGS="$2"; shift 2 ;;

--no-gui) export IES4LINUX_MODE="automatic"; shift ;;
--no-color) export NOCOLOR=1; shift 1 ;;
--gui) export PREFERRED_GUI=$2; shift 2 ;;
--no-localization)
eval $(load_variables_file "$IES4LINUX/lang/enUS.sh")
shift
;;

--uninstall)
uninstall
exit 0
;;
--locale)
export CHOOSED_IE6_LOCALE=$(echo "$2" | tr a-z A-Z)
shift 2
;;
--list-locales)
echo $IE6_LOCALES | fmt -w 40
exit 0
;;
--debug)
export DEBUG=true
shift
;;
--help | -h)
sh lib/help.sh
exit 0
;;
--full-help)
sh lib/help.sh full
exit 0
;;
*)
echo "Error: unknown option \"$1\""
if echo "$1" | grep '=' >/dev/null; then
echo "Options are not GNU-style"
echo " i.e. don't use: --option=value"
echo " use instead: --option value"
fi
echo "run \"./ies4linux --help\" for more info"
exit 1
;;
esac
done

Ubuntu Jaunty and LSB (Linux Standard Base)

I can't believe it but it's true, LSB is not part of the Jaunty default installation *sigh*

the following command works so nicely if one wants to detect the linux version a script is running on:
$ echo $(lsb_release -rcsi)

but without LSB the command won't work. I am a little bit surprised that it is not common among all linux releases to include LSB (except for the ones going for small footprint like DSL).

Install LSB on jaunty with:

$ sudo apt-get install -y lsb

10 Jul 2009

simplified deb package management

pkg shell script to the rescue. typing often used commands for software management on a debian based (deb) system can be boring an error prone. Some commands might be used often, such as «apt-get install», «apt-cache search» and «dpkg -l», etc. This script exposes the most used commands as easy to remebr commands (pkg* for package *i = install, *s = search, *u = update, etc.).

Modes:
pkgi [parameters] >name< Install package with >name<
pkgs [parameters] >name< Search for package >name<
pkgu Upgrade all packages
pkgl >name< List installed Packages filtered by >name<
pkgr [parameters] >name< Remove installed package
pkgp [parameters] >name< Purge installed package
pkgc Cleanup
pkg setup Setup symlinks
pkg remove|uninstall Remove symlinks

pkg (bash script):
#!/bin/bash

# shortcuts to frequently used package management tools like apt-get,
# dpkg and apt-cache
#
# NOTE: this script does not work if you havb spaces in your path.
#
# $Id$

# usage
function usage {
cat << EOT
usage: (pkgi|pkgs|pkgr|pkgp|pkgl|pkgu) [parameters] [name]

Modes:
pkgi [parameters] <name> Install package with <name>
pkgs [parameters] <name> Search for package <name>
pkgu Upgrade all packages
pkgl <name> List installed Packages filtered by <name>
pkgr [parameters] <name> Remove installed package
pkgp [parameters] <name> Purge installed package
pkgc Cleanup
pkg setup Setup symlinks
pkg remove|uninstall Remove symlinks
Mappings:
pkgi [parameters] <name> sudo apt-get install [parameters] <name>
pkgs [parameters] <name> apt-cache search [parameters] <name>
pkgu sudo apt-get update && sudo apt-get upgrade
pkgl <name> dpkg -l | grep <name>
pkgr [parameters] <name> sudo apt-get remove [parameters] <name>
pkgr [parameters] <name> sudo apt-get remove --purge [parameters] <name>
pkgc sudo apt-get autoremove
Exit Codes
0: success
1: unknown command (install, remove, autoclean, etc.)
2: parameter missing
3: no write permission (needed by setup)
EOT
}

function fn_help {
fn=$(basename $1)
echo -en "usage: $fn "

case $fn in
"pkgi")
echo "[parameters] <name> - Install package with <name>" ;;
"pkgu" )
echo "- Update repository" ;;
"pkgs" )
echo "[parameters] <name> - Search for package <name>" ;;
"pkgl" )
echo "<name> - List installed Packages filtered by <name>" ;;
"pkgr" )
echo "[parameters] <name> - Remove installed package " ;;
"pkgp" )
echo "[parameters] <name> - Purge installed package " ;;
"pkgc" )
echo "- Cleanup" ;;
* )
echo "Unknown program!"
exit 2
;;
esac
}

function remove {
for l in $@; do
p=$(basename $l)
if [[ "$p" == "pkg" ]]; then
continue
fi
rm $l
done

exit 0;
}

# parameters
filename=$(basename "$0");
command=""

if [[ "$filename" == "pkgi" ]]; then command="install"; fi
if [[ "$filename" == "pkgu" ]]; then command="upgrade"; fi
if [[ "$filename" == "pkgs" ]]; then command="search"; fi
if [[ "$filename" == "pkgl" ]]; then command="list"; fi
if [[ "$filename" == "pkgr" ]]; then command="remove"; fi
if [[ "$filename" == "pkgp" ]]; then command="purge"; fi
if [[ "$filename" == "pkgc" ]]; then command="autoremove"; fi

# setup ?
if [[ "$filename" == "pkg" ]]; then
basedir=$(dirname $0)
escaped=$(echo "$basedir" | sed -e 's/\//\\\//g')
pkgs=$(echo $basedir/pkg* | sed -e 's/'$escaped"\/pkg "'//')

if [[ "$1" == "remove" || "$1" == "uninstall" ]]; then
# if [[ $(basename $0) == "pkg" ]]; then
# exit 0;
# fi
#
echo "Removing ..."
remove $pkgs
fi

if [[ "$1" == "setup" ]]; then

# check if we can write to the directory to reate the symlinks
if [[ ! -w "$basedir" ]]; then
echo "No write permission to create symlinks in $basedir";
exit 2;
fi

echo "Installed links"
ls -la $pkgs;

echo
echo "Purging links"
if [[ $(basename $0) != "pkg" ]]; then
exit 0;
fi
# for l in $pkgs; do
# echo $l
# rm $l
# done

echo
echo "creating links"
for l in pkgc pkgi pkgl pkgr pkgp pkgs pkgu; do
echo $basedir/pkg "->" $basedir/$l
ln -s $basedir/pkg $basedir/$l
done
exit 0;
fi

if [[ -z "$1" || "$1" == "-h" || "$1" == "--help" ]]; then
usage;
exit 0;
fi
fi

# show help text ?
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
fn_help "$0"
exit 0
fi

# show help if parameters are missing
if [[ "$filename" == "pkgi" || "$filename" == "pkgs" ||
"$filename" == "pkgr" || "$filename" == "pkg" ||
"$filename" == "pkgs" || "$filename" == "pkgp" ]]; then
if [[ -z "$1" ]]; then
fn_help "$0"
exit 2
fi
fi

# unknown command
if [[ -z "$command" ]]; then
fn_help "$0"
exit 1
fi

# execute
if [[ "$command" == "list" ]]; then
/usr/bin/dpkg -l | grep -v "^r" | \
sed -e 's/\(..\)[ \t]\+\([^ ]\+\)[ \t]\+\([^ ]\+\)[ \t]\+\(.*\)$/\2 - \4/'|\
grep "$1"
elif [[ "$command" == "search" ]]; then
/usr/bin/apt-cache search $@
elif [[ "$command" == "purge" ]]; then
sudo /usr/bin/apt-get remove --purge $@
elif [[ "$command" == "update" ]]; then
sudo /usr/bin/apt-get update $@ && sudo /usr/bin/apt-get upgrade $@
else
sudo /usr/bin/apt-get $command $@
fi

exit 0