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.xmlAfter 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.