Sunday, 29 April 2012

Migrating/Exporting Zenoss reports (possiblly other objects)

If you are familiar with Zenoss, you should already know that many objects and organizers can be added to ZenPacks that can be used to copy them to other servers. Surprisingly, there is no facility for adding reports(multi-graph or graph reports) to a ZenPack! Thus, I decided to develop a simple script that can export them as XML file which eventually can be fed into Zenoss zenload command. In following you can add top level organizers to topOrg that will be used to export everything inside including all sub-organizers and reports.
import Globals 
import os, sys, commands 
from Products.ZenUtils.ZenScriptBase import ZenScriptBase 
from xml.dom.minidom import parse, parseString 
import StringIO 
filename = '/home/zenoss/exported-reports.xml' 
topOrg = [ 'Reports/Multi-Graph Reports/MyReports', 'Reports/Graph Reports/Devices']

 
if __name__ == '__main__': 
    dmd = None 
    try: 
        scriptBase = ZenScriptBase(connect=True) 
        dmd = scriptBase.dmd 
    except Exception, e: 
        print "Exception found while trying to connect zenoss and exception is %s" %(str(e)) 
    if dmd is None: 
        print "Can't connect to Zenoss - are you sure it's running?" 
        sys.exit(2) 

    try: 
        f = open(filename, 'a') 
    except Exception, e: 
        print "Exception found while opening the file %s to write and exception is %s" %(filename, str(e)) 
        sys.exit(3) 
    orgList = [] 
    for x in topOrg: 
        org = dmd.Reports.getObjByPath(x) 
        orgList.append(org) 
        for y in org.getSubOrganizers(): 
           orgList.append(y) 

    f.write('\n') 
    f.write('\n') 
    for org in orgList: 
        print 'Processing %s' % org 
        stringIO = StringIO.StringIO() 
        org.exportXml(stringIO) 
        xml = parseString(stringIO.getvalue()) 
        xml.getElementsByTagName('object')[0].setAttribute('id', "/zport/dmd%s" % org.getPrimaryDmdId()) 
        f.write(xml.firstChild.toxml()) 
        for report in org.reports(): 
           stringIO = StringIO.StringIO() 
           report.exportXml(stringIO) 
           xml = parseString(stringIO.getvalue()) 
           xml.getElementsByTagName('object')[0].setAttribute('id', "/zport/dmd%s" % report.getPrimaryDmdId()) 
           f.write(xml.firstChild.toxml()) 
    f.write('\n') 
To load them back:
zenload -i /home/zenoss/exported-reports.xml
This script can be modified to export any object and organizer in Zenoss. Note that zenload can be used to import any objects.xml file included in any ZenPacks(in objects folder). This is handy when you don't want to end up with having multiple importing/exporting ZenPacks in your ZenPacks list. Have fun;)

Saturday, 25 February 2012

Building Centos 6 KVM Virtual Host via Standalone Puppet

This is a sample quick install that I did to create a KVM VM Host Centos 6.2 physical machine and one Guest VM bridged on physical network. I normally don't like to use puppetmaster or run puppet automatically as daemon. Therefore, puppet configs are shared via NFS. You would possibly like to review and change bits to fit your needs. The Host is using 192.168.0.40 as IP and the Guest is 192.168.0.41. This installation is ideal if you have a server in a data center and would like to use it to its max by having multiple VMs inside. One architecture which I would recommend is to use the Host as Apache ProxyPass to VMs. For extra security you may use private NATed IPs for Guests. This way you will need only a single public IP on Host, exposing all backend web or application VM servers and possibly even load-balancing them. I used http://blog.mattbrock.co.uk/2012/02/12/virtualisation-with-kvm-and-lvm-on-centos-6-via-the-command-line/ as a reference to do this. Therefore, I highly recommend to read it first. It has nice hints for managing the VMs. Once you did the first Guest VM installed, you may clone it to create more.

1- For VM Host, do basic server install. Following is partial ks file. Nothing interesting here. Just remember to create a Physical Volume to host VMs. It gives better performance compared to flat file system.

part / --fstype=ext4 --onpart=sda1
part swap --onpart=sda2
part pv.008003 --onpart=sda3

repo --name="CentOS"  --baseurl=cdrom:sr1 --cost=100

%packages
@base
@client-mgmt-tools
@console-internet
@core
@debugging
@directory-client
@hardware-monitoring
@java-platform
@large-systems
@network-file-system-client
@performance
@perl-runtime
@server-platform
@server-policy
pax
oddjob
sgpio
certmonger
pam_krb5
krb5-workstation
perl-DBD-SQLite
%end

2- Install Extra repo(obviously this can be scripted):
[root@vmhost ~]# rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm
# Disable it
[root@vmhost yum]# sed -i  "s/enabled=1/enabled=0/g" /etc/yum.repos.d/epel.repo
# Install puppet
[root@vmhost yum]# yum -y install --enablerepo=epel puppet
3- Create /mnt/build to host puppet files. This will be NFS exported so that Guests can access puppet file.
4- Create /mnt/build/vmhost-manifest.pp with following config:
class build-host {
# Some preperation
        file {'motd':
              ensure  => file,
              path    => '/etc/motd',
              mode    => 0644,
              content => "Welcome to ${::fqdn} with IP ${::ipaddress},\nan ${::architecture} ${::operatingsystem} machine part of ${::domain}.\n",
                }

# Setting up bridge network
        file {'eth0':
              ensure  => file,
              path    => '/etc/sysconfig/network-scripts/ifcfg-eth0',
              mode    => 0644,
              content => "DEVICE=\"eth0\"\nNM_CONTROLLED=\"yes\"\nONBOOT=yes\nTYPE=Ethernet\nBRIDGE=\"br0\"\n",
              require => File['br0']
                }

        file {'br0':
              ensure  => file,
              path    => '/etc/sysconfig/network-scripts/ifcfg-br0',
              mode    => 0644,
              content => "DEVICE=\"br0\"\nONBOOT=yes\nTYPE=Bridge\nBOOTPROTO=none\nIPADDR=192.168.0.40\nPREFIX=24\nGATEWAY=192.168.0.1\nDNS1=192.168.0.1\nDEFROUTE=yes\nIPV4_FAILURE_FATAL=yes\nIPV6INIT=no\n",
              require => Package['bridge-utils']
                }

        exec {'restart_network' :
                        command => "/etc/init.d/network restart", 
                        require => File['br0'],
                        unless => "/sbin/ifconfig | grep virbr",    
                }

# Adding Volume Group to Physical Volume
        $vms = "/dev/sda3"
        exec {'volume_group' :
                        command => "/sbin/vgcreate  vms ${vms}",
                        unless => "/sbin/vgdisplay 2>&1| grep vms",
                }

        exec {'vm0root' :
                        command => "/sbin/lvcreate -L 10G -n vm0-root",
                        unless => "/sbin/lvdisplay 2>&1| grep vm0-root",
                }

        exec {'vm0swap' :
                        command => "/sbin/lvcreate -L 4096M -n vm0-swap",
                        unless => "/sbin/lvdisplay 2>&1| grep vm0-swap",
                }

# Disabling SELinux
        if $selinux != 'false' {
                exec {"disable_selinux_enforcement":
                        command => "/bin/sed -i s/SELINUX=.*/SELINUX=disabled/g /etc/sysconfig/selinux  && /bin/sed -i s/SELINUX=.*/SELINUX=disabled/g /etc/selinux/config", }

                notify {"SELinux disabled! Please reboot!" : require => Exec['disable_selinux_enforcement'], }
        }

# Setting up NFS export for Guest VMs to access puppet configs
        file { '/mnt/build' :
                ensure => "directory", }
        exec {"export_puppet" :
                command => '/bin/echo "/mnt/build 192.168.0.0/24(r)" >> /etc/exports',
                unless => '/bin/grep mnt\/build /etc/exports',
                require => File['/mnt/build']
                }


# Package install
        package{'qemu-kvm' : ensure => installed, } 
        package{'libvirt' : ensure => installed, }
        package{'python-virtinst' : ensure => installed, }
        package{'bridge-utils' : ensure => installed, }
        package{'httpd' : ensure => installed, }
        package{'screen' : ensure => installed, }
        package{'createrepo' : ensure => installed, }

# Turning on and off service resources
        # Turning on used services
        service { 'libvirtd':  ensure => 'running', enable => 'true', hasstatus => true, }
        service { 'avahi-daemon':  ensure => 'running', enable => 'true', hasstatus => true, }
        service { 'libvirt-guests':  ensure => 'running', enable => 'true', hasstatus => true, }
        service { 'ntpd':  ensure => 'running', enable => 'true', hasstatus => true,}
        service { 'ntpdate':  ensure => 'running', enable => 'true', hasstatus => true,}
        service { 'httpd':  ensure => 'running', enable => 'true', hasstatus => true, require => Package['httpd'],}
        service { 'rpcbind':  ensure => 'running', enable => 'true',  hasstatus => true,}
        service { 'nfs':  ensure => 'running', enable => 'true',  hasstatus => true, require => Service['rpcbind'],}
        # Turning off un-used services
        service { 'abrt-ccpp':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'abrt-oops':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'abrtd':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'atd':  ensure => 'stopped', enable => 'false', hasstatus => true, }
        service { 'auditd':  ensure => 'stopped', enable => 'false', hasstatus => true, }
        service { 'autofs':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'cups':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'ip6tables':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'iptables':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'iscsi':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'netfs':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'nfslock':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'portreserve':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'qpidd':  ensure => 'stopped', enable => 'false',  hasstatus => true,}
        service { 'rpcidmapd':  ensure => 'stopped', enable => 'false',  hasstatus => true,}



# Package['Server Platform'] -> File['/home/dwilson/repos/'] -> Notify['Hello']

  
}

node default {
  include build-host
}

5- Run 'puppet -v /mnt/build/vmhost-manifest.pp' to apply all changes.
6- Run 'brctl show' to check bridge interface.
7- To create an accessible repo for your Guests, mount Centos 6.2 minimal install CD on /mnt/cdrom.
8- cp -rf /mnt/cdrom/. /var/www/html/centos/x86_64
9- In /var/www/html/centos/x86_64, modify .treeinfo to have following:
[images-x86_64]

kernel = isolinux/vmlinuz
initrd = isolinux/initrd.img

10- Create vm0-ks.cfg KickStart file on the apache root as:
[root@vmhost ~]# cat /var/www/html/vm0-ks.cfg 
#KS file for VM

install
url --url http://192.168.0.40/centos/x86_64

# Use logical volumes
zerombr
clearpart --all --initlabel
#clearpart --none
bootloader --location=mbr --driveorder=vda,vdb --append=" rhgb crashkernel=auto quiet"
part / --fstype ext4 --size 1 --grow --ondrive=vda
part swap --size 1 --grow --ondrive=vdb

# Kickstart file automatically generated by anaconda.

#version=DEVEL
lang en_US.UTF-8
keyboard us-acentos
network --onboot yes --device eth0 --bootproto static --ip 192.168.0.41 --netmask 255.255.255.0 --gateway 192.160.0.1 --noipv6 --nameserver 192.168.0.1 --hostname web.local
rootpw  letmein
firewall --disabled
authconfig --enableshadow --passalgo=sha512
selinux --disabled
timezone --utc Europe/London


#part / --fstype=ext4 --grow --asprimary --size=200

#part swap --grow --asprimary --size=200

#repo --name="CentOS"  --baseurl=cdrom:sr0 --cost=100

%packages --nobase
@core

11- Create VM by:

virt-install --name=vm0 --cpuset=1 --ram=1024 --arch=x86_64 --network bridge=br0 --disk=/dev/mapper/vms-vm0--root --disk=/dev/mapper/vms-vm0--swap --location http://192.168.0.40/centos/x86_64/ --vnc --vnclisten=0.0.0.0 --noautoconsole --extra-args "ks=http://192.168.0.40/vm0-ks.cfg" --virt-type kvm --os-variant rhel6

12- To watch the progress vnc to your Host as above command creates a one extra screen for you.

13- To backup your Guest VM use following script:
#!/bin/sh
if [ $1 ]
then
virsh suspend $1;
lvcreate -L 100M -n $1-root-snapshot -s /dev/vms/$1-root;
virsh resume $1;
dd if=/dev/mapper/vms-$1--root--snapshot | gzip > ./$1-root.img.gz;
lvremove /dev/mapper/vms-vm0--root--snapshot
else
echo "Please specify the vm name"
fi

Enjoy!

Wednesday, 27 July 2011

Preparing IDE and development environment for Zenoss - part1

Finding a good IDE for Zenoss development can sometimes be tricky. Most people resort to use ssh and vim to do the job. Although I like vim a lot, however, it is not the editor of my choice for big jobs. I find a balance of mouse and keyboard short-cuts easier and quicker to use. This is the first part which discusses preparing a VM Dev environment. In part2 I will cover the actual IDE setup.

1- Download the latest VMWare Image from http://community.zenoss.org/docs/DOC-3240?noregister. I am using 32bit 3.1.0 at the time of writing this.
2- I prefer VBox instead of VMWare, so extracted the image, imported in VBox 4.0.12 and added it as a Red Hat Linux guest loading the VMWare harddrive. Then changed the advanced setting of Network interface to use Intel 1000 MT Desktop network adapter instead of PCnet. If you don't do this, your network interface won't come up after boot. After boot login username:root password: zenoss. Remove vmware tools by running vmware-uninstall-tools.pl. Note this step won't be needed if you want to use VMWare. In that case, you just need to run the image and login.
3- Assuming your network works with Internet then run yum groupinstall gnome-desktop
4- Run yum install setuptool system-config-display system-config-network system-config-services system-config-securitylevel gcc make
5- run passwd zenoss to set a password for zenoss user I have put the default 'zenoss'
6- run system-config-display to create initial X config
7- run system-config-securitylevel-tui and then disable SELinux
8- From Vbox menu select install guest additions, this will mount Guest ISO Virtual CD
9- run mount /dev/cdrom /media to mount guest additions
10- Now logout from root and log back in with zenoss user and the password you set
11- run startx, this should bring full gnome desktop which will be in low resolution
12- Open a terminal shell and run following command in it:

[zenoss@localhost ~]$ su - --session-command=/media
                                     /VBOXADDITIONS_4.0.12/VBoxLinuxAdditions.run

This should build whole guest additions successfully. As mentioned if you decided to go with VMWare you won't need to do this step and step 9. I haven't tested that scenario though. After installation you will need to reboot.
13- Login with zenoss user and run startx, now you should have a full blown gnome desktop with all guest VM bells and whistles including shared folders and copy paste.

I personally use a shared folder for project development as I can access source code both from VM and Host OS. To do that you might want to take a look at my older post virtualbox-and-guest-ubuntu-shared

This will continue in part 2...

Tuesday, 14 June 2011

PS process State codes

PROCESS STATE CODES
Here are the different values that the s, stat and state output specifiers
(header "STAT" or "S") will display to describe the state of a process.
D    Uninterruptible sleep (usually IO)
R    Running or runnable (on run queue)
S    Interruptible sleep (waiting for an event to complete)
T    Stopped, either by a job control signal or because it is being traced.
W    paging (not valid since the 2.6.xx kernel)
X    dead (should never be seen)
Z    Defunct ("zombie") process, terminated but not reaped by its parent.

For BSD formats and when the stat keyword is used, additional characters may
be displayed:
<    high-priority (not nice to other users)
N    low-priority (nice to other users)
L    has pages locked into memory (for real-time and custom IO)
s    is a session leader
l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
+    is in the foreground process group

Debugging a Linux process

To debug a compiled C process in RedHat Linux. You will need to install devel and debuginfo of the package you are insterested in. For example to debug python interpreter you will need to install python, python-debuginfo and python-devel packages. Then find the stuck process PID via PS and then:

# gdp --pid <pid num>

Then you will be in gdp prompt. You then can use following commands:

>continue        will continue execution until you press Ctrl-C
>bt                  show backtrace
>next               execute next line
>list                 show source code
>step               step into child function
>finish              execute until finish the current function
>show help      show extra commands that can be used with show
>print <var>    prints content of a variable

Another good tool for debugging is Valgrind

Tuesday, 24 May 2011

Co-routines in Python

Co-routines are very interesting subject in python which enables several routines to feed into each other very similar to unix piping. The good point of this approach is that each routine gets executed onces each bit of data is required. So it is very effiecient in terms of CPU and memory usage. Following link is a great resource on this subject.

http://www.dabeaz.com/coroutines/

Friday, 20 May 2011

Postgresql 9.0 and ident

I was trying to create some monitoring tool for new postgresql 9.0 in a project on RHEL. Spent couple of hours tweaking hba file with no effect! Quite disturbing! Then I found the file was somewhere else due to difference between the 9.0 rpm and the original RH one! Here is the command to find it. Quite useful:

postgres=# show hba_file; 
              hba_file             
-------------------------------------
 /var/lib/pgsql/9.0/data/pg_hba.conf
(1 row)

I found it in this blog, quite other nice things in it.