Internal/Isolated networks on oVirt

OVirt logo

Although virt-manager provides easily isolated network, oVirt haven’t so evident configuration. In fact, we need some commands on terminal.

You can use dummy module to get internal networks. First of all, make sure your host load dummy module at startup.
Create /etc/sysconfig/modules/dummy.modules:

modprobe dummy >/dev/null 2&1
exit0

Manually, you can run modprobe to load on a running machine. It will appear a dummy0 network interface. Done this, create /etc/sysconfig/network-scripts/ifcfg-dummy0 with this content:

DEVICE=dummy0
BOOTPROTO=none
ONBOOT=yes
NM_CONTROLLED=no
PROMISC=yes

Now comes the oVirt configuration. In webadmin portal, go to the ‘Network’ tab and click new:

New network

New network

The definition could be simple. Just give a name and match ‘VM network’:

New network

New network

With the virtual switch created, we need to link our dummy interface on it. Go to the network configuration of host:

Configure network on host

Configure network on host

Configure network on host

Configure network on host

Drag internal network and drop in dummy0 interface

Configure network on host

Configure network on host

Check ‘Save network configuration’ and click ok.

Configure network on host

Configure network on host

Now, for each virtual machine you want to use internal network, you can create a virtual NIC and attach to internal virtual switch.

Configure network on host

Configure network on host

Shell tricks

tricks

There are many keys or commands that could turn easier our lives. That’s some:

Read text file inside tar.xz file:

cat samba-4.0.9.tar.xz | tar -JxO samba-4.0.9/source4/scripting/bin/samba_backup | less

Command correction:

# nkdir -v /tmp/foo
bash: nkdir: command not found
# ^nkdir^mkdir
mkdir foo

See the difference of file in remote machines:

diff <(ssh server1 'cat file') <(ssh server2 'cat file')

Or installed packages:

diff <(ssh server1 'rpm -qa | sort') <(ssh server2 'rpm -qa | sort')

You have an alias with the same name of a command, but you want to run the command, not alias:

$ alias vi=vim
$ \vi

You can see that ones and many others here.

Partition shrink

drive-harddisk

Several times we need resize our storage area. Normally we expand volumes, but not shrink. Although not common, it’s possible too. Surfing on the web, I found that great article.

My tests worked gracefully! I extended this article above resizing the virtual disk image file, with qemu-img.

qemu-img convert -f qcow2 -O raw resize.img resize_raw.img
qemu-img resize resize_raw.img 5360321024
qemu-img convert -f raw -O qcow2 resize_raw.img resize.img

5360321024 is the exactly size in bytes of the sum of all partitions.

Rebuilding Slackware packages from installed files

package

Frequently I update my Slackware with current repository, but sometimes it causes me problems with my ATI video card. As native Linux support to my video card isn’t good, I need use proprietary driver. The development of ATI driver is slower than Linux, so not always it compiles with most recent kernel. When I update my system, I’m not sure that ATI driver will compile to slackware-current kernel version, so I need try update. If it doesn’t work, I need downgrade to previous version, but if I don’t have the package, I can’t downgrade, because the last release of Slackware will have old kernel, and current repository replaces the last one.

Thus, I thought a way to generate the package from installed files. Searching on the web, I found the right procedure here.

Based on that pearl, I coded a script in order to automate the process. The rebuildpkg can be found on my github. Anyone who want help me, are welcome.

Example of use:

# rebuildpkg aaa_elflibs

dovecot imap postscript

dovecot

Recentemente tive a necessidade de controlar as contas de e-mail que estavam ativas no servidor de e-mails. Para isto, resolvi registrar a data e hora do último login. Meu sistema usa dovecot versão 2.x, então alterei o arquivo 10-master.conf da seguinte forma:

service imap {
  executable = imap imap-lastlogin
  ...
}

E também:

service imap-lastlogin {
  executable = script-login -d /usr/local/bin/lastlogin.sh
  unix_listener imap-lastlogin {
    user = $default_internal_user
    mode = 0666
  }
}

Então criei o script a ser executado logo no momento do login, para salvar na base de dados a data e hora do login:

#!/bin/bash

echo "UPDATE mailbox SET lastlogin = now() WHERE username = '$USER'" | mysql -u dovecot --password="secret" postfix
exec $@

Caso queira que seu script faça outra coisa, basta alterá-lo.

mail queue length via net-snmp

Mail queue

It is possible check the mail queue length using net-snmp with extended table. Follow my suggestion.

Create script:

#!/bin/bash

queuelength=`/usr/sbin/postqueue -p | awk '$0 ~ /Requests.$/ {print $5}'`

echo -n "Mail queue length: "
if [ "$queuelength" == "" ]; then
        echo 0;
else
        echo ${queuelength};
fi
exit $queuelength

In snmpd.conf, add line:

exec postqueue /usr/local/bin/postqueue.sh

Be sure that postqueue.sh have execution permission.

You can check out using:

snmpwalk -v 1 -c public localhost extTable

You can see more here.

Dovecot mailbox backup

Backup

In Linux environment there are several ways to do a backup. Packing with tar, cpio, or copying to a remote server with scp, rsync, ftp… But dovecot has the right tool for that propose. It is dsync.
Dsync works like rsync, which copies only the difference of a location1 to the location2. It could operate either mirror or backup mode.
As mirror, it synchronizes the content of location1 and location2. That mode is usually used to maintain 2 servers synchronized to offer a loadbalance environment.
As backup, dovecot copies location1 to location2, so as to have backup copies, in case of a disaster.
The main difference of dsync and other tools like scp or rsync is that dsync care about dovecot indexes files and metadata. Thus, the copy is made free of corruption.
You can find more details consulting the dsync’s manpage. Below an example:

sysadmin@mailserver# dsync -u eduardo backup maildir:/tmp/mailbox/eduardo/

If you want to copy to another server using ssh, you can use:

sysadmin@mailserver# dsync -u eduardo backup ssh mailuser@mailserver2 dsync -u eduardo

Dsync can be used to revert a backup, adding -R in the options. It can be also used to convert the mailbox format. Details you can find here.

Cisco 2960 switch script backup

copy

Bons administradores de sistemas precisam consolidar tarefas corriqueiras. Também se faz necessário backups das configurações de seus ativos. Desta forma, criei um script que pode ser executado por um agendador de tarefas automático, como o cron, para fazer backups dos meus switches. Aqui está:

#!/bin/bash
EXPECT_BIN=`which expect`
DIFF_BIN=`which diff`
BACKUP_DIR=${BACKUP_DIR:-/tmp/backup}
SWITCH_LIST=${SWITCH_LIST:-/tmp/switchlist}
PASS="t0P53cr7"

if [ -z "$EXPECT_BIN" ] ; then
  echo "You need expect!"
  exit
fi

if [ -z "$DIFF_BIN" ] ; then
  echo "You need diff!"
  exit
fi

if [ ! -f "$SWITCH_LIST" ] ; then
  echo "$SWITCH_LIST does not exist!"
  exit
fi

mkdir -p $BACKUP_DIR

cat << EOF > /tmp/backup.exp
#!$EXPECT_BIN
set timeout 20

set ip [lindex \$argv 0]
set hostname [lindex \$argv 1]
set file [lindex \$argv 2]

spawn ssh "admin\@\$ip"
expect {
  "assword:" {
    send "$PASS\r"
  }
  "(yes/no)? " {
    send "yes\r"
    expect "assword:"
    send "$PASS\r"
  }
}
expect "\$hostname>"
send "enable\r"
expect "assword:"
send "$PASS\r"
expect "\$hostname#";
send "terminal length 0\r";
expect "\$hostname#";
log_file "\$file"
send "show running\r";
expect -re ".*end\r";
log_file
expect "\$hostname#";
send "exit\r";
expect "closed."
EOF

chmod +x /tmp/backup.exp

while read line ; do
  ip=`echo $line | cut -d ':' -f1`
  hostname=`echo $line | cut -d ':' -f2`
  file=`echo $ip-$hostname.$(date +%Y%m%d%H%M%S).conf`

  echo -n "Collecting $hostname..."
  /tmp/backup.exp $ip $hostname $BACKUP_DIR/$file > /dev/null 2>&1
  chmod -x $BACKUP_DIR/$ip-$hostname*.conf
  if [ -n "$($DIFF_BIN -Naur `ls -t1 $BACKUP_DIR/$ip-$hostname*.conf | head -n2 | tail -n1` $BACKUP_DIR/$file)" ] ; then
    $DIFF_BIN -Naur `ls -t1 $BACKUP_DIR/$ip-$hostname*.conf | head -n2 | tail -n1` $BACKUP_DIR/$file > $BACKUP_DIR/$file.patch
    echo -n "changed config, patch $file.patch generated "
  fi
  echo "done!"
done < $SWITCH_LIST

rm -f /tmp/backup.exp

A lista de switches deve conter um por linha, sendo IP e hostname separados por ‘:’. Veja o exemplo:

172.16.3.17:SW-IT-017
172.16.3.18:SW-IT-018

Seu que não é o melhor script que existe no mundo, mas é o suficiente para mim. Ficaria grato se alguém sugerisse melhorias.

Scope of variables in while loop

loop

Recently I needed count lines of a log containing some sentence. For that, I used while loop of bash that way:

noqueue=0
grep NOQUEUE /var/log/maillog | while read i ; do
  noqueue=`expr $noqueue + $(echo ${i} | grep -c "550 5.1.1")`
done
echo "$noqueue"

But the result echoed was always 0. When I tried echo noqueue variable inside loop, it printed the expected, incremented values of noqueue. It looked as the global variable was being ignored.

Searching for explanation on the web, I mean, Google, I read that the pipe started another scope where the first noqueue did not exist, and when the loop terminated, it was vanished. So, I got the solution here.

My script should be like this to work:

noqueue=0
while read i ; do
  noqueue=`expr $noqueue + $(echo ${i} | grep -c "550 5.1.1")`
done << EOF
$(grep NOQUEUE /var/log/maillog)
EOF
echo "$noqueue"

Now, it is printing what I have expected.