QuickStart/Ubuntu

This page is a complete getting started guide for Ubuntu.

Note: This particular how to was done on jaunty, but should apply to any other recent version of Ubuntu.

Install Bcfg2

We first need to install the server. This can be done one of two ways--from source or from precompiled binaries.

From Source

Install Prerequisities

For more information see Prereqs

root@jaunty:~# aptitude install debsums python-gamin python-lxml m2crypto
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Reading extended state information      
Initializing package states... Done
Note: selecting "python-m2crypto" instead of the
      virtual package "m2crypto"
The following NEW packages will be installed:
  debsums python-gamin python-lxml python-m2crypto 
0 packages upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 301kB/354kB of archives. After unpacking 1675kB will be used.
Writing extended state information... Done
Get:1 http://us.archive.ubuntu.com jaunty/universe python-m2crypto 0.18.2-2 [301kB]
Fetched 301kB in 1s (181kB/s)           
Preconfiguring packages ...
Selecting previously deselected package debsums.
(Reading database ... 129253 files and directories currently installed.)
Unpacking debsums (from .../debsums_2.0.40_all.deb) ...
Selecting previously deselected package python-gamin.
Unpacking python-gamin (from .../python-gamin_0.1.9-2ubuntu3_amd64.deb) ...
Selecting previously deselected package python-lxml.
Unpacking python-lxml (from .../python-lxml_2.1.5-1_amd64.deb) ...
Selecting previously deselected package python-m2crypto.
Unpacking python-m2crypto (from .../python-m2crypto_0.18.2-2_amd64.deb) ...
Processing triggers for man-db ...
Setting up debsums (2.0.40) ...

Setting up python-gamin (0.1.9-2ubuntu3) ...

Setting up python-lxml (2.1.5-1) ...

Setting up python-m2crypto (0.18.2-2) ...

Processing triggers for python-support ...
Reading package lists... Done             
Building dependency tree       
Reading state information... Done
Reading extended state information      
Initializing package states... Done
Writing extended state information... Done

Build Bcfg2 from source

This example will build the .deb packages from subversion

  • First, follow the instructions here for installing the build prerequisites (essentially you will need to install the following)
    • cdbs docbook-xsl libxslt1.1 python-dev python2.4-dev sgml-base xml-core xsltproc fakeroot build-essential subversion
  • Checkout trunk:
    root@jaunty:~# svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2
    
  • Change to the debian directory of the checked out bcfg2 source
    root@jaunty:~# cd bcfg2/debian/
    root@jaunty:~/bcfg2/debian#
    
  • run ./buildsys-select.sh pycentral
    root@jaunty:~/bcfg2/debian# ./buildsys-select.sh pycentral
    sed \
    		-e "s/@cdbs@/, cdbs (>= 0.4.23-1.1), debhelper (>= 5), debhelper (>= 5.0.37.2), cdbs (>= 0.4.43), python-dev (>= 2.3.5-11), python-central (>= 0.6)/g" \
    		-e "s/^Build-Depends\(\|-Indep\): ,/Build-Depends\1:/g" \
    		\
    		-e "s/^Cpu: .*/Architecture: /g" \
    		-e "/^System: /d" \
    		\
    		-e "s/\[cpu: \([^]]*\)\]/\[\`type-handling \\\\\`echo \1 | tr ' ' ','\\\\\` any\`\]/g" \
    		-e "s/\[system: \([^]]*\)\]/\[\`type-handling any \\\\\`echo \1 | tr ' ' ','\\\\\`\`\]/g" \
    		\
    		-e "s/\"/\\\\\"/g" \
    		-e "s/^/echo \"/g" \
    		-e "s/\\$/\\\\$/g" \
    		-e "s/$/\"/g" \
    	< debian/control.in | /bin/sh > debian/control
    dpkg-checkbuilddeps -B
    test -x debian/rules
    dh_testroot
    dh_clean 
    cd . && python setup.py clean -a
    running clean
    'build/lib' does not exist -- can't clean it
    'build/bdist.linux-x86_64' does not exist -- can't clean it
    'build/scripts-2.5' does not exist -- can't clean it
    rm -f python-build-stamp-*
    find . -name '*.pyc' -exec rm '{}' ';'
    
  • Change back to the root svn directory and build the packages
    root@jaunty:~/bcfg2/debian# cd ../ && fakeroot dpkg-buildpackage -uc -us
    ...
    lots of build output here
    ...
    dpkg-genchanges: including full source code in upload
    dpkg-buildpackage: full upload; Debian-native package (full source is included)
    root@jaunty:~/bcfg2#
    
  • If you don't have them already, you may need to install: libxml2-utils openssl python-cheetah
  • Use dpkg to install your new bcfg2 packages
    root@jaunty:~/bcfg2# cd ..
    root@jaunty:~# dpkg -i *.deb
    Selecting previously deselected package bcfg2.
    (Reading database ... 129354 files and directories currently installed.)
    Unpacking bcfg2 (from bcfg2_1.0pre1-0.0_all.deb) ...
    Selecting previously deselected package bcfg2-server.
    Unpacking bcfg2-server (from bcfg2-server_1.0pre1-0.0_all.deb) ...
    Setting up bcfg2 (1.0pre1-0.0) ...
    Replacing config file /etc/bcfg2.conf with new version
    
    Processing triggers for man-db ...
    Setting up bcfg2-server (1.0pre1-0.0) ...
    Starting Configuration Management Server:  * bcfg2-server
    
    

Using Ubuntu-supplied deb packages

This one is pretty straightforward:

root@jaunty:~# aptitude install bcfg2-server
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Reading extended state information      
Initializing package states... Done
The following NEW packages will be installed:
  bcfg2{a} bcfg2-server graphviz{a} ttf-liberation{a} 
0 packages upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 1879kB of archives. After unpacking 5280kB will be used.
Do you want to continue? [Y/n/?] y
Writing extended state information... Done
Get:1 http://us.archive.ubuntu.com jaunty/universe bcfg2 0.9.5.7-1.1 [148kB]
Get:2 http://us.archive.ubuntu.com jaunty/universe bcfg2-server 0.9.5.7-1.1 [297kB]
Get:3 http://us.archive.ubuntu.com jaunty/main graphviz 2.20.2-3ubuntu1 [429kB]
Get:4 http://us.archive.ubuntu.com jaunty/main ttf-liberation 1.04.93-1 [1005kB]
Fetched 1879kB in 5s (319kB/s)          
Selecting previously deselected package bcfg2.
(Reading database ... 129287 files and directories currently installed.)
Unpacking bcfg2 (from .../bcfg2_0.9.5.7-1.1_all.deb) ...
Selecting previously deselected package bcfg2-server.
Unpacking bcfg2-server (from .../bcfg2-server_0.9.5.7-1.1_all.deb) ...
Selecting previously deselected package graphviz.
Unpacking graphviz (from .../graphviz_2.20.2-3ubuntu1_amd64.deb) ...
Selecting previously deselected package ttf-liberation.
Unpacking ttf-liberation (from .../ttf-liberation_1.04.93-1_all.deb) ...
Processing triggers for man-db ...
Setting up bcfg2 (0.9.5.7-1.1) ...
Replacing config file /etc/bcfg2.conf with new version

Setting up bcfg2-server (0.9.5.7-1.1) ...
Starting Configuration Management Server:  * bcfg2-server

Setting up graphviz (2.20.2-3ubuntu1) ...

Setting up ttf-liberation (1.04.93-1) ...
Updating fontconfig cache for /usr/share/fonts/truetype/ttf-liberation
No CIDSupplement specified for Batang-Bold, defaulting to 0.
No CIDSupplement specified for Batang-Regular, defaulting to 0.
No CIDSupplement specified for UMingCN, defaulting to 0.
No CIDSupplement specified for Dotum-Bold, defaulting to 0.
No CIDSupplement specified for Dotum-Regular, defaulting to 0.

Reading package lists... Done             
Building dependency tree       
Reading state information... Done
Reading extended state information      
Initializing package states... Done
Writing extended state information... Done

NOTE: You may have more dependencies if you haven't installed them already.

Initialize your repository

Now that you're done with the install, you need to intialize your repository and setup your bcfg2.conf. bcfg2-admin init is a tool which allows you to automate this.

root@jaunty:~# bcfg2-admin init
Store bcfg2 configuration in [/etc/bcfg2.conf]: 
Location of bcfg2 repository [/var/lib/bcfg2]: 
Input password used for communication verification (without echoing; leave blank for a random):
Input the server location [https://jaunty:6789]: 
Input base Operating System for clients:
1: Redhat/Fedora/RHEL/RHAS/Centos
2: SUSE/SLES
3: Mandrake
4: Debian
5: Ubuntu
6: Gentoo
7: FreeBSD
: 5
Generating a 1024 bit RSA private key
......++++++
.................++++++
writing new private key to '/etc/bcfg2.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:
Repository created successfuly in /var/lib/bcfg2

Of course, change responses as necessary.

Start the server

You are now ready to start your bcfg2 server for the first time.

root@jaunty:~# /etc/init.d/bcfg2-server start
root@jaunty:~# tail /var/log/syslog
Feb 18 14:57:24 jaunty bcfg2-server[7384]: Processed 16 gamin events in 0.193 seconds. 0 collapsed
Feb 18 14:57:39 jaunty bcfg2-server[7384]: Bound to port 6789

Run bcfg2 to be sure you are able to communicate with the server

root@jaunty:~# bcfg2 -vqn
no server x509 fingerprint; no server verification performed!
Loaded tool drivers:
 APT          Action       DebInit      FreeBSDInit  POSIX       

Phase: initial
Correct entries:	0
Incorrect entries:	0
Total managed entries:	0
Unmanaged entries:	1281


Phase: final
Correct entries:	0
Incorrect entries:	0
Total managed entries:	0
Unmanaged entries:	1281

The fingerprint message is just a warning. However, if you would like to get rid of it, you can do the following:

root@jaunty:~# bcfg2-admin fingerprint
3cd391ea130e9490872b463eb9fd329cba82807c

You will take this fingerprint and paste it into your bcfg2.conf file in the [communication] section:

root@jaunty:~# cat /etc/bcfg2.conf 

[server]
repository = /var/lib/bcfg2
plugins = Base,Bundler,Cfg,Metadata,Pkgmgr,Rules,SSHbase

[statistics]
sendmailpath = /usr/lib/sendmail
database_engine = sqlite3
# 'postgresql', 'mysql', 'mysql_old', 'sqlite3' or 'ado_mssql'.
database_name =
# Or path to database file if using sqlite3.
#<repository>/etc/brpt.sqlite is default path if left empty
database_user =
# Not used with sqlite3.
database_password =
# Not used with sqlite3.
database_host =
# Not used with sqlite3.
database_port =
# Set to empty string for default. Not used with sqlite3.
web_debug = True


[communication]
protocol = xmlrpc/ssl
password = 2kThtr8y
key = /etc/bcfg2.key
# fingerprint of server (from bcfg2-admin fingerprint)
fingerprint = 3cd391ea130e9490872b463eb9fd329cba82807c

[components]
bcfg2 = https://jaunty:6789

Now if you run the client, no more warning

root@jaunty:~# bcfg2 -vqn
Loaded tool drivers:
 APT          Action       DebInit      FreeBSDInit  POSIX       

Phase: initial
Correct entries:	0
Incorrect entries:	0
Total managed entries:	0
Unmanaged entries:	1281


Phase: final
Correct entries:	0
Incorrect entries:	0
Total managed entries:	0
Unmanaged entries:	1281

Bring your first machine under Bcfg2 control

Now it is time to get your first machine's configuration into your Bcfg2 repository. Let's start with the server itself.

There are two ways to go about building your base config. The first way is slightly quicker and easier. The second way involves setting up DBStats in order to hold the extra package information which can be used to generate the listing for you.

Quick and Easy

First, create a base file containing all installed packages

root@jaunty:~# cat create-base.sh 
echo "<Base><Group name=\"jaunty\">" > /tmp/jaunty.xml
dpkg -l | grep ^ii | awk '{print "<Package name=\"" $2 "\"/>"}' >> /tmp/jaunty.xml
echo "</Group></Base>" >> /tmp/jaunty.xml
root@jaunty:~# sh create-base.sh
root@jaunty:~# cp /tmp/jaunty.xml /var/lib/bcfg2/Base/jaunty.xml

Add a new group jaunty to groups.xml

root@jaunty:~# cat /var/lib/bcfg2/Metadata/groups.xml 

<Groups version='3.0'>
   <Group profile='true' public='true' default='true' name='basic'>
      <Group name='jaunty'/>
   </Group>
   <Group name='jaunty'>
      <Group name='ubuntu'/>
   </Group>
   <Group name='ubuntu'/>
   <Group name='debian'/>
   <Group name='freebsd'/>
   <Group name='gentoo'/>
   <Group name='redhat'/>
   <Group name='suse'/>
   <Group name='mandrake'/>
   <Group name='solaris'/>
</Groups>

As you can see, the jaunty group inherits the ubuntu group (Note that group names are case sensitive; i.e. Ubuntu != ubuntu). Now let's get a Pkgmgr listing based on the installed package versions.

Generate Pkgmgr listing

root@jaunty:~# cat create-pkgmgr.sh 
echo "<PackageList priority=\"0\" type=\"deb\"><Group name=\"jaunty\">" > /tmp/pkgmgr-jaunty.xml
dpkg -l | grep ^ii | awk '{print "<Package name=\"" $2 "\" version=\"" $3 "\"/>"}' >> /tmp/pkgmgr-jaunty.xml
echo "</Group></PackageList>" >> /tmp/pkgmgr-jaunty.xml
root@jaunty:~# sh create-pkgmgr.sh
root@jaunty:~# cp /tmp/pkgmgr-jaunty.xml /var/lib/bcfg2/Pkgmgr/pkgmgr-jaunty.xml

Now when we run bcfg2, we see Correct entries (woohoo!)

root@jaunty:~# bcfg2 -vqn
Loaded tool drivers:
 APT          Action       DebInit      FreeBSDInit  POSIX       

Phase: initial
Correct entries:	1247
Incorrect entries:	0
Total managed entries:	1247
Unmanaged entries:	34


Phase: final
Correct entries:	1247
Incorrect entries:	0
Total managed entries:	1247
Unmanaged entries:	34

So what are these other unmanaged entries? They are the services detected by Bcfg2. You can also bring these under bcfg2 control. To see what these 'extra' entries are, add the -e option to bcfg2

root@jaunty:~# bcfg2 -vqen
Loaded tool drivers:
 APT          Action       DebInit      FreeBSDInit  POSIX       

Phase: initial
Correct entries:	1247
Incorrect entries:	0
Total managed entries:	1247
Unmanaged entries:	34


Phase: final
Correct entries:	1247
Incorrect entries:	0
Total managed entries:	1247
Unmanaged entries:	34
 Service:NetworkManager         Service:binfmt-support         Service:klogd                  Service:saned                 
 Service:acpi-support           Service:bluetooth              Service:laptop-mode            Service:single                
 Service:acpid                  Service:cron                   Service:policykit              Service:stop-readahead        
 Service:anacron                Service:cups                   Service:powernowd              Service:sysklogd              
 Service:apport                 Service:dbus                   Service:powernowd.early        Service:system-tools-backends 
 Service:atd                    Service:gdm                    Service:pulseaudio             Service:usplash               
 Service:avahi-daemon           Service:hal                    Service:rc.local               Service:vbesave               
 Service:bcfg2                  Service:hotkey-setup           Service:rmnologin             
 Service:bcfg2-server           Service:killprocs              Service:rsync

Generate service listing

Above we see that there are the services that Bcfg2 was able to detect, but that we have not yet specified what to do with.

  • First get a list of all the services on the machine (we can do this by modifying our create-base.sh script from above)
    root@jaunty:~# cat create-base.sh 
    echo "<Base><Group name=\"jaunty\">" > /tmp/jaunty.xml
    dpkg -l | grep ^ii | cut -d' ' -f3 | awk '{print "<Package name=\"" $1 "\"/>"}' >> /tmp/jaunty.xml
    find /etc/rc[12345].d/S* | \
        cut -d/ -f4 | sed -e 's/S[0-99]*//' | \
        sort -n | \
        uniq | \
        awk '{print "<Service name=\"" $1 "\"/>"}' >> /tmp/jaunty.xml
    echo "</Group></Base>" >> /tmp/jaunty.xml
    
    After running it again, you can copy it to Base/jaunty.xml
  • Next, we obtain a list of running services to add to Rules
    root@jaunty:~# cat create-svc-rules.sh
    echo "<Rules priority=\"1\"><Group name=\"jaunty\">" > /tmp/jaunty-services.xml
    find /etc/rc[12345].d/S* | \
        cut -d/ -f4 | sed -e 's/S[0-99]*//' | \
        sort -n | \
        uniq | \
        awk '{print "<Service name=\"" $1 "\" status=\"on\" type=\"deb\"/>"}' >> /tmp/jaunty-services.xml
    echo "</Group></Rules>" >> /tmp/jaunty-services.xml
    root@jaunty:~# cp /tmp/jaunty-services.xml /var/lib/bcfg2/Rules/jaunty-services.xml
    
  • Now when we run bcfg2, we see no more unmanaged entries!
    root@jaunty:~# bcfg2 -vqn
    Loaded tool drivers:
     APT          Action       DebInit      FreeBSDInit  POSIX       
    
    Phase: initial
    Correct entries:	1281
    Incorrect entries:	0
    Total managed entries:	1281
    Unmanaged entries:	0
    
    All entries correct.
    
    Phase: final
    Correct entries:	1281
    Incorrect entries:	0
    Total managed entries:	1281
    Unmanaged entries:	0
    

DBStats

Setting up Django

First we need to download and install Django. As of 1.0pre1, Bcfg2 only supports 0.96 releases of Django. See Reports/Dynamic/Installation for more information.

  • Download Django from http://www.djangoproject.com/download/0.96.3/tarball/
  • Extract the sources
  • Change to the Django directory and install
    root@jaunty:~# cd Django-0.96.3
    root@jaunty:~/Django-0.96.3# python setup.py install
    
  • Now we need to create the sqlite database
    root@jaunty:~# cd bcfg2
    root@jaunty:~/bcfg2# python src/lib/Server/Reports/manage.py syncdb
    Creating table auth_message
    Creating table auth_group
    Creating table auth_user
    Creating table auth_permission
    Creating table django_content_type
    Creating table django_session
    Creating table django_site
    Creating table django_admin_log
    Creating table reports_interaction
    Creating table reports_internaldatabaseversion
    Creating table reports_ping
    Creating table reports_reason
    Creating table reports_client
    Creating table reports_entries_interactions
    Creating table reports_entries
    Creating table reports_performance
    
    You just installed Django's auth system, which means you don't have any superusers defined.
    Would you like to create one now? (yes/no): no
    Installing index for auth.Message model
    Installing index for auth.Permission model
    Installing index for admin.LogEntry model
    Installing index for reports.Interaction model
    Installing index for reports.Ping model
    Installing index for reports.Client model
    Installing index for reports.Entries_interactions model
    Installing index for reports.Entries model
    Loading 'initial_data' fixtures...
    No fixtures found.
    
  • Add DBStats to the plugins line of bcfg2.conf. The resulting [server] section should look something like this:
    [server]
    repository = /var/lib/bcfg2
    plugins = Base,Bundler,Cfg,DBStats,Metadata,Pkgmgr,Rules,SSHbase
    
  • Start the bcfg2 server
    root@jaunty:~/bcfg2# /etc/init.d/bcfg2-server start
    
  • Run bcfg2
    root@jaunty:~/bcfg2# bcfg2 -vqn
    Loaded tool drivers:
     APT          Action       DebInit      FreeBSDInit  POSIX       
    
    Phase: initial
    Correct entries:	0
    Incorrect entries:	0
    Total managed entries:	0
    Unmanaged entries:	1281
    
    
    Phase: final
    Correct entries:	0
    Incorrect entries:	0
    Total managed entries:	0
    Unmanaged entries:	1281
    
    This looks similar to before. You may notice, however, that this run is different from previous runs in that it takes quite a bit longer. This extra time comes from Bcfg2 populating the statistics database.
  • Now we will use the minestruct mode of bcfg2-admin to build a base file based on the entries in our database
    NOTE: bcfg2-admin minestruct builds the xml for unmanaged entries. If you have no unmanaged entries, you will get </Base> as the output to this command.
    root@jaunty:~/bcfg2# bcfg2-admin minestruct jaunty > /tmp/jaunty.xml
    root@jaunty:~/bcfg2# cp /tmp/jaunty.xml /var/lib/bcfg2/Base/jaunty.xml
    
  • The next thing to do is to generate a Pkgmgr listing based on the installed packages (this is exactly the same as above)
  • Lastly, we generate a list of services (this can be done like above)
  • Now when we run bcfg2, we see no more unmanaged entries!
    root@jaunty:~# bcfg2 -vqn
    Loaded tool drivers:
     APT          Action       DebInit      FreeBSDInit  POSIX       
    
    Phase: initial
    Correct entries:	1281
    Incorrect entries:	0
    Total managed entries:	1281
    Unmanaged entries:	0
    
    All entries correct.
    
    Phase: final
    Correct entries:	1281
    Incorrect entries:	0
    Total managed entries:	1281
    Unmanaged entries:	0
    
    All entries correct.