Category Archives: Uncategorized

perl: warning: Setting locale failed.

I’ve seen this perl error for a while and ignored it but it was stopping postgres from starting. This is on Ubuntu Intrepid 8.10, specifically a JeOS install made by vm-builder, which is the key.

$ sudo /etc/init.d/postgresql-8.3 start
 * Starting PostgreSQL 8.3 database server
 * perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
The PostgreSQL server failed to start. Please check the log output:
FATAL:  invalid value for parameter "lc_messages": "en_US.UTF-8"

The solution:

sudo apt-get install language-pack-en

Configuring ssl requests with SubjectAltName with openssl

Subject Alternative Names are a X509 Version 3 (RFC 2459) extension to allow an SSL certificate to specify multiple names that the certificate should match. SubjectAltName can contain email addresses, IP addresses, regular DNS host names, etc. There’s a clean enough list of browser compatibility here.

Changing /etc/ssl/openssl.cnf isn’t too hard. Although most the documentation is hard to grasp, especially if you’re only trying to make requests. From this, I developed these changes to a standard config provided by debian/ubuntu. Edit openssl.cnf and uncomment “x509_extensions = v3_ca” in the [ req ] section.

Annoyingly, nobody appears to have figured out how to get openssl to ask you for this value.

I thought I was clever putting ‘subjectAltName=email:move’ in the v3_req section, which would put the email address you type in the subjectAltName field. I’d put in “foo@example.org, DNS:www1.example.org, DNS:www2.example.org” in the email field when ‘openssl req’ asked for it. Visually it worked, but the browsers didn’t like it. This appears to be functionality to deal with part 4.1.2.6 of the RFC, moving email address into subjectAltName.

I thought about writing a script that would copy openssl.cnf, ask me for the value of SubjectAltName, run sed against it, then start openssl. It would appear seamless, but of course be a hack.

A better answer lies here, you can configure openssl to use environment variables. At the top of openssl.cnf under where it set’s HOME=”…” I added

SAN="email:noc@example.com"

And in [ v3_req ] I added:

subjectAltName=${ENV::SAN}

So if you run openssl like this:

SAN="DNS:www.1example.org, DNS:www2.example.org" \
  openssl req -new -key www.example.org.key -out www.example.org.csr

It will fill in subjectAltName with the contents of the SAN variable, otherwise will fill it with the contents specified at the top of the file. There’s no way to use conditionals (I assume).If you just leave it blank, or leave it out altogether, you get these errors:

Unable to load config info from /usr/lib/ssl/openssl.cnf

and respectively,

Error Loading request extension section v3_req
27687:error:2206D06C:X509 V3 routines:X509V3_PARSE_LIST:invalid null name:v3_utl.c:327:
27687:error:22097069:X509 V3 routines:DO_EXT_NCONF:invalid extension string:v3_conf.c:139:name=subjectAltName,section=
27687:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:v3_conf.c:93:name=subjectAltName, value=

Adding hosts to virt-manager in Ubuntu Intrepid

I have a nice ssh-key system setup for connecting to KVM hosts, and through permission settings on:

/var/run/libvirt/libvirt-sock
/var/run/libvirt/libvirt-sock-ro

I managed access to the guests. Recently upgrading to intrepid brought along a new version of virt-manager, that whenever you add a QEMU+SSH libvirt instance in, it forcibly adds ‘root@’ to the URI where before the username was left out. If you add a URI like ‘bryanm@host’ it becomes ‘root@bryanm@host’.

Use gconf-editor, under apps -> virt-manager -> connections add new URI’s by hand rather than using the virt-manager interface as a workaround.

edit: launchpad bug #294965, Red Hat bug #470416.

Request-tracker: Could not load a valid user

A while back I moved my rt instance, mostly debianized it, and stabilized on RT 3.6.7 (decompressed on top of the 3.6.5 deb). I recently found that external emails were no longer creating new accounts.

It’s possible that I fixed the problem along the way and that my email account I was testing from was sending my ‘RealName’ and we were matching on that.

[Thu Nov  6 01:54:45 2008] [error]: RT could not load a valid user, and RT's configuration does not allow
for the creation of a new user for your email. (/usr/share/request-tracker3.6/lib/RT/Interface/Email.pm:243)
[Thu Nov  6 01:54:45 2008] [error]: Could not record email: Could not load a valid user (/usr/share/request-tracker3.6/html/REST/1.0/NoAuth/mail-gateway:75)
[Thu Nov  6 02:09:46 2008] [crit]: User creation failed in mailgateway: Name in use (/usr/share/request-tracker3.6/lib/RT/Interface/Email.pm:243)
[Thu Nov  6 02:09:46 2008] [crit]: User  'test@example.org' could not be loaded in the mail gateway (/usr/share/request-tracker3.6/lib/RT/Interface/Email.pm:243)
[Thu Nov  6 02:09:47 2008] [err]: Couldn't load  from the users database. (/usr/share/request-tracker3.6/lib/RT/CurrentUser.pm:147)
[Thu Nov  6 02:09:47 2008] [err]: Couldn't load  from the users database. (/usr/share/request-tracker3.6/lib/RT/CurrentUser.pm:147)
[Thu Nov  6 02:09:47 2008] [error]: Couldn't create ticket from message with commands, fallback to standard mailgate.

Error: No permission to create tickets in the queue 'lposupport' (/usr/share/perl5/RT/Interface/Email/Filter/TakeAction.pm:504)
[Thu Nov  6 02:09:47 2008] [crit]: Couldn't create ticket from message with commands, fallback to standard mailgate.

Error: No permission to create tickets in the queue 'lposupport' (/usr/share/request-tracker3.6/lib/RT/Interface/Email.pm:243)
[Thu Nov  6 02:09:47 2008] [error]: RT could not load a valid user, and RT's configuration does not allow
for the creation of a new user for this email (test@example.org).

You might need to grant 'Everyone' the right 'CreateTicket' for the
queue lposupport. (/usr/share/request-tracker3.6/lib/RT/Interface/Email.pm:243)

I had to reconfigure my configs during the move. Of course I checked the queue permissions, then expected that $AutoCreateNonExternalUsers was not set to 1. Neither was the solution. I installed the latest versions of RT and ExternalAuth from source. Still not working. The trick? I found a recommended change to the LDAP attr_match_list, reducing it to just Name and EmailAddress. This makes sense from the newer logs I saw in debugging.

Upgrading also led me to a new error about d_filter not being set. I used the following, taken from this thread:

'd_filter' => '(userAccountControl:1.2.840.113556.1.4.803:=2)',

And the logs:

[Thu Nov  6 05:02:00 2008] [debug]: Going to create user with address 'test@example.org' (/opt/rt3/bin/../lib/RT/Interface/Email/Auth/MailFrom.pm:94)
[Thu Nov  6 05:02:00 2008] [debug]: RT::User::CanonicalizeUserInfo called by RT::User /opt/rt3/bin/../lib/RT/User_Overlay.pm 128 with: Comments: Autocreated
on ticket submission, Disabled: 0, EmailAddress: test@example.org, Name: info@imob.org, Password: , Privileged: 0, RealName: Bryan McLellan (/usr/share/perl5/RT
/User_Vendor.pm:400)
[Thu Nov  6 05:02:00 2008] [debug]: Attempting to get user info using this external service: My_LDAP (/usr/share/perl5/RT/User_Vendor.pm:408)
[Thu Nov  6 05:02:00 2008] [debug]: Attempting to use this canonicalization key: Name (/usr/share/perl5/RT/User_Vendor.pm:417)
[Thu Nov  6 05:02:01 2008] [debug]: LDAP Search ===  Base: dc=corp,dc=example,dc=org == Filter: (&(objectclass=user)(sAMAccountName=test@example.org)) == Attrs
: l,cn,st,mail,sAMAccountName,co,streetAddress,postalCode,telephoneNumber,sAMAccountName,physicalDeliveryOfficeName,sAMAccountName (/usr/share/perl5/RT/User_
Vendor.pm:538)
[Thu Nov  6 05:02:01 2008] [info]: RT::User::LookupExternalUserInfo : Returning:  EmailAddress: , Name: , RealName:  (/usr/share/perl5/RT/User_Vendor.pm:703)
[Thu Nov  6 05:02:01 2008] [debug]: RT::User::LookupExternalUserInfo No user was found this time (/usr/share/perl5/RT/User_Vendor.pm:706)
[Thu Nov  6 05:02:01 2008] [debug]: Attempting to use this canonicalization key: EmailAddress (/usr/share/perl5/RT/User_Vendor.pm:417)
[Thu Nov  6 05:02:02 2008] [debug]: LDAP Search ===  Base: dc=corp,dc=example,dc=org == Filter: (&(objectclass=user)(mail=test@example.org)) == Attrs: l,cn,st,mail,sAMAccountName,co,streetAddress,postalCode,telephoneNumber,sAMAccountName,physicalDeliveryOfficeName,sAMAccountName (/usr/share/perl5/RT/User_Vendor.pm:538)
[Thu Nov  6 05:02:02 2008] [info]: RT::User::LookupExternalUserInfo : Returning:  EmailAddress: , Name: , RealName:  (/usr/share/perl5/RT/User_Vendor.pm:703)
[Thu Nov  6 05:02:02 2008] [debug]: RT::User::LookupExternalUserInfo No user was found this time (/usr/share/perl5/RT/User_Vendor.pm:706)
[Thu Nov  6 05:02:02 2008] [debug]: Attempting to use this canonicalization key: RealName (/usr/share/perl5/RT/User_Vendor.pm:417)
[Thu Nov  6 05:02:03 2008] [debug]: LDAP Search ===  Base: dc=corp,dc=example,dc=org == Filter: (&(objectclass=user)(cn=Bryan McLellan)) == Attrs: l,cn,st,mail,sAMAccountName,co,streetAddress,postalCode,telephoneNumber,sAMAccountName,physicalDeliveryOfficeName,sAMAccountName (/usr/share/perl5/RT/User_Vendor.pm:538)
[Thu Nov  6 05:02:03 2008] [info]: RT::User::LookupExternalUserInfo : Returning:  Address1: , City: , Country: , EmailAddress: bryanm@widemile.com, ExternalAuthId: bryanm, Gecos: bryanm, Name: bryanm, Organization: , RealName: Bryan Mclellan, State: , WorkPhone: 206-985-7171 x117, Zip:  (/usr/share/perl5/RT/User_Vendor.pm:703)
[Thu Nov  6 05:02:03 2008] [info]: RT::User::CanonicalizeUserInfo returning Address1: , City: , Comments: Autocreated on ticket submission, Country: , Disabled: 0, EmailAddress: bryanm@widemile.com, ExternalAuthId: bryanm, Gecos: bryanm, Name: bryanm, Organization: , Password: , Privileged: 0, RealName: Bryan Mclellan, State: , WorkPhone: 206-985-7171 x117, Zip:  (/usr/share/perl5/RT/User_Vendor.pm:444)
[Thu Nov  6 05:02:03 2008] [crit]: User creation failed in mailgateway: Name in use (/opt/rt3/bin/../lib/RT/Interface/Email.pm:244)
[Thu Nov  6 05:02:04 2008] [warning]: Couldn't load user 'test@example.org'.giving up (/opt/rt3/bin/../lib/RT/Interface/Email.pm:806)
[Thu Nov  6 05:02:04 2008] [crit]: User  'info@imob.org' could not be loaded in the mail gateway (/opt/rt3/bin/../lib/RT/Interface/Email.pm:244)
[Thu Nov  6 05:02:04 2008] [error]: RT could not load a valid user, and RT's configuration does not allow
for the creation of a new user for this email (test@example.org).

You might need to grant 'Everyone' the right 'CreateTicket' for the
queue lposupport. (/opt/rt3/bin/../lib/RT/Interface/Email.pm:244)

How I dealt with KVM host identification

Recently I started researching how a KVM guest could tell who it’s host is. I dug into the KVM code and found in r77 there’s new functionality to pass -uuid on the command line on the host and access it from the qemu monitor. KVM-78 should have bios modifications such that ‘dmidecode’ will return this uuid if passed as well. As noted in that last link, libvirt doesn’t support that yet. Although it’s a trivial change I can’t really wait for all this stuff, nor do I want to take the time to package it.

The existing vmport code in qemu, best I can tell, is used mostly for some vmmouse stuff. I can’t find anywhere than anyone actually uses it. I don’t want to write code to start poking around memory holes, so I threw out the idea of prodding around there.

In the end, I used my infrastructure, again. kvm/libvirt hosts report their guests to iclassify based on hostname:

#!/usr/bin/ruby -w
# This is an iclassify script for updating a libvirt (KVM) host with the list of guests
# Until KVM guests can access their UUID, this will rely on hostname being unique
# 2008-10-28 -- Bryan McLellan 

def update_guests
  local_guests = Array.new
  server_guests = Array.new

  # Get the list of current guest hostnames
  %x[virsh list --all 2>/dev/null].each { |line|

    # ignore header lines, match lines that start with a number ID, grab hostname from second column
    if row = line.match(/^\s+\d+\s+(\S+)/)
      local_guests << row[1]
    end
  }

  unless local_guests.empty?
	  # update the array, and try to give it a break if it's the same
	  server_guests = attrib?("guest-hostname")
	  replace_attrib("guest-hostname", local_guests) unless server_guests == local_guests
  end

end 

if tag?("kvm")
  update_guests
end

Then I could modify my ruby script that displays virt server status, originally written when I was using just vmware servers, to also show kvm/libvirt hosts:

client = IClassify::Client.new(config[:server], config[:user], config[:passwd])

vmwarehosts = client.search('(tag:vmware-server OR tag:kvm) AND NOT tag:workstation', [])

vmwarehosts.sort_by { |node| node.description }.each do |node|

  puts node.description
  puts "\tmemory free/total: " + node.attrib?('memoryfree').gsub!(/[^0-9.]/,"") + "/" + node.attrib?('memorysize') \
    + "\tswap free/total: " + node.attrib?('swapfree').gsub!(/[^0-9.]/,"") + "/" + node.attrib?('swapsize')
  print "\tguests: "

  # remember that node.description and friends aren't always clean
  guests = client.search("vmwarehost:#{node.attrib?('hostname')}", [])
  guests.sort_by { |node| node.description }.each do |guest|
    print "#{guest.attrib?('hostname')} "

  end
  if node.attrib?("guest-hostname")
    node.attrib?("guest-hostname").each { |guest| print "#{guest} " }
  end
  puts "\n"
end

And I guess that works for me for now. Later it’ll be nice to use the host and guests’s real UUID as the iclassify uuid. That’s a project for another day.

Mounting KVM qcow2 qemu disk images

qcow2 images are not flat files, see qemu-img(1). KVM ships with qemu-nbd, which lets you use the NBD protocol to share the disk image on the network.

First, for partition nbd partition support you need to be running kernel 2.6.26 (commit, changelog) or greater. For ubuntu users, that means it’s time to upgrade to intrepid ibex. Load the nbd module with:

sudo modprobe nbd max_part=8

If you leave off the max_part attribute, partitions are not supported and you’ll be able to access the disk, but not have device nodes for any of the partitions. Running

sudo qemu-nbd root.qcow2

will bind to all interfaces (0.0.0.0) and share the disk on the default port (1024). It’s important to note that the nbd kernel module produces /dev/nbd0 while the nbd-client man page recommends /dev/nb0 in it’s examples. The error message isn’t so clear, see lp:290076.

# nbd-client localhost 1024 /dev/nb0
Error: Can not open NBD: No such file or directory

This can all be reduced in steps using the ‘–connect’ option of qemu-nbd, like this:

sudo qemu-nbd --connect=/dev/nbd0 root.qcow2

At which point you can view the disk partitions:

sudo fdisk /dev/nbd0

or mount a disk, such as

mount /dev/nbd0p1 /mnt

KVM: Who’s your daddy?

I guess I never blogged about the VMWare solution to this. I wanted a node to detect if it was a VMWare guest, and if it was, to register the name of it’s host as an iClassify attribute. Originally the solution to know what VMWare server host a guest was on was to put it in it’s hostname when you created the node, like ‘vm03-somecrap’. That just sucked. With the information in iclassify, it was easy to write a ruby script to give me a list of hosts and their guests. And that worked alright. I’d run a script on the host against each guest something like:

#!/bin/bash
VMWARECMD=/usr/bin/vmware-cmd

# vmware config files returned by 'vmware-cmd -l' often have spaces, by default bash for treats spaces as a field seperator
IFS=$'\n'

if [ "$1" == "" ]; then
  echo $0: requires vmware host hostname as an argument
  exit 1
fi

for config in `$VMWARECMD -l` ; do
  $VMWARECMD "$config" setguestinfo host $1
done

Which one could then read on the guest if the vmware-guest tools where installed with:

/usr/sbin/vmware-guestd --cmd 'info-get guestinfo.host'

Finding the syntax for vmware-guestd took forever. I don’t know why I didn’t blog that.

I want to do something similar for KVM. I use libvirt, so the first step was looking at the configuration file options for libvirt and the command line options for qemu to see if anything nice matched up. I played a bit with the serial pipe option, which you can use even though it’s not listed on the libvirt page because I saw it in the source, but I couldn’t get it to do much. I had thought about having a daemon return hostname or such to the FIFO whenever queried with a \n or something.

I figured I could find something to pass to the kernel cmdline in an append option, but I really don’t want to have to template the libvirt template files just to stuff a hostname in there.

I really want something I can pass to SMBIOS that I can pull with dmidecode on the guest. I started digging into the LinuxBIOS/coreboot code that comes with the ubuntu kvm source package and in bios/rombios32.c, I found a function called uuid_probe that sets the uuid variable. I just posted to the coreboot mailing list asking about it. #qemu on irc.freenode.net just got me this when I asked about it:

15:29 < aliguori> in linux bios?  it's stuff that shouldn't be there

Googling for 0x564d5868 revealed it’s indicative of the VMWare backdoor stuff. This lead me to what appears to be some emulation of this called VMPort in QEMU. I have no idea yet what it does, if it ever worked, and thus if I can interact with it yet.

Running multiple nrpe binaries on debian/ubuntu

Silly init scripts. I have two nrpe binaries running on the nagios server, one for it to check the normal things like CPU, disk, etc, and one for an external nagios server to connect and make sure that nagios is running. For basic security reasons, these use different nrpe config files with a seperate set of plugins.

But the init script has to be modified so they don’t kill each other. I made a link from ‘/usr/sbin/nrpe-ext’ to ‘/usr/sbin/nrpe’ then copied ‘/etc/init.d/nagios-nrpe-server’ to ‘/etc/init.d/nagios-nrpe-server-ext’

Make the following modification to both so they don’t kill each other:

52c52
< 	start-stop-daemon --stop --quiet --oknodo --exec $DAEMON
---
> 	start-stop-daemon --stop --quiet --oknodo --name $NAME
57c57
< 	start-stop-daemon --stop --signal HUP --quiet --exec $DAEMON
---
> 	start-stop-daemon --stop --signal HUP --quiet --name $NAME

Then make these changes to nagios-nrpe-server-ext so it starts a unique process:

5c5
< # Provides:          nagios-nrpe-server
---
> # Provides:          nagios-nrpe-server-ext
17,20c17,20
< DAEMON=/usr/sbin/nrpe
< NAME=nagios-nrpe
< DESC=nagios-nrpe
< CONFIG=/etc/nagios/nrpe.cfg
---
> DAEMON=/usr/sbin/nrpe-ext
> NAME=nrpe-ext
> DESC=nagios-nrpe-ext
> CONFIG=/etc/nagios/nrpe-ext.cfg

And update nagios-nrpe-server so it works with our new invocation of start-stop-daemon:

18c18
< NAME=nagios-nrpe
---
> NAME=nrpe

KVM Virtio network performance

I’ve switched my production infrastructure from VMWare server to KVM and libvirt recently. I’ve been working on moving from ubuntu-vm-builder to python-vm-builder (now just vm-builder). Nick Barcet made a tree while we were talking about the lack of a bridging option that adds a ‘–net-virtio’ option. So I started using virtio on a new libvirt guest for networking.

On the guest, lspci will show this device when using virtio:

00:03.0 Ethernet controller: Qumranet, Inc. Unknown device 1000

From the host, in simple tests (‘ping -c100 guestname’) aren’t all that different and are pretty statistically useless.

with virtio:

100 packets transmitted, 100 received, 0% packet loss, time 99012ms
rtt min/avg/max/mdev = 0.113/0.387/0.821/0.065 ms

without virtio:

100 packets transmitted, 100 received, 0% packet loss, time 99007ms
rtt min/avg/max/mdev = 0.143/0.200/0.307/0.032 ms

Running iperf with the server on the guest and the client on the host produces:

with virtio:

------------------------------------------------------------
Client connecting to virtio, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  3] local 10.0.1.172 port 54168 connected with 10.0.1.33 port 5001
[  3]  0.0-10.0 sec  1.34 GBytes  1.15 Gbits/sec

without virtio:

------------------------------------------------------------
Client connecting to novirtio, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  3] local 10.0.1.172 port 34414 connected with 10.0.1.13 port 5001
[  3]  0.0-10.0 sec    375 MBytes    315 Mbits/sec

So that’s better. Both guests are Ubuntu 8.04.1 running 2.6.24-19-server SMP x86_64 with 1 vcpu and 768MB of RAM. Host has 8GB of RAM, same kernel and distro, with 8 CPUs (Xeon’s with HT and all that crap).

Access is denied when saving files from Office 2007 on Vista to a redirected documents folder

Client is Office 2007 on Vista, saving to ‘Document’s which is redirected folder on a Server 2003 R2 file share. Whenever saving files you get “access is denied” and it creates a 0KB file, but you can copy the file there in explorer no problem. As a side note, offline files and folders is also enabled.

It’s related to SMB2, which is Vista + Server 2008 tricks. See KB 296264 about ensure that opportunistic locks are enabled in the registery on the server.

Consumer hardware in enterprise environments

Sunday, 6:55AM: The CEO of my last startup, which laid off the entire development team over a year ago calls my cellphone to report a total network outage. He has an international trip that he’s leaving on and needs to get into his email to coordinate his trip. Too bad they laid off everyone that could help, with prejudice.

I wrapped up my social plans and went in to the data center last night. The workstation in the lab couldn’t reach the domain controllers on another subnet, so it lacked a DHCP address as well. I narrowed it down to the Netgear GSM7324 L3 Switch that was being used in the core. A purchase of my predocessor there, I always looked at it funny. Netgear’s one foray into enterprise routing that I’ve ever seen, I didn’t care for it much. It’s CLI tried to be a Cisco, but was substantially different so it only served to confuse people with Cisco experience (the dell gear is much closer at the UI emulation, for the record).

I drag out a serial console to reveal:

Timebase: 33.000000 MHz, MEM: 132.000000 MHĂș

NetGear Boot code......

Flash size = 16MB

Testing 128MB SDRAM..............................Pass

Unknown PCI devices.
PCI devices found -
Motorola MPC8245
Select an option. If no selection in 10 seconds then
operational code will start.

1 - Start operational code.
2 - Start Boot Menu.
Select (1, 2):

Operational Code Date: Thu Aug  3 22:43:40 2006
Uncompressing.....

50%                     100%
||||||||||||||||||||||||||||||||||||||||||||||||||
Attaching interface lo0...done

Adding 36274 symbols for standalone.

Unknown box topology

This is apparently common for people that take the plunge and try to save some money over buying a tried and true piece of equipment for their core. There lineup has a few newer, more expensive, models. The GSM7324 still sits at the lowest price point for a Netgear L3 switch though, luring those in thinking that there’s no tradeoff in price.

So apart came all the trunks and redundant switch links. There was enough redundancy in the physical cabling to the edge switches that I could switch to access links for each subnet. I chained all the switches back together, like it was when I first started, and set up routing on a [Juniper] Netscreen 50 instead, being the only alternative. Everything started coming back up as I dig through the network in search of the original static routing entries that I never found the time to upgrade.

How important is network administration? Too important for system administrators to get away with not knowing. A colleague was recently complaining that he couldn’t get an interviewee to answer why having two physical separate switches is better than having one. I find all of this unfortunate and trying, when I have had to re-architect every network I’ve inherited since moving to Seattle. Sometimes I think we should go back to yelling about the 5-4-3 rule on a soapbox so we’ll at least get a sane switch topology. Hopefully by the time they realize why the 5-4-3 rule doesn’t apply anymore, they’ll have picked up why switch topology is too important to be a matter of just plugging switches together like they’re power strips. Because that’s a great pet peeve too.

rubygems super slow

On any Debian Etch or Ubuntu Hardy box, running gem tends to do a source update (‘Bulk updating Gem source index for: http://gems.rubyforge.org/’) and go super slow. Especially on low memory virtual machines. I could put in a purchase order for another 40GB of RAM, oorrrr…. Rumors were that newer versions of rubygems were better, so I went about upgrading hardy the debian way. And it’s much better.

Put intrepid in your sources.list. Puppet manages mine for my network so I use sources.list.d:

/etc/apt/sources.list.d/intrepid.sources.list:
deb-src http://mirrors.cat.pdx.edu/ubuntu/ intrepid main restricted universe multiverse
deb-src http://mirrors.cat.pdx.edu/ubuntu/ intrepid-updates main restricted universe multiverse
deb-src http://security.ubuntu.com/ubuntu intrepid-security main restricted universe multiverse

Then (basically)

sudo apt-get update
mkdir /tmp/rubydeb
cd /tmp/rubydeb
sudo apt-get build-dep ruby1.8 ruby1.9 rubygems
sudo apt-get source ruby1.8 ruby1.9 rubygems
# run dpkg-buildpackage -rfakeroot in ruby1.8 and ruby1.9
# sudo dpkg -i the resulting appropriate debs (you need ruby1.9 to build rubygems)
# run dpkg-buildpackage -rfakeroot in rubygems
sudo apt-get remove libgems-ruby1.8 rubygems
# sudo dpkg -i the new rubygems deb

Everything seems good, life seems better.

BackupExec 12.0 RALUS on debian/ubuntu

A recent upgrade of BE forced out the old legacy unix agent that was a single binary and easy to script, making us use RALUS. Could have been worse. The manual install is a bit sketch, someone noted that alien could convert the rpm’s, so I started there. I found the rpms in tgz files under ‘pkgs/Linux’ and ‘RALUS64/pkgs/Linux’ for both architectures. I ran alien on an x86 and an x64 box to create a full set. The debs don’t have dependency information, but I just dealt with that with puppet because it was quicker. Ignore the errors about alien not creating postrm/postinst scripts, they’re no big deal.

RALUS wants the user that connects to have beoper as a secondary group. Also you need libstdc++5 installed. Here’s a self-documenting puppet recipe, in case there are more questions:

class ralus {

  realize User["beoper"]
  realize Group["beoper"]

  package { "vrtsvxmsa":
    ensure => installed,
  }

  package { "libstdc++5":
    ensure => installed,
  }

  package { "vrtsralus":
    ensure => installed,
    require => [ Package["vrtsvxmsa"], Package["libstdc++5"] ],
  }

  exec { "ralus-init":
    command => "/bin/cp /opt/VRTSralus/bin/VRTSralus.init /etc/init.d/ralus",
    require => Package["vrtsralus"],
    onlyif => "/usr/bin/test ! -x /etc/init.d/ralus",
  }

  service { "ralus":
    ensure => running,
    enable => true,
    require => [ Exec["ralus-init"], User["beoper"] ],
  }
}

fixing OCS 2007 for LM with lcscmd

Live Meeting cannot connect to the meeting.
Wait a few moments, and then try to join the meeting again.
If you still cannot connect, contact your administrator or technical support.

See Microsoft KB #938288.

Lots of ‘lcscmd’ options (in \Program Files\Common Files\Microsoft Office Communications Server 2007) require a pool name. I eventually found it with ‘lcscmd /forest /action:checkallpoolsstate’, where I saw a line that said ‘Executing “Check Pool BLAH”‘ where BLAH was my pool name. Even easier, in the MMC applet, the first container under ‘Standard Edition Servers’ is the pool, the one that doesn’t specify the FQDN.

Get on your full server, not the edge server, and from the above directory run:

lcscmd /web /action:clearpoolexternalurls /poolname:POOLNAME
lcscmd /web /action:updatepoolurls /externalwebfqdn:conference.example.org /poolname:POOLNAME

Their example just shows ‘contoso.com’ as the fqdn. That’s a little sketchy, being a domain name that might point to a web server. There’s little explanation as to which IP address (host) on the edge that should go to. I have the hostname of my web conference edge server there. After running this the clients could connect to live meeting without a restart of OCS (LCS).

running god inside runit

God ignores the TERM signal. Maybe this is a ruby thing? I’m not really going to bother looking. But when trying to run God inside runit, which normally sends a TERM when you tell it to stop a process; this is no good. It looks like God ignores HUP if run as a daemon:

      def run_daemonized
        # trap and ignore SIGHUP
        Signal.trap('HUP') {}

In which case the only way I could find to stop it is with an INT signal. But HUP will kill it when run non-daemonized with the “-D” option. I guess mysql and other daemons do this sorta thing too and I got the idea from this thread. For other processes see this archive of runit scripts for something that works or examples. Anyways, my runit run script for god:

#!/bin/sh
exec 2>&1

trap 'kill -HUP %1' 1 2 13 15

/usr/bin/god -D -c /etc/god/master.god --log-level debug --no-syslog & wait