Skype video on Fedora 16 64bit

Install Skype – I used these instructions. This will seem to get everything working, but video will just give you a black screen and no error message. This is because Skype is 32 bit and you webcam driver is 64 bit. Make sure you have libv4l.i686 installed.

sudo yum install libv4l.i686

Now create a wrapper script to launch it with a custom environment. I put it in /usr/local/bin/skype

#!/bin/bash
LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so  /usr/bin/skype

This will now get loaded before the main Skype executable and you will have a working video device.

A learning experience

How many times have you installed/updated a bit of software and read the line “Please take a back up” or something to that effect? 99 times out of a hundred, you will just continue and ignore it.

Today I had a reminder of why it is import to do so. I did a routine plug-in upgrade on our Jira installation (Customware Salesforce connector for those who want to know). I have done this several times, I had tested it our Dev installation I was 100% confident it would work as expected. However, I actually decided to take a backup anyway.

I ran the upgrade in the production environment and re-indexed. Nothing out of the ordinary. 10% of the way into the index it fell over. Jira’s database was gone! Fortunately I was able to restore from my backup and at worst a comment or two was lost, but that still caused significant downtime.

I had done everything I could to make sure the upgrade would go smoothly, but it still did not. That is why software vendors always tell you to take a backup before even the smallest change – DO IT!

Bike for sale

Gallery

This gallery contains 5 photos.

I am selling my track bike. It is a hand-made frame (dated 15 Oct 1986) with this stuff on it: Campagnolo chain rings Campagnolo crankset Mavic ma40 rimsVittoria tyres Suntour custom hubs Cinelli handlebars It is currently set to 46×16 … Continue reading

PyCurl and self-signed SSL certificates

At Snell we make heavy use of self-signed certificates for internal websites, such as the R&D wiki. Active Directory makes it easy for us to make this transparent to the users, those that use Firefox/Chrome can find our well-published instructions to add the CA certificate to their own browsers.

Today I was writing a script to that pulls lots of attachments off our Confluence wiki, which we access through SSL using one of those certificates. Of course PyCurl  moaned that it could not verify the host, but I did not care – I know it is the right host!

Finding documentation both on SSL and PyCurl is problematic at best. OpenSSL’s documentation it complete, but could not be more unreadable if written by a right-handed doctor using a broken crayon with his left-hand; pyCurl’s documentation is non-existent.

After an hour of Google-Fu and DuckDuckGo-Fu I finally managed to do what I wanted:

#!/usr/bin/env python
downloadedFile = "/tmp/ +
outfile = file(downloadedFile, 'wb')
url = https://someurl.example.com
c = pycurl.Curl()
c.setopt(c.URL, url)
c.setopt(pycurl.USERPWD, "%s:%s" % (username, password))
c.setopt(c.WRITEFUNCTION, outfile.write)
c.setopt(c.SSL_VERIFYPEER, 0) # That is you key line for this purpose!
c.perform()
c.close

There you go!

 

Add SAN functions to Highly Available NFS/NAS

This based on my last post where I documented building a Highly Available NFS/NAS server.

There is not a huge amount that needs to be done in order to add iSCSI functionality as well.

Add a file called /etc/drbd/iscsi.res containing:

resource iscsi {
    on nfs1 {
        device /dev/drbd1;
        disk   /dev/vdc;
        meta-disk internal;
        address   10.0.0.1:7789;
    }
    on nfs2 {
        device /dev/drbd1;
        disk   /dev/vdc;
        meta-disk internal;
        address   10.0.0.2:7789;
    }
}

This differs from the previous resource in 2 ways. Obviously it using a different physical disk. Also the port number of the address is incremented; each resource has to have its own port to communicate on.

Configure Heartbeat

Add a new resource to /etc/ha.d/haresources:

iscsi1.snellwilcox.local IPaddr::10.0.0.101/24/eth0 drbddisk::iscsi tgtd

Same primary host, new IP address, new drbd resource and of course the service to be controlled (tgtd in this case).

I also made a couple of changes to /etc/ha.d/ha.cf:

keepalive 500ms
deadtime 5
warntime 10
initdead 120

This changes the regularity of the heartbeat packets from every 2 seconds to 2 every second. We also say that a node is dead after only 5 seconds rather than after 30.

Configure an iSCSI Target

Tgtd has a config file that you can use in /etc/tgt/targets.conf. It is an xml file, so add entry like:

iscsi.target1>
    backing-store /dev/drbd/by-res/iscsi

The target name is by convention iqn.<year>-<month>.<reverse-domainname>:<hostname>.<targetname>. Each backing store will be a seperate LUN. A discussion of this is out of the scope of this article.

By default, this config file is disabled. Enable it by un-commenting the line #TGTD_CONFIG=/etc/tgt/targets.conf in /etc/sysconfig/tgtd. You can now enable the target with service tgtd reload.

Now when you run tgtadm –mode target –op show you should get something like:

Target 1: iqn.2012-03.com.example:iscsi.target1
    System information:
        Driver: iscsi
        State: ready
    I_T nexus information:
    LUN information:
        LUN: 0
            Type: controller
            SCSI ID: IET     00010000
            SCSI SN: beaf10
            Size: 0 MB, Block size: 1
            Online: Yes
            Removable media: No
            Readonly: No
            Backing store type: null
            Backing store path: None
            Backing store flags:
        LUN: 1
            Type: disk
            SCSI ID: IET     00010001
            SCSI SN: beaf11
            Size: 8590 MB, Block size: 512
            Online: Yes
            Removable media: No
            Readonly: No
            Backing store type: rdwr
            Backing store path: /dev/drbd/by-res/iscsi
            Backing store flags:
    Account information:
    ACL information:
        ALL

 Connect An Initiator

Install the iscsi utils:

yum install iscsi-initiator-utils
chkconfig iscsi on
chkconfig iscsid on

Discover the targets on the host and login to the target.

iscsiadm -m discovery -t sendtargets -p 10.0.0.101
iscsiadm -m node --login

If you run cat /proc/partitions you will see an new partition has appeared. You can do whatever you want with it.

 

Highly Available NFS/NAS

Take 2 Centos Servers (nfs1 and nfs2 will do nicely) and install ELrepo and EPEL on them both:

yum install http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm \ http://elrepo.org/elrepo-release-6-4.el6.elrepo.noarch.rpm --nogpgcheck

Each of them should ideally have 2 NICS, with the secondary ones just used for DRBD sync purposes. We’ll give these the address 10.0.0.1/32 and 10.0.0.2/32.

I am also assuming that you have disabled the firewall and SELinux – I do not recommend that for production, but for testing it is fine.

DRBD Configuration

Install DRBD 8.4 on the both:

yum install drbd84-utils kmod-drbd84

On each node the file /etc/drbd.d/global_common.conf should contain:

global {
  usage-count yes;
}
common {
  net {
    protocol C;
  }
}

and /etc/drbd.d/main.res should contain:

resource main {
  on nfs1 {
    device    /dev/drbd0;
    disk      /dev/sdb;
    address   10.0.0.1:7788;
    meta-disk internal;
  }
  on nfs2 {
    device    /dev/drbd0;
    disk      /dev/sdb;
    address   10.0.0.2:7788;
    meta-disk internal;
  }
}

On both nodes you will need to create the resource metadata:

drbdadm create-md main

and start the daemons

service drbd start
chkconfig drbd on

Now service drbd status will give you:

drbd driver loaded OK; device status:
version: 8.4.1 (api:1/proto:86-100)
GIT-hash: 91b4c048c1a0e06777b5f65d312b38d47abaea80 build by dag@Build64R6, 2011-12-21 06:08:50
m:res   cs         ro                   ds                         p  mounted  fstype
0:main  Connected  Secondary/Secondary  Inconsistent/Inconsistent  C

Both devices or secondary and inconsistent, this is normal at this stage. Choose a node to be your primary and run:

drbdadm primary --force main

And it start sync’ing, which will take a long time. You can temporarily make it faster with (on one node:

drbdadm disk-options --resync-rate=110M main

Put it back again with drbdadm adjust main

On your primary node you can now create a fiiesystem. I’m using ext4 for no good reason other than it being the default. Use whatever you are most comfortable with.

mkfs.ext4 /dev/drbd0

Configure NFS

If you diid a minimal Centos install, then you willl need to install the nfs-utils package (yum install nfs-utils). Prepare your mount points and exports on both servers:

mkdir /drbd
echo "/drbd/main *(rw)" >> /etc/exports

Now we do the actual NFS set up. We previously choose nfs1 as our master when you used it to trigger the initial sync. On nfs1 mount the replicated volumes, move the NFS data to it, then create symlinks to our replicated data.

mount /dev/drbd0 /drbd
mkdir /drbd/main
mv /var/lib/nfs/ /drbd/
ln -s /drbd/nfs/ /var/lib/nfs
umount /drbd

If you get errors about not bring able to remove directories in /var/lib/nfs do not worry.

Now a little preparation on nfs2:

mv /var/lib/nfs /var/lib/nfs.bak
ln -s /drbd/nfs/ /var/lib/nfs

This will create a broken symbolic link, but it will be fixed when everything fails over.

Heartbeat Configuration

Heartbeat is in the EPEL repository, so enable that and install it on both nodes:

yum -y install heartbeat

Make sure that /etc/ha.d/ha.cf contains:

keepalive 2
deadtime 30
bcast eth0
node nfs1 nfs2

The values in node should be whatever uname -n returns.

Now create /etc/ha.d/haresources:

nfs1 IPaddr::10.0.0.100/24/eth0 drbddisk::main Filesystem::/dev/drbd0::/drbd::ext4 nfslock nfs

That is a little cryptic, so I’ll explain; nfs1 is the primary node, IPaddr sets up a floating address on eth0 that our clients will connect to. This has a resource drbddisk::main bound to it, which sets our main to resource to primary on nfs1. Filesystem mounts /dev/drbd0 at /drbd on nfs1. Finally the the services nfslock and nfs are started on nfs1.

Finally, it needs an authentication file in /etc/ha.d/authkeys, which should be chmod’ed to 600 to be only readable by root.

auth 3
3 md5 mypassword123

You should also make sure that nfslock and nfs do not start up by themselves:

chkconfig nfs off
chkconfig nfslock off

Now you can start heartbeat and check it is working:

service heartbeat start
chkconfig heartbeat on

Testing

Running ifconfig on nfs1 should give you something like:

eth0      Link encap:Ethernet  HWaddr 52:54:00:84:73:BD  
          inet addr:10.0.0.1  Bcast:10.0.0.255  Mask:255.255.255.0
          inet6 addr: fe80::5054:ff:fe84:73bd/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:881922 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1302012 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:239440621 (228.3 MiB)  TX bytes:5791818459 (5.3 GiB)

eth0:0    Link encap:Ethernet  HWaddr 52:54:00:84:73:BD  
          inet addr:10.0.0.100  Bcast:10.0.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:224 (224.0 b)  TX bytes:224 (224.0 b)

Note an entry for eth0:0 has miraculously appeared.

Also df should include the entry:

/dev/drbd0             20G  172M   19G   1% /drbd

Reboot nfs1 and the services should appear on nfs2.

Connect an NFS client to you floating address (10.0.0.100) and you should be able to kill the live node and it will carry on.

Music Player Daemon in Fedora

This should have nice and simple, but there was a little gotcha (for me anyway).

First install the RPMFusion repositories:
yum localinstall --nogpgcheck http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm

Now you can install MPD and a simple client with
yum install mpd mpc

By default it looks in /var/lib/mpd/music which strikes me as reasonable, so copy some music there. Now comes the bit that caught me out; you will need to update is library:
mpc update

A lot of documentation on the net talks about running mpd –create-db, but this is now depreciated. I eventually found this out on Arch Linux’s wiki.

Connect a client and listen to your music – I’m using gmpc (yum install gmpc) which is very feature rich, but if you want something simpler, try Sonata (yum install sonata) or even mpc itself. Finally you can also use you MPDroid on your phone.

Back to Basics

I have been a Sys Admin for quite a while now. Specialising in Linux means that I am often called upon to be a “jack of all trades, master of many”. In the last week I have touched upon storage, multiple programming languages (Bash, PHP, Python, Ruby and Java), Linux, Exchange, Tomcat, Virtualization and Systems architecture. I am sure the list could go on … and on … and on …

There is however something that I feel I am missing. Before I was in my current post, I was more of a developer. I did a lot of Shell scripting, but also ADA and C/C++. Nowadays I do not do that, which is a shame. Virtually all modern programming languages trace their roots back to C and C++. The whole of Linux/UNIX traces its roots back to C. Our world is built on C/C++!

This is something I have neglected over recent years, so I’m going to change that. A bit of Google-fu just now has bought me some interesting resources:

I have not looked at any of these in detail yet, but I will be over the next few days. At the end I hope to have dragged this hard-earned knowledge kicking and screaming from the back of my mind.

RIP Moog

This morning I had to put my little girl to sleep. Moog has been with me all my adult life, longer even  than my wife.

Moog

RIP Moog

This was the hardest thing I have ever had to do, but I am sure it was the right thing.

She had arthritis and a cancerous lump in her throat that meant she could no longer eat. In spite of this she has been an exceptionally happy cat and utterly adored by all who met her.

Rest in Peace Moog – I’ll see you when I get to heaven

Home-made Redundant, Thin-provisioned SAN

The inspiration for this came from a mixture of problems I was having with my HP P2000, ideas that have been floating around my head for a while, plus a post over at Bauer-power.net. Basically I got given a bunch of warranty returned Supermicro servers from our Customer Service guys  and got tasked with making it our secondary VMware store and DR snapshot storage. Incidentally, the Supermicro servers are used for our Channel-in-a-box product for those you in the broadcast world. They are not ideal, the 2U 12 disk models that Pablo uses are far more suitable.

Plenty of companies already build their arrays on commodity hardware like these, so I am not doing anything new:

  • Dell Compellent (Supermicro, soon to be Dell)
  • CoRAID (Supermicro)
  • EMC  Clarion and VNX
  • HP P4000 (HP DL180)
  • 3Par
  • Pure Storage
  • Nutanix
  • Solid Fire

My set up is basically the same as that used by Pablo in the second iteration of his array:

  • Linux
  • GlusterFS
  • Tgtd
  • Heartbeat

There are a couple of differences:

  1. Mine uses a new version of GlusterFS which is currently in beta. This has several new features, the one I am interested in is Granular Locking. As I am storing VM images, I do not want these being locked during a self-heal – a problem in 3.2 and before. There are also other things such as object-storage (Amazon S3 compatible) for use with Open Stack. I’d love that, but I am not using it in my environment :( .
  2. I am building on top of CentOS. I started with Red Hat and will continue to use it for server environments in the forceeable future.
  3. I do not have de-duplication as I am not using ZFS, I am running on top of Ext4 and will use XFS or BTRFS if I need to. I am only using 8x 1TB drives as that is what I got given for free.

I have had to build a couple of custom RPMS which I have made available in my Yum repository.

I did investigate de-duplication using LessFS, but sadly that is a no go as it does not currently support Extended Attributes, which are required by GlusterFS.

Installation

Install a basic CentOS 6 system on each node – the base system will be fine.

The two servers are

server1 192.168.1.1(eth0),10.0.0.1(eth1)
server2 192.168.1.2(eth0),10.0.0.2(eth1)

They connect to the rest of your network using eth0 and eth1 is a dedicated link between the 2. I would put them via a seperate switches/vLANs rather than a direct link, that way you can scale out your pool easily.

In the hosts file add:

10.0.0.1 server1.example.com
10.0.0.2 server2.example.com

Add my repository:

rpm --import http://yum.chriscowley.me.uk/RPM-GPG-KEY-ChrisCowley
yum install http://yum.chriscowley.me.uk/el/6/x86_64/RPMS/chriscowley-release-1-1.noarch.rpm
rpm --import https://fedoraproject.org/static/0608B895.txt
yum install http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm 

Now you can install the necessary packages, which is not many. :

yum install glusterfs-core glusterfs-fuse heartbeat scsi-target-utils

Now you can add create a pool of servers:

GlusterFS

From server1:

gluster peer probe server2

You next step is to configure a Gluster Volume. Gluster’s documentation for this is excellent. For our simple 2-node cluster we just want a simple replicated volume. As you grow, you can simple add extra pairs of nodes to expand your storage pool.

On each node create a folder to store the data and a mount-point for the replicated data:

mkdir /exp1
mkdir /mnt/test-volume

Now create your volume and activate it(on a single node):

gluster volume create test-volume replica 2 transport tcp server1:/exp1 server2:/exp1
gluster volume start test-volume

Now you need to mount that volume on each of your nodes.

echo "`hostname`:/test-volume /mnt/test-volume glusterfs defaults,noauto,_netdev 0 0" >> /etc/fstab
echo "mount /mnt/test-volume" >> /etc/rc.local
mount /mnt/test-volume

Heartbeat

Now you need to configure heartbeat to control a floating IP address and the associated TGTD service. You need to create a few files on each node.

/etc/ha.d/authkeys:

auth 2
2 crc

/etc/ha.d/ha.cf

logfacility     local0
keepalive 500ms
deadtime 5
warntime 10
initdead 120
bcast eth1
node server1
node server2
auto_failback no

/etc/ha.d/haresources:

server1 IPaddr::192.168.1.3/24/eth0 tgtd

There are a couple of considerations. The Gluster filesystems need to be mounted before tgtd starts. Tgtd is in turn controled by Heartbeat (see the above haresources file). To this end make sure both heartbeat and tgtd are disabled and start heartbeat from /etc/rc.local.

echo "/etc/init.d/heartbeat start" >> /etc/rc.local

With all this done on both nodes, you can now start heartbeat on each node:

/etc/init.d/heartbeat start

Checking ifconfig will show that one of your nodes now has an eth0:0 address.You will also find that tgtd is also running on that same node.

iSCSI Target

First create yourself a file to use as the backend for your iSCSI target:

dd if=/dev/zero bs=1M count=40000 of=/mnt/test-volume/test.img

or, if you prefer thin provisioned:

dd if=/dev/zero bs=1M seek=40000 count=0 of=/mnt/test-volume/test.img

You now need to define this file as a target. This requires the editting of 2 files.

/etc/sysconfig/tgtd:

TGTD_CONFIG=/etc/tgt/targets.conf

/etc/tgtd/targets.conf, make sure there is an entry such as:

<target iqn.2012-02.com.example.gluster:isci>
    backing-store /mnt/test-volume/test.img
    initiator-address 192.168.1.10
</target>

This will make that image file you created available to the client with the address 192.168.1.10. This targets.conf file is extremely well commented, so have a read. Now just tell tgtd to reload its configuration from the live node:

/etc/init.d/tgtd reload

Conclusion

Nothing here is particularly complicated, but it does give you a lot of storage for a very low price, using a very enterprise friendly OS.