Disk Change @ Hetzner

1. Get serial of defective disk

# for i in a b; \
 do echo $i ; smartctl -i /dev/sd$i | grep -i serial ;\
done

The disk not returning a serial is most likely the defective one.

2. Create a Ticket @ Hetzner Robot

Log in to the Hetzner Robot and create a Ticket: Left menu:

Anfragen -> Serverprobleme ausklappen -> Festplatte defekt

If the serial of the defective drive can’t be obtained, enter the serial of the working one and stress that the said serial is the working drive. Otherwise they’ll swap the wrong one and you end up with nothing!

3. Copy partition table

Once the drive is replaced, copy the partition table from the working drive to the new one. sgdisk comes to rescue (THINK BEFORE YOU COPY & PASTE, WON’T WORK ANYWAY):

# sgdisk -R=/dev/sd[new] /dev/sd[old]

In doubt, RTFM twice: man sgdisk

4. Resync the RAID

mdadm comes to rescue:

# mdadm --manage /dev/md0 --add /dev/sd[new][part]

If you can’t get the former command to work, again: RTFM! It’s your data!

5. Stare at the progress

# watch cat /proc/mdstat

6. Be delighted!

Restart KDE

When plasmashell crashes, restart it like this without logging out:

$ kquitapp plasmashell ; sleep 3 ; plasmashell --shut-up &

If that doesn’t work, kill the process plasmashell with SIGKILL.

If KWin doesn’t work any more, restart it with:

$ kwin_x11 --replace 2>&1 > /dev/null &

 

Check_MK: Send notifications to contact group

This is kinda convoluted and not very intuitive.

  1. Create a contact group: WATO → Contact Groups → New Contact group
  2. Create a User with the E-Mail-Address you want the notifications sent to: WATO → Users → New Users and add him to the contact group! The tab may be collapsed by default, so it’s easily overlooked. It’s the third panel from the top, right under “Security”
  3. Create a notification rule: WATO → Notifications → New Rule. Then add the newly created contact group. Expand the tab “Contact Selection” and check “The members of certain contact group”. Next, click “Add Element” and select the newly created contact group.
  4. Save and activate changes.

Custom Checks with check_mk_agent

1. Install xinetd and check_mk_agent

Install xinetd first. The check_mk_agent package drops a configuration snippet into /etc/xinetd.d/, which makes xinetd listen on port 6556 for the agent.

2. Write the custom check (Service to check)

The server-side check can be written in any language, as long as it can print to STDOUT. The output format is quite simple:

<<<check_name>>>
data1 data2 ... dataN
data1 data2 ... dataN
...

check_name is the identifier. It can be anything, but it has to be enclosed in <<<>>>. Data[1-] are the things you want to check, including performance counters, anything you like. Server-side the data will be split at white-spaces.

Simple example: check if bacula-director and bacula-storage-daemon is running (in perl):

#!/usr/bin/perl -w 
 
use strict; 
 
my @instances = `ps o cmd ax`; 
my %count; 
foreach my $i (@instances){ 
        if($i =~ m#bacula-sd#){ 
                $count{"storage_daemon"}++; 
        } 
        if($i =~ m#bacula-dir#){ 
                $count{"director"}++; 
        } 
} 
 
print "<<<bacula_system>>>\n"; 
foreach my $k (keys %count){ 
        print "$k $count{$k}\n"; 
}

Output:

<<<bacula_system>>> 
storage_daemon 1 
director 1

One storage daemon process and one director process running. Perfect! Drop this script in /usr/lib/check_mk/plugins and make it executable.

3. The check_mk-Server-Part

Now we have to create the server-side counterpart. This has to be in python, because check_mk uses introspection extensively. Create a script named exactly as the identifier in local/share/check_mk/checks starting in the home directory of your check_mk-site-user. In the example given: local/share/check_mk/checks/bacula_system

The first thing we need is the dictionary check_info[] with at least these entries:

  • check_function: Name of the function actually performing the check
  • inventory_function: Name of the inventory function (called by WATO, the Web Administration)
  • service_description: Name of the service, can be a format string

Example:

#!/usr/bin/python 
 
def inventory_bacula_instances(info): 
    inventory = [] 
    inventory.append( ("storage_daemon", None) ) 
    inventory.append( ("director", None) ) 
    return inventory 
 
def check_bacula_instances(item, params, info): 
    count = 0 
    for each in info: 
        if each[0] == item: 
            count = int(each[1]) 
 
    retval = 3 
    perfdata = [ (item, count) ] 
    if count == 0: 
       retstring = "No instance found for %s" % item 
       return (2, retstring, perfdata) 
    else: 
        retstring = "%d instances found for %s" % (int(count), item) 
        return (0, retstring, perfdata) 
 
    return (3, "Checking %s failed" % item, perfdata) 
 
check_info["bacula_system"] = { 
    "check_function":       check_bacula_instances, 
    "inventory_function":   inventory_bacula_instances, 
    "service_description":  'Bacula: %s', 
    "has_perfdata":         True, 
}

3. The inventory function

The inventory function returns an array of Tuples with the items to check, in our case the items storage_daemon and directory returned by our perl script. The Tuples are fed to the check_function, in our case check_bacula_instances(item, params, info).

4. The check_function

The check_function does the actual work. The return values are:

  • 0: OK
  • 1: Warning
  • 2: Critical
  • 3: Unknown

The parameters:

  • item: The name of the item to check, i. e. the first item of the Tuple returned by the inventory_function. In our case “storage_daemon” or “director”
  • params: no idea (TODO)
  • info: a dictionary as key and an array with the values returned from the server-side script. In the example given something like this:
{'director': ['director', 1], 'storage_daemon': ['storage_daemon', 1]}

So info[‘director’][1] gives you the count of director processes.

5. Configure the check

  1. Login to WATO, click WATO-Configuration->Hosts->New Host.
  2. Enter hostname
  3. Click Save & Test, check that the agent is available
  4. Click Save & Exit
  5. Click Save & go to Services
  6. Save and activate the new configuration
  7. Have FUN!

6. Debugging

Sprinkle the python script with “print <somethingorother>” and call

$ cmk <hostname>

from the command line.

Ich habe fertig 🙂

 

 

Convert 1080 Bluray-Rip DTS to 720p-AC3

1. Convert video:

ffmpeg -i <infile> \
 -an -sn \
 -preset slow \
 -tune film \
 -s hd720 \
 -c:v libx264 -threads 0 \
 -x264opts fast_pskip=0 \
 -b:v 4300k \
 -minrate 4000k \
 -maxrate 4400k \
 <outfile.mkv>

Minimum bitrate 4000kb/s, maximum 4400kb/s, average 4300kb/s.

2. Convert audio:

ffmpeg -i <infile> \
 -vn -sn \
 -acodec ac3 \
 <outfile.ac3>

3. Extract subs:

mkvextract tracks <infile> <trno>:<outfile>

Convert it to SRT with Subtitle Edit

4. Merge it:

mkvmerge <outfile_from_1> <outfile_from_2> <outfile_from_3> \
 -o <final_out.mkv>

That’s it!

Installation SSD

On May 27, 2015, I replaced the system raid of hadante (4 spinning 500 GB disks, RAID5) with 4 Samsung SSD drives (also 500 GB, RAID5). It was well worth it. The speed is amazing!

Along with the disks I ordered 4 3.5″ -> 2.5″ installation frames. As it turned out I only needed two, because you can easily stack two SSD drives on one frame with the right frame. There even is a gap in between, so I don’t expect heat problems.

The RAID5-rebuild was blazing fast. Overall, everything seems to be much snappier.

The serial numbers – SSD drives from top to bottom:

  1. S21JNXAG415926
  2. S21JNXAG415880
  3. S21JNXAG433264
  4. S21JNXAG433168

The old serial numbers – spinning drives from top to bottom:

  1. S13TJ1EQ401080 (Samsung)
  2. 5VMJ32Q9 (Seagate)
  3. 3PM23C12 (Seagate)
  4. S13TJ1EQ401081 (Samsung)

 

flac + cue to mp3

To convert a single flac file with a cue sheet to mp3, first split it up:

$ shnsplit -f <sheet.cue> <source.flac>

Then convert the wav-files to mp3 with ffmpeg:

for i in *.wav ; do ffmpeg -i ${i} -codec:a libmp3lame -qscale:a 2 ${i%%wav}mp3 ; done

Or, if you have individual flac files:

for i in *.flac; do ffmpeg -i ${i} -codec:a libmp3lame -qscale:a 2 ${i%%flac}mp3 ; done

qscale:a 2 produces mp3s with an average bitrate around 170-210 kbit/s. It should be close to lossless.

Upgrade Mailscanner

The easy part:

  • Download the tarball from the official website
  • Unpack to somewhere
  • execute <unpack-dir>/install.sh

The hard part:

Do not agree to install the missing perl modules from CPAN! Install them via the package manager. If almost every module is missing, perldoc is not installed. Debian is especially nasty here. They have a perldoc executable, even if it isn’t installed, and it only prints “the package perl-doc is not installed” or something and instructions how to install it.

Unfortunately the installer uses perldoc to figure out which modules are missing, so when it calls the stub everything is missing…

If there is a version mismatch, check if you have a CPAN-Version installed in /usr/local/<something>.

# perl -V

shows @INC at the bottom. Remove the offending package and install it via your favorite package manager.

The config part:

Generate a new config in the new etc-Directory as described in the docs. If you’re using MailWatch, don’t forget to copy

lib/MailScanner/CustomFunctions/MailWatch.pm

to the new directory. Stop mailscanner, link the new version to /opt/MailScanner or something and start it. You applaud 🙂

 

Upgrade wheezy to jessie

All in all, it was easy. Just one big caveat regarding apache2. Can’t say if it was PEBKAC any more. But read below.

1. Check for obsolete packages

As stated in the official Upgrade Guide: Do an audit!

# dpkg --audit

Really, do it! And fix the non-compliant packages.

2. Install the Distribution Kernel

Again, really do it. Otherwise the dist-upgrade will fail on udev, if your custom kernel doesn’t have CONFIG_SIGNALFD, CONFIG_FHANDLE and whatnot built in. You can override it, but then it won’t boot. So better be safe.

3. Update and dist-upgrade

Change /etc/apt/sources.list to use jessie. Then

# apt-get update
# apt-get dist-upgrade

Carefully watch for configfile-conflicts. Esp. Apache and cyrus! Keep the config for:

  • /etc/cyrus.conf
  • /etc/imapd.conf

Don’t overwrite them! We’ll fix them later!

4. Reboot

Reboot into the new system, get systemd running. Again, don’t even think to go on without a reboot

5. Fix cyrus and postfix

The command for cyr_* has changed. Now it’s so cyrus <*>, so move the old config out of the way and replace it with .dpkg-dist. Then diff it and change the relevant line(s). That would be especially:

lmtpunix cmd="lmtpd" \
   listen="/var/spool/postfix/cyrus-socket/lmtp" \
   prefork=0 maxchild=20

with

lmtp cmd="lmtpd -a" listen="localhost:lmtp" prefork=0 maxchild=20

So don’t listen on an AF_UNIX socket any more but on a network socket. For this to work you need to add this line to /etc/services:

lmtp        24/tcp

LMTP doesn’t seem to be a well known port, whatever…

Now for postfix: Change /etc/postfix/main.cf accordingly:

mailbox_transport = lmtp:inet:localhost

I.e. listen on a network socket instead of AF_UNIX. This way you don’t have to bother with permissions on the socket file, and it’s IPv6-enabled as a bonus 🙂

6. Fix apache2

Make sure all your files in sites-available end in *.conf! Otherwise they won’t be loaded! I learned the hard way, wondering why SSL-Connections failed because there was no SSL. Check what VHosts are loaded with:

# apache2ctl -t -D DUMP_VHOSTS

If that shows no Vhosts, you don’t have any! Fix it. BTW, NameVirtualHost is obsolete. Remove it. So seems to be gnutls…

Create an IPv6-enabled-VHost like this:

<VirtualHost _default_:443>
...
</VirtualHost>