Don't understand german? Read or subscribe to my english-only feed.

State of the art Debian/wheezy deployments with GRUB and LVM/SW-RAID/Crypto

February 28th, 2014

Moving from Lilo to GRUB, using LVM as default, etc throughout the last years it was time to evaluate how well LVM works without a separate boot partition, possibly also on top of Software RAID. Big disks are asking for partitioning with GPT, just UEFI isn’t my default yet, so I’m still defaulting to Legacy BIOS for Debian/wheezy (I expect this to change for Debian/jessie and according hardware approaching at my customers).

So what we have and want in this demonstration setup:

  • Debian 7 AKA wheezy
  • 4 hard-disks with Software RAID (on 8GB RAM), using GPT partitioning + GRUB2
  • using state-of-the-art features without too much workarounds like separate /boot partition outside of LVM or mdadm with 0.9 metadata, just no (U)EFI yet
  • LVM on top of SW-RAID (RAID5) for /boot partition [SW-RAID->LVM]
  • Cryptsetup-LUKS on top of LVM on top of SW-RAID (RAID5) for data [SW-RAID->LVM->Crypto] (this gives us more flexibility about crypto yes/no and different cryptsetup options for the LVs compared to using it below RAID/LVM)
  • Rescue-system intregration via grml-rescueboot (not limited to Grml, but Grml should work out-of-the-box)

System used for installation:

root@grml ~ # grml-version
grml64-full 2013.09 Release Codename Hefeknuddler [2013-09-27]

Partition setup:

root@grml ~ # parted /dev/sda
GNU Parted 2.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel gpt
(parted) mkpart primary 2048s 4095s
(parted) set 1 bios_grub on
(parted) name 1 "BIOS Boot Partition"
(parted) mkpart primary 4096s 100%
(parted) set 2 raid on
(parted) name 2 "SW-RAID / Linux"
(parted) quit
Information: You may need to update /etc/fstab.

Clone partition layout from sda to all the other disks:

root@grml ~ # for f in {b,c,d} ; sgdisk -R=/dev/sd$f /dev/sda
The operation has completed successfully.
The operation has completed successfully.
The operation has completed successfully.

Make sure each disk has its unique UUID:

root@grml ~ # for f in {b,c,d} ; sgdisk -G /dev/sd$f
The operation has completed successfully.
The operation has completed successfully.
The operation has completed successfully.

SW-RAID setup:

root@grml ~ # mdadm --create /dev/md0 --verbose --level=raid5 --raid-devices=4 /dev/sd{a,b,c,d}2
mdadm: layout defaults to left-symmetric
mdadm: layout defaults to left-symmetric
mdadm: chunk size defaults to 512K
mdadm: size set to 1465004544K
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
root@grml ~ #

SW-RAID speedup (system dependent, YMMV):

root@grml ~ # cat /sys/block/md0/md/stripe_cache_size
256
root@grml ~ # echo 16384 > /sys/block/md0/md/stripe_cache_size # 16MB
root@grml ~ # blockdev --getra /dev/md0
6144
root@grml ~ # blockdev --setra 65536 /dev/md0 # 32 MB
root@grml ~ # sysctl dev.raid.speed_limit_max
dev.raid.speed_limit_max = 200000
root@grml ~ # sysctl -w dev.raid.speed_limit_max=9999999999
dev.raid.speed_limit_max = 9999999999
root@grml ~ # sysctl dev.raid.speed_limit_min
dev.raid.speed_limit_min = 1000
root@grml ~ # sysctl -w dev.raid.speed_limit_min=100000
dev.raid.speed_limit_min = 100000

LVM setup:

root@grml ~ # pvcreate /dev/md0
  Physical volume "/dev/md0" successfully created
root@grml ~ # vgcreate homesrv /dev/md0
  Volume group "homesrv" successfully created
root@grml ~ # lvcreate -n rootfs -L4G homesrv
  Logical volume "rootfs" created
root@grml ~ # lvcreate -n bootfs -L1G homesrv
  Logical volume "bootfs" created

Check partition setup + alignment:

root@grml ~ # parted -s /dev/sda print
Model: ATA WDC WD15EADS-00P (scsi)
Disk /dev/sda: 1500GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system  Name                 Flags
 1      1049kB  2097kB  1049kB               BIOS Boot Partition  bios_grub
 2      2097kB  1500GB  1500GB               SW-RAID / Linux      raid

root@grml ~ # parted -s /dev/sda unit s print
Model: ATA WDC WD15EADS-00P (scsi)
Disk /dev/sda: 2930277168s
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start  End          Size         File system  Name                 Flags
 1      2048s  4095s        2048s                     BIOS Boot Partition  bios_grub
 2      4096s  2930276351s  2930272256s               SW-RAID / Linux      raid

root@grml ~ # gdisk -l /dev/sda
GPT fdisk (gdisk) version 0.8.5

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.
Disk /dev/sda: 2930277168 sectors, 1.4 TiB
Logical sector size: 512 bytes
Disk identifier (GUID): 212E463A-A4E3-428B-B7E5-8D5785141564
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 2930277134
Partitions will be aligned on 2048-sector boundaries
Total free space is 2797 sectors (1.4 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048            4095   1024.0 KiB  EF02  BIOS Boot Partition
   2            4096      2930276351   1.4 TiB     FD00  SW-RAID / Linux

root@grml ~ # mdadm -E /dev/sda2
/dev/sda3:
          Magic : a92b4efc
        Version : 1.2
    Feature Map : 0x0
     Array UUID : 7ed3b741:0774d529:d5a71c1f:cf942f0a
           Name : grml:0  (local to host grml)
  Creation Time : Fri Jan 31 15:26:12 2014
     Raid Level : raid5
   Raid Devices : 4

 Avail Dev Size : 2928060416 (1396.21 GiB 1499.17 GB)
     Array Size : 4392089088 (4188.62 GiB 4497.50 GB)
  Used Dev Size : 2928059392 (1396.21 GiB 1499.17 GB)
    Data Offset : 262144 sectors
   Super Offset : 8 sectors
          State : clean
    Device UUID : c1e4213b:81822fd1:260df456:2c9926fb

    Update Time : Mon Feb  3 09:41:48 2014
       Checksum : b8af8f6 - correct
         Events : 72

         Layout : left-symmetric
     chunk size : 512k

   Device Role : Active device 0
   Array State : AAAA ('A' == active, '.' == missing)

root@grml ~ # pvs -o +pe_start
  PV         VG      Fmt  Attr PSize PFree 1st PE
  /dev/md0   homesrv lvm2 a--  4.09t 4.09t   1.50m
root@grml ~ # pvs --units s -o +pe_start
  PV         VG      Fmt  Attr PSize       PFree       1st PE
  /dev/md0   homesrv lvm2 a--  8784175104S 8773689344S   3072S
root@grml ~ # pvs -o +pe_start
  PV         VG      Fmt  Attr PSize PFree 1st PE
  /dev/md0   homesrv lvm2 a--  4.09t 4.09t   1.50m
root@grml ~ # pvs --units s -o +pe_start
  PV         VG      Fmt  Attr PSize       PFree       1st PE
  /dev/md0   homesrv lvm2 a--  8784175104S 8773689344S   3072S
root@grml ~ # vgs -o +pe_start
  VG      #PV #LV #SN Attr   VSize VFree 1st PE
  homesrv   1   2   0 wz--n- 4.09t 4.09t   1.50m
root@grml ~ # vgs --units s -o +pe_start
  VG      #PV #LV #SN Attr   VSize       VFree       1st PE
  homesrv   1   2   0 wz--n- 8784175104S 8773689344S   3072S

Cryptsetup:

root@grml ~ # echo cryptsetup >> /etc/debootstrap/packages
root@grml ~ # cryptsetup luksFormat -c aes-xts-plain64 -s 256 /dev/mapper/homesrv-rootfs

WARNING!
========
This will overwrite data on /dev/mapper/homesrv-rootfs irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
root@grml ~ # cryptsetup luksOpen /dev/mapper/homesrv-rootfs cryptorootfs
Enter passphrase for /dev/mapper/homesrv-rootfs:

Filesystems:

root@grml ~ # mkfs.ext4 /dev/mapper/cryptorootfs
mke2fs 1.42.8 (20-Jun-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=128 blocks, Stripe width=384 blocks
262144 inodes, 1048192 blocks
52409 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1073741824
32 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done

root@grml ~ # mkfs.ext4 /dev/mapper/homesrv-bootfs
mke2fs 1.42.8 (20-Jun-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=128 blocks, Stripe width=384 blocks
65536 inodes, 262144 blocks
13107 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=268435456
8 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376

Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

Install Debian/wheezy:

root@grml ~ # mount /dev/mapper/cryptorootfs /media
root@grml ~ # mkdir /media/boot
root@grml ~ # mount /dev/mapper/homesrv-bootfs /media/boot
root@grml ~ # grml-debootstrap --target /media --password YOUR_PASSWORD --hostname YOUR_HOSTNAME
 * grml-debootstrap [0.57] - Please recheck configuration before execution:

   Target:          /media
   Install grub:    no
   Using release:   wheezy
   Using hostname:  YOUR_HOSTNAME
   Using mirror:    http://http.debian.net/debian
   Using arch:      amd64

   Important! Continuing will delete all data from /media!

 * Is this ok for you? [y/N] y
[...]

Enable grml-rescueboot (to have easy access to rescue ISO via GRUB):

root@grml ~ # mkdir /media/boot/grml
root@grml ~ # wget -O /media/boot/grml/grml64-full_$(date +%Y.%m.%d).iso http://daily.grml.org/grml64-full_testing/latest/grml64-full_testing_latest.iso
root@grml ~ # grml-chroot /media apt-get -y install grml-rescueboot

[NOTE: We’re installing a daily ISO for grml-rescueboot here because the 2013.09 Grml release doesn’t work for this LVM/SW-RAID setup while newer ISOs are working fine already. The upcoming Grml stable release is supposed to work just fine, so you will be able to choose http://download.grml.org/grml64-full_2014.XX.iso by then. :)]

Install GRUB on all disks and adjust crypttab, fstab + initramfs:

root@grml ~ # grml-chroot /media /bin/bash
(grml)root@grml:/# for f in {a,b,c,d} ; do grub-install /dev/sd$f ; done
(grml)root@grml:/# update-grub
(grml)root@grml:/# echo "cryptorootfs /dev/mapper/homesrv-rootfs none luks" > /etc/crypttab
(grml)root@grml:/# echo "/dev/mapper/cryptorootfs / auto defaults,errors=remount-ro 0   1" > /etc/fstab
(grml)root@grml:/# echo "/dev/mapper/homesrv-bootfs /boot auto defaults 0 0" >> /etc/fstab
(grml)root@grml:/# update-initramfs -k all -u
(grml)root@grml:/# exit

Clean unmounted/removal for reboot:

root@grml ~ # umount /media/boot
root@grml ~ # umount /media/
root@grml ~ # cryptsetup luksClose cryptorootfs
root@grml ~ # dmsetup remove homesrv-bootfs
root@grml ~ # dmsetup remove homesrv-rootfs

NOTE: On a previous hardware installation I had to install GRUB 2.00-22 from Debian/unstable to get GRUB working.
Some metadata from different mdadm and LVM experiments seems to have been left and confused GRUB 1.99-27+deb7u2 from Debian/wheezy (I wasn’t able to reproduce this issue in my VM demo/test setup).
Just in cause you might experience the following error message, try GRUB >=2.00-22:

  # grub-install --recheck /dev/sda
  error: unknown LVM metadata header.
  error: unknown LVM metadata header.
  /usr/sbin/grub-probe: error: cannot find a GRUB drive for /dev/mapper/cryptorootfs.  Check your device.map.
  Auto-detection of a filesystem of /dev/mapper/cryptorootfs failed.
  Try with --recheck.
  If the problem persists please report this together with the output of "/usr/sbin/grub-probe --device-map="/boot/grub/device.map"
  --target=fs -v /boot/grub" to <bug-grub@gnu.org>

Revisiting 2013

January 8th, 2014

2013 was a fantastic year for me. Following the real-life fork it was the first year of my daughter’s life. Whenever I heard people saying “oh, children are growing sooooo fast” in the past it felt like a lie for me, but seeing your own child grow I can just sign that, and it’s fantastic.

It was also the first year in our new home, and I’m not just happy with the building itself but also our neighborhood turned out to be great. New friends for drinking beer. :)

Also my business year was kind of special. jenkins-debian-glue has quite taken off and I had several interesting consulting gigs thanks to it. Business wise I learned a lot of stuff, especially related to distributor handling thanks to business around Grml-Forensic.

2014 already started interesting with several things in the pipeline, more details about that at a later stage.

Conclusion: I tend to call 2013 the best year of my life so far.

Event: mur.at Streitgespräche am 05.12.2013 + 06.12.2013 im ESC

November 27th, 2013

Copy/Paste von mur.at:

mur.at Streitgespräche am 05.12.2013 und 06.12.2013 – 19 Uhr

Piep, Piep, Piep, wir haben uns alle lieb? Von wegen! Mur.at möchte die Macht des guten alten Streitgesprächs, des gepflegten Meinungsaustauschs, der erbitterten Kontroverse, der lautgedachten Erörterung, des abendlichen Gedankenaustausches, des freundlichen Meinungsgefechts, etc. wiederbeleben!

Darum richten wir erstmals an zwei aufeinander folgenden Abenden jeweils einen potenziellen Disput zweier Widersacher*Innen mit Beteiligungsmöglichkeit des Publikums aus. Veranstaltungsort ist das neue ESC (esc.mur.at), Bürgergasse 5, Palais Trauttmansdorff, Graz.

Thema 1: Zwischen Datenmaßlosigkeit und Speicherdiät: Lebst du schon in der Cloud oder wie viele externe Speicherplatten hast du so?

Donnerstag, 05.12.2013, 19 Uhr

In Zeiten des eigenen exzessiven Datenspeicherbedürfnisses und der gleichzeitig allgegenwärtigen Datenüberwachung durch Staat und Wirtschaft diskutieren die geladenen “Streithansln” verschiedene Ansätze und Maßnahmen, wie man mit den eigenen Daten umgehen sollte. Es treffen aufeinander Karl Voit und Heinz Wittenbrink.

Thema 2: A/Symmetrischer Internetausbau – wie schnell soll das Internet der Zukunft noch werden?

Freitag, 06.12.2013, 19 Uhr

In vielen Haushalten regiert der preisgünstige ADSL Internetanschluss (sprich: viel Download, wenig Upload) und nur wenige professionelle NutzerInnen leisten sich den ungleich teureren Ausbau der schnellen Glasfaserleitung. Über die in/direkten politischen und praktischen Folgen dieser Aus- und Umbaupolitik der Datenautobahn zanken Michael “Mika” Prokop und Josef “Seppo” Gründler.

Event: Infracoders Graz Treffen am 09.10.2013

October 3rd, 2013

Edmund Haselwanter­ hat mich eingeladen beim ersten Treffen der Infracoders Graz über das Thema “Continuous Integration im Rechenzentrum” zu reden. Dieser Einladung folge ich sehr gerne und werde basierend auf meinem Vortrag von der OSDC über Themen wie Continuous Integration/Delivery, Jenkins, jenkins-debian-glue, Puppet und mcollective referieren.

  • Wann: Mittwoch, 9. Oktober 2013, 19:00 Uhr
  • Wo: BYTEPOETS GmbH / Münzgrabenstraße 92/2/3, Graz

Der Eintritt ist frei, Bier und Pizza werden von BYTEPOETS gesponsert. Weitere Details gibt es auf Meetup.

How to get grub-reboot working™

May 10th, 2013

So while testing Proxmox VE 3.0 RC1 I had the need to reboot the system into a kernel version different than the one being the default in the bootloader GRUB. “lilo -R …” worked fine in the past, but with GRUB it’s not as trivial on the first sight to get its equivalent. I remembered to have had problems with grub-reboot in the past already, or to quote a friend of mine: “has grub-reboot worked ever?”

Well yes, grub-reboot works – but only once you’re aware of the fact that you need to manually edit /etc/default/grub. :( It’s actually documented at wiki.debian.org/GrubReboot, but not in the man page/info document of grub-reboot itself (great idea to provide a separate wiki page for this issue but not consider editing the official documentation instead, not).

So here you go:

# grep GRUB_DEFAULT /etc/default/grub 
GRUB_DEFAULT=0
# sed -i 's/^GRUB_DEFAULT.*/GRUB_DEFAULT=saved/' /etc/default/grub
# grep GRUB_DEFAULT /etc/default/grub 
GRUB_DEFAULT=saved

# update-grub
[...]
# grep '^menuentry' /boot/grub/grub.cfg
menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-amd64' --class debian --class gnu-linux --class gnu --class os {
menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-amd64 (recovery mode)' --class debian --class gnu-linux --class gnu --class os {
menuentry 'Debian GNU/Linux, with Linux 2.6.32-20-pve' --class debian --class gnu-linux --class gnu --class os {
menuentry 'Debian GNU/Linux, with Linux 2.6.32-20-pve (recovery mode)' --class debian --class gnu-linux --class gnu --class os {
menuentry 'Debian GNU/Linux, with Linux 2.6.32-5-amd64' --class debian --class gnu-linux --class gnu --class os {
menuentry 'Debian GNU/Linux, with Linux 2.6.32-5-amd64 (recovery mode)' --class debian --class gnu-linux --class gnu --class os {

# grub-reboot 2  # to boot the third entry, the command writes to /boot/grub/grubenv
# reboot

FTR: Filed as #707695.

The #newinwheezy game: Grml packages in Debian/wheezy

May 2nd, 2013

Following up on the #newinwheezy game: Debian/wheezy is the first Debian release which ships packages from the Grml system. Grml became an official Debian Derivative and I’m very happy that three major projects of Grml found their official way into Debian:

As the description states grml2usb is interesting for getting Grml onto a USB device when the dd(1) approach (“dd if=grml.iso of=/dev/sdX“) just isn’t flexible enough.

grml-debootstrap provides a decent way to install Debian systems from the command line. As its author I might be biased but I’ve to mention that it’s working so nice that it is in use at several of my customers for automated roll-outs without any worries at all, and I got reports from other companies that they are very happy users of it as well.

Finally the grml-rescueboot packages provides a very simple and nice way to boot a rescue system from within GRUB (short version: throw a Grml ISO to /boot/grml/, run update-grub and be done).

PS: Thanks everyone for joining the #newinwheezy game over at planet.debian.org. :)

The #newinwheezy game: new forensic packages in Debian/wheezy

April 29th, 2013

Debian/wheezy includes a bunch of packages for people interested in digital forensics. The packages maintained within the Debian Forensics team which are shipped with the upcoming Debian/wheezy stable release for the first time in a Debian release are:

  • dc3dd: patched version of GNU dd with forensic features
  • extundelete: utility to recover deleted files from ext3/ext4 partition
  • rephrase: Specialized passphrase recovery tool for GnuPG
  • rkhunter: rootkit, backdoor, sniffer and exploit scanner (see comments)
  • rsakeyfind: locates BER-encoded RSA private keys in memory images
  • undbx: Tool to extract, recover and undelete e-mail messages from .dbx files

Join the #newinwheezy game and present packages which are new in Debian/wheezy.

OSDC 2013: Folien zu Continuous Integration im Rechenzentrum

April 19th, 2013

Ich bin zurück von der Open Source Data Center Conference 2013, sehr schön war es. Die Vortragsfolien zu meinem Vortrag “Continuous Integration im Rechenzentrum” habe ich soeben hochgeladen: PDF (4,4MB)

ldmtool: accessing Microsoft Windows dynamic disks from Linux

February 18th, 2013

Linux is a great platform for dealing with all kinds of different file systems, partition tables etc. But one of the few annoying situations when working in IT forensics are Microsoft Windows dynamic disks, AKA LDM (Logical Disk Manager).

Thanks to libldm’s ldmtool this is no longer true. A short demonstration from a real-life IT forensics investigation (actual IDs/data randomized for obvious reasons):

# ldmtool
ldm> scan /dev/sdc*
[
  "1bad5bbc-a4b5-42e1-8823-001014b00003"
]
ldm> show diskgroup 1bad5bbc-a4b5-42e1-8823-001014b00003
{
  "name" : "FOOBAR-Dg0",
  "guid" : "1bad5bbc-a4b5-42e1-8823-001014b00003",
  "volumes" : [
    "Volume1"
  ],
  "disks" : [
    "Disk1",
    "Disk2"
  ]
}
ldm> show volume 1bad5bbc-a4b5-42e1-8823-001014b00003 Volume1
{
  "name" : "Volume1",
  "type" : "striped",
  "size" : 3907039232,
  "chunk-size" : 128,
  "hint" : "D:",
  "partitions" : [
    "Disk1-01",
    "Disk2-01"
  ]
}
ldm> show partition 1bad5bbc-a4b5-42e1-8823-001014b00003 Disk1-01
{
  "name" : "Disk1-01",
  "start" : 1985,
  "size" : 1953519616,
  "disk" : "Disk1"
}
ldm> create all
Unable to create volume Volume1 in disk group 1bad5bbc-a4b5-42e1-8823-001014b00003: Disk Disk2 required by striped volume Volume1 is missing
[
]
ldm> scan /dev/sdd*
[
  "1bad5bbc-a4b5-42e1-8823-001014b00003"
]
ldm> create all
[
  "ldm_vol_FOOBAR-Dg0_Volume1"
]
ldm>

The just created device mapper device then can be handled as usual:

# dmsetup ls | grep ldm
ldm_vol_FOOBAR-Dg0_Volume1        (254:4)
# mount /dev/mapper/ldm_vol_FOOBAR-Dg0_Volume1 /mnt/whatever

ldmtool just hit Debian unstable (and I intend to ship the tool with the upcoming version of Grml-Forensic).

Event: OSDC 2013

January 8th, 2013

I’ll be speaker at the Open Source Data Center Conference 2013 in Nuremberg/Germany on 17th and 18th April, talking about Continuous Integration/Delivery in the data-center. I was speaking at OSDC back in 2009 and very much enjoyed the conference – so I’m totally looking forward to OSDC 2013, hope to see you there!

Revisiting 2012

January 1st, 2013

2012 was a very special year for me, so it’s worth some words.

In April the Grazer Linuxtage event took place, being one of the major IT events in Austria nowadays. I’m one of its original founders and after being part of the main organisation team for ten times I decided to leave the organisation team. I’m looking forward to enjoying the event in 2013 as visitor, I’m sure the organisation team will provide an absolutely rocking event.

In August I officially launched the jenkins-debian-glue project. It turned out to have been worth all the effort to go public with it. I received plenty of feedback and people are hacking on such great things nowadays that I have to find some time soon to bring those nifty new features people came up with back into my mainline.

In December my wife and me moved to our new place, being a house we bought in Graz. I’m very happy that everything worked out as planned. Thanks to wonderful friends we managed to reach a very pleasing state of our new place within just a few weeks. Once again many many thanks (you know who I mean)!

Throughout the whole year I’ve had several challenging IT consulting gigs in and outside of Austria as well as interesting forensic investigations. Sadly most of them are settled under NDA. That’s still something I can’t get really used to as being someone who likes to share and talk about my work with similarly minded people.

The year ended with a real-life fork, being such a wonderful experience that I still can’t believe that it’s true.

Thanks 2012, totally looking forward to 2013!

fork()

December 31st, 2012

On 31st of December 2012 my lovely wife has made ​​me the gift of my life: welcome to the world, Verena.

Neue Anschrift

December 11th, 2012

Rund 4,5 Jahre später ist es nochmals soweit: ich bin gesiedelt, wieder innerhalb von Graz, diesmal in etwas (zumindest geplant) langlebigeres. Die neue Adresse findet man wie üblich im Whois-Record meiner Domains.

October 2012: recordings from several IT conferences available

October 13th, 2012

In the last few days several IT events published recordings/slides from their events. I haven’t had the time to take a closer look at the material yet but there might be some gems among them so I thought it’s worth spreading the word:

Jenkins: marking an upstream job as failed if its downstream job fails

October 4th, 2012

Since I’m not aware of a ready-to-go solution, this issue once again came up at a company where I’m doing Jenkins/CI consulting for and the solution involves some trickiness you need to be aware of I’m hereby documenting it.

If you have a build pipeline inside your Jenkins setup you might have so called upstream jobs which trigger downstream jobs. If such a downstream job fails you might want to set the build state of the upstream job to “failure” as well.

First of all install the Groovy Postbuild Plugin as well as the Copy Artifact Plugin. (The Copy Artifact Plugin is not strictly needed, you can also choose a different approach for artifact handling, but the plugin works very well for me.)

In the upstream job you have to archive artifacts. Otherwise the script that we will use in the downstream job doesn’t have a connection to the upstream job through the getUpstreamBuilds() method. If you don’t have any artifacts then just create a simple textfile and use that as artfifact file. After the artifact step you can place the trigger for the downstream job. This is the relevant part for a working sample configuration for such an upstream job:

Screenshot Jenkins upstream job configuration

In the downstream job make sure to grab the artifacts from the upstream job. Then use build steps or whatever you need as usual. This is the relevant part for a working sample configuration for such a downstream job:

Screenshot Jenkins downstream job configuration

Finally use the following Groovy script as the Groovy Postbuild action:

upstreamBuilds = manager.build.getUpstreamBuilds();

if(!upstreamBuilds) {
  manager.listener.logger.println("Error: could not identify upstream build");
} else {
  upstreamJob = upstreamBuilds.keySet().iterator().next();
  lastUpstreamBuild = upstreamJob.getLastBuild();
  buildResult = manager.build.result;

  if(lastUpstreamBuild.getResult().isBetterThan(buildResult)) {
    manager.listener.logger.println("Adjusting build state of upstream job to build result of this job, being " + buildResult);
    lastUpstreamBuild.setResult(buildResult);
  }
}

That’s it. Now every time your downstream job fails it should set the according upstream job to “failure” as well.

How geeks celebrate a birthday AKA bin2dec

August 30th, 2012

Far away from Rosetta Code, but that’s what Frank and I came up with when explaining 100000₂:

Guile:

guile <<< \#b100000
guile -c '((@@ (ice-9 format) format) #t "~d~%" #b100000)'

Racket:

racket -e '#b100000'

Ruby:

ruby -e 'puts "100000".to_i(2)'

Python:

python -c 'print int("100000", 2)'

Perl:

perl -e 'print 0b100000'

Zsh:

zsh -c 'print $((2#100000))'
zsh -c 'print $((2#1<<5))'

bc:

echo "ibase=2; 100000" | bc

Clojure:

clojure -e '2r100000'

Scala:

scala -e 'Console.println(Integer.parseInt("100000", 2))'

Octave:

octave -q --eval 'bin2dec("100000")'

AWK:

echo 100000 | awk '{r=0;for(i=1;i<=length;i++){r*=2;r+=(substr($0,i,1)!="0")} print r}'

C:

tcc -run - <<< $'#include <stdlib.h>\nint main() { printf ("%d\\n", strtol("100000", NULL, 2)); return 0;}'

Haskell:

runhaskell <<< 'import Data.Char; main = putStrLn $ show $ foldl1 ((+) . (*2)) $ map (digitToInt) "100000"'

CLISP:

clisp -q -x '#b100000'

100000₂

August 29th, 2012

jenkins-debian-glue: Continuous Integration for Debian and Ubuntu made easy

August 27th, 2012

jenkins-debian-glue is an open source project of mine which recently celebrated its first birthday and it’s time to finally write about it.

jenkins-debian-glue allows you to build Debian and Ubuntu packages directly from the Jenkins continuous integration system. It retrieves package sources from a version control repository, adjusts debian/changelog (handle version number + mention changes that took place) and builds according source and binary packages out of it. Its lintitan integration provides Q/A reports about the resulting source and binary Debian packages.

It started as a small pet project of mine to get integration of Debian packaging inside Jenkins. I mainly had the needs for the Grml project in mind and starting with Grml 2011.12 every release (including also all the daily builds) was built using Jenkins since then. It turned out that my project would also be a perfect match for one of my customers, Sipwise GmbH. In December 2011 the sip:provider 2.4 was the first stable release that was built 100% through Jenkins and featuring jenkins-debian-glue.

Thanks to special needs and the open source friendliness of Sipwise I could invest further time into the project. Recently the project got even some further drive thanks to interest by some fellow Debian Developers, most notably are the icinga, nagios-plugins,… packages and the PostgreSQL in Debian Hackathon.

Now if you’re also interested in it: there’s an automated deployment procedure available for your service to get started with the whole jenkins-debian-glue and Jenkins stack in less than 10 minutes, working just fine on Debian as well as Ubuntu.

For further details please head over to jenkins-debian-glue.org or check out this 6:36min screencast (safe for work, no audio :)):

This embedded video doesn’t work for you? Try heading over to YouTube.

Kritik: 123gold / Trauring-Lounge Graz

May 6th, 2012

So, dieser Blogartikel gurkt schon ewig in den Entwürfen rum, also endlich mal raus damit…

Die “123gold Trauring-Lounge Graz” hat am 1. März 2011 ihr Geschäft eröffnet. Das kam gerade recht für das Event des Jahres und so haben meine Liebste und ich uns dort nach einem passenden Paar Trauringe umgesehen. Die Verkäuferin Frau S. wirkte nervös und chaotisch aber freundlich und bemüht, so haben wir die etwas chaotische Beratung in Kauf genommen.

Unsere gewünschten Ringe wurde bestellt und waren rechtzeitig für das Event zur Abholung bereit. Die Ringe waren ein wenig zu groß, aber da uns versprochen wurde, dass eine Verkleinerung des Ringes für 25€ möglich ist und wir uns ob der Größe einfach unsicher waren, war uns das in dem Moment egal. Marianne war der Ring schließlich für den Alltagsgebrauch ganz klar zu groß und daher hat sie sich nach der Hochzeit auf den Weg in das Geschäft gemacht. Doch auf einmal hieß es, dass die Verkleinerung in ihrem Fall doch mehr kostet als angekündigt, weil wegen des eingesetzten Diamantes der Ring neu eingeschmolzen werden muss. Sie ging zur Konkurrenz ums Eck – dem Juwelierladen Weikhart – und dort wurde ihr gesagt, dass der Ring ganz klar um 2 Nummern zu groß ist, aber die Anpassung leider nicht von Weikhart durchgeführt werden kann, da der Diamant-Einsatz eine spezielle Behandlung durch den Hersteller/Produzenten benötigt. Marianne hat in den sauren Apfel gebissen und sich den Ring bei der Trauring-Lounge kleiner machen lassen.

Auch mein Ring war zu groß, besonders bei kalten Fingern war es störend. Ich habe aber erst später den Weg in die Trauring-Lounge geschafft. Unsere damalige Verkäuferin war dann leider nicht mehr anzutreffen. Der erste Hammer kommt aber sofort: die Verkäuferin gibt mir falsche Modellringe zum Probieren in die Hand, denn innen sind diese komplett anders geformt als mein Exemplar. Das ist genau das, was sich im Nachhinein als der Grund für die falschen Ringgrößen herausstellte. Nach meinem diesbezüglichen Hinweis habe ich dann zwischen zwei Modellen der richtigen Passform entscheiden müssen. Die Variante die zwei Nummern kleiner war als mein Ring kam mir eine Spur zu klein vor, die größere Variante wiederum kam mir zu locker vor. Die Dame konnte mir aber meine Entscheidung nicht leichter machen (im Gegenteil, mit dem Hinweis auf die Option einer Zwischengröße hat sie mich noch weiter verunsichert). So habe ich mich erst mal nach den Kosten für die Anpassung erkundigt. Nach meinem Hinweis darauf, dass wir bereits ursprünglich beim Kauf schlecht beraten wurden – denn auch damals bekamen wir nicht die zu unserem Modell passenden Proberinge zum Probieren – bot mir die Verkäuferin einen Preisnachlass um 10€ an. Doch sollte es jetzt statt der ursprünglich versprochenen 25€ auf einmal 35€ pro verkleinerter Größe – sprich 70€ für 2 Größen kleiner – kosten. Die 60€ empfand ich als Hohn und als letztes Angebot wurde mir noch eine Anpassung um 35€ angeboten. Daraufhin habe ich den Laden verlassen um mir in einem anderen Juwelierladen ein Angebot einzuholen.

Im Juwelierladen Weikhart gleich auf der anderen Seite vom Hauptplatz habe ich daraufhin die Situation geschildert und bekam eine äußerst kompetente und freundliche Beratung. Im Vergleich zur Trauring-Lounge wurde mir die Entscheidung für die Größenwahl leicht gemacht, denn die Verkäuferin hat mir den Ring – ganz im Gegensatz zur Konkurrenz – nicht nur auf den Finger gesteckt, sondern auch “herumprobiert”. Es wäre eine ganz klare Angelegenheit: 2 Nummern zu groß. Aufgrund einer ungewöhnlichen Legierungsart wurde auch sofort Rücksprache mit dem Goldschmied gehalten, ob die Änderung denn auch möglich sei. Ich könnte den Ring am nächsten Tag abholen, da der Aufwand aber aufgrund der ungewöhnlichen Legierung noch nicht abschätzbar sei können sie mir noch nicht garantieren, wie viel es ausmachen würde. Als Preisbereich wurden 10 bis 25€ genannt. Für mich war die Entscheidung damit natürlich eine klare Sache. Keine vier Stunden später erhalte ich bereits den Anruf, dass ab sofort mein Ring abgeholt werden kann. Das habe ich dann auch getan, und gezahlt habe ich dafür 10(!) Euro.

Der direkte Vergleich der Beratung war wie Tag zu Nacht, von den Kosten ganz abgesehen. Da man Trauringe üblicherweise nur einmal im Leben kauft können wir unsere Geschichte nur teilen, was hiermit getan sei. Unser Fazit und was ihr daher bitte wissen und weitererzählen sollt:

tl;dr: Finger weg von der 123gold / Trauring-Lounge Graz

Grazer Linuxtage 2012: Call for Lectures

January 23rd, 2012

Am Samstag, dem 28. April finden heuer wieder die Grazer Linuxtage statt!

Die Suche nach Vorträgen und Projektständen wurde soeben offiziell eröffnet. Wenn du ein spannendes Thema oder Projekt hast, über das du vor einem interessierten Publikum reden möchtest ist das deine Chance. :)

Die Grazer Linuxtage feiern heuer ihren 10. Geburtstag(!) und wir erwarten auch diesmal wieder mehr als 500 Besucher auf einem der größten IT-Events in Österreich.

Disclaimer: Die Grazer Linuxtage sind für ein buntgemischtes Thema bekannt. Wir beschränken uns aber weder auf Linux, noch mußt du dir ein supertechnisches Thema aussuchen. Von Anwendersoftware und Projektvorstellungen, über Themen für Systemadministratoren und Softwareentwickler, bis hin zu freier Kultur und Technik ist alles mit dabei. Ganz besonders freuen wir uns über Vorträge für Einsteiger (du musst definitiv kein Superduperüberdrüber-Geek sein um bei uns vorzutragen – weder wir noch unser Publikum beißen!).

Wir freuen uns über deine Vortrags- und/oder Projektstand-Einreichung über Linuxtage.at.