Saturday, January 3, 2015

Selectively change DNS servers for Netflix with dnsmasq

I recently started using OpenDNS name servers at home to provide some basic content filtering.

We also use Netflix on various devices. Configuring these devices to use custom name servers, we are able to access the US Netflix. But that customization bypasses OpenDNS. Also, it needs to be enabled on each device.

I wanted to find a way to use OpenDNS name servers - preserving content filtering - by default and using the custom name servers for Netflix only. Also nice if the configuration can be done in one place rather than on each device.

It looks like dnsmasq works well for this.

I run dnsmasq on my linux server (Ubuntu 10.04) and point my router (TP-Link Archer D7 AC1750) to use that as the DNS server for DHCP.

(Note "for DHCP" - this was the key. When I tried first setting my dnsmasq server as the router's WAN DNS server, this did not work - browsing any internet page failed on hostname resolution. It needed to be set as the router's DHCP DNS server.)

On the linux server... 

I installed dnsmasq and configured it to do DNS only (not DHCP, I left that to the router).

sudo apt-get install dnsmasq
sudo cp -p /etc/dnsmasq.conf /etc/dnsmasq.conf.0

/etc/dnsmasq.conf

domain-needed
bogus-priv
# not looking in /etc/resolv.conf
no-resolv
# opendns servers are the defaults
server=208.67.222.222
server=208.67.220.220
# nameservers for netflix
# replace x.x.x.x with working primary and secondary servers for US netflix
server=/netflix.com/netflix.net/nflximg.com/x.x.x.x
server=/netflix.com/netflix.net/nflximg.com/x.x.x.x
cache-size=5000
# see what it's doing in /var/log/daemon.log (probably disable this after)
log-queries

Restart the service

sudo service dnsmasq restart

See what it's doing

tail -f /var/log/daemon.log

On the router...

In the WAN configuration, leave OpenDNS name servers configured.

In the DHCP configuration
  • set the IP address of the linux server as the primary name server
  • set the IP address of the router as the secondary (backup if the linux server goes down).

Testing

While testing on Windows, I renewed and flushed ipconfig after each change in the DNS configuration:

ipconfig /renew
ipconfig /flushdns

On the linux box, tail /var/log/daemon.log to confirm that dnsmasq is getting used and what it is doing.

In a browser, try http://www.netflix.com in a new browser window. If it redirects to http://www.netflix.com/us then things are working.

Result

Now each device connecting to the router with DHCP is given the dnsmasq on the linux server as its primary DNS server, and the router - configured for OpenDNS - as the fall back name server.

Netflix USA is served by default to all devices. If I want a device to use the default Netflix for our region, I can change the nameservers on the device to use my router's IP address (so falling back to OpenDNS servers).

In all cases, we are using OpenDNS for everything apart from the Netflix domains, so general content filtering is preserved.

And as a bonus, any host defined in /etc/hosts on the dnsmasq linux server becomes available by name to all DHCP hosts in the network. So I can address a couple of services (logitech media server, plex, ...) running on different boxes by name rather than by IP address.

References

http://www.ireckon.net/2014/05/use-getflix-or-unblock-us-servers-selectively-with-dnsmasq
https://getflix.zendesk.com/hc/en-gb/articles/201056954-Can-I-selectively-use-Getflix-DNS-servers-for-specific-domains-
http://www.raspberrypi.org/forums/viewtopic.php?t=46154
http://www.linux.com/learn/tutorials/516220-dnsmasq-for-easy-lan-name-services


Tuesday, December 23, 2014

Devolo dLAN 200 AV Windows 8

I have a pair of Devolo dLAN 200 AV powerline adapters which I haven't used in ages.

I found that the configuration software which came on a CD with the adapters is incompatible with Windows 8 and the product itself is out of production.

After messing around unsuccessfully with the old software in a Windows XP VM in VirtualBox, what eventually worked was much simpler. With a firmware upgrade on the adapters and a newer configuration utility which installs on Windows 8, I was able to configure the adapters to talk to each other.
  • Download the last available firmware for the dLAN 200 AV powerline from the Devolo site: http://www.devolo.com/en/Downloads/dLAN-200-AV
  • With a powerline adapter directly connected to the PC, double click the firmware exe. It launches and installs the firmware successfully.
  • Repeat for the other adapter(s).
  • Download and install the dLAN Cockpit utility from the Devolo site: http://www.devolo.com/en/Downloads/dLAN-200-AV-Wireless-N
  • Connect one adapter direct to the Windows PC, the other to the router.
  • Launch the Cockpit utility
  • Click Options and select Reset network to factory defaults
  • Click Add adapter and enter the security ID of the adapter connected to the router

After a short wait, the second adapter appeared in the Cockpit UI showing connected.


Saturday, October 31, 2009

abcde: CDROM has not been defined or cannot be found

Back to auto CD ripping again after a bit of a break, caused by the power supply of my USB-IDE cable set packing in. This is how I connect a CD drive to my fitPC, so it was a bit of a set back. The ebay vendor kindly sent me a replacement cable set, so I'm back in business.

But when I fed a new music CD to the drive, it didn't rip. On investigation, I found
abcde: CDROM has not been defined or cannot be found
Two useful threads I found were http://ubuntuforums.org/showthread.php?p=7849371 and http://ubuntuforums.org/showthread.php?p=7622858.

I found that for some reason, instead of /dev/cdrom I only had /dev/cdrom2. Editing /etc/abcde.conf, I defined CDROM=/dev/cdrom2. That fixed the problem for abcde.

The second thread showed how to get my CDROM drive at /dev/cdrom again. Following funkydan2's lead I moved /etc/udev/rules.d/70-persistant-cd.rules to one side and rebooted. The file was regenerated and /dev/cdrom reappeared.

That done, I reverted /etc/abcde.conf, commenting out the CDROM=/dev/cdrom2 line.

Saturday, September 12, 2009

Sync files to an mp3 player with WinMerge

To sync files between my PC and my mp3 player, I'm finding WinMerge to be a fast, lightweight solution.

This is a bit geeky, because WinMerge is generally a programmer's tool. Typically you open two different versions of a file or folder in WinMerge; it shows the differences in a left/right view, and lets you copy differences from one side to the other.

But that's exactly what you need to selectively sync a music collection from one place to another, like to an mp3 player.

What I do is to open my music collection folder (on my PC) and my mp3 player's music folder in WinMerge. It quickly scans for differences, then shows me
  • which folders and files are on left or right only (e.g. not on the mp3 player).
  • which folders and files are different (e.g. different folder contents or different file size)
  • which files and folders are identical (i.e. in sync)
Then it's easy to select files to copy to the mp3 player.

Because I'm a geek, I store my music collection on a mini Linux file server and access it using Samba over a wireless network. You do not have to do this! But just for interest, in this environment and using the setup below, WinMerge generates the diff view of my collection of around 5,000 tracks in about 3 seconds. Of course it will work just the same but faster with files stored on your PC.

The following instructions assume you have installed and launched WinMerge and have your mass storage class mp3 player connected to your PC. My player is a Sansa Clip.

1. Configure WinMerge to do fast scans of your music collection

Edit -> Options



Select the Compare category
Tick Ignore time differences less than 3 seconds
File Compare Method: Modified Date and Size

Changing the file compare method from Full Contents to Modified Date and Size is key to achieving fast scan times. You don't need a byte by byte comparison to sync your mp3s. Date and filesize comparison is fast and all you need.

2. Open your music collection and your mp3 player in WinMerge

In Select Files or Folders Dialog



Left: select music folder on your PC
Right: select music folder on your mp3 player
Filter: *.mp3
Tick Include Subfolders
Click OK

3. Customize the view

You will want an Explorer tree view: View -> Tree mode

It can be handy to show file size differences:

Tools -> Customize Columns
Add left size and right size

4. Save all this as a WinMerge project

File -> Save Project



On this page you also have option to make one side read only. This is handy if you want to protect your music collection and only copy files in one direction - to your mp3 player.

Next time you want to sync files, just open the project. All your configuration steps are saved.


5. Start syncing

WinMerge is now showing your music collection in an Explorer tree view. Different icons in the tree clearly show you which folders and files are
  • on left only (i.e. not on mp3 player):

  • on right only (i.e. only on mp3 player)
  • identical:

  • or different (e.g. different folder contents, different file size)
To copy from PC to mp3 player, select the files or folders to copy, then

Right click the folder or file/s
Copy -> Left to Right

... or just hit the "Copy right" icon in the toolbar:




To check result of the merge, click refresh.

Sin é.

Thursday, June 4, 2009

Auto rip audio CDs in Ubuntu Server

I got my headless Linux server set up to auto rip music CDs and add them to my music library. Pop a CD in the tray and it automatically rips and tags the tracks to FLAC files and ejects the CD... and queues up a task to transcode to mp3 and then rescan my Squeezecenter library later. Here's how:

* Detection of the audio CD and kicking stuff off is done by ivman.
* Ripping and tagging is done by abcde.
* Transcoding is done by flac2mp3.
* Refreshing the library is done using the Squeezecenter CLI.

It took me "a while" to get it working end to end. The tough part was getting ivman configured. But that's the essential part for automation.

Ivman

To install
$ sudo apt-get install ivman
which installs a bunch of dependencies (but no X). Then I enabled an action to start a script when ivman detects an audio CD. This is what I added to /etc/ivman/IvmConfigActions.xml:
<ivm:Match name="hal.volume.disc.type" value="cd_rom">
<ivm:Match name="hal.volume.disc.has_audio" value="true">
<ivm:Match name="hal.volume.disc.has_data" value="false">
<ivm:Option name="exec" value="/home/user_x/bin/rip_cd '$hal.block.device$'"/>
</ivm:Match>
</ivm:Match>
</ivm:Match>
The rip_cd script just invokes abcde and directs its output to a log file.

The problem that broke my heart for ages was that ivman didn't have permission to use the cdrom drive. I got this error in the log file from abcde:
cd-discid: /dev/cdrom: open: Permission denied
[ERROR] abcde: CD could not be read. Perhaps there's no CD in the drive?
No such problem running abcde directly from the command line as the same user ivman ran as, since that user is a member of the group "cdrom".

How I eventually got it working consistently was to configure ivman to run explicitly as the group "cdrom".

Ivman requires you to specify both a user and a group for the daemon to run as - in /etc/ivman/IvmConfigBase.xml). Just because the user you specify is a member of a group, e.g. cdrom, doesn't mean that ivman will run as a member of that group.

In my setup, ivman is now solely configured from /etc/ivman and runs as "user_x" and group "cdrom". And abcde is solely configured from /etc/abcde.conf.

It can help to run ivman in debug mode:
$ sudo /etc/init.d/ivman stop
$ sudo ivman -d --nofork

ABCDE

To install
$ sudo apt-get install abcde
This also installs cd-discid and probably cdparanoia (which I had installed already). Getting abcde configured is easy, especially thanks to a great guide on Andrew's Corner.

I included a post-read hook in /etc/abcde.conf to enqueue a transcoding script when the CD is ripped.
post_read ()
{
atq -q x | while read line; do job=`echo $line | sed -e 's/\([0123456789]*\).*/\1/'`; atrm $job; done
at -q x 01:00AM -f /home/user_x/bin/flac2mp3
}
It would probably be better just to run the transcoding script as a cron job rather than "on demand". But this way works too.

The flac2mp3 script invokes Robin Bowes' flac2mp3, directing its output to a log file, and then invokes the Squeezecenter CLI to rescan the music library.

Of course, abcde would happily take care of ripping to FLAC and mp3 at the same time. But I prefer to rip to FLAC and transcode from there. That way, if I need to change tags, I just update the FLACs and run flac2mp3 to update the tags in my mp3s.

Squeezecenter CLI

Squeezecenter has a telnet-based command line interface. One of the things it supports is executing a rescan of the library. So I included the scriptlet below in my transcoding script, after transcoding completes:
echo `date` "requesting squeezecenter rescan..." >> $log
(
sleep 1;
/bin/echo -e "rescan\r";
sleep 1;
/bin/echo -e "exit\r";
sleep 1;
) | telnet localhost 9090 >> $log 2>&1
echo `date` "telnet exit status: " $? >> $log
Directing the output to a file was useful here (again). It helped me diagnose a problem when the "wrong" version of echo got used when the script was run from the at task, causing the telnet to fail. The fix was to use /bin/echo explicitly.

Of course, I could just let Squeezecenter schedule a regular rescan of the music library instead of doing it on demand. But I wanted to give the CLI a try.

Anyway, that's about it.

Just a note on hardware. I'm still using the fit-PC slim as my server. It doesn't have a CD drive. I connect the internal DVD burner from my old PC through a cheapo IDE-USB adapter cable from ebay.

Saturday, February 28, 2009

Installing mediainfo on Ubuntu

There's no single ready made package for mediainfo as far as I can see, so no apt-get install, but the required .deb packages are available and so can be installed using dpkg.

Pick the appropriate packages for your system from the mediainfo sourceforge download page, then install in the correct order using dpkg -i.

To install the CLI version on my fit-pc Ubuntu 8.10 server, I did
$ wget http://downloads.sourceforge.net/mediainfo/mediainfo_0.7.11-1_i386.Debian_5.0.deb
$ wget http://downloads.sourceforge.net/mediainfo/libmediainfo0_0.7.11-1_i386.Debian_5.0.deb
$ wget http://downloads.sourceforge.net/zenlib/libzen0_0.3.8-1_i386.Debian_5.0.deb
$ sudo dpkg -i libzen0_0.3.8-1_i386.Debian_5.0.deb
$ sudo dpkg -i libmediainfo0_0.7.11-1_i386.Debian_5.0.deb
$ sudo dpkg -i mediainfo_0.7.11-1_i386.Debian_5.0.deb
Then it's good to go.

Monday, February 2, 2009

Automount USB disks in Ubuntu Server

I am using the usbmount package to automount a 1TB USB disk connected to my mini linux media server. This allows me to mount and unmount the external disk simply by turning it on and off, which is a convenient and power-saving arrangement.

Since I'm now storing DVD rips for my Popcorn Hour media player, I needed to add more storage to my streaming media server. My fit-PC takes 2.5" IDE/PATA drives, so it is already fully loaded with a 250G drive. So I got a 1TB 3.5" SATA drive (Western Digital GreenPower) and put it in a USB enclosure.

It's a very quiet, low power drive (about 9W generally), but I don't want it on 24/7. Spinning down the disk is one option, and I might investigate that further. But right now I want
  1. To simply switch the disk on when I need it and off when I'm done.
  2. For that to be safe (without potential for losing data).
  3. To include the disk in the network share I export for the Popcorn Hour.
Desktops systems automount USB disks when you plug them in or power them on. This functionality is not available by default in Ubuntu server. (The packages used depend on the desktop environment.) Following a suggestion in the Ubuntu documentation, I installed the usbmount package
This package automatically mounts USB mass storage devices (typically USB pens) when they are plugged in, and unmounts them when they are removed. The mountpoints (/media/usb[0-7] by default), filesystem types to consider, and mount options are configurable. When multiple devices are plugged in, the first available mountpoint is automatically selected. If the device provides a model name, a symbolic link /var/run/usbmount/MODELNAME pointing to the mountpoint is automatically created. [...]
... which sounds ideal. And as far as I can see, it does the job.

I couldn't find much online about how to configure usbmount, but I soon found /etc/usbmount/usbmount.conf. You can configure mount options per filesystem type. The default options are
MOUNTOPTIONS="sync,noexec,nodev,noatime"

Out of the box, it only automounts ext2 and ext3 formatted volumes. I had formatted my new disk with XFS, so I added xfs to the configuration

FILESYSTEMS="ext2 ext3 xfs"

and it seems to work fine. When I switch on the disk, I see these messages in syslog:

kernel: [1034394.920087] usb 1-2: new high speed USB device using ehci_hcd and address 27
kernel: [1034395.064826] usb 1-2: configuration #1 chosen from 1 choice
kernel: [1034395.078845] scsi25 : SCSI emulation for USB Mass Storage devices
kernel: [1034395.085992] usb-storage: device found at 27
kernel: [1034395.086033] usb-storage: waiting for device to settle before scanning
kernel: [1034400.084595] usb-storage: device scan complete
kernel: [1034400.087474] scsi 25:0:0:0: Direct-Access     WDC WD10 EADS-00L5B1      0041 PQ: 0 ANSI: 0
kernel: [1034400.091636] sd 25:0:0:0: [sdb] 1953525168 512-byte hardware sectors (1000205 MB)
kernel: [1034400.094271] sd 25:0:0:0: [sdb] Write Protect is off
kernel: [1034400.094309] sd 25:0:0:0: [sdb] Mode Sense: 03 00 00 00
kernel: [1034400.094328] sd 25:0:0:0: [sdb] Assuming drive cache: write through
kernel: [1034400.104985] sd 25:0:0:0: [sdb] 1953525168 512-byte hardware sectors (1000205 MB)
kernel: [1034400.113058] sd 25:0:0:0: [sdb] Write Protect is off
kernel: [1034400.113094] sd 25:0:0:0: [sdb] Mode Sense: 03 00 00 00
kernel: [1034400.113114] sd 25:0:0:0: [sdb] Assuming drive cache: write through
kernel: [1034400.120193]  sdb: sdb1
kernel: [1034400.137434] sd 25:0:0:0: [sdb] Attached SCSI disk
kernel: [1034400.137980] sd 25:0:0:0: Attached scsi generic sg1 type 0
usbmount[16483]: executing command: mount -txfs -osync,noexec,nodev,noatime /dev/sdb1 /media/usb0
kernel: [1034401.228110] XFS mounting filesystem sdb1
kernel: [1034401.710070] Ending clean XFS mount for filesystem: sdb1
usbmount[16483]: executing command: run-parts /etc/usbmount/mount.d

The disk is mounted:

$ mount
<snip...>
/dev/sdb1 on /media/usb0 type xfs (rw,noexec,nodev,sync,noatime)

And when I switch it off, I see

kernel: [1034259.923629] usb 1-2: USB disconnect, address 26
kernel: [1034259.936251] xfs_force_shutdown(sdb1,0x1) called from line 420 of file /build/buildd/linux-2.6.27/fs/xfs/xfs_rw.c.  Return address = 0xe0a9ddb4
kernel: [1034259.936334] Filesystem "sdb1": I/O Error Detected.  Shutting down filesystem: sdb1
kernel: [1034259.936404] Please umount the filesystem, and rectify the problem(s)
kernel: [1034259.949818] Filesystem "sdb1": xfs_log_force: error 5 returned.
kernel: [1034259.949851] Filesystem "sdb1": xfs_log_force: error 5 returned.
kernel: [1034259.949890] xfs_force_shutdown(sdb1,0x1) called from line 420 of file /build/buildd/linux-2.6.27/fs/xfs/xfs_rw.c.  Return address = 0xe0a9ddb4
kernel: [1034259.968157] Filesystem "sdb1": xfs_log_force: error 5 returned.
usbmount[16307]: executing command: umount -l /media/usb0
kernel: [1034260.050924] Filesystem "sdb1": xfs_log_force: error 5 returned.
kernel: [1034260.057086] Filesystem "sdb1": xfs_log_force: error 5 returned.
kernel: [1034260.061208] xfs_force_shutdown(sdb1,0x1) called from line 420 of file /build/buildd/linux-2.6.27/fs/xfs/xfs_rw.c.  Return address = 0xe0a9ddb4
kernel: [1034260.069650] Filesystem "sdb1": xfs_log_force: error 5 returned.
kernel: [1034260.073675] Filesystem "sdb1": xfs_log_force: error 5 returned.
kernel: [1034260.077672] xfs_force_shutdown(sdb1,0x1) called from line 420 of file /build/buildd/linux-2.6.27/fs/xfs/xfs_rw.c.  Return address = 0xe0a9ddb4
usbmount[16307]: executing command: run-parts /etc/usbmount/umount.d
kernel: [1034260.084706] Filesystem "sdb1": xfs_log_force: error 5 returned.
kernel: [1034260.084735] Filesystem "sdb1": xfs_log_force: error 5 returned.
kernel: [1034260.084820] Filesystem "sdb1": xfs_log_force: error 5 returned.
kernel: [1034260.084864] Filesystem "sdb1": xfs_log_force: error 5 returned.
kernel: [1034260.084891] Filesystem "sdb1": xfs_log_force: error 5 returned.

which doesn't look so great. But after repeatedly mounting and unmounting the disk without any apparent problems, I was getting the feeling that this was not harmful.

I did a bit of searching to see whether XFS supports the sync mount option. The answer wasn't clear, so I raised a question on the XFS mailing list to see what they thought. The initial response was discouraging, but on followup it seems like since...
  • I am sync mounting the filesystem (what usbmount does by default), and

  • my kernel version is later than 2.6.17 (from which point write barrier support is enabled by default in XFS)
... I can keep on doing what I'm doing. I will not get corruption of the file system. (Do read the thread, the XFS FAQ and otherwise satisfy yourself. It's your data.)

The last item on my wish list was to include the disk in the network share I export for the Popcorn Hour. This is easy.

Usbmount mounts the disk to /media/usb[0-7] arbitrarily, but it also creates a symbolic link in /var/run/usbmount using the disk model name, which provides a consistent reference point. I created a link in my media storage directory to that point, e.g.
ln -s /home/shared/movies /var/run/usbmount/WDC_WD10_EADS-00L5B1_1/movies

Using my existing Samba share (/home/shared), this works perfectly. When the disk is on, I can browse into the linked directory from the Popcorn Hour. When the disk is off, the link is invisible.

Friday, January 23, 2009

Installing SwissCenter on Ubuntu Server

I got SwissCenter up and running on my fit-PC Slim, which is now running Ubuntu 8.10 Server.

At first I was working off the official SwissCenter Linux install documentation which is for SuSE 9.3. Later on I found this cheatsheet for installing SwissCenter on Ubuntu which is a bit out of date now, but still very useful.

Install apache2 and mysql

I had these installed already, done in the standard way as in the Ubuntu Server Guide, which is to say
$ sudo apt-get install apache2
$ sudo apt-get install mysql-server
Actually, I had the default mysql instance disabled, so re-enable it now and maybe try converging to a single mysql instance later.
$ cd /etc/rc2.d
$ sudo mv K81mysql S19mysql
$ sudo /etc/init.d/mysql start
Install PHP
$ sudo apt-get install php5 libapache2-mod-php5 php5-mysql php5-gd
Install SwissCenter
$ wget http://www.swisscenter.co.uk/downloads/swisscenter.zip
$ sudo mkdir -p /srv/www/swisscenter
$ cd /srv/www/swisscenter/
$ sudo unzip ~/swisscenter.zip
$ sudo chown -R www-data:www-data .
(Using www-data which is the standard apache user/group in Debian-based distributions, rather than wwwrun as specified in the SwissCenter document.)

Enable the site in Apache

Slightly different from the document here... I appended the following to /etc/apache2/sites-available/default
Listen 8080
NameVirtualHost --myhostname--
<virtualhost>
DocumentRoot "/srv/www/swisscenter"
<directory>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
Allow from all
</directory>
<ifmodule>
DirectoryIndex index.html index.php
</ifmodule>
</VirtualHost>
Then restarted apache.

Checking and configuring SwissCenter

Point web browser to the SwissCenter Configuration page at http://<servername>:8080/config. On first attempt, the page showed:
Warning: dl() [function.dl]: Dynamically loaded extensions aren't enabled in /srv/www/swisscenter/base/image.php on line 50

Fatal error: Call to undefined function imagecreatetruecolor() in /srv/www/swisscenter/base/image.php on line 251
After a bit of searching, I found I needed to include php5-gd (included in the install command above. I didn't have it originally), so
$ sudo apt-get install php5-gd
$ sudo /etc/init.d/apache2 restart
Better this time. But the page still shows some errors under Installation Checks.
Unable to locate a TrueType font. The "Now Playing" screen will be missing track information.
Google turned up this, which helped me to find Advanced Options / Miscellaneous in the SwissCenter configuration pages where you can set the path to a TT font. I entered /usr/share/fonts/truetype/freefont/FreeSans.ttf.

That left a warning that database is not created yet. You create it from the SwissCenter Create Database page. On first attempt, I got
Unable to create database - Is your MySQL "Root" password correct?
Umm... Looks like I changed the default mysql root password when I installed mysql. I've forgotten it now. So I had to reset the root password. Now I can create the database successfully.

Back on the main Configuration page,
Unable to write to the SwissCenter playlists directory (playlists)
Under Media Management / Playlists, you enter a full path to a dir (which must be writeable by www-data user), i.e. created something like
$ sudo -u www-data mkdir <some_dir>
After all that, SwissCenter is up and ready to load some content. I pointed it to my photos and music directories for a start.

Accessing SwissCenter from the Popcorn Hour

The simplest way for a start is to add the SwissCenter URL to the Web Services page in the Popcorn Hour, i.e. create an entry pointing to http://servername:8080.

But you can run an additional service on the server to broadcast the SwissCenter's UPnP interface. With that running, SwissCenter shows up automatically in the Popcorn Hour's Media Sources page.

There's a nice custom broadcast script and a Debian init script to start and stop this broadcast service automatically. I modified the init.d script slightly to make it run in the background:
$ diff -upN broadcast.orig broadcast
--- broadcast.orig 2008-09-11 17:02:03.000000000 +0100
+++ broadcast 2009-01-11 02:00:52.011883945 +0000
@@ -46,7 +46,7 @@ do_start()
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
- start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
+ start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --background --make-pidfile -- \
$DAEMON_ARGS \
|| return 2
# Add code here, if necessary, that waits for the process to be ready
@@ -95,7 +95,7 @@ do_reload() {

case "$1" in
start)
- [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
+ log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
@@ -103,7 +103,7 @@ case "$1" in
esac
;;
stop)
- [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
+ log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;

And that's about it.

Thursday, January 8, 2009

I got a Popcorn Hour

I got a Popcorn Hour A-110 (AKA Networked Media Tank) media player just before Christmas.

I've had my Squeezebox network music player for a couple of years now, and along the way I've got hooked on
  • the idea of storing my digital media centrally

  • running a low power server

  • hacking around with Linux
So now I'm going to have a go at streaming video. The Popcorn Hour seems like a good device to do it with.

My video content is DVDs ripped in full to ISOs using DVDFab (free version). I'm not compressing or discarding any of the non-movie content yet. But as each title takes 6-8GB, I might look into one or both soonish...

So far, I've had perfect success viewing this content on my TV in these ways:
  1. From an external disk (NTFS formatted), connected to a USB port on the Popcorn Hour.

  2. From an NFS share hosted on my fit-PC mini server, with the content stored on it's internal disk.

  3. As previous, but with the content on the external disk, connected to a USB port on the fit-PC.

  4. As previous, but using Samba instead of NFS.
For options 2-4 this is streaming via a pair of Devolo Homeplug AV adapters (AKA powerline networking). One adapter is connected to my router in the "server room". The other is connected to the Popcorn Hour in the TV room.

I hadn't expected the Homeplug setup to work. Quite a few people have reported problems with powerline networking on the Popcorn Hour forums. (And I had previously been unsuccessful streaming this way to a Hauppauge MVP box - it stuttered badly whatever I tried.) So was resigned to somehow running a cable from one end of the house to the other. But happy day, it is working flawlessly for me - at least for this standard-def content.

And my fit-PC handles streaming the video over NFS and Samba without breaking sweat.

Loads of scope for geeky time suckage with this. So more posts may follow.

(It took me absolutely feckin' ages to successfully export an NFS shared from a directory mounted from the NTFS formatted USB disk, but that's a whole other story.)

Saturday, November 22, 2008

When apt-get fails to reinstall a package

While experimenting with the Moin Moin Wiki, I got into some bother attempting to uninstall and reinstall it. The problem originated from me manually removing some configuration files. apt-get subsequently refused to reinstall those files. I eventually resolved by using dpkg.

I had initially followed the installation steps for Moin Moin on the Ubuntu Server Guide. So I had installed by doing
$ sudo apt-get install python-moinmoin
So to uninstall, I did
$ sudo apt-get remove python-moinmoin
I now know that that did not uninstall a base package, moinmoin-common, on which it depends. But I didn't notice that at first. All I saw was that some configuration files were still present in /etc/moin, so I rm -rf them.

And there began my trouble, because thereafter I could not get apt-get to delete or reinstall the configuration files to that dir.

I did various iterations of apt-get install, apt-get remove and apt-get purge for the moinmoin-common and python-moinmoin packages. But the remove operations never removed /etc/moin and the installs never installed the missing files.

I used dpkg-deb to inspect the moinmoin-common archive file in /var/cache/apt/archives. I could see the to files I wanted were in the archive. But I could not get them to unpack to /etc/moin.

A temporary workaround was to use dpkg-deb to extract the archive file to /tmp, which unpacked everything, and then manually copy the uninstallable files from there to /etc/moin. But I wanted to find the proper solution.

I found a thread on the Ubuntu Forums outlining an equivalent problem with an apache2 installation. The advice there was to use Synaptic to remove the package. I don't have that option as I am running a headless server and Synaptic is a GUI tool. But at least there was the suggestion of a solution. If it can be done in a Debian/Ubuntu GUI, then be sure it can be done on the command line too.

Then I found a good article at Linux.com which explained how you can escalate from apt-get to dpkg to resolve package management problems.

So the happy ending was to do
$ sudo dpkg --purge moinmoin-common
This removed the troublesome files and the references to them that the package manager was evidently keeping. After that, I was able to cleanly reinstall Moin Moin.

Thursday, November 20, 2008

CUPS print server

I installed CUPS on my fit-PC mini Linux server to turn it into a USB print server.

Got a USB printer? Want to let several computers share it? Want to print to it wirelessly? Well you could buy a USB print server. Connect one of these to your router and your printer and you can share the printer on your network. If your router is wireless, you now have a wireless print server.

But since I already have an always-on mini Linux server, I can simply install CUPS on that and let it be my print server.

The setup
  • Fit-PC mini Linux server connected to my wireless router, as before.
  • USB laser printer (HP LaserJet 1010) connected to a USB port on the server.
  • CUPS installed and configured on the server to allow any PC connected to the router to use the printer.
  • Generic printer driver installed on Windows laptops so they can use the printer through the printer server.
So now I have a very handy wireless print server...
  • I can send stuff to the printer whenever I like.
  • The printer itself doesn't need to be turned on - just the server. Print jobs are spooled to the server.
  • When I want to collect printed pages, I just turn on the printer. The server detects it and sends the pending pages.
  • Pending print jobs are is written to disk, so even if you turn off the server, they are there when it restarts.
Installing and configuring CUPS on the server was straightforward.
$ sudo apt-get install cupsys
I Googled a bit for cupsys setup tips and made a few changes to /etc/cups/cupsd.conf.

For what it's worth, here's the diff between the default configuration (Ubuntu 8.04) and my current version.
$ diff /etc/cups/cupsd.conf.original /etc/cups/cupsd.conf
18a19
> Listen <my-server-ip-address>:631
27c28
< DefaultAuthType Basic
---
> DefaultAuthType None
31c32,35
< Order allow,deny
---
> Order deny,allow
> Deny From All
> Allow From 127.0.0.1
> Allow From 192.168.2.*
36a41
> Allow 192.168.2.*
58a64
> Allow 192.168.2.*
I think I had to restart the server once after installing cupsys, before I could access its web interface from my laptop. (Maybe apparmor related. I'm begining to think that reboot is required to allow any newly installed HTTP service available. Could be wrong there.)

Anyway, once it's setup right, you can point your browser to
http://<your-server>:631
to browse and manage the print server.

The setup on Windows laptops was very easy. I used "Add Printer" to add a network printer, specifying connect by URL, and a generic PostScript driver (I used Generic / MS Publisher ImageSetter).

There are of course many other ways to set it up, e.g. different printer driver options are covered here. But this is working out nicely for me.

Wednesday, November 12, 2008

Performance of SqueezeCenter on fit-PC Slim

Here is some data on the performance of SqueezeCenter on my fit-PC Slim.

Library rescan

4004 mp3 files

* Look for new & changed music - 1:50
* Clear library and rescan everything - 18:01


3987 flac files

* Clear library and rescan everything - 13:06

Power consumption was peaked at 9 watts during rescans compared to 7 watts for normal operation.


Web interface*

Full cold load^ of the interface - 15 secs
Warm load - 5 secs

*Firefox 2
^Clear browser cache and restart browser

Saturday, November 8, 2008

Some photos of the fit-PC

"For those who like that sort of thing, that is the sort of thing they like."




fit-PC and a AAA battery




fit-PC on the left next to the Linksys router




Squeezebox and fit-PC




Typical power consumption 7 watts

Thursday, November 6, 2008

SqueezeCenter on the fit-PC Slim

It's a few weeks since I installed SqueezeCenter 7.2 on my mini Linux server. I'm delighted to say that it's working out great.

Music playback on my Squeezebox player is flawless. The responsiveness of the player and web interface is just fine.

My server is the recently released fit-PC Slim (512MB RAM), which I ordered diskless and fitted with a 250GB disk. It's running a minimal server install of Ubuntu 8.04 with a few services including SqueezeCenter.

In its current configuration, my fit-PC draws just 7 watts.

I think that's pretty terrific. I expect to get the power consumption even lower whenever I get around to disabling the WIFI adapter in the BIOS.

I only have one Squeezebox, so can't comment on the ability to serve multiple clients, though I have played to the Squeezebox and my laptop simultaneously without glitches. Also, no problem streaming music while performing other background tasks, like copying on new music files and transcoding from FLAC to mp3.

I reckon the fit-PC is a really great fit for SqueezeCenter.

Saturday, November 1, 2008

Akasa HDD enclosure - remove the jumpers

I decommissioned my old server tonight and ripped out everything useful, including the 250GB IDE/PATA disk. I got an Akasa disk enclosure a few weeks ago specifically to recycle this disk. I had a couple of false starts, but they were resolved by removing the jumpers on the disk. (The Akasa manual says nothing about jumpers).

First off, with one jumper in the master/single position, Windows XP couldn't see the disk at all. Next, I misread the jumper diagram on the disk and put it in the "limit disk capacity" setting. Now Windows could see the disk, but only 33.8 GB of it. Same story connected to Linux. Finally, I removed the jumpers altogether. Now Linux and Windows can see the disk and its full capacity.

Formatting the disk with an NTFS partition now...

Wednesday, October 15, 2008

Migrating subversion repository

I have a small subversion repository on my old server. I want to migrate it to the fit-PC.

Looking at the relevant section of Version Control with Subversion, it looks like it should be easy. Just create a dumpfile on the old box and load it to a new repository on the new one.

So on the old box
$ svnadmin dump repos > dumpfile
and copy the dumpfile onto the new box.

Last time I setup subversion + apache for HTTP access. This time I'm going to try svn+ssh.

As usual, Ubuntu provides a good general reference.

Install subversion
$ sudo apt-get install subversion 
Setup a subversion user and group, add myself to the group
$ sudo addgroup svn
$ sudo useradd -g svn -m -p <pwd> svn
$ sudo usermod -a -G svn <my_user>
Create the repository and load the dumpfile
$ sudo su svn
$ cd /home/svn
$ svnadmin create repos
$ svnadmin load repos < dumpfile
I want svnserve process to start when the box boots, so I added this line to /etc/rc.local:
sudo -u svn svnserve -d -r /home/svn
I'll make a proper init.d script like this one later.

Restart the box

Verify I am a member of the svn group
$ groups
Verify that svnserve process started
$ ps -ef | grep svnserve
Verify I can read the repository locally
$ svn list svn://localhost/repos/<project>/trunk

Setup access to the repository from Eclipse on my laptop

(I already have the subclipse plugin installed).

File / Import
Checkout Projects from SVN
Create a new repository location
svn+ssh://<hostname>/home/svn/repos

That fails with an error dialog and this message on the console:
    The system cannot find the file specified. 
svn: Can't create tunnel: The system cannot find the file specified.

Back to Google... The answer is here.

The problem was that Eclipse was not configured with an SSH client. Quick fix for me was to switch the Eclipse / Team / SVN configuration from JavaHL (which requires external SSH client) to SVNKit (which includes one). Now it works.

Edit! Actually, not quite there yet...

On attempting to commit to the repository, I got error
svn: Commit failed (details follow):
svn: Can't create directory '/home/svn/repos/db/transactions/1-1.txn':
Permission denied
It turns out that svn+ssh does not connect to the svnserve daemon I started above, but rather creates a temporary svnserve process (on each invocation) as the ssh user. And in the setup above, the ssh user has read access to the repos, but not write access. (Just like if you use subversion + apache and don't make the repository writable by the www-data user).

Temporary workaround (to commit my current work) is to make the whole repository writable by my ssh user
$ cd /home/svn
$ sudo chown <sshuser>:<sshuser> -R repos
Now the commit succeeds.

Next task is to read the relevant section of the Subversion manual more carefully. My original setup above will support working with the repository using svn://<host>/repos. I might just go with that for now.

Monday, October 13, 2008

Installing SqueezeCenter

Running SqueezeCenter to feed the Squeezebox music player is my old server's main duty. So it's first up for installation on my new fit-PC.

Edit /etc/apt/sources.list to add
deb http://debian.slimdevices.com stable main

$ sudo apt-get update
$ sudo apt-get install squeezecenter
The web interface is not available from my laptop until I restart the box (something to do with apparmor?). On restart, I can access the web interface fine.

SqueezeCenter installs mysql (unless you have it already) and SqueezeCenter then runs its own mysql instance, in addition to the default one. I don't want two mysql instances running on my little server, so I'll disable the default one for now:
$ cd /etc/rc2.d
$ cat README
$ sudo mv S18mysql-ndb K82mysql-ndb
$ sudo mv S19mysql K81mysql
$ sudo mv S17mysql-ndb-mgm K83mysql-ndb-mgm
Alternative would be to get squeezecenter to use the default mysql instance instead, and disable the dedicated squeezecenter one. Supposed to be possible. I'll try that whenever I end up with some other application which needs mysql.

Sunday, October 12, 2008

Initial setup

The first thing I want to do is get rid of the monitor and keyboard, so

$ sudo apt-get install openssh-server
$ sudo apt-get install screen

(Screen is great. I use it whenever I need to kick off some long-duration command. It means I can close the laptop, dropping my ssh session, but still reconnect to the console running the command whenever I want to.)

Edit /etc/network/interfaces to change from DHCP to static IP address, which is covered well here.

Serial console

I never tried this before...

I ordered the serial cable with my fit-PC and got a €3 generic USB RS-232 adapter cable from this store on ebay.

The instructions on the fit-PC wiki were great. On the other side, all I had to do was check which COM port the USB adapter was on using Windows device manager, and then create a serial PuTTY session using the same configuration.

With this setup, I get GRUB and kernel output to, and login from, the serial console. This is a real bonus compared to my old PC server.

I'd really like to be able to configure the fit-PC BIOS over the serial connection as well, but it sounds like that might be a bit more difficult.

Anyway, BIOS configuration changes aside, I can ditch the keyboard and monitor now. My fit-PC is ready to be a headless server.

Saturday, October 11, 2008

Ubuntu USB stick install, part 2

I finally got a successful install. But it took several attempts and a lot of Google.

First attempt

In the fit-PC BIOS setup, I set Drive C: Nand Flash but neglected to set Drive D: IDE. So when the installer got round to the partitioning stage it could only see the USB stick, not the hard disk. Hit reset button and start again...

Second attempt

I didn't create a separate ext3 /boot partition, just XFS root and /home partitions. Apparently installing GRUB on an XFS partition is not a good thing. Near the end of the install, the installer offers to install LILO for me. Now I dimly remembered going through LILO versus GRUB before and preferring GRUB, so I try to install GRUB anyway. The installer warns me that this is a bad idea. When I ignore that this makes a fatal error in the install which then hangs. Grit teeth, hit reset button and start again...

Third and fourth attempts

I created a separate ext3 /boot partition to stay sweet with GRUB. So I now have
#1 primary 100MB ext3 /boot
#1 primary 4GB XFS /
#5 logical 246GB XFS /home
Now the install completed successfully each time. But it all ended in tears when I tried to reboot the fit-PC. Each time, it immediately dropped to a debugger interface, saying Embedded BIOS Debugger Breakpoint Trap and refused to do anything else. Weep, hit the sack and try again in the morning...

I noticed that after each install attempt, I could no longer boot from the USB stick. It gave GRUB Error 21. I could fix the stick by reconnecting it to my old Linux box and doing install-mbr /dev/sdb. But why?

I finally guessed that the Ubuntu installer must be installing GRUB to the MBR of my USB stick, instead of the hard disk in my fit-PC where I needed it. Armed with that hunch, Google finally gave me some answers, like this, this and this.

Fifth attempt

I let the Ubuntu installer run to the very end, where it tells you to reboot. At that point, I opened a console and took a look around.

I found (fdisk) that my hard disk partitions were mounted on /target. So I did
# chroot /target
# grub-install /dev/sdb
to install GRUB into the MBR of the hard disk. Then I went back to the installer's console and let it finish.

On restart I removed the USB stick, hit DEL to enter the BIOS setup, reverted to Drive C: IDE and saved to reboot.

On first attempt GRUB started (phew) but said
Error 21: Selected disk does not exist
Press any key to continue...
So I did. Then GRUB gives the menu list of image it can boot and allows you to edit and boot them. I edited the entry for the first image. It's first line was root (hd1,0). I edited that to root (hd0,0) and the hit 'b' to boot. The system booted at last.

Once in, I took a look at /boot/grub/menu.list. All three had root (hd1,0).

I rebooted to confirm that GRUB would fail again with same error.
It did. I fixed as before. Once back in, I edited /boot/grub/menu.list to change all the hd1 to hd0 and rebooted again.

At last, the system boots successfully. Now I can get on with the more interesting stuff.

Friday, October 10, 2008

fit-PC BIOS notes

Once you have a bootable device attached to fit-PC, you enter the BIOS by holding down DEL key after resetting the box.

To reset the BIOS to factory defaults, hit down arrow 8 times, then hit enter. You never know when that might come in handy.

There's a "print out" of the BIOS menus here on the fit-PC wiki.