From db95be5468badbbeee26b7023e95439267a02157 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Fri, 15 Oct 2010 19:50:42 -0500 Subject: doc: Fix centos quickstart instructions (reported by Joe Sauer) Signed-off-by: Sol Jerome --- doc/quickstart/centos.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/quickstart/centos.txt b/doc/quickstart/centos.txt index 2aaa8d744..4a702683e 100644 --- a/doc/quickstart/centos.txt +++ b/doc/quickstart/centos.txt @@ -424,7 +424,7 @@ packages. Currently, the way to manage them is using :ref:`BoundEntries .. code-block:: xml - + @@ -445,6 +445,8 @@ packages. Currently, the way to manage them is using :ref:`BoundEntries +.. note:: version="foo" is just a dummy attribute for the gpg-pubkey Package + To actually push the gpg keys out via Bcfg2, you will need to manage the files as well. This can be done by adding Path entries for each of the gpg keys you want to manage -- cgit v1.2.3-1-g7c22 From 5d2c48f2c4e0245205833b4b70090fa286dceecd Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 18 Oct 2010 13:06:07 -0500 Subject: README: Update URLs to point to bcfg2.org Signed-off-by: Sol Jerome (cherry picked from commit 1b56006774c2f835e2826f49f26fcb4cbe15414b) --- README | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README b/README index bac8e30ae..beb0d3303 100644 --- a/README +++ b/README @@ -23,17 +23,17 @@ Installation For details about the installation of Bcfg2 please refer to the following pages in the Bcfg2 wiki. -* Prerequisites: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Prereqs -* Download: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Download -* Installation: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Install +* Prerequisites: http://bcfg2.org/wiki/Prereqs +* Download: http://bcfg2.org/wiki/Download +* Installation: http://bcfg2.org/wiki/Install Need help --------- -* FAQ: http://trac.mcs.anl.gov/projects/bcfg2/wiki/FAQ +* FAQ: http://bcfg2.org/wiki/FAQ * IRC: #bcfg2 on chat.freenode.net * Mailing list: https://lists.mcs.anl.gov/mailman/listinfo/bcfg-dev -* Bug tracker: http://trac.mcs.anl.gov/projects/bcfg2/report +* Bug tracker: http://bcfg2.org/report Documentation ------------- @@ -41,8 +41,8 @@ Documentation A lot of documentation is available in the Bcfg2 wiki and the Bcfg2 manual. -Wiki: http://trac.mcs.anl.gov/projects/bcfg2/wiki/ -Manual: http://doc.bcfg2.fourkitchens.com/ +Wiki: http://bcfg2.org/wiki/ +Manual: http://docs.bcfg2.org/ Bcfg2 is licensed under BSD, for more details check COPYING. -- cgit v1.2.3-1-g7c22 From a845a6d856f60876967258dfd5c39f8f97e8afd2 Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Fri, 22 Oct 2010 14:00:29 -0400 Subject: initial add of SSLCA plugin --- src/lib/Server/Plugins/SSLCA.py | 209 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 src/lib/Server/Plugins/SSLCA.py diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py new file mode 100644 index 000000000..294f82f3f --- /dev/null +++ b/src/lib/Server/Plugins/SSLCA.py @@ -0,0 +1,209 @@ +import Bcfg2.Server.Plugin +import Bcfg2.Options +import os +from ConfigParser import ConfigParser, NoSectionError, NoOptionError +from M2Crypto import RSA, EVP, X509, m2 + +""" +How this should work.... + +V1.0 - Only handles localhost.key and localhost.crt, therefor +assuming we only care about a cert for www, or all ssl services +will use the same cert + +Initialiazation: +Grab options from bcfg2.conf +load cakey, cacert +cache other options + +Req comes in for key & cert +If key exists: + load key + cache key + return key +Else: + gen key + cache key + save key + return key +If cert exists: + load cert + If fails to verify against key: + gen cert + save cert + return cert + If aliases fail don't match + gen cert + save cert + return cert + return cert +Else: + gen cert + save cert + return cert + +V2.0 - Maybe create additional types, SSLCertPath, SSLKeyPath, +to allow generation of multiple certs/keys in arbitrary locations +""" + + +class SSLbase(Bcfg2.Server.Plugin.Plugin, + Bcfg2.Server.Plugin.Generator, + Bcfg2.Server.Plugin.DirectoryBacked): + """ + The sslca generator manages ssl certificates + and keys + """ + + name = 'SSLbase' + __version__ = '0.00000000001' + __author__ = 'ghagger@wgen.net' + + hostkey = 'localhost.key' + hostcert = 'localhost.crt' + + def __init__(self, core, datastore): + Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) + Bcfg2.Server.Plugin.Generator.__init__(self) + try: + Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, + self.core.fam) + except OSError, ioerr: + self.logger.error("Failed to load SSLbase repository from %s" \ + % (self.data)) + self.logger.error(ioerr) + raise Bcfg2.Server.Plugin.PluginInitError + self.Entries = {'Path': + {'/etc/pki/tls/private/localhost.key': self.get_key, + '/etc/pki/tls/certs/localhost.crt': self.get_cert}} + # grab essential sslca configuration from bcfg2.conf + cp = ConfigParser() + cp.read(Bcfg2.Options.CFILE.value) + try: + ca_cert_filename = cp.get('sslca', 'ca_cert') + ca_key_filename = cp.get('sslca', 'ca_key') + self.ca_key_passphrase = cp.get('sslca', 'ca_key_passphrase') + self.cert_subject = cp.get('sslca', 'cert_subject') + self.cert_days = cp.get('sslca', 'cert_days') + self.pkey_bits = cp.get('sslca', 'pkey_bits') + except: + raise NoOptionError + self.ca_cert = X509.load_cert(ca_cert_filename) + self.ca_key = EVP.load_key(ca_key_filename, lambda x: self.ca_key_passphrase) + self._newkey = False + + def get_key(self, entry, metadata): + filename = self.hostkey+".H_%s" % metadata.hostname + if filename in self.entries.keys(): + entry.text = self.entries[filename].data + self.pkey = EVP.load_key_string(entry.text) + else: + (self.pkey, entry.text) = self.build_key(filename) + keyfile = open(self.data + '/' +filename, 'w') + keyfile.write(entry.text) + keyfile.close() + self._newkey = True + + def build_key(self, filename): + """Generate new private key for client.""" + rsa_key = RSA.gen_key(int(self.pkey_bits), m2.RSA_F4) + pkey = EVP.PKey() + pkey.assign_rsa(rsa_key) + keyfile = open(self.data + '/' +filename, 'w') + keyfile.write(pkey.as_pem(cipher=None)) + keyfile.close() + self._newkey = True + return pkey, pkey.as_pem(cipher=None) + + def get_cert(self, entry, metadata): + filename = self.hostcert + ".H_%s" % metadata.hostname + # load prexisting cert, if any + if filename in self.entries.keys() and self._newkey == False: + cert = X509.load_cert_string(self.entries[filename].data) + # check cert subjectAltNames match current aliases + cert_aliases = cert.get_ext('subjectAltName') + if cert_aliases: + if metadata.aliases != [alias.lstrip('DNS:') for alias in cert_aliases.get_value().split(', ')]: + entry.text = self.build_cert(filename, metadata) + return + entry.text = cert.as_text()+cert.as_string() + else: + entry.text = self.build_cert(filename, metadata) + + def get_serial(self): + serialpath = self.data + '/serial' + serial = 0 + if os.path.isfile(serialpath): + serialfile = open(serialpath, 'r') + serial = int(serialfile.read()) + serialfile.close() + serialfile = open(serialpath, 'w') + serial += 1 + serialfile.write(str(serial)) + serialfile.close() + return serial + + def build_cert(self, filename, metadata): + req = self.make_request(self.pkey, metadata) + serial = self.get_serial() + cert = self.make_cert(req, serial, metadata.aliases) + cert_out = cert.as_text()+cert.as_pem() + certfile = open(self.data + '/' +filename, 'w') + certfile.write(cert_out) + certfile.close() + cert_store = self.data + '/certstore' + if not os.path.isdir(cert_store): + os.mkdir(cert_store) + storefile = open(cert_store + '/' + str(serial) + '.pem', 'w') + storefile.write(cert_out) + storefile.close() + return cert_out + + def make_request(self, key, metadata): + req = X509.Request() + req.set_version(2) + req.set_pubkey(key) + name = X509.X509_Name() + parts = [a.split('=') for a in self.cert_subject.split(',')] + [setattr(name, k, v) for k,v in parts] + name.CN = metadata.hostname + req.set_subject_name(name) + req.sign(key, 'sha1') + return req + + def make_cert(self, req, serial, aliases): + pkey = req.get_pubkey() + if not req.verify(pkey): + raise ValueError, 'Error verifying request' + sub = req.get_subject() + cert = X509.X509() + cert.set_serial_number(serial) + cert.set_version(2) + cert.set_subject(sub) + cert.set_issuer(self.ca_cert) + cert.set_pubkey(pkey) + notBefore = m2.x509_get_not_before(cert.x509) + notAfter = m2.x509_get_not_after(cert.x509) + m2.x509_gmtime_adj(notBefore, 0) + m2.x509_gmtime_adj(notAfter, 60*60*24*long(self.cert_days)) + exts = [ + ('basicConstraints','CA:FALSE'), + ('subjectKeyIdentifier','hash'), + ('authorityKeyIdentifier','keyid,issuer:always'), + ('nsCertType','SSL Server'), + ] + if aliases: + exts.append(('subjectAltName', ','.join(['DNS:'+alias for alias in aliases]))) + for ext in exts: + cert.add_ext(X509.new_extension(ext[0],ext[1])) + cert.sign(self.ca_key, 'sha1') + return cert + + def HandleEvent(self, event=None): + """Local event handler that does something....""" + Bcfg2.Server.Plugin.DirectoryBacked.HandleEvent(self, event) + + def HandlesEntry(self, entry, _): + """Handle entries dynamically.""" + return entry.tag == 'Path' and (entry.get('name').endswith(self.hostkey) or entry.get('name').endswith(self.hostcert)) + -- cgit v1.2.3-1-g7c22 From 416162c37c0b30cf42db1b7bd86bf5e15ff61284 Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Fri, 22 Oct 2010 14:31:09 -0400 Subject: added some docs for sslca --- doc/server/plugins/generators/sslca.txt | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 doc/server/plugins/generators/sslca.txt diff --git a/doc/server/plugins/generators/sslca.txt b/doc/server/plugins/generators/sslca.txt new file mode 100644 index 000000000..17f936ffc --- /dev/null +++ b/doc/server/plugins/generators/sslca.txt @@ -0,0 +1,53 @@ +===== +SSLCA +===== + +SSLCA is a simple generator plugin designed to handle creation of +SSL private keys and certificates on request. + +At present, only the following file locations are supported, and thus +only a single key and certifcate will be generated: + +* /etc/pki/tls/private/localhost.key +* /etc/pki/tls/certs/localhost.crt + +While this could be seen as very limiting, SSLCA does support any aliases +specified in clients.xml. Any aliases will be added to the cert under the +subjectAltName extension. + + +Interacting with SSLCA +====================== + +* Pre-seeding with existing keys/certs -- Currently existing keys/certs + will be overwritten by new, sslca-managed ones by default. Pre-existing + files can be added to the repository by putting them in + /SSLCA/.H_ + +* Revoking existing keys -- deleting /SSLCA/\*.H_ + will remove files for an existing client. + + +Getting started +=============== + +#. Add SSLCA to the **plugins** line in ``/etc/bcfg2.conf`` and + restart the server -- This enables the SSLCA plugin on the Bcfg2 + server. + +#. Add Path entries for ``/etc/pki/tls/private/localhost.key``, and + ``/etc/pky/tls/certs/localhost.crt``, etc to a bundle or base. + +#. Add a [sslca] section to ``/etc/bcfg2.conf`` contaning the following + information: + + ca_cert - location of the CA certificate + ca_key - CA private key + ca_key_passphrase - Passphrase (if any) needed to use the CA private key + cert_subject - Additional subject info for the resulting certificates, CN + will always be the bcfg2 clients hostname. + cert_days - number of days from generation that cert should be valid. + pkey_bits - number of bits for the private key. + +#. Enjoy. + -- cgit v1.2.3-1-g7c22 From df1d94eda634e2f00757af19b70e1abb6b1b98a2 Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Fri, 22 Oct 2010 15:15:03 -0400 Subject: moved some sslca docs around --- doc/server/plugins/generators/sslca.txt | 43 +++++++++++++++++++++++++++++++++ src/lib/Server/Plugins/SSLCA.py | 43 --------------------------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/doc/server/plugins/generators/sslca.txt b/doc/server/plugins/generators/sslca.txt index 17f936ffc..cfc01efe1 100644 --- a/doc/server/plugins/generators/sslca.txt +++ b/doc/server/plugins/generators/sslca.txt @@ -51,3 +51,46 @@ Getting started #. Enjoy. + +==== +TODO +==== + +V1.0 - Only handles localhost.key and localhost.crt, therefor +assuming we only care about a cert for www, or all ssl services +will use the same cert + +Initialiazation: +Grab options from bcfg2.conf +load cakey, cacert +cache other options + +Req comes in for key & cert +If key exists: + load key + cache key + return key +Else: + gen key + cache key + save key + return key +If cert exists: + load cert + If fails to verify against key: + gen cert + save cert + return cert + If aliases fail don't match + gen cert + save cert + return cert + return cert +Else: + gen cert + save cert + return cert + +V2.0 - Maybe create additional types, SSLCertPath, SSLKeyPath, +to allow generation of multiple certs/keys in arbitrary locations + diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index 294f82f3f..29acabbf4 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -4,49 +4,6 @@ import os from ConfigParser import ConfigParser, NoSectionError, NoOptionError from M2Crypto import RSA, EVP, X509, m2 -""" -How this should work.... - -V1.0 - Only handles localhost.key and localhost.crt, therefor -assuming we only care about a cert for www, or all ssl services -will use the same cert - -Initialiazation: -Grab options from bcfg2.conf -load cakey, cacert -cache other options - -Req comes in for key & cert -If key exists: - load key - cache key - return key -Else: - gen key - cache key - save key - return key -If cert exists: - load cert - If fails to verify against key: - gen cert - save cert - return cert - If aliases fail don't match - gen cert - save cert - return cert - return cert -Else: - gen cert - save cert - return cert - -V2.0 - Maybe create additional types, SSLCertPath, SSLKeyPath, -to allow generation of multiple certs/keys in arbitrary locations -""" - - class SSLbase(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.Generator, Bcfg2.Server.Plugin.DirectoryBacked): -- cgit v1.2.3-1-g7c22 From 5228ffeba0e516ae3deeecde0403c1c7f9d639a6 Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Fri, 22 Oct 2010 16:05:05 -0400 Subject: ok, so i should have renamed the class to SSLCA a long time ago... doh --- src/lib/Server/Plugins/SSLCA.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index 29acabbf4..734049417 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -4,7 +4,7 @@ import os from ConfigParser import ConfigParser, NoSectionError, NoOptionError from M2Crypto import RSA, EVP, X509, m2 -class SSLbase(Bcfg2.Server.Plugin.Plugin, +class SSLCA(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.Generator, Bcfg2.Server.Plugin.DirectoryBacked): """ -- cgit v1.2.3-1-g7c22 From 17cfe3010f115dfc5294129aaae61660cfbb4896 Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Fri, 22 Oct 2010 22:39:19 -0400 Subject: added extra todo notes --- doc/server/plugins/generators/sslca.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/server/plugins/generators/sslca.txt b/doc/server/plugins/generators/sslca.txt index cfc01efe1..5f987be1e 100644 --- a/doc/server/plugins/generators/sslca.txt +++ b/doc/server/plugins/generators/sslca.txt @@ -56,7 +56,14 @@ Getting started TODO ==== -V1.0 - Only handles localhost.key and localhost.crt, therefor +V1.0 - Nearly done... + +...need to add cert expiry checking/regen... + +...otherwise the below is done, but really should be rewritten to +use openssl binary rather than patched m2crypto + +Only handles localhost.key and localhost.crt, therefor assuming we only care about a cert for www, or all ssl services will use the same cert @@ -91,6 +98,8 @@ Else: save cert return cert + + V2.0 - Maybe create additional types, SSLCertPath, SSLKeyPath, to allow generation of multiple certs/keys in arbitrary locations -- cgit v1.2.3-1-g7c22 From 93f8ad89b0f74322348976efef9f74ffc31ee9d0 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Fri, 22 Oct 2010 12:11:57 -0500 Subject: Extend client metadata to include group category information (cherry picked from commit cc1d65d91aa00cdc91637c2e9afa36e11b5cc6a0) --- src/lib/Server/Plugins/Metadata.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/lib/Server/Plugins/Metadata.py b/src/lib/Server/Plugins/Metadata.py index 3161a69e3..81fd3e173 100644 --- a/src/lib/Server/Plugins/Metadata.py +++ b/src/lib/Server/Plugins/Metadata.py @@ -39,14 +39,21 @@ class ClientMetadata(object): """Test to see if client is a member of group.""" return group in self.groups + def group_in_category(self, category): + for grp in self.query.all_groups_in_category(category): + if grp in self.groups: + return grp + return '' + class MetadataQuery(object): - def __init__(self, by_name, get_clients, by_groups, by_profiles, all_groups): + def __init__(self, by_name, get_clients, by_groups, by_profiles, all_groups, all_groups_in_category): # resolver is set later self.by_name = by_name self.names_by_groups = by_groups self.names_by_profiles = by_profiles self.all_clients = get_clients self.all_groups = all_groups + self.all_groups_in_category = all_groups_in_category def by_groups(self, groups): return [self.by_name(name) for name in self.names_by_groups(groups)] @@ -105,7 +112,8 @@ class Metadata(Bcfg2.Server.Plugin.Plugin, lambda:self.clients.keys(), self.get_client_names_by_groups, self.get_client_names_by_profiles, - self.get_all_group_names) + self.get_all_group_names, + self.get_all_groups_in_category) @classmethod def init_repo(cls, repo, groups, os_selection, clients): @@ -592,6 +600,12 @@ class Metadata(Bcfg2.Server.Plugin.Plugin, [all_groups.update(g[1]) for g in self.groups.values()] return all_groups + def get_all_groups_in_category(self, category): + all_groups = set() + [all_groups.add(g) for g in self.categories \ + if self.categories[g] == category] + return all_groups + def get_client_names_by_profiles(self, profiles): return [client for client, profile in self.clients.iteritems() \ if profile in profiles] -- cgit v1.2.3-1-g7c22 From d1527d8991bff83a3d6ba18e3de258993722f459 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Wed, 27 Oct 2010 10:58:56 -0500 Subject: Guppy.py: New plugin to help trace memory leaks (cherry picked from commit 4be21b7fbb93c3552713ab9914114fbe0068b93d) --- src/lib/Server/Plugins/Guppy.py | 63 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/lib/Server/Plugins/Guppy.py diff --git a/src/lib/Server/Plugins/Guppy.py b/src/lib/Server/Plugins/Guppy.py new file mode 100644 index 000000000..b217378d6 --- /dev/null +++ b/src/lib/Server/Plugins/Guppy.py @@ -0,0 +1,63 @@ +""" +This plugin is used to trace memory leaks within the bcfg2-server +process using Guppy. By default the remote debugger is started +when this plugin is enabled. The debugger can be shutoff in a running +process using "bcfg2-admin xcmd Guppy.Disable" and reenabled using +"bcfg2-admin xcmd Guppy.Enable". + +To attach the console run: + +python -c "from guppy import hpy;hpy().monitor()" + +For example: + +# python -c "from guppy import hpy;hpy().monitor()" + +*** Connection 1 opened *** + lc +CID PID ARGV + 1 25063 ['/usr/sbin/bcfg2-server', '-D', '/var/run/bcfg2-server.pid'] + sc 1 +Remote connection 1. To return to Monitor, type or . + int +Remote interactive console. To return to Annex, type '-'. +>>> hp.heap() +... + + +""" +import re +import Bcfg2.Server.Plugin + +class Guppy(Bcfg2.Server.Plugin.Plugin): + """Guppy is a debugging plugin to help trace memory leaks""" + name = 'Guppy' + __version__ = '$Id$' + __author__ = 'bcfg-dev@mcs.anl.gov' + + experimental = True + __rmi__ = Bcfg2.Server.Plugin.Plugin.__rmi__ + ['Enable','Disable'] + + def __init__(self, core, datastore): + Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) + + self.Enable() + + def Enable(self): + """Enable remote debugging""" + try: + from guppy.heapy import Remote + Remote.on() + except: + self.logger.error("Failed to create Heapy context") + raise Bcfg2.Server.Plugin.PluginInitError + + def Disable(self): + """Disable remote debugging""" + try: + from guppy.heapy import Remote + Remote.off() + except: + self.logger.error("Failed to disable Heapy") + raise Bcfg2.Server.Plugin.PluginInitError + -- cgit v1.2.3-1-g7c22 From 196b67a03a5ff8b550f2dfe8efc95893c408b483 Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Wed, 27 Oct 2010 17:52:19 -0400 Subject: starting to establish the way sslca will truly work --- src/lib/Server/Plugins/SSLCA.py | 623 ++++++++++++++++++++++++++++++---------- 1 file changed, 471 insertions(+), 152 deletions(-) diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index 734049417..f18c18944 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -1,166 +1,485 @@ import Bcfg2.Server.Plugin -import Bcfg2.Options -import os -from ConfigParser import ConfigParser, NoSectionError, NoOptionError -from M2Crypto import RSA, EVP, X509, m2 - -class SSLCA(Bcfg2.Server.Plugin.Plugin, - Bcfg2.Server.Plugin.Generator, - Bcfg2.Server.Plugin.DirectoryBacked): - """ - The sslca generator manages ssl certificates - and keys - """ +from subprocess import Popen, PIPE +import lxml.etree +import posixpath +import logging +import pdb - name = 'SSLbase' - __version__ = '0.00000000001' - __author__ = 'ghagger@wgen.net' +class SSLCA(Bcfg2.Server.Plugin.GroupSpool): + #Bcfg2.Server.Plugin.Plugin, + #Bcfg2.Server.Plugin.Generator, + #Bcfg2.Server.Plugin.DirectoryBacked): - hostkey = 'localhost.key' - hostcert = 'localhost.crt' + """ + The SSLCA generator handles the creation and + management of ssl certificates and their keys. + """ + name = 'SSLCA' + __version__ = '$Id:$' + __author__ = 'g.hagger@gmail.com' + __child__ = Bcfg2.Server.Plugin.FileBacked def __init__(self, core, datastore): - Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) - Bcfg2.Server.Plugin.Generator.__init__(self) - try: - Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, - self.core.fam) - except OSError, ioerr: - self.logger.error("Failed to load SSLbase repository from %s" \ - % (self.data)) - self.logger.error(ioerr) - raise Bcfg2.Server.Plugin.PluginInitError - self.Entries = {'Path': - {'/etc/pki/tls/private/localhost.key': self.get_key, - '/etc/pki/tls/certs/localhost.crt': self.get_cert}} - # grab essential sslca configuration from bcfg2.conf - cp = ConfigParser() - cp.read(Bcfg2.Options.CFILE.value) - try: - ca_cert_filename = cp.get('sslca', 'ca_cert') - ca_key_filename = cp.get('sslca', 'ca_key') - self.ca_key_passphrase = cp.get('sslca', 'ca_key_passphrase') - self.cert_subject = cp.get('sslca', 'cert_subject') - self.cert_days = cp.get('sslca', 'cert_days') - self.pkey_bits = cp.get('sslca', 'pkey_bits') - except: - raise NoOptionError - self.ca_cert = X509.load_cert(ca_cert_filename) - self.ca_key = EVP.load_key(ca_key_filename, lambda x: self.ca_key_passphrase) - self._newkey = False + Bcfg2.Server.Plugin.GroupSpool.__init__(self, core, datastore) +# Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) +# Bcfg2.Server.Plugin.Generator.__init__(self) +# try: +# Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, +# self.core.fam) +# except OSError, ioerr: +# self.logger.error("Failed to load SSHbase repository from %s" \ +# % (self.data)) +# self.logger.error(ioerr) +# raise Bcfg2.Server.Plugin.PluginInitError +# + def HandleEvent(self, event=None): + action = event.code2str() + if event.filename[0] == '/': + return + epath = "".join([self.data, self.handles[event.requestID], + event.filename]) + if posixpath.isdir(epath): + ident = self.handles[event.requestID] + event.filename + else: + ident = self.handles[event.requestID][:-1] + + self.logger.error('ACTION: %s, IDENT %s, FILENAME %s' % (action, ident, event.filename)) + + if action in ['exists', 'created']: + if posixpath.isdir(epath): + self.AddDirectoryMonitor(epath[len(self.data):]) + if ident not in self.entries and posixpath.isfile(epath): + if event.filename.endswith('key.xml'): + self.Entries['Path'][ident] = self.get_key + elif event.filename.endswith('cert.xml'): + pass +# self.Entries['Path'][ident] = self.get_cert + else: + fname = "".join([ident, '/', event.filename]) + self.entries[fname] = self.__child__(epath) + self.entries[fname].HandleEvent(event) + if action == 'changed': + self.entries[ident].HandleEvent(event) + elif action == 'deleted': + fbase = self.handles[event.requestID] + event.filename + if fbase in self.entries: + # a directory was deleted + del self.entries[fbase] + del self.Entries['Path'][fbase] + else: + self.entries[ident].HandleEvent(event) def get_key(self, entry, metadata): - filename = self.hostkey+".H_%s" % metadata.hostname - if filename in self.entries.keys(): - entry.text = self.entries[filename].data - self.pkey = EVP.load_key_string(entry.text) + path = entry.get('name') + permdata = {'owner':'root', + 'group':'root', + 'type':'file', + 'perms':'644'} + [entry.attrib.__setitem__(key, permdata[key]) for key in permdata] + filename = "".join([path, '/', path.rsplit('/', 1)[1], '.H_', metadata.hostname]) + if filename not in self.entries.keys(): + key = self.build_key(filename, metadata) + open(self.data + filename, 'w').write(key) + entry.text = key else: - (self.pkey, entry.text) = self.build_key(filename) - keyfile = open(self.data + '/' +filename, 'w') - keyfile.write(entry.text) - keyfile.close() - self._newkey = True - - def build_key(self, filename): - """Generate new private key for client.""" - rsa_key = RSA.gen_key(int(self.pkey_bits), m2.RSA_F4) - pkey = EVP.PKey() - pkey.assign_rsa(rsa_key) - keyfile = open(self.data + '/' +filename, 'w') - keyfile.write(pkey.as_pem(cipher=None)) - keyfile.close() - self._newkey = True - return pkey, pkey.as_pem(cipher=None) + entry.text = self.entries[filename].data + + def build_key(self, filename, metadata): + # TODO read params + type = 'rsa' + bits = 2048 + if type == 'rsa': + cmd = "openssl genrsa %s " % bits + elif type == 'dsa': + cmd = "openssl dsaparam -noout -genkey %s" % bits + key = Popen(cmd, shell=True, stdout=PIPE).stdout.read() + return key def get_cert(self, entry, metadata): - filename = self.hostcert + ".H_%s" % metadata.hostname - # load prexisting cert, if any - if filename in self.entries.keys() and self._newkey == False: - cert = X509.load_cert_string(self.entries[filename].data) - # check cert subjectAltNames match current aliases - cert_aliases = cert.get_ext('subjectAltName') - if cert_aliases: - if metadata.aliases != [alias.lstrip('DNS:') for alias in cert_aliases.get_value().split(', ')]: - entry.text = self.build_cert(filename, metadata) - return - entry.text = cert.as_text()+cert.as_string() + path = entry.get('name') + permdata = {'owner':'root', + 'group':'root', + 'type':'file', + 'perms':'644'} + [entry.attrib.__setitem__(key, permdata[key]) for key in permdata] + filename = "".join([path, '/', path.rsplit('/', 1)[1], '.H_', metadata.hostname]) + if filename in self.entries.keys() and self.verify_cert(filename) : + entry.text = self.entries[filename].data else: - entry.text = self.build_cert(filename, metadata) - - def get_serial(self): - serialpath = self.data + '/serial' - serial = 0 - if os.path.isfile(serialpath): - serialfile = open(serialpath, 'r') - serial = int(serialfile.read()) - serialfile.close() - serialfile = open(serialpath, 'w') - serial += 1 - serialfile.write(str(serial)) - serialfile.close() - return serial - - def build_cert(self, filename, metadata): - req = self.make_request(self.pkey, metadata) - serial = self.get_serial() - cert = self.make_cert(req, serial, metadata.aliases) - cert_out = cert.as_text()+cert.as_pem() - certfile = open(self.data + '/' +filename, 'w') - certfile.write(cert_out) - certfile.close() - cert_store = self.data + '/certstore' - if not os.path.isdir(cert_store): - os.mkdir(cert_store) - storefile = open(cert_store + '/' + str(serial) + '.pem', 'w') - storefile.write(cert_out) - storefile.close() - return cert_out - - def make_request(self, key, metadata): - req = X509.Request() - req.set_version(2) - req.set_pubkey(key) - name = X509.X509_Name() - parts = [a.split('=') for a in self.cert_subject.split(',')] - [setattr(name, k, v) for k,v in parts] - name.CN = metadata.hostname - req.set_subject_name(name) - req.sign(key, 'sha1') - return req - - def make_cert(self, req, serial, aliases): - pkey = req.get_pubkey() - if not req.verify(pkey): - raise ValueError, 'Error verifying request' - sub = req.get_subject() - cert = X509.X509() - cert.set_serial_number(serial) - cert.set_version(2) - cert.set_subject(sub) - cert.set_issuer(self.ca_cert) - cert.set_pubkey(pkey) - notBefore = m2.x509_get_not_before(cert.x509) - notAfter = m2.x509_get_not_after(cert.x509) - m2.x509_gmtime_adj(notBefore, 0) - m2.x509_gmtime_adj(notAfter, 60*60*24*long(self.cert_days)) - exts = [ - ('basicConstraints','CA:FALSE'), - ('subjectKeyIdentifier','hash'), - ('authorityKeyIdentifier','keyid,issuer:always'), - ('nsCertType','SSL Server'), - ] - if aliases: - exts.append(('subjectAltName', ','.join(['DNS:'+alias for alias in aliases]))) - for ext in exts: - cert.add_ext(X509.new_extension(ext[0],ext[1])) - cert.sign(self.ca_key, 'sha1') - return cert + cert = self.build_cert(filename, metadata) + open(self.data + filename, 'w').write(cert) + entry.text = cert + + def verify_cert(self): + # TODO + # check cert matches key + # check expiry + pass + + def build_req(self): + pass + + def build_cert(self): + pass + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#class SSLCAFile: +# +# def __init__(self, datastore, name, specific, encoding): +# self.data = datastore +# self.name = name +# self.specific = specific +# self.encoding = encoding +# if name.endswith('.xml'): +# self.xml = lxml.etree.parse(name) +# +# def handle_event(self, event=None): +# """Handle all fs events for this file.""" +# if event and event.code2str() == 'deleted': +# return +# +# def bind_entry(self, entry, metadata): +# pdb.set_trace() +# +# +#class SSLCAKeyFile(SSLCAFile): +# +# def __init__(self, datastore, name, specific, encoding): +# SSLCAFile.__init__(self, datastore, name, specific, encoding) +# key_attrs = self.xml.find('Key') +# self.bits = key_attrs.get('bits') +# self.type = key_attrs.get('type') +# +# def bind_entry(self, entry, metadata): +# """Build literal file information.""" +# if entry.tag == 'Path': +# entry.set('type', 'file') +# entry.text = self.get_key(entry, metadata) +# +# def get_key(self, entry, metadata): +# fname = +dir '.H_' + metadata.hostname +# # TODO add logic to get+verify key if hostfile exists & save if not +# pdb.set_trace() +# return self.build_key() +# +# def build_key(self): +# if self.type == 'rsa': +# cmd = "openssl genrsa %s " % self.bits +# elif self.type == 'dsa': +# cmd = "openssl dsaparam -noout -genkey %s" % self.bits +# key = Popen(cmd, shell=True, stdout=PIPE).stdout.read() +# return key +# +# +#class SSLCACertFile(SSLCAFile): +# +# def __init__(self, datastore, name, specific, encoding): +# SSLCAFile.__init__(self, datastore, name, specific, encoding) +# cert_attrs = self.xml.find('Cert') +# #self.format = cert_attrs.get('format') +# #self.key = cert_attrs.get('key') +# #self.ca = cert_attrs.get('ca') +# +# def bind_entry(self, entry, metadata): +# """Build literal file information.""" +# fname = entry.get('realname', entry.get('name')) +# if entry.tag == 'Path': +# entry.set('type', 'file') +# entry.text = 'booya cert' +# +# +#class SSLCAEntrySet(Bcfg2.Server.Plugin.EntrySet): +# """ +# Handles host and group specific entries +# """ +# def __init__(self, datastore, basename, path, entry_type, encoding): +# self.data = datastore +# Bcfg2.Server.Plugin.EntrySet.__init__(self, basename, path, entry_type, encoding) +# +# def entry_init(self, event): +# """Handle template and info file creation.""" +# logger = logging.getLogger('Bcfg2.Plugins.SSLCA') +# if event.filename in self.entries: +# logger.warn("Got duplicate add for %s" % event.filename) +# else: +# fpath = "%s/%s" % (self.path, event.filename) +# try: +# spec = self.specificity_from_filename(event.filename) +# except Bcfg2.Server.Plugin.SpecificityError: +# if not self.ignore.match(event.filename): +# logger.error("Could not process filename %s; ignoring" % fpath) +# return +# self.entries[event.filename] = self.entry_type(self.data, fpath, +# spec, self.encoding) +# self.entries[event.filename].handle_event(event) +# +# +#class SSLCA(Bcfg2.Server.Plugin.GroupSpool): +# """ +# The SSLCA generator handles the creation and +# management of ssl certificates and their keys. +# """ +# name = 'SSLCA' +# __version__ = '$Id:$' +# __author__ = 'g.hagger@gmail.com' +# filename_pattern = '(key|cert)\.xml' +# es_cls = SSLCAEntrySet +# +# def __init__(self, core, datastore): +# Bcfg2.Server.Plugin.GroupSpool.__init__(self, core, datastore) +# +# def HandleEvent(self, event): +# action = event.code2str() +# if event.filename[0] == '/': +# return +# epath = "".join([self.data, self.handles[event.requestID], +# event.filename]) +# if posixpath.isdir(epath): +# ident = self.handles[event.requestID] + event.filename +# else: +# ident = self.handles[event.requestID][:-1] +# +# if action in ['exists', 'created']: +# if posixpath.isdir(epath): +# self.AddDirectoryMonitor(epath[len(self.data):]) +# if ident not in self.entries and posixpath.isfile(epath): +# if event.filename.endswith('key.xml'): +# es_child_cls = SSLCAKeyFile +# elif event.filename.endswith('cert.xml'): +# es_child_cls = SSLCACertFile +# else: +# return +# dirpath = "".join([self.data, ident]) +# self.entries[ident] = self.es_cls(self.data, +# self.filename_pattern, +# dirpath, +# es_child_cls, +# self.encoding) +# self.Entries['Path'][ident] = self.entries[ident].bind_entry +# if not posixpath.isdir(epath): +# # do not pass through directory events +# self.entries[ident].handle_event(event) +# if action == 'changed': +# self.entries[ident].handle_event(event) +# elif action == 'deleted': +# fbase = self.handles[event.requestID] + event.filename +# if fbase in self.entries: +# # a directory was deleted +# del self.entries[fbase] +# del self.Entries['Path'][fbase] +# else: +# self.entries[ident].handle_event(event) + + + + + + + + - def HandleEvent(self, event=None): - """Local event handler that does something....""" - Bcfg2.Server.Plugin.DirectoryBacked.HandleEvent(self, event) - def HandlesEntry(self, entry, _): - """Handle entries dynamically.""" - return entry.tag == 'Path' and (entry.get('name').endswith(self.hostkey) or entry.get('name').endswith(self.hostcert)) +#import Bcfg2.Options +#import os +#from ConfigParser import ConfigParser, NoSectionError, NoOptionError +#from M2Crypto import RSA, EVP, X509, m2 +#class SSLCA(Bcfg2.Server.Plugin.Plugin, +# Bcfg2.Server.Plugin.Generator, +# Bcfg2.Server.Plugin.DirectoryBacked): +# """ +# The sslca generator manages ssl certificates +# and keys +# """ +# +# name = 'SSLbase' +# __version__ = '0.00000000001' +# __author__ = 'ghagger@wgen.net' +# +# hostkey = 'localhost.key' +# hostcert = 'localhost.crt' +# +# def __init__(self, core, datastore): +# Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) +# Bcfg2.Server.Plugin.Generator.__init__(self) +# try: +# Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, +# self.core.fam) +# except OSError, ioerr: +# self.logger.error("Failed to load SSLbase repository from %s" \ +# % (self.data)) +# self.logger.error(ioerr) +# raise Bcfg2.Server.Plugin.PluginInitError +# self.Entries = {'Path': +# {'/etc/pki/tls/private/localhost.key': self.get_key, +# '/etc/pki/tls/certs/localhost.crt': self.get_cert}} +# # grab essential sslca configuration from bcfg2.conf +# cp = ConfigParser() +# cp.read(Bcfg2.Options.CFILE.value) +# try: +# ca_cert_filename = cp.get('sslca', 'ca_cert') +# ca_key_filename = cp.get('sslca', 'ca_key') +# self.ca_key_passphrase = cp.get('sslca', 'ca_key_passphrase') +# self.cert_subject = cp.get('sslca', 'cert_subject') +# self.cert_days = cp.get('sslca', 'cert_days') +# self.pkey_bits = cp.get('sslca', 'pkey_bits') +# except: +# raise NoOptionError +# self.ca_cert = X509.load_cert(ca_cert_filename) +# self.ca_key = EVP.load_key(ca_key_filename, lambda x: self.ca_key_passphrase) +# self._newkey = False +# +# def get_key(self, entry, metadata): +# filename = self.hostkey+".H_%s" % metadata.hostname +# if filename in self.entries.keys(): +# entry.text = self.entries[filename].data +# self.pkey = EVP.load_key_string(entry.text) +# else: +# (self.pkey, entry.text) = self.build_key(filename) +# keyfile = open(self.data + '/' +filename, 'w') +# keyfile.write(entry.text) +# keyfile.close() +# self._newkey = True +# +# def build_key(self, filename): +# """Generate new private key for client.""" +# rsa_key = RSA.gen_key(int(self.pkey_bits), m2.RSA_F4) +# pkey = EVP.PKey() +# pkey.assign_rsa(rsa_key) +# keyfile = open(self.data + '/' +filename, 'w') +# keyfile.write(pkey.as_pem(cipher=None)) +# keyfile.close() +# self._newkey = True +# return pkey, pkey.as_pem(cipher=None) +# +# def get_cert(self, entry, metadata): +# filename = self.hostcert + ".H_%s" % metadata.hostname +# # load prexisting cert, if any +# if filename in self.entries.keys() and self._newkey == False: +# cert = X509.load_cert_string(self.entries[filename].data) +# # check cert subjectAltNames match current aliases +# cert_aliases = cert.get_ext('subjectAltName') +# if cert_aliases: +# if metadata.aliases != [alias.lstrip('DNS:') for alias in cert_aliases.get_value().split(', ')]: +# entry.text = self.build_cert(filename, metadata) +# return +# entry.text = cert.as_text()+cert.as_string() +# else: +# entry.text = self.build_cert(filename, metadata) +# +# def get_serial(self): +# serialpath = self.data + '/serial' +# serial = 0 +# if os.path.isfile(serialpath): +# serialfile = open(serialpath, 'r') +# serial = int(serialfile.read()) +# serialfile.close() +# serialfile = open(serialpath, 'w') +# serial += 1 +# serialfile.write(str(serial)) +# serialfile.close() +# return serial +# +# def build_cert(self, filename, metadata): +# req = self.make_request(self.pkey, metadata) +# serial = self.get_serial() +# cert = self.make_cert(req, serial, metadata.aliases) +# cert_out = cert.as_text()+cert.as_pem() +# certfile = open(self.data + '/' +filename, 'w') +# certfile.write(cert_out) +# certfile.close() +# cert_store = self.data + '/certstore' +# if not os.path.isdir(cert_store): +# os.mkdir(cert_store) +# storefile = open(cert_store + '/' + str(serial) + '.pem', 'w') +# storefile.write(cert_out) +# storefile.close() +# return cert_out +# +# def make_request(self, key, metadata): +# req = X509.Request() +# req.set_version(2) +# req.set_pubkey(key) +# name = X509.X509_Name() +# parts = [a.split('=') for a in self.cert_subject.split(',')] +# [setattr(name, k, v) for k,v in parts] +# name.CN = metadata.hostname +# req.set_subject_name(name) +# req.sign(key, 'sha1') +# return req +# +# def make_cert(self, req, serial, aliases): +# pkey = req.get_pubkey() +# if not req.verify(pkey): +# raise ValueError, 'Error verifying request' +# sub = req.get_subject() +# cert = X509.X509() +# cert.set_serial_number(serial) +# cert.set_version(2) +# cert.set_subject(sub) +# cert.set_issuer(self.ca_cert) +# cert.set_pubkey(pkey) +# notBefore = m2.x509_get_not_before(cert.x509) +# notAfter = m2.x509_get_not_after(cert.x509) +# m2.x509_gmtime_adj(notBefore, 0) +# m2.x509_gmtime_adj(notAfter, 60*60*24*long(self.cert_days)) +# exts = [ +# ('basicConstraints','CA:FALSE'), +# ('subjectKeyIdentifier','hash'), +# ('authorityKeyIdentifier','keyid,issuer:always'), +# ('nsCertType','SSL Server'), +# ] +# if aliases: +# exts.append(('subjectAltName', ','.join(['DNS:'+alias for alias in aliases]))) +# for ext in exts: +# cert.add_ext(X509.new_extension(ext[0],ext[1])) +# cert.sign(self.ca_key, 'sha1') +# return cert +# +# def HandleEvent(self, event=None): +# """Local event handler that does something....""" +# Bcfg2.Server.Plugin.DirectoryBacked.HandleEvent(self, event) +# +# def HandlesEntry(self, entry, _): +# """Handle entries dynamically.""" +# return entry.tag == 'Path' and (entry.get('name').endswith(self.hostkey) or entry.get('name').endswith(self.hostcert)) +# -- cgit v1.2.3-1-g7c22 From b50f7745652d144e6746129f927be80ab5054823 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 28 Oct 2010 14:20:15 -0500 Subject: Pacman: Use logging infrastructure for printing messages Signed-off-by: Sol Jerome --- src/lib/Client/Tools/Pacman.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/lib/Client/Tools/Pacman.py b/src/lib/Client/Tools/Pacman.py index a9edc4d65..85068ddfc 100644 --- a/src/lib/Client/Tools/Pacman.py +++ b/src/lib/Client/Tools/Pacman.py @@ -1,8 +1,7 @@ """This is the bcfg2 support for pacman""" import Bcfg2.Client.Tools -import Bcfg2.Options -import Bcfg2.Client.Tools + class Pacman(Bcfg2.Client.Tools.PkgTool): '''Archlinux package support''' @@ -31,7 +30,8 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): def VerifyPackage(self, entry, modlist): '''Verify Package status for entry''' - print "VerifyPackage : " + entry.get('name')+ " : " + entry.get('version') + self.logger.info("VerifyPackage : %s : %s" % entry.get('name'), + entry.get('version')) if not 'version' in entry.attrib: self.logger.info("Cannot verify unversioned package %s" % @@ -44,8 +44,8 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): elif self.installed[entry.attrib['name']] == entry.attrib['version']: #if not self.setup['quick'] and \ # entry.get('verify', 'true') == 'true': - #FIXME: We should be able to check this once - # http://trac.macports.org/ticket/15709 is implemented + #FIXME: need to figure out if pacman + # allows you to verify packages return True else: entry.set('current_version', self.installed[entry.get('name')]) @@ -76,11 +76,7 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): print "packages : " + pkgline try: - self.logger.debug('Running Pacman.Install()') - print "running : %s -S %s" % (self.pkgtool, pkgline) - s = self.cmd.run("%s -S %s" % (self.pkgtool, pkgline)) - print "pacman : " + str(s) - except Exception as ex: - print "error in cmd.run ", ex - - self.logger.debug('Running Pacman.Install()') + self.logger.debug("Running : %s -S %s" % (self.pkgtool, pkgline)) + self.cmd.run("%s -S %s" % (self.pkgtool, pkgline)) + except Exception as e: + self.logger.error("Error occurred during installation: %s" % e) -- cgit v1.2.3-1-g7c22 From 636adaa1b3c0109e0f77be55ff0e8b3b18d65600 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 28 Oct 2010 14:37:08 -0500 Subject: Reports: Fix default time zone settings (Resolves Ticket #957) We were previously defaulting to America/Chicago instead of leaving this option up to the user. Setting the default to None will cause Django to go by the system time. Note also that Django sets the os.environ['TZ'] variable when this is not none, so we want to be careful not to set that if we don't have to. Signed-off-by: Sol Jerome --- man/bcfg2.conf.5 | 5 +++++ src/lib/Server/Hostbase/settings.py | 7 +++++-- src/lib/Server/Reports/settings.py | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/man/bcfg2.conf.5 b/man/bcfg2.conf.5 index 394bb347d..f2e47b7ac 100644 --- a/man/bcfg2.conf.5 +++ b/man/bcfg2.conf.5 @@ -325,6 +325,11 @@ Host for database connections. Not used for sqlite3. .B database_port Port for database connections. Not used for sqlite3. +.TP +.B time_zone +Specify a time zone other than that used on the system. (Note that this +will cause the bcfg2 server to log messages in this time zone as well). + .SH COMMUNICATION OPTIONS Specified in the [communication] section. These options define diff --git a/src/lib/Server/Hostbase/settings.py b/src/lib/Server/Hostbase/settings.py index dadf98d24..a42fd5b2e 100644 --- a/src/lib/Server/Hostbase/settings.py +++ b/src/lib/Server/Hostbase/settings.py @@ -44,8 +44,11 @@ DATABASE_HOST = options['database_host'] # Set to empty string for default. Not used with sqlite3. DATABASE_PORT = int(options['database_port']) # Local time zone for this installation. All choices can be found here: -# http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE -TIME_ZONE = 'America/Chicago' +# http://docs.djangoproject.com/en/dev/ref/settings/#time-zone +try: + TIME_ZONE = c.get('statistics', 'time_zone') +except: + TIME_ZONE = None # enter the defauly MX record machines will get in Hostbase # this setting may move elsewhere eventually diff --git a/src/lib/Server/Reports/settings.py b/src/lib/Server/Reports/settings.py index 81220c0e3..b725783ca 100644 --- a/src/lib/Server/Reports/settings.py +++ b/src/lib/Server/Reports/settings.py @@ -49,7 +49,7 @@ if DATABASE_ENGINE == 'sqlite3' and DATABASE_NAME == '': try: TIME_ZONE = c.get('statistics', 'time_zone') except: - TIME_ZONE = 'America/Chicago' + TIME_ZONE = None # Language code for this installation. All choices can be found here: # http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes -- cgit v1.2.3-1-g7c22 From a44304d3fcb3fa4ec186e7ebbeb4d4e72f25e9de Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 28 Oct 2010 17:09:10 -0500 Subject: doc: Move Properties plugin documentation under connectors Signed-off-by: Sol Jerome --- doc/server/plugins/connectors/properties.txt | 46 ++++++++++++++++++++++++++++ doc/server/plugins/index.txt | 10 +++++- doc/server/plugins/properties.txt | 46 ---------------------------- 3 files changed, 55 insertions(+), 47 deletions(-) create mode 100644 doc/server/plugins/connectors/properties.txt delete mode 100644 doc/server/plugins/properties.txt diff --git a/doc/server/plugins/connectors/properties.txt b/doc/server/plugins/connectors/properties.txt new file mode 100644 index 000000000..fa8bfd884 --- /dev/null +++ b/doc/server/plugins/connectors/properties.txt @@ -0,0 +1,46 @@ +.. -*- mode: rst -*- + +.. _server-plugins-properties: + +========== +Properties +========== + +The Properties plugin is a connector plugin that adds information from +properties files into client metadata instances. + +Enabling Properties +=================== + +First, ``mkdir /var/lib/bcfg2/Properties``. Each property XML file goes +in this directory. Each will automatically be cached by the server, +and reread/reparsed upon changes. Add **Properties** to your ``plugins`` +line in ``/etc/bcfg2.conf``. + +Data Structures +=============== + +Properties adds a new dictionary to client metadata instances that maps +property file names to PropertyFile instances. PropertyFile instances +contain parsed XML data as the "data" attribute. + +Usage +===== + +Specific property files can be referred to in +templates as metadata.Properties[]. The +data attribute is an LXML element object. (Documented +`here `_) + +Currently, no access methods are defined for this data, but as we +formulate common use cases, we will add them to the !PropertyFile class +as methods. This will simplify templates. + +Accessing Properties contest from TGenshi +========================================= + +Access contents of ``Properties/auth.xml`` + +:: + + ${metadata.Properties['auth.xml'].data.find('file').find('bcfg2.key').text} diff --git a/doc/server/plugins/index.txt b/doc/server/plugins/index.txt index 126331325..61f91da86 100644 --- a/doc/server/plugins/index.txt +++ b/doc/server/plugins/index.txt @@ -68,6 +68,15 @@ Literal Configuration (Generators) Each of these plugins has a corresponding subdirectory with the same name in the Bcfg2 repository. +Connector Plugins +----------------- + +.. toctree:: + :maxdepth: 2 + :glob: + + connectors/* + Statistics Plugins ------------------ @@ -103,5 +112,4 @@ More details can be found in :ref:`server-plugins-plugin-roles` plugin-roles probes/index - properties trigger diff --git a/doc/server/plugins/properties.txt b/doc/server/plugins/properties.txt deleted file mode 100644 index fa8bfd884..000000000 --- a/doc/server/plugins/properties.txt +++ /dev/null @@ -1,46 +0,0 @@ -.. -*- mode: rst -*- - -.. _server-plugins-properties: - -========== -Properties -========== - -The Properties plugin is a connector plugin that adds information from -properties files into client metadata instances. - -Enabling Properties -=================== - -First, ``mkdir /var/lib/bcfg2/Properties``. Each property XML file goes -in this directory. Each will automatically be cached by the server, -and reread/reparsed upon changes. Add **Properties** to your ``plugins`` -line in ``/etc/bcfg2.conf``. - -Data Structures -=============== - -Properties adds a new dictionary to client metadata instances that maps -property file names to PropertyFile instances. PropertyFile instances -contain parsed XML data as the "data" attribute. - -Usage -===== - -Specific property files can be referred to in -templates as metadata.Properties[]. The -data attribute is an LXML element object. (Documented -`here `_) - -Currently, no access methods are defined for this data, but as we -formulate common use cases, we will add them to the !PropertyFile class -as methods. This will simplify templates. - -Accessing Properties contest from TGenshi -========================================= - -Access contents of ``Properties/auth.xml`` - -:: - - ${metadata.Properties['auth.xml'].data.find('file').find('bcfg2.key').text} -- cgit v1.2.3-1-g7c22 From ed7386814afdf3ca70bb9454ab7fb09a664e1657 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 28 Oct 2010 18:00:55 -0500 Subject: Pacman: Fix traceback for exception handler Signed-off-by: Sol Jerome --- src/lib/Client/Tools/Pacman.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Client/Tools/Pacman.py b/src/lib/Client/Tools/Pacman.py index 85068ddfc..be3fb0c94 100644 --- a/src/lib/Client/Tools/Pacman.py +++ b/src/lib/Client/Tools/Pacman.py @@ -78,5 +78,5 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): try: self.logger.debug("Running : %s -S %s" % (self.pkgtool, pkgline)) self.cmd.run("%s -S %s" % (self.pkgtool, pkgline)) - except Exception as e: + except Exception, e: self.logger.error("Error occurred during installation: %s" % e) -- cgit v1.2.3-1-g7c22 From 106248d2315704efdee5e352b207a62b5cf697d5 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 28 Oct 2010 19:36:48 -0500 Subject: Reports: Don't set TIME_ZONE unless it's supported Django added the TIME_ZONE = None bit in 1.2 and we are still supporting distros with 1.0 installed by default. Signed-off-by: Sol Jerome --- src/lib/Server/Reports/settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/Server/Reports/settings.py b/src/lib/Server/Reports/settings.py index b725783ca..9efe38552 100644 --- a/src/lib/Server/Reports/settings.py +++ b/src/lib/Server/Reports/settings.py @@ -49,7 +49,8 @@ if DATABASE_ENGINE == 'sqlite3' and DATABASE_NAME == '': try: TIME_ZONE = c.get('statistics', 'time_zone') except: - TIME_ZONE = None + if django.VERSION[0] == 1 and django.VERSION[1] > 2: + TIME_ZONE = None # Language code for this installation. All choices can be found here: # http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes -- cgit v1.2.3-1-g7c22 From 890a6f79dd857bdfe03a3fbf4e79f2901d8b88d7 Mon Sep 17 00:00:00 2001 From: Narayan Desai Date: Fri, 29 Oct 2010 11:46:45 -0500 Subject: bcfg2: implement -Q option (bundle-quick mode) Implement the -Q option for the bcfg2 client. This option only verifies and installs the entries in bundles specified with -b. Considerably improves runtime performance when package checksums are being checked. This option prevents the client from sending statistics to the server, and is incompatible with -r. --- man/bcfg2.1 | 7 +++++++ src/lib/Options.py | 2 ++ src/sbin/bcfg2 | 17 +++++++++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/man/bcfg2.1 b/man/bcfg2.1 index bf20649c3..938d41dfe 100644 --- a/man/bcfg2.1 +++ b/man/bcfg2.1 @@ -113,6 +113,13 @@ Run bcfg2 in quick mode. Package checksum verification won't be performed. This mode relaxes the constraints of correctness, and thus should only be used in safe conditions. +.TP +.BR "\-Q" +Run bcfg2 in "bundle quick" mode, where only entries in a bundle are +or installed. This runs much faster than -q, but doesn't provide +statistics to the server at all. In order for this option to work, the +-b option must also be provided. This option is incompatible with -r. + .TP .BR "\-r " Cause bcfg2 to remove extra configuration elements it detects. Mode is diff --git a/src/lib/Options.py b/src/lib/Options.py index b467a776d..1dcad6427 100644 --- a/src/lib/Options.py +++ b/src/lib/Options.py @@ -290,6 +290,8 @@ CLIENT_REMOVE = Option('force removal of additional configuration items', default=False, cmd='-r', odesc="") CLIENT_BUNDLE = Option('only configure the given bundle(s)', default=[], cmd='-b', odesc='', cook=colon_split) +CLIENT_BUNDLEQUICK = Option('only verify/configure the given bundle(s)', default=False, + cmd='-Q') CLIENT_INDEP = Option('only configure the given bundle(s)', default=False, cmd='-z') CLIENT_KEVLAR = Option('run in kevlar (bulletproof) mode', default=False, diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2 index 3407a1c53..10262e4a9 100755 --- a/src/sbin/bcfg2 +++ b/src/sbin/bcfg2 @@ -49,6 +49,7 @@ class Client: 'dryrun': Bcfg2.Options.CLIENT_DRYRUN, 'paranoid': Bcfg2.Options.CLIENT_PARANOID, 'bundle': Bcfg2.Options.CLIENT_BUNDLE, + 'bundle-quick': Bcfg2.Options.CLIENT_BUNDLEQUICK, 'indep': Bcfg2.Options.CLIENT_INDEP, 'file': Bcfg2.Options.CLIENT_FILE, 'interactive': Bcfg2.Options.INTERACTIVE, @@ -62,7 +63,6 @@ class Client: 'password': Bcfg2.Options.SERVER_PASSWORD, 'retries': Bcfg2.Options.CLIENT_RETRIES, 'kevlar': Bcfg2.Options.CLIENT_KEVLAR, - 'key': Bcfg2.Options.SERVER_KEY, 'decision-list': DECISION_LIST, 'encoding': Bcfg2.Options.ENCODING, 'omit-lock-check': Bcfg2.Options.OMIT_LOCK_CHECK, @@ -93,6 +93,13 @@ class Client: to_file=self.setup['filelog']) self.logger = logging.getLogger('bcfg2') self.logger.debug(self.setup) + if self.setup['bundle-quick']: + if self.setup['bundle'] == []: + self.logger.error("-Q option requires -b") + raise SystemExit(1) + elif self.setup['remove'] != False: + self.logger.error("-Q option incompatible with -r") + raise SystemExit(1) if 'drivers' in self.setup and self.setup['drivers'] == 'help': self.logger.info("The following drivers are available:") self.logger.info(Bcfg2.Client.Tools.drivers) @@ -251,6 +258,12 @@ class Client: self.fatal_error("Server error: %s" % (self.config.text)) return(1) + if self.setup['bundle-quick']: + newconfig = Bcfg2.Client.XML.XML('') + [newconfig.append(bundle) for bundle in self.config.getchildren() if \ + bundle.tag == 'Bundle' and bundle.get('name') in self.setup['bundle']] + self.config = newconfig + self.tools = Bcfg2.Client.Frame.Frame(self.config, self.setup, times, self.setup['drivers'], @@ -281,7 +294,7 @@ class Client: except OSError: self.logger.error("Failed to unlock lockfile %s" % lockfile.name) - if not self.setup['file']: + if not self.setup['file'] and not self.setup['bundle-quick']: # upload statistics feedback = self.tools.GenerateStats() -- cgit v1.2.3-1-g7c22 From c654cb28381ea0b623ac8c2d17063e6fccce445b Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Fri, 29 Oct 2010 16:05:46 -0400 Subject: SSLCA.py rewritten to use openssl binary --- src/lib/Server/Plugins/SSLCA.py | 531 +++++++++------------------------------- 1 file changed, 122 insertions(+), 409 deletions(-) diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index f18c18944..8f1154d7f 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -1,15 +1,22 @@ +""" +Notes: + +1. Put these notes in real docs!!! +2. dir structure for CA's must be correct +3. for subjectAltNames to work, openssl.conf must have copy_extensions on +""" + + import Bcfg2.Server.Plugin -from subprocess import Popen, PIPE import lxml.etree import posixpath -import logging +import tempfile +from subprocess import Popen, PIPE +from ConfigParser import ConfigParser + import pdb class SSLCA(Bcfg2.Server.Plugin.GroupSpool): - #Bcfg2.Server.Plugin.Plugin, - #Bcfg2.Server.Plugin.Generator, - #Bcfg2.Server.Plugin.DirectoryBacked): - """ The SSLCA generator handles the creation and management of ssl certificates and their keys. @@ -18,23 +25,12 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): __version__ = '$Id:$' __author__ = 'g.hagger@gmail.com' __child__ = Bcfg2.Server.Plugin.FileBacked + key_specs = {} + cert_specs = {} - def __init__(self, core, datastore): - Bcfg2.Server.Plugin.GroupSpool.__init__(self, core, datastore) -# Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) -# Bcfg2.Server.Plugin.Generator.__init__(self) -# try: -# Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, -# self.core.fam) -# except OSError, ioerr: -# self.logger.error("Failed to load SSHbase repository from %s" \ -# % (self.data)) -# self.logger.error(ioerr) -# raise Bcfg2.Server.Plugin.PluginInitError -# def HandleEvent(self, event=None): action = event.code2str() - if event.filename[0] == '/': + if event.filename[0] == '/' or event.filename.startswith('CAs'): return epath = "".join([self.data, self.handles[event.requestID], event.filename]) @@ -45,49 +41,70 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): self.logger.error('ACTION: %s, IDENT %s, FILENAME %s' % (action, ident, event.filename)) + fname = "".join([ident, '/', event.filename]) + + + # TODO: check/fix handling of _all_ .xml file events vs hostfiles if action in ['exists', 'created']: if posixpath.isdir(epath): self.AddDirectoryMonitor(epath[len(self.data):]) if ident not in self.entries and posixpath.isfile(epath): if event.filename.endswith('key.xml'): + key_spec = dict(lxml.etree.parse(epath).find('Key').items()) + self.key_specs[ident] = { + 'bits': key_spec.get('bits', 2048), + 'type': key_spec.get('type', 'rsa') + } self.Entries['Path'][ident] = self.get_key elif event.filename.endswith('cert.xml'): - pass -# self.Entries['Path'][ident] = self.get_cert + cert_spec = dict(lxml.etree.parse(epath).find('Cert').items()) + self.cert_specs[ident] = { + 'ca': cert_spec.get('ca', 'default'), + 'format': cert_spec.get('format', 'pem'), + 'key': cert_spec.get('key'), + 'days': cert_spec.get('days', 365), + 'C': cert_spec.get('c'), + 'L': cert_spec.get('l'), + 'ST': cert_spec.get('st'), + 'OU': cert_spec.get('ou'), + 'O': cert_spec.get('o'), + 'emailAddress': cert_spec.get('emailaddress') + } + self.Entries['Path'][ident] = self.get_cert else: - fname = "".join([ident, '/', event.filename]) self.entries[fname] = self.__child__(epath) self.entries[fname].HandleEvent(event) if action == 'changed': - self.entries[ident].HandleEvent(event) + self.entries[fname].HandleEvent(event) elif action == 'deleted': - fbase = self.handles[event.requestID] + event.filename - if fbase in self.entries: + if fname in self.entries: # a directory was deleted - del self.entries[fbase] - del self.Entries['Path'][fbase] + del self.entries[fname] else: - self.entries[ident].HandleEvent(event) + self.entries[fname].HandleEvent(event) def get_key(self, entry, metadata): - path = entry.get('name') + # set path type and permissions, otherwise bcfg2 won't bind the file permdata = {'owner':'root', 'group':'root', 'type':'file', 'perms':'644'} [entry.attrib.__setitem__(key, permdata[key]) for key in permdata] + + # check if we already have a hostfile, or need to generate a new key + # TODO: verify key fits the specs + path = entry.get('name') filename = "".join([path, '/', path.rsplit('/', 1)[1], '.H_', metadata.hostname]) if filename not in self.entries.keys(): - key = self.build_key(filename, metadata) + key = self.build_key(filename, entry, metadata) open(self.data + filename, 'w').write(key) entry.text = key else: entry.text = self.entries[filename].data - def build_key(self, filename, metadata): - # TODO read params - type = 'rsa' - bits = 2048 + def build_key(self, filename, entry, metadata): + type = self.key_specs[entry.get('name')]['type'] + bits = self.key_specs[entry.get('name')]['bits'] if type == 'rsa': cmd = "openssl genrsa %s " % bits elif type == 'dsa': @@ -96,390 +113,86 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): return key def get_cert(self, entry, metadata): - path = entry.get('name') + # set path type and permissions, otherwise bcfg2 won't bind the file permdata = {'owner':'root', 'group':'root', 'type':'file', 'perms':'644'} [entry.attrib.__setitem__(key, permdata[key]) for key in permdata] + + path = entry.get('name') filename = "".join([path, '/', path.rsplit('/', 1)[1], '.H_', metadata.hostname]) - if filename in self.entries.keys() and self.verify_cert(filename) : + + # first - ensure we have a key to work with + key = self.cert_specs[entry.get('name')].get('key') + key_filename = "".join([key, '/', key.rsplit('/', 1)[1], '.H_', metadata.hostname]) + if key_filename not in self.entries: + e = lxml.etree.Element('Path') + e.attrib['name'] = key + self.core.Bind(e, metadata) + + # check if we have a valid hostfile + if filename in self.entries.keys() and self.verify_cert(): entry.text = self.entries[filename].data else: - cert = self.build_cert(filename, metadata) + cert = self.build_cert(entry, metadata) open(self.data + filename, 'w').write(cert) entry.text = cert def verify_cert(self): - # TODO - # check cert matches key - # check expiry - pass - - def build_req(self): - pass - - def build_cert(self): - pass - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#class SSLCAFile: -# -# def __init__(self, datastore, name, specific, encoding): -# self.data = datastore -# self.name = name -# self.specific = specific -# self.encoding = encoding -# if name.endswith('.xml'): -# self.xml = lxml.etree.parse(name) -# -# def handle_event(self, event=None): -# """Handle all fs events for this file.""" -# if event and event.code2str() == 'deleted': -# return -# -# def bind_entry(self, entry, metadata): -# pdb.set_trace() -# -# -#class SSLCAKeyFile(SSLCAFile): -# -# def __init__(self, datastore, name, specific, encoding): -# SSLCAFile.__init__(self, datastore, name, specific, encoding) -# key_attrs = self.xml.find('Key') -# self.bits = key_attrs.get('bits') -# self.type = key_attrs.get('type') -# -# def bind_entry(self, entry, metadata): -# """Build literal file information.""" -# if entry.tag == 'Path': -# entry.set('type', 'file') -# entry.text = self.get_key(entry, metadata) -# -# def get_key(self, entry, metadata): -# fname = +dir '.H_' + metadata.hostname -# # TODO add logic to get+verify key if hostfile exists & save if not -# pdb.set_trace() -# return self.build_key() -# -# def build_key(self): -# if self.type == 'rsa': -# cmd = "openssl genrsa %s " % self.bits -# elif self.type == 'dsa': -# cmd = "openssl dsaparam -noout -genkey %s" % self.bits -# key = Popen(cmd, shell=True, stdout=PIPE).stdout.read() -# return key -# -# -#class SSLCACertFile(SSLCAFile): -# -# def __init__(self, datastore, name, specific, encoding): -# SSLCAFile.__init__(self, datastore, name, specific, encoding) -# cert_attrs = self.xml.find('Cert') -# #self.format = cert_attrs.get('format') -# #self.key = cert_attrs.get('key') -# #self.ca = cert_attrs.get('ca') -# -# def bind_entry(self, entry, metadata): -# """Build literal file information.""" -# fname = entry.get('realname', entry.get('name')) -# if entry.tag == 'Path': -# entry.set('type', 'file') -# entry.text = 'booya cert' -# -# -#class SSLCAEntrySet(Bcfg2.Server.Plugin.EntrySet): -# """ -# Handles host and group specific entries -# """ -# def __init__(self, datastore, basename, path, entry_type, encoding): -# self.data = datastore -# Bcfg2.Server.Plugin.EntrySet.__init__(self, basename, path, entry_type, encoding) -# -# def entry_init(self, event): -# """Handle template and info file creation.""" -# logger = logging.getLogger('Bcfg2.Plugins.SSLCA') -# if event.filename in self.entries: -# logger.warn("Got duplicate add for %s" % event.filename) -# else: -# fpath = "%s/%s" % (self.path, event.filename) -# try: -# spec = self.specificity_from_filename(event.filename) -# except Bcfg2.Server.Plugin.SpecificityError: -# if not self.ignore.match(event.filename): -# logger.error("Could not process filename %s; ignoring" % fpath) -# return -# self.entries[event.filename] = self.entry_type(self.data, fpath, -# spec, self.encoding) -# self.entries[event.filename].handle_event(event) -# -# -#class SSLCA(Bcfg2.Server.Plugin.GroupSpool): -# """ -# The SSLCA generator handles the creation and -# management of ssl certificates and their keys. -# """ -# name = 'SSLCA' -# __version__ = '$Id:$' -# __author__ = 'g.hagger@gmail.com' -# filename_pattern = '(key|cert)\.xml' -# es_cls = SSLCAEntrySet -# -# def __init__(self, core, datastore): -# Bcfg2.Server.Plugin.GroupSpool.__init__(self, core, datastore) -# -# def HandleEvent(self, event): -# action = event.code2str() -# if event.filename[0] == '/': -# return -# epath = "".join([self.data, self.handles[event.requestID], -# event.filename]) -# if posixpath.isdir(epath): -# ident = self.handles[event.requestID] + event.filename -# else: -# ident = self.handles[event.requestID][:-1] -# -# if action in ['exists', 'created']: -# if posixpath.isdir(epath): -# self.AddDirectoryMonitor(epath[len(self.data):]) -# if ident not in self.entries and posixpath.isfile(epath): -# if event.filename.endswith('key.xml'): -# es_child_cls = SSLCAKeyFile -# elif event.filename.endswith('cert.xml'): -# es_child_cls = SSLCACertFile -# else: -# return -# dirpath = "".join([self.data, ident]) -# self.entries[ident] = self.es_cls(self.data, -# self.filename_pattern, -# dirpath, -# es_child_cls, -# self.encoding) -# self.Entries['Path'][ident] = self.entries[ident].bind_entry -# if not posixpath.isdir(epath): -# # do not pass through directory events -# self.entries[ident].handle_event(event) -# if action == 'changed': -# self.entries[ident].handle_event(event) -# elif action == 'deleted': -# fbase = self.handles[event.requestID] + event.filename -# if fbase in self.entries: -# # a directory was deleted -# del self.entries[fbase] -# del self.Entries['Path'][fbase] -# else: -# self.entries[ident].handle_event(event) - - - - - - - - - - -#import Bcfg2.Options -#import os -#from ConfigParser import ConfigParser, NoSectionError, NoOptionError -#from M2Crypto import RSA, EVP, X509, m2 + return False + + def build_cert(self, entry, metadata): + req_config = self.build_req_config(entry, metadata) + req = self.build_request(req_config, entry) + ca_config = "".join([self.data, '/CAs/', self.cert_specs[entry.get('name')]['ca'], '/', 'openssl.cnf']) + days = self.cert_specs[entry.get('name')]['days'] + cmd = "openssl ca -config %s -in %s -days %s -batch -passin pass:TODO!!!!" % (ca_config, req, days) + pdb.set_trace() + cert = Popen(cmd, shell=True, stdout=PIPE).stdout.read() + # TODO: remove tempfiles + return cert + + def build_req_config(self, entry, metadata): + # create temp request config file + conffile = open(tempfile.mkstemp()[1], 'w') + cp = ConfigParser({}) + cp.optionxform = str + defaults = { + 'req': { + 'default_md': 'sha1', + 'distinguished_name': 'req_distinguished_name', + 'req_extensions': 'v3_req', + 'x509_extensions': 'v3_req', + 'prompt': 'no' + }, + 'req_distinguished_name': {}, + 'v3_req': { + 'subjectAltName': '@alt_names' + }, + 'alt_names': {} + } + for section in defaults.keys(): + cp.add_section(section) + for key in defaults[section]: + cp.set(section, key, defaults[section][key]) + x = 1 + for alias in metadata.aliases: + cp.set('alt_names', 'DNS.'+str(x), alias) + x += 1 + for item in ['C', 'L', 'ST', 'O', 'OU', 'emailAddress']: + if self.cert_specs[entry.get('name')][item]: + cp.set('req_distinguished_name', item, self.cert_specs[entry.get('name')][item]) + cp.set('req_distinguished_name', 'CN', metadata.hostname) + cp.write(conffile) + conffile.close() + return conffile.name + + def build_request(self, req_config, entry): + req = tempfile.mkstemp()[1] + key = self.cert_specs[entry.get('name')]['key'] + days = self.cert_specs[entry.get('name')]['days'] + cmd = "openssl req -new -config %s -days %s -key %s -text -out %s" % (req_config, days, key, req) + res = Popen(cmd, shell=True, stdout=PIPE).stdout.read() + return req -#class SSLCA(Bcfg2.Server.Plugin.Plugin, -# Bcfg2.Server.Plugin.Generator, -# Bcfg2.Server.Plugin.DirectoryBacked): -# """ -# The sslca generator manages ssl certificates -# and keys -# """ -# -# name = 'SSLbase' -# __version__ = '0.00000000001' -# __author__ = 'ghagger@wgen.net' -# -# hostkey = 'localhost.key' -# hostcert = 'localhost.crt' -# -# def __init__(self, core, datastore): -# Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) -# Bcfg2.Server.Plugin.Generator.__init__(self) -# try: -# Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, -# self.core.fam) -# except OSError, ioerr: -# self.logger.error("Failed to load SSLbase repository from %s" \ -# % (self.data)) -# self.logger.error(ioerr) -# raise Bcfg2.Server.Plugin.PluginInitError -# self.Entries = {'Path': -# {'/etc/pki/tls/private/localhost.key': self.get_key, -# '/etc/pki/tls/certs/localhost.crt': self.get_cert}} -# # grab essential sslca configuration from bcfg2.conf -# cp = ConfigParser() -# cp.read(Bcfg2.Options.CFILE.value) -# try: -# ca_cert_filename = cp.get('sslca', 'ca_cert') -# ca_key_filename = cp.get('sslca', 'ca_key') -# self.ca_key_passphrase = cp.get('sslca', 'ca_key_passphrase') -# self.cert_subject = cp.get('sslca', 'cert_subject') -# self.cert_days = cp.get('sslca', 'cert_days') -# self.pkey_bits = cp.get('sslca', 'pkey_bits') -# except: -# raise NoOptionError -# self.ca_cert = X509.load_cert(ca_cert_filename) -# self.ca_key = EVP.load_key(ca_key_filename, lambda x: self.ca_key_passphrase) -# self._newkey = False -# -# def get_key(self, entry, metadata): -# filename = self.hostkey+".H_%s" % metadata.hostname -# if filename in self.entries.keys(): -# entry.text = self.entries[filename].data -# self.pkey = EVP.load_key_string(entry.text) -# else: -# (self.pkey, entry.text) = self.build_key(filename) -# keyfile = open(self.data + '/' +filename, 'w') -# keyfile.write(entry.text) -# keyfile.close() -# self._newkey = True -# -# def build_key(self, filename): -# """Generate new private key for client.""" -# rsa_key = RSA.gen_key(int(self.pkey_bits), m2.RSA_F4) -# pkey = EVP.PKey() -# pkey.assign_rsa(rsa_key) -# keyfile = open(self.data + '/' +filename, 'w') -# keyfile.write(pkey.as_pem(cipher=None)) -# keyfile.close() -# self._newkey = True -# return pkey, pkey.as_pem(cipher=None) -# -# def get_cert(self, entry, metadata): -# filename = self.hostcert + ".H_%s" % metadata.hostname -# # load prexisting cert, if any -# if filename in self.entries.keys() and self._newkey == False: -# cert = X509.load_cert_string(self.entries[filename].data) -# # check cert subjectAltNames match current aliases -# cert_aliases = cert.get_ext('subjectAltName') -# if cert_aliases: -# if metadata.aliases != [alias.lstrip('DNS:') for alias in cert_aliases.get_value().split(', ')]: -# entry.text = self.build_cert(filename, metadata) -# return -# entry.text = cert.as_text()+cert.as_string() -# else: -# entry.text = self.build_cert(filename, metadata) -# -# def get_serial(self): -# serialpath = self.data + '/serial' -# serial = 0 -# if os.path.isfile(serialpath): -# serialfile = open(serialpath, 'r') -# serial = int(serialfile.read()) -# serialfile.close() -# serialfile = open(serialpath, 'w') -# serial += 1 -# serialfile.write(str(serial)) -# serialfile.close() -# return serial -# -# def build_cert(self, filename, metadata): -# req = self.make_request(self.pkey, metadata) -# serial = self.get_serial() -# cert = self.make_cert(req, serial, metadata.aliases) -# cert_out = cert.as_text()+cert.as_pem() -# certfile = open(self.data + '/' +filename, 'w') -# certfile.write(cert_out) -# certfile.close() -# cert_store = self.data + '/certstore' -# if not os.path.isdir(cert_store): -# os.mkdir(cert_store) -# storefile = open(cert_store + '/' + str(serial) + '.pem', 'w') -# storefile.write(cert_out) -# storefile.close() -# return cert_out -# -# def make_request(self, key, metadata): -# req = X509.Request() -# req.set_version(2) -# req.set_pubkey(key) -# name = X509.X509_Name() -# parts = [a.split('=') for a in self.cert_subject.split(',')] -# [setattr(name, k, v) for k,v in parts] -# name.CN = metadata.hostname -# req.set_subject_name(name) -# req.sign(key, 'sha1') -# return req -# -# def make_cert(self, req, serial, aliases): -# pkey = req.get_pubkey() -# if not req.verify(pkey): -# raise ValueError, 'Error verifying request' -# sub = req.get_subject() -# cert = X509.X509() -# cert.set_serial_number(serial) -# cert.set_version(2) -# cert.set_subject(sub) -# cert.set_issuer(self.ca_cert) -# cert.set_pubkey(pkey) -# notBefore = m2.x509_get_not_before(cert.x509) -# notAfter = m2.x509_get_not_after(cert.x509) -# m2.x509_gmtime_adj(notBefore, 0) -# m2.x509_gmtime_adj(notAfter, 60*60*24*long(self.cert_days)) -# exts = [ -# ('basicConstraints','CA:FALSE'), -# ('subjectKeyIdentifier','hash'), -# ('authorityKeyIdentifier','keyid,issuer:always'), -# ('nsCertType','SSL Server'), -# ] -# if aliases: -# exts.append(('subjectAltName', ','.join(['DNS:'+alias for alias in aliases]))) -# for ext in exts: -# cert.add_ext(X509.new_extension(ext[0],ext[1])) -# cert.sign(self.ca_key, 'sha1') -# return cert -# -# def HandleEvent(self, event=None): -# """Local event handler that does something....""" -# Bcfg2.Server.Plugin.DirectoryBacked.HandleEvent(self, event) -# -# def HandlesEntry(self, entry, _): -# """Handle entries dynamically.""" -# return entry.tag == 'Path' and (entry.get('name').endswith(self.hostkey) or entry.get('name').endswith(self.hostcert)) -# -- cgit v1.2.3-1-g7c22 From 347f9f2814dc8cdfc12a0c38fcb78c942622bf5d Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Mon, 1 Nov 2010 16:10:52 -0400 Subject: Now reads ca key passphrases from bcfg2.conf Corrected handling of modifications to xml files --- src/lib/Server/Plugins/SSLCA.py | 87 ++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 22 deletions(-) diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index 8f1154d7f..d2137f23f 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -8,9 +8,11 @@ Notes: import Bcfg2.Server.Plugin +import Bcfg2.Options import lxml.etree import posixpath import tempfile +import os from subprocess import Popen, PIPE from ConfigParser import ConfigParser @@ -27,8 +29,13 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): __child__ = Bcfg2.Server.Plugin.FileBacked key_specs = {} cert_specs = {} + ca_passphrases = {} def HandleEvent(self, event=None): + """ + Updates which files this plugin handles based upon filesystem events. + Allows configuration items to be added/removed without server restarts. + """ action = event.code2str() if event.filename[0] == '/' or event.filename.startswith('CAs'): return @@ -39,16 +46,10 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): else: ident = self.handles[event.requestID][:-1] - self.logger.error('ACTION: %s, IDENT %s, FILENAME %s' % (action, ident, event.filename)) - fname = "".join([ident, '/', event.filename]) - - # TODO: check/fix handling of _all_ .xml file events vs hostfiles - if action in ['exists', 'created']: - if posixpath.isdir(epath): - self.AddDirectoryMonitor(epath[len(self.data):]) - if ident not in self.entries and posixpath.isfile(epath): + if event.filename.endswith('.xml'): + if action in ['exists', 'created', 'changed']: if event.filename.endswith('key.xml'): key_spec = dict(lxml.etree.parse(epath).find('Key').items()) self.key_specs[ident] = { @@ -58,8 +59,9 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): self.Entries['Path'][ident] = self.get_key elif event.filename.endswith('cert.xml'): cert_spec = dict(lxml.etree.parse(epath).find('Cert').items()) + ca = cert_spec.get('ca', 'default') self.cert_specs[ident] = { - 'ca': cert_spec.get('ca', 'default'), + 'ca': ca, 'format': cert_spec.get('format', 'pem'), 'key': cert_spec.get('key'), 'days': cert_spec.get('days', 365), @@ -70,20 +72,33 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): 'O': cert_spec.get('o'), 'emailAddress': cert_spec.get('emailaddress') } + cp = ConfigParser() + cp.read(self.core.cfile) + self.ca_passphrases[ca] = cp.get('sslca', ca+'_passphrase') self.Entries['Path'][ident] = self.get_cert - else: + if action == 'deleted': + if ident in self.Entries['Path']: + del self.Entries['Path'][ident] + else: + if action in ['exists', 'created']: + if posixpath.isdir(epath): + self.AddDirectoryMonitor(epath[len(self.data):]) + if ident not in self.entries and posixpath.isfile(epath): self.entries[fname] = self.__child__(epath) self.entries[fname].HandleEvent(event) - if action == 'changed': - self.entries[fname].HandleEvent(event) - elif action == 'deleted': - if fname in self.entries: - # a directory was deleted - del self.entries[fname] - else: + if action == 'changed': self.entries[fname].HandleEvent(event) + elif action == 'deleted': + if fname in self.entries: + del self.entries[fname] + else: + self.entries[fname].HandleEvent(event) def get_key(self, entry, metadata): + """ + either grabs a prexisting key hostfile, or triggers the generation + of a new key if one doesn't exist. + """ # set path type and permissions, otherwise bcfg2 won't bind the file permdata = {'owner':'root', 'group':'root', @@ -103,6 +118,9 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): entry.text = self.entries[filename].data def build_key(self, filename, entry, metadata): + """ + generates a new key according the the specification + """ type = self.key_specs[entry.get('name')]['type'] bits = self.key_specs[entry.get('name')]['bits'] if type == 'rsa': @@ -113,6 +131,10 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): return key def get_cert(self, entry, metadata): + """ + either grabs a prexisting cert hostfile, or triggers the generation + of a new cert if one doesn't exist. + """ # set path type and permissions, otherwise bcfg2 won't bind the file permdata = {'owner':'root', 'group':'root', @@ -140,20 +162,38 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): entry.text = cert def verify_cert(self): - return False + """ + check that a certificate validates against the ca cert, + and that it has not expired. + """ + # TODO: verify key validates and has not expired + # possibly also ensure no less than x days until expiry + return True def build_cert(self, entry, metadata): + """ + creates a new certificate according to the specification + """ req_config = self.build_req_config(entry, metadata) req = self.build_request(req_config, entry) - ca_config = "".join([self.data, '/CAs/', self.cert_specs[entry.get('name')]['ca'], '/', 'openssl.cnf']) + ca = self.cert_specs[entry.get('name')]['ca'] + ca_config = "".join([self.data, '/CAs/', ca, '/', 'openssl.cnf']) days = self.cert_specs[entry.get('name')]['days'] - cmd = "openssl ca -config %s -in %s -days %s -batch -passin pass:TODO!!!!" % (ca_config, req, days) - pdb.set_trace() + passphrase = self.ca_passphrases[ca] + cmd = "openssl ca -config %s -in %s -days %s -batch -passin pass:%s" % (ca_config, req, days, passphrase) cert = Popen(cmd, shell=True, stdout=PIPE).stdout.read() - # TODO: remove tempfiles + try: + os.unlink(req_config) + os.unlink(req) + except OSError: + self.logger.error("Failed to unlink temporary files") return cert def build_req_config(self, entry, metadata): + """ + generates a temporary openssl configuration file that is + used to generate the required certificate request + """ # create temp request config file conffile = open(tempfile.mkstemp()[1], 'w') cp = ConfigParser({}) @@ -189,6 +229,9 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): return conffile.name def build_request(self, req_config, entry): + """ + creates the certificate request + """ req = tempfile.mkstemp()[1] key = self.cert_specs[entry.get('name')]['key'] days = self.cert_specs[entry.get('name')]['days'] -- cgit v1.2.3-1-g7c22 From d7ce5d6926dffab8c167d41f4068d0f71c9beda7 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Tue, 2 Nov 2010 13:03:05 -0500 Subject: bcfg2-info: showentries matches argument length incorrectly --- src/sbin/bcfg2-info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info index d3a9bf8be..497c39174 100755 --- a/src/sbin/bcfg2-info +++ b/src/sbin/bcfg2-info @@ -303,7 +303,7 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): def do_showentries(self, args): """Show abstract configuration entries for a given host.""" arglen = len(args.split()) - if arglen not in [2, 3]: + if arglen not in [1, 2]: print("Usage: showentries ") return client = args.split()[0] -- cgit v1.2.3-1-g7c22 From b7ebe51fbd178e0e20b009cfe4f9d4a7fd352aed Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Tue, 2 Nov 2010 13:03:05 -0500 Subject: bcfg2-info: showentries matches argument length incorrectly (cherry picked from commit d7ce5d6926dffab8c167d41f4068d0f71c9beda7) --- src/sbin/bcfg2-info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info index 6732d8830..9721122f3 100755 --- a/src/sbin/bcfg2-info +++ b/src/sbin/bcfg2-info @@ -303,7 +303,7 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): def do_showentries(self, args): """Show abstract configuration entries for a given host.""" arglen = len(args.split()) - if arglen not in [2, 3]: + if arglen not in [1, 2]: print("Usage: showentries ") return client = args.split()[0] -- cgit v1.2.3-1-g7c22 From b75139eb492ca3485c4bc6328265f3e75e9624fe Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Tue, 2 Nov 2010 13:52:19 -0500 Subject: docs: Added more information for the metadata object used in TGenshi and TCheetah --- doc/server/plugins/generators/tcheetah.txt | 16 +----- doc/server/plugins/generators/tgenshi/index.txt | 6 ++- doc/server/plugins/grouping/metadata.txt | 67 +++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/doc/server/plugins/generators/tcheetah.txt b/doc/server/plugins/generators/tcheetah.txt index e1ad600a2..52a0f3264 100644 --- a/doc/server/plugins/generators/tcheetah.txt +++ b/doc/server/plugins/generators/tcheetah.txt @@ -27,7 +27,7 @@ located in in a ``TCheetah`` subdirectory of your repository, usually files, ``template`` and ``info``. The template is a standard Cheetah template with two additions: -* `self.metadata` is the client's metadata +* `self.metadata` is the client's :ref:`metadata ` * `self.properties` is an xml document of unstructured data The ``info`` file is formatted like ``:info`` files from Cfg. @@ -44,19 +44,7 @@ Permissions entry and a Path entry to handle the same file. self.metadata variables ======================= -The following variables are available for self.metadata: - -* hostname -* bundles -* groups -* categories -* probes -* uuid -* password - -self.metadata is an instance of the class -ClientMetadata of file `Bcfg2/Server/Plugins/Metadata.py -`_. +self.metadata is an instance of the class ClientMetadata and documented :ref:`here `. self.properties =============== diff --git a/doc/server/plugins/generators/tgenshi/index.txt b/doc/server/plugins/generators/tgenshi/index.txt index cd9bcf152..425b3a289 100644 --- a/doc/server/plugins/generators/tgenshi/index.txt +++ b/doc/server/plugins/generators/tgenshi/index.txt @@ -48,8 +48,10 @@ supported. Inside of templates =================== -* metadata is the client's metadata -* properties.properties is an xml document of unstructured data +* **metadata** is the client's :ref:`metadata ` +* **properties.properties** is an xml document of unstructured data +* **name** is the path name specified in bcfg +* **path** is the path to the TGenshi template See the genshi `documentation `_ for examples of diff --git a/doc/server/plugins/grouping/metadata.txt b/doc/server/plugins/grouping/metadata.txt index 96fc70ff5..22c967262 100644 --- a/doc/server/plugins/grouping/metadata.txt +++ b/doc/server/plugins/grouping/metadata.txt @@ -225,3 +225,70 @@ Probes The metadata plugin includes client-side probing functionality. This is fully documented :ref:`here `. + +.. _server-plugins-grouping-metadata-clientmetadata: + +ClientMetadata +============== + +A special client metadata class is available to the TGenshi and TCheetah +plugins. + ++----------------------+------------------------------------------------+-------------------+ +| Attribute | Description | Value | ++======================+================================================+===================+ +| hostname | Client hostname | String | ++----------------------+------------------------------------------------+-------------------+ +| profile | Client profile | String | ++----------------------+------------------------------------------------+-------------------+ +| aliases | Client aliases | List | ++----------------------+------------------------------------------------+-------------------+ +| addresses | Adresses this client is known by | List | ++----------------------+------------------------------------------------+-------------------+ +| groups | Groups this client is a member of | List | ++----------------------+------------------------------------------------+-------------------+ +| categories | Categories of this clients groups | List | ++----------------------+------------------------------------------------+-------------------+ +| uuid | uuid identifier for this client | String | ++----------------------+------------------------------------------------+-------------------+ +| password | bcfg password for this client | String | ++----------------------+------------------------------------------------+-------------------+ +| connectors | connector plugins known to this client | List | ++----------------------+------------------------------------------------+-------------------+ +| query | MetadataQuery object | MetadataQuery | ++----------------------+------------------------------------------------+-------------------+ + +| + ++------------------------------+------------------------------------------------+-------------------+ +| Method | Description | Value | ++==============================+================================================+===================+ +| inGroup(group) | True if this client is a memnber of 'group' | Boolean | ++------------------------------+------------------------------------------------+-------------------+ +| group_in_category(category) | Returns the group in 'category' if the client | String | +| | is a member of 'category', otherwise '' | | ++------------------------------+------------------------------------------------+-------------------+ + +MetadataQuery +------------- + +This class provides query routines for the servers Metadata. + ++------------------------------+------------------------------------------------+-------------------+ +| Method | Description | Value | ++==============================+================================================+===================+ +| by_name(client) | Get ClientMetadata object for 'client' | ClientMetadata | ++------------------------------+------------------------------------------------+-------------------+ +| names_by_groups(group) | | | ++------------------------------+------------------------------------------------+-------------------+ +| names_by_profiles(profile) | All clients names in 'profile' | List | ++------------------------------+------------------------------------------------+-------------------+ +| all_clients() | All known client hostnames | List | ++------------------------------+------------------------------------------------+-------------------+ +| all_groups() | All known group names | List | ++------------------------------+------------------------------------------------+-------------------+ +| all_groups_in_category(cat) | All groups in category 'cat' | List | ++------------------------------+------------------------------------------------+-------------------+ +| all() | Get ClientMetadata for all clients | List | ++------------------------------+------------------------------------------------+-------------------+ + -- cgit v1.2.3-1-g7c22 From 53a383ab2afcbcac748b5387cbfb786feb5f7acf Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 2 Nov 2010 18:46:23 -0500 Subject: YUMng: Sync Joe Digilio's patch over from svn Jack Neely's commit message: Add a patch from Joe Digilio to include a verify_flags knob. I've added a line to also load this from the config file, and log in debug mode. Specifying 'verify_flags' with an Instance will override the values from the config file. Signed-off-by: Sol Jerome --- src/lib/Client/Tools/YUMng.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/Client/Tools/YUMng.py b/src/lib/Client/Tools/YUMng.py index 9cdcdca40..f0d906717 100644 --- a/src/lib/Client/Tools/YUMng.py +++ b/src/lib/Client/Tools/YUMng.py @@ -210,6 +210,8 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): "version_fail_action", "upgrade").lower() == "upgrade" self.doReinst = CP.get(self.name, "verify_fail_action", "reinstall").lower() == "reinstall" + self.verifyFlags = CP.get(self.name, "verify_flags", + "").lower().replace(' ', ',') self.installOnlyPkgs = self.yb.conf.installonlypkgs if 'gpg-pubkey' not in self.installOnlyPkgs: @@ -225,6 +227,7 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): % self.doReinst) self.logger.debug("YUMng: installOnlyPkgs: %s" \ % str(self.installOnlyPkgs)) + self.logger.debug("YUMng: verify_flags: %s" % self.verifyFlags) def _fixAutoVersion(self, entry): # old style entry; synthesize Instances from current installed @@ -436,6 +439,8 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): stat['verify_fail'] = False stat['pkg'] = entry stat['modlist'] = modlist + verify_flags = inst.get('verify_flags', self.verifyFlags) + verify_flags = verify_flags.lower().replace(' ', ',').split(',') if len(POs) == 0: # Package not installed @@ -505,6 +510,8 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): for p in probs: if p.type == 'missing' and os.path.islink(fn): continue + elif 'no' + p.type in verify_flags: + continue if p.type not in ['missingok', 'ghost']: tmp.append((p.type, p.message)) if tmp != []: -- cgit v1.2.3-1-g7c22 From feed7f02aeda0b8abe4a3a521e6ab13081c84232 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Tue, 2 Nov 2010 19:39:24 -0500 Subject: reports: fix bcfg2-admin reports init when db is nonexistent --- src/lib/Server/Reports/updatefix.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib/Server/Reports/updatefix.py b/src/lib/Server/Reports/updatefix.py index 6d9b5e952..f8fca1f90 100644 --- a/src/lib/Server/Reports/updatefix.py +++ b/src/lib/Server/Reports/updatefix.py @@ -139,8 +139,12 @@ def dosync(): fresh = True # ensure database connection are close, so that the management can do it's job right - cursor.close() - connection.close() + try: + cursor.close() + connection.close() + except: + # ignore any errors from missing/invalid dbs + pass # Do the syncdb according to the django version if "call_command" in dir(django.core.management): # this is available since django 1.0 alpha. -- cgit v1.2.3-1-g7c22 From 6079a4b01ee4d500fb79cd5552f00e987ed65485 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Tue, 2 Nov 2010 19:39:24 -0500 Subject: reports: fix bcfg2-admin reports init when db is nonexistent (cherry picked from commit feed7f02aeda0b8abe4a3a521e6ab13081c84232) --- src/lib/Server/Reports/updatefix.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib/Server/Reports/updatefix.py b/src/lib/Server/Reports/updatefix.py index 6d9b5e952..f8fca1f90 100644 --- a/src/lib/Server/Reports/updatefix.py +++ b/src/lib/Server/Reports/updatefix.py @@ -139,8 +139,12 @@ def dosync(): fresh = True # ensure database connection are close, so that the management can do it's job right - cursor.close() - connection.close() + try: + cursor.close() + connection.close() + except: + # ignore any errors from missing/invalid dbs + pass # Do the syncdb according to the django version if "call_command" in dir(django.core.management): # this is available since django 1.0 alpha. -- cgit v1.2.3-1-g7c22 From d4a8aa409cd3db6143f91809466866e9b088254c Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Tue, 2 Nov 2010 21:16:36 -0400 Subject: Properly documented the way this _should_ work. Need to make some small changes to the SSLCA plugin itself to make this truly the case. --- doc/server/plugins/generators/sslca.txt | 155 +++++++++++++++----------------- 1 file changed, 73 insertions(+), 82 deletions(-) diff --git a/doc/server/plugins/generators/sslca.txt b/doc/server/plugins/generators/sslca.txt index 5f987be1e..118a16559 100644 --- a/doc/server/plugins/generators/sslca.txt +++ b/doc/server/plugins/generators/sslca.txt @@ -1,105 +1,96 @@ +.. -*- mode: rst -*- + +.. _server-plugins-generators-sslca: + ===== SSLCA ===== -SSLCA is a simple generator plugin designed to handle creation of -SSL private keys and certificates on request. +SSLCA is a generator plugin designed to handle creation of SSL private keys +and certificates on request. -At present, only the following file locations are supported, and thus -only a single key and certifcate will be generated: +Borrowing ideas from the TGenshi and SSHbase plugins, SSLCA automates the +generation of SSL certificates by allowing you to specify key and certificate +definitions. Then, when a client requests a Path that contains such a +definition within the SSLCA repository, the matching key/cert is generated, and +stored in a hostfile in the repo so that subsequent requests do not result in +repeated key/cert recreation. In the event that a new key or cert is needed, +the offending hostfile can simply be removed from the repository, and the next +time that host checks in, a new file will be created. If that file happens to +be the key, any dependent certificates will also be regenerated. -* /etc/pki/tls/private/localhost.key -* /etc/pki/tls/certs/localhost.crt +Getting started +=============== -While this could be seen as very limiting, SSLCA does support any aliases -specified in clients.xml. Any aliases will be added to the cert under the -subjectAltName extension. +In order to use SSLCA, you must first have at least one CA configured on +your system. For details on setting up your own OpenSSL based CA, please +see http://www.openssl.org/docs/apps/ca.html for details of the suggested +directory layout and configuration directives. +For SSLCA to work, the openssl.cnf (or other configuration file) for that CA +must contain full (not relative) paths. -Interacting with SSLCA -====================== +#. Add SSLCA to the **plugins** line in ``/etc/bcfg2.conf`` and restart the + server -- This enabled the SSLCA plugin on the Bcfg2 server. -* Pre-seeding with existing keys/certs -- Currently existing keys/certs - will be overwritten by new, sslca-managed ones by default. Pre-existing - files can be added to the repository by putting them in - /SSLCA/.H_ +#. Add a section to your ``/etc/bcfg2.conf`` called sslca_foo, replacing foo +with the name you wish to give your CA so you can reference it in certificate +definitions. -* Revoking existing keys -- deleting /SSLCA/\*.H_ - will remove files for an existing client. +#. Under that section, add an entry for ``config`` that gives the location of +the openssl configuration file for your CA. +#. If necessary, add an entry for ``passphrase`` containing the passphrase for +the CA's private key. We store this in ``/etc/bcfg2.conf`` as the permissions +on that file should have it only readable by the bcfg2 user. If no passphrase +is entry exists, it is assumed that the private key is stored unencrypted. -Getting started -=============== +#. Add an entry ``chaincert`` that points to the location of your ssl chaining +certificate. This is used when preexisting certifcate hostfiles are found, so +that they can be validated and only regenerated if they no longer meet the +specification. -#. Add SSLCA to the **plugins** line in ``/etc/bcfg2.conf`` and - restart the server -- This enables the SSLCA plugin on the Bcfg2 - server. +#. Once all this is done, you should have a section in your ``/etc/bcfg2.conf`` +that looks similar to the following: -#. Add Path entries for ``/etc/pki/tls/private/localhost.key``, and - ``/etc/pky/tls/certs/localhost.crt``, etc to a bundle or base. + [sslca_default] + config = /etc/pki/CA/openssl.cnf + passphrase = youReallyThinkIdShareThis? + chaincert = /etc/pki/CA/chaincert.crt -#. Add a [sslca] section to ``/etc/bcfg2.conf`` contaning the following - information: +#. You are now ready to create key and certificate definitions. For this +example we'll assume you've added Path entries for the key, +``/etc/pki/tls/private/localhost.key``, and the certificate, +``/etc/pki/tls/certs/localhost.crt`` to a bundle or base. - ca_cert - location of the CA certificate - ca_key - CA private key - ca_key_passphrase - Passphrase (if any) needed to use the CA private key - cert_subject - Additional subject info for the resulting certificates, CN - will always be the bcfg2 clients hostname. - cert_days - number of days from generation that cert should be valid. - pkey_bits - number of bits for the private key. +#. Defining a key or certificate is similar to defining a TGenshi template. +Under your Bcfg2's SSLCA directory, create the directory structure to match the +path to your key. In this case this would be something like +``/var/lib/bcfg2/SSLCA/etc/pki/tls/private/localhost.key``. -#. Enjoy. +#. Within that directory, create a ``key.xml`` file containing the following: + + + + +#. This will cause the generation of an 2048 bit RSA key when a client requests +that Path. Alternatively you can specify ``dsa`` as the keytype, or a different +number of bits. + +#. Similarly, create the matching directory structure for the certificate path, +and a ``cert.xml`` containinng the following: + + + + + +#. When a client requests the cert path, a certificate will be generated using +the key hostfile at the specified key location, using the CA matching the ca +attribute. ie. ca="default" will match [sslca_default] in your +``/etc/bcfg2.conf`` -==== TODO ==== -V1.0 - Nearly done... - -...need to add cert expiry checking/regen... - -...otherwise the below is done, but really should be rewritten to -use openssl binary rather than patched m2crypto - -Only handles localhost.key and localhost.crt, therefor -assuming we only care about a cert for www, or all ssl services -will use the same cert - -Initialiazation: -Grab options from bcfg2.conf -load cakey, cacert -cache other options - -Req comes in for key & cert -If key exists: - load key - cache key - return key -Else: - gen key - cache key - save key - return key -If cert exists: - load cert - If fails to verify against key: - gen cert - save cert - return cert - If aliases fail don't match - gen cert - save cert - return cert - return cert -Else: - gen cert - save cert - return cert - - - -V2.0 - Maybe create additional types, SSLCertPath, SSLKeyPath, -to allow generation of multiple certs/keys in arbitrary locations - +#. Add generation of pkcs12 format certs -- cgit v1.2.3-1-g7c22 From e2b8d674fe5a38906fcd07e760303178e2fe5c30 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 2 Nov 2010 20:31:51 -0500 Subject: doc: Fix broken link to help pages Signed-off-by: Sol Jerome --- doc/getting_started/index.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/getting_started/index.txt b/doc/getting_started/index.txt index fe52807d4..2c05c5238 100644 --- a/doc/getting_started/index.txt +++ b/doc/getting_started/index.txt @@ -9,7 +9,7 @@ Using Bcfg2 These are many of the resources available to help new users get started. * For the impatient there is the :ref:`quickstart-index` page. -* :ref:`gettinghelp` has information when you are troubleshooting or need to ask a question. +* :ref:`help-index` has information when you are troubleshooting or need to ask a question. * If you find anything wrong or missing please :ref:`report-a-bug` to let us know. .. toctree:: -- cgit v1.2.3-1-g7c22 From 5fe38f0054cf392829b69961b864f284e34057f4 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Tue, 2 Nov 2010 19:39:24 -0500 Subject: reports: fix bcfg2-admin reports init when db is nonexistent (cherry picked from commit feed7f02aeda0b8abe4a3a521e6ab13081c84232) --- src/lib/Server/Reports/updatefix.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib/Server/Reports/updatefix.py b/src/lib/Server/Reports/updatefix.py index 6d9b5e952..f8fca1f90 100644 --- a/src/lib/Server/Reports/updatefix.py +++ b/src/lib/Server/Reports/updatefix.py @@ -139,8 +139,12 @@ def dosync(): fresh = True # ensure database connection are close, so that the management can do it's job right - cursor.close() - connection.close() + try: + cursor.close() + connection.close() + except: + # ignore any errors from missing/invalid dbs + pass # Do the syncdb according to the django version if "call_command" in dir(django.core.management): # this is available since django 1.0 alpha. -- cgit v1.2.3-1-g7c22 From 2435042c73537a368cda92a4a01c9009d3aaffbe Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Thu, 14 Oct 2010 15:28:58 -0500 Subject: web reports: new skin --- reports/site_media/AnchorPosition.js | 147 ++ reports/site_media/CalendarPopup.js | 739 +++++++- reports/site_media/PopupWindow.js | 336 ++++ reports/site_media/base.css | 5 - reports/site_media/bcfg2.js | 26 + reports/site_media/bcfg2_base.css | 244 +++ reports/site_media/boxypastel.css | 230 --- reports/site_media/date.js | 335 ++++ reports/site_media/global.css | 10 - reports/site_media/layout.css | 44 - reports/site_media/main.js | 27 - reports/site_media/sorttable.js | 203 -- reports/site_media/syntax-coloring.css | 59 - reports/site_media/yui/dom/README | 75 - reports/site_media/yui/dom/dom-debug.js | 927 --------- reports/site_media/yui/dom/dom-min.js | 59 - reports/site_media/yui/dom/dom.js | 892 --------- reports/site_media/yui/event/README | 135 -- reports/site_media/yui/event/event-debug.js | 1797 ------------------ reports/site_media/yui/event/event-min.js | 69 - reports/site_media/yui/event/event.js | 1771 ------------------ reports/site_media/yui/round_tabs.css | 76 - reports/site_media/yui/tabview/README | 16 - .../site_media/yui/tabview/assets/border_tabs.css | 48 - reports/site_media/yui/tabview/assets/tabview.css | 69 - reports/site_media/yui/tabview/tabview-debug.js | 1964 -------------------- reports/site_media/yui/tabview/tabview-min.js | 61 - reports/site_media/yui/tabview/tabview.js | 1945 ------------------- reports/site_media/yui/yahoo/README | 45 - reports/site_media/yui/yahoo/yahoo-debug.js | 144 -- reports/site_media/yui/yahoo/yahoo-min.js | 12 - reports/site_media/yui/yahoo/yahoo.js | 143 -- setup.py | 14 +- src/lib/Server/Plugin.py | 4 +- src/lib/Server/Reports/reports/models.py | 120 +- src/lib/Server/Reports/reports/models.py.orig | 330 ++++ src/lib/Server/Reports/reports/models.py.rej | 15 + src/lib/Server/Reports/reports/templates/404.html | 8 + .../Reports/reports/templates/base-timeview.html | 25 + src/lib/Server/Reports/reports/templates/base.html | 122 +- .../reports/templates/clients/client-nodebox.html | 63 - .../Reports/reports/templates/clients/detail.html | 130 +- .../reports/templates/clients/detailed-list.html | 79 +- .../Reports/reports/templates/clients/history.html | 20 + .../Reports/reports/templates/clients/index.html | 61 +- .../Reports/reports/templates/clients/manage.html | 62 +- .../reports/templates/config_items/index.html | 100 - .../reports/templates/config_items/item.html | 109 ++ .../reports/templates/config_items/listing.html | 62 +- .../Reports/reports/templates/displays/index.html | 18 - .../displays/summary-block-direct-links.html | 7 - .../reports/templates/displays/summary-block.html | 90 - .../reports/templates/displays/summary.html | 63 +- .../reports/templates/displays/sys_view.html | 20 - .../Reports/reports/templates/displays/timing.html | 72 +- .../Server/Reports/reports/templates/index.html | 15 - .../reports/templates/widgets/filter_bar.html | 13 + .../reports/templates/widgets/interaction_list.inc | 38 + .../reports/templates/widgets/page_bar.html | 23 + .../Reports/reports/templatetags/bcfg2_tags.py | 239 +++ .../reports/templatetags/django_templating_sigh.py | 41 - .../reports/templatetags/syntax_coloring.py | 26 +- src/lib/Server/Reports/reports/urls.py | 55 + src/lib/Server/Reports/reports/views.py | 647 +++---- src/lib/Server/Reports/settings.py | 25 +- src/lib/Server/Reports/urls.py | 56 +- src/lib/Server/Reports/utils.py | 94 +- 67 files changed, 3538 insertions(+), 11981 deletions(-) create mode 100644 reports/site_media/AnchorPosition.js create mode 100644 reports/site_media/PopupWindow.js delete mode 100644 reports/site_media/base.css create mode 100644 reports/site_media/bcfg2.js create mode 100644 reports/site_media/bcfg2_base.css delete mode 100644 reports/site_media/boxypastel.css create mode 100644 reports/site_media/date.js delete mode 100644 reports/site_media/global.css delete mode 100644 reports/site_media/layout.css delete mode 100644 reports/site_media/main.js delete mode 100644 reports/site_media/sorttable.js delete mode 100644 reports/site_media/syntax-coloring.css delete mode 100644 reports/site_media/yui/dom/README delete mode 100644 reports/site_media/yui/dom/dom-debug.js delete mode 100644 reports/site_media/yui/dom/dom-min.js delete mode 100644 reports/site_media/yui/dom/dom.js delete mode 100644 reports/site_media/yui/event/README delete mode 100644 reports/site_media/yui/event/event-debug.js delete mode 100644 reports/site_media/yui/event/event-min.js delete mode 100644 reports/site_media/yui/event/event.js delete mode 100644 reports/site_media/yui/round_tabs.css delete mode 100644 reports/site_media/yui/tabview/README delete mode 100644 reports/site_media/yui/tabview/assets/border_tabs.css delete mode 100644 reports/site_media/yui/tabview/assets/tabview.css delete mode 100644 reports/site_media/yui/tabview/tabview-debug.js delete mode 100644 reports/site_media/yui/tabview/tabview-min.js delete mode 100644 reports/site_media/yui/tabview/tabview.js delete mode 100644 reports/site_media/yui/yahoo/README delete mode 100644 reports/site_media/yui/yahoo/yahoo-debug.js delete mode 100644 reports/site_media/yui/yahoo/yahoo-min.js delete mode 100644 reports/site_media/yui/yahoo/yahoo.js create mode 100644 src/lib/Server/Reports/reports/models.py.orig create mode 100644 src/lib/Server/Reports/reports/models.py.rej create mode 100644 src/lib/Server/Reports/reports/templates/404.html create mode 100644 src/lib/Server/Reports/reports/templates/base-timeview.html delete mode 100644 src/lib/Server/Reports/reports/templates/clients/client-nodebox.html create mode 100644 src/lib/Server/Reports/reports/templates/clients/history.html delete mode 100644 src/lib/Server/Reports/reports/templates/config_items/index.html create mode 100644 src/lib/Server/Reports/reports/templates/config_items/item.html delete mode 100644 src/lib/Server/Reports/reports/templates/displays/index.html delete mode 100644 src/lib/Server/Reports/reports/templates/displays/summary-block-direct-links.html delete mode 100644 src/lib/Server/Reports/reports/templates/displays/summary-block.html delete mode 100644 src/lib/Server/Reports/reports/templates/displays/sys_view.html delete mode 100644 src/lib/Server/Reports/reports/templates/index.html create mode 100644 src/lib/Server/Reports/reports/templates/widgets/filter_bar.html create mode 100644 src/lib/Server/Reports/reports/templates/widgets/interaction_list.inc create mode 100644 src/lib/Server/Reports/reports/templates/widgets/page_bar.html create mode 100644 src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py delete mode 100644 src/lib/Server/Reports/reports/templatetags/django_templating_sigh.py create mode 100644 src/lib/Server/Reports/reports/urls.py diff --git a/reports/site_media/AnchorPosition.js b/reports/site_media/AnchorPosition.js new file mode 100644 index 000000000..7db0cc89e --- /dev/null +++ b/reports/site_media/AnchorPosition.js @@ -0,0 +1,147 @@ +// =================================================================== +// Author: Matt Kruse +// WWW: http://www.mattkruse.com/ +// +// NOTICE: You may use this code for any purpose, commercial or +// private, without any further permission from the author. You may +// remove this notice from your final code if you wish, however it is +// appreciated by the author if at least my web site address is kept. +// +// You may *NOT* re-distribute this code in any way except through its +// use. That means, you can include it in your product, or your web +// site, or any other form where the code is actually being used. You +// may not put the plain javascript up on your site for download or +// include it in your javascript libraries for download. +// If you wish to share this code with others, please just point them +// to the URL instead. +// Please DO NOT link directly to my .js files from your site. Copy +// the files to your server and use them there. Thank you. +// =================================================================== + +/* +AnchorPosition.js +Author: Matt Kruse +Last modified: 10/11/02 + +DESCRIPTION: These functions find the position of an tag in a document, +so other elements can be positioned relative to it. + +COMPATABILITY: Netscape 4.x,6.x,Mozilla, IE 5.x,6.x on Windows. Some small +positioning errors - usually with Window positioning - occur on the +Macintosh platform. + +FUNCTIONS: +getAnchorPosition(anchorname) + Returns an Object() having .x and .y properties of the pixel coordinates + of the upper-left corner of the anchor. Position is relative to the PAGE. + +getAnchorWindowPosition(anchorname) + Returns an Object() having .x and .y properties of the pixel coordinates + of the upper-left corner of the anchor, relative to the WHOLE SCREEN. + +NOTES: + +1) For popping up separate browser windows, use getAnchorWindowPosition. + Otherwise, use getAnchorPosition + +2) Your anchor tag MUST contain both NAME and ID attributes which are the + same. For example: + + +3) There must be at least a space between for IE5.5 to see the + anchor tag correctly. Do not do with no space. +*/ + +// getAnchorPosition(anchorname) +// This function returns an object having .x and .y properties which are the coordinates +// of the named anchor, relative to the page. +function getAnchorPosition(anchorname) { + // This function will return an Object with x and y properties + var useWindow=false; + var coordinates=new Object(); + var x=0,y=0; + // Browser capability sniffing + var use_gebi=false, use_css=false, use_layers=false; + if (document.getElementById) { use_gebi=true; } + else if (document.all) { use_css=true; } + else if (document.layers) { use_layers=true; } + // Logic to find position + if (use_gebi && document.all) { + x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]); + y=AnchorPosition_getPageOffsetTop(document.all[anchorname]); + } + else if (use_gebi) { + var o=document.getElementById(anchorname); + x=AnchorPosition_getPageOffsetLeft(o); + y=AnchorPosition_getPageOffsetTop(o); + } + else if (use_css) { + x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]); + y=AnchorPosition_getPageOffsetTop(document.all[anchorname]); + } + else if (use_layers) { + var found=0; + for (var i=0; i9?"":"0")+x} -function isDate(val,format){var date=getDateFromFormat(val,format);if(date==0){return false;}return true;} -function compareDates(date1,dateformat1,date2,dateformat2){var d1=getDateFromFormat(date1,dateformat1);var d2=getDateFromFormat(date2,dateformat2);if(d1==0 || d2==0){return -1;}else if(d1 > d2){return 1;}return 0;} -function formatDate(date,format){format=format+"";var result="";var i_format=0;var c="";var token="";var y=date.getYear()+"";var M=date.getMonth()+1;var d=date.getDate();var E=date.getDay();var H=date.getHours();var m=date.getMinutes();var s=date.getSeconds();var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;var value=new Object();if(y.length < 4){y=""+(y-0+1900);}value["y"]=""+y;value["yyyy"]=y;value["yy"]=y.substring(2,4);value["M"]=M;value["MM"]=LZ(M);value["MMM"]=MONTH_NAMES[M-1];value["NNN"]=MONTH_NAMES[M+11];value["d"]=d;value["dd"]=LZ(d);value["E"]=DAY_NAMES[E+7];value["EE"]=DAY_NAMES[E];value["H"]=H;value["HH"]=LZ(H);if(H==0){value["h"]=12;}else if(H>12){value["h"]=H-12;}else{value["h"]=H;}value["hh"]=LZ(value["h"]);if(H>11){value["K"]=H-12;}else{value["K"]=H;}value["k"]=H+1;value["KK"]=LZ(value["K"]);value["kk"]=LZ(value["k"]);if(H > 11){value["a"]="PM";}else{value["a"]="AM";}value["m"]=m;value["mm"]=LZ(m);value["s"]=s;value["ss"]=LZ(s);while(i_format < format.length){c=format.charAt(i_format);token="";while((format.charAt(i_format)==c) &&(i_format < format.length)){token += format.charAt(i_format++);}if(value[token] != null){result=result + value[token];}else{result=result + token;}}return result;} -function _isInteger(val){var digits="1234567890";for(var i=0;i < val.length;i++){if(digits.indexOf(val.charAt(i))==-1){return false;}}return true;} -function _getInt(str,i,minlength,maxlength){for(var x=maxlength;x>=minlength;x--){var token=str.substring(i,i+x);if(token.length < minlength){return null;}if(_isInteger(token)){return token;}}return null;} -function getDateFromFormat(val,format){val=val+"";format=format+"";var i_val=0;var i_format=0;var c="";var token="";var token2="";var x,y;var now=new Date();var year=now.getYear();var month=now.getMonth()+1;var date=1;var hh=now.getHours();var mm=now.getMinutes();var ss=now.getSeconds();var ampm="";while(i_format < format.length){c=format.charAt(i_format);token="";while((format.charAt(i_format)==c) &&(i_format < format.length)){token += format.charAt(i_format++);}if(token=="yyyy" || token=="yy" || token=="y"){if(token=="yyyy"){x=4;y=4;}if(token=="yy"){x=2;y=2;}if(token=="y"){x=2;y=4;}year=_getInt(val,i_val,x,y);if(year==null){return 0;}i_val += year.length;if(year.length==2){if(year > 70){year=1900+(year-0);}else{year=2000+(year-0);}}}else if(token=="MMM"||token=="NNN"){month=0;for(var i=0;i11)){month=i+1;if(month>12){month -= 12;}i_val += month_name.length;break;}}}if((month < 1)||(month>12)){return 0;}}else if(token=="EE"||token=="E"){for(var i=0;i12)){return 0;}i_val+=month.length;}else if(token=="dd"||token=="d"){date=_getInt(val,i_val,token.length,2);if(date==null||(date<1)||(date>31)){return 0;}i_val+=date.length;}else if(token=="hh"||token=="h"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<1)||(hh>12)){return 0;}i_val+=hh.length;}else if(token=="HH"||token=="H"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<0)||(hh>23)){return 0;}i_val+=hh.length;}else if(token=="KK"||token=="K"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<0)||(hh>11)){return 0;}i_val+=hh.length;}else if(token=="kk"||token=="k"){hh=_getInt(val,i_val,token.length,2);if(hh==null||(hh<1)||(hh>24)){return 0;}i_val+=hh.length;hh--;}else if(token=="mm"||token=="m"){mm=_getInt(val,i_val,token.length,2);if(mm==null||(mm<0)||(mm>59)){return 0;}i_val+=mm.length;}else if(token=="ss"||token=="s"){ss=_getInt(val,i_val,token.length,2);if(ss==null||(ss<0)||(ss>59)){return 0;}i_val+=ss.length;}else if(token=="a"){if(val.substring(i_val,i_val+2).toLowerCase()=="am"){ampm="AM";}else if(val.substring(i_val,i_val+2).toLowerCase()=="pm"){ampm="PM";}else{return 0;}i_val+=2;}else{if(val.substring(i_val,i_val+token.length)!=token){return 0;}else{i_val+=token.length;}}}if(i_val != val.length){return 0;}if(month==2){if( ((year%4==0)&&(year%100 != 0) ) ||(year%400==0) ){if(date > 29){return 0;}}else{if(date > 28){return 0;}}}if((month==4)||(month==6)||(month==9)||(month==11)){if(date > 30){return 0;}}if(hh<12 && ampm=="PM"){hh=hh-0+12;}else if(hh>11 && ampm=="AM"){hh-=12;}var newdate=new Date(year,month-1,date,hh,mm,ss);return newdate.getTime();} -function parseDate(val){var preferEuro=(arguments.length==2)?arguments[1]:false;generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');var d=null;for(var i=0;i screen.availHeight){this.y = screen.availHeight - this.height;}}if(screen && screen.availWidth){if((this.x + this.width) > screen.availWidth){this.x = screen.availWidth - this.width;}}var avoidAboutBlank = window.opera ||( document.layers && !navigator.mimeTypes['*']) || navigator.vendor == 'KDE' ||( document.childNodes && !document.all && !navigator.taintEnabled);this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"");}this.refresh();}} -function PopupWindow_hidePopup(){if(this.divName != null){if(this.use_gebi){document.getElementById(this.divName).style.visibility = "hidden";}else if(this.use_css){document.all[this.divName].style.visibility = "hidden";}else if(this.use_layers){document.layers[this.divName].visibility = "hidden";}}else{if(this.popupWindow && !this.popupWindow.closed){this.popupWindow.close();this.popupWindow = null;}}} -function PopupWindow_isClicked(e){if(this.divName != null){if(this.use_layers){var clickX = e.pageX;var clickY = e.pageY;var t = document.layers[this.divName];if((clickX > t.left) &&(clickX < t.left+t.clip.width) &&(clickY > t.top) &&(clickY < t.top+t.clip.height)){return true;}else{return false;}}else if(document.all){var t = window.event.srcElement;while(t.parentElement != null){if(t.id==this.divName){return true;}t = t.parentElement;}return false;}else if(this.use_gebi && e){var t = e.originalTarget;while(t.parentNode != null){if(t.id==this.divName){return true;}t = t.parentNode;}return false;}return false;}return false;} -function PopupWindow_hideIfNotClicked(e){if(this.autoHideEnabled && !this.isClicked(e)){this.hidePopup();}} -function PopupWindow_autoHide(){this.autoHideEnabled = true;} -function PopupWindow_hidePopupWindows(e){for(var i=0;i0){this.type="DIV";this.divName = arguments[0];}else{this.type="WINDOW";}this.use_gebi = false;this.use_css = false;this.use_layers = false;if(document.getElementById){this.use_gebi = true;}else if(document.all){this.use_css = true;}else if(document.layers){this.use_layers = true;}else{this.type = "WINDOW";}this.offsetX = 0;this.offsetY = 0;this.getXYPosition = PopupWindow_getXYPosition;this.populate = PopupWindow_populate;this.setUrl = PopupWindow_setUrl;this.setWindowProperties = PopupWindow_setWindowProperties;this.refresh = PopupWindow_refresh;this.showPopup = PopupWindow_showPopup;this.hidePopup = PopupWindow_hidePopup;this.setSize = PopupWindow_setSize;this.isClicked = PopupWindow_isClicked;this.autoHide = PopupWindow_autoHide;this.hideIfNotClicked = PopupWindow_hideIfNotClicked;} - - -/* SOURCE FILE: CalendarPopup.js */ - -function CalendarPopup(){var c;if(arguments.length>0){c = new PopupWindow(arguments[0]);}else{c = new PopupWindow();c.setSize(150,175);}c.offsetX = -152;c.offsetY = 25;c.autoHide();c.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");c.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");c.dayHeaders = new Array("S","M","T","W","T","F","S");c.returnFunction = "CP_tmpReturnFunction";c.returnMonthFunction = "CP_tmpReturnMonthFunction";c.returnQuarterFunction = "CP_tmpReturnQuarterFunction";c.returnYearFunction = "CP_tmpReturnYearFunction";c.weekStartDay = 0;c.isShowYearNavigation = false;c.displayType = "date";c.disabledWeekDays = new Object();c.disabledDatesExpression = "";c.yearSelectStartOffset = 2;c.currentDate = null;c.todayText="Today";c.cssPrefix="";c.isShowNavigationDropdowns=false;c.isShowYearNavigationInput=false;window.CP_calendarObject = null;window.CP_targetInput = null;window.CP_dateFormat = "MM/dd/yyyy";c.copyMonthNamesToWindow = CP_copyMonthNamesToWindow;c.setReturnFunction = CP_setReturnFunction;c.setReturnMonthFunction = CP_setReturnMonthFunction;c.setReturnQuarterFunction = CP_setReturnQuarterFunction;c.setReturnYearFunction = CP_setReturnYearFunction;c.setMonthNames = CP_setMonthNames;c.setMonthAbbreviations = CP_setMonthAbbreviations;c.setDayHeaders = CP_setDayHeaders;c.setWeekStartDay = CP_setWeekStartDay;c.setDisplayType = CP_setDisplayType;c.setDisabledWeekDays = CP_setDisabledWeekDays;c.addDisabledDates = CP_addDisabledDates;c.setYearSelectStartOffset = CP_setYearSelectStartOffset;c.setTodayText = CP_setTodayText;c.showYearNavigation = CP_showYearNavigation;c.showCalendar = CP_showCalendar;c.hideCalendar = CP_hideCalendar;c.getStyles = getCalendarStyles;c.refreshCalendar = CP_refreshCalendar;c.getCalendar = CP_getCalendar;c.select = CP_select;c.setCssPrefix = CP_setCssPrefix;c.showNavigationDropdowns = CP_showNavigationDropdowns;c.showYearNavigationInput = CP_showYearNavigationInput;c.copyMonthNamesToWindow();return c;} -function CP_copyMonthNamesToWindow(){if(typeof(window.MONTH_NAMES)!="undefined" && window.MONTH_NAMES!=null){window.MONTH_NAMES = new Array();for(var i=0;i\n";result += '
\n';}else{result += '
\n';result += '
\n';result += '
\n';}if(this.displayType=="date" || this.displayType=="week-end"){if(this.currentDate==null){this.currentDate = now;}if(arguments.length > 0){var month = arguments[0];}else{var month = this.currentDate.getMonth()+1;}if(arguments.length > 1 && arguments[1]>0 && arguments[1]-0==arguments[1]){var year = arguments[1];}else{var year = this.currentDate.getFullYear();}var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);if( ((year%4 == 0)&&(year%100 != 0) ) ||(year%400 == 0) ){daysinmonth[2] = 29;}var current_month = new Date(year,month-1,1);var display_year = year;var display_month = month;var display_date = 1;var weekday= current_month.getDay();var offset = 0;offset =(weekday >= this.weekStartDay) ? weekday-this.weekStartDay : 7-this.weekStartDay+weekday ;if(offset > 0){display_month--;if(display_month < 1){display_month = 12;display_year--;}display_date = daysinmonth[display_month]-offset+1;}var next_month = month+1;var next_month_year = year;if(next_month > 12){next_month=1;next_month_year++;}var last_month = month-1;var last_month_year = year;if(last_month < 1){last_month=12;last_month_year--;}var date_class;if(this.type!="WINDOW"){result += "";}result += '\n';var refresh = windowref+'CP_refreshCalendar';var refreshLink = 'javascript:' + refresh;if(this.isShowNavigationDropdowns){result += '';result += '';result += '';}else{if(this.isShowYearNavigation){result += '';result += '';result += '';result += '';result += '';if(this.isShowYearNavigationInput){result += '';}else{result += '';}result += '';}else{result += '\n';result += '\n';result += '\n';}}result += '
 <'+this.monthNames[month-1]+'> <'+year+'><<'+this.monthNames[month-1]+' '+year+'>>
\n';result += '\n';result += '\n';for(var j=0;j<7;j++){result += '\n';}result += '\n';for(var row=1;row<=6;row++){result += '\n';for(var col=1;col<=7;col++){var disabled=false;if(this.disabledDatesExpression!=""){var ds=""+display_year+LZ(display_month)+LZ(display_date);eval("disabled=("+this.disabledDatesExpression+")");}var dateClass = "";if((display_month == this.currentDate.getMonth()+1) &&(display_date==this.currentDate.getDate()) &&(display_year==this.currentDate.getFullYear())){dateClass = "cpCurrentDate";}else if(display_month == month){dateClass = "cpCurrentMonthDate";}else{dateClass = "cpOtherMonthDate";}if(disabled || this.disabledWeekDays[col-1]){result += ' \n';}else{var selected_date = display_date;var selected_month = display_month;var selected_year = display_year;if(this.displayType=="week-end"){var d = new Date(selected_year,selected_month-1,selected_date,0,0,0,0);d.setDate(d.getDate() +(7-col));selected_year = d.getYear();if(selected_year < 1000){selected_year += 1900;}selected_month = d.getMonth()+1;selected_date = d.getDate();}result += ' \n';}display_date++;if(display_date > daysinmonth[display_month]){display_date=1;display_month++;}if(display_month > 12){display_month=1;display_year++;}}result += '';}var current_weekday = now.getDay() - this.weekStartDay;if(current_weekday < 0){current_weekday += 7;}result += '\n';result += '
'+this.dayHeaders[(this.weekStartDay+j)%7]+'
'+display_date+''+display_date+'
\n';if(this.disabledDatesExpression!=""){var ds=""+now.getFullYear()+LZ(now.getMonth()+1)+LZ(now.getDate());eval("disabled=("+this.disabledDatesExpression+")");}if(disabled || this.disabledWeekDays[current_weekday+1]){result += ' '+this.todayText+'\n';}else{result += ' '+this.todayText+'\n';}result += '
\n';result += '
\n';}if(this.displayType=="month" || this.displayType=="quarter" || this.displayType=="year"){if(arguments.length > 0){var year = arguments[0];}else{if(this.displayType=="year"){var year = now.getFullYear()-this.yearSelectStartOffset;}else{var year = now.getFullYear();}}if(this.displayType!="year" && this.isShowYearNavigation){result += "";result += '\n';result += ' \n';result += ' \n';result += ' \n';result += '
<<'+year+'>>
\n';}}if(this.displayType=="month"){result += '\n';for(var i=0;i<4;i++){result += '';for(var j=0;j<3;j++){var monthindex =((i*3)+j);result += '';}result += '';}result += '
'+this.monthAbbreviations[monthindex]+'
\n';}if(this.displayType=="quarter"){result += '
\n';for(var i=0;i<2;i++){result += '';for(var j=0;j<2;j++){var quarter =((i*2)+j+1);result += '';}result += '';}result += '

Q'+quarter+'

\n';}if(this.displayType=="year"){var yearColumnSize = 4;result += "";result += '\n';result += ' \n';result += ' \n';result += '
<<>>
\n';result += '\n';for(var i=0;i'+currentyear+'';}result += '';}result += '
\n';}if(this.type == "WINDOW"){result += "\n";}return result;} +// HISTORY +// ------------------------------------------------------------------ +// Feb 7, 2005: Fixed a CSS styles to use px unit +// March 29, 2004: Added check in select() method for the form field +// being disabled. If it is, just return and don't do anything. +// March 24, 2004: Fixed bug - when month name and abbreviations were +// changed, date format still used original values. +// January 26, 2004: Added support for drop-down month and year +// navigation (Thanks to Chris Reid for the idea) +// September 22, 2003: Fixed a minor problem in YEAR calendar with +// CSS prefix. +// August 19, 2003: Renamed the function to get styles, and made it +// work correctly without an object reference +// August 18, 2003: Changed showYearNavigation and +// showYearNavigationInput to optionally take an argument of +// true or false +// July 31, 2003: Added text input option for year navigation. +// Added a per-calendar CSS prefix option to optionally use +// different styles for different calendars. +// July 29, 2003: Fixed bug causing the Today link to be clickable +// even though today falls in a disabled date range. +// Changed formatting to use pure CSS, allowing greater control +// over look-and-feel options. +// June 11, 2003: Fixed bug causing the Today link to be unselectable +// under certain cases when some days of week are disabled +// March 14, 2003: Added ability to disable individual dates or date +// ranges, display as light gray and strike-through +// March 14, 2003: Removed dependency on graypixel.gif and instead +/// use table border coloring +// March 12, 2003: Modified showCalendar() function to allow optional +// start-date parameter +// March 11, 2003: Modified select() function to allow optional +// start-date parameter +/* +DESCRIPTION: This object implements a popup calendar to allow the user to +select a date, month, quarter, or year. +COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small +positioning errors - usually with Window positioning - occur on the +Macintosh platform. +The calendar can be modified to work for any location in the world by +changing which weekday is displayed as the first column, changing the month +names, and changing the column headers for each day. + +USAGE: +// Create a new CalendarPopup object of type WINDOW +var cal = new CalendarPopup(); + +// Create a new CalendarPopup object of type DIV using the DIV named 'mydiv' +var cal = new CalendarPopup('mydiv'); + +// Easy method to link the popup calendar with an input box. +cal.select(inputObject, anchorname, dateFormat); +// Same method, but passing a default date other than the field's current value +cal.select(inputObject, anchorname, dateFormat, '01/02/2000'); +// This is an example call to the popup calendar from a link to populate an +// input box. Note that to use this, date.js must also be included!! +Select + +// Set the type of date select to be used. By default it is 'date'. +cal.setDisplayType(type); + +// When a date, month, quarter, or year is clicked, a function is called and +// passed the details. You must write this function, and tell the calendar +// popup what the function name is. +// Function to be called for 'date' select receives y, m, d +cal.setReturnFunction(functionname); +// Function to be called for 'month' select receives y, m +cal.setReturnMonthFunction(functionname); +// Function to be called for 'quarter' select receives y, q +cal.setReturnQuarterFunction(functionname); +// Function to be called for 'year' select receives y +cal.setReturnYearFunction(functionname); + +// Show the calendar relative to a given anchor +cal.showCalendar(anchorname); + +// Hide the calendar. The calendar is set to autoHide automatically +cal.hideCalendar(); + +// Set the month names to be used. Default are English month names +cal.setMonthNames("January","February","March",...); + +// Set the month abbreviations to be used. Default are English month abbreviations +cal.setMonthAbbreviations("Jan","Feb","Mar",...); + +// Show navigation for changing by the year, not just one month at a time +cal.showYearNavigation(); + +// Show month and year dropdowns, for quicker selection of month of dates +cal.showNavigationDropdowns(); + +// Set the text to be used above each day column. The days start with +// sunday regardless of the value of WeekStartDay +cal.setDayHeaders("S","M","T",...); + +// Set the day for the first column in the calendar grid. By default this +// is Sunday (0) but it may be changed to fit the conventions of other +// countries. +cal.setWeekStartDay(1); // week is Monday - Sunday + +// Set the weekdays which should be disabled in the 'date' select popup. You can +// then allow someone to only select week end dates, or Tuedays, for example +cal.setDisabledWeekDays(0,1); // To disable selecting the 1st or 2nd days of the week + +// Selectively disable individual days or date ranges. Disabled days will not +// be clickable, and show as strike-through text on current browsers. +// Date format is any format recognized by parseDate() in date.js +// Pass a single date to disable: +cal.addDisabledDates("2003-01-01"); +// Pass null as the first parameter to mean "anything up to and including" the +// passed date: +cal.addDisabledDates(null, "01/02/03"); +// Pass null as the second parameter to mean "including the passed date and +// anything after it: +cal.addDisabledDates("Jan 01, 2003", null); +// Pass two dates to disable all dates inbetween and including the two +cal.addDisabledDates("January 01, 2003", "Dec 31, 2003"); + +// When the 'year' select is displayed, set the number of years back from the +// current year to start listing years. Default is 2. +// This is also used for year drop-down, to decide how many years +/- to display +cal.setYearSelectStartOffset(2); + +// Text for the word "Today" appearing on the calendar +cal.setTodayText("Today"); + +// The calendar uses CSS classes for formatting. If you want your calendar to +// have unique styles, you can set the prefix that will be added to all the +// classes in the output. +// For example, normal output may have this: +// Today +// But if you set the prefix like this: +cal.setCssPrefix("Test"); +// The output will then look like: +// Today +// And you can define that style somewhere in your page. + +// When using Year navigation, you can make the year be an input box, so +// the user can manually change it and jump to any year +cal.showYearNavigationInput(); + +// Set the calendar offset to be different than the default. By default it +// will appear just below and to the right of the anchorname. So if you have +// a text box where the date will go and and anchor immediately after the +// text box, the calendar will display immediately under the text box. +cal.offsetX = 20; +cal.offsetY = 20; + +NOTES: +1) Requires the functions in AnchorPosition.js and PopupWindow.js + +2) Your anchor tag MUST contain both NAME and ID attributes which are the + same. For example: + + +3) There must be at least a space between for IE5.5 to see the + anchor tag correctly. Do not do with no space. + +4) When a CalendarPopup object is created, a handler for 'onmouseup' is + attached to any event handler you may have already defined. Do NOT define + an event handler for 'onmouseup' after you define a CalendarPopup object + or the autoHide() will not work correctly. + +5) The calendar popup display uses style sheets to make it look nice. + +*/ + +// CONSTRUCTOR for the CalendarPopup Object +function CalendarPopup() { + var c; + if (arguments.length>0) { + c = new PopupWindow(arguments[0]); + } + else { + c = new PopupWindow(); + c.setSize(150,175); + } + c.offsetX = -152; + c.offsetY = 25; + c.autoHide(); + // Calendar-specific properties + c.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December"); + c.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); + c.dayHeaders = new Array("S","M","T","W","T","F","S"); + c.returnFunction = "CP_tmpReturnFunction"; + c.returnMonthFunction = "CP_tmpReturnMonthFunction"; + c.returnQuarterFunction = "CP_tmpReturnQuarterFunction"; + c.returnYearFunction = "CP_tmpReturnYearFunction"; + c.weekStartDay = 0; + c.isShowYearNavigation = false; + c.displayType = "date"; + c.disabledWeekDays = new Object(); + c.disabledDatesExpression = ""; + c.yearSelectStartOffset = 2; + c.currentDate = null; + c.todayText="Today"; + c.cssPrefix=""; + c.isShowNavigationDropdowns=false; + c.isShowYearNavigationInput=false; + window.CP_calendarObject = null; + window.CP_targetInput = null; + window.CP_dateFormat = "MM/dd/yyyy"; + // Method mappings + c.copyMonthNamesToWindow = CP_copyMonthNamesToWindow; + c.setReturnFunction = CP_setReturnFunction; + c.setReturnMonthFunction = CP_setReturnMonthFunction; + c.setReturnQuarterFunction = CP_setReturnQuarterFunction; + c.setReturnYearFunction = CP_setReturnYearFunction; + c.setMonthNames = CP_setMonthNames; + c.setMonthAbbreviations = CP_setMonthAbbreviations; + c.setDayHeaders = CP_setDayHeaders; + c.setWeekStartDay = CP_setWeekStartDay; + c.setDisplayType = CP_setDisplayType; + c.setDisabledWeekDays = CP_setDisabledWeekDays; + c.addDisabledDates = CP_addDisabledDates; + c.setYearSelectStartOffset = CP_setYearSelectStartOffset; + c.setTodayText = CP_setTodayText; + c.showYearNavigation = CP_showYearNavigation; + c.showCalendar = CP_showCalendar; + c.hideCalendar = CP_hideCalendar; + c.getStyles = getCalendarStyles; + c.refreshCalendar = CP_refreshCalendar; + c.getCalendar = CP_getCalendar; + c.select = CP_select; + c.setCssPrefix = CP_setCssPrefix; + c.showNavigationDropdowns = CP_showNavigationDropdowns; + c.showYearNavigationInput = CP_showYearNavigationInput; + c.copyMonthNamesToWindow(); + // Return the object + return c; + } +function CP_copyMonthNamesToWindow() { + // Copy these values over to the date.js + if (typeof(window.MONTH_NAMES)!="undefined" && window.MONTH_NAMES!=null) { + window.MONTH_NAMES = new Array(); + for (var i=0; i\n"; + result += '
\n'; + } + else { + result += '
\n'; + result += '
\n'; + result += '
\n'; + } + // Code for DATE display (default) + // ------------------------------- + if (this.displayType=="date" || this.displayType=="week-end") { + if (this.currentDate==null) { this.currentDate = now; } + if (arguments.length > 0) { var month = arguments[0]; } + else { var month = this.currentDate.getMonth()+1; } + if (arguments.length > 1 && arguments[1]>0 && arguments[1]-0==arguments[1]) { var year = arguments[1]; } + else { var year = this.currentDate.getFullYear(); } + var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31); + if ( ( (year%4 == 0)&&(year%100 != 0) ) || (year%400 == 0) ) { + daysinmonth[2] = 29; + } + var current_month = new Date(year,month-1,1); + var display_year = year; + var display_month = month; + var display_date = 1; + var weekday= current_month.getDay(); + var offset = 0; + + offset = (weekday >= this.weekStartDay) ? weekday-this.weekStartDay : 7-this.weekStartDay+weekday ; + if (offset > 0) { + display_month--; + if (display_month < 1) { display_month = 12; display_year--; } + display_date = daysinmonth[display_month]-offset+1; + } + var next_month = month+1; + var next_month_year = year; + if (next_month > 12) { next_month=1; next_month_year++; } + var last_month = month-1; + var last_month_year = year; + if (last_month < 1) { last_month=12; last_month_year--; } + var date_class; + if (this.type!="WINDOW") { + result += ""; + } + result += '\n'; + var refresh = windowref+'CP_refreshCalendar'; + var refreshLink = 'javascript:' + refresh; + if (this.isShowNavigationDropdowns) { + result += ''; + result += ''; + + result += ''; + } + else { + if (this.isShowYearNavigation) { + result += ''; + result += ''; + result += ''; + result += ''; + + result += ''; + if (this.isShowYearNavigationInput) { + result += ''; + } + else { + result += ''; + } + result += ''; + } + else { + result += '\n'; + result += '\n'; + result += '\n'; + } + } + result += '
 <'+this.monthNames[month-1]+'> <'+year+'><<'+this.monthNames[month-1]+' '+year+'>>
\n'; + result += '\n'; + result += '\n'; + for (var j=0; j<7; j++) { + + result += '\n'; + } + result += '\n'; + for (var row=1; row<=6; row++) { + result += '\n'; + for (var col=1; col<=7; col++) { + var disabled=false; + if (this.disabledDatesExpression!="") { + var ds=""+display_year+LZ(display_month)+LZ(display_date); + eval("disabled=("+this.disabledDatesExpression+")"); + } + var dateClass = ""; + if ((display_month == this.currentDate.getMonth()+1) && (display_date==this.currentDate.getDate()) && (display_year==this.currentDate.getFullYear())) { + dateClass = "cpCurrentDate"; + } + else if (display_month == month) { + dateClass = "cpCurrentMonthDate"; + } + else { + dateClass = "cpOtherMonthDate"; + } + if (disabled || this.disabledWeekDays[col-1]) { + result += ' \n'; + } + else { + var selected_date = display_date; + var selected_month = display_month; + var selected_year = display_year; + if (this.displayType=="week-end") { + var d = new Date(selected_year,selected_month-1,selected_date,0,0,0,0); + d.setDate(d.getDate() + (7-col)); + selected_year = d.getYear(); + if (selected_year < 1000) { selected_year += 1900; } + selected_month = d.getMonth()+1; + selected_date = d.getDate(); + } + result += ' \n'; + } + display_date++; + if (display_date > daysinmonth[display_month]) { + display_date=1; + display_month++; + } + if (display_month > 12) { + display_month=1; + display_year++; + } + } + result += ''; + } + var current_weekday = now.getDay() - this.weekStartDay; + if (current_weekday < 0) { + current_weekday += 7; + } + result += '\n'; + result += '
'+this.dayHeaders[(this.weekStartDay+j)%7]+'
'+display_date+''+display_date+'
\n'; + if (this.disabledDatesExpression!="") { + var ds=""+now.getFullYear()+LZ(now.getMonth()+1)+LZ(now.getDate()); + eval("disabled=("+this.disabledDatesExpression+")"); + } + if (disabled || this.disabledWeekDays[current_weekday+1]) { + result += ' '+this.todayText+'\n'; + } + else { + result += ' '+this.todayText+'\n'; + } + result += '
\n'; + result += '
\n'; + } + + // Code common for MONTH, QUARTER, YEAR + // ------------------------------------ + if (this.displayType=="month" || this.displayType=="quarter" || this.displayType=="year") { + if (arguments.length > 0) { var year = arguments[0]; } + else { + if (this.displayType=="year") { var year = now.getFullYear()-this.yearSelectStartOffset; } + else { var year = now.getFullYear(); } + } + if (this.displayType!="year" && this.isShowYearNavigation) { + result += ""; + result += '\n'; + result += ' \n'; + result += ' \n'; + result += ' \n'; + result += '
<<'+year+'>>
\n'; + } + } + + // Code for MONTH display + // ---------------------- + if (this.displayType=="month") { + // If POPUP, write entire HTML document + result += '\n'; + for (var i=0; i<4; i++) { + result += ''; + for (var j=0; j<3; j++) { + var monthindex = ((i*3)+j); + result += ''; + } + result += ''; + } + result += '
'+this.monthAbbreviations[monthindex]+'
\n'; + } + + // Code for QUARTER display + // ------------------------ + if (this.displayType=="quarter") { + result += '
\n'; + for (var i=0; i<2; i++) { + result += ''; + for (var j=0; j<2; j++) { + var quarter = ((i*2)+j+1); + result += ''; + } + result += ''; + } + result += '

Q'+quarter+'

\n'; + } + + // Code for YEAR display + // --------------------- + if (this.displayType=="year") { + var yearColumnSize = 4; + result += ""; + result += '\n'; + result += ' \n'; + result += ' \n'; + result += '
<<>>
\n'; + result += '\n'; + for (var i=0; i'+currentyear+''; + } + result += ''; + } + result += '
\n'; + } + // Common + if (this.type == "WINDOW") { + result += "\n"; + } + return result; + } diff --git a/reports/site_media/PopupWindow.js b/reports/site_media/PopupWindow.js new file mode 100644 index 000000000..5a5823590 --- /dev/null +++ b/reports/site_media/PopupWindow.js @@ -0,0 +1,336 @@ +// =================================================================== +// Author: Matt Kruse +// WWW: http://www.mattkruse.com/ +// +// NOTICE: You may use this code for any purpose, commercial or +// private, without any further permission from the author. You may +// remove this notice from your final code if you wish, however it is +// appreciated by the author if at least my web site address is kept. +// +// You may *NOT* re-distribute this code in any way except through its +// use. That means, you can include it in your product, or your web +// site, or any other form where the code is actually being used. You +// may not put the plain javascript up on your site for download or +// include it in your javascript libraries for download. +// If you wish to share this code with others, please just point them +// to the URL instead. +// Please DO NOT link directly to my .js files from your site. Copy +// the files to your server and use them there. Thank you. +// =================================================================== + +/* +PopupWindow.js +Author: Matt Kruse +Last modified: 02/16/04 + +DESCRIPTION: This object allows you to easily and quickly popup a window +in a certain place. The window can either be a DIV or a separate browser +window. + +COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small +positioning errors - usually with Window positioning - occur on the +Macintosh platform. Due to bugs in Netscape 4.x, populating the popup +window with +{% endblock %} + +{% block body_onload %}javascript:clientdetailload(){% endblock %} + +{% block pagebanner %}Client Details{% endblock %} {% block content %} -

Client Status Detail page for {{client.name}}


-Select time: - + + {% for i in client.interactions.all|slice:":25" %} + + {% endfor %} +
+ + + {% if interaction.isstale %} +
+ This node did not run within the last 24 hours — it may be out of date. +
+ {% endif %} + + + {% if interaction.server %} + + {% endif %} + {% if interaction.repo_rev_code %} + + {% endif %} + + + {% if not interaction.isclean %} + + {% endif %} +
Timestamp{{interaction.timestamp}}
Served by{{interaction.server}}
Revision{{interaction.repo_rev_code}}
State{{interaction.state|capfirst}}
Managed entries{{interaction.totalcount}}
Deviation{{interaction.percentbad|floatformat:"3"}}%
+ + {% if interaction.bad_entry_count %} +
+
+
[+]
+

Bad Entries — {{ interaction.bad_entry_count }}

+
+ + {% for e in interaction.bad|sortwell %} + + + + + {% endfor %} +
{{e.entry.kind}}: + {{e.entry.name}}
+
+ {% endif %} + + {% if interaction.modified_entry_count %} +
+
+
[+]
+

Modified Entries — {{ interaction.modified_entry_count }}

+
+ + {% for e in interaction.modified|sortwell %} + + + + + {% endfor %} +
{{e.entry.kind}}: + {{e.entry.name}}
+
+ {% endif %} + + {% if interaction.extra_entry_count %} +
+
+
[+]
+

Extra Entries — {{ interaction.extra_entry_count }}

+
+ + {% for e in interaction.extra|sortwell %} + + + + {% endfor %} - -         -Manage {{client.name}} options.
+
{{e.entry.kind}}:{{e.entry.name}}
+
+ {% endif %} -{% include "clients/client-nodebox.html" %} + {% if entry_list %} +
+
+

Recent Interactions

+
+
+ {% include "widgets/interaction_list.inc" %} + +
+
+ {% endif %} {% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/clients/detailed-list.html b/src/lib/Server/Reports/reports/templates/clients/detailed-list.html index 5a1352cff..0c1fae8d5 100644 --- a/src/lib/Server/Reports/reports/templates/clients/detailed-list.html +++ b/src/lib/Server/Reports/reports/templates/clients/detailed-list.html @@ -1,57 +1,15 @@ -{% extends "base.html" %} +{% extends "base-timeview.html" %} +{% load bcfg2_tags %} -{% block title %}Detailed Client Listing{% endblock %} - -{% block extra_header_info %} - - - -{% endblock%} - -{% block pagebanner %} -
-

Detailed Client List

-
-
-{% endblock %} +{% block title %}Bcfg2 - Detailed Client Listing{% endblock %} +{% block pagebanner %}Clients - Detailed View{% endblock %} {% block content %} -
-
- -Enter date or use calendar popup: -@ - -Calendar - - | -

-
-
- -
+
{% if entry_list %} + {% filter_navigator %} - + @@ -61,30 +19,19 @@ - {% for client,entry,stale in entry_list %} + {% for entry in entry_list %} - - + + - +
Node State GoodLast Run Server
{{ client }}{{ entry.state }}{{ entry.client.name }}{{ entry.state }} {{ entry.goodcount }} {{ entry.bad_entry_count }} {{ entry.modified_entry_count }} {{ entry.extra_entry_count }}{{ entry.timestamp|date:"Y-m-d H:i" }}{{ entry.timestamp|date:"Y-m-d\&\n\b\s\p\;H:i"|safe }} {% if entry.server %} - {{ entry.server }} + {{ entry.server }} {% else %}   {% endif %} diff --git a/src/lib/Server/Reports/reports/templates/clients/history.html b/src/lib/Server/Reports/reports/templates/clients/history.html new file mode 100644 index 000000000..01d4ec2f4 --- /dev/null +++ b/src/lib/Server/Reports/reports/templates/clients/history.html @@ -0,0 +1,20 @@ +{% extends "base.html" %} +{% load bcfg2_tags %} + +{% block title %}Bcfg2 - Interaction History{% endblock %} +{% block pagebanner %}Interaction history{% if client %} for {{ client.name }}{% endif %}{% endblock %} + +{% block extra_header_info %} +{% endblock %} + +{% block content %} +
+{% if entry_list %} + {% filter_navigator %} + {% include "widgets/interaction_list.inc" %} +{% else %} +

No client records are available.

+{% endif %} +
+{% page_navigator %} +{% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/clients/index.html b/src/lib/Server/Reports/reports/templates/clients/index.html index cfb8a6c83..e0c0d2d7a 100644 --- a/src/lib/Server/Reports/reports/templates/clients/index.html +++ b/src/lib/Server/Reports/reports/templates/clients/index.html @@ -1,56 +1,33 @@ -{% extends "base.html" %} +{% extends "base-timeview.html" %} {% block extra_header_info %} - - - {% endblock%} -{% block title %}Client Index Listing{% endblock %} +{% block title %}Bcfg2 - Client Grid View{% endblock %} -{% block pagebanner %} -
-

Clients List

-
-
-{% endblock %} +{% block pagebanner %}Clients - Grid View{% endblock %} {% block content %} -
- -Enter date or use calendar popup: - -
- -@ - -Calendar - - | -
-


{% if inter_list %} - + {% if forloop.last %} + {% else %} - {% url Bcfg2.Server.Reports.reports.views.client_detail client,inter.id %} - {% endifequal %} - {% endspaceless %}">{{ client }} - - {% ifequal half_list forloop.counter0 %} - -{% endif %} + {% endif %} {% endfor %} - -
-
-
    - {% endifequal %} + {% if forloop.counter|divisibleby:"4" %}
+
{% else %}

No client records are available.

{% endif %} diff --git a/src/lib/Server/Reports/reports/templates/clients/manage.html b/src/lib/Server/Reports/reports/templates/clients/manage.html index 61f0fe017..5725ae577 100644 --- a/src/lib/Server/Reports/reports/templates/clients/manage.html +++ b/src/lib/Server/Reports/reports/templates/clients/manage.html @@ -1,29 +1,45 @@ {% extends "base.html" %} + {% block extra_header_info %} - - {% endblock%} -{% block title %}{{client.name}}{% endblock %} -{% block content %} -

Client Options Management page for {{client.name}}


-

Client status detail page: {{client.name}}.

-

Hosts may be prevented from showing up in the reporting system if they have been retired, are no longer managed by bcfg2 :(, etc.

-Select deactivation date: -
- -Enter date or use calendar popup: - -
- -@ - -Calendar - -
-


-

-

{{message}}

+{% block title %}Bcfg2 - Manage Clients{% endblock %} +{% block pagebanner %}Clients - Manage{% endblock %} + +{% block content %} +
+ {% if message %} +
{{ message }}
+ {% endif %} +{% if clients %} + + + + + + + {% for client in clients %} + + + + + + {% endfor %} +
NodeExpirationManage
+ + + {{ client.name }}{% firstof client.expiration 'Active' %} +
+
{# here for no reason other then to validate #} + + + +
+
+
+
+{% else %} +

No client records are available.

+{% endif %} {% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/config_items/index.html b/src/lib/Server/Reports/reports/templates/config_items/index.html deleted file mode 100644 index 04083344c..000000000 --- a/src/lib/Server/Reports/reports/templates/config_items/index.html +++ /dev/null @@ -1,100 +0,0 @@ -{% extends "base.html" %} - -{% load syntax_coloring %} - -{% block extra_header_info %} - - - -{% endblock%} -{% block title %}Configuration Element Details{% endblock %} - -{% block pagebanner %} -
-

Configuration Element Details

-
-
-{% endblock %} - -{% block content %} - -{% ifequal mod_or_bad "bad" %} -
-

Bad {{item.entry.kind}}: {{item.entry.name}}

-
-{% else %} -
-

Modified {{item.entry.kind}}: {{item.entry.name}}

-
-{% endifequal %} -
- - -{% if item.reason.current_owner %} - -{% endif %}{% if item.reason.current_group %} - -{% endif %}{% if item.reason.current_perms %} - -{% endif %}{% if item.reason.current_status %} - -{% endif %}{% if item.reason.current_to %} - -{% endif %}{% if item.reason.current_version %} - -{% endif %}{% if not item.reason.current_exists %} - -{% endif %}{% if item.reason.current_diff %} - -{% endif %} -
ReasonCurrent StatusSpecified in bcfg2
Owner: {{item.reason.current_owner}}{{item.reason.owner}}
Group: {{item.reason.current_group}}{{item.reason.group}}
Permissions: {{item.reason.current_perms}}{{item.reason.perms}}
Status: {{item.reason.current_status}}{{item.reason.status}}
Link Destination: {{item.reason.current_to}}{{item.reason.to}}
Version: {{item.reason.current_version}}{{item.reason.version}}
Existence: This item does not currently exist on the host but is specified to exist in the configuration.
NDiff:
{{item.reason.current_diff|syntaxhilight:"diff"}}
-
-
- -Enter date or use calendar popup: - -
- -@ - -Calendar -{% ifequal mod_or_bad "modified" %} - - | -{% else %} - - | -{% endifequal %} -
-


-{% if associated_client_list %} -

The following clients had this problem as of {{timestamp_date}}@{{timestamp_time}}:

- {% for client in associated_client_list %} - {{client.name}}
- {% endfor %} -
-
-{% else %} -

No Clients had this problem at {{timestamp}}

-{% endif %} - - - - - - - -{% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/config_items/item.html b/src/lib/Server/Reports/reports/templates/config_items/item.html new file mode 100644 index 000000000..41474922b --- /dev/null +++ b/src/lib/Server/Reports/reports/templates/config_items/item.html @@ -0,0 +1,109 @@ +{% extends "base.html" %} +{% load syntax_coloring %} + + +{% block title %}Bcfg2 - Element Details{% endblock %} + + +{% block extra_header_info %} + +{% endblock%} + +{% block pagebanner %}Element Details{% endblock %} + +{% block content %} +
+

{{mod_or_bad|capfirst}} {{item.entry.kind}}: {{item.entry.name}}

+
+ +
+ + {% if isextra %} +

This item exists on the host but is not defined in the configuration.

+ {% endif %} + + {% if not item.reason.current_exists %} +
This item does not currently exist on the host but is specified to exist in the configuration.
+ {% endif %} + + {% if item.reason.current_owner or item.reason.current_group or item.reason.current_perms or item.reason.current_status or item.reason.current_status or item.reason.current_to or item.reason.current_version %} + + + + {% if item.reason.current_owner %} + + + {% endif %} + {% if item.reason.current_group %} + + + {% endif %} + {% if item.reason.current_perms %} + + + {% endif %} + {% if item.reason.current_status %} + + + {% endif %} + {% if item.reason.current_to %} + + + {% endif %} + {% if item.reason.current_version %} + + + {% endif %} +
Problem TypeExpectedFound
Owner{{item.reason.owner}}{{item.reason.current_owner}}
Group{{item.reason.group}}{{item.reason.current_group}}
Permissions{{item.reason.perms}}{{item.reason.current_perms}}
Status{{item.reason.status}}{{item.reason.current_status}}
Symlink Target{{item.reason.to}}{{item.reason.current_to}}
Package Version{{item.reason.version|cut:"("|cut:")"}}{{item.reason.current_version|cut:"("|cut:")"}}
+ {% endif %} + + {% if item.reason.current_diff %} +
+
+

Incorrect file contents

+
+
+ {{ item.reason.current_diff|syntaxhilight }} +
+
+ {% endif %} + + +
+
+

Occurances on {{ timestamp|date:"Y-m-d" }}

+
+ {% if associated_list %} + + {% for inter in associated_list %} + + + + {% endfor %} +
{{inter.client.name}}{{inter.timestamp}}
+ {% else %} +

Missing client list

+ {% endif %} +
+ +
+{% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/config_items/listing.html b/src/lib/Server/Reports/reports/templates/config_items/listing.html index 64a60e506..572249470 100644 --- a/src/lib/Server/Reports/reports/templates/config_items/listing.html +++ b/src/lib/Server/Reports/reports/templates/config_items/listing.html @@ -1,50 +1,32 @@ -{% extends "base.html" %} -{% load django_templating_sigh %} +{% extends "base-timeview.html" %} +{% load bcfg2_tags %} -{% block extra_header_info %} - - - - - - - - - -{% endblock %} +{% block pagebanner %}{{mod_or_bad|capfirst}} Element Listing{% endblock %} -{% block title %}{{mod_or_bad|capfirst}} Item Listing{% endblock %} +{% block content %} +{% if item_list_dict %} + {% for kind, entries in item_list_dict.items %} -{% block pagebanner %} -
-

{{mod_or_bad|capfirst}} Configuration Elements

+
+
+
[+]
+

{{ kind }} — {{ entries|length }}

-
-{% endblock %} -{% block content %} -{% if item_list_pseudodict %} -
+ + {% for e in entries %} + + + + {% endfor %} +
{{e.entry.name}}
+
+ {% endfor %} {% else %}

There are currently no inconsistent configuration entries.

{% endif %} diff --git a/src/lib/Server/Reports/reports/templates/displays/index.html b/src/lib/Server/Reports/reports/templates/displays/index.html deleted file mode 100644 index c078539b6..000000000 --- a/src/lib/Server/Reports/reports/templates/displays/index.html +++ /dev/null @@ -1,18 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Display Index Listing{% endblock %} -{% block pagebanner %} -
-

BCFG Display Index

- {% comment %} Report Run @ {% now "F j, Y P"%}{% endcomment %} -
-
-{% endblock %} - -{% block content %} - -{% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/displays/summary-block-direct-links.html b/src/lib/Server/Reports/reports/templates/displays/summary-block-direct-links.html deleted file mode 100644 index 60f97eadc..000000000 --- a/src/lib/Server/Reports/reports/templates/displays/summary-block-direct-links.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "displays/summary-block.html" %} -{% block linkprefix1 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} -{% block linkprefix2 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} -{% block linkprefix3 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} -{% block linkprefix4 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} -{% block linkprefix5 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} -{% block linkprefix6 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} \ No newline at end of file diff --git a/src/lib/Server/Reports/reports/templates/displays/summary-block.html b/src/lib/Server/Reports/reports/templates/displays/summary-block.html deleted file mode 100644 index 060ff0fa1..000000000 --- a/src/lib/Server/Reports/reports/templates/displays/summary-block.html +++ /dev/null @@ -1,90 +0,0 @@ -{% load django_templating_sigh %} - -
-

Summary:

-

{{client_list|length }} Nodes were included in your report.

- {% if clean_client_list %} -
- {{clean_client_list|length}} nodes are clean.
-
    - {% for client in clean_client_list|sortname %} - {% set_interaction "foo" %} -
  • Node: - {{client.name}}{{interaction.timestamp}}
  • - {% endfor %} -
-
- {% endif %} - {% if bad_client_list %} -
- {{bad_client_list|length}} nodes are bad.
-
    - {% for client in bad_client_list|sortname %} - {% set_interaction "foo" %} -
  • Node: - {{client.name}}{{interaction.timestamp}}
  • - {% endfor %} -
-
- {% endif %} - {% if modified_client_list %} -
- {{modified_client_list|length}} nodes were modified in the previous run.
-
    - {% for client in modified_client_list|sortname %} - {% set_interaction "foo" %} -
  • Node: - {{client.name}}{{interaction.timestamp}}
  • - {% endfor %} -
-
- {% endif %} - {% if extra_client_list %} -
- {{extra_client_list|length}} nodes have extra configuration. (includes both good and bad nodes)
-
    - {% for client in extra_client_list|sortname %} - {% set_interaction "foo" %} -
  • Node: - {{client.name}}{{interaction.timestamp}}
  • - {% endfor %} -
-
- {% endif %} - {% if stale_up_client_list %} -
- {{stale_up_client_list|length}} nodes did not run within the last 24 hours but were pingable.
-
    - {% for client in stale_up_client_list|sortname %} - {% set_interaction "foo" %} -
  • Node: - {{client.name}}{{interaction.timestamp}}
  • - {% endfor %} -
-
- {% endif %} - {% if stale_all_client_list %} -
- {{stale_all_client_list|length}} nodes did not run within the last 24 hours. (includes nodes up and down)
-
    - {% for client in stale_all_client_list|sortname %} - {% set_interaction "foo" %} -
  • Node: - {{client.name}}{{interaction.timestamp}}
  • - {% endfor %} -
-
- {% endif %} - {% if down_client_list %} -
- {{down_client_list|length}} nodes were down.
-
    - {% for client in down_client_list|sortname %} - {% set_interaction "foo" %} -
  • Node: - {{client.name}}{{interaction.timestamp}}
  • - {% endfor %} -
-
- {% endif %} -
diff --git a/src/lib/Server/Reports/reports/templates/displays/summary.html b/src/lib/Server/Reports/reports/templates/displays/summary.html index 29cbb22d7..0124f635d 100644 --- a/src/lib/Server/Reports/reports/templates/displays/summary.html +++ b/src/lib/Server/Reports/reports/templates/displays/summary.html @@ -1,31 +1,42 @@ -{% extends "base.html" %} +{% extends "base-timeview.html" %} +{% load bcfg2_tags %} + +{% block title %}Bcfg2 - Client Summary{% endblock %} +{% block pagebanner %}Clients - Summary{% endblock %} + +{% block body_onload %}javascript:hide_table_array(hide_tables){% endblock %} + {% block extra_header_info %} - - + {% endblock%} -{% block title %}Display Index Listing{% endblock %} -{% block pagebanner %} -
-

BCFG Clients Summary

- Report Run @ {% now "F j, Y P"%} -
-
-{% endblock %} {% block content %} -
- -Enter date or use calendar popup: - -
- -@ - -Calendar - - | -
-


- {% include "displays/summary-block-direct-links.html" %} +
+

{{ node_count }} nodes reporting in

+
+{% if summary_data %} + {% for summary in summary_data %} +
+
+
[+]
+

{{ summary.nodes|length }} {{ summary.label }}

+
+ + + {% for node in summary.nodes|sort_interactions_by_name %} + + + + {% endfor %} +
{{ node.client.name }}
+
+ {% endfor %} +{% else %} +

No data to report on

+{% endif %} {% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/displays/sys_view.html b/src/lib/Server/Reports/reports/templates/displays/sys_view.html deleted file mode 100644 index 1298059bf..000000000 --- a/src/lib/Server/Reports/reports/templates/displays/sys_view.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "base.html" %} -{% load django_templating_sigh %} - -{% block title %}System-View Display{% endblock %} -{% block pagebanner %} -
-

Grand System View

- Report Run @ {% now "F j, Y P"%} -
-
-{% endblock %} -{% block content %} -

This view is deprecated and will be removed soon.


Please use the "Summary" view and drill down instead.
- - {% include "displays/summary-block.html" %} - {% for client in client_list %} - {% set_interaction "foo" %} - {% include "clients/client-nodebox.html" %} - {% endfor %} -{% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/displays/timing.html b/src/lib/Server/Reports/reports/templates/displays/timing.html index 32ddab464..47accb2cb 100644 --- a/src/lib/Server/Reports/reports/templates/displays/timing.html +++ b/src/lib/Server/Reports/reports/templates/displays/timing.html @@ -1,54 +1,38 @@ -{% extends "base.html" %} +{% extends "base-timeview.html" %} +{% load bcfg2_tags %} + +{% block title %}Bcfg2 - Performance Metrics{% endblock %} +{% block pagebanner %}Performance Metrics{% endblock %} + {% block extra_header_info %} - - - {% endblock%} -{% block title %}Display Index Listing{% endblock %} {% block content %} -
-

BCFG Performance Timings

- Report Run @ {% now "F j, Y P"%} -
-
-
- -Enter date or use calendar popup: - -
- -@ - -Calendar - - | -
-


-
- - - - - - - - - +
+ {% if metrics %} +
HostnameParseProbeInventoryInstallConfigTotal
+ + + + + + + + - {% for dict_unit in stats_list %} - - - - - - - - + {% for metric in metrics|dictsort:"name" %} + + + {% for mitem in metric|build_metric_list %} + + {% endfor %} {% endfor %}
NameParseProbeInventoryInstallConfigTotal
{{dict_unit.name}}{{dict_unit.parse}}{{dict_unit.probe}}{{dict_unit.inventory}}{{dict_unit.install}}{{dict_unit.config}}{{dict_unit.total}}
{{ metric.name }}{{ mitem }}
-
+ {% else %} +

No metric data available

+ {% endif %} +
{% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/index.html b/src/lib/Server/Reports/reports/templates/index.html deleted file mode 100644 index 002a3f770..000000000 --- a/src/lib/Server/Reports/reports/templates/index.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "base.html" %} - -{% block pagebanner %} -
-

BCFG Reports

- {% comment %} Report Run @ {% now "F j, Y P"%}{% endcomment %} -
-
-{% endblock %} -{% block content %} -

Welcome to the Bcfg2 Reporting System

-

-Please use the links at the left to navigate. -

-{% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/widgets/filter_bar.html b/src/lib/Server/Reports/reports/templates/widgets/filter_bar.html new file mode 100644 index 000000000..6b57baf6a --- /dev/null +++ b/src/lib/Server/Reports/reports/templates/widgets/filter_bar.html @@ -0,0 +1,13 @@ +{% spaceless %} +{% if filters %} +{% for filter, filter_url in filters %} + {% if forloop.first %} +
Active filters (click to remove): + {% endif %} + {{ filter|capfirst }}{% if not forloop.last %}, {% endif %} + {% if forloop.last %} +
+ {% endif %} +{% endfor %} +{% endif %} +{% endspaceless %} diff --git a/src/lib/Server/Reports/reports/templates/widgets/interaction_list.inc b/src/lib/Server/Reports/reports/templates/widgets/interaction_list.inc new file mode 100644 index 000000000..8f2dec1dc --- /dev/null +++ b/src/lib/Server/Reports/reports/templates/widgets/interaction_list.inc @@ -0,0 +1,38 @@ +{% load bcfg2_tags %} +
+ + + + {% if not client %} + + {% endif %} + + + + + + + + {% for entry in entry_list %} + + + {% if not client %} + + {% endif %} + + + + + + + + {% endfor %} +
TimestampClientStateGoodBadModifiedExtraServer
{{ entry.timestamp|date:"Y-m-d\&\n\b\s\p\;H:i"|safe }}{{ entry.client.name }}{{ entry.state }}{{ entry.goodcount }}{{ entry.bad_entry_count }}{{ entry.modified_entry_count }}{{ entry.extra_entry_count }} + {% if entry.server %} + {{ entry.server }} + {% else %} +   + {% endif %} +
+
diff --git a/src/lib/Server/Reports/reports/templates/widgets/page_bar.html b/src/lib/Server/Reports/reports/templates/widgets/page_bar.html new file mode 100644 index 000000000..aa0def83e --- /dev/null +++ b/src/lib/Server/Reports/reports/templates/widgets/page_bar.html @@ -0,0 +1,23 @@ +{% spaceless %} +{% for page, page_url in pager %} + {% if forloop.first %} +
+ {% if prev_page %}< Prev {% endif %} + {% if first_page %}1 ... {% endif %} + {% endif %} + {% ifequal page current_page %} + {{ page }} + {% else %} + {{ page }} + {% endifequal %} + {% if forloop.last %} + {% if last_page %} ... {{ total_pages }} {% endif %} + {% if next_page %}Next > {% endif %} + |{% for limit, limit_url in page_limits %} {{ limit }}{% endfor %} +
+ {% else %} +   + {% endif %} +{% endfor %} +{% endspaceless %} + diff --git a/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py b/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py new file mode 100644 index 000000000..2c27aab04 --- /dev/null +++ b/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py @@ -0,0 +1,239 @@ +from django import template +from django.core.urlresolvers import resolve, reverse, Resolver404, NoReverseMatch +from django.utils.encoding import smart_unicode, smart_str +from datetime import datetime, timedelta +from Bcfg2.Server.Reports.utils import filter_list + +register = template.Library() + +__PAGE_NAV_LIMITS__ = (10, 25, 50, 100) + +@register.inclusion_tag('widgets/page_bar.html', takes_context=True) +def page_navigator(context): + """ + Creates paginated links. + + Expects the context to be a RequestContext and views.prepare_paginated_list() + to have populated page information. + """ + fragment = dict() + try: + path = context['request'].path + total_pages = int(context['total_pages']) + records_per_page = int(context['records_per_page']) + except KeyError, e: + return fragment + except ValueError, e: + return fragment + + if total_pages < 2: + return {} + + try: + view, args, kwargs = resolve(path) + current_page = int(kwargs.get('page_number',1)) + fragment['current_page'] = current_page + fragment['page_number'] = current_page + fragment['total_pages'] = total_pages + fragment['records_per_page'] = records_per_page + if current_page > 1: + kwargs['page_number'] = current_page - 1 + fragment['prev_page'] = reverse(view, args=args, kwargs=kwargs) + if current_page < total_pages: + kwargs['page_number'] = current_page + 1 + fragment['next_page'] = reverse(view, args=args, kwargs=kwargs) + + view_range = 5 + if total_pages > view_range: + pager_start = current_page - 2 + pager_end = current_page + 2 + if pager_start < 1: + pager_end += (1 - pager_start) + pager_start = 1 + if pager_end > total_pages: + pager_start -= (pager_end - total_pages) + pager_end = total_pages + else: + pager_start = 1 + pager_end = total_pages + + if pager_start > 1: + kwargs['page_number'] = 1 + fragment['first_page'] = reverse(view, args=args, kwargs=kwargs) + if pager_end < total_pages: + kwargs['page_number'] = total_pages + fragment['last_page'] = reverse(view, args=args, kwargs=kwargs) + + pager = [] + for page in range(pager_start, int(pager_end) + 1): + kwargs['page_number'] = page + pager.append( (page, reverse(view, args=args, kwargs=kwargs)) ) + + kwargs['page_number'] = 1 + page_limits = [] + for limit in __PAGE_NAV_LIMITS__: + kwargs['page_limit'] = limit + page_limits.append( (limit, reverse(view, args=args, kwargs=kwargs)) ) + # resolver doesn't like this + del kwargs['page_number'] + del kwargs['page_limit'] + page_limits.append( ('all', reverse(view, args=args, kwargs=kwargs) + "|all") ) + + fragment['pager'] = pager + fragment['page_limits'] = page_limits + + except Resolver404: + path = "404" + except NoReverseMatch, nr: + path = "NoReverseMatch: %s" % nr + except ValueError: + path = "ValueError" + #FIXME - Handle these + + fragment['path'] = path + return fragment + +@register.inclusion_tag('widgets/filter_bar.html', takes_context=True) +def filter_navigator(context): + try: + path = context['request'].path + view, args, kwargs = resolve(path) + + # Strip any page limits and numbers + if 'page_number' in kwargs: + del kwargs['page_number'] + if 'page_limit' in kwargs: + del kwargs['page_limit'] + + filters = [] + for filter in filter_list: + if filter in kwargs: + myargs = kwargs.copy() + del myargs[filter] + filters.append( (filter, reverse(view, args=args, kwargs=myargs) ) ) + filters.sort(lambda x,y: cmp(x[0], y[0])) + return { 'filters': filters } + except (Resolver404, NoReverseMatch, ValueError, KeyError): + pass + return dict() + +def _subtract_or_na(mdict, x, y): + """ + Shortcut for build_metric_list + """ + try: + return round(mdict[x] - mdict[y], 4) + except: + return "n/a" + +@register.filter +def build_metric_list(mdict): + """ + Create a list of metric table entries + + Moving this here it simplify the view. Should really handle the case where these + are missing... + """ + td_list = [] + # parse + td_list.append( _subtract_or_na(mdict, 'config_parse', 'config_download')) + #probe + td_list.append( _subtract_or_na(mdict, 'probe_upload', 'start')) + #inventory + td_list.append( _subtract_or_na(mdict, 'inventory', 'initialization')) + #install + td_list.append( _subtract_or_na(mdict, 'install', 'inventory')) + #cfg download & parse + td_list.append( _subtract_or_na(mdict, 'config_parse', 'probe_upload')) + #total + td_list.append( _subtract_or_na(mdict, 'finished', 'start')) + return td_list + +@register.filter +def isstale(timestamp, entry_max=None): + """ + Check for a stale timestamp + + Compares two timestamps and returns True if the + difference is greater then 24 hours. + """ + if not entry_max: + entry_max = datetime.now() + return entry_max - timestamp > timedelta(hours=24) + +@register.filter +def sort_interactions_by_name(value): + """ + Sort an interaction list by client name + """ + inters = list(value) + inters.sort(lambda a,b: cmp(a.client.name, b.client.name)) + return inters + +class AddUrlFilter(template.Node): + def __init__(self, filter_name, filter_value): + self.filter_name = filter_name + self.filter_value = filter_value + self.fallback_view = 'Bcfg2.Server.Reports.reports.views.render_history_view' + + def render(self, context): + link = '#' + try: + path = context['request'].path + view, args, kwargs = resolve(path) + filter_value = self.filter_value.resolve(context, True) + if filter_value: + filter_name = smart_str(self.filter_name) + filter_value = smart_unicode(filter_value) + kwargs[filter_name] = filter_value + # These two don't make sense + if filter_name == 'server' and 'hostname' in kwargs: + del kwargs['hostname'] + elif filter_name == 'hostname' and 'server' in kwargs: + del kwargs['server'] + try: + link = reverse(view, args=args, kwargs=kwargs) + except NoReverseMatch, rm: + link = reverse(self.fallback_view, args=None, + kwargs={ filter_name: filter_value }) + except NoReverseMatch, rm: + raise rm + except (Resolver404, ValueError), e: + pass + return link + +@register.tag +def add_url_filter(parser, token): + """ + Return a url with the filter added to the current view. + + Takes a new filter and resolves the current view with the new filter + applied. Resolves to Bcfg2.Server.Reports.reports.views.client_history + by default. + + {% add_url_filter server=interaction.server %} + """ + try: + tag_name, filter_pair = token.split_contents() + filter_name, filter_value = filter_pair.split('=', 1) + filter_name = filter_name.strip() + filter_value = parser.compile_filter(filter_value) + except ValueError: + raise template.TemplateSyntaxError, "%r tag requires exactly one argument" % token.contents.split()[0] + if not filter_name or not filter_value: + raise template.TemplateSyntaxError, "argument should be a filter=value pair" + + return AddUrlFilter(filter_name, filter_value) + +@register.filter +def sortwell(value): + """ + Sorts a list(or evaluates queryset to list) of bad, extra, or modified items in the best + way for presentation + """ + + configItems = list(value) + configItems.sort(lambda x,y: cmp(x.entry.name, y.entry.name)) + configItems.sort(lambda x,y: cmp(x.entry.kind, y.entry.kind)) + return configItems + diff --git a/src/lib/Server/Reports/reports/templatetags/django_templating_sigh.py b/src/lib/Server/Reports/reports/templatetags/django_templating_sigh.py deleted file mode 100644 index c0d05d2c1..000000000 --- a/src/lib/Server/Reports/reports/templatetags/django_templating_sigh.py +++ /dev/null @@ -1,41 +0,0 @@ -from django import template -#from Bcfg2.Server.Reports.reports.models import Client, Interaction, Bad, Modified, Extra - -register = template.Library() - -def set_interaction(parser, token): - try: - # Splitting by None == splitting by spaces. - tag_name, format_string = token.contents.split(None, 1) - except ValueError: - raise template.TemplateSyntaxError, "%r tag requires an argument" % token.contents[0] - if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")): - raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name - return SetInteraction(format_string[1:-1]) - -def sortwell(value): - "sorts a list(or evaluates queryset to list) of bad, extra, or modified items in the best" - "way for presentation" - configItems = list(value) - configItems.sort(lambda x,y: cmp(x.entry.name, y.entry.name)) - configItems.sort(lambda x,y: cmp(x.entry.kind, y.entry.kind)) - return configItems -def sortname(value): - "sorts a list( or evaluates queryset) by name" - configItems = list(value) - configItems.sort(lambda x,y: cmp(x.name, y.name)) - return configItems - -class SetInteraction(template.Node): - def __init__(self, times): - self.times = times#do soemthing to select different interaction with host? - def render(self, context): - try: - context['interaction'] = context['client_interaction_dict'][context['client'].id] - except:#I don't fully know what the implications of this are. - pass - return '' - -register.tag('set_interaction', set_interaction) -register.filter('sortwell', sortwell) -register.filter('sortname', sortname) diff --git a/src/lib/Server/Reports/reports/templatetags/syntax_coloring.py b/src/lib/Server/Reports/reports/templatetags/syntax_coloring.py index 083b83a73..43dafb262 100644 --- a/src/lib/Server/Reports/reports/templatetags/syntax_coloring.py +++ b/src/lib/Server/Reports/reports/templatetags/syntax_coloring.py @@ -1,4 +1,7 @@ from django import template +from django.utils.encoding import smart_unicode, smart_str +from django.utils.html import conditional_escape +from django.utils.safestring import mark_safe register = template.Library() @@ -11,15 +14,28 @@ try: except: colorize = False -def syntaxhilight(value, arg="diff"): - '''Returns a syntax-hilighted version of Code; requires code/language arguments''' +@register.filter +def syntaxhilight(value, arg="diff", autoescape=None): + """ + Returns a syntax-hilighted version of Code; requires code/language arguments + """ + + if autoescape: + value = conditional_escape(value) + arg = conditional_escape(arg) + if colorize: try: + output = u'' + lexer = get_lexer_by_name(arg) - return highlight(value, lexer, HtmlFormatter()) + output += highlight(value, lexer, HtmlFormatter()) + return mark_safe(output) except: return value else: - return value + return mark_safe(u'
Tip: Install pygments for highlighting
%s
' % value) +syntaxhilight.needs_autoescape = True -register.filter('syntaxhilight', syntaxhilight) diff --git a/src/lib/Server/Reports/reports/urls.py b/src/lib/Server/Reports/reports/urls.py new file mode 100644 index 000000000..9970d26a1 --- /dev/null +++ b/src/lib/Server/Reports/reports/urls.py @@ -0,0 +1,55 @@ +from django.conf.urls.defaults import * +from django.core.urlresolvers import reverse, NoReverseMatch +from django.http import HttpResponsePermanentRedirect +from Bcfg2.Server.Reports.utils import filteredUrls, paginatedUrls, timeviewUrls + +def newRoot(request): + try: + grid_view = reverse('reports_grid_view') + except NoReverseMatch: + grid_view = '/grid' + return HttpResponsePermanentRedirect(grid_view) + +urlpatterns = patterns('Bcfg2.Server.Reports.reports', + (r'^$', newRoot), + + url(r'^manage/?$', 'views.client_manage', name='reports_client_manage'), + url(r'^client/(?P\S+)/(?P\d+)/?$', 'views.client_detail', name='reports_client_detail_pk'), + url(r'^client/(?P\S+)/?$', 'views.client_detail', name='reports_client_detail'), + url(r'^elements/(?P\w+)/(?P\d+)/?$', 'views.config_item', name='reports_item'), +) + +urlpatterns += patterns('Bcfg2.Server.Reports.reports', + *timeviewUrls( + (r'^grid/?$', 'views.client_index', None, 'reports_grid_view'), + (r'^summary/?$', 'views.display_summary', None, 'reports_summary'), + (r'^timing/?$', 'views.display_timing', None, 'reports_timing'), + (r'^elements/(?P\w+)/?$', 'views.config_item_list', None, 'reports_item_list'), +)) + +urlpatterns += patterns('Bcfg2.Server.Reports.reports', + *filteredUrls(*timeviewUrls( + (r'^detailed/?$', + 'views.client_detailed_list', None, 'reports_detailed_list') +))) + +urlpatterns += patterns('Bcfg2.Server.Reports.reports', + *paginatedUrls( *filteredUrls( + (r'^history/?$', + 'views.render_history_view', None, 'reports_history'), + (r'^history/(?P[\w\-\.]+)/?$', + 'views.render_history_view', None, 'reports_client_history'), +))) + + # Uncomment this for admin: + #(r'^admin/', include('django.contrib.admin.urls')), + + +## Uncomment this section if using authentication +#urlpatterns += patterns('', +# (r'^login/$', 'django.contrib.auth.views.login', +# {'template_name': 'auth/login.html'}), +# (r'^logout/$', 'django.contrib.auth.views.logout', +# {'template_name': 'auth/logout.html'}) +# ) + diff --git a/src/lib/Server/Reports/reports/views.py b/src/lib/Server/Reports/reports/views.py index d159dcd43..64617ce70 100644 --- a/src/lib/Server/Reports/reports/views.py +++ b/src/lib/Server/Reports/reports/views.py @@ -1,354 +1,379 @@ -# Create your views here. -#from django.shortcuts import get_object_or_404, render_to_response -from django.template import Context, loader -from django.http import HttpResponseRedirect, HttpResponse +""" +Report views + +Functions to handle all of the reporting views. +""" +from django.template import Context, RequestContext, loader +from django.http import HttpResponse, HttpResponseRedirect, HttpResponseServerError, Http404 from django.shortcuts import render_to_response, get_object_or_404 -from Bcfg2.Server.Reports.reports.models import Client, Interaction, Entries, Entries_interactions, Performance, Reason -from Bcfg2.Server.Reports.reports.models import TYPE_BAD, TYPE_MODIFIED, TYPE_EXTRA -from datetime import datetime, timedelta -from time import strptime +from django.core.urlresolvers import resolve, reverse, Resolver404, NoReverseMatch from django.db import connection from django.db.backends import util -from django.contrib.auth.decorators import login_required -def index(request): - return render_to_response('index.html') +from Bcfg2.Server.Reports.reports.models import * +from datetime import datetime, timedelta +from time import strptime +import sys -def config_item_modified(request, eyedee =None, timestamp = 'now', type=TYPE_MODIFIED): - #if eyedee = None, dump with a 404 - timestamp = timestamp.replace("@"," ") - if type == TYPE_MODIFIED: - mod_or_bad = "modified" - else: - mod_or_bad = "bad" - - item = get_object_or_404(Entries_interactions, id=eyedee) - #if everything is blank except current_exists, do something special - cursor = connection.cursor() - if timestamp == 'now': - cursor.execute("select client_id from reports_interaction, reports_entries_interactions, reports_client "+ - "WHERE reports_client.current_interaction_id = reports_entries_interactions.interaction_id "+ - "AND reports_entries_interactions.interaction_id = reports_interaction.id "+ - "AND reports_entries_interactions.entry_id = %s " + - "AND reports_entries_interactions.reason_id = %s", [item.entry.id, item.reason.id]) - associated_client_list = Client.objects.active(timestamp).filter(id__in=[x[0] for x in cursor.fetchall()]) - else: - interact_queryset = Interaction.objects.interaction_per_client(timestamp) - interactionlist = [] - [interactionlist.append(x.id) for x in interact_queryset] - if not interactionlist == []: - cursor.execute("select client_id from reports_interaction, reports_entries_interactions, reports_client "+ - "WHERE reports_entries_interactions.interaction_id IN %s "+ - "AND reports_entries_interactions.interaction_id = reports_interaction.id "+ - "AND reports_entries_interactions.entry_id = %s " + - "AND reports_entries_interactions.reason_id = %s ", [interactionlist, item.entry_id, item.reason.id]) - associated_client_list = Client.objects.active(timestamp).filter(id__in=[x[0] for x in cursor.fetchall()]) - else: - associated_client_list = [] +class PaginationError(Exception): + """This error is raised when pagination cannot be completed.""" + pass - if timestamp == 'now': - timestamp = datetime.now().isoformat('@') +def server_error(request): + """ + 500 error handler. - return render_to_response('config_items/index.html', {'item':item, - 'mod_or_bad':mod_or_bad, - 'associated_client_list':associated_client_list, - 'timestamp' : timestamp, - 'timestamp_date' : timestamp[:10], - 'timestamp_time' : timestamp[11:19]}) + For now always return the debug response. Mailing isn't appropriate here. + """ + from django.views import debug + return debug.technical_500_response(request, *sys.exc_info()) -def config_item_bad(request, eyedee = None, timestamp = 'now'): - return config_item_modified(request, eyedee, timestamp, TYPE_BAD) +def timeview(fn): + """ + Setup a timeview view -def bad_item_index(request, timestamp = 'now', type=TYPE_BAD): - timestamp = timestamp.replace("@"," ") - if type == TYPE_BAD: - mod_or_bad = "bad" - else: - mod_or_bad = "modified" + Handles backend posts from the calendar and converts date pieces + into a 'timestamp' parameter + + """ + def _handle_timeview(request, **kwargs): + """Send any posts back.""" + if request.method == 'POST': + cal_date = request.POST['cal_date'] + try: + fmt = "%Y/%m/%d" + if cal_date.find(' ') > -1: + fmt += " %H:%M" + timestamp = datetime(*strptime(cal_date, fmt)[0:6]) + view, args, kw = resolve(request.path) + kw['year'] = "%0.4d" % timestamp.year + kw['month'] = "%02.d" % timestamp.month + kw['day'] = "%02.d" % timestamp.day + if cal_date.find(' ') > -1: + kw['hour'] = timestamp.hour + kw['minute'] = timestamp.minute + return HttpResponseRedirect(reverse(view, args=args, kwargs=kw)) + except KeyError: + pass + except: + pass + # FIXME - Handle this + + """Extract timestamp from args.""" + timestamp = None + try: + timestamp = datetime(int(kwargs.pop('year')), int(kwargs.pop('month')), + int(kwargs.pop('day')), int(kwargs.pop('hour', 0)), + int(kwargs.pop('minute', 0)), 0) + kwargs['timestamp'] = timestamp + except KeyError: + pass + except: + raise + return fn(request, **kwargs) + + return _handle_timeview + +def config_item(request, pk, type="bad"): + """ + Display a single entry. + + Dispalys information about a single entry. + + """ + item = get_object_or_404(Entries_interactions, id=pk) + timestamp=item.interaction.timestamp + time_start=item.interaction.timestamp.replace(\ + hour=0, minute=0, second=0, microsecond=0) + time_end=time_start + timedelta(days=1) + + todays_data = Interaction.objects.filter(\ + timestamp__gte=time_start,\ + timestamp__lt=time_end) + shared_entries = Entries_interactions.objects.filter(entry=item.entry,\ + reason=item.reason, type=item.type, + interaction__in=[x['id']\ + for x in todays_data.values('id')]) + + associated_list = Interaction.objects.filter(id__in=[x['interaction']\ + for x in shared_entries.values('interaction')])\ + .order_by('client__name','timestamp').select_related().all() + + return render_to_response('config_items/item.html', + {'item':item, + 'isextra': item.type == TYPE_EXTRA, + 'mod_or_bad': type, + 'associated_list':associated_list, + 'timestamp' : timestamp}, + context_instance=RequestContext(request)) + +@timeview +def config_item_list(request, type, timestamp=None): + """Render a listing of affected elements""" + mod_or_bad = type.lower() + type = convert_entry_type_to_id(type) + if type < 0: + raise Http404 - current_clients = [c.current_interaction - for c in Client.objects.active(timestamp)] + current_clients = Interaction.objects.get_interaction_per_client_ids(timestamp) item_list_dict = {} - for x in Entries_interactions.objects.select_related().filter(interaction__in=current_clients, type=type).distinct(): + seen = dict() + for x in Entries_interactions.objects.filter(interaction__in=current_clients, type=type).select_related(): + if (x.entry, x.reason) in seen: + continue + seen[(x.entry, x.reason)] = 1 if item_list_dict.get(x.entry.kind, None): item_list_dict[x.entry.kind].append(x) else: item_list_dict[x.entry.kind] = [x] - item_list_pseudodict = item_list_dict.items() - if timestamp == 'now': - timestamp = datetime.now().isoformat('@') + for kind in item_list_dict: + item_list_dict[kind].sort(lambda a,b: cmp(a.entry.name, b.entry.name)) - return render_to_response('config_items/listing.html', {'item_list_pseudodict':item_list_pseudodict, + return render_to_response('config_items/listing.html', {'item_list_dict':item_list_dict, 'mod_or_bad':mod_or_bad, - 'timestamp' : timestamp, - 'timestamp_date' : timestamp[:10], - 'timestamp_time' : timestamp[11:19]}) -def modified_item_index(request, timestamp = 'now'): - return bad_item_index(request, timestamp, TYPE_MODIFIED) - -def client_index(request, timestamp = 'now'): - timestamp = timestamp.replace("@"," ") - - c_dict = dict() - [c_dict.__setitem__(cl.id,cl.name) for cl in Client.objects.active(timestamp).order_by('name')] - - list = [] - for inter in Interaction.objects.interaction_per_client(timestamp): - if inter.client_id in c_dict: - list.append([c_dict[inter.client_id], inter]) - list.sort(lambda a,b: cmp(a[0], b[0])) - half_list = len(list) / 2 - - if timestamp == 'now': - timestamp = datetime.now().isoformat('@') + 'timestamp' : timestamp}, + context_instance=RequestContext(request)) + +@timeview +def client_index(request, timestamp=None): + """ + Render a grid view of active clients. + + Keyword parameters: + timestamp -- datetime objectto render from + + """ + list = Interaction.objects.interaction_per_client(timestamp).select_related()\ + .order_by("client__name").all() + return render_to_response('clients/index.html', - {'inter_list': list, - 'half_list': half_list, - 'timestamp' : timestamp, - 'timestamp_date' : timestamp[:10], - 'timestamp_time' : timestamp[11:19]}) + { 'inter_list': list, 'timestamp' : timestamp}, + context_instance=RequestContext(request)) -def client_detailed_list(request, **kwargs): +@timeview +def client_detailed_list(request, timestamp=None, **kwargs): """ Provides a more detailed list view of the clients. Allows for extra - filters to be passed in. Somewhat clunky now that dates are allowed. + filters to be passed in. """ - context = dict(path=request.path) - timestamp = 'now' - entry_max = datetime.now() - if request.GET: - context['qsa']='?%s' % request.GET.urlencode() - if request.GET.has_key('date1') and request.GET.has_key('time'): - timestamp = "%s %s" % (request.GET['date1'],request.GET['time']) - entry_max = datetime(*strptime(timestamp, "%Y-%m-%d %H:%M:%S")[0:6]) - client_list = Client.objects.active(timestamp).order_by('name') - if timestamp == 'now': - timestamp = datetime.now().isoformat('@') - context['timestamp_date'] = timestamp[:10] - context['timestamp_time'] = timestamp[11:19] - - interactions = Interaction.objects.interaction_per_client(timestamp) - if 'state' in kwargs and kwargs['state']: - context['state'] = kwargs['state'] - interactions=interactions.filter(state__exact=kwargs['state']) - if 'server' in kwargs and kwargs['server']: - interactions=interactions.filter(server__exact=kwargs['server']) - context['server'] = kwargs['server'] - # build the entry list from available clients - c_dict = dict() - [c_dict.__setitem__(cl.id,cl.name) for cl in client_list] - - entry_list = [] - for inter in interactions: - if inter.client_id in c_dict: - entry_list.append([c_dict[inter.client_id], inter, \ - entry_max - inter.timestamp > timedelta(hours=24)]) - entry_list.sort(lambda a,b: cmp(a[0], b[0])) - ''' - if(datetime.now()-self.timestamp > timedelta(hours=25) ): - return True - else: - return False - ''' - - context['entry_list'] = entry_list - return render_to_response('clients/detailed-list.html', context) + kwargs['interaction_base'] = Interaction.objects.interaction_per_client(timestamp).select_related() + kwargs['orderby'] = "client__name" + kwargs['page_limit'] = 0 + return render_history_view(request, 'clients/detailed-list.html', **kwargs) def client_detail(request, hostname = None, pk = None): - #SETUP error pages for when you specify a client or interaction that doesn't exist + context = dict() client = get_object_or_404(Client, name=hostname) if(pk == None): - interaction = client.current_interaction + context['interaction'] = client.current_interaction + return render_history_view(request, 'clients/detail.html', page_limit=5, + client=client, context=context) else: - interaction = client.interactions.get(pk=pk)#can this be a get object or 404? - return render_to_response('clients/detail.html', {'client': client, 'interaction': interaction}) + context['interaction'] = client.interactions.get(pk=pk) + return render_history_view(request, 'clients/detail.html', page_limit=5, + client=client, maxdate=context['interaction'].timestamp, context=context) -def client_manage(request, hostname = None): - #SETUP error pages for when you specify a client or interaction that doesn't exist - client = get_object_or_404(Client, name=hostname) - currenttime = datetime.now().isoformat('@') - if client.expiration != None: - message = ("This client currently has an expiration date of %s. " - "Reports after %s will not include data for this host " - "You may change this if you wish by selecting a new " - "time, earlier or later." - % (client.expiration, client.expiration)) - else: - message = ("This client is currently active and displayed. You " - "may choose a date after which this client will no " - "longer appear in reports.") +def client_manage(request): + """Manage client expiration""" + message = '' if request.method == 'POST': - date = request.POST['date1'] - time = request.POST['time'] try: - timestamp = datetime(*(strptime(date+"@"+time, "%Y-%m-%d@%H:%M:%S")[0:6])) - except ValueError: - timestamp = None - if timestamp == None: - message = "Invalid removal date, please try again using the format: yyyy-mm-dd hh:mm:ss." - else: - client.expiration = timestamp + client_name = request.POST.get('client_name', None) + client_action = request.POST.get('client_action', None) + client = Client.objects.get(name=client_name) + if client_action == 'expire': + client.expiration = datetime.now(); + client.save() + message = "Expiration for %s set to %s." % \ + (client_name, client.expiration.strftime("%Y-%m-%d %H:%M:%S")) + elif client_action == 'unexpire': + client.expiration = None; client.save() - message = "Expiration for client set to %s." % client.expiration - return render_to_response('clients/manage.html', {'client': client, 'message': message, - 'timestamp_date' : currenttime[:10], - 'timestamp_time' : currenttime[11:19]}) - -def display_sys_view(request, timestamp = 'now'): - client_lists = prepare_client_lists(request, timestamp) - return render_to_response('displays/sys_view.html', client_lists) - -def display_summary(request, timestamp = 'now'): - - client_lists = prepare_client_lists(request, timestamp) - #this returns timestamp and the timestamp parts too - return render_to_response('displays/summary.html', client_lists) - -def display_timing(request, timestamp = 'now'): - #We're going to send a list of dictionaries. Each dictionary will be a row in the table - #+------+-------+----------------+-----------+---------+----------------+-------+ - #| name | parse | probe download | inventory | install | cfg dl & parse | total | - #+------+-------+----------------+-----------+---------+----------------+-------+ - client_list = Client.objects.active(timestamp.replace("@"," ")).order_by('name') - stats_list = [] - - if not timestamp == 'now': - results = Performance.objects.performance_per_client(timestamp.replace("@"," ")) + message = "%s is now active." % client_name else: - results = Performance.objects.performance_per_client() - timestamp = datetime.now().isoformat('@') - - for client in client_list:#Go explicitly to an interaction ID! (new item in dictionary) + message = "Missing action" + except Client.DoesNotExist: + if not client_name: + client_name = "" + message = "Couldn't find client \"%s\"" % client_name + + return render_to_response('clients/manage.html', + {'clients': Client.objects.order_by('name').all(), 'message': message}, + context_instance=RequestContext(request)) + +@timeview +def display_summary(request, timestamp=None): + """ + Display a summary of the bcfg2 world + """ + query = Interaction.objects.interaction_per_client(timestamp).select_related() + node_count = query.count() + recent_data = query.all() + if not timestamp: + timestamp = datetime.now() + + collected_data = dict(clean=[],bad=[],modified=[],extra=[],stale=[],pings=[]) + for node in recent_data: + if timestamp - node.timestamp > timedelta(hours=24): + collected_data['stale'].append(node) + # If stale check for uptime try: - d = results[client.name] - except KeyError: - d = {} + if node.client.pings.latest().status == 'N': + collected_data['pings'].append(node) + except Ping.DoesNotExist: + collected_data['pings'].append(node) + continue + if node.bad_entry_count() > 0: + collected_data['bad'].append(node) + else: + collected_data['clean'].append(node) + if node.modified_entry_count() > 0: + collected_data['modified'].append(node) + if node.extra_entry_count() > 0: + collected_data['extra'].append(node) + + # label, header_text, node_list + summary_data = [] + get_dict = lambda name, label: { 'name': name, + 'nodes': collected_data[name], + 'label': label } + if len(collected_data['clean']) > 0: + summary_data.append( get_dict('clean', 'nodes are clean.') ) + if len(collected_data['bad']) > 0: + summary_data.append( get_dict('bad', 'nodes are bad.') ) + if len(collected_data['modified']) > 0: + summary_data.append( get_dict('modified', 'nodes were modified.') ) + if len(collected_data['extra']) > 0: + summary_data.append( get_dict('extra', + 'nodes have extra configurations.') ) + if len(collected_data['stale']) > 0: + summary_data.append( get_dict('stale', + 'nodes did not run within the last 24 hours.') ) + if len(collected_data['pings']) > 0: + summary_data.append( get_dict('pings', + 'are down.') ) + + return render_to_response('displays/summary.html', + {'summary_data': summary_data, 'node_count': node_count, + 'timestamp': timestamp}, + context_instance=RequestContext(request)) + +@timeview +def display_timing(request, timestamp=None): + mdict = dict() + inters = Interaction.objects.interaction_per_client(timestamp).select_related().all() + [mdict.__setitem__(inter, {'name': inter.client.name}) \ + for inter in inters] + for metric in Performance.objects.filter(interaction__in=mdict.keys()).all(): + for i in metric.interaction.all(): + mdict[i][metric.metric] = metric.value + return render_to_response('displays/timing.html', + {'metrics': mdict.values(), 'timestamp': timestamp}, + context_instance=RequestContext(request)) + + +def render_history_view(request, template='clients/history.html', **kwargs): + """ + Provides a detailed history of a clients interactions. + + Renders a detailed history of a clients interactions. Allows for various + filters and settings. Automatically sets pagination data into the context. + + Keyword arguments: + interaction_base -- Interaction QuerySet to build on + (default Interaction.objects) + context -- Additional context data to render with + page_number -- Page to display (default 1) + page_limit -- Number of results per page, if 0 show all (default 25) + client -- Client object to render + hostname -- Client hostname to lookup and render. Returns a 404 if + not found + server -- Filter interactions by server + state -- Filter interactions by state + entry_max -- Most recent interaction to display + orderby -- Sort results using this field - dict_unit = {} - try: - dict_unit["name"] = client.name #node name - except: - dict_unit["name"] = "n/a" - try: - dict_unit["parse"] = round(d["config_parse"] - d["config_download"], 4) #parse - except: - dict_unit["parse"] = "n/a" - try: - dict_unit["probe"] = round(d["probe_upload"] - d["start"], 4) #probe - except: - dict_unit["probe"] = "n/a" - try: - dict_unit["inventory"] = round(d["inventory"] - d["initialization"], 4) #inventory - except: - dict_unit["inventory"] = "n/a" - try: - dict_unit["install"] = round(d["install"] - d["inventory"], 4) #install - except: - dict_unit["install"] = "n/a" - try: - dict_unit["config"] = round(d["config_parse"] - d["probe_upload"], 4)#config download & parse - except: - dict_unit["config"] = "n/a" + """ + + context = kwargs.get('context', dict()) + max_results = int(kwargs.get('page_limit', 25)) + page = int(kwargs.get('page_number', 1)) + + client=kwargs.get('client', None) + if not client and 'hostname' in kwargs: + client = get_object_or_404(Client, name=kwargs['hostname']) + if client: + context['client'] = client + + entry_max = kwargs.get('maxdate', None) + context['entry_max'] = entry_max + + # Either filter by client or limit by clients + iquery = kwargs.get('interaction_base', Interaction.objects) + if client: + iquery = iquery.filter(client__exact=client).select_related() + + if 'orderby' in kwargs and kwargs['orderby']: + iquery = iquery.order_by(kwargs['orderby']) + + if 'state' in kwargs and kwargs['state']: + iquery = iquery.filter(state__exact=kwargs['state']) + if 'server' in kwargs and kwargs['server']: + iquery = iquery.filter(server__exact=kwargs['server']) + + if entry_max: + iquery = iquery.filter(timestamp__lte=entry_max) + + if max_results < 0: + max_results = 1 + entry_list = [] + if max_results > 0: try: - dict_unit["total"] = round(d["finished"] - d["start"], 4) #total - except: - dict_unit["total"] = "n/a" - - stats_list.append(dict_unit) - - return render_to_response('displays/timing.html', {'client_list': client_list, - 'stats_list': stats_list, - 'timestamp' : timestamp, - 'timestamp_date' : timestamp[:10], - 'timestamp_time' : timestamp[11:19]}) - -def display_index(request): - return render_to_response('displays/index.html') - -def prepare_client_lists(request, timestamp = 'now'): - #I suggest we implement "expiration" here. - - timestamp = timestamp.replace("@"," ") - #client_list = Client.objects.all().order_by('name')#change this to order by interaction's state - client_interaction_dict = {} - clean_client_list = [] - bad_client_list = [] - extra_client_list = [] - modified_client_list = [] - stale_up_client_list = [] - #stale_all_client_list = [] - down_client_list = [] - - cursor = connection.cursor() - - interact_queryset = Interaction.objects.interaction_per_client(timestamp) - # or you can specify a time like this: '2007-01-01 00:00:00' - [client_interaction_dict.__setitem__(x.client_id, x) for x in interact_queryset] - client_list = Client.objects.active(timestamp).filter(id__in=client_interaction_dict.keys()).order_by('name') - - [clean_client_list.append(x) for x in Client.objects.active(timestamp).filter(id__in=[y.client_id for y in interact_queryset.filter(state='clean')])] - [bad_client_list.append(x) for x in Client.objects.active(timestamp).filter(id__in=[y.client_id for y in interact_queryset.filter(state='dirty')])] - - client_ping_dict = {} - [client_ping_dict.__setitem__(x,'Y') for x in client_interaction_dict.keys()]#unless we know otherwise... + rec_start, rec_end = prepare_paginated_list(request, context, iquery, page, max_results) + except PaginationError, page_error: + if isinstance(page_error[0], HttpResponse): + return page_error[0] + return HttpResponseServerError(page_error) + context['entry_list'] = iquery.all()[rec_start:rec_end] + else: + context['entry_list'] = iquery.all() + + return render_to_response(template, context, + context_instance=RequestContext(request)) + +def prepare_paginated_list(request, context, paged_list, page=1, max_results=25): + """ + Prepare context and slice an object for pagination. + """ + if max_results < 1: + raise PaginationError, "Max results less then 1" + if paged_list == None: + raise PaginationError, "Invalid object" + + try: + nitems = paged_list.count() + except TypeError: + nitems = len(paged_list) + rec_start = (page - 1) * int(max_results) try: - cursor.execute("select reports_ping.status, x.client_id from (select client_id, MAX(endtime) "+ - "as timer from reports_ping GROUP BY client_id) x, reports_ping where "+ - "reports_ping.client_id = x.client_id AND reports_ping.endtime = x.timer") - [client_ping_dict.__setitem__(x[1], x[0]) for x in cursor.fetchall()] + total_pages = (nitems / int(max_results)) + 1 except: - pass #This is to fix problems when you have only zero records returned - - client_down_ids = [y for y in client_ping_dict.keys() if client_ping_dict[y]=='N'] - if not client_down_ids == []: - [down_client_list.append(x) for x in Client.objects.active(timestamp).filter(id__in=client_down_ids)] - - if (timestamp == 'now' or timestamp == None): - cursor.execute("select client_id, MAX(timestamp) as timestamp from reports_interaction GROUP BY client_id") - results = cursor.fetchall() - for x in results: - if type(x[1]) == type("") or type(x[1]) == type(u""): - ts = util.typecast_timestamp(x[1]) - else: - ts = x[1] - stale_all_client_list = Client.objects.active(timestamp).filter(id__in=[x[0] for x in results if datetime.now() - ts > timedelta(days=1)]) - else: - cursor.execute("select client_id, timestamp, MAX(timestamp) as timestamp from reports_interaction "+ - "WHERE timestamp < %s GROUP BY client_id", [timestamp]) - t = strptime(timestamp,"%Y-%m-%d %H:%M:%S") - datetimestamp = datetime(t[0], t[1], t[2], t[3], t[4], t[5]) - results = cursor.fetchall() - for x in results: - if type(x[1]) == type(""): - x[1] = util.typecast_timestamp(x[1]) - stale_all_client_list = Client.objects.active(timestamp).filter(id__in=[x[0] for x in results if datetimestamp - x[1] > timedelta(days=1)]) - - [stale_up_client_list.append(x) for x in stale_all_client_list if not client_ping_dict[x.id]=='N'] + total_pages = 1 + if page > total_pages: + # If we passed beyond the end send back + try: + view, args, kwargs = resolve(request.path) + kwargs['page_number'] = total_pages + raise PaginationError, HttpResponseRedirect( reverse(view, kwargs=kwargs) ) + except (Resolver404, NoReverseMatch, ValueError): + raise "Accessing beyond last page. Unable to resolve redirect." + + context['total_pages'] = total_pages + context['records_per_page'] = max_results + return (rec_start, rec_start + int(max_results)) - - cursor.execute("SELECT reports_client.id FROM reports_client, reports_interaction, reports_entries_interactions WHERE reports_client.id = reports_interaction.client_id AND reports_client.current_interaction_id = reports_entries_interactions.interaction_id and reports_entries_interactions.type=%s GROUP BY reports_client.id", [TYPE_MODIFIED]) - modified_client_list = Client.objects.active(timestamp).filter(id__in=[x[0] for x in cursor.fetchall()]) - - cursor.execute("SELECT reports_client.id FROM reports_client, reports_interaction, reports_entries_interactions WHERE reports_client.id = reports_interaction.client_id AND reports_client.current_interaction_id = reports_entries_interactions.interaction_id and reports_entries_interactions.type=%s GROUP BY reports_client.id", [TYPE_EXTRA]) - extra_client_list = Client.objects.active(timestamp).filter(id__in=[x[0] for x in cursor.fetchall()]) - - if timestamp == 'now': - timestamp = datetime.now().isoformat('@') - - return {'client_list': client_list, - 'client_interaction_dict':client_interaction_dict, - 'clean_client_list': clean_client_list, - 'bad_client_list': bad_client_list, - 'extra_client_list': extra_client_list, - 'modified_client_list': modified_client_list, - 'stale_up_client_list': stale_up_client_list, - 'stale_all_client_list': stale_all_client_list, - 'down_client_list': down_client_list, - 'timestamp' : timestamp, - 'timestamp_date' : timestamp[:10], - 'timestamp_time' : timestamp[11:19]} diff --git a/src/lib/Server/Reports/settings.py b/src/lib/Server/Reports/settings.py index 59d29114d..81220c0e3 100644 --- a/src/lib/Server/Reports/settings.py +++ b/src/lib/Server/Reports/settings.py @@ -1,3 +1,5 @@ +import django + # Django settings for bcfg2 reports project. from ConfigParser import ConfigParser, NoSectionError, NoOptionError c = ConfigParser() @@ -62,7 +64,9 @@ MEDIA_ROOT = '' # URL that handles the media served from MEDIA_ROOT. # Example: "http://media.lawrence.com" -MEDIA_URL = '' +MEDIA_URL = '/site_media' +if c.has_option('statistics', 'web_prefix'): + MEDIA_URL = c.get('statistics', 'web_prefix').rstrip('/') + MEDIA_URL # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a # trailing slash. @@ -109,9 +113,26 @@ TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates". # Always use forward slashes, even on Windows. '/usr/share/python-support/python-django/django/contrib/admin/templates/', - '/usr/share/bcfg2/Reports/templates' + 'Bcfg2.Server.Reports.reports' ) +if django.VERSION[0] == 1 and django.VERSION[1] < 2: + TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.core.context_processors.auth', + 'django.core.context_processors.debug', + 'django.core.context_processors.i18n', + 'django.core.context_processors.media', + 'django.core.context_processors.request' + ) +else: + TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.contrib.auth.context_processors.auth', + 'django.core.context_processors.debug', + 'django.core.context_processors.i18n', + 'django.core.context_processors.media', + 'django.core.context_processors.request' + ) + INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', diff --git a/src/lib/Server/Reports/urls.py b/src/lib/Server/Reports/urls.py index e1326b5ea..5d298c974 100644 --- a/src/lib/Server/Reports/urls.py +++ b/src/lib/Server/Reports/urls.py @@ -1,4 +1,7 @@ from django.conf.urls.defaults import * +from django.http import HttpResponsePermanentRedirect + +handler500 = 'Bcfg2.Server.Reports.reports.views.server_error' from ConfigParser import ConfigParser, NoSectionError, NoOptionError c = ConfigParser() @@ -9,56 +12,15 @@ c.read(['/etc/bcfg2.conf', '/etc/bcfg2-web.conf']) # web_prefix_root is a workaround for the index if c.has_option('statistics', 'web_prefix'): web_prefix = c.get('statistics', 'web_prefix').lstrip('/') - web_prefix_root = web_prefix else: web_prefix = '' - web_prefix_root = '/' urlpatterns = patterns('', - # Example: - # (r'^%sBcfg2.Server.Reports/' % web_prefix, include('Bcfg2.Server.Reports.apps.foo.urls.foo')), - (r'^%s*$' % web_prefix_root,'Bcfg2.Server.Reports.reports.views.index'), - - (r'^%sclients-detailed/state/(?P\w+)/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.client_detailed_list'), - (r'^%sclients-detailed/server/(?P[\w\-\.]+)/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.client_detailed_list'), - (r'^%sclients-detailed/server/(?P[\w\-\.]+)/(?P[A-Za-z]+)/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.client_detailed_list'), - (r'^%sclients-detailed/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.client_detailed_list'), - (r'^%sclients/(?P(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.client_index'), - (r'^%sclients/(?P(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))$' % web_prefix,'Bcfg2.Server.Reports.reports.views.client_index'), - (r'^%sclients/(?P\S+)/(?P\d+)/$' % web_prefix, 'Bcfg2.Server.Reports.reports.views.client_detail'), - (r'^%sclients/(?P\S+)/manage/$' % web_prefix, 'Bcfg2.Server.Reports.reports.views.client_manage'), - (r'^%sclients/(?P\S+)/$' % web_prefix, 'Bcfg2.Server.Reports.reports.views.client_detail'), - (r'^%sclients/(?P\S+)$' % web_prefix, 'Bcfg2.Server.Reports.reports.views.client_detail'), - #hack because hostnames have periods and we still want to append slash - (r'^%sclients/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.client_index'), - (r'^%sdisplays/sys-view/(?P(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.display_sys_view'), - (r'^%sdisplays/sys-view/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.display_sys_view'), - (r'^%sdisplays/summary/(?P(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.display_summary'), - (r'^%sdisplays/summary/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.display_summary'), - (r'^%sdisplays/timing/(?P(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.display_timing'), - (r'^%sdisplays/timing/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.display_timing'), - (r'^%sdisplays/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.display_index'), - - (r'^%selements/modified/(?P\d+)/(?P(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.config_item_modified'), - (r'^%selements/modified/(?P\d+)/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.config_item_modified'), - (r'^%selements/modified/(?P(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01]\ - [0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.modified_item_index'), - (r'^%selements/modified/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.modified_item_index'), - (r'^%selements/bad/(?P\d+)/(?P(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.config_item_bad'), - (r'^%selements/bad/(?P\d+)/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.config_item_bad'), - (r'^%selements/bad/(?P(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01]\ - [0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.bad_item_index'), - (r'^%selements/bad/$' % web_prefix,'Bcfg2.Server.Reports.reports.views.bad_item_index'), + (r'^%s' % web_prefix, include('Bcfg2.Server.Reports.reports.urls')) ) - # Uncomment this for admin: - #(r'^%sadmin/' % web_prefix, include('django.contrib.admin.urls')), - - -## Uncomment this section if using authentication -#urlpatterns += patterns('', -# (r'^%slogin/$' % web_prefix, 'django.contrib.auth.views.login', -# {'template_name': 'auth/login.html'}), -# (r'^%slogout/$' % web_prefix, 'django.contrib.auth.views.logout', -# {'template_name': 'auth/logout.html'}) -# ) +urlpatterns += patterns("django.views", + url(r"media/(?P.*)$", "static.serve", { + "document_root": '/Users/tlaszlo/svn/bcfg2/reports/site_media/', + }) +) diff --git a/src/lib/Server/Reports/utils.py b/src/lib/Server/Reports/utils.py index 2ef21e446..b74f09e74 100755 --- a/src/lib/Server/Reports/utils.py +++ b/src/lib/Server/Reports/utils.py @@ -1,7 +1,13 @@ -'''Helper functions for reports''' +"""Helper functions for reports""" +from Bcfg2.Server.Reports.reports.models import TYPE_CHOICES +from django.conf.urls.defaults import * +import re + +"""List of filters provided by filteredUrls""" +filter_list = ('server', 'state') class BatchFetch(object): - '''Fetch Django objects in smaller batches to save memory''' + """Fetch Django objects in smaller batches to save memory""" def __init__(self, obj, step=10000): self.count = 0 @@ -15,8 +21,8 @@ class BatchFetch(object): return self def next(self): - '''Return the next object from our array and fetch from the - database when needed''' + """Return the next object from our array and fetch from the + database when needed""" if self.block_count + self.count - self.step == self.max: raise StopIteration if self.block_count == 0 or self.count == self.step: @@ -28,3 +34,83 @@ class BatchFetch(object): self.count += 1 return self.data[self.count - 1] +def generateUrls(fn): + """ + Parse url tuples and send to functions. + + Decorator for url generators. Handles url tuple parsing + before the actual function is called. + """ + def url_gen(*urls): + results = [] + for url_tuple in urls: + if isinstance(url_tuple, (list, tuple)): + results += fn(*url_tuple) + else: + raise ValueError("Unable to handle compiled urls") + return results + return url_gen + +@generateUrls +def paginatedUrls(pattern, view, kwargs=None, name=None): + """ + Takes a group of url tuples and adds paginated urls. + + Extends a url tuple to include paginated urls. Currently doesn't handle url() compiled + patterns. + + """ + results = [(pattern, view, kwargs, name)] + tail = '' + mtail = re.search('(/+\+?\\*?\??\$?)$', pattern) + if mtail: + tail = mtail.group(1) + pattern = pattern[:len(pattern) - len(tail)] + results += [(pattern + "/(?P\d+)" + tail, view, kwargs)] + results += [(pattern + "/(?P\d+)\|(?P\d+)" + tail, view, kwargs)] + if not kwargs: + kwargs = dict() + kwargs['page_limit'] = 0 + results += [(pattern + "/?\|(?Pall)" + tail, view, kwargs)] + return results + +@generateUrls +def filteredUrls(pattern, view, kwargs=None, name=None): + """ + Takes a url and adds filtered urls. + + Extends a url tuple to include filtered view urls. Currently doesn't + handle url() compiled patterns. + """ + results = [(pattern, view, kwargs, name)] + tail = '' + mtail = re.search('(/+\+?\\*?\??\$?)$', pattern) + if mtail: + tail = mtail.group(1) + pattern = pattern[:len(pattern) - len(tail)] + for filter in ('/state/(?P\w+)', + '/server/(?P[\w\-\.]+)', + '/server/(?P[\w\-\.]+)/(?P[A-Za-z]+)'): + results += [(pattern + filter + tail, view, kwargs)] + return results + +@generateUrls +def timeviewUrls(pattern, view, kwargs=None, name=None): + """ + Takes a url and adds timeview urls + + Extends a url tuple to include filtered view urls. Currently doesn't + handle url() compiled patterns. + """ + results = [(pattern, view, kwargs, name)] + tail = '' + mtail = re.search('(/+\+?\\*?\??\$?)$', pattern) + if mtail: + tail = mtail.group(1) + pattern = pattern[:len(pattern) - len(tail)] + for filter in ('/(?P\d{4})-(?P\d{2})-(?P\d{2})/' + \ + '(?P\d\d)-(?P\d\d)', + '/(?P\d{4})-(?P\d{2})-(?P\d{2})'): + results += [(pattern + filter + tail, view, kwargs)] + return results + -- cgit v1.2.3-1-g7c22 From 0a9a99122fd2177dd41cc8e16d32008ba0f02a8a Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Thu, 14 Oct 2010 15:30:51 -0500 Subject: web reports: removing old images --- reports/site_media/img/loading.gif | Bin 729 -> 0 bytes reports/site_media/img/newcats_bkgd.gif | Bin 93 -> 0 bytes reports/site_media/img/ptr.gif | Bin 261 -> 0 bytes reports/site_media/img/round_4px_trans_gray.gif | Bin 463 -> 0 bytes reports/site_media/img/tab_left.gif | Bin 129 -> 0 bytes reports/site_media/img/tab_right.gif | Bin 491 -> 0 bytes 6 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 reports/site_media/img/loading.gif delete mode 100644 reports/site_media/img/newcats_bkgd.gif delete mode 100644 reports/site_media/img/ptr.gif delete mode 100644 reports/site_media/img/round_4px_trans_gray.gif delete mode 100644 reports/site_media/img/tab_left.gif delete mode 100644 reports/site_media/img/tab_right.gif diff --git a/reports/site_media/img/loading.gif b/reports/site_media/img/loading.gif deleted file mode 100644 index 6a56815b2..000000000 Binary files a/reports/site_media/img/loading.gif and /dev/null differ diff --git a/reports/site_media/img/newcats_bkgd.gif b/reports/site_media/img/newcats_bkgd.gif deleted file mode 100644 index f5a9585c6..000000000 Binary files a/reports/site_media/img/newcats_bkgd.gif and /dev/null differ diff --git a/reports/site_media/img/ptr.gif b/reports/site_media/img/ptr.gif deleted file mode 100644 index f3a14a102..000000000 Binary files a/reports/site_media/img/ptr.gif and /dev/null differ diff --git a/reports/site_media/img/round_4px_trans_gray.gif b/reports/site_media/img/round_4px_trans_gray.gif deleted file mode 100644 index f313dd96b..000000000 Binary files a/reports/site_media/img/round_4px_trans_gray.gif and /dev/null differ diff --git a/reports/site_media/img/tab_left.gif b/reports/site_media/img/tab_left.gif deleted file mode 100644 index 9bb2fb041..000000000 Binary files a/reports/site_media/img/tab_left.gif and /dev/null differ diff --git a/reports/site_media/img/tab_right.gif b/reports/site_media/img/tab_right.gif deleted file mode 100644 index 67b8076c5..000000000 Binary files a/reports/site_media/img/tab_right.gif and /dev/null differ -- cgit v1.2.3-1-g7c22 From ec6125bb25e7c8f24527b83c6f88d55c8a2f1a78 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Thu, 14 Oct 2010 15:56:20 -0500 Subject: web reports: tweaks and updates --- reports/site_media/bcfg2_logo.png | Bin 0 -> 27109 bytes src/lib/Server/Reports/reports/views.py | 42 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 21 deletions(-) create mode 100644 reports/site_media/bcfg2_logo.png diff --git a/reports/site_media/bcfg2_logo.png b/reports/site_media/bcfg2_logo.png new file mode 100644 index 000000000..aeb3b7f5f Binary files /dev/null and b/reports/site_media/bcfg2_logo.png differ diff --git a/src/lib/Server/Reports/reports/views.py b/src/lib/Server/Reports/reports/views.py index 64617ce70..a061a3964 100644 --- a/src/lib/Server/Reports/reports/views.py +++ b/src/lib/Server/Reports/reports/views.py @@ -182,24 +182,24 @@ def client_manage(request): message = '' if request.method == 'POST': try: - client_name = request.POST.get('client_name', None) - client_action = request.POST.get('client_action', None) - client = Client.objects.get(name=client_name) - if client_action == 'expire': - client.expiration = datetime.now(); - client.save() - message = "Expiration for %s set to %s." % \ - (client_name, client.expiration.strftime("%Y-%m-%d %H:%M:%S")) - elif client_action == 'unexpire': - client.expiration = None; - client.save() - message = "%s is now active." % client_name - else: - message = "Missing action" - except Client.DoesNotExist: - if not client_name: - client_name = "" - message = "Couldn't find client \"%s\"" % client_name + client_name = request.POST.get('client_name', None) + client_action = request.POST.get('client_action', None) + client = Client.objects.get(name=client_name) + if client_action == 'expire': + client.expiration = datetime.now(); + client.save() + message = "Expiration for %s set to %s." % \ + (client_name, client.expiration.strftime("%Y-%m-%d %H:%M:%S")) + elif client_action == 'unexpire': + client.expiration = None; + client.save() + message = "%s is now active." % client_name + else: + message = "Missing action" + except Client.DoesNotExist: + if not client_name: + client_name = "" + message = "Couldn't find client \"%s\"" % client_name return render_to_response('clients/manage.html', {'clients': Client.objects.order_by('name').all(), 'message': message}, @@ -222,10 +222,10 @@ def display_summary(request, timestamp=None): collected_data['stale'].append(node) # If stale check for uptime try: - if node.client.pings.latest().status == 'N': - collected_data['pings'].append(node) - except Ping.DoesNotExist: + if node.client.pings.latest().status == 'N': collected_data['pings'].append(node) + except Ping.DoesNotExist: + collected_data['pings'].append(node) continue if node.bad_entry_count() > 0: collected_data['bad'].append(node) -- cgit v1.2.3-1-g7c22 From 619cada8e315f58e1579c4173e98faa02eee1785 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Thu, 14 Oct 2010 16:43:42 -0500 Subject: web reports: fix quotes in base-timeview.html --- src/lib/Server/Reports/reports/templates/base-timeview.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Server/Reports/reports/templates/base-timeview.html b/src/lib/Server/Reports/reports/templates/base-timeview.html index d0617cde7..842de36f0 100644 --- a/src/lib/Server/Reports/reports/templates/base-timeview.html +++ b/src/lib/Server/Reports/reports/templates/base-timeview.html @@ -6,7 +6,7 @@ function showCalendar() { var cal = new CalendarPopup("calendar_div"); cal.showYearNavigation(); cal.select(document.forms['cal_form'].cal_date,'cal_link', - 'yyyy/MM/dd' {% if timestamp %}, '{{ timestamp|date:'Y/m/d' }}'{% endif %} ); + 'yyyy/MM/dd' {% if timestamp %}, '{{ timestamp|date:"Y/m/d" }}'{% endif %} ); return false; } function bcfg2_check_date() { -- cgit v1.2.3-1-g7c22 From 0992dd9de133e3326dba08461a4c316ac4abbcdf Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 14 Oct 2010 17:40:24 -0500 Subject: Keep interpreter specifications consistent Signed-off-by: Sol Jerome --- src/lib/Client/Tools/rpmtools.py | 2 +- src/sbin/bcfg2-info | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/Client/Tools/rpmtools.py b/src/lib/Client/Tools/rpmtools.py index e224a3fb3..3cd2b7014 100755 --- a/src/lib/Client/Tools/rpmtools.py +++ b/src/lib/Client/Tools/rpmtools.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python """ Module that uses rpm-python to implement the following rpm functionality for the bcfg2 RPM and YUM client drivers: diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info index 9721122f3..497c39174 100755 --- a/src/sbin/bcfg2-info +++ b/src/sbin/bcfg2-info @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python """This tool loads the Bcfg2 core into an interactive debugger.""" __revision__ = '$Revision$' -- cgit v1.2.3-1-g7c22 From e11b587f3e7327b4ce22bef0c71c734fccffae59 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 14 Oct 2010 17:53:48 -0500 Subject: reports: Point to the bcfg2.org URLs Signed-off-by: Sol Jerome --- src/lib/Server/Reports/reports/templates/base.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/Server/Reports/reports/templates/base.html b/src/lib/Server/Reports/reports/templates/base.html index 64c105e34..7a36c9893 100644 --- a/src/lib/Server/Reports/reports/templates/base.html +++ b/src/lib/Server/Reports/reports/templates/base.html @@ -22,7 +22,7 @@ @@ -77,8 +77,8 @@ {% endcomment %} {% endblock %}
-- cgit v1.2.3-1-g7c22 From 27ab33cbf8c68ef47416db3998b6df6408f1889e Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 14 Oct 2010 19:09:11 -0500 Subject: reports: Remove svn merge conflicts Signed-off-by: Sol Jerome --- src/lib/Server/Reports/reports/models.py.orig | 330 -------------------------- src/lib/Server/Reports/reports/models.py.rej | 15 -- 2 files changed, 345 deletions(-) delete mode 100644 src/lib/Server/Reports/reports/models.py.orig delete mode 100644 src/lib/Server/Reports/reports/models.py.rej diff --git a/src/lib/Server/Reports/reports/models.py.orig b/src/lib/Server/Reports/reports/models.py.orig deleted file mode 100644 index 5468420f6..000000000 --- a/src/lib/Server/Reports/reports/models.py.orig +++ /dev/null @@ -1,330 +0,0 @@ -"""Django models for Bcfg2 reports.""" -from django.db import models -from django.db import connection, transaction -from django.db.models import Q -from datetime import datetime, timedelta -from time import strptime - -KIND_CHOICES = ( - #These are the kinds of config elements - ('Package', 'Package'), - ('Path', 'directory'), - ('Path', 'file'), - ('Path', 'permissions'), - ('Path', 'symlink'), - ('Service', 'Service'), -) -PING_CHOICES = ( - #These are possible ping states - ('Up (Y)', 'Y'), - ('Down (N)', 'N') -) -TYPE_BAD = 1 -TYPE_MODIFIED = 2 -TYPE_EXTRA = 3 - -TYPE_CHOICES = ( - (TYPE_BAD, 'Bad'), - (TYPE_MODIFIED, 'Modified'), - (TYPE_EXTRA, 'Extra'), -) -class ClientManager(models.Manager): - """Extended client manager functions.""" - def active(self, timestamp='now'): - '''returns a set of clients that have been created and have not yet been - expired as of optional timestmamp argument. Timestamp should be a - string formatted in the fashion: 2006-01-01 00:00:00''' - - if timestamp == 'now': - timestamp = datetime.now() - else: - print timestamp - try: - timestamp = datetime(*strptime(timestamp, "%Y-%m-%d %H:%M:%S")[0:6]) - except ValueError: - return self.filter(expiration__lt=timestamp, creation__gt=timestamp); - ''' - - this is a really hacky way to return an empty QuerySet - - this should return Client.objects.none() in Django - development version. - ''' - - return self.filter(Q(expiration__gt=timestamp) | Q(expiration__isnull=True), - creation__lt=timestamp) - - -class Client(models.Model): - """Object representing every client we have seen stats for.""" - creation = models.DateTimeField(auto_now_add=True) - name = models.CharField(max_length=128,) - current_interaction = models.ForeignKey('Interaction', - null=True, blank=True, - related_name="parent_client") - expiration = models.DateTimeField(blank=True, null=True) - - def __str__(self): - return self.name - - objects = ClientManager() - - class Admin: - pass - -class Ping(models.Model): - """Represents a ping of a client (sparsely).""" - client = models.ForeignKey(Client, related_name="pings") - starttime = models.DateTimeField() - endtime = models.DateTimeField() - status = models.CharField(max_length=4, choices=PING_CHOICES)#up/down - - class Meta: - get_latest_by = 'endtime' - -class InteractiveManager(models.Manager): - """Manages interactions objects. - - Returns most recent interaction as of specified timestamp in format: - '2006-01-01 00:00:00' or 'now' or None->'now' - - """ - def interaction_per_client(self, maxdate = None): - """Returns the most recent interactions for clients as of a date. - FIXME - check the dates passed in. - - """ - from django.db import connection - cursor = connection.cursor() - - sql = 'select reports_interaction.id, x.client_id from (select client_id, MAX(timestamp) ' + \ - 'as timer from reports_interaction' - if maxdate != 'now': - sql = sql + " where timestamp < '%s' " % maxdate - sql = sql + ' GROUP BY client_id) x, reports_interaction where ' + \ - 'reports_interaction.client_id = x.client_id AND reports_interaction.timestamp = x.timer' - try: - cursor.execute(sql) - except: - '''FIXME - really need some error hadling''' - return self.none() - return self.filter(id__in = [item[0] for item in cursor.fetchall()]) - - -class Interaction(models.Model): - """Models each reconfiguration operation interaction between client and server.""" - client = models.ForeignKey(Client, related_name="interactions",) - timestamp = models.DateTimeField()#Timestamp for this record - state = models.CharField(max_length=32)#good/bad/modified/etc - repo_rev_code = models.CharField(max_length=64)#repo revision at time of interaction - client_version = models.CharField(max_length=32)#Client Version - goodcount = models.IntegerField()#of good config-items - totalcount = models.IntegerField()#of total config-items - server = models.CharField(max_length=256) # Name of the server used for the interaction - bad_entries = models.IntegerField(default=-1) - modified_entries = models.IntegerField(default=-1) - extra_entries = models.IntegerField(default=-1) - - def __str__(self): - return "With " + self.client.name + " @ " + self.timestamp.isoformat() - - def percentgood(self): - if not self.totalcount == 0: - return (self.goodcount/float(self.totalcount))*100 - else: - return 0 - - def percentbad(self): - if not self.totalcount == 0: - return ((self.totalcount-self.goodcount)/(float(self.totalcount)))*100 - else: - return 0 - - def isclean(self): - if (self.bad_entry_count() == 0 and self.goodcount == self.totalcount): - return True - else: - return False - - def isstale(self): - if (self == self.client.current_interaction):#Is Mostrecent - if(datetime.now()-self.timestamp > timedelta(hours=25) ): - return True - else: - return False - else: - #Search for subsequent Interaction for this client - #Check if it happened more than 25 hrs ago. - if (self.client.interactions.filter(timestamp__gt=self.timestamp) - .order_by('timestamp')[0].timestamp - - self.timestamp > timedelta(hours=25)): - return True - else: - return False - def save(self): - super(Interaction, self).save() #call the real save... - self.client.current_interaction = self.client.interactions.latest() - self.client.save()#save again post update - - def delete(self): - '''Override the default delete. Allows us to remove Performance items''' - pitems = list(self.performance_items.all()) - super(Interaction, self).delete() - for perf in pitems: - if perf.interaction.count() == 0: - perf.delete() - - def badcount(self): - return self.totalcount - self.goodcount - - def bad(self): - return Entries_interactions.objects.select_related().filter(interaction=self, type=TYPE_BAD) - - def bad_entry_count(self): - """Number of bad entries. Store the count in the interation field to save db queries.""" - if self.bad_entries < 0: - self.bad_entries = Entries_interactions.objects.filter(interaction=self, type=TYPE_BAD).count() - self.save() - return self.bad_entries - - def modified(self): - return Entries_interactions.objects.select_related().filter(interaction=self, type=TYPE_MODIFIED) - - def modified_entry_count(self): - """Number of modified entries. Store the count in the interation field to save db queries.""" - if self.modified_entries < 0: - self.modified_entries = Entries_interactions.objects.filter(interaction=self, type=TYPE_MODIFIED).count() - self.save() - return self.modified_entries - - def extra(self): - return Entries_interactions.objects.select_related().filter(interaction=self, type=TYPE_EXTRA) - - def extra_entry_count(self): - """Number of extra entries. Store the count in the interation field to save db queries.""" - if self.extra_entries < 0: - self.extra_entries = Entries_interactions.objects.filter(interaction=self, type=TYPE_EXTRA).count() - self.save() - return self.extra_entries - - objects = InteractiveManager() - - class Admin: - list_display = ('client', 'timestamp', 'state') - list_filter = ['client', 'timestamp'] - pass - class Meta: - get_latest_by = 'timestamp' - unique_together = ("client", "timestamp") - -class Reason(models.Model): - """reason why modified or bad entry did not verify, or changed.""" - owner = models.TextField(max_length=128, blank=True) - current_owner = models.TextField(max_length=128, blank=True) - group = models.TextField(max_length=128, blank=True) - current_group = models.TextField(max_length=128, blank=True) - perms = models.TextField(max_length=4, blank=True)#txt fixes typing issue - current_perms = models.TextField(max_length=4, blank=True) - status = models.TextField(max_length=3, blank=True)#on/off/(None) - current_status = models.TextField(max_length=1, blank=True)#on/off/(None) - to = models.TextField(max_length=256, blank=True) - current_to = models.TextField(max_length=256, blank=True) - version = models.TextField(max_length=128, blank=True) - current_version = models.TextField(max_length=128, blank=True) - current_exists = models.BooleanField()#False means its missing. Default True - current_diff = models.TextField(max_length=1280, blank=True) - is_binary = models.BooleanField(default=False) - def _str_(self): - return "Reason" - - @staticmethod - @transaction.commit_on_success - def prune_orphans(): - '''Prune oprhaned rows... no good way to use the ORM''' - cursor = connection.cursor() - cursor.execute('delete from reports_reason where not exists (select rei.id from reports_entries_interactions rei where rei.reason_id = reports_reason.id)') - transaction.set_dirty() - - -class Entries(models.Model): - """Contains all the entries feed by the client.""" - name = models.CharField(max_length=128, db_index=True) - kind = models.CharField(max_length=16, choices=KIND_CHOICES, db_index=True) - - def __str__(self): - return self.name - - @staticmethod - @transaction.commit_on_success - def prune_orphans(): - '''Prune oprhaned rows... no good way to use the ORM''' - cursor = connection.cursor() - cursor.execute('delete from reports_entries where not exists (select rei.id from reports_entries_interactions rei where rei.entry_id = reports_entries.id)') - transaction.set_dirty() - -class Entries_interactions(models.Model): - """Define the relation between the reason, the interaction and the entry.""" - entry = models.ForeignKey(Entries) - reason = models.ForeignKey(Reason) - interaction = models.ForeignKey(Interaction) - type = models.IntegerField(choices=TYPE_CHOICES) - -class PerformanceManager(models.Manager): - """ - Provides ability to effectively query for performance information - It is possible this should move to the view - - """ - #Date format for maxdate: '2006-01-01 00:00:00' - def performance_per_client(self, maxdate = None): - from django.db import connection - cursor = connection.cursor() - if (maxdate == 'now' or maxdate == None): - cursor.execute("SELECT reports_client.name, reports_performance.metric, reports_performance.value "+ - "FROM reports_performance, reports_performance_interaction, reports_client WHERE ( "+ - "reports_client.current_interaction_id = reports_performance_interaction.interaction_id AND "+ - "reports_performance.id = reports_performance_interaction.performance_id)") - else: - cursor.execute("select reports_client.name, reports_performance.metric, "+ - "reports_performance.value from (Select reports_interaction.client_id as client_id, "+ - "MAX(reports_interaction.timestamp) as timestamp from reports_interaction where "+ - "timestamp < %s GROUP BY reports_interaction.client_id) x, reports_client, "+ - "reports_interaction, reports_performance, reports_performance_interaction where "+ - "reports_client.id = x.client_id AND x.timestamp = reports_interaction.timestamp AND "+ - "x.client_id = reports_interaction.client_id AND reports_performance.id = "+ - "reports_performance_interaction.performance_id AND "+ - "reports_performance_interaction.interaction_id = reports_interaction.id", [maxdate]) - - results = {} - for row in cursor.fetchall(): - try: - results[row[0]].__setitem__(row[1], row[2]) - except KeyError: - results[row[0]] = {row[1]:row[2]} - - return results - -#performance metrics, models a performance-metric-item -class Performance(models.Model): - """Object representing performance data for any interaction.""" - interaction = models.ManyToManyField(Interaction, related_name="performance_items") - metric = models.CharField(max_length=128) - value = models.DecimalField(max_digits=32, decimal_places=16) - def __str__(self): - return self.metric - - @staticmethod - @transaction.commit_on_success - def prune_orphans(): - '''Prune oprhaned rows... no good way to use the ORM''' - cursor = connection.cursor() - cursor.execute('delete from reports_performance where not exists (select ri.id from reports_performance_interaction ri where ri.performance_id = reports_performance.id)') - transaction.set_dirty() - - objects = PerformanceManager() - -class InternalDatabaseVersion(models.Model): - """Object that tell us to witch version is the database.""" - version = models.IntegerField() - updated = models.DateTimeField(auto_now_add=True) - - def __str__(self): - return "version %d updated the %s" % (self.version, self.updated.isoformat()) diff --git a/src/lib/Server/Reports/reports/models.py.rej b/src/lib/Server/Reports/reports/models.py.rej deleted file mode 100644 index c8e1b2229..000000000 --- a/src/lib/Server/Reports/reports/models.py.rej +++ /dev/null @@ -1,15 +0,0 @@ -*************** -*** 1,6 **** - """Django models for Bcfg2 reports.""" - from django.db import models -- from django.db.models import Q - from datetime import datetime, timedelta - from time import strptime - ---- 1,6 ---- - """Django models for Bcfg2 reports.""" - from django.db import models -+ from django.db.models import Q, Max - from datetime import datetime, timedelta - from time import strptime - -- cgit v1.2.3-1-g7c22 From ab15eceee650081c4a7c2a4803a210c42f73edd8 Mon Sep 17 00:00:00 2001 From: asaf Date: Fri, 15 Oct 2010 14:27:25 +0200 Subject: Packages plugin / Client tools : add support for pacman based distros(arch, parabola), needs some more work --- src/lib/Client/Tools/Pacman.py | 81 +++++++++++++++++++++++++++ src/lib/Server/Plugins/Packages.py | 112 +++++++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 src/lib/Client/Tools/Pacman.py diff --git a/src/lib/Client/Tools/Pacman.py b/src/lib/Client/Tools/Pacman.py new file mode 100644 index 000000000..f155adfd4 --- /dev/null +++ b/src/lib/Client/Tools/Pacman.py @@ -0,0 +1,81 @@ +"""This is the bcfg2 support for pacman""" + +import Bcfg2.Client.Tools +import Bcfg2.Options +import Bcfg2.Client.Tools + +class Pacman(Bcfg2.Client.Tools.PkgTool): + '''Archlinux package support''' + name = 'Pacman' + __execs__ = ["/usr/bin/pacman"] + __handles__ = [('Package', 'txz')] + __req__ = {'Package': ['name', 'version']} + pkgtype = 'pacman' + pkgtool = ("/usr/bin/pacman --needed --noconfirm --noprogressbar -S %s") + + def __init__(self, logger, setup, config): + Bcfg2.Client.Tools.PkgTool.__init__(self, logger, setup, config) + self.installed = {} + self.RefreshPackages() + + def RefreshPackages(self): + '''Refresh memory hashes of packages''' + pkgcache = self.cmd.run("/usr/bin/pacman -Q")[1] + self.installed = {} + for pkg in pkgcache: + pkgname = pkg.split(' ')[0].strip() + version = pkg.split(' ')[1].strip() + #self.logger.info(" pkgname: %s, version: %s" % (pkgname, version)) + self.installed[pkgname] = version + + def VerifyPackage(self, entry, modlist): + '''Verify Package status for entry''' + if not 'version' in entry.attrib: + self.logger.info("Cannot verify unversioned package %s" % + (entry.attrib['name'])) + return False + + if entry.attrib['name'] in self.installed: + if self.installed[entry.attrib['name']] == entry.attrib['version']: + #if not self.setup['quick'] and \ + # entry.get('verify', 'true') == 'true': + #FIXME: We should be able to check this once + # http://trac.macports.org/ticket/15709 is implemented + return True + else: + entry.set('current_version', self.installed[entry.get('name')]) + self.logger.info("attribname: %s" % (entry.attrib['name'])) + self.logger.info("attribname: %s" % (entry.attrib['name'])) + return False + entry.set('current_exists', 'false') + self.logger.info("attribname: %s" % (entry.attrib['name'])) + return False + + def RemovePackages(self, packages): + '''Remove extra packages''' + names = [pkg.get('name') for pkg in packages] + self.logger.info("Removing packages: %s" % " ".join(names)) + self.cmd.run("/usr/bin/pacman --noconfirm --noprogressbar -R %s" % \ + " ".join(names)) + self.RefreshPackages() + self.extra = self.FindExtraPackages() + + def Install(self, packages, states): + ''' + Pacman Install + ''' + pkgline = "" + for pkg in packages: + pkgline += " " + pkg.get('name') + + print "packages : " + pkgline + + try: + self.logger.debug('Running Pacman.Install()') + print "AAAAA" + s = self.cmd.run("%s install" % self.pkgtool) + print "BBB: " + str(s) + except Exception as ex: + print "error in cmd.run ", ex + + self.logger.debug('Running Pacman.Install()') diff --git a/src/lib/Server/Plugins/Packages.py b/src/lib/Server/Plugins/Packages.py index b83b7444f..b24cd48da 100644 --- a/src/lib/Server/Plugins/Packages.py +++ b/src/lib/Server/Plugins/Packages.py @@ -1,6 +1,7 @@ import cPickle import copy import gzip +import tarfile import glob import logging import lxml.etree @@ -467,6 +468,114 @@ class APTSource(Source): pkg not in self.blacklist and \ (len(self.whitelist) == 0 or pkg in self.whitelist) +class PACSource(Source): + basegroups = ['arch', 'parabola'] + ptype = 'txz' + + def __init__(self, basepath, url, version, arches, components, groups, + rawurl, blacklist, whitelist, recommended): + Source.__init__(self, basepath, url, version, arches, components, groups, + rawurl, blacklist, whitelist, recommended) + self.pkgnames = set() + + self.url_map = [{'rawurl': self.rawurl, 'url': self.url, 'version': self.version, \ + 'components': self.components, 'arches': self.arches, 'groups': self.groups}] + + def save_state(self): + cache = file(self.cachefile, 'wb') + cPickle.dump((self.pkgnames, self.deps, self.provides), + cache, 2) + cache.close() + + def load_state(self): + data = file(self.cachefile) + self.pkgnames, self.deps, self.provides = cPickle.load(data) + + def filter_unknown(self, unknown): + filtered = set([u for u in unknown if u.startswith('choice')]) + unknown.difference_update(filtered) + + def get_urls(self): + if not self.rawurl: + return ["%s/%s/os/%s/%s.db.tar.gz" % \ + (self.url, part, arch, part) for part in self.components \ + for arch in self.arches] + else: + raise Exception("PACSource : RAWUrl not supported (yet)") + urls = property(get_urls) + + + def read_files(self): + bdeps = dict() + bprov = dict() + + if self.recommended: + depfnames = ['Depends', 'Pre-Depends', 'Recommends'] + else: + depfnames = ['Depends', 'Pre-Depends'] + + for fname in self.files: + if not self.rawurl: + barch = [x for x in fname.split('@') if x in self.arches][0] + else: + # RawURL entries assume that they only have one + # element and that it is the architecture of the source. + barch = self.arches[0] + + if barch not in bdeps: + bdeps[barch] = dict() + bprov[barch] = dict() + try: + print "try to read : " + fname + tar = tarfile.open(fname, "r") + reader = gzip.GzipFile(fname) + except: + print("Failed to read file %s" % fname) + raise + + for tarinfo in tar: + if tarinfo.isdir(): + self.pkgnames.add(tarinfo.name.rsplit("-",2)[0]) + print "added : " + tarinfo.name.rsplit("-",2)[0] + tar.close() + + self.deps['global'] = dict() + self.provides['global'] = dict() + for barch in bdeps: + self.deps[barch] = dict() + self.provides[barch] = dict() + for pkgname in self.pkgnames: + pset = set() + for barch in bdeps: + if pkgname not in bdeps[barch]: + bdeps[barch][pkgname] = [] + pset.add(tuple(bdeps[barch][pkgname])) + if len(pset) == 1: + self.deps['global'][pkgname] = pset.pop() + else: + for barch in bdeps: + self.deps[barch][pkgname] = bdeps[barch][pkgname] + provided = set() + for bprovided in bprov.values(): + provided.update(set(bprovided)) + for prov in provided: + prset = set() + for barch in bprov: + if prov not in bprov[barch]: + continue + prset.add(tuple(bprov[barch].get(prov, ()))) + if len(prset) == 1: + self.provides['global'][prov] = prset.pop() + else: + for barch in bprov: + self.provides[barch][prov] = bprov[barch].get(prov, ()) + self.save_state() + + def is_package(self, _, pkg): + return pkg in self.pkgnames and \ + pkg not in self.blacklist and \ + (len(self.whitelist) == 0 or pkg in self.whitelist) + class Packages(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.StructureValidator, Bcfg2.Server.Plugin.Generator, @@ -742,6 +851,9 @@ class Packages(Bcfg2.Server.Plugin.Plugin, self.sources.append(APTSource(self.cachepath, **source_from_xml(s))) for s in xdata.findall('.//YUMSource'): self.sources.append(YUMSource(self.cachepath, **source_from_xml(s))) + for s in xdata.findall('.//PACSource'): + self.sources.append(PACSource(self.cachepath, **source_from_xml(s))) + cachefiles = [] for source in self.sources: cachefiles.append(source.cachefile) -- cgit v1.2.3-1-g7c22 From c85bd9581d6232e30c54b715fdfe2a75271a35d2 Mon Sep 17 00:00:00 2001 From: Asaf Date: Sun, 17 Oct 2010 07:44:56 +0200 Subject: changed package type to 'pacman', if request package version is 'auto' and its installed dont re-install --- src/lib/Client/Tools/Pacman.py | 21 +++++++++++++-------- src/lib/Server/Plugins/Packages.py | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/lib/Client/Tools/Pacman.py b/src/lib/Client/Tools/Pacman.py index f155adfd4..a9edc4d65 100644 --- a/src/lib/Client/Tools/Pacman.py +++ b/src/lib/Client/Tools/Pacman.py @@ -8,10 +8,10 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): '''Archlinux package support''' name = 'Pacman' __execs__ = ["/usr/bin/pacman"] - __handles__ = [('Package', 'txz')] + __handles__ = [('Package', 'pacman')] __req__ = {'Package': ['name', 'version']} pkgtype = 'pacman' - pkgtool = ("/usr/bin/pacman --needed --noconfirm --noprogressbar -S %s") + pkgtool = ("/usr/bin/pacman --needed --noconfirm --noprogressbar") def __init__(self, logger, setup, config): Bcfg2.Client.Tools.PkgTool.__init__(self, logger, setup, config) @@ -30,13 +30,18 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): def VerifyPackage(self, entry, modlist): '''Verify Package status for entry''' + + print "VerifyPackage : " + entry.get('name')+ " : " + entry.get('version') + if not 'version' in entry.attrib: self.logger.info("Cannot verify unversioned package %s" % (entry.attrib['name'])) return False if entry.attrib['name'] in self.installed: - if self.installed[entry.attrib['name']] == entry.attrib['version']: + if entry.attrib['version'] == 'auto': + return True + elif self.installed[entry.attrib['name']] == entry.attrib['version']: #if not self.setup['quick'] and \ # entry.get('verify', 'true') == 'true': #FIXME: We should be able to check this once @@ -55,8 +60,8 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): '''Remove extra packages''' names = [pkg.get('name') for pkg in packages] self.logger.info("Removing packages: %s" % " ".join(names)) - self.cmd.run("/usr/bin/pacman --noconfirm --noprogressbar -R %s" % \ - " ".join(names)) + self.cmd.run("%s --noconfirm --noprogressbar -R %s" % \ + (self.pkgtool, " ".join(names))) self.RefreshPackages() self.extra = self.FindExtraPackages() @@ -72,9 +77,9 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): try: self.logger.debug('Running Pacman.Install()') - print "AAAAA" - s = self.cmd.run("%s install" % self.pkgtool) - print "BBB: " + str(s) + print "running : %s -S %s" % (self.pkgtool, pkgline) + s = self.cmd.run("%s -S %s" % (self.pkgtool, pkgline)) + print "pacman : " + str(s) except Exception as ex: print "error in cmd.run ", ex diff --git a/src/lib/Server/Plugins/Packages.py b/src/lib/Server/Plugins/Packages.py index b24cd48da..194330723 100644 --- a/src/lib/Server/Plugins/Packages.py +++ b/src/lib/Server/Plugins/Packages.py @@ -470,7 +470,7 @@ class APTSource(Source): class PACSource(Source): basegroups = ['arch', 'parabola'] - ptype = 'txz' + ptype = 'pacman' def __init__(self, basepath, url, version, arches, components, groups, rawurl, blacklist, whitelist, recommended): -- cgit v1.2.3-1-g7c22 From 6b9c663a568dbde04b738bd33a9f30afc6048938 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Sun, 17 Oct 2010 20:43:16 -0500 Subject: Client Tools: Pylint/PEP8 fixes Signed-off-by: Sol Jerome --- src/lib/Client/Tools/Action.py | 23 ++++++--- src/lib/Client/Tools/Blast.py | 5 +- src/lib/Client/Tools/Chkconfig.py | 8 ++- src/lib/Client/Tools/DebInit.py | 10 ++-- src/lib/Client/Tools/FreeBSDInit.py | 1 + src/lib/Client/Tools/FreeBSDPackage.py | 3 +- src/lib/Client/Tools/IPS.py | 5 +- src/lib/Client/Tools/MacPorts.py | 1 + src/lib/Client/Tools/POSIX.py | 13 +++-- src/lib/Client/Tools/Portage.py | 8 +-- src/lib/Client/Tools/RcUpdate.py | 4 +- src/lib/Client/Tools/SMF.py | 17 ++++--- src/lib/Client/Tools/SYSV.py | 6 ++- src/lib/Client/Tools/YUMng.py | 89 +++++++++++++++++++--------------- src/lib/Client/Tools/launchd.py | 18 ++++--- 15 files changed, 133 insertions(+), 78 deletions(-) diff --git a/src/lib/Client/Tools/Action.py b/src/lib/Client/Tools/Action.py index 3610d9015..452788f94 100644 --- a/src/lib/Client/Tools/Action.py +++ b/src/lib/Client/Tools/Action.py @@ -3,23 +3,34 @@ __revision__ = '$Revision$' import Bcfg2.Client.Tools -# -# -# => +""" + + + => +""" + class Action(Bcfg2.Client.Tools.Tool): """Implement Actions""" name = 'Action' __handles__ = [('PostInstall', None), ('Action', None)] __req__ = {'PostInstall': ['name'], - 'Action':['name', 'timing', 'when', 'command', 'status']} + 'Action': ['name', 'timing', 'when', 'command', 'status']} def RunAction(self, entry): """This method handles command execution and status return.""" if not self.setup['dryrun']: if self.setup['interactive']: - prompt = 'Run Action %s, %s: (y/N): ' % (entry.get('name'), entry.get('command')) + prompt = ('Run Action %s, %s: (y/N): ' % + (entry.get('name'), entry.get('command'))) if raw_input(prompt) not in ['y', 'Y']: return False if self.setup['servicemode'] == 'build': diff --git a/src/lib/Client/Tools/Blast.py b/src/lib/Client/Tools/Blast.py index 737c6924e..4f2891fd6 100644 --- a/src/lib/Client/Tools/Blast.py +++ b/src/lib/Client/Tools/Blast.py @@ -2,7 +2,9 @@ """This provides bcfg2 support for blastwave""" __revision__ = '$Revision$' -import Bcfg2.Client.Tools.SYSV, tempfile +import tempfile +import Bcfg2.Client.Tools.SYSV + class Blast(Bcfg2.Client.Tools.SYSV.SYSV): """Support for Blastwave packages""" @@ -27,7 +29,6 @@ class Blast(Bcfg2.Client.Tools.SYSV.SYSV): # Install comes from Bcfg2.Client.Tools.PkgTool # Extra comes from Bcfg2.Client.Tools.Tool # Remove comes from Bcfg2.Client.Tools.SYSV - def FindExtraPackages(self): """Pass through to null FindExtra call.""" return [] diff --git a/src/lib/Client/Tools/Chkconfig.py b/src/lib/Client/Tools/Chkconfig.py index 5dbb7b345..b7227ec3d 100644 --- a/src/lib/Client/Tools/Chkconfig.py +++ b/src/lib/Client/Tools/Chkconfig.py @@ -81,7 +81,9 @@ class Chkconfig(Bcfg2.Client.Tools.SvcTool): self.logger.info("Installing Service %s" % (entry.get('name'))) pass1 = True if entry.get('status') == 'off': - rc = self.cmd.run(rcmd % (entry.get('name'), entry.get('status')) + " --level 0123456")[0] + rc = self.cmd.run(rcmd % (entry.get('name'), + entry.get('status')) + \ + " --level 0123456")[0] pass1 = rc == 0 rc = self.cmd.run(rcmd % (entry.get('name'), entry.get('status')))[0] return pass1 and rc == 0 @@ -93,5 +95,7 @@ class Chkconfig(Bcfg2.Client.Tools.SvcTool): self.logger.debug('Found active services:') self.logger.debug(allsrv) specified = [srv.get('name') for srv in self.getSupportedEntries()] - return [Bcfg2.Client.XML.Element('Service', type='chkconfig', name=name) \ + return [Bcfg2.Client.XML.Element('Service', + type='chkconfig', + name=name) \ for name in allsrv if name not in specified] diff --git a/src/lib/Client/Tools/DebInit.py b/src/lib/Client/Tools/DebInit.py index 0185f420c..aee8ffd65 100644 --- a/src/lib/Client/Tools/DebInit.py +++ b/src/lib/Client/Tools/DebInit.py @@ -1,16 +1,18 @@ """Debian Init Support for Bcfg2""" __revision__ = '$Revision$' -import glob, os, re +import glob +import os +import re import Bcfg2.Client.Tools - # Debian squeeze and beyond uses a dependecy based boot sequence DEBIAN_OLD_STYLE_BOOT_SEQUENCE = ( 'etch', '4.0', 'lenny', '5.0', '5.0.1', '5.0.2', '5.0.3', '5.0.4', '5.0.4', '5.0.5', ) + class DebInit(Bcfg2.Client.Tools.SvcTool): """Debian Service Support for Bcfg2.""" name = 'DebInit' @@ -35,7 +37,9 @@ class DebInit(Bcfg2.Client.Tools.SvcTool): start_sequence = int(entry.get('sequence')) kill_sequence = 100 - start_sequence else: - self.logger.warning("Your debian version boot sequence is dependency based \"sequence\" attribute wil be ignored.") + self.logger.warning("Your debian version boot sequence is " + "dependency based \"sequence\" attribute " + "will be ignored.") else: start_sequence = None diff --git a/src/lib/Client/Tools/FreeBSDInit.py b/src/lib/Client/Tools/FreeBSDInit.py index e597a294b..10f0f2e93 100644 --- a/src/lib/Client/Tools/FreeBSDInit.py +++ b/src/lib/Client/Tools/FreeBSDInit.py @@ -8,6 +8,7 @@ __revision__ = '$Rev$' import os import Bcfg2.Client.Tools + class FreeBSDInit(Bcfg2.Client.Tools.SvcTool): """FreeBSD service support for Bcfg2.""" name = 'FreeBSDInit' diff --git a/src/lib/Client/Tools/FreeBSDPackage.py b/src/lib/Client/Tools/FreeBSDPackage.py index 49cfa5bd2..04c05adaa 100644 --- a/src/lib/Client/Tools/FreeBSDPackage.py +++ b/src/lib/Client/Tools/FreeBSDPackage.py @@ -8,6 +8,7 @@ __revision__ = '$Rev$' import re import Bcfg2.Client.Tools + class FreeBSDPackage(Bcfg2.Client.Tools.PkgTool): """The FreeBSD toolset implements package operations and inherits the rest from Toolset.Toolset.""" @@ -24,7 +25,7 @@ class FreeBSDPackage(Bcfg2.Client.Tools.PkgTool): pattern = re.compile('(.*)-(\d.*)') for pkg in packages: if pattern.match(pkg): - name = pattern.match(pkg).group(1) + name = pattern.match(pkg).group(1) version = pattern.match(pkg).group(2) self.installed[name] = version diff --git a/src/lib/Client/Tools/IPS.py b/src/lib/Client/Tools/IPS.py index d7d84617f..9afd23143 100644 --- a/src/lib/Client/Tools/IPS.py +++ b/src/lib/Client/Tools/IPS.py @@ -1,11 +1,12 @@ """This is the Bcfg2 support for OpenSolaris packages.""" __revision__ = '$Revision$' -import Bcfg2.Client.Tools - import pkg.client.image as image import pkg.client.progress as progress +import Bcfg2.Client.Tools + + class IPS(Bcfg2.Client.Tools.PkgTool): """The IPS driver implements OpenSolaris package operations.""" name = 'IPS' diff --git a/src/lib/Client/Tools/MacPorts.py b/src/lib/Client/Tools/MacPorts.py index 70285fa3a..23b536451 100644 --- a/src/lib/Client/Tools/MacPorts.py +++ b/src/lib/Client/Tools/MacPorts.py @@ -3,6 +3,7 @@ __revision__ = '$Revision$' import Bcfg2.Client.Tools + class MacPorts(Bcfg2.Client.Tools.PkgTool): """macports package support.""" name = 'MacPorts' diff --git a/src/lib/Client/Tools/POSIX.py b/src/lib/Client/Tools/POSIX.py index 9d37b77d3..a4417297a 100644 --- a/src/lib/Client/Tools/POSIX.py +++ b/src/lib/Client/Tools/POSIX.py @@ -44,6 +44,7 @@ def calcPerms(initial, perms): tempperms |= perm return tempperms + def normUid(entry): """ This takes a user name or uid and @@ -58,6 +59,7 @@ def normUid(entry): log.error('UID normalization failed for %s' % (entry.get('name'))) return False + def normGid(entry): """ This takes a group name or gid and @@ -75,6 +77,7 @@ def normGid(entry): text_chars = "".join([chr(y) for y in range(32, 127)] + list("\n\r\t\b")) notrans = string.maketrans("", "") + def isString(strng): """Returns true if a string contains no binary chars.""" if "\0" in strng: @@ -85,6 +88,7 @@ def isString(strng): return len(strng.translate(notrans, text_chars)) == 0 + class POSIX(Bcfg2.Client.Tools.Tool): """POSIX File support code.""" name = 'POSIX' @@ -161,7 +165,8 @@ class POSIX(Bcfg2.Client.Tools.Tool): else: os.unlink(entry.get('name')) except OSError: - self.logger.info("Symlink %s cleanup failed" % (entry.get('name'))) + self.logger.info("Symlink %s cleanup failed" %\ + (entry.get('name'))) try: os.symlink(entry.get('to'), entry.get('name')) return True @@ -205,7 +210,8 @@ class POSIX(Bcfg2.Client.Tools.Tool): pruneTrue = True ex_ents = [] if entry.get('prune', 'false') == 'true' \ - and (entry.tag == 'Directory' or entry.get('type') == 'directory'): + and (entry.tag == 'Directory' or + entry.get('type') == 'directory'): # FIXME: need to verify both old and new POSIX types try: entries = ['/'.join([entry.get('name'), ent]) \ @@ -217,7 +223,8 @@ class POSIX(Bcfg2.Client.Tools.Tool): entry.get('name')) self.logger.debug(ex_ents) nqtext = entry.get('qtext', '') + '\n' - nqtext += "Directory %s contains extra entries:" % entry.get('name') + nqtext += "Directory %s contains extra entries:" % \ + entry.get('name') nqtext += ":".join(ex_ents) entry.set('qtest', nqtext) [entry.append(XML.Element('Prune', path=x)) for x in ex_ents] diff --git a/src/lib/Client/Tools/Portage.py b/src/lib/Client/Tools/Portage.py index 765e981fe..58d2aad29 100644 --- a/src/lib/Client/Tools/Portage.py +++ b/src/lib/Client/Tools/Portage.py @@ -4,9 +4,10 @@ __revision__ = '$Revision$' import re import Bcfg2.Client.Tools + class Portage(Bcfg2.Client.Tools.PkgTool): - """The Gentoo toolset implements package and service operations and inherits - the rest from Toolset.Toolset.""" + """The Gentoo toolset implements package and service operations and + inherits the rest from Toolset.Toolset.""" name = 'Portage' __execs__ = ['/usr/bin/emerge', '/usr/bin/equery'] __handles__ = [('Package', 'ebuild')] @@ -47,8 +48,7 @@ class Portage(Bcfg2.Client.Tools.PkgTool): if self.installed[entry.attrib['name']] == entry.attrib['version']: if not self.setup['quick'] and \ entry.get('verify', 'true') == 'true': - output = self.cmd.run \ - ("/usr/bin/equery check '=%s-%s' 2>&1 |grep '!!!' | awk '{print $2}'" \ + output = self.cmd.run("/usr/bin/equery check '=%s-%s' 2>&1 |grep '!!!' | awk '{print $2}'" \ % (entry.get('name'), entry.get('version')))[1] if [filename for filename in output \ if filename not in modlist]: diff --git a/src/lib/Client/Tools/RcUpdate.py b/src/lib/Client/Tools/RcUpdate.py index a91562c30..159172b78 100644 --- a/src/lib/Client/Tools/RcUpdate.py +++ b/src/lib/Client/Tools/RcUpdate.py @@ -87,5 +87,7 @@ class RcUpdate(Bcfg2.Client.Tools.SvcTool): self.logger.debug('Found active services:') self.logger.debug(allsrv) specified = [srv.get('name') for srv in self.getSupportedEntries()] - return [Bcfg2.Client.XML.Element('Service', type='rc-update', name=name) \ + return [Bcfg2.Client.XML.Element('Service', + type='rc-update', + name=name) \ for name in allsrv if name not in specified] diff --git a/src/lib/Client/Tools/SMF.py b/src/lib/Client/Tools/SMF.py index 733228d18..f0bc6bd05 100644 --- a/src/lib/Client/Tools/SMF.py +++ b/src/lib/Client/Tools/SMF.py @@ -1,15 +1,18 @@ """SMF support for Bcfg2""" __revision__ = '$Revision$' -import glob, os +import glob +import os + import Bcfg2.Client.Tools + class SMF(Bcfg2.Client.Tools.SvcTool): """Support for Solaris SMF Services.""" __handles__ = [('Service', 'smf')] __execs__ = ['/usr/sbin/svcadm', '/usr/bin/svcs'] name = 'SMF' - __req__ = {'Service':['name', 'status']} + __req__ = {'Service': ['name', 'status']} __ireq__ = {'Service': ['name', 'status', 'FMRI']} def get_svc_command(self, service, action): @@ -53,7 +56,8 @@ class SMF(Bcfg2.Client.Tools.SvcTool): (entry.get("FMRI"), ":".join(files))) return entry.get('status') == 'on' else: - self.logger.debug("No service matching %s" % (entry.get("FMRI"))) + self.logger.debug("No service matching %s" % \ + (entry.get("FMRI"))) return entry.get('status') == 'off' try: srvdata = self.cmd.run("/usr/bin/svcs -H -o STA %s" % \ @@ -79,7 +83,8 @@ class SMF(Bcfg2.Client.Tools.SvcTool): os.rename(loc, loc.replace('/S', '/DISABLED.S')) return True except OSError: - self.logger.error("Failed to rename init script %s" % (loc)) + self.logger.error("Failed to rename init script %s" % \ + (loc)) return False else: cmdrc = self.cmd.run("/usr/sbin/svcadm disable %s" % \ @@ -94,8 +99,8 @@ class SMF(Bcfg2.Client.Tools.SvcTool): os.rename(loc.replace('/S', '/DISABLED.S'), loc) cmdrc = 0 except OSError: - self.logger.debug("Failed to rename %s to %s" \ - % (loc.replace('/S', '/DISABLED.S'), loc)) + self.logger.debug("Failed to rename %s to %s" % \ + (loc.replace('/S', '/DISABLED.S'), loc)) cmdrc = 1 else: srvdata = self.cmd.run("/usr/bin/svcs -H -o STA %s" % diff --git a/src/lib/Client/Tools/SYSV.py b/src/lib/Client/Tools/SYSV.py index c2b0eb2cc..b5e1f1c59 100644 --- a/src/lib/Client/Tools/SYSV.py +++ b/src/lib/Client/Tools/SYSV.py @@ -2,7 +2,10 @@ """This provides bcfg2 support for Solaris SYSV packages.""" __revision__ = '$Revision$' -import tempfile, Bcfg2.Client.Tools, Bcfg2.Client.XML +import tempfile + +import Bcfg2.Client.Tools +import Bcfg2.Client.XML noask = ''' @@ -19,6 +22,7 @@ action=nocheck basedir=default ''' + class SYSV(Bcfg2.Client.Tools.PkgTool): """Solaris SYSV package support.""" __execs__ = ["/usr/sbin/pkgadd", "/usr/bin/pkginfo"] diff --git a/src/lib/Client/Tools/YUMng.py b/src/lib/Client/Tools/YUMng.py index 077d71508..9fc776471 100644 --- a/src/lib/Client/Tools/YUMng.py +++ b/src/lib/Client/Tools/YUMng.py @@ -4,7 +4,6 @@ __revision__ = '$Revision$' import ConfigParser import copy import os.path -import sys import yum import yum.packages import yum.rpmtrans @@ -21,6 +20,7 @@ try: except NameError: from sets import Set as set + def build_yname(pkgname, inst): """Build yum appropriate package name.""" d = {} @@ -39,6 +39,7 @@ def build_yname(pkgname, inst): d['arch'] = inst.get('arch') return d + def short_yname(nevra): d = nevra.copy() if 'version' in d: @@ -49,17 +50,19 @@ def short_yname(nevra): del d['release'] return d + def nevraString(p): if isinstance(p, yum.packages.PackageObject): return str(p) else: ret = "" - for i, j in [('epoch','%s:'), ('name','%s'), ('version','-%s'), - ('release','-%s'), ('arch','.%s')]: + for i, j in [('epoch', '%s:'), ('name', '%s'), ('version', '-%s'), + ('release', '-%s'), ('arch', '.%s')]: if i in p: ret = "%s%s" % (ret, j % p[i]) return ret + class Parser(ConfigParser.ConfigParser): def get(self, section, option, default): @@ -73,6 +76,7 @@ class Parser(ConfigParser.ConfigParser): except (ConfigParser.NoOptionError, ConfigParser.NoSectionError): return default + class RPMDisplay(yum.rpmtrans.RPMBaseCallback): """We subclass the default RPM transaction callback so that we can control Yum's verbosity and pipe it through the right logger.""" @@ -83,11 +87,11 @@ class RPMDisplay(yum.rpmtrans.RPMBaseCallback): self.state = None self.package = None - def event(self, package, action, te_current, te_total, + def event(self, package, action, te_current, te_total, ts_current, ts_total): - """ + """ @param package: A yum package object or simple string of a package name - @param action: A yum.constant transaction set state or in the obscure + @param action: A yum.constant transaction set state or in the obscure rpm repackage case it could be the string 'repackaging' @param te_current: Current number of bytes processed in the transaction element being processed @@ -114,6 +118,7 @@ class RPMDisplay(yum.rpmtrans.RPMBaseCallback): """Deal with error reporting.""" self.logger.error(msg) + class YumDisplay(yum.callbacks.ProcessTransBaseCallback): """Class to handle display of what step we are in the Yum transaction such as downloading packages, etc.""" @@ -141,10 +146,10 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): def __init__(self, logger, setup, config): self.yb = yum.YumBase() Bcfg2.Client.Tools.PkgTool.__init__(self, logger, setup, config) - self.ignores = [ entry.get('name') for struct in config \ - for entry in struct \ - if entry.tag == 'Path' and \ - entry.get('type') == 'ignore' ] + self.ignores = [entry.get('name') for struct in config \ + for entry in struct \ + if entry.tag == 'Path' and \ + entry.get('type') == 'ignore'] self.instance_status = {} self.extra_instances = [] self.modlists = {} @@ -168,7 +173,7 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): except yum.Errors.YumBaseError, e: self.logger.error("YUMng error: %s" % e) raise Bcfg2.Client.Tools.toolInstantiationError - + yup = self.yb.doPackageLists(pkgnarrow='updates') if hasattr(self.yb.rpmdb, 'pkglist'): yinst = self.yb.rpmdb.pkglist @@ -201,7 +206,7 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): in truth self.doInstall = CP.get(self.name, "installed_action", "install").lower() == "install" - self.doUpgrade = CP.get(self.name, + self.doUpgrade = CP.get(self.name, "version_fail_action", "upgrade").lower() == "upgrade" self.doReinst = CP.get(self.name, "verify_fail_action", "reinstall").lower() == "reinstall" @@ -254,7 +259,7 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): instance = Bcfg2.Client.XML.SubElement(entry, 'Package') for attrib in list(entry.attrib.keys()): instance.attrib[attrib] = entry.attrib[attrib] - instances = [ instance ] + instances = [instance] return instances @@ -287,18 +292,20 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): else: results = verify(po) self.verifyCache[key] = results - if not rpmUtils.arch.isMultiLibArch(): return results + if not rpmUtils.arch.isMultiLibArch(): + return results # Okay deal with a buggy yum multilib and verify packages = self.yb.rpmdb.searchNevra(name=po.name, epoch=po.epoch, ver=po.version, rel=po.release) # find all arches of pkg - if len(packages) == 1: + if len(packages) == 1: return results # No mathcing multilib packages files = set(po.returnFileEntries()) # Will be the list of common fns common = {} for p in packages: - if p != po: files = files & set(p.returnFileEntries()) + if p != po: + files = files & set(p.returnFileEntries()) for p in packages: k = (p.name, p.epoch, p.version, p.release, p.arch) self.logger.debug("Multilib Verify: comparing %s to %s" \ @@ -320,10 +327,11 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): # this fn had verify problems in all but one of the multilib # packages. That means its correct in the package that's # "on top." Therefore, this is a fake verify problem. - if fn in results: del results[fn] + if fn in results: + del results[fn] return results - + def RefreshPackages(self): """ Creates self.installed{} which is a dict of installed packages. @@ -407,12 +415,13 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): virtPkg = True self.logger.info("%s appears to be provided by:" \ % entry.get('name')) - for p in POs: self.logger.info(" %s" % p) + for p in POs: + self.logger.info(" %s" % p) for inst in instances: nevra = build_yname(entry.get('name'), inst) snevra = short_yname(nevra) - if nevra in packageCache: + if nevra in packageCache: continue # Ignore duplicate instances else: packageCache.append(nevra) @@ -436,15 +445,16 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): qtext_versions.append("I(%s)" % nevra) continue - if not pkg_checks: continue + if not pkg_checks: + continue # Check EVR if virtPkg: self.logger.debug(" Not checking version for virtual package") - _POs = [ po for po in POs ] # Make a copy + _POs = [po for po in POs] # Make a copy elif entry.get('name') == 'gpg-pubkey': - _POs = [ p for p in POs if p.version == nevra['version'] \ - and p.release == nevra['release'] ] + _POs = [p for p in POs if p.version == nevra['version'] \ + and p.release == nevra['release']] else: _POs = self.yb.rpmdb.searchNevra(**snevra) if len(_POs) == 0: @@ -452,7 +462,7 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): stat['version_fail'] = True # Just chose the first pkg for the error message self.logger.info(" Wrong version installed. "\ - "Want %s, but have %s" % (nevraString(nevra), + "Want %s, but have %s" % (nevraString(nevra), nevraString(POs[0]))) qtext_versions.append("U(%s)" % str(POs[0])) continue @@ -485,7 +495,7 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): [ig.get('name') for ig in inst.findall('Ignore')] + \ self.ignores for fn, probs in vResult.items(): - if fn in modlist: + if fn in modlist: self.logger.debug(" %s in modlist, skipping" % fn) continue if fn in ignores: @@ -499,18 +509,19 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): tmp.append((p.type, p.message)) if tmp != []: stat['verify'][fn] = tmp - + if stat['verify'] != {}: stat['verify_fail'] = True package_fail = True self.logger.debug(" Verify Problems:") for fn, probs in stat['verify'].items(): self.logger.debug(" %s" % fn) - for p in probs: self.logger.debug(" %s: %s" % p) + for p in probs: + self.logger.debug(" %s: %s" % p) if len(POs) > 0: # Is this an install only package? We just look at the first one - provides = set([ p[0] for p in POs[0].provides ] + [ POs[0].name ]) + provides = set([p[0] for p in POs[0].provides] + [POs[0].name]) install_only = len(set(self.installOnlyPkgs) & provides) > 0 else: install_only = False @@ -530,7 +541,6 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): return not package_fail - def FindExtraInstances(self, entry, POs): """ Check for installed instances that are not in the config. @@ -538,12 +548,13 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): are no Instances to remove. """ - if len(POs) == 0: return None + if len(POs) == 0: + return None name = entry.get('name') - extra_entry = Bcfg2.Client.XML.Element('Package', name=name, + extra_entry = Bcfg2.Client.XML.Element('Package', name=name, type=self.pkgtype) instances = self._buildInstances(entry) - _POs = [ p for p in POs ] # Shallow copy + _POs = [p for p in POs] # Shallow copy # Algorythm is sensitive to duplicates, check for them checked = [] @@ -565,19 +576,19 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): epoch=p.epoch, name=p.name, version=p.version, release=p.release, arch=p.arch) - if _POs == []: + if _POs == []: return None else: return extra_entry def FindExtraPackages(self): """Find extra packages.""" - packages = [ e.get('name') for e in self.getSupportedEntries() ] + packages = [e.get('name') for e in self.getSupportedEntries()] extras = [] for p in self.installed.keys(): if p not in packages: - entry = Bcfg2.Client.XML.Element('Package', name=p, + entry = Bcfg2.Client.XML.Element('Package', name=p, type=self.pkgtype) for i in self.installed[p]: inst = Bcfg2.Client.XML.SubElement(entry, 'Instance', \ @@ -608,16 +619,16 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): rel = yum.misc.keyIdToRPMVer(gpg['timestamp']) if not (ver == inst.get('version') and rel == inst.get('release')): self.logger.info("GPG key file %s does not match gpg-pubkey-%s-%s"\ - % (key_file, inst.get('version'), + % (key_file, inst.get('version'), inst.get('release'))) return False - if not yum.misc.keyInstalled(ts, gpg['keyid'], + if not yum.misc.keyInstalled(ts, gpg['keyid'], gpg['timestamp']) == 0: result = ts.pgpImportPubkey(yum.misc.procgpgkey(rawkey)) else: self.logger.debug("gpg-pubkey-%s-%s already installed"\ - % (inst.get('version'), + % (inst.get('version'), inst.get('release'))) return True diff --git a/src/lib/Client/Tools/launchd.py b/src/lib/Client/Tools/launchd.py index a8b785016..db6d94c1b 100644 --- a/src/lib/Client/Tools/launchd.py +++ b/src/lib/Client/Tools/launchd.py @@ -2,20 +2,23 @@ __revision__ = '$Revision$' import os -import Bcfg2.Client.Tools import popen2 +import Bcfg2.Client.Tools + + class launchd(Bcfg2.Client.Tools.Tool): """Support for Mac OS X launchd services.""" __handles__ = [('Service', 'launchd')] __execs__ = ['/bin/launchctl', '/usr/bin/defaults'] name = 'launchd' - __req__ = {'Service':['name', 'status']} + __req__ = {'Service': ['name', 'status']} ''' Currently requires the path to the plist to load/unload, and Name is acually a reverse-fqdn (or the label). ''' + def __init__(self, logger, setup, config): Bcfg2.Client.Tools.Tool.__init__(self, logger, setup, config) @@ -77,7 +80,6 @@ class launchd(Bcfg2.Client.Tools.Tool): return 'on' return False - def InstallService(self, entry): """Enable or disable launchd item.""" name = entry.get('name') @@ -95,18 +97,19 @@ class launchd(Bcfg2.Client.Tools.Tool): """Remove Extra launchd entries.""" pass - - def FindExtra(self): """Find Extra launchd services.""" try: - allsrv = self.cmd.run("/bin/launchctl list")[1] + allsrv = self.cmd.run("/bin/launchctl list")[1] except IndexError: allsrv = [] [allsrv.remove(svc) for svc in [entry.get("name") for entry in self.getSupportedEntries()] if svc in allsrv] - return [Bcfg2.Client.XML.Element("Service", type='launchd', name=name, status='on') for name in allsrv] + return [Bcfg2.Client.XML.Element("Service", + type='launchd', + name=name, + status='on') for name in allsrv] def BundleUpdated(self, bundle, states): """Reload launchd plist.""" @@ -126,4 +129,3 @@ class launchd(Bcfg2.Client.Tools.Tool): #only if necessary.... self.cmd.run("/bin/launchctl stop %s" % name) self.cmd.run("/bin/launchctl unload -w %s" % (self.FindPlist(entry))) - -- cgit v1.2.3-1-g7c22 From 4cbecb5c7dd792bb0da2d75e7372625d07a920d1 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Mon, 18 Oct 2010 11:11:18 -0500 Subject: web_reports: remove web_prefix, add wsgi handler --- src/lib/Server/Reports/reports.wsgi | 4 ++++ src/lib/Server/Reports/urls.py | 26 +++++++++----------------- 2 files changed, 13 insertions(+), 17 deletions(-) create mode 100644 src/lib/Server/Reports/reports.wsgi diff --git a/src/lib/Server/Reports/reports.wsgi b/src/lib/Server/Reports/reports.wsgi new file mode 100644 index 000000000..232650485 --- /dev/null +++ b/src/lib/Server/Reports/reports.wsgi @@ -0,0 +1,4 @@ +import os +os.environ['DJANGO_SETTINGS_MODULE'] = 'Bcfg2.Server.Reports.settings' +import django.core.handlers.wsgi +application = django.core.handlers.wsgi.WSGIHandler() diff --git a/src/lib/Server/Reports/urls.py b/src/lib/Server/Reports/urls.py index 5d298c974..85bad72fb 100644 --- a/src/lib/Server/Reports/urls.py +++ b/src/lib/Server/Reports/urls.py @@ -3,24 +3,16 @@ from django.http import HttpResponsePermanentRedirect handler500 = 'Bcfg2.Server.Reports.reports.views.server_error' -from ConfigParser import ConfigParser, NoSectionError, NoOptionError -c = ConfigParser() -c.read(['/etc/bcfg2.conf', '/etc/bcfg2-web.conf']) - -# web_prefix should have a trailing slash, but no leading slash -# e.g. web_prefix = bcfg2/ -# web_prefix_root is a workaround for the index -if c.has_option('statistics', 'web_prefix'): - web_prefix = c.get('statistics', 'web_prefix').lstrip('/') -else: - web_prefix = '' +#from ConfigParser import ConfigParser, NoSectionError, NoOptionError +#c = ConfigParser() +#c.read(['/etc/bcfg2.conf', '/etc/bcfg2-web.conf']) urlpatterns = patterns('', - (r'^%s' % web_prefix, include('Bcfg2.Server.Reports.reports.urls')) + (r'^', include('Bcfg2.Server.Reports.reports.urls')) ) -urlpatterns += patterns("django.views", - url(r"media/(?P.*)$", "static.serve", { - "document_root": '/Users/tlaszlo/svn/bcfg2/reports/site_media/', - }) -) +#urlpatterns += patterns("django.views", +# url(r"media/(?P.*)$", "static.serve", { +# "document_root": '/Users/tlaszlo/svn/bcfg2/reports/site_media/', +# }) +#) -- cgit v1.2.3-1-g7c22 From 1fec89ad5d79845dcd779f3686b6b89c7a3b1b21 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Mon, 18 Oct 2010 11:13:46 -0500 Subject: web_reports: remove comments --- src/lib/Server/Reports/urls.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/lib/Server/Reports/urls.py b/src/lib/Server/Reports/urls.py index 85bad72fb..d7ff1eee5 100644 --- a/src/lib/Server/Reports/urls.py +++ b/src/lib/Server/Reports/urls.py @@ -3,10 +3,6 @@ from django.http import HttpResponsePermanentRedirect handler500 = 'Bcfg2.Server.Reports.reports.views.server_error' -#from ConfigParser import ConfigParser, NoSectionError, NoOptionError -#c = ConfigParser() -#c.read(['/etc/bcfg2.conf', '/etc/bcfg2-web.conf']) - urlpatterns = patterns('', (r'^', include('Bcfg2.Server.Reports.reports.urls')) ) -- cgit v1.2.3-1-g7c22 From 966aa56675a92a7bb3a7f09daded03069ee4c1e8 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Mon, 18 Oct 2010 11:34:24 -0500 Subject: web_reports: use PATH_INFO instead of path in the resolver. fixes prefix problems. --- src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py b/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py index 2c27aab04..8285915bd 100644 --- a/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py +++ b/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py @@ -18,7 +18,7 @@ def page_navigator(context): """ fragment = dict() try: - path = context['request'].path + path = context['request'].META['PATH_INFO'] total_pages = int(context['total_pages']) records_per_page = int(context['records_per_page']) except KeyError, e: @@ -96,7 +96,7 @@ def page_navigator(context): @register.inclusion_tag('widgets/filter_bar.html', takes_context=True) def filter_navigator(context): try: - path = context['request'].path + path = context['request'].META['PATH_INFO'] view, args, kwargs = resolve(path) # Strip any page limits and numbers @@ -179,7 +179,7 @@ class AddUrlFilter(template.Node): def render(self, context): link = '#' try: - path = context['request'].path + path = context['request'].META['PATH_INFO'] view, args, kwargs = resolve(path) filter_value = self.filter_value.resolve(context, True) if filter_value: -- cgit v1.2.3-1-g7c22 From 5227542b233cb445f9c242687f53a3578c0dbc47 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 18 Oct 2010 11:43:37 -0500 Subject: POSIX: Remove client-side support for old POSIX types Signed-off-by: Sol Jerome --- schemas/rules.xsd | 26 -- src/lib/Client/Frame.py | 14 - src/lib/Client/Tools/APT.py | 2 +- src/lib/Client/Tools/POSIX.py | 636 ++++++++++++++++++---------------- src/lib/Client/Tools/YUMng.py | 2 +- src/lib/Client/Tools/__init__.py | 3 +- src/lib/Server/Admin/Bundle.py | 2 +- src/lib/Server/Plugins/POSIXCompat.py | 38 -- src/lib/Server/Plugins/__init__.py | 1 - src/sbin/bcfg2-repo-validate | 41 ++- 10 files changed, 355 insertions(+), 410 deletions(-) delete mode 100644 src/lib/Server/Plugins/POSIXCompat.py diff --git a/schemas/rules.xsd b/schemas/rules.xsd index 207eb65e5..80036834a 100644 --- a/schemas/rules.xsd +++ b/schemas/rules.xsd @@ -54,14 +54,6 @@ - - - - - - - - @@ -70,11 +62,6 @@ - - - - - @@ -89,21 +76,11 @@ - - - - - - - - - - @@ -117,11 +94,8 @@ - - - diff --git a/src/lib/Client/Frame.py b/src/lib/Client/Frame.py index 6cfb19732..545d4b584 100644 --- a/src/lib/Client/Frame.py +++ b/src/lib/Client/Frame.py @@ -110,20 +110,6 @@ class Frame: self.logger.info("Loaded tool drivers:") self.logger.info([tool.name for tool in self.tools]) if not self.dryrun and not self.setup['bundle']: - for cfile in [cfl for cfl in config.findall(".//ConfigFile") \ - if cfl.get('name') in self.__important__]: - tl = [t for t in self.tools if t.handlesEntry(cfile) \ - and t.canVerify(cfile)] - if tl: - if not tl[0].VerifyConfigFile(cfile, []): - if self.setup['interactive'] and not \ - promptFilter("Install %s: %s? (y/N):", [cfile]): - continue - try: - self.states[cfile] = tl[0].InstallConfigFile(cfile) - except: - self.logger.error("Unexpected tool failure", - exc_info=1) for cfile in [cfl for cfl in config.findall(".//Path") \ if cfl.get('name') in self.__important__ and \ cfl.get('type') == 'file']: diff --git a/src/lib/Client/Tools/APT.py b/src/lib/Client/Tools/APT.py index 9dc2c5bba..2afe2eab7 100644 --- a/src/lib/Client/Tools/APT.py +++ b/src/lib/Client/Tools/APT.py @@ -55,7 +55,7 @@ class APT(Bcfg2.Client.Tools.Tool): '%s/apt/apt.conf' % etc_path, '%s/dpkg/dpkg.cfg' % etc_path] + \ [entry.get('name') for struct in config for entry in struct \ - if entry.tag in ['Path', 'ConfigFile'] and \ + if entry.tag == 'Path' and \ entry.get('name').startswith('%s/apt/sources.list' % etc_path)] self.nonexistent = [entry.get('name') for struct in config for entry in struct \ if entry.tag == 'Path' and entry.get('type') == 'nonexistent'] diff --git a/src/lib/Client/Tools/POSIX.py b/src/lib/Client/Tools/POSIX.py index a4417297a..d2611130c 100644 --- a/src/lib/Client/Tools/POSIX.py +++ b/src/lib/Client/Tools/POSIX.py @@ -1,11 +1,11 @@ """All POSIX Type client support for Bcfg2.""" __revision__ = '$Revision$' -from datetime import datetime from stat import S_ISVTX, S_ISGID, S_ISUID, S_IXUSR, S_IWUSR, S_IRUSR, S_IXGRP from stat import S_IWGRP, S_IRGRP, S_IXOTH, S_IWOTH, S_IROTH, ST_MODE, S_ISDIR from stat import S_IFREG, ST_UID, ST_GID, S_ISREG, S_IFDIR, S_ISLNK, ST_MTIME import binascii +from datetime import datetime import difflib import errno import grp @@ -14,7 +14,6 @@ import os import pwd import shutil import stat -import string import time import Bcfg2.Client.Tools import Bcfg2.Options @@ -45,21 +44,6 @@ def calcPerms(initial, perms): return tempperms -def normUid(entry): - """ - This takes a user name or uid and - returns the corresponding uid or False. - """ - try: - try: - return int(entry.get('owner')) - except: - return int(pwd.getpwnam(entry.get('owner'))[2]) - except (OSError, KeyError): - log.error('UID normalization failed for %s' % (entry.get('name'))) - return False - - def normGid(entry): """ This takes a group name or gid and @@ -74,40 +58,33 @@ def normGid(entry): log.error('GID normalization failed for %s' % (entry.get('name'))) return False -text_chars = "".join([chr(y) for y in range(32, 127)] + list("\n\r\t\b")) -notrans = string.maketrans("", "") - -def isString(strng): - """Returns true if a string contains no binary chars.""" - if "\0" in strng: +def normUid(entry): + """ + This takes a user name or uid and + returns the corresponding uid or False. + """ + try: + try: + return int(entry.get('owner')) + except: + return int(pwd.getpwnam(entry.get('owner'))[2]) + except (OSError, KeyError): + log.error('UID normalization failed for %s' % (entry.get('name'))) return False - if not strng: - return True - - return len(strng.translate(notrans, text_chars)) == 0 - class POSIX(Bcfg2.Client.Tools.Tool): """POSIX File support code.""" name = 'POSIX' - __handles__ = [('ConfigFile', None), - ('Directory', None), - ('Path', 'device'), + __handles__ = [('Path', 'device'), ('Path', 'directory'), ('Path', 'file'), ('Path', 'hardlink'), ('Path', 'nonexistent'), ('Path', 'permissions'), - ('Path', 'symlink'), - ('Permissions', None), - ('SymLink', None)] - __req__ = {'ConfigFile': ['name', 'owner', 'group', 'perms'], - 'Directory': ['name', 'owner', 'group', 'perms'], - 'Path': ['name', 'type'], - 'Permissions': ['name', 'owner', 'group', 'perms'], - 'SymLink': ['name', 'to']} + ('Path', 'symlink')] + __req__ = {'Path': ['name', 'type']} # grab paranoid options from /etc/bcfg2.conf opts = {'ppath': Bcfg2.Options.PARANOID_PATH, @@ -120,64 +97,150 @@ class POSIX(Bcfg2.Client.Tools.Tool): def canInstall(self, entry): """Check if entry is complete for installation.""" if Bcfg2.Client.Tools.Tool.canInstall(self, entry): - if (entry.tag, entry.text, entry.get('empty', 'false')) == \ - ('ConfigFile', None, 'false'): + if (entry.tag, + entry.get('type'), + entry.text, + entry.get('empty', 'false')) == ('Path', + 'file', + None, + 'false'): return False return True else: return False - def VerifySymLink(self, entry, _): - """Verify SymLink Entry.""" - try: - sloc = os.readlink(entry.get('name')) - if sloc == entry.get('to'): - return True - self.logger.debug("Symlink %s points to %s, should be %s" % \ - (entry.get('name'), sloc, entry.get('to'))) - entry.set('current_to', sloc) - entry.set('qtext', "Link %s to %s? [y/N] " % (entry.get('name'), - entry.get('to'))) + def gatherCurrentData(self, entry): + if entry.tag == 'Path' and entry.get('type') == 'file': + try: + ondisk = os.stat(entry.get('name')) + except OSError: + entry.set('current_exists', 'false') + self.logger.debug("%s %s does not exist" % + (entry.tag, entry.get('name'))) + return False + try: + entry.set('current_owner', str(ondisk[ST_UID])) + entry.set('current_group', str(ondisk[ST_GID])) + except (OSError, KeyError): + pass + entry.set('perms', str(oct(ondisk[ST_MODE])[-4:])) + try: + content = open(entry.get('name')).read() + entry.set('current_bfile', binascii.b2a_base64(content)) + except IOError, error: + self.logger.error("Failed to read %s: %s" % (error.filename, + error.strerror)) + + def Verifydevice(self, entry, _): + """Verify device entry.""" + if entry.get('dev_type') == None or \ + entry.get('owner') == None or \ + entry.get('group') == None: + self.logger.error('Entry %s not completely specified. ' + 'Try running bcfg2-repo-validate.' % (entry.get('name'))) return False + if entry.get('dev_type') in ['block', 'char']: + # check if major/minor are properly specified + if entry.get('major') == None or \ + entry.get('minor') == None: + self.logger.error('Entry %s not completely specified. ' + 'Try running bcfg2-repo-validate.' % (entry.get('name'))) + return False + try: + # check for file existence + filestat = os.stat(entry.get('name')) except OSError: entry.set('current_exists', 'false') - entry.set('qtext', "Link %s to %s? [y/N] " % (entry.get('name'), - entry.get('to'))) + self.logger.debug("%s %s does not exist" % + (entry.tag, entry.get('name'))) return False - def InstallSymLink(self, entry): - """Install SymLink entry.""" - self.logger.info("Installing Symlink %s" % (entry.get('name'))) - if os.path.lexists(entry.get('name')): - try: - fmode = os.lstat(entry.get('name'))[ST_MODE] - if S_ISREG(fmode) or S_ISLNK(fmode): - self.logger.debug("Non-directory entry already exists at " - "%s. Unlinking entry." % \ - (entry.get('name'))) - os.unlink(entry.get('name')) - elif S_ISDIR(fmode): - self.logger.debug("Directory entry already exists at %s" %\ - (entry.get('name'))) - self.cmd.run("mv %s/ %s.bak" % \ - (entry.get('name'), - entry.get('name'))) - else: - os.unlink(entry.get('name')) - except OSError: - self.logger.info("Symlink %s cleanup failed" %\ - (entry.get('name'))) try: - os.symlink(entry.get('to'), entry.get('name')) - return True + # attempt to verify device properties as specified in config + dev_type = entry.get('dev_type') + mode = calcPerms(device_map[dev_type], + entry.get('mode', '0600')) + owner = normUid(entry) + group = normGid(entry) + if dev_type in ['block', 'char']: + # check for incompletely specified entries + if entry.get('major') == None or \ + entry.get('minor') == None: + self.logger.error('Entry %s not completely specified. ' + 'Try running bcfg2-repo-validate.' % (entry.get('name'))) + return False + major = int(entry.get('major')) + minor = int(entry.get('minor')) + if major == os.major(filestat.st_rdev) and \ + minor == os.minor(filestat.st_rdev) and \ + mode == filestat.st_mode and \ + owner == filestat.st_uid and \ + group == filestat.st_gid: + return True + else: + return False + elif dev_type == 'fifo' and \ + mode == filestat.st_mode and \ + owner == filestat.st_uid and \ + group == filestat.st_gid: + return True + else: + self.logger.info('Device properties for %s incorrect' % \ + entry.get('name')) + return False except OSError: + self.logger.debug("%s %s failed to verify" % + (entry.tag, entry.get('name'))) return False - def VerifyDirectory(self, entry, modlist): - """Verify Directory entry.""" + def Installdevice(self, entry): + """Install device entries.""" + try: + # check for existing paths and remove them + os.lstat(entry.get('name')) + try: + os.unlink(entry.get('name')) + exists = False + except OSError: + self.logger.info('Failed to unlink %s' % \ + entry.get('name')) + return False + except OSError: + exists = False + + if not exists: + try: + dev_type = entry.get('dev_type') + mode = calcPerms(device_map[dev_type], + entry.get('mode', '0600')) + if dev_type in ['block', 'char']: + # check if major/minor are properly specified + if entry.get('major') == None or \ + entry.get('minor') == None: + self.logger.error('Entry %s not completely specified. ' + 'Try running bcfg2-repo-validate.' % (entry.get('name'))) + return False + major = int(entry.get('major')) + minor = int(entry.get('minor')) + device = os.makedev(major, minor) + os.mknod(entry.get('name'), mode, device) + else: + os.mknod(entry.get('name'), mode) + os.chown(entry.get('name'), normUid(entry), normGid(entry)) + return True + except KeyError: + self.logger.error('Failed to install %s' % entry.get('name')) + except OSError: + self.logger.error('Failed to install %s' % entry.get('name')) + return False + + def Verifydirectory(self, entry, modlist): + """Verify Path type='directory' entry.""" if entry.get('perms') == None or \ entry.get('owner') == None or \ entry.get('group') == None: + self.logger.error('Entry %s not completely specified. ' + 'Try running bcfg2-repo-validate.' % (entry.get('name'))) return False while len(entry.get('perms', '')) < 4: entry.set('perms', '0' + entry.get('perms', '')) @@ -210,9 +273,8 @@ class POSIX(Bcfg2.Client.Tools.Tool): pruneTrue = True ex_ents = [] if entry.get('prune', 'false') == 'true' \ - and (entry.tag == 'Directory' or - entry.get('type') == 'directory'): - # FIXME: need to verify both old and new POSIX types + and (entry.tag == 'Path' and entry.get('type') == 'directory'): + # check for any extra entries when prune='true' attribute is set try: entries = ['/'.join([entry.get('name'), ent]) \ for ent in os.listdir(entry.get('name'))] @@ -227,7 +289,8 @@ class POSIX(Bcfg2.Client.Tools.Tool): entry.get('name') nqtext += ":".join(ex_ents) entry.set('qtest', nqtext) - [entry.append(XML.Element('Prune', path=x)) for x in ex_ents] + [entry.append(XML.Element('Prune', path=x)) \ + for x in ex_ents] except OSError: ex_ents = [] pruneTrue = True @@ -243,7 +306,8 @@ class POSIX(Bcfg2.Client.Tools.Tool): entry.set('qtext', nqtext) if group != str(normGid(entry)): entry.set('current_group', group) - self.logger.debug("%s %s group wrong" % (entry.tag, entry.get('name'))) + self.logger.debug("%s %s group wrong" % \ + (entry.tag, entry.get('name'))) nqtext = entry.get('qtext', '') + '\n' nqtext += "%s group is %s should be %s" % \ (entry.get('name'), group, entry.get('group')) @@ -251,10 +315,16 @@ class POSIX(Bcfg2.Client.Tools.Tool): if perms != entry.get('perms'): entry.set('current_perms', perms) self.logger.debug("%s %s permissions are %s should be %s" % - (entry.tag, entry.get('name'), perms, entry.get('perms'))) + (entry.tag, + entry.get('name'), + perms, + entry.get('perms'))) nqtext = entry.get('qtext', '') + '\n' - nqtext += "%s perms are %s should be %s" % \ - (entry.get('name'), perms, entry.get('perms')) + nqtext += "%s %s perms are %s should be %s" % \ + (entry.tag, + entry.get('name'), + perms, + entry.get('perms')) entry.set('qtext', nqtext) if mtime != entry.get('mtime', '-1'): entry.set('current_mtime', mtime) @@ -265,21 +335,23 @@ class POSIX(Bcfg2.Client.Tools.Tool): nqtext += "%s mtime is %s should be %s" % \ (entry.get('name'), mtime, entry.get('mtime')) entry.set('qtext', nqtext) - if entry.tag != 'ConfigFile': + if entry.get('type') != 'file': nnqtext = entry.get('qtext') - nnqtext += '\nInstall %s %s: (y/N) ' % (entry.tag, entry.get('name')) + nnqtext += '\nInstall %s %s: (y/N) ' % (entry.get('type'), + entry.get('name')) entry.set('qtext', nnqtext) return pTrue and pruneTrue - def InstallDirectory(self, entry): - """Install Directory entry.""" + def Installdirectory(self, entry): + """Install Path type='directory' entry.""" if entry.get('perms') == None or \ entry.get('owner') == None or \ entry.get('group') == None: self.logger.error('Entry %s not completely specified. ' - 'Try running bcfg2-repo-validate.' % (entry.get('name'))) + 'Try running bcfg2-repo-validate.' % \ + (entry.get('name'))) return False - self.logger.info("Installing Directory %s" % (entry.get('name'))) + self.logger.info("Installing directory %s" % (entry.get('name'))) try: fmode = os.lstat(entry.get('name')) if not S_ISDIR(fmode[ST_MODE]): @@ -289,7 +361,8 @@ class POSIX(Bcfg2.Client.Tools.Tool): os.unlink(entry.get('name')) exists = False except OSError: - self.logger.info("Failed to unlink %s" % (entry.get('name'))) + self.logger.info("Failed to unlink %s" % \ + (entry.get('name'))) return False else: self.logger.debug("Found a pre-existing directory at %s" % \ @@ -334,7 +407,8 @@ class POSIX(Bcfg2.Client.Tools.Tool): pname = pent.get('path') ulfailed = False if os.path.isdir(pname): - self.logger.info("Not removing extra directory %s, please check and remove manually" % pname) + self.logger.info("Not removing extra directory %s, " + "please check and remove manually" % pname) continue try: self.logger.debug("Unlinking file %s" % pname) @@ -344,188 +418,12 @@ class POSIX(Bcfg2.Client.Tools.Tool): ulfailed = True if ulfailed: return False - return self.InstallPermissions(entry) - - def VerifyhardLink(self, entry, _): - """Verify HardLink entry.""" - try: - if os.path.samefile(entry.get('name'), entry.get('to')): - return True - self.logger.debug("Hardlink %s is incorrect" % \ - entry.get('name')) - entry.set('qtext', "Link %s to %s? [y/N] " % \ - (entry.get('name'), - entry.get('to'))) - return False - except OSError: - entry.set('current_exists', 'false') - entry.set('qtext', "Link %s to %s? [y/N] " % \ - (entry.get('name'), - entry.get('to'))) - return False - - def InstallhardLink(self, entry): - """Install HardLink entry.""" - self.logger.info("Installing Hardlink %s" % (entry.get('name'))) - if os.path.lexists(entry.get('name')): - try: - fmode = os.lstat(entry.get('name'))[ST_MODE] - if S_ISREG(fmode) or S_ISLNK(fmode): - self.logger.debug("Non-directory entry already exists at " - "%s. Unlinking entry." % (entry.get('name'))) - os.unlink(entry.get('name')) - elif S_ISDIR(fmode): - self.logger.debug("Directory entry already exists at %s" % \ - (entry.get('name'))) - self.cmd.run("mv %s/ %s.bak" % \ - (entry.get('name'), - entry.get('name'))) - else: - os.unlink(entry.get('name')) - except OSError: - self.logger.info("Hardlink %s cleanup failed" % (entry.get('name'))) - try: - os.link(entry.get('to'), entry.get('name')) - return True - except OSError: - return False - - def VerifyPermissions(self, entry, _): - """Verify Permissions entry""" - return self.VerifyDirectory(entry, _) - - def InstallPermissions(self, entry): - """Install POSIX permissions""" - if entry.get('perms') == None or \ - entry.get('owner') == None or \ - entry.get('group') == None: - self.logger.error('Entry %s not completely specified. ' - 'Try running bcfg2-repo-validate.' % (entry.get('name'))) - return False - try: - os.chown(entry.get('name'), normUid(entry), normGid(entry)) - os.chmod(entry.get('name'), calcPerms(S_IFDIR, entry.get('perms'))) - return True - except (OSError, KeyError): - self.logger.error('Permission fixup failed for %s' % \ - (entry.get('name'))) - return False - - def Verifydevice(self, entry, _): - """Verify device entry.""" - try: - # check for file existence - filestat = os.stat(entry.get('name')) - except OSError: - entry.set('current_exists', 'false') - self.logger.debug("%s %s does not exist" % - (entry.tag, entry.get('name'))) - return False - - try: - # attempt to verify device properties as specified in config - dev_type = entry.get('dev_type') - mode = calcPerms(device_map[dev_type], - entry.get('mode', '0600')) - owner = entry.get('owner') - group = entry.get('group') - if dev_type in ['block', 'char']: - major = int(entry.get('major')) - minor = int(entry.get('minor')) - if major == os.major(filestat.st_rdev) and \ - minor == os.minor(filestat.st_rdev) and \ - mode == filestat.st_mode and \ - owner == filestat.st_uid and \ - group == filestat.st_gid: - return True - else: - return False - elif dev_type == 'fifo' and \ - mode == filestat.st_mode and \ - owner == filestat.st_uid and \ - group == filestat.st_gid: - return True - else: - self.logger.info('Device properties for %s incorrect' % \ - entry.get('name')) - return False - except OSError: - self.logger.debug("%s %s failed to verify" % - (entry.tag, entry.get('name'))) - return False - - def Installdevice(self, entry): - """Install device entries.""" - try: - # check for existing paths and remove them - filestat = os.lstat(entry.get('name')) - try: - os.unlink(entry.get('name')) - exists = False - except OSError: - self.logger.info('Failed to unlink %s' % \ - entry.get('name')) - return False - except OSError: - exists = False - - if not exists: - try: - dev_type = entry.get('dev_type') - mode = calcPerms(device_map[dev_type], - entry.get('mode', '0600')) - if dev_type in ['block', 'char']: - major = int(entry.get('major')) - minor = int(entry.get('minor')) - device = os.makedev(major, minor) - os.mknod(entry.get('name'), mode, device) - else: - os.mknod(entry.get('name'), mode) - os.chown(entry.get('name'), normUid(entry), normGid(entry)) - return True - except OSError: - self.logger.error('Failed to install %s' % entry.get('name')) - return False + return self.Installpermissions(entry) - def Verifynonexistent(self, entry, _): - """Verify nonexistent entry.""" - # return true if path does _not_ exist - return not os.path.lexists(entry.get('name')) - - def Installnonexistent(self, entry): - '''Remove nonexistent entries''' - try: - os.remove(entry.get('name')) - return True - except OSError: - self.logger.error('Failed to remove %s' % entry.get('name')) - return False - - def gatherCurrentData(self, entry): - if entry.tag == 'ConfigFile': - try: - ondisk = os.stat(entry.get('name')) - except OSError: - entry.set('current_exists', 'false') - self.logger.debug("%s %s does not exist" % - (entry.tag, entry.get('name'))) - return False - try: - entry.set('current_owner', str(ondisk[ST_UID])) - entry.set('current_group', str(ondisk[ST_GID])) - except (OSError, KeyError): - pass - entry.set('perms', str(oct(ondisk[ST_MODE])[-4:])) - try: - content = open(entry.get('name')).read() - entry.set('current_bfile', binascii.b2a_base64(content)) - except IOError, error: - self.logger.error("Failed to read %s: %s" % (error.filename, error.strerror)) - - def VerifyConfigFile(self, entry, _): - """Install ConfigFile entry.""" - # configfile verify is permissions check + content check - permissionStatus = self.VerifyDirectory(entry, _) + def Verifyfile(self, entry, _): + """Verify Path type='file' entry.""" + # permissions check + content check + permissionStatus = self.Verifydirectory(entry, _) tbin = False if entry.get('encoding', 'ascii') == 'base64': tempdata = binascii.a2b_base64(entry.text) @@ -534,8 +432,8 @@ class POSIX(Bcfg2.Client.Tools.Tool): tempdata = '' else: if entry.text == None: - self.logger.error("Cannot verify incomplete ConfigFile %s" % \ - (entry.get('name'))) + self.logger.error("Cannot verify incomplete Path type='%s' %s" % \ + (entry.get('type'), entry.get('name'))) return False tempdata = entry.text if type(tempdata) == unicode: @@ -558,7 +456,12 @@ class POSIX(Bcfg2.Client.Tools.Tool): # md5sum so it would be faster for big binary files contentStatus = content == tempdata if not contentStatus: - if tbin or not isString(content): + try: + content.decode('ascii') + isstring = True + except: + isstring = False + if tbin or not isstring: entry.set('current_bfile', binascii.b2a_base64(content)) nqtext = entry.get('qtext', '') nqtext += '\nBinary file, no printable diff' @@ -567,7 +470,8 @@ class POSIX(Bcfg2.Client.Tools.Tool): rawdiff = [] start = time.time() longtime = False - for x in difflib.ndiff(content.split('\n'), tempdata.split('\n')): + for x in difflib.ndiff(content.split('\n'), + tempdata.split('\n')): now = time.time() rawdiff.append(x) if now - start > 5 and not longtime: @@ -606,9 +510,9 @@ class POSIX(Bcfg2.Client.Tools.Tool): entry.set('qtext', qtxt) return contentStatus and permissionStatus - def InstallConfigFile(self, entry): - """Install ConfigFile entry.""" - self.logger.info("Installing ConfigFile %s" % (entry.get('name'))) + def Installfile(self, entry): + """Install Path type='file' entry.""" + self.logger.info("Installing file %s" % (entry.get('name'))) parent = "/".join(entry.get('name').split('/')[:-1]) if parent: @@ -642,9 +546,9 @@ class POSIX(Bcfg2.Client.Tools.Tool): self.setup.get("paranoid", False) and not \ (entry.get('current_exists', 'true') == 'false'): bkupnam = entry.get('name').replace('/', '_') - # current list of backups for this ConfigFile + # current list of backups for this file bkuplist = [f for f in os.listdir(self.ppath) if - f.startswith(bkupnam)] + f.startswith(bkupnam)] bkuplist.sort() if len(bkuplist) == int(self.max_copies): # remove the oldest backup available @@ -663,7 +567,7 @@ class POSIX(Bcfg2.Client.Tools.Tool): self.logger.info("Backup of %s saved to %s" % (entry.get('name'), self.ppath)) except IOError, e: - self.logger.error("Failed to create backup file for ConfigFile %s" % \ + self.logger.error("Failed to create backup file for %s" % \ (entry.get('name'))) self.logger.error(e) return False @@ -694,7 +598,7 @@ class POSIX(Bcfg2.Client.Tools.Tool): os.utime(entry.get('name'), (int(entry.get('mtime')), int(entry.get('mtime')))) except: - self.logger.error("ConfigFile %s mtime fix failed" \ + self.logger.error("File %s mtime fix failed" \ % (entry.get('name'))) return False return True @@ -705,42 +609,158 @@ class POSIX(Bcfg2.Client.Tools.Tool): print(err) return False - def Verifydirectory(self, entry, _): - ret = getattr(self, 'VerifyDirectory') - return ret(entry, _) + def Verifyhardlink(self, entry, _): + """Verify HardLink entry.""" + if entry.get('to') == None: + self.logger.error('Entry %s not completely specified. ' + 'Try running bcfg2-repo-validate.' % \ + (entry.get('name'))) + return False + try: + if os.path.samefile(entry.get('name'), entry.get('to')): + return True + self.logger.debug("Hardlink %s is incorrect" % \ + entry.get('name')) + entry.set('qtext', "Link %s to %s? [y/N] " % \ + (entry.get('name'), + entry.get('to'))) + return False + except OSError: + entry.set('current_exists', 'false') + entry.set('qtext', "Link %s to %s? [y/N] " % \ + (entry.get('name'), + entry.get('to'))) + return False - def Installdirectory(self, entry): - ret = getattr(self, 'InstallDirectory') - return ret(entry) + def Installhardlink(self, entry): + """Install HardLink entry.""" + if entry.get('to') == None: + self.logger.error('Entry %s not completely specified. ' + 'Try running bcfg2-repo-validate.' % \ + (entry.get('name'))) + return False + self.logger.info("Installing Hardlink %s" % (entry.get('name'))) + if os.path.lexists(entry.get('name')): + try: + fmode = os.lstat(entry.get('name'))[ST_MODE] + if S_ISREG(fmode) or S_ISLNK(fmode): + self.logger.debug("Non-directory entry already exists at " + "%s. Unlinking entry." % (entry.get('name'))) + os.unlink(entry.get('name')) + elif S_ISDIR(fmode): + self.logger.debug("Directory already exists at %s" % \ + (entry.get('name'))) + self.cmd.run("mv %s/ %s.bak" % \ + (entry.get('name'), + entry.get('name'))) + else: + os.unlink(entry.get('name')) + except OSError: + self.logger.info("Hardlink %s cleanup failed" % \ + (entry.get('name'))) + try: + os.link(entry.get('to'), entry.get('name')) + return True + except OSError: + return False - def Verifyfile(self, entry, _): - ret = getattr(self, 'VerifyConfigFile') - return ret(entry, _) + def Verifynonexistent(self, entry, _): + """Verify nonexistent entry.""" + # return true if path does _not_ exist + return not os.path.lexists(entry.get('name')) - def Installfile(self, entry): - ret = getattr(self, 'InstallConfigFile') - return ret(entry) + def Installnonexistent(self, entry): + '''Remove nonexistent entries''' + try: + os.remove(entry.get('name')) + return True + except OSError: + self.logger.error('Failed to remove %s' % entry.get('name')) + return False def Verifypermissions(self, entry, _): - ret = getattr(self, 'VerifyPermissions') - return ret(entry, _) + """Verify Path type='permissions' entry""" + return self.Verifydirectory(entry, _) def Installpermissions(self, entry): - ret = getattr(self, 'InstallPermissions') - return ret(entry) + """Install POSIX permissions""" + if entry.get('perms') == None or \ + entry.get('owner') == None or \ + entry.get('group') == None: + self.logger.error('Entry %s not completely specified. ' + 'Try running bcfg2-repo-validate.' % (entry.get('name'))) + return False + try: + os.chown(entry.get('name'), normUid(entry), normGid(entry)) + os.chmod(entry.get('name'), calcPerms(S_IFDIR, entry.get('perms'))) + return True + except (OSError, KeyError): + self.logger.error('Permission fixup failed for %s' % \ + (entry.get('name'))) + return False def Verifysymlink(self, entry, _): - ret = getattr(self, 'VerifySymLink') - return ret(entry, _) + """Verify Path type='symlink' entry.""" + if entry.get('to') == None: + self.logger.error('Entry %s not completely specified. ' + 'Try running bcfg2-repo-validate.' % \ + (entry.get('name'))) + return False + try: + sloc = os.readlink(entry.get('name')) + if sloc == entry.get('to'): + return True + self.logger.debug("Symlink %s points to %s, should be %s" % \ + (entry.get('name'), sloc, entry.get('to'))) + entry.set('current_to', sloc) + entry.set('qtext', "Link %s to %s? [y/N] " % (entry.get('name'), + entry.get('to'))) + return False + except OSError: + entry.set('current_exists', 'false') + entry.set('qtext', "Link %s to %s? [y/N] " % (entry.get('name'), + entry.get('to'))) + return False def Installsymlink(self, entry): - ret = getattr(self, 'InstallSymLink') - return ret(entry) + """Install Path type='symlink' entry.""" + if entry.get('to') == None: + self.logger.error('Entry %s not completely specified. ' + 'Try running bcfg2-repo-validate.' % \ + (entry.get('name'))) + return False + self.logger.info("Installing symlink %s" % (entry.get('name'))) + if os.path.lexists(entry.get('name')): + try: + fmode = os.lstat(entry.get('name'))[ST_MODE] + if S_ISREG(fmode) or S_ISLNK(fmode): + self.logger.debug("Non-directory entry already exists at " + "%s. Unlinking entry." % \ + (entry.get('name'))) + os.unlink(entry.get('name')) + elif S_ISDIR(fmode): + self.logger.debug("Directory already exists at %s" %\ + (entry.get('name'))) + self.cmd.run("mv %s/ %s.bak" % \ + (entry.get('name'), + entry.get('name'))) + else: + os.unlink(entry.get('name')) + except OSError: + self.logger.info("Symlink %s cleanup failed" %\ + (entry.get('name'))) + try: + os.symlink(entry.get('to'), entry.get('name')) + return True + except OSError: + return False def InstallPath(self, entry): + """Dispatch install to the proper method according to type""" ret = getattr(self, 'Install%s' % entry.get('type')) return ret(entry) def VerifyPath(self, entry, _): + """Dispatch verify to the proper method according to type""" ret = getattr(self, 'Verify%s' % entry.get('type')) return ret(entry, _) diff --git a/src/lib/Client/Tools/YUMng.py b/src/lib/Client/Tools/YUMng.py index 9fc776471..ce8832395 100644 --- a/src/lib/Client/Tools/YUMng.py +++ b/src/lib/Client/Tools/YUMng.py @@ -157,7 +157,7 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): self.__important__ = self.__important__ + \ [entry.get('name') for struct in config \ for entry in struct \ - if entry.tag in ['Path', 'ConfigFile'] and \ + if entry.tag in == 'Path' and \ (entry.get('name').startswith('/etc/yum.d') \ or entry.get('name').startswith('/etc/yum.repos.d')) \ or entry.get('name') == '/etc/yum.conf'] diff --git a/src/lib/Client/Tools/__init__.py b/src/lib/Client/Tools/__init__.py index 1d89e6d02..8a90e130c 100644 --- a/src/lib/Client/Tools/__init__.py +++ b/src/lib/Client/Tools/__init__.py @@ -172,8 +172,7 @@ class Tool: '''Build a list of potentially modified POSIX paths for this entry''' return [entry.get('name') for struct in self.config.getchildren() \ for entry in struct.getchildren() \ - if entry.tag in ['ConfigFile', 'SymLink', 'Directory', - 'Permissions', 'Ignore', 'Path']] + if entry.tag in ['Ignore', 'Path']] def gatherCurrentData(self, entry): """Default implementation of the information gathering routines.""" diff --git a/src/lib/Server/Admin/Bundle.py b/src/lib/Server/Admin/Bundle.py index e293c6a4f..41cd5727e 100644 --- a/src/lib/Server/Admin/Bundle.py +++ b/src/lib/Server/Admin/Bundle.py @@ -91,7 +91,7 @@ class Bundle(Bcfg2.Server.Admin.MetadataCore): tree = lxml.etree.parse(bundle_list[int(lineno)]) #Prints bundle content #print lxml.etree.tostring(tree) - names = ['Action', 'ConfigFile', 'Directory', 'Package', 'Permission', 'Service', 'SymLink'] + names = ['Action', 'Package', 'Path', 'Service'] for name in names: for node in tree.findall("//" + name): print "%s:\t%s" % (name, node.attrib["name"]) diff --git a/src/lib/Server/Plugins/POSIXCompat.py b/src/lib/Server/Plugins/POSIXCompat.py deleted file mode 100644 index fc16e4b48..000000000 --- a/src/lib/Server/Plugins/POSIXCompat.py +++ /dev/null @@ -1,38 +0,0 @@ -"""This plugin provides a compatibility layer which turns new-style -POSIX entries into old-style entries. -""" - -__revision__ = '$Revision$' - -import Bcfg2.Server.Plugin - -COMPAT_DICT = {'file': 'ConfigFile', - 'directory': 'Directory', - 'permissions': 'Permissions', - 'symlink': 'SymLink'} - - -class POSIXCompat(Bcfg2.Server.Plugin.Plugin, - Bcfg2.Server.Plugin.GoalValidator): - """POSIXCompat is a goal validator plugin for POSIX entries.""" - name = 'POSIXCompat' - __version__ = '$Id$' - __author__ = 'bcfg-dev@mcs.anl.gov' - - def __init__(self, core, datastore): - Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) - Bcfg2.Server.Plugin.GoalValidator.__init__(self) - - def validate_goals(self, metadata, goals): - """Verify that we are generating correct old - Cfg/Directory/Symlink entries. - """ - for goal in goals: - for entry in goal.getchildren(): - if entry.tag == 'Path' and \ - entry.get('type') not in ['nonexistent', 'device']: - # Use new entry 'type' attribute to map old entry tags - oldentry = entry - entry.tag = COMPAT_DICT[entry.get('type')] - del entry.attrib['type'] - goal.replace(oldentry, entry) diff --git a/src/lib/Server/Plugins/__init__.py b/src/lib/Server/Plugins/__init__.py index 758f1219d..c69c37452 100644 --- a/src/lib/Server/Plugins/__init__.py +++ b/src/lib/Server/Plugins/__init__.py @@ -22,7 +22,6 @@ __all__ = [ 'Properties', 'Probes', 'Pkgmgr', - 'POSIXCompat', 'Rules', 'SSHbase', 'Snapshots', diff --git a/src/sbin/bcfg2-repo-validate b/src/sbin/bcfg2-repo-validate index 1889c9892..3d5efb093 100755 --- a/src/sbin/bcfg2-repo-validate +++ b/src/sbin/bcfg2-repo-validate @@ -88,14 +88,14 @@ if __name__ == '__main__': # (as defined in doc/server/configurationentries) # TODO: See if it is possible to do this in the schema instead required_configuration_attrs = { - 'device':['name', 'owner', 'group', 'dev_type'], - 'directory':['name', 'owner', 'group', 'perms'], - 'file':['name', 'owner', 'group', 'perms'], - 'hardlink':['name', 'to'], - 'symlink':['name', 'to'], - 'ignore':['name'], - 'nonexist':['name'], - 'permissions':['name', 'owner', 'group', 'perms']} + 'device': ['name', 'owner', 'group', 'dev_type'], + 'directory': ['name', 'owner', 'group', 'perms'], + 'file': ['name', 'owner', 'group', 'perms'], + 'hardlink': ['name', 'to'], + 'symlink': ['name', 'to'], + 'ignore': ['name'], + 'nonexist': ['name'], + 'permissions': ['name', 'owner', 'group', 'perms']} for rfile in rules_list: try: xdata = lxml.etree.parse(rfile) @@ -110,6 +110,11 @@ if __name__ == '__main__': + ['type']) except KeyError: continue + if 'dev_type' in required_attrs: + dev_type = posixpath.get('dev_type') + if dev_type in ['block', 'char']: + # check if major/minor are specified + required_attrs |= set(['major', 'minor']) if pathset.issuperset(required_attrs): continue else: @@ -146,16 +151,16 @@ if __name__ == '__main__': else: pset.add(ptuple) - filesets = {'metadata':(metadata_list, "%s/metadata.xsd"), - 'clients':(clients_list, "%s/clients.xsd"), - 'info':(info_list, "%s/info.xsd"), - 'bundle':(bundle_list, "%s/bundle.xsd"), - 'pkglist':(pkg_list, "%s/pkglist.xsd"), - 'base':(base_list, "%s/base.xsd"), - 'rules':(rules_list, "%s/rules.xsd"), - 'imageinfo':(imageinfo_list, "%s/report-configuration.xsd"), - 'services':(services_list, "%s/services.xsd"), - 'deps':(deps_list, "%s/deps.xsd"), + filesets = {'metadata': (metadata_list, "%s/metadata.xsd"), + 'clients': (clients_list, "%s/clients.xsd"), + 'info': (info_list, "%s/info.xsd"), + 'bundle': (bundle_list, "%s/bundle.xsd"), + 'pkglist': (pkg_list, "%s/pkglist.xsd"), + 'base': (base_list, "%s/base.xsd"), + 'rules': (rules_list, "%s/rules.xsd"), + 'imageinfo': (imageinfo_list, "%s/report-configuration.xsd"), + 'services': (services_list, "%s/services.xsd"), + 'deps': (deps_list, "%s/deps.xsd"), 'decisions': (dec_list, "%s/decisions.xsd"), 'packages': (pkgcfg_list, "%s/packages.xsd"), 'grouppatterns': (gp_list, "%s/grouppatterns.xsd"), -- cgit v1.2.3-1-g7c22 From 8ec06a41bf6221238c4559a14c7506148e5d40c7 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Mon, 18 Oct 2010 12:16:39 -0500 Subject: web_reports: update setup.py to include wsgi file --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a1499e474..6d5aae417 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,8 @@ setup(cmdclass=cmdclass, package_dir = {'Bcfg2':'src/lib'}, package_data = {'Bcfg2.Server.Reports.reports':['fixtures/*.xml', 'templates/*.html', 'templates/*/*.html', - 'templates/*/*.inc' ] }, + 'templates/*/*.inc' ], + 'Bcfg2.Server.Reports':['reports.wsgi'] }, scripts = glob('src/sbin/*'), data_files = [('share/bcfg2/schemas', glob('schemas/*.xsd')), -- cgit v1.2.3-1-g7c22 From d17fedf68c947c3ada40b441d32c8d3f185028f9 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Mon, 18 Oct 2010 12:40:54 -0500 Subject: web_reports: more PATH_INFO fixes --- src/lib/Server/Reports/reports/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/Server/Reports/reports/views.py b/src/lib/Server/Reports/reports/views.py index a061a3964..00d35c092 100644 --- a/src/lib/Server/Reports/reports/views.py +++ b/src/lib/Server/Reports/reports/views.py @@ -46,7 +46,7 @@ def timeview(fn): if cal_date.find(' ') > -1: fmt += " %H:%M" timestamp = datetime(*strptime(cal_date, fmt)[0:6]) - view, args, kw = resolve(request.path) + view, args, kw = resolve(request.META['PATH_INFO']) kw['year'] = "%0.4d" % timestamp.year kw['month'] = "%02.d" % timestamp.month kw['day'] = "%02.d" % timestamp.day @@ -367,7 +367,7 @@ def prepare_paginated_list(request, context, paged_list, page=1, max_results=25) if page > total_pages: # If we passed beyond the end send back try: - view, args, kwargs = resolve(request.path) + view, args, kwargs = resolve(request.META['PATH_INFO']) kwargs['page_number'] = total_pages raise PaginationError, HttpResponseRedirect( reverse(view, kwargs=kwargs) ) except (Resolver404, NoReverseMatch, ValueError): -- cgit v1.2.3-1-g7c22 From 375be7ae1b70d83c692b246f4a7eee36cfa46093 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 18 Oct 2010 12:40:58 -0500 Subject: Reports: Fix typo Signed-off-by: Sol Jerome --- src/lib/Server/Reports/reports/templates/config_items/item.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Server/Reports/reports/templates/config_items/item.html b/src/lib/Server/Reports/reports/templates/config_items/item.html index 41474922b..58aed1684 100644 --- a/src/lib/Server/Reports/reports/templates/config_items/item.html +++ b/src/lib/Server/Reports/reports/templates/config_items/item.html @@ -88,7 +88,7 @@ div.entry_list h3 {
-

Occurances on {{ timestamp|date:"Y-m-d" }}

+

Occurences on {{ timestamp|date:"Y-m-d" }}

{% if associated_list %} -- cgit v1.2.3-1-g7c22 From b6c96eabe1c2ad98897abc2a4fa24ff01af49f68 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Mon, 18 Oct 2010 13:33:51 -0500 Subject: YUMng: syntax error --- src/lib/Client/Tools/YUMng.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Client/Tools/YUMng.py b/src/lib/Client/Tools/YUMng.py index ce8832395..9cdcdca40 100644 --- a/src/lib/Client/Tools/YUMng.py +++ b/src/lib/Client/Tools/YUMng.py @@ -157,7 +157,7 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): self.__important__ = self.__important__ + \ [entry.get('name') for struct in config \ for entry in struct \ - if entry.tag in == 'Path' and \ + if entry.tag == 'Path' and \ (entry.get('name').startswith('/etc/yum.d') \ or entry.get('name').startswith('/etc/yum.repos.d')) \ or entry.get('name') == '/etc/yum.conf'] -- cgit v1.2.3-1-g7c22 From d594844a9f5ebc0f26f35d03fcf1f90de4ef2d6a Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Tue, 19 Oct 2010 11:45:53 -0500 Subject: web_reports: determine static prefix automatically --- misc/bcfg2.spec | 54 +++++++++++++++++++++- src/lib/Server/Reports/reports/templates/base.html | 16 ++++--- .../Reports/reports/templatetags/bcfg2_tags.py | 35 ++++++++++++++ 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/misc/bcfg2.spec b/misc/bcfg2.spec index 72008435a..c38e52c3b 100644 --- a/misc/bcfg2.spec +++ b/misc/bcfg2.spec @@ -13,7 +13,7 @@ %define lxmldep %(rpm -q %{alt_lxml} 2>&1 > /dev/null && echo %{alt_lxml} || echo %{dfl_lxml}) Name: bcfg2 -Version: 1.1.0 +Version: 1.2.0 Release: %{release} Summary: Configuration management system @@ -93,6 +93,39 @@ systems are constantly changing; if required in your environment, Bcfg2 can enable the construction of complex change management and deployment strategies. +%package -n bcfg2-web +Version: %{version} +Summary: Bcfg2 Web Reporting Interface +Group: System Tools +Requires: bcfg2-server +Requires: httpd,mod_wsgi,Django + +%description -n bcfg2-web +Bcfg2 helps system administrators produce a consistent, reproducible, +and verifiable description of their environment, and offers +visualization and reporting tools to aid in day-to-day administrative +tasks. It is the fifth generation of configuration management tools +developed in the Mathematics and Computer Science Division of Argonne +National Laboratory. + +It is based on an operational model in which the specification can be +used to validate and optionally change the state of clients, but in a +feature unique to bcfg2 the client's response to the specification can +also be used to assess the completeness of the specification. Using +this feature, bcfg2 provides an objective measure of how good a job an +administrator has done in specifying the configuration of client +systems. Bcfg2 is therefore built to help administrators construct an +accurate, comprehensive specification. + +Bcfg2 has been designed from the ground up to support gentle +reconciliation between the specification and current client states. It +is designed to gracefully cope with manual system modifications. + +Finally, due to the rapid pace of updates on modern networks, client +systems are constantly changing; if required in your environment, +Bcfg2 can enable the construction of complex change management and +deployment strategies. + %prep %setup -q -n bcfg2-%{version} @@ -117,6 +150,11 @@ deployment strategies. %{__install} -m 755 debian/bcfg2.cron.hourly %{buildroot}%{_sysconfdir}/cron.hourly/bcfg2 %{__install} -m 755 tools/bcfg2-cron %{buildroot}%{_prefix}/lib/bcfg2/bcfg2-cron +%if "%{_vendor}" == "redhat" +%{__install} -d %{buildroot}%{_sysconfdir}/httpd/conf.d +%{__install} -m 644 misc/apache/bcfg2.conf %{buildroot}%{_sysconfdir}/httpd/conf.d/bcfg2.conf +%endif + %clean [ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot} || exit 2 @@ -147,7 +185,10 @@ deployment strategies. %{python_sitelib}/*egg-info %endif -%{_datadir}/bcfg2 +%dir %{_datadir}/bcfg2 +%{_datadir}/bcfg2/Hostbase +%{_datadir}/bcfg2/schemas +%{_datadir}/bcfg2/xsl-transforms %config(noreplace) %{_sysconfdir}/default/bcfg2-server %{_sbindir}/bcfg2-admin %{_sbindir}/bcfg2-build-reports @@ -160,6 +201,15 @@ deployment strategies. %{_mandir}/man8/*.8* %dir %{_prefix}/lib/bcfg2 +%files -n bcfg2-web +%defattr(-,root,root,-) + +%{_datadir}/bcfg2/site_media + +%if "%{_vendor}" == "redhat" +%config(noreplace) %{_sysconfdir}/httpd/conf.d/bcfg2.conf +%endif + %changelog * Mon Jun 21 2010 Fabian Affolter - 1.1.0rc3-0.1 - Changed source0 in order that it works with spectool diff --git a/src/lib/Server/Reports/reports/templates/base.html b/src/lib/Server/Reports/reports/templates/base.html index 7a36c9893..9bd9da218 100644 --- a/src/lib/Server/Reports/reports/templates/base.html +++ b/src/lib/Server/Reports/reports/templates/base.html @@ -1,3 +1,5 @@ +{% load bcfg2_tags %} + @@ -10,19 +12,19 @@ - - - - - - + + + + + + {% block extra_header_info %}{% endblock %} diff --git a/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py b/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py index 8285915bd..7fffe289d 100644 --- a/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py +++ b/src/lib/Server/Reports/reports/templatetags/bcfg2_tags.py @@ -237,3 +237,38 @@ def sortwell(value): configItems.sort(lambda x,y: cmp(x.entry.kind, y.entry.kind)) return configItems +class MediaTag(template.Node): + def __init__(self, filter_value): + self.filter_value = filter_value + + def render(self, context): + base = context['MEDIA_URL'] + try: + request = context['request'] + try: + base = request.environ['bcfg2.media_url'] + except: + if request.path != request.META['PATH_INFO']: + offset = request.path.find(request.META['PATH_INFO']) + if offset > 0: + base = "%s/%s" % (request.path[:offset], \ + context['MEDIA_URL'].strip('/')) + except: + pass + return "%s/%s" % (base, self.filter_value) + +@register.tag +def to_media_url(parser, token): + """ + Return a url relative to the media_url. + + {% to_media_url /bcfg2.css %} + """ + try: + tag_name, filter_value = token.split_contents() + filter_value = parser.compile_filter(filter_value) + except ValueError: + raise template.TemplateSyntaxError, "%r tag requires exactly one argument" % token.contents.split()[0] + + return MediaTag(filter_value) + -- cgit v1.2.3-1-g7c22 From 2962754674bd523450aaba2451b8a837855f3655 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Tue, 19 Oct 2010 12:00:34 -0500 Subject: web_reports: updated spec to build web reports rpm --- misc/apache/bcfg2.conf | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 misc/apache/bcfg2.conf diff --git a/misc/apache/bcfg2.conf b/misc/apache/bcfg2.conf new file mode 100644 index 000000000..2963091ec --- /dev/null +++ b/misc/apache/bcfg2.conf @@ -0,0 +1,28 @@ +LoadModule wsgi_module modules/mod_wsgi.so + + + # + # If the root is changed update the static content alias as well + # + WSGIScriptAlias /bcfg2 "/usr/lib/python2.4/site-packages/Bcfg2/Server/Reports/reports.wsgi" + + WSGISocketPrefix run + WSGIDaemonProcess Bcfg2.Server.Reports processes=1 threads=10 + WSGIProcessGroup Bcfg2.Server.Reports + + # + # Manually set this to override the static content + # + #SetEnv bcfg2.media_url /bcfg2/site_media/ + + # + # This should have the same prefix as WSGIScriptAlias + # + Alias "/bcfg2/site_media/" "/usr/share/bcfg2/site_media/" + + Options None + AllowOverride None + Order allow,deny + Allow from all + + -- cgit v1.2.3-1-g7c22 From aa253e853dcc166d341d74cf4a1c27a4e563dc3a Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Tue, 19 Oct 2010 16:06:35 -0500 Subject: web_reports: debian reports package --- debian/bcfg2-server.install | 4 +++- debian/bcfg2-web.install | 2 ++ debian/control | 9 +++++++++ debian/rules | 9 +++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 debian/bcfg2-web.install diff --git a/debian/bcfg2-server.install b/debian/bcfg2-server.install index 859806fa0..91b1b2aef 100644 --- a/debian/bcfg2-server.install +++ b/debian/bcfg2-server.install @@ -1,5 +1,7 @@ debian/bcfg2-server.default usr/share/bcfg2 debian/tmp/usr/bin/bcfg2-* usr/sbin debian/tmp/usr/lib/python*/*-packages/Bcfg2/Server/* -debian/tmp/usr/share/bcfg2/* +debian/tmp/usr/share/bcfg2/Hostbase/* +debian/tmp/usr/share/bcfg2/schemas/* +debian/tmp/usr/share/bcfg2/xsl-transforms/* debian/tmp/usr/share/man/man8/* diff --git a/debian/bcfg2-web.install b/debian/bcfg2-web.install new file mode 100644 index 000000000..bfa55a925 --- /dev/null +++ b/debian/bcfg2-web.install @@ -0,0 +1,2 @@ +misc/apache/bcfg2.conf etc/apache2/conf.d/ +debian/tmp/usr/share/bcfg2/site_media/* diff --git a/debian/control b/debian/control index acfc6cc9c..726958c85 100644 --- a/debian/control +++ b/debian/control @@ -29,3 +29,12 @@ Description: Configuration management server for clients bound by client profiles. bcfg2-server is the server for bcfg2 clients, which generates configuration sets and stores statistics of client system states. + +Package: bcfg2-web +Architecture: all +Depends: ${python:Depends}, ${misc:Depends}, bcfg2 (= ${binary:Version}), python-django, libapache2-mod-wsgi +XB-Python-Version: >= 2.4 +Description: Configuration management web interface + Bcfg2 is a configuration management system that generates configuration sets + for clients bound by client profiles. + bcfg2-web is the reporting server for bcfg2. diff --git a/debian/rules b/debian/rules index 928b3d2d3..928880859 100755 --- a/debian/rules +++ b/debian/rules @@ -1,4 +1,7 @@ #!/usr/bin/make -f + +WSGI_LOC = $(shell find debian/bcfg2-server/ -name reports.wsgi | perl -p -e 's|debian/bcfg2-server||') + %: dh --with python-support $@ @@ -14,3 +17,9 @@ override_dh_installinit: dh_installinit --package=bcfg2 --no-start # Install bcfg2-server initscript without starting it on postinst dh_installinit --package=bcfg2-server --no-start + +override_dh_installdeb: + dh_installdeb + perl -pi -e 's/^.*LoadModule.*//' debian/bcfg2-web/etc/apache2/conf.d/bcfg2.conf + perl -pi -e 's|/usr.*/reports.wsgi|$(WSGI_LOC)|' debian/bcfg2-web/etc/apache2/conf.d/bcfg2.conf + -- cgit v1.2.3-1-g7c22 From 31688574736713d0f9bf33ed0c3a9ae8e5b0c718 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Thu, 21 Oct 2010 09:30:34 -0500 Subject: spec: updated to handle opensuse and web reports --- misc/bcfg2.spec | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/misc/bcfg2.spec b/misc/bcfg2.spec index c38e52c3b..e9798c39f 100644 --- a/misc/bcfg2.spec +++ b/misc/bcfg2.spec @@ -98,7 +98,14 @@ Version: %{version} Summary: Bcfg2 Web Reporting Interface Group: System Tools Requires: bcfg2-server -Requires: httpd,mod_wsgi,Django +Requires: httpd,Django +%if "%{_vendor}" == "redhat" +Requires: mod_wsgi +%define apache_conf %{_sysconfdir}/httpd +%else +Requires: apache2-mod_wsgi +%define apache_conf %{_sysconfdir}/apache2 +%endif %description -n bcfg2-web Bcfg2 helps system administrators produce a consistent, reproducible, @@ -150,10 +157,8 @@ deployment strategies. %{__install} -m 755 debian/bcfg2.cron.hourly %{buildroot}%{_sysconfdir}/cron.hourly/bcfg2 %{__install} -m 755 tools/bcfg2-cron %{buildroot}%{_prefix}/lib/bcfg2/bcfg2-cron -%if "%{_vendor}" == "redhat" -%{__install} -d %{buildroot}%{_sysconfdir}/httpd/conf.d -%{__install} -m 644 misc/apache/bcfg2.conf %{buildroot}%{_sysconfdir}/httpd/conf.d/bcfg2.conf -%endif +%{__install} -d %{buildroot}%{apache_conf}/conf.d +%{__install} -m 644 misc/apache/bcfg2.conf %{buildroot}%{apache_conf}/conf.d/bcfg2.conf %clean [ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot} || exit 2 @@ -206,9 +211,7 @@ deployment strategies. %{_datadir}/bcfg2/site_media -%if "%{_vendor}" == "redhat" -%config(noreplace) %{_sysconfdir}/httpd/conf.d/bcfg2.conf -%endif +%config(noreplace) %{apache_conf}/conf.d/bcfg2.conf %changelog * Mon Jun 21 2010 Fabian Affolter - 1.1.0rc3-0.1 -- cgit v1.2.3-1-g7c22 From bccfe3f9f173f3fa5fb86914778e48d9923bc2ae Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Thu, 21 Oct 2010 12:51:12 -0500 Subject: web_reports: Moved location of reports.wsgi to a more stable location --- debian/bcfg2-web.install | 1 + debian/control | 1 + debian/rules | 5 ----- misc/apache/bcfg2.conf | 4 +--- misc/bcfg2.spec | 5 +++-- reports/reports.wsgi | 4 ++++ setup.py | 4 ++-- src/lib/Server/Reports/reports.wsgi | 4 ---- 8 files changed, 12 insertions(+), 16 deletions(-) create mode 100644 reports/reports.wsgi delete mode 100644 src/lib/Server/Reports/reports.wsgi diff --git a/debian/bcfg2-web.install b/debian/bcfg2-web.install index bfa55a925..68caa98fa 100644 --- a/debian/bcfg2-web.install +++ b/debian/bcfg2-web.install @@ -1,2 +1,3 @@ misc/apache/bcfg2.conf etc/apache2/conf.d/ +debian/tmp/usr/share/bcfg2/reports.wsgi debian/tmp/usr/share/bcfg2/site_media/* diff --git a/debian/control b/debian/control index 726958c85..4db926f77 100644 --- a/debian/control +++ b/debian/control @@ -33,6 +33,7 @@ Description: Configuration management server Package: bcfg2-web Architecture: all Depends: ${python:Depends}, ${misc:Depends}, bcfg2 (= ${binary:Version}), python-django, libapache2-mod-wsgi +Suggests: python-mysqldb, python-psycopg2, python-sqlite XB-Python-Version: >= 2.4 Description: Configuration management web interface Bcfg2 is a configuration management system that generates configuration sets diff --git a/debian/rules b/debian/rules index 928880859..1638b8415 100755 --- a/debian/rules +++ b/debian/rules @@ -18,8 +18,3 @@ override_dh_installinit: # Install bcfg2-server initscript without starting it on postinst dh_installinit --package=bcfg2-server --no-start -override_dh_installdeb: - dh_installdeb - perl -pi -e 's/^.*LoadModule.*//' debian/bcfg2-web/etc/apache2/conf.d/bcfg2.conf - perl -pi -e 's|/usr.*/reports.wsgi|$(WSGI_LOC)|' debian/bcfg2-web/etc/apache2/conf.d/bcfg2.conf - diff --git a/misc/apache/bcfg2.conf b/misc/apache/bcfg2.conf index 2963091ec..b9b4b0452 100644 --- a/misc/apache/bcfg2.conf +++ b/misc/apache/bcfg2.conf @@ -1,10 +1,8 @@ -LoadModule wsgi_module modules/mod_wsgi.so - # # If the root is changed update the static content alias as well # - WSGIScriptAlias /bcfg2 "/usr/lib/python2.4/site-packages/Bcfg2/Server/Reports/reports.wsgi" + WSGIScriptAlias /bcfg2 "/usr/share/bcfg2/reports.wsgi" WSGISocketPrefix run WSGIDaemonProcess Bcfg2.Server.Reports processes=1 threads=10 diff --git a/misc/bcfg2.spec b/misc/bcfg2.spec index e9798c39f..8e77ad908 100644 --- a/misc/bcfg2.spec +++ b/misc/bcfg2.spec @@ -158,7 +158,7 @@ deployment strategies. %{__install} -m 755 tools/bcfg2-cron %{buildroot}%{_prefix}/lib/bcfg2/bcfg2-cron %{__install} -d %{buildroot}%{apache_conf}/conf.d -%{__install} -m 644 misc/apache/bcfg2.conf %{buildroot}%{apache_conf}/conf.d/bcfg2.conf +%{__install} -m 644 misc/apache/bcfg2.conf %{buildroot}%{apache_conf}/conf.d/wsgi_bcfg2.conf %clean [ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot} || exit 2 @@ -209,9 +209,10 @@ deployment strategies. %files -n bcfg2-web %defattr(-,root,root,-) +%{_datadir}/bcfg2/reports.wsgi %{_datadir}/bcfg2/site_media -%config(noreplace) %{apache_conf}/conf.d/bcfg2.conf +%config(noreplace) %{apache_conf}/conf.d/wsgi_bcfg2.conf %changelog * Mon Jun 21 2010 Fabian Affolter - 1.1.0rc3-0.1 diff --git a/reports/reports.wsgi b/reports/reports.wsgi new file mode 100644 index 000000000..232650485 --- /dev/null +++ b/reports/reports.wsgi @@ -0,0 +1,4 @@ +import os +os.environ['DJANGO_SETTINGS_MODULE'] = 'Bcfg2.Server.Reports.settings' +import django.core.handlers.wsgi +application = django.core.handlers.wsgi.WSGIHandler() diff --git a/setup.py b/setup.py index 6d5aae417..37a6b9e36 100644 --- a/setup.py +++ b/setup.py @@ -30,8 +30,7 @@ setup(cmdclass=cmdclass, package_dir = {'Bcfg2':'src/lib'}, package_data = {'Bcfg2.Server.Reports.reports':['fixtures/*.xml', 'templates/*.html', 'templates/*/*.html', - 'templates/*/*.inc' ], - 'Bcfg2.Server.Reports':['reports.wsgi'] }, + 'templates/*/*.inc' ] }, scripts = glob('src/sbin/*'), data_files = [('share/bcfg2/schemas', glob('schemas/*.xsd')), @@ -39,6 +38,7 @@ setup(cmdclass=cmdclass, glob('reports/xsl-transforms/*.xsl')), ('share/bcfg2/xsl-transforms/xsl-transform-includes', glob('reports/xsl-transforms/xsl-transform-includes/*.xsl')), + ('share/bcfg2', ['reports/reports.wsgi']), ('share/man/man1', glob("man/bcfg2.1")), ('share/man/man5', glob("man/*.5")), ('share/man/man8', glob("man/*.8")), diff --git a/src/lib/Server/Reports/reports.wsgi b/src/lib/Server/Reports/reports.wsgi deleted file mode 100644 index 232650485..000000000 --- a/src/lib/Server/Reports/reports.wsgi +++ /dev/null @@ -1,4 +0,0 @@ -import os -os.environ['DJANGO_SETTINGS_MODULE'] = 'Bcfg2.Server.Reports.settings' -import django.core.handlers.wsgi -application = django.core.handlers.wsgi.WSGIHandler() -- cgit v1.2.3-1-g7c22 From 600cb7c95e62f523df492d086734fcf74bb1ca6b Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Thu, 21 Oct 2010 13:48:44 -0500 Subject: Plugin.py: Reverted broken regex --- src/lib/Server/Plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/Server/Plugin.py b/src/lib/Server/Plugin.py index 0458a4ce0..95569e3ac 100644 --- a/src/lib/Server/Plugin.py +++ b/src/lib/Server/Plugin.py @@ -33,8 +33,8 @@ info_regex = re.compile( \ 'encoding:(\s)*(?P\w+)|' + 'group:(\s)*(?P\S+)|' + 'important:(\s)*(?P\S+)|' + - 'mtime:(\s)*(?P\w+)$' + - '^owner:(\s)*(?P\S+)|' + + 'mtime:(\s)*(?P\w+)|' + + 'owner:(\s)*(?P\S+)|' + 'paranoid:(\s)*(?P\S+)|' + 'perms:(\s)*(?P\w+)|') -- cgit v1.2.3-1-g7c22 From 3e55068024caf55f0ed287e878c22aa71ff5ecfd Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 28 Oct 2010 14:20:15 -0500 Subject: Pacman: Use logging infrastructure for printing messages Signed-off-by: Sol Jerome --- src/lib/Client/Tools/Pacman.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/lib/Client/Tools/Pacman.py b/src/lib/Client/Tools/Pacman.py index a9edc4d65..85068ddfc 100644 --- a/src/lib/Client/Tools/Pacman.py +++ b/src/lib/Client/Tools/Pacman.py @@ -1,8 +1,7 @@ """This is the bcfg2 support for pacman""" import Bcfg2.Client.Tools -import Bcfg2.Options -import Bcfg2.Client.Tools + class Pacman(Bcfg2.Client.Tools.PkgTool): '''Archlinux package support''' @@ -31,7 +30,8 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): def VerifyPackage(self, entry, modlist): '''Verify Package status for entry''' - print "VerifyPackage : " + entry.get('name')+ " : " + entry.get('version') + self.logger.info("VerifyPackage : %s : %s" % entry.get('name'), + entry.get('version')) if not 'version' in entry.attrib: self.logger.info("Cannot verify unversioned package %s" % @@ -44,8 +44,8 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): elif self.installed[entry.attrib['name']] == entry.attrib['version']: #if not self.setup['quick'] and \ # entry.get('verify', 'true') == 'true': - #FIXME: We should be able to check this once - # http://trac.macports.org/ticket/15709 is implemented + #FIXME: need to figure out if pacman + # allows you to verify packages return True else: entry.set('current_version', self.installed[entry.get('name')]) @@ -76,11 +76,7 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): print "packages : " + pkgline try: - self.logger.debug('Running Pacman.Install()') - print "running : %s -S %s" % (self.pkgtool, pkgline) - s = self.cmd.run("%s -S %s" % (self.pkgtool, pkgline)) - print "pacman : " + str(s) - except Exception as ex: - print "error in cmd.run ", ex - - self.logger.debug('Running Pacman.Install()') + self.logger.debug("Running : %s -S %s" % (self.pkgtool, pkgline)) + self.cmd.run("%s -S %s" % (self.pkgtool, pkgline)) + except Exception as e: + self.logger.error("Error occurred during installation: %s" % e) -- cgit v1.2.3-1-g7c22 From 40d3006505ea03cb2318622dff16eb7c2e8f7213 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 28 Oct 2010 14:37:08 -0500 Subject: Reports: Fix default time zone settings (Resolves Ticket #957) We were previously defaulting to America/Chicago instead of leaving this option up to the user. Setting the default to None will cause Django to go by the system time. Note also that Django sets the os.environ['TZ'] variable when this is not none, so we want to be careful not to set that if we don't have to. Signed-off-by: Sol Jerome --- man/bcfg2.conf.5 | 5 +++++ src/lib/Server/Hostbase/settings.py | 7 +++++-- src/lib/Server/Reports/settings.py | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/man/bcfg2.conf.5 b/man/bcfg2.conf.5 index 394bb347d..f2e47b7ac 100644 --- a/man/bcfg2.conf.5 +++ b/man/bcfg2.conf.5 @@ -325,6 +325,11 @@ Host for database connections. Not used for sqlite3. .B database_port Port for database connections. Not used for sqlite3. +.TP +.B time_zone +Specify a time zone other than that used on the system. (Note that this +will cause the bcfg2 server to log messages in this time zone as well). + .SH COMMUNICATION OPTIONS Specified in the [communication] section. These options define diff --git a/src/lib/Server/Hostbase/settings.py b/src/lib/Server/Hostbase/settings.py index dadf98d24..a42fd5b2e 100644 --- a/src/lib/Server/Hostbase/settings.py +++ b/src/lib/Server/Hostbase/settings.py @@ -44,8 +44,11 @@ DATABASE_HOST = options['database_host'] # Set to empty string for default. Not used with sqlite3. DATABASE_PORT = int(options['database_port']) # Local time zone for this installation. All choices can be found here: -# http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE -TIME_ZONE = 'America/Chicago' +# http://docs.djangoproject.com/en/dev/ref/settings/#time-zone +try: + TIME_ZONE = c.get('statistics', 'time_zone') +except: + TIME_ZONE = None # enter the defauly MX record machines will get in Hostbase # this setting may move elsewhere eventually diff --git a/src/lib/Server/Reports/settings.py b/src/lib/Server/Reports/settings.py index 81220c0e3..b725783ca 100644 --- a/src/lib/Server/Reports/settings.py +++ b/src/lib/Server/Reports/settings.py @@ -49,7 +49,7 @@ if DATABASE_ENGINE == 'sqlite3' and DATABASE_NAME == '': try: TIME_ZONE = c.get('statistics', 'time_zone') except: - TIME_ZONE = 'America/Chicago' + TIME_ZONE = None # Language code for this installation. All choices can be found here: # http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes -- cgit v1.2.3-1-g7c22 From 313afd64879e1d7c860012c0b7d5430d100eaf41 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 28 Oct 2010 17:09:10 -0500 Subject: doc: Move Properties plugin documentation under connectors Signed-off-by: Sol Jerome --- doc/server/plugins/connectors/properties.txt | 46 ++++++++++++++++++++++++++++ doc/server/plugins/index.txt | 10 +++++- doc/server/plugins/properties.txt | 46 ---------------------------- 3 files changed, 55 insertions(+), 47 deletions(-) create mode 100644 doc/server/plugins/connectors/properties.txt delete mode 100644 doc/server/plugins/properties.txt diff --git a/doc/server/plugins/connectors/properties.txt b/doc/server/plugins/connectors/properties.txt new file mode 100644 index 000000000..fa8bfd884 --- /dev/null +++ b/doc/server/plugins/connectors/properties.txt @@ -0,0 +1,46 @@ +.. -*- mode: rst -*- + +.. _server-plugins-properties: + +========== +Properties +========== + +The Properties plugin is a connector plugin that adds information from +properties files into client metadata instances. + +Enabling Properties +=================== + +First, ``mkdir /var/lib/bcfg2/Properties``. Each property XML file goes +in this directory. Each will automatically be cached by the server, +and reread/reparsed upon changes. Add **Properties** to your ``plugins`` +line in ``/etc/bcfg2.conf``. + +Data Structures +=============== + +Properties adds a new dictionary to client metadata instances that maps +property file names to PropertyFile instances. PropertyFile instances +contain parsed XML data as the "data" attribute. + +Usage +===== + +Specific property files can be referred to in +templates as metadata.Properties[]. The +data attribute is an LXML element object. (Documented +`here `_) + +Currently, no access methods are defined for this data, but as we +formulate common use cases, we will add them to the !PropertyFile class +as methods. This will simplify templates. + +Accessing Properties contest from TGenshi +========================================= + +Access contents of ``Properties/auth.xml`` + +:: + + ${metadata.Properties['auth.xml'].data.find('file').find('bcfg2.key').text} diff --git a/doc/server/plugins/index.txt b/doc/server/plugins/index.txt index 126331325..61f91da86 100644 --- a/doc/server/plugins/index.txt +++ b/doc/server/plugins/index.txt @@ -68,6 +68,15 @@ Literal Configuration (Generators) Each of these plugins has a corresponding subdirectory with the same name in the Bcfg2 repository. +Connector Plugins +----------------- + +.. toctree:: + :maxdepth: 2 + :glob: + + connectors/* + Statistics Plugins ------------------ @@ -103,5 +112,4 @@ More details can be found in :ref:`server-plugins-plugin-roles` plugin-roles probes/index - properties trigger diff --git a/doc/server/plugins/properties.txt b/doc/server/plugins/properties.txt deleted file mode 100644 index fa8bfd884..000000000 --- a/doc/server/plugins/properties.txt +++ /dev/null @@ -1,46 +0,0 @@ -.. -*- mode: rst -*- - -.. _server-plugins-properties: - -========== -Properties -========== - -The Properties plugin is a connector plugin that adds information from -properties files into client metadata instances. - -Enabling Properties -=================== - -First, ``mkdir /var/lib/bcfg2/Properties``. Each property XML file goes -in this directory. Each will automatically be cached by the server, -and reread/reparsed upon changes. Add **Properties** to your ``plugins`` -line in ``/etc/bcfg2.conf``. - -Data Structures -=============== - -Properties adds a new dictionary to client metadata instances that maps -property file names to PropertyFile instances. PropertyFile instances -contain parsed XML data as the "data" attribute. - -Usage -===== - -Specific property files can be referred to in -templates as metadata.Properties[]. The -data attribute is an LXML element object. (Documented -`here `_) - -Currently, no access methods are defined for this data, but as we -formulate common use cases, we will add them to the !PropertyFile class -as methods. This will simplify templates. - -Accessing Properties contest from TGenshi -========================================= - -Access contents of ``Properties/auth.xml`` - -:: - - ${metadata.Properties['auth.xml'].data.find('file').find('bcfg2.key').text} -- cgit v1.2.3-1-g7c22 From b93a686ac42e56b6d7c27d1dd15b162cf3a56886 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 28 Oct 2010 18:00:55 -0500 Subject: Pacman: Fix traceback for exception handler Signed-off-by: Sol Jerome --- src/lib/Client/Tools/Pacman.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Client/Tools/Pacman.py b/src/lib/Client/Tools/Pacman.py index 85068ddfc..be3fb0c94 100644 --- a/src/lib/Client/Tools/Pacman.py +++ b/src/lib/Client/Tools/Pacman.py @@ -78,5 +78,5 @@ class Pacman(Bcfg2.Client.Tools.PkgTool): try: self.logger.debug("Running : %s -S %s" % (self.pkgtool, pkgline)) self.cmd.run("%s -S %s" % (self.pkgtool, pkgline)) - except Exception as e: + except Exception, e: self.logger.error("Error occurred during installation: %s" % e) -- cgit v1.2.3-1-g7c22 From 90d3b840f49f2e86697a2abd35299bf7b8e93ee9 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 28 Oct 2010 19:36:48 -0500 Subject: Reports: Don't set TIME_ZONE unless it's supported Django added the TIME_ZONE = None bit in 1.2 and we are still supporting distros with 1.0 installed by default. Signed-off-by: Sol Jerome --- src/lib/Server/Reports/settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/Server/Reports/settings.py b/src/lib/Server/Reports/settings.py index b725783ca..9efe38552 100644 --- a/src/lib/Server/Reports/settings.py +++ b/src/lib/Server/Reports/settings.py @@ -49,7 +49,8 @@ if DATABASE_ENGINE == 'sqlite3' and DATABASE_NAME == '': try: TIME_ZONE = c.get('statistics', 'time_zone') except: - TIME_ZONE = None + if django.VERSION[0] == 1 and django.VERSION[1] > 2: + TIME_ZONE = None # Language code for this installation. All choices can be found here: # http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes -- cgit v1.2.3-1-g7c22 From d7a26f768612b2fb1754dd30ce5a748955230494 Mon Sep 17 00:00:00 2001 From: Narayan Desai Date: Fri, 29 Oct 2010 11:46:45 -0500 Subject: bcfg2: implement -Q option (bundle-quick mode) Implement the -Q option for the bcfg2 client. This option only verifies and installs the entries in bundles specified with -b. Considerably improves runtime performance when package checksums are being checked. This option prevents the client from sending statistics to the server, and is incompatible with -r. --- man/bcfg2.1 | 7 +++++++ src/lib/Options.py | 2 ++ src/sbin/bcfg2 | 17 +++++++++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/man/bcfg2.1 b/man/bcfg2.1 index bf20649c3..938d41dfe 100644 --- a/man/bcfg2.1 +++ b/man/bcfg2.1 @@ -113,6 +113,13 @@ Run bcfg2 in quick mode. Package checksum verification won't be performed. This mode relaxes the constraints of correctness, and thus should only be used in safe conditions. +.TP +.BR "\-Q" +Run bcfg2 in "bundle quick" mode, where only entries in a bundle are +or installed. This runs much faster than -q, but doesn't provide +statistics to the server at all. In order for this option to work, the +-b option must also be provided. This option is incompatible with -r. + .TP .BR "\-r " Cause bcfg2 to remove extra configuration elements it detects. Mode is diff --git a/src/lib/Options.py b/src/lib/Options.py index b467a776d..1dcad6427 100644 --- a/src/lib/Options.py +++ b/src/lib/Options.py @@ -290,6 +290,8 @@ CLIENT_REMOVE = Option('force removal of additional configuration items', default=False, cmd='-r', odesc="") CLIENT_BUNDLE = Option('only configure the given bundle(s)', default=[], cmd='-b', odesc='', cook=colon_split) +CLIENT_BUNDLEQUICK = Option('only verify/configure the given bundle(s)', default=False, + cmd='-Q') CLIENT_INDEP = Option('only configure the given bundle(s)', default=False, cmd='-z') CLIENT_KEVLAR = Option('run in kevlar (bulletproof) mode', default=False, diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2 index 3407a1c53..10262e4a9 100755 --- a/src/sbin/bcfg2 +++ b/src/sbin/bcfg2 @@ -49,6 +49,7 @@ class Client: 'dryrun': Bcfg2.Options.CLIENT_DRYRUN, 'paranoid': Bcfg2.Options.CLIENT_PARANOID, 'bundle': Bcfg2.Options.CLIENT_BUNDLE, + 'bundle-quick': Bcfg2.Options.CLIENT_BUNDLEQUICK, 'indep': Bcfg2.Options.CLIENT_INDEP, 'file': Bcfg2.Options.CLIENT_FILE, 'interactive': Bcfg2.Options.INTERACTIVE, @@ -62,7 +63,6 @@ class Client: 'password': Bcfg2.Options.SERVER_PASSWORD, 'retries': Bcfg2.Options.CLIENT_RETRIES, 'kevlar': Bcfg2.Options.CLIENT_KEVLAR, - 'key': Bcfg2.Options.SERVER_KEY, 'decision-list': DECISION_LIST, 'encoding': Bcfg2.Options.ENCODING, 'omit-lock-check': Bcfg2.Options.OMIT_LOCK_CHECK, @@ -93,6 +93,13 @@ class Client: to_file=self.setup['filelog']) self.logger = logging.getLogger('bcfg2') self.logger.debug(self.setup) + if self.setup['bundle-quick']: + if self.setup['bundle'] == []: + self.logger.error("-Q option requires -b") + raise SystemExit(1) + elif self.setup['remove'] != False: + self.logger.error("-Q option incompatible with -r") + raise SystemExit(1) if 'drivers' in self.setup and self.setup['drivers'] == 'help': self.logger.info("The following drivers are available:") self.logger.info(Bcfg2.Client.Tools.drivers) @@ -251,6 +258,12 @@ class Client: self.fatal_error("Server error: %s" % (self.config.text)) return(1) + if self.setup['bundle-quick']: + newconfig = Bcfg2.Client.XML.XML('') + [newconfig.append(bundle) for bundle in self.config.getchildren() if \ + bundle.tag == 'Bundle' and bundle.get('name') in self.setup['bundle']] + self.config = newconfig + self.tools = Bcfg2.Client.Frame.Frame(self.config, self.setup, times, self.setup['drivers'], @@ -281,7 +294,7 @@ class Client: except OSError: self.logger.error("Failed to unlock lockfile %s" % lockfile.name) - if not self.setup['file']: + if not self.setup['file'] and not self.setup['bundle-quick']: # upload statistics feedback = self.tools.GenerateStats() -- cgit v1.2.3-1-g7c22 From dd0168f42a2efddecec09c51313899ea7b3b39ec Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Tue, 2 Nov 2010 13:52:19 -0500 Subject: docs: Added more information for the metadata object used in TGenshi and TCheetah --- doc/server/plugins/generators/tcheetah.txt | 16 +----- doc/server/plugins/generators/tgenshi/index.txt | 6 ++- doc/server/plugins/grouping/metadata.txt | 67 +++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/doc/server/plugins/generators/tcheetah.txt b/doc/server/plugins/generators/tcheetah.txt index e1ad600a2..52a0f3264 100644 --- a/doc/server/plugins/generators/tcheetah.txt +++ b/doc/server/plugins/generators/tcheetah.txt @@ -27,7 +27,7 @@ located in in a ``TCheetah`` subdirectory of your repository, usually files, ``template`` and ``info``. The template is a standard Cheetah template with two additions: -* `self.metadata` is the client's metadata +* `self.metadata` is the client's :ref:`metadata ` * `self.properties` is an xml document of unstructured data The ``info`` file is formatted like ``:info`` files from Cfg. @@ -44,19 +44,7 @@ Permissions entry and a Path entry to handle the same file. self.metadata variables ======================= -The following variables are available for self.metadata: - -* hostname -* bundles -* groups -* categories -* probes -* uuid -* password - -self.metadata is an instance of the class -ClientMetadata of file `Bcfg2/Server/Plugins/Metadata.py -`_. +self.metadata is an instance of the class ClientMetadata and documented :ref:`here `. self.properties =============== diff --git a/doc/server/plugins/generators/tgenshi/index.txt b/doc/server/plugins/generators/tgenshi/index.txt index cd9bcf152..425b3a289 100644 --- a/doc/server/plugins/generators/tgenshi/index.txt +++ b/doc/server/plugins/generators/tgenshi/index.txt @@ -48,8 +48,10 @@ supported. Inside of templates =================== -* metadata is the client's metadata -* properties.properties is an xml document of unstructured data +* **metadata** is the client's :ref:`metadata ` +* **properties.properties** is an xml document of unstructured data +* **name** is the path name specified in bcfg +* **path** is the path to the TGenshi template See the genshi `documentation `_ for examples of diff --git a/doc/server/plugins/grouping/metadata.txt b/doc/server/plugins/grouping/metadata.txt index 96fc70ff5..22c967262 100644 --- a/doc/server/plugins/grouping/metadata.txt +++ b/doc/server/plugins/grouping/metadata.txt @@ -225,3 +225,70 @@ Probes The metadata plugin includes client-side probing functionality. This is fully documented :ref:`here `. + +.. _server-plugins-grouping-metadata-clientmetadata: + +ClientMetadata +============== + +A special client metadata class is available to the TGenshi and TCheetah +plugins. + ++----------------------+------------------------------------------------+-------------------+ +| Attribute | Description | Value | ++======================+================================================+===================+ +| hostname | Client hostname | String | ++----------------------+------------------------------------------------+-------------------+ +| profile | Client profile | String | ++----------------------+------------------------------------------------+-------------------+ +| aliases | Client aliases | List | ++----------------------+------------------------------------------------+-------------------+ +| addresses | Adresses this client is known by | List | ++----------------------+------------------------------------------------+-------------------+ +| groups | Groups this client is a member of | List | ++----------------------+------------------------------------------------+-------------------+ +| categories | Categories of this clients groups | List | ++----------------------+------------------------------------------------+-------------------+ +| uuid | uuid identifier for this client | String | ++----------------------+------------------------------------------------+-------------------+ +| password | bcfg password for this client | String | ++----------------------+------------------------------------------------+-------------------+ +| connectors | connector plugins known to this client | List | ++----------------------+------------------------------------------------+-------------------+ +| query | MetadataQuery object | MetadataQuery | ++----------------------+------------------------------------------------+-------------------+ + +| + ++------------------------------+------------------------------------------------+-------------------+ +| Method | Description | Value | ++==============================+================================================+===================+ +| inGroup(group) | True if this client is a memnber of 'group' | Boolean | ++------------------------------+------------------------------------------------+-------------------+ +| group_in_category(category) | Returns the group in 'category' if the client | String | +| | is a member of 'category', otherwise '' | | ++------------------------------+------------------------------------------------+-------------------+ + +MetadataQuery +------------- + +This class provides query routines for the servers Metadata. + ++------------------------------+------------------------------------------------+-------------------+ +| Method | Description | Value | ++==============================+================================================+===================+ +| by_name(client) | Get ClientMetadata object for 'client' | ClientMetadata | ++------------------------------+------------------------------------------------+-------------------+ +| names_by_groups(group) | | | ++------------------------------+------------------------------------------------+-------------------+ +| names_by_profiles(profile) | All clients names in 'profile' | List | ++------------------------------+------------------------------------------------+-------------------+ +| all_clients() | All known client hostnames | List | ++------------------------------+------------------------------------------------+-------------------+ +| all_groups() | All known group names | List | ++------------------------------+------------------------------------------------+-------------------+ +| all_groups_in_category(cat) | All groups in category 'cat' | List | ++------------------------------+------------------------------------------------+-------------------+ +| all() | Get ClientMetadata for all clients | List | ++------------------------------+------------------------------------------------+-------------------+ + -- cgit v1.2.3-1-g7c22 From d1a2629b426c94d0ccc1ba60c2c0c49e940a6d88 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 2 Nov 2010 18:46:23 -0500 Subject: YUMng: Sync Joe Digilio's patch over from svn Jack Neely's commit message: Add a patch from Joe Digilio to include a verify_flags knob. I've added a line to also load this from the config file, and log in debug mode. Specifying 'verify_flags' with an Instance will override the values from the config file. Signed-off-by: Sol Jerome --- src/lib/Client/Tools/YUMng.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/Client/Tools/YUMng.py b/src/lib/Client/Tools/YUMng.py index 9cdcdca40..f0d906717 100644 --- a/src/lib/Client/Tools/YUMng.py +++ b/src/lib/Client/Tools/YUMng.py @@ -210,6 +210,8 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): "version_fail_action", "upgrade").lower() == "upgrade" self.doReinst = CP.get(self.name, "verify_fail_action", "reinstall").lower() == "reinstall" + self.verifyFlags = CP.get(self.name, "verify_flags", + "").lower().replace(' ', ',') self.installOnlyPkgs = self.yb.conf.installonlypkgs if 'gpg-pubkey' not in self.installOnlyPkgs: @@ -225,6 +227,7 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): % self.doReinst) self.logger.debug("YUMng: installOnlyPkgs: %s" \ % str(self.installOnlyPkgs)) + self.logger.debug("YUMng: verify_flags: %s" % self.verifyFlags) def _fixAutoVersion(self, entry): # old style entry; synthesize Instances from current installed @@ -436,6 +439,8 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): stat['verify_fail'] = False stat['pkg'] = entry stat['modlist'] = modlist + verify_flags = inst.get('verify_flags', self.verifyFlags) + verify_flags = verify_flags.lower().replace(' ', ',').split(',') if len(POs) == 0: # Package not installed @@ -505,6 +510,8 @@ class YUMng(Bcfg2.Client.Tools.PkgTool): for p in probs: if p.type == 'missing' and os.path.islink(fn): continue + elif 'no' + p.type in verify_flags: + continue if p.type not in ['missingok', 'ghost']: tmp.append((p.type, p.message)) if tmp != []: -- cgit v1.2.3-1-g7c22 From b6eab0d793bdad28755f61cef670a62b3ffc50e4 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 2 Nov 2010 20:31:51 -0500 Subject: doc: Fix broken link to help pages Signed-off-by: Sol Jerome --- doc/getting_started/index.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/getting_started/index.txt b/doc/getting_started/index.txt index fe52807d4..2c05c5238 100644 --- a/doc/getting_started/index.txt +++ b/doc/getting_started/index.txt @@ -9,7 +9,7 @@ Using Bcfg2 These are many of the resources available to help new users get started. * For the impatient there is the :ref:`quickstart-index` page. -* :ref:`gettinghelp` has information when you are troubleshooting or need to ask a question. +* :ref:`help-index` has information when you are troubleshooting or need to ask a question. * If you find anything wrong or missing please :ref:`report-a-bug` to let us know. .. toctree:: -- cgit v1.2.3-1-g7c22 From 6bbd4d6797d763777188d3984808f1ff692b2376 Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Tue, 2 Nov 2010 21:51:00 -0400 Subject: fixed lookup of ca options in bcfg2.conf, removing CA trees from SSLCA repo --- src/lib/Server/Plugins/SSLCA.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index d2137f23f..823bf7fa0 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -29,7 +29,7 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): __child__ = Bcfg2.Server.Plugin.FileBacked key_specs = {} cert_specs = {} - ca_passphrases = {} + CAs = {} def HandleEvent(self, event=None): """ @@ -37,7 +37,7 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): Allows configuration items to be added/removed without server restarts. """ action = event.code2str() - if event.filename[0] == '/' or event.filename.startswith('CAs'): + if event.filename[0] == '/': return epath = "".join([self.data, self.handles[event.requestID], event.filename]) @@ -74,7 +74,7 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): } cp = ConfigParser() cp.read(self.core.cfile) - self.ca_passphrases[ca] = cp.get('sslca', ca+'_passphrase') + self.CAs[ca] = dict(cp.items('sslca_'+ca)) self.Entries['Path'][ident] = self.get_cert if action == 'deleted': if ident in self.Entries['Path']: @@ -177,10 +177,13 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): req_config = self.build_req_config(entry, metadata) req = self.build_request(req_config, entry) ca = self.cert_specs[entry.get('name')]['ca'] - ca_config = "".join([self.data, '/CAs/', ca, '/', 'openssl.cnf']) + ca_config = self.CAs[ca]['config'] days = self.cert_specs[entry.get('name')]['days'] - passphrase = self.ca_passphrases[ca] - cmd = "openssl ca -config %s -in %s -days %s -batch -passin pass:%s" % (ca_config, req, days, passphrase) + passphrase = self.CAs[ca].get('passphrase') + if passphrase: + cmd = "openssl ca -config %s -in %s -days %s -batch -passin pass:%s" % (ca_config, req, days, passphrase) + else: + cmd = "openssl ca -config %s -in %s -days %s -batch" % (ca_config, req, days) cert = Popen(cmd, shell=True, stdout=PIPE).stdout.read() try: os.unlink(req_config) -- cgit v1.2.3-1-g7c22 From 9d45d2c7d00ab20963041a4e7834eb97f7851f77 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 3 Nov 2010 09:58:55 -0500 Subject: doc: Update version for next major release Signed-off-by: Sol Jerome --- doc/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index e1d1a74b2..95ce9d281 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -47,9 +47,9 @@ copyright = u'2009-%s, Narayan Desai' % time.strftime('%Y') # built documents. # # The short X.Y version. -version = '1.1' +version = '1.2' # The full version, including alpha/beta/rc tags. -release = '1.1.0' +release = '1.2.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -- cgit v1.2.3-1-g7c22 From e0208c832fa922cf3958f58f023bd13d053ff879 Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Wed, 3 Nov 2010 11:00:53 -0400 Subject: added verification of existing certs --- src/lib/Server/Plugins/SSLCA.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index 823bf7fa0..a961e744a 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -154,20 +154,25 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): self.core.Bind(e, metadata) # check if we have a valid hostfile - if filename in self.entries.keys() and self.verify_cert(): + if filename in self.entries.keys() and self.verify_cert(filename, entry): entry.text = self.entries[filename].data else: cert = self.build_cert(entry, metadata) open(self.data + filename, 'w').write(cert) entry.text = cert - def verify_cert(self): + def verify_cert(self, filename, entry): """ check that a certificate validates against the ca cert, and that it has not expired. """ - # TODO: verify key validates and has not expired - # possibly also ensure no less than x days until expiry + chaincert = self.CAs[self.cert_specs[entry.get('name')]['ca']].get('chaincert') + cert = "".join([self.data, '/', filename]) + cmd = "openssl verify -CAfile %s %s" % (chaincert, cert) + proc = Popen(cmd, shell=True) + proc.communicate() + if proc.returncode != 0: + return False return True def build_cert(self, entry, metadata): -- cgit v1.2.3-1-g7c22 From 378bcbeef00ad842e1a7cbad7358ed1523054843 Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Wed, 3 Nov 2010 10:58:58 -0500 Subject: docs: Remove references to "bcfg2-admin reports init" until its fixed in 1.1.1 --- doc/server/reports/dynamic.txt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/doc/server/reports/dynamic.txt b/doc/server/reports/dynamic.txt index 0786f0cbe..1ec41af64 100644 --- a/doc/server/reports/dynamic.txt +++ b/doc/server/reports/dynamic.txt @@ -34,22 +34,17 @@ section below. Distributed environments can share a single remote database for reporting. -Run ``/usr/sbin/bcfg2-admin reports init`` to initialize -the database. If you're using sqlite, make sure the webserver -can write to the database. - The recommended statistics plugin is DBStats. To use it, add it to the **plugins** line in your ``bcfg2.conf``. Alternatively, the Statistics plugin can be used in conjunction with a crontab entry to run ``/usr/sbin/bcfg2-admin reports load_stats``. -Restart the Bcfg2 server. Run a client in dryrun mode in order to get -the client's statistics loaded into the database. +Detailed installation instructions can be found :ref:`here `. .. _dynamic-http-install: -Installation of web-based Reports ---------------------------------- +Apache configuration for web-based reports +------------------------------------------ .. note:: -- cgit v1.2.3-1-g7c22 From ece317ca9f404e0a6fad93d82beffd73e495cb4c Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 3 Nov 2010 19:01:44 -0500 Subject: doc: Fix indentation errors so that SSLCA docs can build Signed-off-by: Sol Jerome --- doc/server/plugins/generators/sslca.txt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/doc/server/plugins/generators/sslca.txt b/doc/server/plugins/generators/sslca.txt index 118a16559..ebc625e11 100644 --- a/doc/server/plugins/generators/sslca.txt +++ b/doc/server/plugins/generators/sslca.txt @@ -70,9 +70,11 @@ path to your key. In this case this would be something like #. Within that directory, create a ``key.xml`` file containing the following: - - - + .. code-block:: xml + + + + #. This will cause the generation of an 2048 bit RSA key when a client requests that Path. Alternatively you can specify ``dsa`` as the keytype, or a different @@ -81,9 +83,11 @@ number of bits. #. Similarly, create the matching directory structure for the certificate path, and a ``cert.xml`` containinng the following: - - - + .. code-block:: xml + + + + #. When a client requests the cert path, a certificate will be generated using the key hostfile at the specified key location, using the CA matching the ca -- cgit v1.2.3-1-g7c22 From b2572ea9cbd290a81567313f733a8f253987334d Mon Sep 17 00:00:00 2001 From: Tim Laszlo Date: Thu, 4 Nov 2010 06:09:07 -0500 Subject: docs: add note about sqlite permission --- doc/server/reports/install.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/server/reports/install.txt b/doc/server/reports/install.txt index 6d081fffd..80f9342ae 100644 --- a/doc/server/reports/install.txt +++ b/doc/server/reports/install.txt @@ -179,3 +179,5 @@ then have something like this:: web_debug = True Restart apache and point a browser to your Bcfg2 server. + +If using sqlite be sure the sql database file and directory containing the database are writable to apache. -- cgit v1.2.3-1-g7c22 From e2b894cc01bb3a10fa950112f49a12ba1b09a63d Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 4 Nov 2010 16:56:50 -0500 Subject: doc: Update to point to git repository Signed-off-by: Sol Jerome --- doc/development/index.txt | 2 +- doc/getting_started/using-bcfg2-with-centos.txt | 4 ++-- doc/server/plugins/structures/bundler/index.txt | 3 +-- doc/unsorted/contribute.txt | 4 ++-- doc/unsorted/install.txt | 4 ++-- doc/unsorted/writing_specification.txt | 3 +-- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/doc/development/index.txt b/doc/development/index.txt index 505cc1e02..74621815f 100644 --- a/doc/development/index.txt +++ b/doc/development/index.txt @@ -36,7 +36,7 @@ Environment setup for development * Check out a copy of the code:: - svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2 + git clone git://git.mcs.anl.gov/bcfg2.git * Create link to src/lib:: diff --git a/doc/getting_started/using-bcfg2-with-centos.txt b/doc/getting_started/using-bcfg2-with-centos.txt index 7c452f422..93875d4c5 100644 --- a/doc/getting_started/using-bcfg2-with-centos.txt +++ b/doc/getting_started/using-bcfg2-with-centos.txt @@ -43,9 +43,9 @@ Now you can install the rest of the prerequisites:: Build Packages from source ########################## -* After installing subversion, check out a copy of trunk :: +* After installing git, clone the master branch:: - [root@centos redhat]# svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2 + [root@centos redhat]# git clone git://git.mcs.anl.gov/bcfg2.git * Install the ``fedora-packager`` package :: diff --git a/doc/server/plugins/structures/bundler/index.txt b/doc/server/plugins/structures/bundler/index.txt index f7517284d..da49b299e 100644 --- a/doc/server/plugins/structures/bundler/index.txt +++ b/doc/server/plugins/structures/bundler/index.txt @@ -29,8 +29,7 @@ The following is an annotated copy of a bundle: .. code-block:: xml - + diff --git a/doc/unsorted/contribute.txt b/doc/unsorted/contribute.txt index a0bdd0ada..fab9d09a1 100644 --- a/doc/unsorted/contribute.txt +++ b/doc/unsorted/contribute.txt @@ -23,10 +23,10 @@ trac system, you will need to create a session by clicking on the [https://trac.mcs.anl.gov/projects/bcfg2/prefs Preferences] link and filling out/saving changes to the form. In order to be considered for mainline inclusion, patches need to be BSD licensed. The most convenient -way to prepare patches is by using svn diff inside of a source tree +way to prepare patches is by using git diff inside of a source tree checked out of subversion. The source tree can be checked out by running:: - svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2 + git clone git://git.mcs.anl.gov/bcfg2.git Users wishing to contribute on a regular basis can apply for direct subversion access. Mail the mailing list for details. diff --git a/doc/unsorted/install.txt b/doc/unsorted/install.txt index 56a4b9ebf..6589261ab 100644 --- a/doc/unsorted/install.txt +++ b/doc/unsorted/install.txt @@ -33,9 +33,9 @@ Using native OS X python First, make sure you have Xcode installed as you need `packagemaker` which comes bundled in the Developer tools. -Check out the source from subversion:: +Clone the git source:: - svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2 + git clone git://git.mcs.anl.gov/bcfg2.git Change to the osx directory and type make. Your new package should be located at bcfg2-'''$VERSION'''.pkg (where '''$VERSION''' is that which is specified in setup.py). diff --git a/doc/unsorted/writing_specification.txt b/doc/unsorted/writing_specification.txt index eced54841..5a75165bf 100644 --- a/doc/unsorted/writing_specification.txt +++ b/doc/unsorted/writing_specification.txt @@ -166,8 +166,7 @@ The following is an annotated copy of a bundle: .. code-block:: xml - + -- cgit v1.2.3-1-g7c22 From 3d10ec2113ab4df5e93419a83129f5820cfa2644 Mon Sep 17 00:00:00 2001 From: Graham Hagger Date: Fri, 5 Nov 2010 14:17:30 -0400 Subject: Fixed verification of preexisting certificates --- src/lib/Server/Plugins/SSLCA.py | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index a961e744a..a9986d284 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -1,23 +1,12 @@ -""" -Notes: - -1. Put these notes in real docs!!! -2. dir structure for CA's must be correct -3. for subjectAltNames to work, openssl.conf must have copy_extensions on -""" - - import Bcfg2.Server.Plugin import Bcfg2.Options import lxml.etree import posixpath import tempfile import os -from subprocess import Popen, PIPE +from subprocess import Popen, PIPE, STDOUT from ConfigParser import ConfigParser -import pdb - class SSLCA(Bcfg2.Server.Plugin.GroupSpool): """ The SSLCA generator handles the creation and @@ -157,7 +146,7 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): if filename in self.entries.keys() and self.verify_cert(filename, entry): entry.text = self.entries[filename].data else: - cert = self.build_cert(entry, metadata) + cert = self.build_cert(key_filename, entry, metadata) open(self.data + filename, 'w').write(cert) entry.text = cert @@ -167,20 +156,19 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): and that it has not expired. """ chaincert = self.CAs[self.cert_specs[entry.get('name')]['ca']].get('chaincert') - cert = "".join([self.data, '/', filename]) + cert = self.data + filename cmd = "openssl verify -CAfile %s %s" % (chaincert, cert) - proc = Popen(cmd, shell=True) - proc.communicate() - if proc.returncode != 0: - return False - return True + res = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).stdout.read() + if res == cert + ": OK\n" + return True + return False - def build_cert(self, entry, metadata): + def build_cert(self, key_filename, entry, metadata): """ creates a new certificate according to the specification """ req_config = self.build_req_config(entry, metadata) - req = self.build_request(req_config, entry) + req = self.build_request(key_filename, req_config, entry) ca = self.cert_specs[entry.get('name')]['ca'] ca_config = self.CAs[ca]['config'] days = self.cert_specs[entry.get('name')]['days'] @@ -236,13 +224,13 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): conffile.close() return conffile.name - def build_request(self, req_config, entry): + def build_request(self, key_filename, req_config, entry): """ creates the certificate request """ req = tempfile.mkstemp()[1] - key = self.cert_specs[entry.get('name')]['key'] days = self.cert_specs[entry.get('name')]['days'] + key = self.data + key_filename cmd = "openssl req -new -config %s -days %s -key %s -text -out %s" % (req_config, days, key, req) res = Popen(cmd, shell=True, stdout=PIPE).stdout.read() return req -- cgit v1.2.3-1-g7c22 From a1a0321602585314375d0577516fb012e27f2c59 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 5 Nov 2010 17:25:10 -0400 Subject: fixed needless syntax error bug i checked int ealier. Also ensured that the hostname gets added to any subjectAltNames so that the cert will work for the hostname as well as aliases --- src/lib/Server/Plugins/SSLCA.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index a9986d284..0dc448e69 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -159,7 +159,7 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): cert = self.data + filename cmd = "openssl verify -CAfile %s %s" % (chaincert, cert) res = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).stdout.read() - if res == cert + ": OK\n" + if res == cert + ": OK\n": return True return False @@ -213,8 +213,10 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): for key in defaults[section]: cp.set(section, key, defaults[section][key]) x = 1 - for alias in metadata.aliases: - cp.set('alt_names', 'DNS.'+str(x), alias) + altnames = list(metadata.aliases) + altnames.append(metadata.hostname) + for altname in altnames: + cp.set('alt_names', 'DNS.'+str(x), altname) x += 1 for item in ['C', 'L', 'ST', 'O', 'OU', 'emailAddress']: if self.cert_specs[entry.get('name')][item]: -- cgit v1.2.3-1-g7c22 From 6c0dea0a84ac71bdd4692b86bc1e62ec44223f5e Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Sun, 7 Nov 2010 13:42:44 -0600 Subject: doc: Clarify mandatory attributes Signed-off-by: Sol Jerome --- doc/server/configurationentries.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/server/configurationentries.txt b/doc/server/configurationentries.txt index fff57b7e8..1146a51c6 100644 --- a/doc/server/configurationentries.txt +++ b/doc/server/configurationentries.txt @@ -50,9 +50,9 @@ plugin that handles the entry in the case of `Cfg`_, `TGenshi`_, or a device, directory, hardlink, symlink, etc), then you will specify both the *type* and any other necessary attributes in `Rules`_. -Attributes listed in the table below are mandatory attributes for that -type. For example, the `dev_type` attribute is required for device -entries, but not for hardlink entries. +Running ``bcfg2-repo-validate`` will check your configuration +specification for the presence of any mandatory attributes that are +necessary for the Path type specified. .. note:: A tool for converting old POSIX entries is available in the Bcfg2 source directory at tools/posixunified.py -- cgit v1.2.3-1-g7c22 From 1c3f9b38a7631495e5f3da5d463db2b234becf89 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 8 Nov 2010 09:02:57 -0600 Subject: doc: Fix typo in templates Signed-off-by: Sol Jerome --- doc/authentication.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/authentication.txt b/doc/authentication.txt index 814d5b95e..9b1bdc187 100644 --- a/doc/authentication.txt +++ b/doc/authentication.txt @@ -39,12 +39,12 @@ bcfg2.conf from the per-client metadata:: protocol = xmlrpc/ssl #if $self.metadata.uuid != None user = $self.metadata.uuid - #endif + #end if #if $self.metadata.password != None password = $self.metadata.password #else password = my-password-foobat - #endif + #end if [components] bcfg2 = https://localhost:6789 -- cgit v1.2.3-1-g7c22 From 9ca441386172affc7b3a68a9e8cf7c01f4c5913b Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 8 Nov 2010 22:15:59 +0100 Subject: Author changed for latex document --- doc/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index 95ce9d281..e11cc4ca8 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -175,7 +175,7 @@ latex_font_size = '11pt' # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('contents', 'bcfg2.tex', u'Bcfg2 Documentation', - u'Narayan Desai and Thorsten Lockert', 'manual', True), + u'Narayan Desai et al.', 'manual', True), ] # The name of an image file (relative to this directory) to place at the top of -- cgit v1.2.3-1-g7c22 From 553c693618321fad2a88030b16d42d3253befaec Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Mon, 8 Nov 2010 23:52:30 +0100 Subject: Directories moved --- doc/getting_help/index.txt | 33 +++++ doc/getting_help/irc.txt | 45 ++++++ doc/getting_help/mailinglist.txt | 24 ++++ doc/help/index.txt | 33 ----- doc/help/irc.txt | 45 ------ doc/help/mailinglist.txt | 24 ---- doc/reports/dynamic.txt | 270 +++++++++++++++++++++++++++++++++++ doc/reports/index.txt | 29 ++++ doc/reports/install.txt | 183 ++++++++++++++++++++++++ doc/reports/item_detail.jpg | Bin 0 -> 98249 bytes doc/reports/node_dropdown.jpg | Bin 0 -> 148486 bytes doc/reports/static.txt | 100 +++++++++++++ doc/reports/summary_cal.jpg | Bin 0 -> 175328 bytes doc/server/reports/dynamic.txt | 270 ----------------------------------- doc/server/reports/index.txt | 29 ---- doc/server/reports/install.txt | 183 ------------------------ doc/server/reports/item_detail.jpg | Bin 98249 -> 0 bytes doc/server/reports/node_dropdown.jpg | Bin 148486 -> 0 bytes doc/server/reports/static.txt | 100 ------------- doc/server/reports/summary_cal.jpg | Bin 175328 -> 0 bytes 20 files changed, 684 insertions(+), 684 deletions(-) create mode 100644 doc/getting_help/index.txt create mode 100644 doc/getting_help/irc.txt create mode 100644 doc/getting_help/mailinglist.txt delete mode 100644 doc/help/index.txt delete mode 100644 doc/help/irc.txt delete mode 100644 doc/help/mailinglist.txt create mode 100644 doc/reports/dynamic.txt create mode 100644 doc/reports/index.txt create mode 100644 doc/reports/install.txt create mode 100644 doc/reports/item_detail.jpg create mode 100644 doc/reports/node_dropdown.jpg create mode 100644 doc/reports/static.txt create mode 100644 doc/reports/summary_cal.jpg delete mode 100644 doc/server/reports/dynamic.txt delete mode 100644 doc/server/reports/index.txt delete mode 100644 doc/server/reports/install.txt delete mode 100644 doc/server/reports/item_detail.jpg delete mode 100644 doc/server/reports/node_dropdown.jpg delete mode 100644 doc/server/reports/static.txt delete mode 100644 doc/server/reports/summary_cal.jpg diff --git a/doc/getting_help/index.txt b/doc/getting_help/index.txt new file mode 100644 index 000000000..bc713bcbe --- /dev/null +++ b/doc/getting_help/index.txt @@ -0,0 +1,33 @@ +.. -*- mode: rst -*- + +.. _help-index: + +======================= +Getting Help with Bcfg2 +======================= + +Having trouble? We'd like to help! + +* Try the :ref:`FAQ ` -- it's got answers to many common questions. +* Looking for specific information? Try the :ref:`genindex`, :ref:`modindex` or the :ref:`detailed table of contents `. +* Search for information in the :ref:`help-mailinglist`. +* Visit our :ref:`help-irc` channel. + +.. _report-a-bug: + +Report A Bug +============ + +Report bugs with Bcfg2 on the `Trac ticket tracker`_. + +.. _Bcfg2 mailing list archives: http://trac.mcs.anl.gov/projects/bcfg2/wiki/MailingList +.. _Trac ticket tracker: http://trac.mcs.anl.gov/projects/bcfg2/wiki + +Other ways to get in touch +========================== + +.. toctree:: + :maxdepth: 2 + + irc + mailinglist diff --git a/doc/getting_help/irc.txt b/doc/getting_help/irc.txt new file mode 100644 index 000000000..37d2099d3 --- /dev/null +++ b/doc/getting_help/irc.txt @@ -0,0 +1,45 @@ +.. -*- mode: rst -*- + +.. _help-irc: + +=== +IRC +=== + +The Bcfg2 IRC channel is `#bcfg2 on chat.freenode.net`_. It is home +to both support and development discussions. If you have a question, +suggestion, or just want to know about Bcfg2, please drop in and say hi. + +.. _#bcfg2 on chat.freenode.net: irc://chat.freenode.net/bcfg2 + +Archives are available at: http://colabti.org/irclogger/irclogger_logs/bcfg2. + +.. raw:: html + +
+ + +
+ in the timespan + + (yyyymmdd-yyyymmdd) +

Options:
+
+
+ + +Administrative Note +=================== + +If the IRC logging stops working for a while, coordinate on #bcfg2 and +then bug **feb** on #irclogger (freenode), and stick around on that +channel until you get an answer (**feb** is great, but busy and in a +non-US time zone). Actually as long as **ilogger2** is logged in you +should be okay (**feb** looks at the logs). + +If you have private logs for the period of time **ilogger2** was off the +channel, you can convert them to the `format shown here`_, and **feb** +will incorporate them into the online logs. Be sure to strip out any +private messages in your logs first :-) + +.. _format shown here: http://colabti.org/irclogger/irclogger_log/bcfg2?date=2008-03-21,Fri;raw=on diff --git a/doc/getting_help/mailinglist.txt b/doc/getting_help/mailinglist.txt new file mode 100644 index 000000000..c77caa0c4 --- /dev/null +++ b/doc/getting_help/mailinglist.txt @@ -0,0 +1,24 @@ +.. -*- mode: rst -*- + +.. _help-mailinglist: + +============ +Mailing List +============ + +To subscribe to the mailing list for Bcfg2 please visit the `bcfg-dev +mailman page`_ + +`Searchable archives`_ are available from Gmane. You can also read the +mailing list from any NNTP client via Gmane. + +.. _bcfg-dev mailman page: https://lists.mcs.anl.gov/mailman/listinfo/bcfg-dev +.. _Searchable archives: http://dir.gmane.org/gmane.comp.sysutils.bcfg2.devel + +.. raw:: html + +
+ + + + diff --git a/doc/help/index.txt b/doc/help/index.txt deleted file mode 100644 index bc713bcbe..000000000 --- a/doc/help/index.txt +++ /dev/null @@ -1,33 +0,0 @@ -.. -*- mode: rst -*- - -.. _help-index: - -======================= -Getting Help with Bcfg2 -======================= - -Having trouble? We'd like to help! - -* Try the :ref:`FAQ ` -- it's got answers to many common questions. -* Looking for specific information? Try the :ref:`genindex`, :ref:`modindex` or the :ref:`detailed table of contents `. -* Search for information in the :ref:`help-mailinglist`. -* Visit our :ref:`help-irc` channel. - -.. _report-a-bug: - -Report A Bug -============ - -Report bugs with Bcfg2 on the `Trac ticket tracker`_. - -.. _Bcfg2 mailing list archives: http://trac.mcs.anl.gov/projects/bcfg2/wiki/MailingList -.. _Trac ticket tracker: http://trac.mcs.anl.gov/projects/bcfg2/wiki - -Other ways to get in touch -========================== - -.. toctree:: - :maxdepth: 2 - - irc - mailinglist diff --git a/doc/help/irc.txt b/doc/help/irc.txt deleted file mode 100644 index 37d2099d3..000000000 --- a/doc/help/irc.txt +++ /dev/null @@ -1,45 +0,0 @@ -.. -*- mode: rst -*- - -.. _help-irc: - -=== -IRC -=== - -The Bcfg2 IRC channel is `#bcfg2 on chat.freenode.net`_. It is home -to both support and development discussions. If you have a question, -suggestion, or just want to know about Bcfg2, please drop in and say hi. - -.. _#bcfg2 on chat.freenode.net: irc://chat.freenode.net/bcfg2 - -Archives are available at: http://colabti.org/irclogger/irclogger_logs/bcfg2. - -.. raw:: html - -
- - -
- in the timespan - - (yyyymmdd-yyyymmdd) -

Options:
-
-
- - -Administrative Note -=================== - -If the IRC logging stops working for a while, coordinate on #bcfg2 and -then bug **feb** on #irclogger (freenode), and stick around on that -channel until you get an answer (**feb** is great, but busy and in a -non-US time zone). Actually as long as **ilogger2** is logged in you -should be okay (**feb** looks at the logs). - -If you have private logs for the period of time **ilogger2** was off the -channel, you can convert them to the `format shown here`_, and **feb** -will incorporate them into the online logs. Be sure to strip out any -private messages in your logs first :-) - -.. _format shown here: http://colabti.org/irclogger/irclogger_log/bcfg2?date=2008-03-21,Fri;raw=on diff --git a/doc/help/mailinglist.txt b/doc/help/mailinglist.txt deleted file mode 100644 index c77caa0c4..000000000 --- a/doc/help/mailinglist.txt +++ /dev/null @@ -1,24 +0,0 @@ -.. -*- mode: rst -*- - -.. _help-mailinglist: - -============ -Mailing List -============ - -To subscribe to the mailing list for Bcfg2 please visit the `bcfg-dev -mailman page`_ - -`Searchable archives`_ are available from Gmane. You can also read the -mailing list from any NNTP client via Gmane. - -.. _bcfg-dev mailman page: https://lists.mcs.anl.gov/mailman/listinfo/bcfg-dev -.. _Searchable archives: http://dir.gmane.org/gmane.comp.sysutils.bcfg2.devel - -.. raw:: html - -
- - - - diff --git a/doc/reports/dynamic.txt b/doc/reports/dynamic.txt new file mode 100644 index 000000000..1ec41af64 --- /dev/null +++ b/doc/reports/dynamic.txt @@ -0,0 +1,270 @@ +.. -*- mode: rst -*- + +.. _server-reports-dynamic: + +============================== +Bcfg2 Dynamic Reporting System +============================== + +.. versionadded:: 0.8.2 + +Installation +============ + +Prerequisites +------------- + +* sqlite3 +* pysqlite2 +* `Django `_ +* mod-python + +Install +------- + +Be sure to include the specified fields included in the example +``bcfg2.conf`` file. These can be specified in either ``/etc/bcfg2.conf``, +if it is readable by the webserver user, or ``/etc/bcfg2-web.conf``. Any +database supported by Django can be used. If you are not using sqlite +(the default choice), please see the :ref:`alternative-databases` +section below. + +.. note:: + + Distributed environments can share a single remote database for + reporting. + +The recommended statistics plugin is DBStats. To use it, add it to the +**plugins** line in your ``bcfg2.conf``. Alternatively, the Statistics +plugin can be used in conjunction with a crontab entry to run +``/usr/sbin/bcfg2-admin reports load_stats``. + +Detailed installation instructions can be found :ref:`here `. + +.. _dynamic-http-install: + +Apache configuration for web-based reports +------------------------------------------ + +.. note:: + + Reports no longer needs to be installed at the root URL for a given + host. Therefore, reports no longer require their own virtual host. + + In order to make this work, you will need to specify your web prefix + by adding a **web_prefix** setting in the [statistics] section of + your ``bcfg2.conf``. + +An example site config is included below for the vhost "reports.mcs.anl.gov":: + + + ServerAdmin webmaster@mcs.anl.gov + ServerName reports.mcs.anl.gov + DocumentRoot /var/www/reports + + Order deny,allow + Deny from all + Allow from localhost #you may want to change this + AllowOverride None + + + # Possible values include: debug, info, notice, warn, error, crit, + # alert, emerg. + LogLevel warn + + ServerSignature Off + + # Stop TRACE/TRACK vulnerability + + RewriteEngine on + RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) + RewriteRule .* - [F] + + + SetHandler python-program + PythonHandler django.core.handlers.modpython + SetEnv DJANGO_SETTINGS_MODULE Bcfg2.Server.Reports.settings + PythonDebug On + + + SetHandler None + + + +The first three lines of this configuration must be customized per site. + +The ``bcfg2-tarball/reports/site_media/`` directory needs to be copied +to ``/var/www/reports/site_media/`` It could live anywhere; as long as +the contents are accessible on the virtual host at ``/site_media/``. + +At this point you should be able to point your web browser to the +virtualhost you created and see the new reports + +Example WSGI configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +entry.wsgi:: + + import os, sys + os.environ['DJANGO_SETTINGS_MODULE'] = 'Bcfg2.Server.Reports.settings' + import django.core.handlers.wsgi + application = django.core.handlers.wsgi.WSGIHandler() + +Apache conf:: + + Alias /bcfg2reports/site_media "/path/to/site_media" + + Order deny,allow + Allow from all + AllowOverride None + + # If Python is installed in a non-standard prefix: + #WSGIPythonHome /python/prefix + #WSGIPythonPath /python/prefix/lib/python2.6/site-packages + WSGIScriptAlias /bcfg2reports "/another/path/to/entry.wsgi" + +.. _alternative-databases: + +Notes on Alternative Databases +------------------------------ + +If you choose to use a different database, you'll need to edit +``/etc/bcfg2.conf``. These fields should be updated in the [statistics] +section: + +* database_engine + + * ex: database_engine = mysql + * ex: database_engine = postgresql_psycopg2 + +* database_name +* database_user +* database_password +* database_host +* database_port (optional) + +Summary and Features +==================== + +The new reporting system was implemented to address a number of +deficiencies in the previous system. By storing statistics data in a +relational database, we are now able to view and analyze more information +about the state of the configuration, including information about previous +configuration. Specific features in the new system include: + +* The ability to look at a :ref:`reports-calendar-summary` with past + statistics information. +* More recent data concerning hosts. +* Additional information display in reports. Primarily, reasons for + :ref:`configuration item verification failure ` + are now accessible. +* Instead of static pages, pages are generated on the fly, allowing + users to drill down to find out about a :ref:`specific host + `, rather than only having one huge page with + too much information. + +Planned improvements include +============================ + +* Accounts, customized displays for each admin. And privacy of config data. +* Config browsing capabilities; to look at your config in an interesting way. +* Fixing all the known bugs from below. + +Unfortunately with all the improvements, there are a few less exciting +elements about the new reporting system. The new reporting system +moves away from static pages and towards a real web application, which +causes mainly problems with dependencies and makes installation more +difficult. This should become less of a problem over time as we develop +a better installation process for a web application. + +Usage +===== + +bcfg2-admin reports (command line script) +----------------------------------------- + +The bcfg2-admin tool provides management and maintenance capabilities for +the reporting database. A few useful `Django `_ +commands are provided as well. + +* init: Initialize a new database +* load_stats: Load statistics data from the Statistics plugin into the + database. This was importscript.py. +* scrub: Scrub the database for duplicate reasons. +* update: Apply any updates to the reporting database. Unlike the syncdb + command, this will modify existing tables. + +Django commands +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* syncdb: Create the tables for any models not installed. Django will + not modify any existing tables. +* sqlall: Print the sql statements used to create the database. Note: + This does not show the fixture data. +* validate: Validate the database against the current models. + +bcfg2-reports (command line script) +----------------------------------- + +bcfg2-reports allows you to retrieve data from the database about clients, +and the states of their current interactions. It also allows you to +change the expired/unexpired states. + +The utility runs as a standalone application. It does, however, use the +models from ``/src/lib/Server/Reports/reports/models.py``. + +A number of different options can be used to change what bcfg2-reports +displays:: + + Usage: python bcfg2-reports [option] ... + + Options and arguments (and corresponding environment variables): + -a : shows all hosts, including expired hosts + -b NAME : single-host mode - shows bad entries from the + current interaction of NAME + -c : shows only clean hosts + -d : shows only dirty hosts + -e NAME : single-host mode - shows extra entries from the + current interaction of NAME + -h : shows help and usage info about bcfg2-reports + -s NAME : single-host mode - shows bad and extra entries from + the current interaction of NAME + -x NAME : toggles expired/unexpired state of NAME + --badentry=KIND,NAME : shows only hosts whose current interaction has bad + entries in of KIND kind and NAME name; if a single + argument ARG1 is given, then KIND,NAME pairs will be + read from a file of name ARG1 + --extraentry=KIND,NAME : shows only hosts whose current interaction has extra + entries in of KIND kind and NAME name; if a single + argument ARG1 is given, then KIND,NAME pairs will be + read from a file of name ARG1 + --fields=ARG1,ARG2,... : only displays the fields ARG1,ARG2,... + (name,time,state) + --sort=ARG1,ARG2,... : sorts output on ARG1,ARG2,... (name,time,state) + --stale : shows hosts which haven't run in the last 24 hours + +Screenshots +=========== + +.. _reports-calendar-summary: + +Calendar Summary +---------------- + +.. image:: summary_cal.jpg + :alt: Calendar summary + +.. _reports-item-detail: + +Item detail +----------- + +.. image:: item_detail.jpg + :alt: Item detail + +Node dropdown +------------- + +.. _reports-node-dropdown: + +.. image:: node_dropdown.jpg + :alt: Node dropdown diff --git a/doc/reports/index.txt b/doc/reports/index.txt new file mode 100644 index 000000000..bef686305 --- /dev/null +++ b/doc/reports/index.txt @@ -0,0 +1,29 @@ +.. -*- mode: rst -*- + +.. _server-reports-index: + +The Bcfg2 Reporting System +========================== + +Bcfg2's reporting system is its killer feature. It allows administrators +to gain a broad understanding of the configuration state of their entire +environment. It summarizes + +* Configuration changes and when they were made +* Discrepancies between the specification and current client states + + * Clients can be grouped by misconfiguration type + +* Configuration entries that are not specified +* Overall client summaries according to these types + +There are two systems, the old system, which builds static reports based +on a series of XSLT stylesheets and a new dynamic reporting system that +uses django and a database backend. + +.. toctree:: + :maxdepth: 2 + + install + static + dynamic diff --git a/doc/reports/install.txt b/doc/reports/install.txt new file mode 100644 index 000000000..80f9342ae --- /dev/null +++ b/doc/reports/install.txt @@ -0,0 +1,183 @@ +.. -*- mode: rst -*- + +.. _EPEL: http://fedoraproject.org/wiki/EPEL + +.. This is combination of the Ubuntu guide and the Centos guide for + installing the web reports. + +.. _server-reports-install: + +===================== +Dynamic (web) Reports +===================== + +The first step is to install the needed software components like the +Django framework and the database (SQlite2). All packages for Fedora +are in the Fedora Package Collection or in EPEL_ for CentOS/RHEL:: + + [root@system01 ~]# yum -y install Django python-simplejson python-sqlite2 + +Of course is a web server needed as well:: + + [root@system01 ~]# yum -y install httpd mod_python + +The same packages are needed for Ubuntu systems:: + + [root@system01 ~]# aptitude install python-django apache2 libapache2-mod-python + +Now we need to create the sqlite database. Use the following command on +Fedora, CentOS, or RHEL.:: + + [root@system01 ~]# python /usr/lib/python2.4/site-packages/Bcfg2/Server/Reports/manage.py syncdb + Creating table auth_permission + Creating table auth_group + Creating table auth_user + Creating table auth_message + Creating table django_content_type + Creating table django_session + Creating table django_site + Creating table django_admin_log + Creating table reports_client + Creating table reports_ping + Creating table reports_interaction + Creating table reports_reason + Creating table reports_entries + Creating table reports_entries_interactions + Creating table reports_performance + Creating table reports_internaldatabaseversion + + 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.Permission model + Installing index for auth.Message model + Installing index for admin.LogEntry model + Installing index for reports.Client model + Installing index for reports.Ping model + Installing index for reports.Interaction model + Installing index for reports.Entries model + Installing index for reports.Entries_interactions model + +.. note:: There are different versions of Python available. If you are + unsure about your installed version use the following line instead of + the line above.:: + + [root@system01 ~]# PYVER=`python -c 'import sys;print(sys.version[0:3])'`; python /usr/lib/python$PYVER/site-packages/Bcfg2/site-packages/Bcfg2/Server/Reports/manage.py syncdb + +The path on Ubuntu systems is different. Please use the same path as shown +in the following command to execute the script on an Ubuntu machine in +the next steps:: + + [root@system01 ~]# python /usr/share/pyshared/Bcfg2/Server/Reports/manage.py syncdb + Creating table auth_permission + Creating table auth_group + Creating table auth_user + Creating table auth_message + Creating table django_content_type + Creating table django_session + Creating table django_site + Creating table django_admin_log + Creating table reports_client + Creating table reports_ping + Creating table reports_interaction + Creating table reports_reason + Creating table reports_entries + Creating table reports_entries_interactions + Creating table reports_performance + Creating table reports_internaldatabaseversion + + 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.Permission model + Installing index for auth.Message model + Installing index for admin.LogEntry model + Installing index for reports.Client model + Installing index for reports.Ping model + Installing index for reports.Interaction model + Installing index for reports.Entries model + Installing index for reports.Entries_interactions model + +The server should be tested to make sure that there are no mistakes:: + + [root@system01 ~]# python /usr/lib/python2.6/site-packages/Bcfg2/Server/Reports/manage.py testserver + Creating test database... + Creating table auth_permission + Creating table auth_group + Creating table auth_user + Creating table auth_message + Creating table django_content_type + Creating table django_session + Creating table django_site + Creating table django_admin_log + Creating table reports_client + Creating table reports_ping + Creating table reports_interaction + Creating table reports_reason + Creating table reports_entries + Creating table reports_entries_interactions + Creating table reports_performance + Creating table reports_internaldatabaseversion + Installing index for auth.Permission model + Installing index for auth.Message model + Installing index for admin.LogEntry model + Installing index for reports.Client model + Installing index for reports.Ping model + Installing index for reports.Interaction model + Installing index for reports.Entries model + Installing index for reports.Entries_interactions model + Validating models... + 0 errors found + + Django version 1.1.1, using settings 'Reports.settings' + Development server is running at http://127.0.0.1:8000/ + Quit the server with CONTROL-C. + +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,Packages,Probes,Rules,SSHbase + +Start/restart the Bcfg2 server:: + + [root@system01 ~]# /etc/init.d/bcfg2-server restart + +Run the Bcfg2 client in order to populate the statistics database +(this run should take a bit longer since you are uploading the client +statistics to the database). + +Download the static reports content:: + + [root@system01 ~]# cd /var/www/ + [root@system01 ~]# svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2/reports + +Configure Apache using :ref:`dynamic-http-install` as a guide + +Copy server/statistics sections of ``bcfg2.conf`` to +``/etc/bcfg2-web.conf`` (make sure it is world-readable). You should +then have something like this:: + + [server] + repository = /var/lib/bcfg2 + plugins = Base,Bundler,Cfg,DBStats,Metadata,Packages,Probes,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. + #/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 + +Restart apache and point a browser to your Bcfg2 server. + +If using sqlite be sure the sql database file and directory containing the database are writable to apache. diff --git a/doc/reports/item_detail.jpg b/doc/reports/item_detail.jpg new file mode 100644 index 000000000..198880599 Binary files /dev/null and b/doc/reports/item_detail.jpg differ diff --git a/doc/reports/node_dropdown.jpg b/doc/reports/node_dropdown.jpg new file mode 100644 index 000000000..d3f7d4f14 Binary files /dev/null and b/doc/reports/node_dropdown.jpg differ diff --git a/doc/reports/static.txt b/doc/reports/static.txt new file mode 100644 index 000000000..d5d96fe12 --- /dev/null +++ b/doc/reports/static.txt @@ -0,0 +1,100 @@ +.. -*- mode: rst -*- + +.. _server-reports-static: + +============================= +Bcfg2 Static Reporting System +============================= + +The Bcfg2 reporting system collects and displays information about the +operation of the Bcfg2 client, and the configuration states of target +machines. + +Goals +===== + +The reporting system provides an interface to administrators describing +a few important tasks + +* Client configuration state, particularly aspects that do not match the configuration specification. + Information about bad and extra configuration elements is included. +* Client execution results (a list of configuration elements that were modified) +* Client execution performance data (including operation retry counts, and timings for several critical execution regions) + +This data can be used to understand the current configuration state +of the entire network, the operations performed by the client, how the +configuration changes propagate, and any reconfiguration operations that +have failed. + +Retention Model +=============== + +The current reporting system stores statistics in an XML data store, by +default to {{{/etc/statistics.xml}}}. It retains either one or two +statistic sets per host. If the client has a clean configuration state, +the most recent (clean) record is retained. If the client has a dirty +configuration state, two records are retained. One record is the last +clean record. The other record is the most recent record collected, +detailing the incorrect state. + +This retention model, while non-optimal, does manage to persistently +record most of the data that users would like. + +Setup +===== + +In order to configure your Bcfg2 server for receiving reports, you +will need to list the Statistics plugin in the plugins line of your +``bcfg2.conf``. You will also need a [statistics] section +in your ``bcfg2.conf``. You can find out more about what goes there in the +``bcfg2.conf`` manpage. + +Output +====== + +Several output reports can be generated from the statistics store with +the command line tool {{{bcfg2-build-reports}}}. + +* Nodes Digest +* Nodes Individual +* Overview Statistics +* Performance + +The data generated by these reports can be delivered by several +mechanisms: + +* HTML +* Email +* RSS + +Shortcomings and Planned Enhancements +===================================== + +When designing the current reporting system, we were overly concerned with +the potential explosion in data size over time. In order to address this, +we opted to use the retention scheme described above. This approach has +several shortcomings: + +* A comprehensive list of reconfiguration operations (with associated + timestamps) isn't retained +* Client results for any given day (except the last one) aren't uniformly + retained. This means that inter-client analysis is difficult, if + not impossible + +We plan to move to a database backend to address the dataset size +problem and start retaining all information. The move to a SQL backend +will allow many more types of queries to be efficiently processed. It +will also make on-demand reports simpler. + +Other sorts of information would also be useful to track. We plan to +add the ability to tag a particular configuration element as security +related, and include this in reports. This will aid in the effective +prioritization of manual and failed reconfiguration tasks. + +Capability Goals (posed as questions) +------------------------------------- + +* What machines have not yet applied critical updates? +* How long did critical updates take to be applied? +* What configuration did machine X have on a particular date? +* When did machine X perform configuration update Y? diff --git a/doc/reports/summary_cal.jpg b/doc/reports/summary_cal.jpg new file mode 100644 index 000000000..fab010762 Binary files /dev/null and b/doc/reports/summary_cal.jpg differ diff --git a/doc/server/reports/dynamic.txt b/doc/server/reports/dynamic.txt deleted file mode 100644 index 1ec41af64..000000000 --- a/doc/server/reports/dynamic.txt +++ /dev/null @@ -1,270 +0,0 @@ -.. -*- mode: rst -*- - -.. _server-reports-dynamic: - -============================== -Bcfg2 Dynamic Reporting System -============================== - -.. versionadded:: 0.8.2 - -Installation -============ - -Prerequisites -------------- - -* sqlite3 -* pysqlite2 -* `Django `_ -* mod-python - -Install -------- - -Be sure to include the specified fields included in the example -``bcfg2.conf`` file. These can be specified in either ``/etc/bcfg2.conf``, -if it is readable by the webserver user, or ``/etc/bcfg2-web.conf``. Any -database supported by Django can be used. If you are not using sqlite -(the default choice), please see the :ref:`alternative-databases` -section below. - -.. note:: - - Distributed environments can share a single remote database for - reporting. - -The recommended statistics plugin is DBStats. To use it, add it to the -**plugins** line in your ``bcfg2.conf``. Alternatively, the Statistics -plugin can be used in conjunction with a crontab entry to run -``/usr/sbin/bcfg2-admin reports load_stats``. - -Detailed installation instructions can be found :ref:`here `. - -.. _dynamic-http-install: - -Apache configuration for web-based reports ------------------------------------------- - -.. note:: - - Reports no longer needs to be installed at the root URL for a given - host. Therefore, reports no longer require their own virtual host. - - In order to make this work, you will need to specify your web prefix - by adding a **web_prefix** setting in the [statistics] section of - your ``bcfg2.conf``. - -An example site config is included below for the vhost "reports.mcs.anl.gov":: - - - ServerAdmin webmaster@mcs.anl.gov - ServerName reports.mcs.anl.gov - DocumentRoot /var/www/reports - - Order deny,allow - Deny from all - Allow from localhost #you may want to change this - AllowOverride None - - - # Possible values include: debug, info, notice, warn, error, crit, - # alert, emerg. - LogLevel warn - - ServerSignature Off - - # Stop TRACE/TRACK vulnerability - - RewriteEngine on - RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) - RewriteRule .* - [F] - - - SetHandler python-program - PythonHandler django.core.handlers.modpython - SetEnv DJANGO_SETTINGS_MODULE Bcfg2.Server.Reports.settings - PythonDebug On - - - SetHandler None - - - -The first three lines of this configuration must be customized per site. - -The ``bcfg2-tarball/reports/site_media/`` directory needs to be copied -to ``/var/www/reports/site_media/`` It could live anywhere; as long as -the contents are accessible on the virtual host at ``/site_media/``. - -At this point you should be able to point your web browser to the -virtualhost you created and see the new reports - -Example WSGI configuration -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -entry.wsgi:: - - import os, sys - os.environ['DJANGO_SETTINGS_MODULE'] = 'Bcfg2.Server.Reports.settings' - import django.core.handlers.wsgi - application = django.core.handlers.wsgi.WSGIHandler() - -Apache conf:: - - Alias /bcfg2reports/site_media "/path/to/site_media" - - Order deny,allow - Allow from all - AllowOverride None - - # If Python is installed in a non-standard prefix: - #WSGIPythonHome /python/prefix - #WSGIPythonPath /python/prefix/lib/python2.6/site-packages - WSGIScriptAlias /bcfg2reports "/another/path/to/entry.wsgi" - -.. _alternative-databases: - -Notes on Alternative Databases ------------------------------- - -If you choose to use a different database, you'll need to edit -``/etc/bcfg2.conf``. These fields should be updated in the [statistics] -section: - -* database_engine - - * ex: database_engine = mysql - * ex: database_engine = postgresql_psycopg2 - -* database_name -* database_user -* database_password -* database_host -* database_port (optional) - -Summary and Features -==================== - -The new reporting system was implemented to address a number of -deficiencies in the previous system. By storing statistics data in a -relational database, we are now able to view and analyze more information -about the state of the configuration, including information about previous -configuration. Specific features in the new system include: - -* The ability to look at a :ref:`reports-calendar-summary` with past - statistics information. -* More recent data concerning hosts. -* Additional information display in reports. Primarily, reasons for - :ref:`configuration item verification failure ` - are now accessible. -* Instead of static pages, pages are generated on the fly, allowing - users to drill down to find out about a :ref:`specific host - `, rather than only having one huge page with - too much information. - -Planned improvements include -============================ - -* Accounts, customized displays for each admin. And privacy of config data. -* Config browsing capabilities; to look at your config in an interesting way. -* Fixing all the known bugs from below. - -Unfortunately with all the improvements, there are a few less exciting -elements about the new reporting system. The new reporting system -moves away from static pages and towards a real web application, which -causes mainly problems with dependencies and makes installation more -difficult. This should become less of a problem over time as we develop -a better installation process for a web application. - -Usage -===== - -bcfg2-admin reports (command line script) ------------------------------------------ - -The bcfg2-admin tool provides management and maintenance capabilities for -the reporting database. A few useful `Django `_ -commands are provided as well. - -* init: Initialize a new database -* load_stats: Load statistics data from the Statistics plugin into the - database. This was importscript.py. -* scrub: Scrub the database for duplicate reasons. -* update: Apply any updates to the reporting database. Unlike the syncdb - command, this will modify existing tables. - -Django commands -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -* syncdb: Create the tables for any models not installed. Django will - not modify any existing tables. -* sqlall: Print the sql statements used to create the database. Note: - This does not show the fixture data. -* validate: Validate the database against the current models. - -bcfg2-reports (command line script) ------------------------------------ - -bcfg2-reports allows you to retrieve data from the database about clients, -and the states of their current interactions. It also allows you to -change the expired/unexpired states. - -The utility runs as a standalone application. It does, however, use the -models from ``/src/lib/Server/Reports/reports/models.py``. - -A number of different options can be used to change what bcfg2-reports -displays:: - - Usage: python bcfg2-reports [option] ... - - Options and arguments (and corresponding environment variables): - -a : shows all hosts, including expired hosts - -b NAME : single-host mode - shows bad entries from the - current interaction of NAME - -c : shows only clean hosts - -d : shows only dirty hosts - -e NAME : single-host mode - shows extra entries from the - current interaction of NAME - -h : shows help and usage info about bcfg2-reports - -s NAME : single-host mode - shows bad and extra entries from - the current interaction of NAME - -x NAME : toggles expired/unexpired state of NAME - --badentry=KIND,NAME : shows only hosts whose current interaction has bad - entries in of KIND kind and NAME name; if a single - argument ARG1 is given, then KIND,NAME pairs will be - read from a file of name ARG1 - --extraentry=KIND,NAME : shows only hosts whose current interaction has extra - entries in of KIND kind and NAME name; if a single - argument ARG1 is given, then KIND,NAME pairs will be - read from a file of name ARG1 - --fields=ARG1,ARG2,... : only displays the fields ARG1,ARG2,... - (name,time,state) - --sort=ARG1,ARG2,... : sorts output on ARG1,ARG2,... (name,time,state) - --stale : shows hosts which haven't run in the last 24 hours - -Screenshots -=========== - -.. _reports-calendar-summary: - -Calendar Summary ----------------- - -.. image:: summary_cal.jpg - :alt: Calendar summary - -.. _reports-item-detail: - -Item detail ------------ - -.. image:: item_detail.jpg - :alt: Item detail - -Node dropdown -------------- - -.. _reports-node-dropdown: - -.. image:: node_dropdown.jpg - :alt: Node dropdown diff --git a/doc/server/reports/index.txt b/doc/server/reports/index.txt deleted file mode 100644 index bef686305..000000000 --- a/doc/server/reports/index.txt +++ /dev/null @@ -1,29 +0,0 @@ -.. -*- mode: rst -*- - -.. _server-reports-index: - -The Bcfg2 Reporting System -========================== - -Bcfg2's reporting system is its killer feature. It allows administrators -to gain a broad understanding of the configuration state of their entire -environment. It summarizes - -* Configuration changes and when they were made -* Discrepancies between the specification and current client states - - * Clients can be grouped by misconfiguration type - -* Configuration entries that are not specified -* Overall client summaries according to these types - -There are two systems, the old system, which builds static reports based -on a series of XSLT stylesheets and a new dynamic reporting system that -uses django and a database backend. - -.. toctree:: - :maxdepth: 2 - - install - static - dynamic diff --git a/doc/server/reports/install.txt b/doc/server/reports/install.txt deleted file mode 100644 index 80f9342ae..000000000 --- a/doc/server/reports/install.txt +++ /dev/null @@ -1,183 +0,0 @@ -.. -*- mode: rst -*- - -.. _EPEL: http://fedoraproject.org/wiki/EPEL - -.. This is combination of the Ubuntu guide and the Centos guide for - installing the web reports. - -.. _server-reports-install: - -===================== -Dynamic (web) Reports -===================== - -The first step is to install the needed software components like the -Django framework and the database (SQlite2). All packages for Fedora -are in the Fedora Package Collection or in EPEL_ for CentOS/RHEL:: - - [root@system01 ~]# yum -y install Django python-simplejson python-sqlite2 - -Of course is a web server needed as well:: - - [root@system01 ~]# yum -y install httpd mod_python - -The same packages are needed for Ubuntu systems:: - - [root@system01 ~]# aptitude install python-django apache2 libapache2-mod-python - -Now we need to create the sqlite database. Use the following command on -Fedora, CentOS, or RHEL.:: - - [root@system01 ~]# python /usr/lib/python2.4/site-packages/Bcfg2/Server/Reports/manage.py syncdb - Creating table auth_permission - Creating table auth_group - Creating table auth_user - Creating table auth_message - Creating table django_content_type - Creating table django_session - Creating table django_site - Creating table django_admin_log - Creating table reports_client - Creating table reports_ping - Creating table reports_interaction - Creating table reports_reason - Creating table reports_entries - Creating table reports_entries_interactions - Creating table reports_performance - Creating table reports_internaldatabaseversion - - 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.Permission model - Installing index for auth.Message model - Installing index for admin.LogEntry model - Installing index for reports.Client model - Installing index for reports.Ping model - Installing index for reports.Interaction model - Installing index for reports.Entries model - Installing index for reports.Entries_interactions model - -.. note:: There are different versions of Python available. If you are - unsure about your installed version use the following line instead of - the line above.:: - - [root@system01 ~]# PYVER=`python -c 'import sys;print(sys.version[0:3])'`; python /usr/lib/python$PYVER/site-packages/Bcfg2/site-packages/Bcfg2/Server/Reports/manage.py syncdb - -The path on Ubuntu systems is different. Please use the same path as shown -in the following command to execute the script on an Ubuntu machine in -the next steps:: - - [root@system01 ~]# python /usr/share/pyshared/Bcfg2/Server/Reports/manage.py syncdb - Creating table auth_permission - Creating table auth_group - Creating table auth_user - Creating table auth_message - Creating table django_content_type - Creating table django_session - Creating table django_site - Creating table django_admin_log - Creating table reports_client - Creating table reports_ping - Creating table reports_interaction - Creating table reports_reason - Creating table reports_entries - Creating table reports_entries_interactions - Creating table reports_performance - Creating table reports_internaldatabaseversion - - 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.Permission model - Installing index for auth.Message model - Installing index for admin.LogEntry model - Installing index for reports.Client model - Installing index for reports.Ping model - Installing index for reports.Interaction model - Installing index for reports.Entries model - Installing index for reports.Entries_interactions model - -The server should be tested to make sure that there are no mistakes:: - - [root@system01 ~]# python /usr/lib/python2.6/site-packages/Bcfg2/Server/Reports/manage.py testserver - Creating test database... - Creating table auth_permission - Creating table auth_group - Creating table auth_user - Creating table auth_message - Creating table django_content_type - Creating table django_session - Creating table django_site - Creating table django_admin_log - Creating table reports_client - Creating table reports_ping - Creating table reports_interaction - Creating table reports_reason - Creating table reports_entries - Creating table reports_entries_interactions - Creating table reports_performance - Creating table reports_internaldatabaseversion - Installing index for auth.Permission model - Installing index for auth.Message model - Installing index for admin.LogEntry model - Installing index for reports.Client model - Installing index for reports.Ping model - Installing index for reports.Interaction model - Installing index for reports.Entries model - Installing index for reports.Entries_interactions model - Validating models... - 0 errors found - - Django version 1.1.1, using settings 'Reports.settings' - Development server is running at http://127.0.0.1:8000/ - Quit the server with CONTROL-C. - -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,Packages,Probes,Rules,SSHbase - -Start/restart the Bcfg2 server:: - - [root@system01 ~]# /etc/init.d/bcfg2-server restart - -Run the Bcfg2 client in order to populate the statistics database -(this run should take a bit longer since you are uploading the client -statistics to the database). - -Download the static reports content:: - - [root@system01 ~]# cd /var/www/ - [root@system01 ~]# svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2/reports - -Configure Apache using :ref:`dynamic-http-install` as a guide - -Copy server/statistics sections of ``bcfg2.conf`` to -``/etc/bcfg2-web.conf`` (make sure it is world-readable). You should -then have something like this:: - - [server] - repository = /var/lib/bcfg2 - plugins = Base,Bundler,Cfg,DBStats,Metadata,Packages,Probes,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. - #/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 - -Restart apache and point a browser to your Bcfg2 server. - -If using sqlite be sure the sql database file and directory containing the database are writable to apache. diff --git a/doc/server/reports/item_detail.jpg b/doc/server/reports/item_detail.jpg deleted file mode 100644 index 198880599..000000000 Binary files a/doc/server/reports/item_detail.jpg and /dev/null differ diff --git a/doc/server/reports/node_dropdown.jpg b/doc/server/reports/node_dropdown.jpg deleted file mode 100644 index d3f7d4f14..000000000 Binary files a/doc/server/reports/node_dropdown.jpg and /dev/null differ diff --git a/doc/server/reports/static.txt b/doc/server/reports/static.txt deleted file mode 100644 index d5d96fe12..000000000 --- a/doc/server/reports/static.txt +++ /dev/null @@ -1,100 +0,0 @@ -.. -*- mode: rst -*- - -.. _server-reports-static: - -============================= -Bcfg2 Static Reporting System -============================= - -The Bcfg2 reporting system collects and displays information about the -operation of the Bcfg2 client, and the configuration states of target -machines. - -Goals -===== - -The reporting system provides an interface to administrators describing -a few important tasks - -* Client configuration state, particularly aspects that do not match the configuration specification. - Information about bad and extra configuration elements is included. -* Client execution results (a list of configuration elements that were modified) -* Client execution performance data (including operation retry counts, and timings for several critical execution regions) - -This data can be used to understand the current configuration state -of the entire network, the operations performed by the client, how the -configuration changes propagate, and any reconfiguration operations that -have failed. - -Retention Model -=============== - -The current reporting system stores statistics in an XML data store, by -default to {{{/etc/statistics.xml}}}. It retains either one or two -statistic sets per host. If the client has a clean configuration state, -the most recent (clean) record is retained. If the client has a dirty -configuration state, two records are retained. One record is the last -clean record. The other record is the most recent record collected, -detailing the incorrect state. - -This retention model, while non-optimal, does manage to persistently -record most of the data that users would like. - -Setup -===== - -In order to configure your Bcfg2 server for receiving reports, you -will need to list the Statistics plugin in the plugins line of your -``bcfg2.conf``. You will also need a [statistics] section -in your ``bcfg2.conf``. You can find out more about what goes there in the -``bcfg2.conf`` manpage. - -Output -====== - -Several output reports can be generated from the statistics store with -the command line tool {{{bcfg2-build-reports}}}. - -* Nodes Digest -* Nodes Individual -* Overview Statistics -* Performance - -The data generated by these reports can be delivered by several -mechanisms: - -* HTML -* Email -* RSS - -Shortcomings and Planned Enhancements -===================================== - -When designing the current reporting system, we were overly concerned with -the potential explosion in data size over time. In order to address this, -we opted to use the retention scheme described above. This approach has -several shortcomings: - -* A comprehensive list of reconfiguration operations (with associated - timestamps) isn't retained -* Client results for any given day (except the last one) aren't uniformly - retained. This means that inter-client analysis is difficult, if - not impossible - -We plan to move to a database backend to address the dataset size -problem and start retaining all information. The move to a SQL backend -will allow many more types of queries to be efficiently processed. It -will also make on-demand reports simpler. - -Other sorts of information would also be useful to track. We plan to -add the ability to tag a particular configuration element as security -related, and include this in reports. This will aid in the effective -prioritization of manual and failed reconfiguration tasks. - -Capability Goals (posed as questions) -------------------------------------- - -* What machines have not yet applied critical updates? -* How long did critical updates take to be applied? -* What configuration did machine X have on a particular date? -* When did machine X perform configuration update Y? diff --git a/doc/server/reports/summary_cal.jpg b/doc/server/reports/summary_cal.jpg deleted file mode 100644 index fab010762..000000000 Binary files a/doc/server/reports/summary_cal.jpg and /dev/null differ -- cgit v1.2.3-1-g7c22 From 391406c85d86dc931f3fdb2483a14d0f1e7e6355 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 9 Nov 2010 00:15:43 +0100 Subject: doc: Massive update --- doc/appendix/articles.txt | 25 + doc/appendix/books.txt | 12 + doc/appendix/configuration.txt | 15 + doc/appendix/configuration/mrepo.txt | 71 +++ doc/appendix/contributors.txt | 53 ++ doc/appendix/files.txt | 16 + doc/appendix/files/mysql.txt | 63 +++ doc/appendix/files/ntp.txt | 151 ++++++ doc/appendix/guides.txt | 16 + doc/appendix/guides/authentication.txt | 143 ++++++ doc/appendix/guides/centos.txt | 565 ++++++++++++++++++++++ doc/appendix/guides/converging_rhel5.txt | 116 +++++ doc/appendix/guides/fedora.txt | 477 ++++++++++++++++++ doc/appendix/guides/gentoo.txt | 177 +++++++ doc/appendix/guides/nat_howto.txt | 56 +++ doc/appendix/guides/ubuntu.txt | 479 ++++++++++++++++++ doc/appendix/guides/using-bcfg2-info.txt | 132 +++++ doc/appendix/guides/using-bcfg2-with-centos.txt | 79 +++ doc/appendix/guides/vcs.txt | 112 +++++ doc/appendix/index.txt | 27 ++ doc/appendix/papers.txt | 44 ++ doc/appendix/tools.txt | 14 + doc/architecture/client.txt | 112 +++++ doc/architecture/config-spec.txt | 54 +++ doc/architecture/design.txt | 77 +++ doc/architecture/goals.txt | 47 ++ doc/architecture/index.txt | 24 + doc/architecture/server.txt | 65 +++ doc/authentication.txt | 12 +- doc/client/tools/blast.txt | 10 + doc/client/tools/chkconfig.txt | 15 + doc/client/tools/debinit.txt | 9 + doc/client/tools/encap.txt | 9 + doc/client/tools/freebsdinit.txt | 9 + doc/client/tools/freebsdpackage.txt | 10 + doc/client/tools/index.txt | 171 +------ doc/client/tools/launchd.txt | 13 + doc/client/tools/portage.txt | 9 + doc/client/tools/posix.txt | 10 + doc/client/tools/rcupdate.txt | 10 + doc/client/tools/rpm.txt | 11 + doc/client/tools/rpmng.txt | 11 + doc/client/tools/smf.txt | 15 + doc/client/tools/sysv.txt | 9 + doc/client/tools/upstart.txt | 11 + doc/client/tools/yum.txt | 11 + doc/development/client-driver.txt | 75 +++ doc/development/documentation.txt | 75 +++ doc/development/emacs_snippet.txt | 60 +++ doc/development/index.txt | 334 ++----------- doc/development/plugin-types.txt | 46 ++ doc/development/plugins.txt | 45 ++ doc/development/server.txt | 83 ++++ doc/development/setup.txt | 19 + doc/development/specification_overview.png | Bin 0 -> 7693 bytes doc/development/testing.txt | 74 +++ doc/development/tips.txt | 23 + doc/development/vim_snippet.txt | 65 +++ doc/development/writing_plugins.txt | 104 ++++ doc/development/writing_specification.txt | 54 +++ doc/faq/client.txt | 14 - doc/faq/general.txt | 26 - doc/faq/index.txt | 11 - doc/getting_help/error-messages.txt | 45 ++ doc/getting_help/faq/client.txt | 16 + doc/getting_help/faq/general.txt | 72 +++ doc/getting_help/faq/index.txt | 17 + doc/getting_help/index.txt | 43 +- doc/getting_help/irc.txt | 45 -- doc/getting_help/ircchannel.txt | 28 ++ doc/getting_help/manpages.txt | 16 + doc/getting_help/manpages/bcfg2-admin.txt | 11 + doc/getting_help/manpages/bcfg2-build-reports.txt | 11 + doc/getting_help/manpages/bcfg2-conf.txt | 11 + doc/getting_help/manpages/bcfg2-info.txt | 11 + doc/getting_help/manpages/bcfg2-repo-validate.txt | 11 + doc/getting_help/manpages/bcfg2-server.txt | 11 + doc/getting_help/manpages/bcfg2.txt | 11 + doc/getting_help/reporting.txt | 12 + doc/getting_started/index.txt | 268 ++++++++-- doc/getting_started/using-bcfg2-info.txt | 132 ----- doc/getting_started/using-bcfg2-with-centos.txt | 79 --- doc/installation/distributions.txt | 17 + doc/installation/distro/archlinux.txt | 17 + doc/installation/distro/debian.txt | 24 + doc/installation/distro/fedora.txt | 23 + doc/installation/distro/gentoo.txt | 27 ++ doc/installation/distro/osx.txt | 29 ++ doc/installation/distro/rhel.txt | 31 ++ doc/installation/distro/ubuntu.txt | 36 ++ doc/installation/index.txt | 23 + doc/installation/packages.txt | 81 ++++ doc/installation/prerequisites.txt | 47 ++ doc/installation/source.txt | 64 +++ doc/server/plugins/generators/tcheetah.txt | 16 +- doc/server/plugins/generators/tgenshi/index.txt | 6 +- doc/server/plugins/grouping/metadata.txt | 67 --- doc/server/plugins/index.txt | 10 +- doc/server/plugins/properties.txt | 46 ++ doc/server/plugins/structures/bundler/index.txt | 2 +- doc/unsorted/contribute.txt | 81 ---- doc/unsorted/converging_rhel5.txt | 116 ----- doc/unsorted/developing_for_bcfg2.txt | 111 ----- doc/unsorted/development_tips.txt | 20 - doc/unsorted/development_writing_plugins.txt | 77 --- doc/unsorted/dynamic_groups.txt | 27 -- doc/unsorted/emacs_snippet.txt | 53 -- doc/unsorted/gentoo.txt | 177 ------- doc/unsorted/install.txt | 47 -- doc/unsorted/learningpython.txt | 23 - doc/unsorted/mrepo.txt | 71 --- doc/unsorted/nat_howto.txt | 56 --- doc/unsorted/writing_specification.txt | 3 +- 113 files changed, 5202 insertions(+), 1761 deletions(-) create mode 100644 doc/appendix/articles.txt create mode 100644 doc/appendix/books.txt create mode 100644 doc/appendix/configuration.txt create mode 100644 doc/appendix/configuration/mrepo.txt create mode 100644 doc/appendix/contributors.txt create mode 100644 doc/appendix/files.txt create mode 100644 doc/appendix/files/mysql.txt create mode 100644 doc/appendix/files/ntp.txt create mode 100644 doc/appendix/guides.txt create mode 100644 doc/appendix/guides/authentication.txt create mode 100644 doc/appendix/guides/centos.txt create mode 100644 doc/appendix/guides/converging_rhel5.txt create mode 100644 doc/appendix/guides/fedora.txt create mode 100644 doc/appendix/guides/gentoo.txt create mode 100644 doc/appendix/guides/nat_howto.txt create mode 100644 doc/appendix/guides/ubuntu.txt create mode 100644 doc/appendix/guides/using-bcfg2-info.txt create mode 100644 doc/appendix/guides/using-bcfg2-with-centos.txt create mode 100644 doc/appendix/guides/vcs.txt create mode 100644 doc/appendix/index.txt create mode 100644 doc/appendix/papers.txt create mode 100644 doc/appendix/tools.txt create mode 100644 doc/architecture/client.txt create mode 100644 doc/architecture/config-spec.txt create mode 100644 doc/architecture/design.txt create mode 100644 doc/architecture/goals.txt create mode 100644 doc/architecture/index.txt create mode 100644 doc/architecture/server.txt create mode 100644 doc/client/tools/blast.txt create mode 100644 doc/client/tools/chkconfig.txt create mode 100644 doc/client/tools/debinit.txt create mode 100644 doc/client/tools/encap.txt create mode 100644 doc/client/tools/freebsdinit.txt create mode 100644 doc/client/tools/freebsdpackage.txt create mode 100644 doc/client/tools/launchd.txt create mode 100644 doc/client/tools/portage.txt create mode 100644 doc/client/tools/posix.txt create mode 100644 doc/client/tools/rcupdate.txt create mode 100644 doc/client/tools/rpm.txt create mode 100644 doc/client/tools/rpmng.txt create mode 100644 doc/client/tools/smf.txt create mode 100644 doc/client/tools/sysv.txt create mode 100644 doc/client/tools/upstart.txt create mode 100644 doc/client/tools/yum.txt create mode 100644 doc/development/client-driver.txt create mode 100644 doc/development/documentation.txt create mode 100644 doc/development/emacs_snippet.txt create mode 100644 doc/development/plugin-types.txt create mode 100644 doc/development/plugins.txt create mode 100644 doc/development/server.txt create mode 100644 doc/development/setup.txt create mode 100644 doc/development/specification_overview.png create mode 100644 doc/development/testing.txt create mode 100644 doc/development/tips.txt create mode 100644 doc/development/vim_snippet.txt create mode 100644 doc/development/writing_plugins.txt create mode 100644 doc/development/writing_specification.txt delete mode 100644 doc/faq/client.txt delete mode 100644 doc/faq/general.txt delete mode 100644 doc/faq/index.txt create mode 100644 doc/getting_help/error-messages.txt create mode 100644 doc/getting_help/faq/client.txt create mode 100644 doc/getting_help/faq/general.txt create mode 100644 doc/getting_help/faq/index.txt delete mode 100644 doc/getting_help/irc.txt create mode 100644 doc/getting_help/ircchannel.txt create mode 100644 doc/getting_help/manpages.txt create mode 100644 doc/getting_help/manpages/bcfg2-admin.txt create mode 100644 doc/getting_help/manpages/bcfg2-build-reports.txt create mode 100644 doc/getting_help/manpages/bcfg2-conf.txt create mode 100644 doc/getting_help/manpages/bcfg2-info.txt create mode 100644 doc/getting_help/manpages/bcfg2-repo-validate.txt create mode 100644 doc/getting_help/manpages/bcfg2-server.txt create mode 100644 doc/getting_help/manpages/bcfg2.txt create mode 100644 doc/getting_help/reporting.txt delete mode 100644 doc/getting_started/using-bcfg2-info.txt delete mode 100644 doc/getting_started/using-bcfg2-with-centos.txt create mode 100644 doc/installation/distributions.txt create mode 100644 doc/installation/distro/archlinux.txt create mode 100644 doc/installation/distro/debian.txt create mode 100644 doc/installation/distro/fedora.txt create mode 100644 doc/installation/distro/gentoo.txt create mode 100644 doc/installation/distro/osx.txt create mode 100644 doc/installation/distro/rhel.txt create mode 100644 doc/installation/distro/ubuntu.txt create mode 100644 doc/installation/index.txt create mode 100644 doc/installation/packages.txt create mode 100644 doc/installation/prerequisites.txt create mode 100644 doc/installation/source.txt create mode 100644 doc/server/plugins/properties.txt delete mode 100644 doc/unsorted/contribute.txt delete mode 100644 doc/unsorted/converging_rhel5.txt delete mode 100644 doc/unsorted/developing_for_bcfg2.txt delete mode 100644 doc/unsorted/development_tips.txt delete mode 100644 doc/unsorted/development_writing_plugins.txt delete mode 100644 doc/unsorted/dynamic_groups.txt delete mode 100644 doc/unsorted/emacs_snippet.txt delete mode 100644 doc/unsorted/gentoo.txt delete mode 100644 doc/unsorted/install.txt delete mode 100644 doc/unsorted/learningpython.txt delete mode 100644 doc/unsorted/mrepo.txt delete mode 100644 doc/unsorted/nat_howto.txt diff --git a/doc/appendix/articles.txt b/doc/appendix/articles.txt new file mode 100644 index 000000000..4e31dd7ed --- /dev/null +++ b/doc/appendix/articles.txt @@ -0,0 +1,25 @@ +.. -*- mode: rst -*- + +.. _appendix-articles: + +======== +Articles +======== + +* Configuration and change management with Bcfg2: "The Dean" - The powerful Bcfg2 provides a sophisticated environment for centralized configuration management. + + * Marko Jung, Nils Magnus + * In the english 'Linux Magazine', 04/09, pages 30-35, April 2009 + * The `Bcfg2 code listings `_ for the article are public. + +* `Konfigurations- und Change-Management in Bcfg2 `_ + + * Marko Jung, Nils Magnus + * In the german 'Linux Magazin', 10/08, pages 76-80, September 2008 + * The `code listings `_ for the article are public. + +* `System Management Methodologies with Bcfg2 `_ + + * Narayan Desai, Rick Bradshaw and Joey Hagedorn + * In ;login: Magazine, Volume 31, #1, pages 11-18, February 2006 + diff --git a/doc/appendix/books.txt b/doc/appendix/books.txt new file mode 100644 index 000000000..7cb864810 --- /dev/null +++ b/doc/appendix/books.txt @@ -0,0 +1,12 @@ +.. -*- mode: rst -*- + +.. _appendix-books: + +===== +Books +===== + +* `Configuration Management with Bcfg2 `_ + + * Narayan Desai and Cory Lueninghoener + diff --git a/doc/appendix/configuration.txt b/doc/appendix/configuration.txt new file mode 100644 index 000000000..3c3258514 --- /dev/null +++ b/doc/appendix/configuration.txt @@ -0,0 +1,15 @@ +.. -*- mode: rst -*- + +.. _appendix-configuration: + +===================== +Example configuration +===================== + +This section contains useful configuration of additional tools. + +.. toctree:: + :maxdepth: 1 + :glob: + + configuration/* diff --git a/doc/appendix/configuration/mrepo.txt b/doc/appendix/configuration/mrepo.txt new file mode 100644 index 000000000..0633af98e --- /dev/null +++ b/doc/appendix/configuration/mrepo.txt @@ -0,0 +1,71 @@ +.. -*- mode: rst -*- + +.. _mrepo: http://dag.wieers.com/home-made/mrepo/ + +.. _appendix-configuration-mrepo: + +mrepo +===== + +This section describes how to setup an `mrepo`_ mirror. + +`mrepo`_ builds a local APT/Yum RPM repository from local ISO files, +downloaded updates, and extra packages from 3rd party repositories. It +takes care of setting up the ISO files, downloading the RPMs, +configuring HTTP access and providing PXE/TFTP resources for remote +network installations. + + +Sample mrepo configuration +-------------------------- + +:: + + ### Configuration file for mrepo + + ### The [main] section allows to override mrepo's default settings + ### The mrepo-example.conf gives an overview of all the possible settings + [main] + srcdir = /var/mrepo/src + wwwdir = /var/www/mrepo + confdir = /etc/mrepo.conf.d + arch = x86_64 + + mailto = + smtp-server = localhost + + hardlink = yes + shareiso = yes + + rsync-timeout = 3600 + + [centos5] + name = CentOS Server $release ($arch) + release = 5 + arch = x86_64 + metadata = yum repomd + + # ISO images + iso = centos-$release-server-$arch-DVD.iso + + #addons = rsync://mirrors.kernel.org/centos/$release/addons/$arch/RPMS + centosplus = rsync://mirrors.kernel.org/centos/$release/centosplus/$arch/RPMS + extras = rsync://mirrors.kernel.org/centos/$release/extras/$arch/RPMS + #fasttrack = rsync://mirrors.kernel.org/centos/$release/fasttrack/$arch/RPMS + os = rsync://mirrors.kernel.org/centos/$release/os/$arch/CentOS + updates = rsync://mirrors.kernel.org/centos/$release/updates/$arch/RPMS + dag = http://apt.sw.be/redhat/el$release/en/$arch/RPMS.dag + dries = http://apt.sw.be/redhat/el$release/en/$arch/RPMS.dries + rpmforge = http://apt.sw.be/redhat/el$release/en/$arch/RPMS.rpmforge + + ### Any other section is considered a definition for a distribution + ### You can put distribution sections in /etc/mrepo.conf.d/ + ### Examples can be found in the documentation at: + ### /usr/share/doc/mrepo-0.8.6/dists/. + +Update the repositories +----------------------- + +To update your local repository, just lauch the following command :: + + mrepo -ug diff --git a/doc/appendix/contributors.txt b/doc/appendix/contributors.txt new file mode 100644 index 000000000..88246b513 --- /dev/null +++ b/doc/appendix/contributors.txt @@ -0,0 +1,53 @@ +.. -*- mode: rst -*- + +.. _AUTHORS: http://trac.mcs.anl.gov/projects/bcfg2/browser/trunk/bcfg2/AUTHORS +.. _MCS: http://www.mcs.anl.gov/ + +.. _appendix-contributors: + +============ +Contributors +============ + +.. + This is list is no longer in chronological order like the + AUTHORS file because it's easier to maintain (for me). + Automatically sorted. + +In alphabetical order of the given name: + +- Brian Pellin and Andrew Lusk did substantial work on Bcfg1, some of which was used in the bcfg2 client. +- Chris Vuletich wrote some SSL code and the verification debugging code +- Cory Lueninghoener wrote the showentries function in ``bcfg2-info`` +- Daniel Clark created encap packages for bcfg2 and deps, wrote fossil-scm dvcs support, and helps with Debian packaging +- Danny Clark enabled the Encap packaging +- David Dahl worked on Hostbase +- David Strauss worked on CentOS, RHEL, Yum, and Bazaar VCS support +- Ed Smith has done substantial hardening of the bcfg client and server and implemented a common logging infrastructure. +- Fabian Affolter made some patches and worked on the manual +- Jason Pepas has written a RPM package list creator has contributed patches to the Red Hat toolset +- Joey Hagedorn has written the reporting subsystem, including StatReports, GenerateHostinfo, and the xslt, css and javascript associated with it. +- Jos Catnook fixed bugs +- Ken Raffenetti and Rick Bradshaw have written the Hostbase plugin +- Michael Jinks wrote the Gentoo tool drivers +- Narayan Desai has written most of bcfg2, including all parts not explicitly mentioned in this file +- Patrick Ruckstuhl fixed bugs in the templating +- Pedro Flores made the Reporting system design help +- Rick Bradshaw has written several of the tools included in the ``tools/`` subdirectory +- Sami Haahtinen has written Debian packaging logic. +- Scott Behrens and Rick Bradshaw have written the VHost plugin +- Scott Matott +- Sol Jerome squashes bugs, helps manage the project roadmap, and implements various interesting features. +- Ti Leggett worked on ebuild packaging and bugfixes, RPM packaging +- Zach Lowry Solaris support and general hardening + + +The entire MCS_ systems team has provided invaluable help in the +design process and refinement of the user interface. In particular, +Gene Rackow and Sandra Bittner have provided great assistance +throughout this project. Philip Steinbachs provided detailed +feedback as an early external user. + +The most updated listing is available in the AUTHORS_ file in the +SVN :term:`repository` of Bcfg2. + diff --git a/doc/appendix/files.txt b/doc/appendix/files.txt new file mode 100644 index 000000000..e5217b684 --- /dev/null +++ b/doc/appendix/files.txt @@ -0,0 +1,16 @@ +.. -*- mode: rst -*- + +.. _appendix-files: + +============= +Example files +============= + +In this section are some examples for getting started with a more +indeep usage of Bcfg2. + +.. toctree:: + :maxdepth: 1 + :glob: + + files/* diff --git a/doc/appendix/files/mysql.txt b/doc/appendix/files/mysql.txt new file mode 100644 index 000000000..ae4a1450b --- /dev/null +++ b/doc/appendix/files/mysql.txt @@ -0,0 +1,63 @@ +.. -*- mode: rst -*- + +.. _getting_started-mysql: + +.. Author: Patrick Ruckstuhl + +Mysql example +============= + +I had some time ago to continue with putting my configuration into +Bcfg2 and maybe this helps someone else. + +I added a new bundle: + +.. code-block:: xml + + + + + + + + + +The ``users.sh`` script looks like this: + +.. code-block:: sh + + #!/bin/sh + + mysql --defaults-extra-file=/etc/mysql/debian.cnf mysql \ + < /root/bcfg2-install/mysql/users.sql + +On debian there is a user account in ``/etc/mysql/debian.cnf`` +automatically created, but you could also (manually) create a +user in the database that has enough permissions and add the +login information in a file yourself. This file looks like this: + +.. code-block:: sh + + [client] + host = localhost + user = debian-sys-maint + password = XXXXXXXXXX + +The ``users.sql`` looks like this: + +.. code-block:: sh + + DELETE FROM db; + INSERT INTO db VALUES ('localhost', 'phpmyadmin', 'pma', 'Y', 'Y', + 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N'); + + DELETE FROM user WHERE User <> 'debian-sys-maint'; + INSERT INTO user VALUES ('localhost', 'root', 'XXXXXXXXXXX', 'Y', 'Y', + 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', + 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', 0, 0, 0); + INSERT INTO user VALUES ('localhost', 'pma', '', 'N', 'N', 'N', 'N', + 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', + 'N', 'N', 'N', '', '', '', '', 0, 0, 0); + + FLUSH PRIVILEGES; + diff --git a/doc/appendix/files/ntp.txt b/doc/appendix/files/ntp.txt new file mode 100644 index 000000000..33cb3bfbb --- /dev/null +++ b/doc/appendix/files/ntp.txt @@ -0,0 +1,151 @@ +.. -*- mode: rst -*- + +.. _appendix-files-ntp: + +.. Author: Jason Pepas + +ntp example +=========== + +Here is a series of example configurations for Bcfg2, each introducing +another layer of functionality. + +* After each change, run ``bcfg-repo-validate -v`` +* Run the server with ``bcfg2-server -v`` +* Update the client with ``bcfg2 -v -d -n`` (will not actually make + client changes) + +Package only +------------ + +Our example starts with the bare minimum configuration setup. We have +a client, a profile group, a list of packages, and a base configuration. + +.. code-block:: sh + + # cat Metadata/clients.xml + + + + +.. code-block:: sh + + # cat Metadata/groups.xml + + + + +.. code-block:: sh + + # cat Base/base.xml + + + + + + +.. code-block:: sh + + # cat Pkgmgr/packages.xml + + + + +Add service +----------- + +Configure the service, and add it to the base. + +.. code-block:: sh + + # cat Svcmgr/services.xml + + + + +.. code-block:: sh + + # cat Base/base.xml + + + + + + + +Add config file +--------------- + +Setup an ``etc/`` directory structure, and add it to the base. + +.. code-block:: sh + + # cat Cfg/etc/ntp.conf/ntp.conf + server ntp1.utexas.edu + +.. code-block:: sh + + # cat Base/base.xml + + + + + + + + +Create a bundle +--------------- + +The above configuration layout works fine for a single service, but +that method of organization would quickly become a nightmare as you +approach the number of packages, services, and config files required +to represent a fully configured host. Bundles allow the grouping of +related configuration entries that are used to provide a single +service. This is done for several reasons: + +* Grouping related things in one place makes it easier to add those + entries for a multiple groups of clients +* Grouping entries into bundles makes their validation occur + collectively. This means that config files can override the + contents of packages. Also, config files are rechecked after + packages are upgraded, so that they can be repaired if the + package install clobbered them. +* Services associated with a bundle get restarted whenever any entity + in that bundle is modified. This ensures that new configuration + files and software are used after installation. + +The config file, package, and service are really all related +components describing the idea of an ntp client, so they should be +logically grouped together. We use a bundle to accomplish this. + +.. code-block:: sh + + # cat Bundler/ntp.xml + + + + + + +After this bundle is created, it must be associated with a group +(or groups). Add a bundle child element to the group(s) which should +install this bundle. + +.. code-block:: sh + + # cat Metadata/groups.xml + + ... + + + + ... + + +Once this bundle is created, a client reconfigure will install these +entries. If any are modified, then the ``ntpd`` service will be +restarted. If you only want ntp configurations to be updated +(and nothing else), the bcfg2 client can be run with a +``-b `` option that will only update entries in +the specified bundle. diff --git a/doc/appendix/guides.txt b/doc/appendix/guides.txt new file mode 100644 index 000000000..81e77cc1f --- /dev/null +++ b/doc/appendix/guides.txt @@ -0,0 +1,16 @@ +.. -*- mode: rst -*- + +.. _appendix-guides: + +====== +Guides +====== + +This section contains platform-specific quickstart guides and howtos +around Bcfg2. + +.. toctree:: + :maxdepth: 1 + :glob: + + guides/* diff --git a/doc/appendix/guides/authentication.txt b/doc/appendix/guides/authentication.txt new file mode 100644 index 000000000..b9efbb929 --- /dev/null +++ b/doc/appendix/guides/authentication.txt @@ -0,0 +1,143 @@ +.. -*- mode: rst -*- + +.. _guide-authentication: + +============== +Authentication +============== + +Scenarios +========= + +1. Cluster nodes that are frequently rebuilt + + Default settings work well; machines do not float, and a per-client + password is not required. + +2. :ref:`NAT Howto nat_howto` + + * Build client records in advance with ``bcfg2-admin``, setting a uuid + for each new client. + + * Set the address attribute for each to the address of the NAT. + + * Optionally, set a per-client password for each, and set into secure + mode. + + .. note:: + + This will require the use of the uuid and password from each + client, and will require that they come through the NAT address. + +Building bcfg2.conf automatically +================================= + +This is a TCheetah template that automatically constructs per-client +`bcfg2.conf` from the per-client metadata:: + + [communication] + protocol = xmlrpc/ssl + #if $self.metadata.uuid != None + user = $self.metadata.uuid + #end if + #if $self.metadata.password != None + password = $self.metadata.password + #else + password = my-password-foobar + #end if + + [components] + bcfg2 = https://localhost:6789 + +In this setup, this will cause any clients that have uuids established +to be set to use them in `bcfg2.conf`. It will also cause any clients +with passwords set to use them instead of the global password. + +How Authentication Works +======================== + +#. First, the client is associated with a client record. If the client + specifies a uuid, it uses this instead of the results of a dns or + address lookup. + +#. Next, the ip address is verified against the client record. If the + address doesn't match, then the client must be set to + location=floating + +#. Finally, the password is verified. If the client is set to secure + mode, the only its per-client password is accepted. If it is not set + to secure mode, then either the global password or per-client password + will be accepted + +Failure during any of these stages results in authentication +failure. Note that clients set into secure mode that do not have +per-client passwords set will not be able to connect. + +SSL Cert-based client authentication +==================================== + +SSL-based client authentication is supported. This requires several +things: + +#. Certificate Authority (to sign all keys) + +#. Server key and cert signed by the CA + +#. Client key and cert signed by the CA + +A variety of CAs can be used, but these keys can be simply generated +using the following set of steps: + +#. Setup a CA + + http://www.flatmtn.com/article/setting-openssl-create-certificates + +#. Create keys for each client and server, signing them with the CA + signing cert + + http://www.flatmtn.com/article/setting-ssl-certificates-apache + + .. note:: + The client CN must be the FQDN of the client (as returned by a + reverse DNS lookup of the ip address. Otherwise, you will end up + with an error message on the client that looks like:: + + Server failure: Protocol Error: 401 Unauthorized + Failed to download probes from bcfg2 + Server Failure + + You will also see an error message on the server that looks + something like:: + + cmssrv01 bcfg2-server[9785]: Got request for cmssrv115 from incorrect address 131.225.206.122 + cmssrv01 bcfg2-server[9785]: Resolved to cmssrv115.fnal.gov + +#. Distribute the keys and certs to the appropriate locations + +#. Copy the ca cert to clients, so that the server can be authenticated + +Clients authenticating themselves with a certificate will be +authenticated that way first; clients can be setup to either +authenticate solely with certs, use certs with a fallback to password, +or password only. Also a bootstrap mode will be added shortly; this +will allow a client to authenticate with a password its first time, +requiring a certificate all subsequent times. This behavior can be +controlled through the use of the auth attribute in +`Metadata/clients.xml`:: + + + + + +Allowed values are: + + +---------------+------------------------------------------+ + | **Auth Type** | **Meaning** | + +---------------+------------------------------------------+ + | cert | Certificates must be used | + +---------------+------------------------------------------+ + | cert+password | Certificate or password may be used | + +---------------+------------------------------------------+ + | bootstrap | Password can be used for one client run, | + | | after that certificate is required | + +---------------+------------------------------------------+ diff --git a/doc/appendix/guides/centos.txt b/doc/appendix/guides/centos.txt new file mode 100644 index 000000000..91c1f268f --- /dev/null +++ b/doc/appendix/guides/centos.txt @@ -0,0 +1,565 @@ +.. -*- mode: rst -*- + +.. _EPEL: http://fedoraproject.org/wiki/EPEL + +.. _guide-centos: + +===================== +Quickstart for CentOS +===================== + +This is a complete getting started guide for CentOS. With this document +you should be able to install a Bcfg2 server and a Bcfg2 client. + +Install Bcfg2 +============= + +The fastest way to get Bcfg2 onto your system is to use Yum or +your preferred package management tool. We'll be using the ones +that are distributed through EPEL_, but depending on your aversion +to risk you could download an RPM from other places as well. See +:ref:`getting_started-using_bcfg2-with-centos` for information about +building Bcfg2 from source and making your own packages. + +Using EPEL +---------- + +Make sure EPEL_ is a valid repository on your server. The `instructions +`_ on how to do this +basically say:: + + [root@centos ~]# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm + +.. note:: + + You will have to adjust this command to match your architecture and + the current EPEL release. + +Install the bcfg2-server and bcfg2 RPMs:: + + [root@centos ~]# yum install bcfg2-server bcfg2 + +Your system should now have the necessary software to use Bcfg2. The +next step is to set up your Bcfg2 :term:`repository`. + +Initialize your repository +========================== + +Now that you're done with the install, you need to initialize your +repository and setup your ``/etc/bcfg2.conf``. ``bcfg2-admin init`` +is a tool which allows you to automate this:: + + [root@centos ~]# 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): + What is the server's hostname: [centos] + Input the server location [https://centos: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 + : 1 + Generating a 2048 bit RSA private key + .........................+++ + ..................+++ + writing new private key to '/etc/bcfg2.key' + ----- + Signature ok + subject=/C=US=ST=Illinois/L=Argonne/CN=centos + Getting Private key + Repository created successfuly in /var/lib/bcfg2 + +Change responses as necessary. + +Start the server +================ + +You are now ready to start your bcfg2 server for the first time:: + + [root@centos ~]# /sbin/service bcfg2-server start + +To verify that everything started ok, look for the running daemon and check the logs:: + + [root@centos ~]# /etc/init.d/service bcfg2-server status + [root@centos ~]# tail /var/log/messages + Mar 29 12:42:26 centos bcfg2-server[5093]: service available at https://centos:6789 + Mar 29 12:42:26 centos bcfg2-server[5093]: serving bcfg2-server at https://centos:6789 + Mar 29 12:42:26 centos bcfg2-server[5093]: serve_forever() [start] + Mar 29 12:42:41 centos bcfg2-server[5093]: Handled 16 events in 0.007s + +Run bcfg2 to be sure you are able to communicate with the server:: + + [root@centos ~]# bcfg2 -vqn + No ca is specified. Cannot authenticate the server with SSL. + No ca is specified. Cannot authenticate the server with SSL. + Loaded plugins: fastestmirror + Loading mirror speeds from cached hostfile + Excluding Packages in global exclude list + Finished + Loaded tool drivers: + Action Chkconfig POSIX YUMng + + Phase: initial + Correct entries: 0 + Incorrect entries: 0 + Total managed entries: 0 + Unmanaged entries: 208 + + + Phase: final + Correct entries: 0 + Incorrect entries: 0 + Total managed entries: 0 + Unmanaged entries: 208 + + No ca is specified. Cannot authenticate the server with SSL. + +The ca message is just a warning, meaning that the client does not +have sufficient information to verify that it is talking to the +correct server. This can be fixed by distributing the ca certificate +from the server to all clients. By default, this file is available in +``/etc/bcfg2.crt`` on the server. Copy this file to the client (with a +bundle) and add the ca option to ``bcfg2.conf`` pointing at the file, +and the client will be able to verify it is talking to the correct server +upon connection:: + + [root@centos ~]# cat /etc/bcfg2.conf + + + [communication] + protocol = xmlrpc/ssl + password = N41lMNeW + ca = /etc/bcfg2.crt + + [components] + bcfg2 = https://centos:6789 + +Now if you run the client, no more warning:: + + [root@centos ~]# bcfg2 -vqn + Loaded plugins: fastestmirror + Loading mirror speeds from cached hostfile + Excluding Packages in global exclude list + Finished + Loaded tool drivers: + Action Chkconfig POSIX YUMng + + Phase: initial + Correct entries: 0 + Incorrect entries: 0 + Total managed entries: 0 + Unmanaged entries: 208 + + + Phase: final + Correct entries: 0 + Incorrect entries: 0 + Total managed entries: 0 + Unmanaged entries: 208 + +Bring your first machine under Bcfg2 control +============================================ + +Now it is time to get your first machine's configuration into your +Bcfg2 :term:`repository`. Let's start with the server itself. + + +Setup the `Packages`_ plugin +---------------------------- + +.. _Packages: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Packages + +First, replace **Pkgmgr** with **Packages** in the plugins +line of ``bcfg2.conf``. Then create Packages layout (as per +:ref:`packages-exampleusage`) in ``/var/lib/bcfg2`` + +.. note:: I am using the RawURL syntax here since we are using `mrepo`_ + to manage our yum mirrors. + +.. _mrepo: http://dag.wieers.com/home-made/mrepo/ + +.. code-block:: xml + + + + + centos5.4 + http://mrepo/centos5-x86_64/RPMS.os + x86_64 + + + centos5.4 + http://mrepo/centos5-x86_64/RPMS.updates + x86_64 + + + centos5.4 + http://mrepo/centos5-x86_64/RPMS.extras + x86_64 + + + +Due to the `Magic Groups`_, we need to modify our Metadata. Let's +add a **centos5.4** group which inherits a **centos** group +(this should replace the existing **redhat** group) present in +``/var/lib/bcfg2/Metadata/groups.xml``. The resulting file should look +something like this + +.. _Magic Groups: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Packages#MagicGroups + +.. code-block:: xml + + + + + + + + + + + + + + + + + + +.. note:: + When editing your xml files by hand, it is useful to occasionally run + `bcfg2-repo-validate` to ensure that your xml validates properly. + +The final thing we need is for the client to have the proper +arch group membership. For this, we will make use of the +:ref:`unsorted-dynamic_groups` capabilities of the Probes plugin. Add +Probes to your plugins line in ``bcfg2.conf`` and create the Probe.:: + + [root@centos ~]# grep plugins /etc/bcfg2.conf + plugins = Base,Bundler,Cfg,Metadata,Packages,Probes,Rules,SSHbase + [root@centos ~]# mkdir /var/lib/bcfg2/Probes + [root@centos ~]# cat /var/lib/bcfg2/Probes/groups + #!/bin/sh + + echo "group:`uname -m`" + +Now we restart the bcfg2-server:: + + [root@centos ~]# /etc/init.d/bcfg2-server restart + +If you tail ``/var/log/syslog`` now, you will see the Packages plugin in +action, updating the cache. + +Start managing packages +----------------------- + +Add a base-packages bundle. Let's see what happens when we just populate +it with the *yum* package. + +.. code-block:: xml + + [root@centos ~]# cat /var/lib/bcfg2/Bundler/base-packages.xml + + + + +You need to reference the bundle from your Metadata. The resulting +profile group might look something like this + +.. code-block:: xml + + + + + + +Now if we run the client, we can see what this has done for us.:: + + [root@centos ~]# bcfg2 -vqn + Running probe groups + Probe groups has result: + x86_64 + Loaded plugins: fastestmirror + Loading mirror speeds from cached hostfile + Excluding Packages in global exclude list + Finished + Loaded tool drivers: + Action Chkconfig POSIX YUMng + Package pam failed verification. + + Phase: initial + Correct entries: 94 + Incorrect entries: 1 + Total managed entries: 95 + Unmanaged entries: 113 + + In dryrun mode: suppressing entry installation for: + Package:pam + + Phase: final + Correct entries: 94 + Incorrect entries: 1 + Package:pam + Total managed entries: 95 + Unmanaged entries: 113 + +Interesting, our **pam** package failed verification. What does this +mean? Let's have a look:: + + [root@centos ~]# rpm --verify pam + ....L... c /etc/pam.d/system-auth + +Sigh, it looks like the default RPM install for pam fails to verify +using its own verification process (trust me, it's not the only one). At +any rate, I was able to get rid of this particular issue by removing the +symlink and running ``yum reinstall pam``. + +As you can see, the Packages plugin has generated the dependencies +required for the yum package automatically. The ultimate goal should +be to move all the packages from the **Unmanaged** entries section to +the **Managed** entries section. So, what exactly *are* those Unmanaged +entries?:: + + [root@centos ~]# bcfg2 -veqn + Running probe groups + Probe groups has result: + x86_64 + Loaded plugins: fastestmirror + Loading mirror speeds from cached hostfile + Excluding Packages in global exclude list + Finished + Loaded tool drivers: + Action Chkconfig POSIX YUMng + Extra Package openssh-clients 4.3p2-36.el5_4.4.x86_64. + Extra Package libuser 0.54.7-2.1el5_4.1.x86_64. + ... + + Phase: initial + Correct entries: 95 + Incorrect entries: 0 + Total managed entries: 95 + Unmanaged entries: 113 + + + Phase: final + Correct entries: 95 + Incorrect entries: 0 + Total managed entries: 95 + Unmanaged entries: 113 + Package:at + Package:avahi + Package:avahi-compat-libdns_sd + ... + +Now you can go through these and continue adding the packages you want +to your Bundle. After a while, I ended up with a minimal bundle that +looks like this + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + +Now when I run the client, you can see I have only one unmanaged +package:: + + [root@centos ~]# bcfg2 -veqn + Running probe groups + Probe groups has result: + x86_64 + Loaded plugins: fastestmirror + Loading mirror speeds from cached hostfile + Excluding Packages in global exclude list + Finished + Loaded tool drivers: + Action Chkconfig POSIX YUMng + Extra Package gpg-pubkey e8562897-459f07a4.None. + Extra Package gpg-pubkey 217521f6-45e8a532.None. + + Phase: initial + Correct entries: 187 + Incorrect entries: 0 + Total managed entries: 187 + Unmanaged entries: 16 + + + Phase: final + Correct entries: 187 + Incorrect entries: 0 + Total managed entries: 187 + Unmanaged entries: 16 + Package:gpg-pubkey + Service:atd + Service:avahi-daemon + Service:bcfg2-server + ... + +The gpg-pubkey packages are special in that they are not really +packages. Currently, the way to manage them is using :ref:`BoundEntries +`. So, after adding them, our Bundle now looks like this + +.. note:: This does not actually control the contents of the files, + you will need to do this part separately (see below). + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + +To actually push the gpg keys out via Bcfg2, you will need to manage the +files as well. This can be done by adding Path entries for each of the +gpg keys you want to manage + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + + + +Then add the files to Cfg:: + + mkdir -p Cfg/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 + cp /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 !$/RPM-GPG-KEY-CentOS-5 + mkdir -p Cfg/etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL + cp /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL !$/RPM-GPG-KEY-EPEL + +Now, running the client shows only unmanaged Service entries. Woohoo! + +Manage services +--------------- + +Now let's clear up the unmanaged service entries by adding the following +entries to our bundle. + +.. code-block:: xml + + + + + + + + + + + + + + + + + + +...and bind them in Rules + +.. code-block:: xml + + [root@centos ~]# cat /var/lib/bcfg2/Rules/services.xml + + + + + + + + + + + + + + + + + + + +Now we run the client and see there are no more unmanaged entries! :: + + [root@centos ~]# bcfg2 -veqn + Running probe groups + Probe groups has result: + x86_64 + Loaded plugins: fastestmirror + Loading mirror speeds from cached hostfile + Excluding Packages in global exclude list + Finished + Loaded tool drivers: + Action Chkconfig POSIX YUMng + + Phase: initial + Correct entries: 205 + Incorrect entries: 0 + Total managed entries: 205 + Unmanaged entries: 0 + + + Phase: final + Correct entries: 205 + Incorrect entries: 0 + Total managed entries: 205 + Unmanaged entries: 0 + +Dynamic (web) reports +===================== + +See installation instructions at :ref:`server-reports-install` diff --git a/doc/appendix/guides/converging_rhel5.txt b/doc/appendix/guides/converging_rhel5.txt new file mode 100644 index 000000000..9d508e5e4 --- /dev/null +++ b/doc/appendix/guides/converging_rhel5.txt @@ -0,0 +1,116 @@ +.. -*- mode: rst -*- + +.. _unsorted-converging_rhel5: + +====================================== +Converging on Verification with RHEL 5 +====================================== + +Running verification +==================== + +To get complete verification status, run:: + + bcfg2 -vqned + +Unmanaged entries +================= + +* Package (top-level) + + #. Enable the "Packages" plugin in {{{/etc/bcfg2.conf}}}, and configure the Yum repositories in {{{/var/lib/bcfg2/Packages/config.xml}}}. + #. If a package is unwanted, remove it:: + + sudo yum remove PACKAGE + + #. Otherwise, add {{{}}} to the Base or Bundler configuration. + +* Package (dependency) + + #. Ensure the Yum repository sources configured in {{{/var/lib/bcfg2/Packages/config.xml}}} are correct. + #. Ensure the Yum repositories themselves are up-to-date with the main package and dependencies. + #. Rebuild the Packages plugin cache:: + + bcfg2-admin xcmd Packages.Refresh + +* Service + + #. Add {{{}}} to the Base or Bundler configuration. + #. Add {{{}}} to {{{/var/lib/bcfg2/Rules/services.xml}}}. + +Incorrect entries +================= + +For a "Package" +--------------- + +* Failed RPM verification + + #. Run {{{rpm -V PACKAGE}}} + #. Add configuration files (the ones with "c" next to them in the verification output) to {{{/var/lib/bcfg2/Cfg/}}}. + + * For example, {{{/etc/motd}}} to {{{/var/lib/bcfg2/Cfg/etc/motd/motd}}}. Yes, there is an extra directory level named after the file. + + #. Specify configuration files as {{{}}} in the Base or Bundler configuration. + #. Add directories to {{{/var/lib/bcfg2/Rules/directories.xml}}}. For example: + + .. code-block:: xml + + + + + + +* Multiple instances + + * Option A: Explicitly list the instances + + #. Drop the {{{}}} from the Base or Bundler configuration. + #. Add an explicit {{{}}} and {{{}}} configuration to a new Bundle, like the following: + + .. code-block:: xml + + + + + + + + + + #. Add the bundle to the applicable groups in {{{/var/lib/bcfg2/Metadata/groups.xml}}}. + + * Option B: Disable verification of the package + + #. Add {{{pkg_checks="false"}}} to the {{{}}} tag. + +For a "Path" +------------------- + + * Unclear verification problem (no details from BCFG2) + + 1. Run {{{bcfg2 -vqI}}} to see detailed verification issues (but deny any suggested actions). + + * Permissions mismatch + + 1. Create an {{{info.xml}}} file in the same directory as the configuration file. Example: + + .. code-block:: xml + + + + + + + + +Other troubleshooting tools +=========================== + + * Generate the physical configuration from the server side:: + + bcfg2-info buildfile /test test.example.com + + * Generate the physical configuration from the client side:: + + bcfg2 -vqn -c/root/bcfg2-physical.xml diff --git a/doc/appendix/guides/fedora.txt b/doc/appendix/guides/fedora.txt new file mode 100644 index 000000000..f3a5a3929 --- /dev/null +++ b/doc/appendix/guides/fedora.txt @@ -0,0 +1,477 @@ +.. -*- mode: rst -*- + +.. This guide is based on the Centos guide. + +.. _guide-fedora: + +====== +Fedora +====== + +This guide is work in progess. + + +This is a complete getting started guide for Fedora. With this +document you should be able to install a Bcfg2 server, a Bcfg2 client, +and change the ``/etc/motd`` file on the client. + +Install Bcfg2 From RPM +====================== + +The fastest way to get Bcfg2 onto your system is to use ``yum`` +or PackageKit. `` +um`` will pull all dependencies of Bcfg2 +automatically in. :: + + $ su -c 'yum install bcfg2-server bcfg2' + +Your system should now have the necessary software to use Bcfg2. +The next step is to set up your Bcfg2 :term:`repository`. + +Initialize your repository +========================== + +Now that you're done with the install, you need to initialize your +repository and setup your ``/etc/bcfg2.conf``. ``bcfg2-admin init`` +is a tool which allows you to automate this: + +.. code-block:: sh + + # bcfg2-admin init + Store bcfg2 configuration in [/etc/bcfg2.conf]: + Location of bcfg2 repository [/var/lib/bcfg2]: + Directory /var/lib/bcfg2 exists. Overwrite? [y/N]:y + Input password used for communication verification (without echoing; leave blank for a random): + What is the server's hostname: [config01.local.net] + Input the server location [https://config01.local.net: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 + : 1 + Generating a 1024 bit RSA private key + .......................................................++++++ + .....++++++ + writing new private key to '/etc/bcfg2.key' + ----- + Signature ok + subject=/C=US/ST=Illinois/L=Argonne/CN=config01.local.net + Getting Private key + Repository created successfuly in /var/lib/bcfg2 + +Change responses as necessary. + +Start the server +================ + +You are now ready to start your bcfg2 server for the first time:: + + $ su -c '/etc/init.d/bcfg2-server start' + Starting Configuration Management Server: bcfg2-server [ OK ] + +To verify that everything started ok, look for the running daemon and +check the logs: + +.. code-block:: sh + + $ su -c 'tail /var/log/messages' + May 16 14:14:57 config01 bcfg2-server[2746]: service available at https://config01.local.net:6789 + May 16 14:14:57 config01 bcfg2-server[2746]: serving bcfg2-server at https://config01.local.net:6789 + May 16 14:14:57 config01 bcfg2-server[2746]: serve_forever() [start] + May 16 14:14:57 config01 bcfg2-server[2746]: Handled 16 events in 0.009s + + +Run ``bcfg2`` to be sure you are able to communicate with the server: + +.. code-block:: sh + + $ su -c 'bcfg2 -vqne' + + /usr/lib/python2.6/site-packages/Bcfg2/Client/Tools/rpmtools.py:23: DeprecationWarning: the md5 module is deprecated; use hashlib instead + import md5 + Loaded plugins: presto, refresh-packagekit + Loaded tool drivers: + Action Chkconfig POSIX YUMng + Extra Package imsettings-libs 0.108.0-2.fc13.i686. + Extra Package PackageKit-device-rebind 0.6.4-1.fc13.i686. + ... + Extra Package newt-python 0.52.11-2.fc13.i686. + Extra Package pulseaudio-gdm-hooks 0.9.21-6.fc13.i686. + + Phase: initial + Correct entries: 0 + Incorrect entries: 0 + Total managed entries: 0 + Unmanaged entries: 1314 + + + Phase: final + Correct entries: 0 + Incorrect entries: 0 + Total managed entries: 0 + Unmanaged entries: 1314 + Package:ConsoleKit Package:jasper-libs Package:pcsc-lite-libs + Package:ConsoleKit-libs Package:java-1.5.0-gcj Package:perf + ... + Package:iw Package:pcre Service:sshd + Package:jack-audio-connection-kit Package:pcsc-lite Service:udev-post + +The ``bcfg2.conf`` file contains only standard plugins so far. + +.. code-block:: sh + + $ su -c '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. + #/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 = test1234 + certificate = /etc/bcfg2.crt + key = /etc/bcfg2.key + ca = /etc/bcfg2.crt + + [components] + bcfg2 = https://config01.local.net:6789 + + +Add the machines to Bcfg2 +------------------------- + +``bcfg2-admin`` can be used to add a machine to Bcfg2 easily. You +need to know the Fully Qualified Domain Name (FQDN) of ever system +you want to control through Bcfg2. :: + + bcfg2-admin client add + +Bring your first machine under Bcfg2 control +-------------------------------------------- + +Now it is time to get the first machine's configuration into the +Bcfg2 repository. The server will be the first machine. It's +already in the ``Metadata/client.xml``. + + +Setup the `Packages`_ plugin +++++++++++++++++++++++++++++ + +.. _Packages: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Packages + +First, replace **Pkgmgr** with **Packages** in the plugins +line of ``bcfg2.conf``. Then create `Packages/` directory in +``/var/lib/bcfg2`` :: + + $ su -c 'mkdir /var/lib/bcfg2/Packages' + +Create a ``config.xml`` file for the packages in +``/var/lib/bcfg2/Packages`` with the following content. Choose a +mirror near your location according the `Mirror list`_ . + +.. _Mirror list: http://mirrors.fedoraproject.org/publiclist/ + +.. code-block:: xml + + + + fedora-13 + ftp://fedora.tu-chemnitz.de/pub/linux/fedora/linux/releases/ + 13 + Fedora + i386 + x86_64 + + + +.. _Magic Groups: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Packages#MagicGroups + +Due to the `Magic Groups`_, we need to modify our Metadata. Let's +add a **fedora13** group which inherits a **fedora** group +(this should replace the existing **redhat** group) present in +``/var/lib/bcfg2/Metadata/groups.xml``. The resulting file should look +something like this + +.. code-block:: xml + + + + + + + + + + + + + + + + + +.. note:: + When editing your xml files by hand, it is useful to occasionally + run ``bcfg2-repo-validate`` to ensure that your xml validates + properly. + +Add a probe ++++++++++++ + +The next step for the client will be to have the proper +arch group membership. For this, we will make use of the +:ref:`server-plugins-grouping-dynamic_groups` capabilities of +the Probes plugin. Add **Probes** to your plugins line in ``bcfg2.conf`` +and create the Probe: + +.. code-block:: sh + + $ su -c 'mkdir /var/lib/bcfg2/Probes' + $ su -c 'cat /var/lib/bcfg2/Probes/groups' + #!/bin/sh + + echo "group:`uname -m`" + +Now a restart of ``bcfg2-server`` is needed:: + + $ su -c '/etc/init.d/bcfg2-server restart' + +To test the Probe just run ``bcfg2 -vqn``. + +.. code-block:: xml + + $ su -c 'bcfg2 -vqn' + Running probe group + Probe group has result: + group:i686 + ... + +Start managing packages ++++++++++++++++++++++++ + +Add a base-packages bundle. Let's see what happens when we just populate +it with the *yum* package. Create the ``base-packages.xml`` in your +``Bundler/`` directory with a entry for ``yum``. + +.. code-block:: xml + + $ cat /var/lib/bcfg2/Bundler/base-packages.xml + + + + +You need to reference the bundle from your ``group.xml``. The resulting +profile group might look something like this + +.. code-block:: xml + + + + + + +Now if we run the client, we can see what this has done for us.:: + + output + +As you can see, the Packages plugin has generated the dependencies +required for the yum package automatically. The ultimate goal should +be to move all the packages from the **Unmanaged** entries section +to the **Managed** entries section. So, what exactly *are* those +Unmanaged entries?:: + + output + +Now you can go through these and continue adding the packages you +want to your Bundle. After a while, I ended up with a minimal bundle +that looks like this + +.. code-block:: xml + + + + + +Now when I run the client, you can see I have only one unmanaged +package:: + + outout + +The gpg-pubkey packages are special in that they are not really +packages. Currently, the way to manage them is using +:ref:`BoundEntries `. So, after adding them, our +Bundle now looks like this + +.. note:: This does not actually control the contents of the files, + you will need to do this part separately (see below). + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + +To actually push the gpg keys out via Bcfg2, you will need to manage +the files as well. This can be done by adding Path entries for each +of the gpg keys you want to manage + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + + + +Then add the files to Cfg:: + + mkdir -p Cfg/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 + cp /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 !$/RPM-GPG-KEY-CentOS-5 + mkdir -p Cfg/etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL + cp /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL !$/RPM-GPG-KEY-EPEL + +Now, running the client shows only unmanaged Service entries. Woohoo! + +Manage services ++++++++++++++++ + +Now let's clear up the unmanaged service entries by adding the +following entries to our bundle... + +.. code-block:: xml + + + + + + + + + + + + + + + + + + +...and bind them in Rules + +.. code-block:: xml + + [root@centos ~]# cat /var/lib/bcfg2/Rules/services.xml + + + + + + + + + + + + + + + + + + + +Now we run the client and see there are no more unmanaged entries! :: + + $ su -c 'bcfg2 -veqn' + + +Adding Plugins +++++++++++++++ + +Git +--- + +.. _Git tutorial: http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html + +Adding the :ref:`server-plugins-version-git` plugins can preserve +versioning information. The first step is to add *Git* to your +plugin line:: + + plugins = Base,Bundler,Cfg,...,Git + +For tracking the configuration files in the ``/var/lib/bcfg2`` +directory a git repository need to be established:: + + git init + +For more detail about the setup of git please refer to a `git tutorial`_. +The first commit can be the empty or the allready populated directory:: + + git add . && git commit -a + +While running ``bcfg2-info`` the following line will show up:: + + Initialized git plugin with git directory = /var/lib/bcfg2/.git + + + + + diff --git a/doc/appendix/guides/gentoo.txt b/doc/appendix/guides/gentoo.txt new file mode 100644 index 000000000..023e6ac24 --- /dev/null +++ b/doc/appendix/guides/gentoo.txt @@ -0,0 +1,177 @@ +.. -*- mode: rst -*- + +.. _guide-gentoo: + +====== +Gentoo +====== + +This document tries to lay out anything Gentoo-specific that you need +to know in order to use Bcfg2. Mostly that has to do with getting it +to cooperate with the various pieces of Portage. Services, all things +POSIX, and just about anything else that Bcfg2 does will work the same +on Gentoo as on any other distribution. Bcfg2 is new on Gentoo; please +let the list know if you find errors or omissions. + +Installing Bcfg2 +================ + +Early in July 2008, Bcfg2 was added to the Gentoo portage tree. So far +it's only keyworded for ~x86, but we hope to see it soon in the amd64 and +x64-solaris ports. If you're using Gentoo on some other architecture, it +should still work provided that you have a reasonably up to date Python; +try adding `app-admin/bcfg2 ~*` to your `/etc/portage/package.keywords` +file. + +If you don’t use portage to install Bcfg2, you’ll want to make sure you +have all the prerequisites installed first. For a server, you’ll need: + +* ``app-admin/gamin`` or ``app-admin/fam`` +* ``dev-python/lxml`` + +Clients will need at least: + +* ``app-portage/gentoolkit`` + +Package Repository +================== + +You’ll need (to make) at least one archive of binary packages. The +Portage driver calls ``emerge`` with the ``–getbinpkgonly`` option. See +:manpage:`make.conf(5)` and :manpage:`emerge(1)` manpages, specifically +the *PORTAGE_BINHOST* environment variable. + +Time Saver: quickpkg +-------------------- + +If you have a standing Gentoo machine that you want to preserve or +propagate, you can generate a complete package archive based on the +present state of the system by using the quickpkg utility. For example: + +.. code-block:: sh + + for pkg in `equery -q l` ; do quickpkg "=$pkg" ; done + +…will leave you with a complete archive of all the packages on your +system in ``/usr/portage/packages/All``, which you can then move to your +ftp server. + +Cataloging Packages In Your Repository +-------------------------------------- + +Once you have a set of packages, you will need to create a catalog for +them in ``/var/lib/bcfg2/Pkgmgr``. Here’s a template: + +.. code-block:: xml + + + + + + + +…and a partially filled-out example, for our local Gentoo/VMware build: + +.. code-block:: xml + + + + + [...] + + + + +The `` name (in our example, “gentoo-200701-vmware”) should +be included by any host which will draw its packages from this list. Our +collection of packages for this class of machines is at the listed URI, +and we only have one collection of packages for this batch of machines so +in our case the `priority` doesn’t really matter, we’ve set it to `0`. + +Notice that package name fields are in `CAT/TITLE` format. + +Here is a hack which will generate a list of Package lines from +a system’s database of installed packages, especially useful in +conjunction with the `quickpkg` example above: + +.. code-block:: sh + + #!/bin/bash + for pkg in `equery -q l` ; do + title=`echo $pkg | sed -e 's/\(.*\)-\([0-9].*\)/\1/'` + version=`echo $pkg | sed -e 's/\(.*\)-\([0-9].*\)/\2/'` + echo " " + done + +Configuring Client Machines +=========================== + +Set up ``/etc/bcfg2.conf`` the way you would for any other Bcfg2 client. + +In ``make.conf``, set *PORTAGE_BINHOST* to point to the URI of +your package repository. You may want to create versions of +``make.conf`` for each package repository you maintain, with +appropriate *PORTAGE_BINHOST* URI's in each, and associated with +that package archive's group under ``Cfg`` -- for example, we have +``Cfg/etc/make.conf/make.conf.G99_gentoo-200701-vmware``. If a client +host switches groups, and the new group needs a different set of packages, +everything should just fall into place. + +Pitfalls +======== + +Package Verification Issues +--------------------------- + +As of this writing (2007/01/31), we’re aware of a number of packages +marked stable in the Gentoo x86 tree which, for one reason or another, +consistently fail to verify cleanly under `equery check`. In some cases +(pam, openldap), files which don’t (ever) exist on the system are +nonetheless recorded in the package database; in some (python, Bcfg2, +ahem), whole classes of files (.pyc and .pyo files) consistently fail +their md5sum checks; and in others, the problem appears to be a +discrepancy in the way that symlinks are created vs. the way they’re +recorded in the database. For example, in the OpenSSH package, +/usr/bin/slogin is a symlink to ./ssh, but equery expects it to point to +an unadorned ssh. An analogous situation exists with their manpages, +leading to noise like this:: + + # equery check openssh + [ Checking net-misc/openssh-4.5_p1 ] + !!! /etc/ssh/sshd_config has incorrect md5sum + !!! /usr/bin/slogin does not point to ssh + !!! /usr/share/man/man1/slogin.1.gz does not point to ssh.1.gz + !!! /etc/ssh/ssh_config has incorrect md5sum + * 62 out of 66 files good + +We can ignore the lines for ``ssh_config`` and ``sshd_config``; those will +be caught by Bcfg2 as registered config files and handled appropriately. + +Because Bcfg2 relies on the client system’s native package reporting +tool to judge the state of installed packages, complaints like these +about trivial or intractable verification failures can trigger unnecessary +bundle reinstalls when the Bcfg2 client runs. Bcfg2 will catch on after a +pass or two that the situation isn’t getting any better with repeated +package installs, stop trying, and list those packages as “bad” in +the client system’s statistics. + +Aside from filing bugs with the Gentoo package maintainers, your narrator +has been unable to come up with a good approach to this. Maybe write a +series of ``Rules`` definitions according to what the package database +thinks it should find, and/or stage copies of affected files under +``Cfg``, and associate those rules and files with the affected package in +a bundle? Annoying but possibly necessary if you want your stats file +to look good. + +/boot +----- + +Gentoo as well as some other distros recommend leaving ``/boot`` unmounted +during normal runtime. This can lead to trouble during verification and +package installation, for example when ``/boot/grub/grub.conf`` turns +up missing. The simplest way around this might just be to ensure that +``/boot`` is mounted whenever you run Bcfg2, possibly wrapping Bcfg2 +in a script for the purpose. I’ve also thought about adding *Action* +clauses to bundles for grub and our kernel packages, which would mount +``/boot`` before the bundle installs and unmount it afterward, but this +doesn’t get around the problem of those packages flunking verification. diff --git a/doc/appendix/guides/nat_howto.txt b/doc/appendix/guides/nat_howto.txt new file mode 100644 index 000000000..131c0c533 --- /dev/null +++ b/doc/appendix/guides/nat_howto.txt @@ -0,0 +1,56 @@ +.. -*- mode: rst -*- + +.. _unsorted-nat_howto: + +========= +NAT HOWTO +========= + +This page describes how to setup bcfg2 to properly function with a collection of clients behind NAT. It describes the issues, how the underlying portions of the bcfg2 system function, and how to correctly setup client metadata to cope with this environment. + +Issues +====== + +Bcfg2, by default, uses ip address lookup to determine the identity of a client that has connected. This process doesn't work properly in the case of NATted hosts, because all requests from these clients come from the same external address when connecting to the server. + +These client identification issues will manifest themselves in a number of ways: + +* Inability to setup discrete clients with different profiles +* Incorrect sharing of probe results across clients in the same NAT pool +* Inability to bootstrap clients properly when client data is not predefined + +Architectural Issues +==================== + +Client identification is performed as the beginning of each client/server interaction. As of 0.9.3pre3, client identification via IP address can be completely short-circuited through the use of a client uuid. Setup of client uuids requires actions of both the client and server. On the server side, the client uuid must be added to the client record in Metadata/clients.xml. This attribute allows the server to use the user part of the authentication to resolve the client's metadata. Also, either the location attribute should be set to floating, or the IP address of the NAT must be reflected in the address attribute. +Once added, the Client entry in clients.xml will look like: + +.. code-block:: xml + + + +Alternatively, the Client entry can be setup like: + +.. code-block:: xml + + + +The difference between these definitions is explained in detail on the [wiki:Authentication] page, but in short, the second form requires that the client access the server from the NAT address, while the first form allows it to connect from any address provided it uses the proper uuid. (Client identification is orthogonal to the use of per-client passwords; this can be set in addition to the attributes above.) + +Once this setup is done, each client must be configured to use the proper uuid upon any server interaction. This can be done using either the command line argument -u, or the setting "user" in the "communication" section of /etc/bcfg2.conf. + +UUID Choice +=========== + +When determining client UUIDs, one must take care to ensure that UUIDs are unique to the client. Any hardware-specific attribute, like a hash of a mac address would be sufficient. Alternatively, if a local hostname is unique, it may be used as well. + +Automated Client Bootstrapping +============================== + +Automated setup of new clients from behind NAT works by using the common password. For example:: + + /usr/sbin/bcfg2 -u ubik3 -p desktop -x + +It is not possible at this time to do automated setup without setting up a pre-shared per-client key. diff --git a/doc/appendix/guides/ubuntu.txt b/doc/appendix/guides/ubuntu.txt new file mode 100644 index 000000000..a4790ffed --- /dev/null +++ b/doc/appendix/guides/ubuntu.txt @@ -0,0 +1,479 @@ +.. -*- mode: rst -*- + +.. _guide-ubuntu: + +====== +Ubuntu +====== + +.. note:: + + This particular how to was done on lucid, but should apply to any + other `stable`__ version of Ubuntu. + +__ ubuntu-releases_ +.. _ubuntu-releases: https://wiki.ubuntu.com/Releases + +Install Bcfg2 +============= + +We first need to install the server. For this example, we will use the +bcfg2 server package from the bcfg2 `PPA`_ (note that there is also a +version available in the ubuntu archives, but it is not as up to date). + +.. _PPA: https://launchpad.net/~bcfg2/+archive/ppa + +Add the Ubuntu PPA listing to your APT sources +---------------------------------------------- + +See http://trac.mcs.anl.gov/projects/bcfg2/wiki/PrecompiledPackages#UbuntuLucid + +Install bcfg2-server +-------------------- +:: + + aptitude install bcfg2-server + +Remove the default configuration preseeded by the ubuntu package:: + + root@lucid:~# rm -rf /etc/bcfg2* /var/lib/bcfg2 + +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 process.:: + + root@lucid:~# 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): + What is the server's hostname: [lucid] + Input the server location [https://lucid: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' + ----- + Signature ok + subject=/C=US/ST=Illinois/L=Argonne/CN=lucid + Getting Private key + 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@lucid:~# /etc/init.d/bcfg2-server start + root@lucid:~# tail /var/log/syslog + Dec 17 22:07:02 lucid bcfg2-server[17523]: serving bcfg2-server at https://lucid:6789 + Dec 17 22:07:02 lucid bcfg2-server[17523]: serve_forever() [start] + Dec 17 22:07:02 lucid bcfg2-server[17523]: Processed 16 fam events in 0.502 seconds. 0 coalesced + +Run bcfg2 to be sure you are able to communicate with the server:: + + root@lucid:~# bcfg2 -vqn + Loaded tool drivers: + APT Action DebInit POSIX + + Phase: initial + Correct entries: 0 + Incorrect entries: 0 + Total managed entries: 0 + Unmanaged entries: 382 + + + Phase: final + Correct entries: 0 + Incorrect entries: 0 + Total managed entries: 0 + Unmanaged entries: 382 + +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. + +Setup the `Packages`_ plugin +---------------------------- + +.. _Packages: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Packages + +Replace Pkgmgr with Packages in the plugins line of ``bcfg2.conf``:: + + root@lucid:~# cat /etc/bcfg2.conf + [server] + repository = /var/lib/bcfg2 + plugins = Base,Bundler,Cfg,Metadata,Packages,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. + #/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 = secret + certificate = /etc/bcfg2.crt + key = /etc/bcfg2.key + ca = /etc/bcfg2.crt + + [components] + bcfg2 = https://lucid:6789 + +Create Packages layout (as per :ref:`packages-exampleusage`) in +``/var/lib/bcfg2`` + +.. code-block:: xml + + root@lucid:~# mkdir /var/lib/bcfg2/Packages + root@lucid:~# cat /var/lib/bcfg2/Packages/config.xml + + + ubuntu-lucid + http://us.archive.ubuntu.com/ubuntu + lucid + main + multiverse + restricted + universe + amd64 + i386 + + + +Due to the `Magic Groups`_, we need to modify our Metadata. Let's add +an **ubuntu-lucid** group which inherits the **ubuntu** group already +present in ``/var/lib/bcfg2/Metadata/groups.xml``. The resulting file +should look something like this + +.. _Magic Groups: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Packages#MagicGroups + +.. code-block:: xml + + + + + + + + + + + + + + + + + + +.. note:: + When editing your xml files by hand, it is useful to occasionally run + `bcfg2-repo-validate` to ensure that your xml validates properly. + +The last thing we need is for the client to have the proper +arch group membership. For this, we will make use of the +:ref:`server-plugins-grouping-dynamic_groups` capabilities of the Probes plugin. Add +Probes to your plugins line in ``bcfg2.conf`` and create the Probe. + +.. code-block:: sh + + root@lucid:~# grep plugins /etc/bcfg2.conf + plugins = Base,Bundler,Cfg,Metadata,Packages,Probes,Rules,SSHbase + root@lucid:~# mkdir /var/lib/bcfg2/Probes + root@lucid:~# cat /var/lib/bcfg2/Probes/groups + #!/bin/sh + + ARCH=`uname -m` + case "$ARCH" in + "x86_64") + echo "group:amd64" + ;; + "i686") + echo "group:i386" + ;; + esac + +Now we restart the bcfg2-server:: + + root@lucid:~# /etc/init.d/bcfg2-server restart + Stopping Configuration Management Server: * bcfg2-server + Starting Configuration Management Server: * bcfg2-server + root@lucid:~# tail /var/log/syslog + Dec 17 22:36:47 lucid bcfg2-server[17937]: Packages: File read failed; falling back to file download + Dec 17 22:36:47 lucid bcfg2-server[17937]: Packages: Updating http://us.archive.ubuntu.com/ubuntu//dists/lucid/main/binary-amd64/Packages.gz + Dec 17 22:36:54 lucid bcfg2-server[17937]: Packages: Updating http://us.archive.ubuntu.com/ubuntu//dists/lucid/multiverse/binary-amd64/Packages.gz + Dec 17 22:36:55 lucid bcfg2-server[17937]: Packages: Updating http://us.archive.ubuntu.com/ubuntu//dists/lucid/restricted/binary-amd64/Packages.gz + Dec 17 22:36:56 lucid bcfg2-server[17937]: Packages: Updating http://us.archive.ubuntu.com/ubuntu//dists/lucid/universe/binary-amd64/Packages.gz + Dec 17 22:37:27 lucid bcfg2-server[17937]: Failed to read file probed.xml + Dec 17 22:37:27 lucid bcfg2-server[17937]: Loading experimental plugin(s): Packages + Dec 17 22:37:27 lucid bcfg2-server[17937]: NOTE: Interfaces subject to change + Dec 17 22:37:27 lucid bcfg2-server[17937]: service available at https://lucid:6789 + Dec 17 22:37:27 lucid bcfg2-server[17937]: serving bcfg2-server at https://lucid:6789 + Dec 17 22:37:27 lucid bcfg2-server[17937]: serve_forever() [start] + Dec 17 22:37:28 lucid bcfg2-server[17937]: Processed 17 fam events in 0.502 seconds. 0 coalesced + +Start managing packages +----------------------- + +Add a base-packages bundle. Let's see what happens when we just populate +it with the ubuntu-standard package. + +.. code-block:: xml + + root@lucid:~# cat /var/lib/bcfg2/Bundler/base-packages.xml + + + + +You need to reference the bundle from your Metadata. The resulting +profile group might look something like this + +.. code-block:: xml + + + + + + +Now if we run the client in debug mode (-d), we can see what this has +done for us.:: + + root@lucid:~# bcfg2 -vqdn + Running probe groups + Probe groups has result: + amd64 + Loaded tool drivers: + APT Action DebInit POSIX + The following packages are specified in bcfg2: + ubuntu-standard + The following packages are prereqs added by Packages: + adduser debconf hdparm libdevmapper1.02.1 libk5crypto3 libparted1.8-12 libxml2 passwd upstart + apt debianutils info libdns53 libkeyutils1 libpci3 logrotate pciutils usbutils + aptitude dmidecode install-info libelf1 libkrb5-3 libpopt0 lsb-base perl-base wget + at dnsutils iptables libept0 libkrb5support0 libreadline5 lshw popularity-contest zlib1g + base-files dosfstools libacl1 libgcc1 liblwres50 libreadline6 lsof psmisc + base-passwd dpkg libattr1 libgdbm3 libmagic1 libselinux1 ltrace readline-common + bsdmainutils ed libbind9-50 libgeoip1 libmpfr1ldbl libsigc++-2.0-0c2a man-db rsync + bsdutils file libc-bin libgmp3c2 libncurses5 libssl0.9.8 memtest86+ sed + cpio findutils libc6 libgssapi-krb5-2 libncursesw5 libstdc++6 mime-support sensible-utils + cpp ftp libcap2 libisc50 libpam-modules libusb-0.1-4 ncurses-bin strace + cpp-4.4 gcc-4.4-base libcomerr2 libisccc50 libpam-runtime libuuid1 netbase time + cron groff-base libcwidget3 libisccfg50 libpam0g libxapian15 parted tzdata + + Phase: initial + Correct entries: 101 + Incorrect entries: 0 + Total managed entries: 101 + Unmanaged entries: 281 + + + Phase: final + Correct entries: 101 + Incorrect entries: 0 + Total managed entries: 101 + Unmanaged entries: 281 + +As you can see, the Packages plugin has generated the dependencies +required for the ubuntu-standard package for us automatically. The +ultimate goal should be to move all the packages from the **Unmanaged** +entries section to the **Managed** entries section. So, what exactly *are* +those Unmanaged entries?:: + + root@lucid:~# bcfg2 -vqen + Running probe groups + Probe groups has result: + amd64 + Loaded tool drivers: + APT Action DebInit POSIX + + Phase: initial + Correct entries: 101 + Incorrect entries: 0 + Total managed entries: 101 + Unmanaged entries: 281 + + + Phase: final + Correct entries: 101 + Incorrect entries: 0 + Total managed entries: 101 + Unmanaged entries: 281 + Package:apparmor + Package:apparmor-utils + Package:apport + ... + +Now you can go through these and continue adding the packages you want to +your Bundle. Note that ``aptitude why`` is useful when trying to figure +out the reason for a package being installed. Also, deborphan is helpful +for removing leftover dependencies which are no longer needed. After a +while, I ended up with a minimal bundle that looks like this + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +As you can see below, I no longer have any unmanaged packages. :: + + root@lucid:~# bcfg2 -vqen + Running probe groups + Probe groups has result: + amd64 + Loaded tool drivers: + APT Action DebInit POSIX + + Phase: initial + Correct entries: 247 + Incorrect entries: 0 + Total managed entries: 247 + Unmanaged entries: 10 + + + Phase: final + Correct entries: 247 + Incorrect entries: 0 + Total managed entries: 247 + Unmanaged entries: 10 + Service:bcfg2 Service:fam Service:killprocs Service:rc.local Service:single + Service:bcfg2-server Service:grub-common Service:ondemand Service:rsync Service:ssh + +Manage services +--------------- + +Now let's clear up the unmanaged service entries by adding the following +entries to our bundle... + +.. code-block:: xml + + + + + + + + + + + + + + +...and bind them in Rules + +.. code-block:: xml + + root@lucid:~# cat /var/lib/bcfg2/Rules/services.xml + + + + + + + + + + + + + + +Now we run the client and see there are no more unmanaged entries! :: + + root@lucid:~# bcfg2 -vqn + Running probe groups + Probe groups has result: + amd64 + Loaded tool drivers: + APT Action DebInit POSIX + + Phase: initial + Correct entries: 257 + Incorrect entries: 0 + Total managed entries: 257 + Unmanaged entries: 0 + + All entries correct. + + Phase: final + Correct entries: 257 + Incorrect entries: 0 + Total managed entries: 257 + Unmanaged entries: 0 + + All entries correct. + +Dynamic (web) reports +===================== + +See installation instructions at :ref:`server-reports-install` diff --git a/doc/appendix/guides/using-bcfg2-info.txt b/doc/appendix/guides/using-bcfg2-info.txt new file mode 100644 index 000000000..5f77a3c70 --- /dev/null +++ b/doc/appendix/guides/using-bcfg2-info.txt @@ -0,0 +1,132 @@ +.. -*- mode: rst -*- + +.. _guide-using_bcfg2_info: + +================ +Using bcfg2-info +================ + +``bcfg2-info`` is a tool for introspecting server functions. It is +useful for understanding how the server is interpreting your +repository. It consists of the same logic executed by the server to +process the repository and produce configuration specifications, just +without all of the network communication code. Think of ``bcfg2-info`` +as ``bcfg2-server`` on a stick. It is a useful location to do testing +and staging of new configuration rules, prior to deployment. This is +particularly useful when developing templates, or developing Bcfg2 +plugins. + +Getting Started +=============== + +First, fire up the bcfg2-info interpreter. + +.. code-block:: none + + [0:464] bcfg2-info + Loading experimental plugin(s): Packages + NOTE: Interfaces subject to change + Handled 8 events in 0.006s + Handled 4 events in 0.035s + Welcome to bcfg2-info + Type "help" for more information + > + +At this point, the server core has been loaded up, all plugins have +been loaded, and the ``bcfg2-info`` has both read the initial state of +the Bcfg2 repository, as well as begun monitoring it for changes. Like +*bcfg2-server*, ``bcfg2-info`` monitors the repository for changes, +however, unlike *bcfg2-server*, it does not process change events +automatically. File modification events can be processed by explicitly +calling the **update** command. This will process the events, +displaying the number of events processed and the amount of time taken +by this processing. If no events are available, no message will be +displayed. For example, after a change to a file in the repository: + +.. code-block:: none + + >update + Handled 1 events in 0.001s + > update + > + +This explicit update process allows you to control the update process, +as well as see the precise changes caused by repository +modifications. + +``bcfg2-info`` has several builtin commands that display the state of +various internal server core state. These are most useful for +examining the state of client metadata, either for a single client, or +for clients overall. + +**clients** + displays a list of clients, along with their profile groups +**groups** + displays a list of groups, the inheritance hierarchy, profile + status, and category name, if there is one. +**showclient** + displays full metadata information for a client, including + profile group, group memberships, bundle list, and any connector + data, like Probe values or Property info. + +Debugging Configuration Rules +============================= + +In addition to the commands listed above for viewing client metadata, +there are also commands which can shed light on the configuration +generation process. Recall that configuration generation occurs in +three major steps: + +1) Resolve client metadata +2) Build list of entries for the configuration +3) Bind host-specific version of each entry + +Step *1* can be viewed with the commands presented in the previous +section. The latter two steps can be examined using the following +commands. + +**showentries** + displays a list of entries (optionally filtered by type) that + appear in a client's configuration specification + +**buildfile** + Perform the entry binding process on a single entry, displaying + its results. This command is very useful when developing + configuration file templates. + +**build** + Build the full configuration specification and write it to a + file. + +**mappings** + displays the entries handled by the plugins loaded by the server + core. This command is useful when the server reports a bind + failure for an entry. + +Debugging and Developing Bcfg2 +============================== + +``bcfg2-info`` loads a full Bcfg2 server core, so it provides the ideal +environment for developing and debugging Bcfg2. Because it is hard to +automate this sort of process, we have only implemented two commands +in ``bcfg2-info`` to aid in the process. + +**profile** + The profile command produces python profiling information for + other ``bcfg2-info`` commands. This can be used to track + performance problems in configuration generation. + +**debug** + The debug command exits the ``bcfg2-info`` interpreter loop and drops + to a python interpreter prompt. The Bcfg2 server core is available + in this namespace as "self". Full documentation for the server core + is out of scope for this document. This capability is most useful + to call into plugin methods, often with setup calls or the enabling + of diagnostics. + + It is possible to return to the ``bcfg2-info`` command loop by + exiting the python interpreter with ^D. + + There is built-in support for IPython in ``bcfg2-info``. If IPython + is installed, dropping into debug mode in ``bcfg2-info`` will use + the IPython interpreter by default. diff --git a/doc/appendix/guides/using-bcfg2-with-centos.txt b/doc/appendix/guides/using-bcfg2-with-centos.txt new file mode 100644 index 000000000..7c452f422 --- /dev/null +++ b/doc/appendix/guides/using-bcfg2-with-centos.txt @@ -0,0 +1,79 @@ +.. -*- mode: rst -*- + +.. _EPEL: http://fedoraproject.org/wiki/EPEL +.. _RPMForge: https://rpmrepo.org/RPMforge + +.. _getting_started-using_bcfg2-with-centos: + +======================= +Using Bcfg2 With CentOS +======================= + +This section covers specific topics for using Bcfg2 with CentOS. Most +likely the tips on this page also apply to other members of the Red Hat +family of Linux operating systems. + +From Source ++++++++++++ + +Install Prerequisities +###################### + +While you can go about building all these things from source, this +how to will try and meet the dependencies using packages from EPEL_ +or RPMforge_. The *el5* package should be compatible with CentOS 5.x. + +EPEL_:: + + [root@centos ~]# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm + +RPMforge_:: + + [root@centos ~]# rpm -Uvh http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm + +.. note:: + + Be careful with `mixing package repositories + `_. + +Now you can install the rest of the prerequisites:: + + [root@centos ~]# yum install python-genshi python-cheetah python-lxml + +Build Packages from source +########################## + +* After installing subversion, check out a copy of trunk :: + + [root@centos redhat]# svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2 + +* Install the ``fedora-packager`` package :: + + [root@centos ~]# yum install fedora-packager + +* A directory structure for the RPM build process has to be established. :: + + [you@centos ~]$ rpmdev-setuptree + +* Change to the *redhat* directory of the checked out Bcfg2 source:: + + [you@centos ~]$ cd bcfg2/redhat/ + +* In the particular directory is a Makefile which will do the job of building the RPM packages. You can do this as root, but it's not recommanded:: + + [you@centos redhat]$ make + +* Now the new RPM package can be installed. Please adjust the path to your RPM package:: + + [root@centos ~]# rpm -ihv /home/YOU/rpmbuild/RPMS/noarch/bcfg2-server-1.0.0-0.2r5835.noarch.rpm + +Install Packages from Package repository +######################################## + +To install the bcfg2-server and bcfg2 from a package repository, just +use Yum to do it:: + + [root@centos ~]# yum install bcfg2-server bcfg2 + +.. toctree:: + :hidden: diff --git a/doc/appendix/guides/vcs.txt b/doc/appendix/guides/vcs.txt new file mode 100644 index 000000000..207337c30 --- /dev/null +++ b/doc/appendix/guides/vcs.txt @@ -0,0 +1,112 @@ +.. -*- mode: rst -*- + +.. _guide-vcs: + +======================= +Version control systems +======================= + +The sections in this guide do only cover the basics steps in the setup +of the different version control system for the usage with the Bcfg2 +plugin support. More more details about + +Git +=== + +.. _Git tutorial: http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html + +Adding the :ref:`server-plugins-version-git` plugins can preserve +versioning information. The first step is to add **Git** to your +plugin line:: + + plugins = Base,Bundler,Cfg,...,Git + +For tracking the configuration files in the ``/var/lib/bcfg2`` +directory a git repository need to be established:: + + git init + +For more detail about the setup of git please refer to a `git tutorial`_. +The first commit can be the empty or the already populated directory:: + + git add . && git commit -a + +While running ``bcfg2-info`` the following line will show up:: + + Initialized git plugin with git directory = /var/lib/bcfg2/.git + +Mercurial +========= + +For the :ref:`server-plugins-version-hg` plugin are the same changes +needed as for git. :: + + plugins = Base,Bundler,Cfg,...,Mercurial + +The repository must be initialized:: + + hg init + +Mercurial will not commit the files to the repository until a user name +is defined in ``/var/lib/bcfg2/.hg/`` + +.. code-block:: sh + + cat <> /var/lib/bcfg2/.hg/hgrc + [ui] + username = Yor name + END_ENTRY + +Now you are able to make submissions to the repository:: + + hg commit + +While running ``bcfg2-info`` the following line will show up:: + + Initialized hg plugin with hg directory = /var/lib/bcfg2/.hg + +Darcs +===== + +If you wish to use the :ref:`server-plugins-version-darcs` plugin an +entry has to be made in the ``bcfg2.conf`` file.:: + + plugins = Base,Bundler,Cfg,...,Darcs + +The dracs repository must be initialized:: + + darcs initialize + +To commit to the darcs repository an author must be added to the +``_darcs/prefs/author`` file. If the ``author`` file is missing, +darcs will ask you to enter your e-mail address. + +.. code-block:: sh + + cat <> /var/lib/bcfg2/_darcs/prefs/author + you@example.com + END_ENTRY + +All files in the ``/var/lib/bcfg2`` should be added to darcs now:: + + darcs add * + +After that you can submit them to the repository:: + + darcs record + +While running ``bcfg2-info`` the following line will show up:: + + Initialized Darcs plugin with darcs directory = /var/lib/bcfg2/_darcs + +Cvs +=== + +If you wish to use the :ref:`server-plugins-version-darcs` plugin an +entry has to be made in the ``bcfg2.conf`` file.:: + + plugins = Base,Bundler,Cfg,...,Cvs + +The CVS repository must be initialized:: + + cvs -d /var/lib/bcfg2 init diff --git a/doc/appendix/index.txt b/doc/appendix/index.txt new file mode 100644 index 000000000..1bac69a3d --- /dev/null +++ b/doc/appendix/index.txt @@ -0,0 +1,27 @@ +.. -*- mode: rst -*- + +.. _appendix-index: + +======== +Appendix +======== + +Bcfg2 is based on a client-server architecture. The client is +responsible for interpreting (but not processing) the configuration +served by the server. This configuration is literal, so no local +process is required. After completion of the configuration process, +the client uploads a set of statistics to the server. This section +will describe the goals and then the architecture motivated by it. + + +.. toctree:: + :maxdepth: 2 + + files + configuration + contributors + books + papers + articles + guides + tools diff --git a/doc/appendix/papers.txt b/doc/appendix/papers.txt new file mode 100644 index 000000000..54f9de5dd --- /dev/null +++ b/doc/appendix/papers.txt @@ -0,0 +1,44 @@ +.. -*- mode: rst -*- + +.. _appendix-papers: + +====== +Papers +====== + + +* Configuration Life-Cycle Management on the TeraGrid. + + * Ti Leggett, Cory Lueninghoener, and Narayan Desai + * In Proceedings of TeraGrid '07 Conference, June 2007 + +* `A Scalable Approach To Deploying And Managing Appliances `_ + + * Rick Bradshaw, Narayan Desai, Tim Freeman, and Kate Keahey + * In Proceedings of the TeraGrid '07 Conference, June 2007 + +* `Bcfg2 - Konfigurationsmanagement Für Heterogene Umgebungen `_ + + * Marko Jung, Robert Gogolok + * In Proceedings of German Unix User Group's Frühjahrsfachgespräch 2007, March 2007. + +* `Directing Change Using Bcfg2 `_ + + * Narayan Desai, Rick Bradshaw, Joey Hagedorn, and Cory Lueninghoener + * In Proceedings of the Twentieth Large Install System Administration Conference (LISA XX), December 2-9, 2006, Washington D.C., USA, 2006. + +* `A Case Study in Configuration Management Tool Deployment `_ + + * Narayan Desai, Rick Bradshaw, Scott Matott, Sandra Bittner, Susan Coghlan, Remy Evard, Cory Leunighhoener, Ti Leggett, J.P. Navarro, Gene Rackow, Craig Stacey, and Tisha Stacey + * In Proceedings of the Nineteenth Large Install System Administration Conference (LISA XIX), December 4-9, 2005, San Diego, CA, USA, 2005. + +* `Bcfg2: A Pay As You Go Approach to Configuration Complexity `_ + + * Narayan Desai + * In Proceedings of the 2005 Australian Unix Users Group (AUUG2005), October 16-21, 2005, Sydney, Australia, 2005. + +* `Bcfg: A Configuration Management Tool for Heterogenous Environments `_ + + * Narayan Desai, Andrew Lusk, Rick Bradshaw, and Remy Evard + * In Proceedings of the 5th IEEE International Conference on Cluster Computing (CLUSTER03), pages 500-503. IEEE Computer Society, 2003. + diff --git a/doc/appendix/tools.txt b/doc/appendix/tools.txt new file mode 100644 index 000000000..040823504 --- /dev/null +++ b/doc/appendix/tools.txt @@ -0,0 +1,14 @@ +.. -*- mode: rst -*- + +.. _appendix-tools: + +===== +Tools +===== + +In the ``tools/`` directory are several tools collected. Those tools +can help you to maintain your Bcfg2 configuration, to make the initial +setup easier, or to do some other tasks. + + +http://trac.mcs.anl.gov/projects/bcfg2/browser/trunk/bcfg2/tools diff --git a/doc/architecture/client.txt b/doc/architecture/client.txt new file mode 100644 index 000000000..77da25621 --- /dev/null +++ b/doc/architecture/client.txt @@ -0,0 +1,112 @@ +.. -*- mode: rst -*- + +.. _architecture-client: + +The Bcfg2 Client +================ + +The Bcfg2 client performs all client configuration or reconfiguration +operations. It renders a declarative configuration specification, provided +by the Bcfg2 server, into a set of configuration operations which will, +if executed, attempt to change the client's state into that described by +the configuration specification. Conceptually, the Bcfg2 client serves to +isolate the Bcfg2 server and specification from the imperative operations +required to implement configuration changes. + +This isolation allows declarative specifications to be manipulated +symbolically on the server, without needing to understand the properties +of the underlying system tools. In this way, the Bcfg2 client acts +as a sort of expert system that *knows* how to implement declarative +configuration changes. + +The operation of the Bcfg2 client is intended to be as simple as +possible. The normal configuration process consists of four main steps: + +* **Probe Execution** + + During the probe execution stage, the client connects to the server + and downloads a series of probes to execute. These probes reveal + local facts to the Bcfg2 server. For example, a probe could discover + the type of video card in a system. The Bcfg2 client returns this + data to the server, where it can influence the client configuration + generation process. + +* **Configuration Download and Inventory** + + The Bcfg2 client now downloads a configuration specification from the + Bcfg2 server. The configuration describes the complete target state + of the machine. That is, all aspects of client configuration should + be represented in this specification. For example, all software + packages and services should be represented in the configuration + specification. The client now performs a local system inventory. + This process consists of verifying each entry present in the + configuration specification. After this check is completed, heuristic + checks are executed for configuration not included in the configuration + specification. We refer to this inventory process as 2-way validation, + as first we verify that the client contains all configuration that + is included in the specification, then we check if the client has + any extra configuration that isn't present. This provides a fairly + rigorous notion of client configuration congruence. Once the 2-way + verification process has been performed, the client has built a list of + all configuration entries that are out of spec. This list has two parts: + specified configuration that is incorrect (or missing) and unspecified + configuration that should be removed. + +* **Configuration Update** + + The client now attempts to update its configuration to match the + specification. Depending on options, changes may not (or only partially) + be performed. First, if extra configuration correction is enabled, + extra configuration can be removed. Then the remaining changes + are processed. The Bcfg2 client loops while progress is made in the + correction of these incorrect configuration entries. This loop results + in the client being able to accomplish all it will be able to during + one execution. Once all entries are fixed, or no progress is being + made, the loop terminates. Once all configuration changes that can be + performed have been, bundle dependencies are handled. Bundle groupings + result in two different behaviors. Contained entries are assumed + to be inter-dependent. To address this, the client re-verifies each + entry in any bundle containing an updates configuration entry. Also, + services contained in modified bundles are restarted. + +* **Statistics Upload** + + Once the reconfiguration process has concluded, the client reports + information back to the server about the actions it performed during the + reconfiguration process. Statistics function as a detailed return code + from the client. The server stores statistics information. Information + included in this statistics update includes (but is not limited to): + + * Overall client status (clean/dirty) + * List of modified configuration entries + * List of uncorrectable configuration entries + * List of unmanaged configuration entries + +Architecture Abstraction +------------------------ + +The Bcfg2 client internally supports the administrative tools available +on different architectures. For example, ``rpm`` and ``apt-get`` are +both supported, allowing operation of Debian, Redhat, SUSE, and Mandriva +systems. The client toolset is determined based on the availability of +client tools. The client includes a series of libraries which describe +how to interact with the system tools on a particular platform. + +Three of the libraries exist. There is a base set of functions, which +contain definitions describing how to perform POSIX operations. Support +for configuration files, directories, symlinks, hardlinks, etc., are +included here. Two other libraries subclass this one, providing support +for Debian and rpm-based systems. + +The Debian toolset includes support for apt-get and update-rc.d. These +tools provide the ability to install and remove packages, and to install +and remove services. + +The Redhat toolset includes support for rpm and chkconfig. Any other +platform that uses these tools can also use this toolset. Hence, all +of the other familiar rpm-based distributions can use this toolset +without issue. + +Other platforms can easily use the POSIX toolset, ignoring support for +packages or services. Alternatively, adding support for new toolsets +isn't difficult. Each toolset consists of about 125 lines of python code. diff --git a/doc/architecture/config-spec.txt b/doc/architecture/config-spec.txt new file mode 100644 index 000000000..57b131318 --- /dev/null +++ b/doc/architecture/config-spec.txt @@ -0,0 +1,54 @@ +.. -*- mode: rst -*- + +.. _architecture-config-spec: + +The Literal Configuration Specification +======================================= + +Literal configuration specifications are served to clients by the +Bcfg2 server. This is a differentiating factor for Bcfg2; all other +major configuration management systems use a non-literal configuration +specification. That is, the clients receive a symbolic configuration that +they process to implement target states. We took the literal approach +for a few reasons: + +* A small list of configuration element types can be defined, each of + which can have a set of defined semantics. This allows the server to + have a well-formed model of client-side operations. Without a static + lexicon with defined semantics, this isn't possible. This allows the + server, for example, to record the update of a package as a coherent + event. +* Literal configurations do not require client-side processing. Removing + client-side processing reduces the critical footprint of the tool. + That is, the Bcfg2 client (and the tools it calls) need to be + functional, but the rest of the system can be in any state. Yet, + the client will receive a correct configuration. +* Having static, defined element semantics also requires that all + operations be defined and implemented in advance. The implementation + can maximize reliability and robustness. In more ad-hoc setups, these + operations aren't necessarily safely implemented. + +The Structure of Specifications +------------------------------- + +Configuration specifications contain some number of clauses. Two types +of clauses exist. Bundles are groups of inter-dependent configuration +entities. The purpose of bundles is to encode installation-time +dependencies such that all new configuration is properly activated +during reconfiguration operations. That is, if a daemon configuration +file is changed, its daemon should be restarted. Another example of +bundle usage is the reconfiguration of a software package. If a package +contains a default configuration file, but it gets overwritten by an +environment-specific one, then that updated configuration file should +survive package upgrade. The purpose of bundles is to describe services, +or reconfigured software packages. Independent clauses contain groups +of configuration entities that aren't related in any way. This provides a +convenient mechanism that can be used for bulk installations of software. + +Each of these clauses contains some number of configuration entities. A +number of configuration entities exist including Path, Package, Service, +etc. Each of these correspond to the obvious system item. Configuration +specifications can get quite large; many systems have specifications +that top one megabyte in size. An example of one is included in an +appendix. These configurations can be written by hand, or generated by +the server. diff --git a/doc/architecture/design.txt b/doc/architecture/design.txt new file mode 100644 index 000000000..7008c601f --- /dev/null +++ b/doc/architecture/design.txt @@ -0,0 +1,77 @@ +.. -*- mode: rst -*- + +.. _architecture-design: + +Design Considerations +===================== + +This section will discuss several aspects of the design of Bcfg2, and the +particular use cases that motivated them. Initially, this will consist +of a discussion of the system metadata, and the intended usage model +for package indices as well. + +System Metadata +--------------- + +Bcfg2 system metadata describes the underlying patterns in system +configurations. It describes commonalities and differences between these +specifications in a rigorous way. The groups used by Bcfg2's metadata are +responsible for differentiating clients from one another, and building +collections of allocatable configuration. + +The Bcfg2 metadata system has been designed with several high-level +goals in mind. Flexibility and precision are paramount concerns; no +configuration should be undescribable using the constructs present in +the Bcfg2 repository. We have found (generally the hard way) that any +assumptions about the inherent simplicity of configuration patterns tend +to be wrong, so obscenely complex configurations must be representable, +even if these requirements seem illogical during the implementation. + +In particular, we wanted to streamline several operations that commonly +occurred in our environment. + +* Copying one node's profile to another node. + + In many environments, many nodes are instances of a common configuration + specification. They all have similar roles and software. In our + environment, desktop machines were the best example of this. Other than + strictly per-host configuration like SSH keys, all desktop machines + use a common configuration specification. This trivializes the process + of creating a new desktop machine. + +* Creating a specialized version of an existing profile. + + In environments with highly varied configurations, departmental + infrastructure being a good example, "another machine like X but with + extra software" is a common requirement. For this reason, it must be + trivially possible to inherit most of a configuration specification + from some more generic source, while being able to describe overriding + aspects in a convenient fashion. + +* Compose several pre-existing configuration aspects to create a new profile. + + The ability to compose configuration aspects allows the easy creation + of new profiles based on a series of predefined set of configuration + specification fragments. The end result is more agility in environments + where change is the norm. + + In order for a classing system to be comprehensive, it must be usable in + complex ways. The Bcfg2 metadata system has constructs that map cleanly + to first-order logic. This implies that any complex configuration + pattern can be represented (at all) by the metadata, as first-order + logic is provably comprehensive. (There is a discussion later in the + document describing the metadata system in detail, and showing how it + corresponds to first-order logic) + +These use cases motivate several of the design decisions that we +made. There must be a many to one correspondence between clients and +groups. Membership in a given profile group must imbue a client with +all of its configuration properties. + +Package Management +------------------ + +The interface provided in the Bcfg2 repository for package specification +was designed with automation in mind. The goal was to support an +append only interface to the repository, so that users do not need to +continuously re-write already existing bits of specification. diff --git a/doc/architecture/goals.txt b/doc/architecture/goals.txt new file mode 100644 index 000000000..395b574a0 --- /dev/null +++ b/doc/architecture/goals.txt @@ -0,0 +1,47 @@ +.. -*- mode: rst -*- + +.. _architecture-goals: + +Goals +===== + +* **Model configurations using declarative semantics.** + + Declarative semantics maximize the utility of configuration management + tools; they provide the most flexibility for the tool to determine + the right course of action in any given situation. This means that + users can focus on the task of describing the desired configuration, + while leaving the task of transitioning clients states to the tool. + +* **Configuration descriptions should be comprehensive.** + + This means that configurations served to the client should be sufficient + to reproduce all desired functionality. This assumption allows the + use of heuristics to detect extra configuration, aiding in reliable, + comprehensive configuration definitions. + +* **Provide a flexible approach to user interactions.** + + Most configuration management systems take a rigid approach to user + interactions; that is, either the client system is always correct, + or the central system is. This means that users are forced into an + overly proscribed model where the system asserts where correct data + is. Configuration data modification is frequently undertaken on both + the configuration server and clients. Hence, the existence of a single + canonical data location can easily pose a problem during normal tool + use. Bcfg2 takes a different approach. + +The default assumption is that data on the server is correct, however, +the client has the option to run in another mode where local changes are +catalogued for server-side integration. If the Bcfg2 client is run in dry +run mode, it can help to reconcile differences between current client +state and the configuration described on the server. The Bcfg2 client +also searches for extra configuration; that is, configuration that is +not specified by the configuration description. When extra configuration +is found, either configuration has been removed from the configuration +description on the server, or manual configuration has occurred on the +client. Options related to two-way verification and removal are useful +for configuration reconciliation when interactive access is used. + +* Plugins and administrative applications. +* Incremental operations. diff --git a/doc/architecture/index.txt b/doc/architecture/index.txt new file mode 100644 index 000000000..d5e034d34 --- /dev/null +++ b/doc/architecture/index.txt @@ -0,0 +1,24 @@ +.. -*- mode: rst -*- + +.. _architecture-index: + +====================== +Architecture in Detail +====================== + +Bcfg2 is based on a client-server architecture. The client is +responsible for interpreting (but not processing) the configuration +served by the server. This configuration is literal, so no local +process is required. After completion of the configuration process, +the client uploads a set of statistics to the server. This section +will describe the goals and then the architecture motivated by it. + + +.. toctree:: + :maxdepth: 1 + + goals + client + server + config-spec + design diff --git a/doc/architecture/server.txt b/doc/architecture/server.txt new file mode 100644 index 000000000..1341f9e0a --- /dev/null +++ b/doc/architecture/server.txt @@ -0,0 +1,65 @@ +.. -*- mode: rst -*- + +.. _architecture-server: + +The Bcfg2 Server +================ + +The Bcfg2 server is responsible for taking a network description and +turning it into a series of configuration specifications for particular +clients. It also manages probed data and tracks statistics for clients. + +The Bcfg2 server takes information from two sources when generating +client configuration specifications. The first is a pool of metadata that +describes clients as members of an aspect-based classing system. That is, +clients are defined in terms of aspects of their behavior. The other is +a file system repository that contains mappings from metadata to literal +configuration. These are combined to form the literal configuration +specifications for clients. + +The Configuration Specification Construction Process +---------------------------------------------------- + +As we described in the previous section, the client connects to the server +to request a configuration specification. The server uses the client's +metadata and the file system repository to build a specification that +is tailored for the client. This process consists of the following steps: + +* **Metadata Lookup** + + The server uses the client's IP address to initiate the metadata + lookup. This initial metadata consists of a (profile, image) tuple. If + the client already has metadata registered, then it is used. If not, + then default values are used and stored for future use. This metadata + tuple is expanded using some profile and class definitions also included + in the metadata. The end result of this process is metadata consisting + of hostname, profile, image, a list of classes, a list of attributes + and a list of bundles. + +* **Abstract Configuration Construction** + + Once the server has the client metadata, it is used to create + an abstract configuration. An abstract configuration contains + all of the configuration elements that will exist in the final + specification **without** any specifics. All entries will be typed + (i.e. the tagname will be one of Package, Path, Action, etc) and will + include a name. These configuration entries are grouped into bundles, + which document installation time interdependencies. + +* **Configuration Binding** + + The abstract configuration determines the structure of the client + configuration, however, it doesn't yet contain literal configuration + information. After the abstract configuration is created, each + configuration entry must be bound to a client-specific value. The Bcfg2 + server uses plugins to provide these client-specific bindings. The Bcfg2 + server core contains a dispatch table that describes which plugins can + handle requests of a particular type. The responsible plugin is located + for each entry. It is called, passing in the configuration entry and + the client's metadata. The behavior of plugins is explicitly undefined, + so as to allow maximum flexibility. The behaviours of the stock plugins + are documented elsewhere in this manual. Once this binding process + is completed, the server has a literal, client-specific configuration + specification. This specification is complete and comprehensive; the + client doesn't need to process it at all in order to use it. It also + represents the totality of the configuration specified for the client. diff --git a/doc/authentication.txt b/doc/authentication.txt index 9b1bdc187..ff3b1d901 100644 --- a/doc/authentication.txt +++ b/doc/authentication.txt @@ -14,9 +14,9 @@ Scenarios Default settings work well; machines do not float, and a per-client password is not required. -2. `NAT_HOWTO `_ +2. :ref:`NAT Howto nat_howto` - * Build client records in advance with bcfg2-admin, setting a uuid + * Build client records in advance with ``bcfg2-admin``, setting a uuid for each new client. * Set the address attribute for each to the address of the NAT. @@ -33,7 +33,7 @@ Building bcfg2.conf automatically ================================= This is a TCheetah template that automatically constructs per-client -bcfg2.conf from the per-client metadata:: +`bcfg2.conf` from the per-client metadata:: [communication] protocol = xmlrpc/ssl @@ -43,14 +43,14 @@ bcfg2.conf from the per-client metadata:: #if $self.metadata.password != None password = $self.metadata.password #else - password = my-password-foobat + password = my-password-foobar #end if [components] bcfg2 = https://localhost:6789 In this setup, this will cause any clients that have uuids established -to be set to use them in bcfg2.conf. It will also cause any clients +to be set to use them in `bcfg2.conf`. It will also cause any clients with passwords set to use them instead of the global password. How Authentication Works @@ -123,7 +123,7 @@ or password only. Also a bootstrap mode will be added shortly; this will allow a client to authenticate with a password its first time, requiring a certificate all subsequent times. This behavior can be controlled through the use of the auth attribute in -Metadata/clients.xml:: +`Metadata/clients.xml`:: diff --git a/doc/client/tools/blast.txt b/doc/client/tools/blast.txt new file mode 100644 index 000000000..14eb53124 --- /dev/null +++ b/doc/client/tools/blast.txt @@ -0,0 +1,10 @@ +.. -*- mode: rst -*- + +.. _client-tools-blast: + +===== +Blast +===== + +Blastwave Packages. This tool driver is for blastwave packages on +solaris. diff --git a/doc/client/tools/chkconfig.txt b/doc/client/tools/chkconfig.txt new file mode 100644 index 000000000..35cc0969e --- /dev/null +++ b/doc/client/tools/chkconfig.txt @@ -0,0 +1,15 @@ +.. -*- mode: rst -*- + +.. _client-tools-chkconfig: + +========= +Chkconfig +========= + +Tool to manage services (primarily on Red Hat based distros). + +.. note:: Start and stop are standard arguments, but the one for reload + isn't consistent across services. You can specify which argument + to use with the `restart` property in Service tags. Example: + ```` diff --git a/doc/client/tools/debinit.txt b/doc/client/tools/debinit.txt new file mode 100644 index 000000000..33d20f89c --- /dev/null +++ b/doc/client/tools/debinit.txt @@ -0,0 +1,9 @@ +.. -*- mode: rst -*- + +.. _client-tools-debinit: + +======= +DebInit +======= + +Debian Service Support; exec's update-rc.d to configure services. diff --git a/doc/client/tools/encap.txt b/doc/client/tools/encap.txt new file mode 100644 index 000000000..40508ac7a --- /dev/null +++ b/doc/client/tools/encap.txt @@ -0,0 +1,9 @@ +.. -*- mode: rst -*- + +.. _client-tools-encap: + +===== +Encap +===== + +`Encap `_ Packages. diff --git a/doc/client/tools/freebsdinit.txt b/doc/client/tools/freebsdinit.txt new file mode 100644 index 000000000..7df2518bc --- /dev/null +++ b/doc/client/tools/freebsdinit.txt @@ -0,0 +1,9 @@ +.. -*- mode: rst -*- + +.. _client-tools-freebsdinit: + +=========== +FreeBSDInit +=========== + +FreeBSD Service Support. Only bundle updates will work. diff --git a/doc/client/tools/freebsdpackage.txt b/doc/client/tools/freebsdpackage.txt new file mode 100644 index 000000000..a460fb41c --- /dev/null +++ b/doc/client/tools/freebsdpackage.txt @@ -0,0 +1,10 @@ +.. -*- mode: rst -*- + +.. _client-tools-freebsdpackage: + +============== +FreeBSDPackage +============== + +FreeBSD Packages. Verifies packages and their version numbers but can't +install packages. diff --git a/doc/client/tools/index.txt b/doc/client/tools/index.txt index 878a221ee..7f6e6b667 100644 --- a/doc/client/tools/index.txt +++ b/doc/client/tools/index.txt @@ -2,154 +2,31 @@ .. _client-tools-index: -Client Tool Drivers -=================== - -Client tool drivers allow Bcfg2 to execute configuration operations by -interfacing with platform and distribution specific tools. - -Tool drivers handle any reconfiguration or verification operation. So -far we have tools that primarily deal with packaging systems and service -management. The POSIX tool also handles file system and permissions/groups -operations. - -To write your own tool driver, to handle a new packaging format, or new -service architecture see :ref:`development-index-writingtooldrivers` - -When the Bcfg2 client is run, it attempts to instantiate each of these -drivers. The succeeding list of drivers are printed as a debug message -after this process has completed. Drivers can supercede one another, -for example, the Yum driver conflicts (and unloads) the RPM driver. This -behavior can be overridden by running the Bcfg2 client with the -D -flag. This flag takes a colon delimited list of drivers to use on -the system. +Available client tools +====================== + +Client tool drivers allow Bcfg2 to execute configuration operations +by interfacing with platform and distribution specific tools. + +Tool drivers handle any reconfiguration or verification operation. +So far we have tools that primarily deal with packaging systems +and service management. The POSIX tool also handles file system +and permissions/groups operations. To write your own tool driver, +to handle a new packaging format, or new service architecture see +:ref:`development-client-driver`. + +When the Bcfg2 client is run, it attempts to instantiate each of +these drivers. The succeeding list of drivers are printed as a +debug message after this process has completed. Drivers can +supercede one another, for example, the Yum driver conflicts (and +unloads) the RPM driver. This behavior can be overridden by running +the Bcfg2 client with the ``-D`` flag. This flag takes a colon +delimited list of drivers to use on the system. Currently these are the tool drivers that are distributed with Bcfg2: -Action ------- - -Pre and post-install tests and actions. This driver executes commands -and supplies status information to the Bcfg2 server via the statistics -mechanism. It can also be used to prevent bundle installation when -pre-conditions are not met. See the UsingActions page for more details. - -APT ---- - -Debian Packages. This tool driver is used to handle packages on dpkg -based systems and employs the "apt" executable. Extra information can be -found at :ref:`client-tools-apt`. - -Blast ------ - -Blastwave Packages. This tool driver is for blastwave packages on solaris - -Chkconfig ---------- - -Tool to manage services (primarily on Redhat based distros). - -.. note:: Start and stop are standard arguments, but the one for reload - isn't consistent across services. You can specify which argument - to use with the `restart` property in Service tags. Example: - ```` - -DebInit -------- - -Debian Service Support; exec's update-rc.d to configure services. - -Encap ------ - -`Encap `_ Packages. - -FreeBSDInit ------------ - -FreeBSD Service Support. Only bundle updates will work. - -FreeBSDPackage --------------- - -FreeBSD Packages. Verifies packages and their version numbers but can't -install packages. - -launchd -------- - -Mac OS X Services. To use this tool, you must maintain a standard launch -daemon .plist file in ``/Library/LaunchDaemons/`` (example ssh.plist) -and setup a ```` entry in your config to load or unload the service. Note the name -is the ''Label'' specified inside of the .plist file - -Portage -------- - -Support for Gentoo Packages. - -POSIX ------ - -Files and Permissions are handled by the POSIX driver. Usage well -documented other places. - -RcUpdate --------- - -Uses the rc-update executable to manage services on distributions such -as Gentoo. - -RPM ---- - -.. warning:: Deprecated in favor of :ref:`RPMng ` - -Executes rpm to manage packages most often on redhat based systems. - -RPMng ------ - -Next-generation RPM tool, will be default in upcoming release. Handles -RPM sublties like epoch and prelinking and 64-bit platforms better than -RPM client tool. :ref:`client-tools-yumng` - -SMF ---- - -Solaris Service Support. - -Example legacy run service (lrc): - -.. code-block:: xml - - - -SYSV ----- - -Handles System V Packaging format that is available on Solaris. - -Upstart -------- - -Upstart service support. Uses `Upstart`_ to configure services. - -.. _Upstart: http://upstart.ubuntu.com/ - -Yum ---- - -.. warning:: Deprecated in favor of :ref:`YUMng ` - -Handles RPMs using the YUM package manager. - -YUMng ------ +.. toctree:: + :maxdepth: 1 + :glob: -Handles RPMs using the YUM package manager. Handles sublties better than -the Yum client tool. :ref:`client-tools-yumng` + * diff --git a/doc/client/tools/launchd.txt b/doc/client/tools/launchd.txt new file mode 100644 index 000000000..59a872297 --- /dev/null +++ b/doc/client/tools/launchd.txt @@ -0,0 +1,13 @@ +.. -*- mode: rst -*- + +.. _client-tools-launchd: + +======= +launchd +======= + +Mac OS X Services. To use this tool, you must maintain a standard launch +daemon .plist file in ``/Library/LaunchDaemons/`` (example ssh.plist) +and setup a ```` entry in your config to load or unload the service. Note the name +is the ''Label'' specified inside of the .plist file diff --git a/doc/client/tools/portage.txt b/doc/client/tools/portage.txt new file mode 100644 index 000000000..7a91408b1 --- /dev/null +++ b/doc/client/tools/portage.txt @@ -0,0 +1,9 @@ +.. -*- mode: rst -*- + +.. _client-tools-portage: + +======= +Portage +======= + +Support for Gentoo Packages. diff --git a/doc/client/tools/posix.txt b/doc/client/tools/posix.txt new file mode 100644 index 000000000..c4da38332 --- /dev/null +++ b/doc/client/tools/posix.txt @@ -0,0 +1,10 @@ +.. -*- mode: rst -*- + +.. _client-tools-posix: + +===== +POSIX +===== + +Files and Permissions are handled by the POSIX driver. Usage well +documented other places. diff --git a/doc/client/tools/rcupdate.txt b/doc/client/tools/rcupdate.txt new file mode 100644 index 000000000..4547d3b39 --- /dev/null +++ b/doc/client/tools/rcupdate.txt @@ -0,0 +1,10 @@ +.. -*- mode: rst -*- + +.. _client-tools-rcupdate: + +======== +RcUpdate +======== + +Uses the rc-update executable to manage services on distributions such +as Gentoo. diff --git a/doc/client/tools/rpm.txt b/doc/client/tools/rpm.txt new file mode 100644 index 000000000..17d367b55 --- /dev/null +++ b/doc/client/tools/rpm.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _client-tools-rpm: + +=== +RPM +=== + +.. warning:: Deprecated in favor of :ref:`RPMng ` + +Executes rpm to manage packages most often on redhat based systems. diff --git a/doc/client/tools/rpmng.txt b/doc/client/tools/rpmng.txt new file mode 100644 index 000000000..c6d6cddf1 --- /dev/null +++ b/doc/client/tools/rpmng.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _client-tools-rpmng: + +===== +RPMng +===== + +Next-generation RPM tool, will be default in upcoming release. Handles +RPM sublties like epoch and prelinking and 64-bit platforms better than +RPM client tool. diff --git a/doc/client/tools/smf.txt b/doc/client/tools/smf.txt new file mode 100644 index 000000000..4829a14ed --- /dev/null +++ b/doc/client/tools/smf.txt @@ -0,0 +1,15 @@ +.. -*- mode: rst -*- + +.. _client-tools-smf: + +=== +SMF +=== + +Solaris Service Support. + +Example legacy run service (lrc): + +.. code-block:: xml + + diff --git a/doc/client/tools/sysv.txt b/doc/client/tools/sysv.txt new file mode 100644 index 000000000..c08614c52 --- /dev/null +++ b/doc/client/tools/sysv.txt @@ -0,0 +1,9 @@ +.. -*- mode: rst -*- + +.. _client-tools-sysv: + +==== +SYSV +==== + +Handles System V Packaging format that is available on Solaris. diff --git a/doc/client/tools/upstart.txt b/doc/client/tools/upstart.txt new file mode 100644 index 000000000..60d0cf4ef --- /dev/null +++ b/doc/client/tools/upstart.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _client-tools-upstart: + +======= +Upstart +======= + +Upstart service support. Uses `Upstart`_ to configure services. + +.. _Upstart: http://upstart.ubuntu.com/ diff --git a/doc/client/tools/yum.txt b/doc/client/tools/yum.txt new file mode 100644 index 000000000..fcb5244df --- /dev/null +++ b/doc/client/tools/yum.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _client-tools-yum: + +=== +Yum +=== + +.. warning:: Deprecated in favor of :ref:`YUMng ` + +Handles RPMs using the YUM package manager. diff --git a/doc/development/client-driver.txt b/doc/development/client-driver.txt new file mode 100644 index 000000000..19da9cb67 --- /dev/null +++ b/doc/development/client-driver.txt @@ -0,0 +1,75 @@ +.. -*- mode: rst -*- + +.. _development-client-driver: + +Writing A Client Tool Driver +============================ + +This page describes the step-by-step process of writing a client tool +driver for a configuration element type. The included example describes +an existing driver, and the process that was used to create it. + +#. Pick a name for the driver. In this case, we picked the name RPM. +#. Add "RPM" to the ``__all__ list`` in ``src/lib/Client/Tools/__init__.py`` +#. Create a file in ``src/lib/Client/Tools`` with the same name (RPM.py) +#. Create a class in this file with the same name (``class RPM``) + + * If it handles ``Package`` entries, subclass ``Bcfg2.Client.Tools.PkgTool`` + (from here referenced as branch [P]) + * If it handles ``Service`` entries, subclass ``Bcfg2.Client.Tools.SvcTool`` + (from here referenced as branch [S]) + * Otherwise, ``subclass Bcfg2.Client.Tools.Tool`` (from here referenced + as branch [T]) + +#. Set ``__name__`` to "RPM" +#. Add any required executable programs to ``__execs__`` +#. Set ``__handles__`` to a list of (``entry.tag``, ``entry.get('type')``) + tuples. This determines which entries the Tool module can be used + on. In this case, we set ``__handles__ = [('Package', 'rpm')]``. +#. Add verification. This method should return True/False depending + on current entry installation status. + + * [T] Add a Verify method. + * [P] Add a VerifyPackage method. + * [S] Add a VerifyService method. + * In the failure path, the current state of failing entry + attributes should be set in the entry, to aid in auditing. + (For example, if a file should be mode 644, and is currently + mode 600, then set attribute current_perms='600' in the input + entry) + +#. Add installation support. This method should return True/False + depending on the results of the installation process. + + * [T,S] Add an Install method. + * [P] The PkgTool baseclass has a generic mechanism for performing + all-at-once installations, followed, in the case of failures, + by single installations. To enable this support, set the pkgtype + attribute to the package type handled by this driver. Set the + ``pkgtool`` to a tuple ("command string %s", ("per-package string + format", [list of package entry fields])). For RPM, we have + ``setup pkgtool = ("rpm --oldpackage --replacepkgs --quiet -U %s", ("%s", ["url"]))`` + +#. Implement entry removal + + * [T,S] Implement a ``Remove`` method that removes all specified + entries (``prototype Remove(self, entries)``) + * [P] Implement a ``RemovePackages`` that removes all specified + entries (same prototype as Remove) + +#. Add a ``FindExtra`` method that locates entries not included in the + configuration. This may or may not be required, certain drivers + do not have the capability to find extra entries. +#. [P] Package drivers require a ``RefreshPackages`` method that updates + the internal representation of the package database. + +Writing Tool Driver Methods +--------------------------- + +#. Programs can be run using ``self.cmd.run``. This function returns a + (return code, stdout list) tuple. +#. The configuration is available as ``self.config`` +#. Runtime options are available in a dictionary as ``self.setup`` +#. Informational, error, and debug messages can be produced by + running ``self.logger.info/error/debug``. + diff --git a/doc/development/documentation.txt b/doc/development/documentation.txt new file mode 100644 index 000000000..8223670b8 --- /dev/null +++ b/doc/development/documentation.txt @@ -0,0 +1,75 @@ +.. -*- mode: rst -*- + +.. _development-documentation: + +Documentation +============= + +There are two parts of documentation in the Bcfg2 project: + +* The wiki +* The manual + + +The wiki +-------- +.. _Wiki: http://trac.mcs.anl.gov/projects/bcfg2/wiki +.. _Trac: http://trac.edgewall.org/ +.. _OpenID: https://openid.org/ +.. _MCS: http://www.mcs.anl.gov/ +.. _Argonne National Laboratory: http://www.anl.gov/ + +A python-based Trac_ instance is used for the Bcfg2 website. The +Wiki_ part of the website can be edited after you have successful +logged in. For the login is a vaild OpenID provider needed and an +interaction from an administrator. Please request your access to +the Wiki_ on the :ref:`mailinglist` or in the :ref:`ircchannel`. + + +The manual +---------- +.. _rst: http://en.wikipedia.org/wiki/ReStructuredText +.. _Sphinx: http://sphinx.pocoo.org +.. _Docutils: + +The source for the manual is located in the `doc/` directory in the +SVN repository or in the source tarball. All files are written in +rst_ (ReStructuredText). For the build process we are using Sphinx_. + +Building the Manual +^^^^^^^^^^^^^^^^^^^ + +* Install the prerequisites. Docutils_ and Sphinx_ are needed to build. + + * For Debian (Lenny) the tools are available in the `backports `_ repository; installation can be done with the following:: + + apt-get -t lenny-backports install python-sphinx + + * The needed tools for Fedora based systems are in the `Fedora Package Collection `_; installation can be done easily with Yum:: + + yum -y install python-sphinx python-docutils + + * Additionally, to build the PDF version: + + * LaTeX + * pdftex + +* Download the source. Please refer to :ref:`source` for more details. + +* Building the HTML version, run the following command in the `doc/` directory. The output will appear in `../build/sphinx/html`:: + + python setup.py build_sphinx + +* Building the PDF version :: + + python setup.py build_sphinx --builder=latex + cd build/sphinx/latex + make + +The latest version of the manual +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The latest version of the manual can always be found +`on the Four Kitchens server `_. + +This is an auto-updated from the `Launchpad mirror `_. diff --git a/doc/development/emacs_snippet.txt b/doc/development/emacs_snippet.txt new file mode 100644 index 000000000..2905a2b45 --- /dev/null +++ b/doc/development/emacs_snippet.txt @@ -0,0 +1,60 @@ +.. -*- mode: rst -*- + +.. _development-emacs_snippet: + +====================== +Emacs + YASnippet mode +====================== + +This page describes using emacs with YASnippet mode with a set of +snippets that allow quick composition of bundles and base files. +More snippets are under development. + +#. Download YASnippet from http://code.google.com/p/yasnippet/ +#. Install it into your emacs load path (typically ~/.emacs.d/site-lisp) +#. Add YASnippet initialization to your .emacs (remember to re-byte-compile it if needed) + + .. code-block:: cl + + (require 'yasnippet-bundle) + + ;;; Bcfg2 snippet + + (yas/define-snippets 'sgml-mode + '( + (" + $0 + " nil) + (" + $0 + " nil) + (" + $0" nil) + (" + $0" nil) + (" + $0" nil) + (" + $0" nil) + (" + $0" nil) + (" + $0" nil) + (" + $0" nil) + ) + ) + +#. One quick M-x eval-current-buffer, and this code is enabled + +Each of these snippets activates on the opening element, ie , +and the snippet will be expanded. The template will be inserted into +the text with a set of input prompts, which default to overwrite mode +and can be tabbed through. + +The code above only works for bundles and base, but will be expanded +to support other xml files as well. diff --git a/doc/development/index.txt b/doc/development/index.txt index 74621815f..222978c98 100644 --- a/doc/development/index.txt +++ b/doc/development/index.txt @@ -6,315 +6,49 @@ Bcfg2 Development ================= -There are many ways to get involved in Bcfg2 development. Here we will -outline some things that can help you get familiar with the various -areas of the Bcfg2 code. +There are several ways users can contribute to the Bcfg2 project. -Tips for Bcfg2 Development --------------------------- +* Developing code +* Testing prereleases +* Reporting bugs +* Adding to the common repository +* Improving the wiki and writing documentation -#. Focus on either the client or server code. This focuses the development process down to the precise pieces of code that matter for the task at hand. - * If you are developing a client driver, then write up a small configuration specification that includes the needed characteristics. - * If you are working on the server, run ``bcfg2-info`` and use to assess the code. +This section will outline some things that can help you get familiar +with the various areas of the Bcfg2 code. -#. Use the python interpreter. One of python's most appealing features is interactive use of the interpreter. +Send patches to the :ref:`mailinglist` or create a trac +`ticket `_ +with the patch included. In order to submit a ticket via the +trac system, you will need to create a session by clicking on the +`Preferences `_ link and +filling out/saving changes to the form. In order to be considered for +mainline inclusion, patches need to be BSD licensed. The most convenient +way to prepare patches is by using ``git diff`` inside of a source tree +checked out of git. - * If you are developing for the client-side, run ``python -i /usr/sbin/bcfg2`` with the appropriate bcfg2 options. This will cause the python interpreter to continue running, leaving all variables intact. This can be used to examine data state in a convenient fashion. - * If you are developing for the server side, use ``bcfg2-info`` and the "debug" option. This will leave you at a python interpreter prompt, with the server core loaded in the variable "bcore". +The source tree can be checked out by running:: -#. Use ``pylint`` obsessively. It raises a lot of style-related warnings which can be ignored, but most all of the errors are legitimate. -#. If you are doing anything with Regular Expressions, `Kodos`_ and `re-try`_ are your friends. - - -.. _Kodos: http://kodos.sourceforge.net -.. _re-try: http://re-try.appspot.com - - -Environment setup for development -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Check out a copy of the code:: - - git clone git://git.mcs.anl.gov/bcfg2.git - -* Create link to src/lib:: - - cd bcfg2 - ln -s src/lib Bcfg2 - -* Add ``bcfg2/src/sbin`` to your PATH environment variable -* Add ``bcfg2`` to your PYTHONPATH environment variable - -.. _development-index-writingtooldrivers: - -Writing A Client Tool Driver -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This page describes the step-by-step process of writing a client tool -driver for a configuration element type. The included example describes -an existing driver, and the process that was used to create it. - -#. Pick a name for the driver. In this case, we picked the name RPM. -#. Add "RPM" to the __all__ list in ``src/lib/Client/Tools/__init__.py`` -#. Create a file in ``src/lib/Client/Tools`` with the same name (RPM.py) -#. Create a class in this file with the same name (class RPM) - - * If it handles Package entries, subclass Bcfg2.Client.Tools.PkgTool (from here referenced as branch [P]) - * If it handles Service entries, subclass Bcfg2.Client.Tools.SvcTool (from here referenced as branch [S]) - * Otherwise, subclass Bcfg2.Client.Tools.Tool (from here referenced as branch [T]) - -#. Set __name__ to "RPM" -#. Add any required executable programs to __execs__ -#. Set __handles__ to a list of (entry.tag, entry.get('type')) tuples. This determines which entries the Tool module can be used on. In this case, we set __handles__ = [('Package', 'rpm')]. -#. Add verification. This method should return True/False depending on current entry installation status. - - * [T] Add a Verify method. - * [P] Add a VerifyPackage method. - * [S] Add a VerifyService method. - * In the failure path, the current state of failing entry attributes should be set in the entry, to aid in auditing. [[BR]] (For example, if a file should be mode 644, and is currently mode 600, then set attribute current_perms='600' in the input entry) - -#. Add installation support. This method should return True/False depending on the results of the installation process. - - * [T,S] Add an Install method. - * [P] The PkgTool baseclass has a generic mechanism for performing all-at-once installations, followed, in the case of failures, by single installations. To enable this support, set the pkgtype attribute to the package type handled by this driver. Set the pkgtool to a tuple ("command string %s", ("per-package string format", [list of package entry fields])). For RPM, we have setup pkgtool = ("rpm --oldpackage --replacepkgs --quiet -U %s", ("%s", ["url"])) - -#. Implement entry removal - - * [T,S] Implement a Remove method that removes all specified entries (prototype Remove(self, entries)) - * [P] Implement a !RemovePackages that removes all specified entries (same prototype as Remove) - -#. Add a FindExtra method that locates entries not included in the configuration. This may or may not be required, certain drivers do not have the capability to find extra entries. -#. [P] Package drivers require a !RefreshPackages method that updates the internal representation of the package database. - -Writing Tool Driver Methods -""""""""""""""""""""""""""" - -#. Programs can be run using self.cmd.run. This function returns a (return code, stdout list) tuple. -#. The configuration is available as self.config -#. Runtime options are available in a dictionary as self.setup -#. Informational, error, and debug messages can be produced by running self.logger.info/error/debug. - -Bcfg2 Plugin development ------------------------- - -While the Bcfg2 server provides a good interface for representing -general system configurations, its plugin interface offers the ability -to implement configuration interfaces and representation tailored to -problems encountered by a particular site. This chapter describes what -plugins are good for, what they can do, and how to implement them. - -Bcfg2 Plugins -^^^^^^^^^^^^^ - -Bcfg2 plugins are loadable python modules that the Bcfg2 server loads at -initialization time. These plugins can contribute to the functions already -offered by the Bcfg2 server or can extend its functionality. In general, -plugins will provide some portion of the configuration for clients, with a -data representation that is tuned for a set of common tasks. Much of the -core functionality of Bcfg2 is implemented by several plugins, however, -they are not special in any way; new plugins could easily supplant one -or all of them. - -The following table describes the various functions of bcfg2 plugins. - -+--------------------+---------------------------------------------+ -| Name | Description | -+====================+=============================================+ -| Probes | Plugins can issue commands to collect | -| | client-side state (like hardware inventory) | -| | to include in client configurations | -+--------------------+---------------------------------------------+ -| ConfigurationEntry | Plugins can construct a list of per-client | -| List | configuration entry lists to include in | -| | client configurations. | -+--------------------+---------------------------------------------+ -| ConfigurationEntry | Literal values for configuration entries | -| contents | | -+--------------------+---------------------------------------------+ -| XML-RPC functions | Plugins can export function calls that | -| | expose internal functions. | -+--------------------+---------------------------------------------+ - -Writing Bcfg2 Plugins -^^^^^^^^^^^^^^^^^^^^^ - -Bcfg2 plugins are python classes that subclass from -Bcfg2.Server.Plugin.Plugin. Several plugin-specific values must be set -in the new plugin. These values dictate how the new plugin will behave -with respect to the above four functions. The following table describes -all important member fields. - -+-----------------+-----------------------------------+--------------------------+ -| Name | Description | Format | -+=================+===================================+==========================+ -| __name__ | The name of the plugin | string | -+-----------------+-----------------------------------+--------------------------+ -| __version__ | The plugin version (generally | string | -| | tied to revctl keyword expansion) | | -+-----------------+-----------------------------------+--------------------------+ -| __author__ | The plugin author. | string | -+-----------------+-----------------------------------+--------------------------+ -| __rmi__ | Set of functions to be exposed as | List of function names | -| | XML-RPC functions | (strings) | -+-----------------+-----------------------------------+--------------------------+ -| Entries | Multidimentional dictionary of | Dictionary of | -| | keys that point to the function | ConfigurationEntityType, | -| | used to bind literal contents for | Name keys, and function | -| | a given configuration entity. | reference values | -+-----------------+-----------------------------------+--------------------------+ -| BuildStructures | Function that returns a list of | Member function | -| | the structures for a given client | | -+-----------------+-----------------------------------+--------------------------+ -| GetProbes | Function that returns a list of | Member function | -| | probes that a given client should | | -| | execute | | -+-----------------+-----------------------------------+--------------------------+ -| ReceiveData | Function that accepts the probe | Member function | -| | results for a given client. | | -+-----------------+-----------------------------------+--------------------------+ - -Example Plugin -^^^^^^^^^^^^^^ - -.. code-block:: python - - import Bcfg2.Server.Plugin - class MyPlugin(Bcfg2.Server.Plugin.Plugin): - """An example plugin.""" - # All plugins need to subclass Bcfg2.Server.Plugin.Plugin - __name__ = 'MyPlugin' - __version__ = '1' - __author__ = 'me@me.com' - __rmi__ = ['myfunction'] - # myfunction is not available remotely as MyPlugin.myfunction - - def __init__(self, core, datastore): - Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) - self.Entries = {'Path':{'/etc/foo.conf': self.buildFoo}} - - def myfunction(self): - """Function for xmlrpc rmi call.""" - # Do something - return True - - def buildFoo(self, entry, metadata): - """Bind per-client information into entry based on metadata.""" - entry.attrib.update({'type':'file', 'owner':'root', 'group':'root', 'perms':'644'}) - entry.text = '''contents of foo.conf''' - -Example Connector -^^^^^^^^^^^^^^^^^ - -.. code-block:: python - - import Bcfg2.Server.Plugin - - class Foo(Bcfg2.Server.Plugin.Plugin, - Bcfg2.Server.Plugin.Connector): - """The Foo plugin is here to illustrate a barebones connector.""" - name = 'Foo' - version = '$Revision: $' - experimental = True - - def __init__(self, core, datastore): - Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) - Bcfg2.Server.Plugin.Connector.__init__(self) - self.store = XMLFileBacked(self.data, core.fam) - - def get_additional_data(self, metadata): - - mydata = {} - for data in self.store.entries['foo.xml'].data.get("foo", []): - - mydata[data] = "bar" - - return dict([('mydata', mydata)]) - - def get_additional_groups(self, meta): - return self.cgroups.get(meta.hostname, list()) - -Server Plugin Types -------------------- - -Generator -^^^^^^^^^ - -Generator plugins contribute to literal client configurations - -Structure -^^^^^^^^^ - -Structure Plugins contribute to abstract client configurations - -Metadata -^^^^^^^^ - -Signal metadata capabilities - -Connector -^^^^^^^^^ - -Connector Plugins augment client metadata instances - -Probing -^^^^^^^ - -Signal probe capability - -Statistics -^^^^^^^^^^ - -Signal statistics handling capability - -Decision -^^^^^^^^ - -Signal decision handling capability - -Version -^^^^^^^ - -Interact with various version control systems - -Writing Server Plugins ----------------------- - -Metadata -^^^^^^^^ - -If you would like to define your own Metadata plugin (to extend/change -functionality of the existing Metadata plugin), here are the steps to -do so. We will call our new plugin `MyMetadata`. - -#. Add MyMetadata.py - - .. code-block:: python - - __revision__ = '$Revision$' - - import Bcfg2.Server.Plugins.Metadata - - class MyMetadata(Bcfg2.Server.Plugins.Metadata.Metadata): - '''This class contains data for bcfg2 server metadata''' - __version__ = '$Id$' - __author__ = 'bcfg-dev@mcs.anl.gov' - - def __init__(self, core, datastore, watch_clients=True): - Bcfg2.Server.Plugins.Metadata.Metadata.__init__(self, core, datastore, watch_clients) - -#. Add MyMetadata to ``src/lib/Server/Plugins/__init__.py`` -#. Replace Metadata with MyMetadata in the plugins line of bcfg2.conf - - -Documentation -------------- - -One of the areas where everyone can help is with the documentation. *Insert verbiage on how people can help.* + git clone git://git.mcs.anl.gov/bcfg2.git +Users wishing to contribute on a regular basis can apply for direct +git access. Mail the :ref:`mailinglist` for details. .. toctree:: :maxdepth: 1 - + + tips + setup + client-driver + plugins + writing_plugins + plugin-types + writing_specification + server + testing + documentation docstyleguide + emacs_snippet + vim_snippet diff --git a/doc/development/plugin-types.txt b/doc/development/plugin-types.txt new file mode 100644 index 000000000..5f0a4771a --- /dev/null +++ b/doc/development/plugin-types.txt @@ -0,0 +1,46 @@ +.. -*- mode: rst -*- + +.. _development-plugin-types: + +Server Plugin Types +------------------- + +Generator +^^^^^^^^^ + +Generator plugins contribute to literal client configurations + +Structure +^^^^^^^^^ + +Structure Plugins contribute to abstract client configurations + +Metadata +^^^^^^^^ + +Signal metadata capabilities + +Connector +^^^^^^^^^ + +Connector Plugins augment client metadata instances + +Probing +^^^^^^^ + +Signal probe capability + +Statistics +^^^^^^^^^^ + +Signal statistics handling capability + +Decision +^^^^^^^^ + +Signal decision handling capability + +Version +^^^^^^^ + +Interact with various version control systems diff --git a/doc/development/plugins.txt b/doc/development/plugins.txt new file mode 100644 index 000000000..b6debba24 --- /dev/null +++ b/doc/development/plugins.txt @@ -0,0 +1,45 @@ +.. -*- mode: rst -*- + +.. _development-plugins: + +Bcfg2 Plugin development +------------------------ + +While the Bcfg2 server provides a good interface for representing +general system configurations, its plugin interface offers the ability +to implement configuration interfaces and representation tailored to +problems encountered by a particular site. This chapter describes what +plugins are good for, what they can do, and how to implement them. + +Bcfg2 Plugins +^^^^^^^^^^^^^ + +Bcfg2 plugins are loadable python modules that the Bcfg2 server loads at +initialization time. These plugins can contribute to the functions already +offered by the Bcfg2 server or can extend its functionality. In general, +plugins will provide some portion of the configuration for clients, with a +data representation that is tuned for a set of common tasks. Much of the +core functionality of Bcfg2 is implemented by several plugins, however, +they are not special in any way; new plugins could easily supplant one +or all of them. + +The following table describes the various functions of bcfg2 plugins. + ++--------------------+---------------------------------------------+ +| Name | Description | ++====================+=============================================+ +| Probes | Plugins can issue commands to collect | +| | client-side state (like hardware inventory) | +| | to include in client configurations | ++--------------------+---------------------------------------------+ +| ConfigurationEntry | Plugins can construct a list of per-client | +| List | configuration entry lists to include in | +| | client configurations. | ++--------------------+---------------------------------------------+ +| ConfigurationEntry | Literal values for configuration entries | +| contents | | ++--------------------+---------------------------------------------+ +| XML-RPC functions | Plugins can export function calls that | +| | expose internal functions. | ++--------------------+---------------------------------------------+ + diff --git a/doc/development/server.txt b/doc/development/server.txt new file mode 100644 index 000000000..0f594422e --- /dev/null +++ b/doc/development/server.txt @@ -0,0 +1,83 @@ +.. -*- mode: rst -*- + +.. _development-server-plugins: + +Writing Server Plugins +---------------------- + +Metadata +^^^^^^^^ + +If you would like to define your own Metadata plugin (to extend/change +functionality of the existing Metadata plugin), here are the steps to +do so. We will call our new plugin `MyMetadata`. + +#. Add MyMetadata.py + + .. code-block:: python + + __revision__ = '$Revision$' + + import Bcfg2.Server.Plugins.Metadata + + class MyMetadata(Bcfg2.Server.Plugins.Metadata.Metadata): + '''This class contains data for bcfg2 server metadata''' + __version__ = '$Id$' + __author__ = 'bcfg-dev@mcs.anl.gov' + + def __init__(self, core, datastore, watch_clients=True): + Bcfg2.Server.Plugins.Metadata.Metadata.__init__(self, core, datastore, watch_clients) + +#. Add MyMetadata to ``src/lib/Server/Plugins/__init__.py`` +#. Replace Metadata with MyMetadata in the plugins line of bcfg2.conf + +.. _development-server-packages: + +Packages +-------- + +In order to support a given client package tool driver, that driver +must support use of the auto value for the version attribute in Package +entries. In this case, the tool driver views the current state of +available packages, and uses the underlying package manager's choice of +correct package version in lieu of an explicit, centrally-specified, +version. This support enables Packages to provide a list of Package +entries with version='auto'. Currently, the APT and YUMng drivers support +this feature. Note that package management systems without any network +support cannot operate in this fashion, so RPMng and SYSV will never be +able to use Packages. Emerge, Zypper, IPS, and Blastwave all have the +needed features to be supported by Packages, but support has not yet +been written. + +Packages fills two major functions in configuration generation. The first +is to provide entry level binding support for Package entries included +in client configurations. This function is quite easy to implement; +Packages determines (based on client group membership) if the package +is available for the client system, and which type it has. Because +version='auto' is used, no version determination needs to be done. + +The second major function is more complex. Packages ensures that client +configurations include all package-level prerequisites for package entries +explicitly included in the configuration. In order to support this, +Packages needs to directly process network data for package management +systems (the network sources for apt or yum, for examples), process +these files, and build data structures describing prerequisites and the +providers of those functions/paths. To simplify implementations of this, +there is a generic base class (Bcfg2.Server.Plugins.Packages.Source) +that provides a framework for fetching network data via HTTP, processing +those sources (with subclass defined methods for processing the specific +format provided by the tool), a generic dependency resolution method, +and a caching mechanism that greatly speeds up server/bcfg2-info startup. + +Each source type must define: + +* a get_urls attribute (and associated urls property) that describes + the URLS where to get data from. +* a read_files method that reads and processes the downloaded files + +Sources may define a get_provides method, if provides are complex. For +example, provides in rpm can be either rpm names or file paths, so +multiple data sources need to be multiplexed. + +The APT source in ``src/lib/Server/Plugins/Packages.py`` provides a +relatively simple implementation of a source. diff --git a/doc/development/setup.txt b/doc/development/setup.txt new file mode 100644 index 000000000..08a85dac1 --- /dev/null +++ b/doc/development/setup.txt @@ -0,0 +1,19 @@ +.. -*- mode: rst -*- + +.. _development-setup: + + +Environment setup for development +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Check out a copy of the code:: + + svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2 + +* Create link to ``src/lib``:: + + cd bcfg2 + ln -s src/lib Bcfg2 + +* Add ``bcfg2/src/sbin`` to your PATH environment variable +* Add ``bcfg2`` to your PYTHONPATH environment variable diff --git a/doc/development/specification_overview.png b/doc/development/specification_overview.png new file mode 100644 index 000000000..66774f359 Binary files /dev/null and b/doc/development/specification_overview.png differ diff --git a/doc/development/testing.txt b/doc/development/testing.txt new file mode 100644 index 000000000..45b1cbefc --- /dev/null +++ b/doc/development/testing.txt @@ -0,0 +1,74 @@ +.. -*- mode: rst -*- + +.. _development-testing: + +Testing +======= + +Testing Prereleases +------------------- + +Before each release, several prereleases will be tagged. It is +helpful to have users test these releases (when feasible) because +it is hard to replicate the full range of potential reconfiguration +situations; between different operating systems, system management +tools, and configuration specification variation, there can be +large differences between sites. + + +For more details please visit `Tracking Development Releases of Bcfg2 `_ . + + +Upgrade Testing +--------------- + +This section describes upgrade procedures to completely test the +client and server. These procedures can be used for either pre-release +testing, or for confidence building in a new release. + + +Server Testing +^^^^^^^^^^^^^^ + +1. Ensure that the server produces the same configurations for clients + + * Before the upgrade, generate all client configurations using the buildall subcommand of bcfg2-info. This subcommand takes a directory argument; it will generate one client configuration in each file, naming each according to the client name. + + .. code-block:: sh + + mgt1:~/bcfg# bcfg2-info + Filesystem check 1 of 25 + ... + > buildall /path/to/cf-old + Generated config for fs2.bgl.mcs.anl.gov in 1.97310400009 seconds + Generated config for fs13.bgl.mcs.anl.gov in 1.47958016396 seconds + ... + + Take notice of any messages produced during configuration generation. These generally reflect minor issues in the configuration specification. Ideally, they should be fixed. + + * Upgrade the server software + * Generate all client configurations in a second location using the new software. Any tracebacks reflect bugs, and should be filed in the ticketing system. Any new messages should be carefully examined. + * Compare each file in the old directory to those in the new directory using ``bcfg2-admin compare -r /old/directory /new/directory`` + + .. code-block:: sh + + mgt1:~/bcfg# bcfg2-admin compare -r cf-old/ cf-new/ + Entry: fs2.bgl.mcs.anl.gov.xml + Entry: fs2.bgl.mcs.anl.gov.xml good + Entry: fs13.bgl.mcs.anl.gov.xml + Entry: fs13.bgl.mcs.anl.gov.xml good + Entry: login1.bgl.mcs.anl.gov.xml + ConfigFile /bin/whatami contents differ + ConfigFile /bin/whatami differs (in bundle softenv) + Entry: login1.bgl.mcs.anl.gov.xml bad + + This can be used to compare configurations for single clients, or different clients. + +2. Compare old and new group diagrams (using ``bcfg2-admin viz``) + +Client Testing +^^^^^^^^^^^^^^ + +Run the client in dry-run and non-dry-run mode; ensure that multiple +runs produce consistent results. + diff --git a/doc/development/tips.txt b/doc/development/tips.txt new file mode 100644 index 000000000..03ffb4871 --- /dev/null +++ b/doc/development/tips.txt @@ -0,0 +1,23 @@ +.. -*- mode: rst -*- + +.. _development-tips: + +Tips for Bcfg2 Development +-------------------------- + +#. Focus on either the client or server code. This focuses the development process down to the precise pieces of code that matter for the task at hand. + + * If you are developing a client driver, then write up a small configuration specification that includes the needed characteristics. + * If you are working on the server, run ``bcfg2-info`` and use to assess the code. + +#. Use the python interpreter. One of python's most appealing features is interactive use of the interpreter. + + * If you are developing for the client-side, run ``python -i /usr/sbin/bcfg2`` with the appropriate bcfg2 options. This will cause the python interpreter to continue running, leaving all variables intact. This can be used to examine data state in a convenient fashion. + * If you are developing for the server side, use ``bcfg2-info`` and the "debug" option. This will leave you at a python interpreter prompt, with the server core loaded in the variable "bcore". + +#. Use ``pylint`` obsessively. It raises a lot of style-related warnings which can be ignored, but most all of the errors are legitimate. +#. If you are doing anything with Regular Expressions, `Kodos`_ and `re-try`_ are your friends. + + +.. _Kodos: http://kodos.sourceforge.net +.. _re-try: http://re-try.appspot.com diff --git a/doc/development/vim_snippet.txt b/doc/development/vim_snippet.txt new file mode 100644 index 000000000..a01c1cfda --- /dev/null +++ b/doc/development/vim_snippet.txt @@ -0,0 +1,65 @@ +.. -*- mode: rst -*- + +.. _development-vim_snippet: + +=================== +Vim Snippet Support +=================== + +This page describes using vim with snipMate and a set of snippets +that allow quick composition of bundles and base files. + +#. Download snipMate from http://www.vim.org/scripts/script.php?script_id=2540 +#. Install it using the install instructions (unzip snipMate.zip -d ~/.vim or equivalent, e.g. $HOME\vimfiles on Windows) +#. Add the following to ``~/.vim/snippets/xml.snippets`` + + .. code-block:: cl + + # Bundle + snippet + ${2} + + # Base + snippet + ${1} + + # Group + snippet + ${2} + + # ConfigFile + snippet + # Service + snippet + # Package + snippet + # Action + snippet + # Directory + snippet + # SymLink + snippet + # Permissions + snippet + + +#. Save and start editing away! + +Each of these snippets activates on the opening element, ie . +After this string is entered, but before entering a space, press , +and the snippet will be expanded. The template will be inserted into +the text with a set of input prompts, which default to overwrite mode +and can be tabbed through. + +The code above only works for bundles and base, but will be expanded +to support other xml files as well. diff --git a/doc/development/writing_plugins.txt b/doc/development/writing_plugins.txt new file mode 100644 index 000000000..40e077e43 --- /dev/null +++ b/doc/development/writing_plugins.txt @@ -0,0 +1,104 @@ +.. -*- mode: rst -*- + +.. _development-write-plugins: + +Writing Bcfg2 Plugins +===================== + +Bcfg2 plugins are python classes that subclass from +Bcfg2.Server.Plugin.Plugin. Several plugin-specific values must be set +in the new plugin. These values dictate how the new plugin will behave +with respect to the above four functions. The following table describes +all important member fields. + ++-----------------+-----------------------------------+--------------------------+ +| Name | Description | Format | ++=================+===================================+==========================+ +| __name__ | The name of the plugin | string | ++-----------------+-----------------------------------+--------------------------+ +| __version__ | The plugin version (generally | string | +| | tied to revctl keyword expansion) | | ++-----------------+-----------------------------------+--------------------------+ +| __author__ | The plugin author. | string | ++-----------------+-----------------------------------+--------------------------+ +| __author__ | The plugin author. | string | ++-----------------+-----------------------------------+--------------------------+ +| __rmi__ | Set of functions to be exposed as | List of function names | +| | XML-RPC functions | (strings) | ++-----------------+-----------------------------------+--------------------------+ +| Entries | Multidimentional dictionary of | Dictionary of | +| | keys that point to the function | ConfigurationEntityType, | +| | used to bind literal contents for | Name keys, and function | +| | a given configuration entity. | reference values | ++-----------------+-----------------------------------+--------------------------+ +| BuildStructures | Function that returns a list of | Member function | +| | the structures for a given client | | ++-----------------+-----------------------------------+--------------------------+ +| GetProbes | Function that returns a list of | Member function | +| | probes that a given client should | | +| | execute | | ++-----------------+-----------------------------------+--------------------------+ +| ReceiveData | Function that accepts the probe | Member function | +| | results for a given client. | | ++-----------------+-----------------------------------+--------------------------+ + +Example Plugin +-------------- + +.. code-block:: python + + import Bcfg2.Server.Plugin + class MyPlugin(Bcfg2.Server.Plugin.Plugin): + '''An example plugin''' + # All plugins need to subclass Bcfg2.Server.Plugin.Plugin + __name__ = 'MyPlugin' + __version__ = '1' + __author__ = 'me@me.com' + __rmi__ = ['myfunction'] + # myfunction is not available remotely as MyPlugin.myfunction + + def __init__(self, core, datastore): + Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) + self.Entries = {'Path':{'/etc/foo.conf': self.buildFoo}} + + def myfunction(self): + '''function for xmlrpc rmi call''' + #do something + return True + + def buildFoo(self, entry, metadata): + '''Bind per-client information into entry based on metadata''' + entry.attrib.update({'type':'file', 'owner':'root', 'group':'root', 'perms':'644'}) + entry.text = '''contents of foo.conf''' + +Example Connector +----------------- + +.. code-block:: python + + import Bcfg2.Server.Plugin + + class Foo(Bcfg2.Server.Plugin.Plugin, + Bcfg2.Server.Plugin.Connector): + '''The Foo plugin is here to illustrate a barebones connector''' + name = 'Foo' + version = '$Revision: $' + experimental = True + + def __init__(self, core, datastore): + Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) + Bcfg2.Server.Plugin.Connector.__init__(self) + self.store = XMLFileBacked(self.data, core.fam) + + def get_additional_data(self, metadata): + + mydata = {} + for data in self.store.entries['foo.xml'].data.get("foo", []): + + mydata[data] = "bar" + + return dict([('mydata', mydata)]) + + def get_additional_groups(self, meta): + return self.cgroups.get(meta.hostname, list()) + diff --git a/doc/development/writing_specification.txt b/doc/development/writing_specification.txt new file mode 100644 index 000000000..4e1c03483 --- /dev/null +++ b/doc/development/writing_specification.txt @@ -0,0 +1,54 @@ +.. -*- mode: rst -*- + +.. _development-writing_specification: + +=========================== +Writing Bcfg2 Specification +=========================== + +Bcfg2 specifications are logically divided in to three areas: + +* Metadata +* Abstract +* Literal + +The metadata portion of the configuration assigns a client to its profile +group and to its non-profile groups. The profile group is assigned +in ``Metadata/clients.xml`` and the non profile group assignments are in +``Metadata/groups.xml``. + +The group memberships contained in the metadata are then used to constuct +an abstract configuration for the client. An abstract configuration for +a client identifies the configuration entities (packages, configuration +files, service, etc) that a client requires, but it does not identify +them explicitly. For instance an abstract configuration may identify +that a client needs the Bcfg2 package with + +.. code-block:: xml + + + +but this does not explicitly identify that an RPM package version +0.9.2 should be loaded from http://rpm.repo.server/bcfg2-1.0.1-0.1.rpm. +The abstract configuration is defined in the xml configuration files +for the Base and Bundles plugins. + +A combination of a clients metadata (group memberships) and abstract +configuration is then used to generate the clients literal configuration. +For instance the above abstract configuration entry may generate a +literal configuration of + + +.. code-block:: xml + + + +A clients literal configuration is generated by a number of plugins that +handle the different configuration entities. + + +.. figure:: specification_overview.png + :width: 60% + :alt: Specification overview + :align: center + diff --git a/doc/faq/client.txt b/doc/faq/client.txt deleted file mode 100644 index e196568bb..000000000 --- a/doc/faq/client.txt +++ /dev/null @@ -1,14 +0,0 @@ -.. _faq-client: - -FAQ: Client -=========== - -**No ca is specified. Cannot authenticate the server with SSL.** - -This means that the client does not have a copy of the CA for the server, -so it can't verify that it is talking to the right server. To fix this -issue, copy ``/etc/bcfg2.crt`` from the server to ``/etc/bcfg2.ca`` -on the client. Then add the following on the client.:: - - [communication] - ca = /etc/bcfg2.ca diff --git a/doc/faq/general.txt b/doc/faq/general.txt deleted file mode 100644 index 65db5883c..000000000 --- a/doc/faq/general.txt +++ /dev/null @@ -1,26 +0,0 @@ -.. _faq-general: - -FAQ: General -============ - -**What does Bcfg2 stand for?** - -Initially, Bcfg stood for the bundle configuration system. Bcfg2 is the -second major revision. At this point, the acronym is meaningless, but -the name has stuck. Luckily, Bcfg2 googles better than Bcfg does. No, -seriously. Try it. All I know is that I have no interest in a billion -cubic feet of gas. - -**What architectures does Bcfg2 support?** - -Bcfg2 should run on any POSIX compatible operating system, however direct -support for an operating system's package and service formats are limited -by the currently available :ref:`client-tools-index` (although new client -tools are pretty easy to add). The following is an incomplete but more -exact list of platforms on which Bcfg2 works. - -* GNU/Linux deb based distros -* GNU/Linux rpm based distros -* Solaris pkg based -* Gentoo portage based -* OSX (POSIX/launchd support) diff --git a/doc/faq/index.txt b/doc/faq/index.txt deleted file mode 100644 index 7f2024619..000000000 --- a/doc/faq/index.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. _faq-index: - -========= -Bcfg2 FAQ -========= - -.. toctree:: - :maxdepth: 2 - - general - client diff --git a/doc/getting_help/error-messages.txt b/doc/getting_help/error-messages.txt new file mode 100644 index 000000000..72d1f1f40 --- /dev/null +++ b/doc/getting_help/error-messages.txt @@ -0,0 +1,45 @@ +.. -*- mode: rst -*- + +.. _error-messages: + +============== +Error Messages +============== + +This page describes error messages produced by Bcfg2 and steps that +can be taken to remedy them. + ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ +| Error | Location | Meaning | Repair | ++===========================================================================+==========+=====================================================================================================+=========+ +| Incomplete information for entry :; cannot verify | Client | The described entry is not fully specified by the server, so no verification can be performed. | [#f1]_ | ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ +| Incomplete information for entry :; cannot install | Client | The described entry is not fully specified by the server, so no verification can be performed. | [#f2]_ | ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ +| The following entries are not handled by any tool: : | Client | The client cannot figure out how to handle this entry. | [#f3]_ | ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ +| no server x509 fingerprint; no server verification performed! | Client | The client is unable to verify the server | [#f4]_ | ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ +| Failed to bind entry: | Server | The server was unable to find a suitable version of entry for client. | [#f5]_ | ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ +| Failed to bind to socket | Server | The server was unable to bind to the tcp server socket. | [#f6]_ | ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ +| Failed to load ssl key | Server | The server was unable to read and process the ssl key. | [#f7]_ | ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ +| Failed to read file | Server | The server failed to read the specified file | [#f8]_ | ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ +| Failed to parse file | Server | The server failed to parse the specified XML file | [#f9]_ | ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ +| Client metadata resolution error for | Server | The server cannot resolve the client hostname or the client is associated with a non-profile group. | [#f10]_ | ++---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ + +.. [#f1] This entry is not being bound. Ensure that a version of this entry applies to this client. +.. [#f2] This entry is not being bound. Ensure that a version of this entry applies to this client. +.. [#f3] Add a type to the generator definition for this entry +.. [#f4] Run bcfg2-admin fingerprint on the server and add it to the client bcfg2.conf as mentioned here +.. [#f5] This entry is not being bound. Ensure that a version of this entry applies to this client. +.. [#f6] Ensure that another instance of the daemon (or any other process) is not listening on the same port. +.. [#f7] Ensure that the key is readable by the user running the daemon and that it is well-formed. +.. [#f8] Ensure that this file still exists; a frequent cause is the deletion of a temp file. +.. [#f9] Ensure that the file is properly formed XML. +.. [#f10] Fix hostname resolution for the client or ensure that the profile group is properly setup. diff --git a/doc/getting_help/faq/client.txt b/doc/getting_help/faq/client.txt new file mode 100644 index 000000000..a230a84bb --- /dev/null +++ b/doc/getting_help/faq/client.txt @@ -0,0 +1,16 @@ +.. -*- mode: rst -*- + +.. _faq-client: + +FAQ: Client +=========== + +**No ca is specified. Cannot authenticate the server with SSL.** + +This means that the client does not have a copy of the CA for the server, +so it can't verify that it is talking to the right server. To fix this +issue, copy ``/etc/bcfg2.crt`` from the server to ``/etc/bcfg2.ca`` +on the client. Then add the following on the client. :: + + [communication] + ca = /etc/bcfg2.ca diff --git a/doc/getting_help/faq/general.txt b/doc/getting_help/faq/general.txt new file mode 100644 index 000000000..f08bfb7b2 --- /dev/null +++ b/doc/getting_help/faq/general.txt @@ -0,0 +1,72 @@ +.. -*- mode: rst -*- + +.. _faq-general: + +FAQ: General +============ + +**What does Bcfg2 stand for?** + +Initially, Bcfg stood for the bundle configuration system. Bcfg2 is the +second major revision. At this point, the acronym is meaningless, but +the name has stuck. Luckily, Bcfg2 googles better than Bcfg does. No, +seriously. Try it. All I know is that I have no interest in a billion +cubic feet of gas. + +**What architectures does Bcfg2 support?** + +Bcfg2 should run on any POSIX compatible operating system, however direct +support for an operating system's package and service formats are limited +by the currently available :ref:`client-tools-index` (although new client +tools are pretty easy to add). The following is an incomplete but more +exact list of platforms on which Bcfg2 works. + +* GNU/Linux deb based distros +* GNU/Linux rpm based distros +* Solaris pkg based +* Gentoo portage based +* OSX (POSIX/launchd support) + +**What pre-requisites are needed to run Bcfg2?** + +Please visit the :ref:`prerequisites` section in the manual. + +**Why won't bcfg2-server start?** + +If your server doesn't seem to be starting and you see no error +messages in your server logs, try running it in the foreground to +see why. + +**Why am I getting a traceback?** + +If you get a traceback, please let us know. You can file a +`ticket `_, send +the traceback to the :ref:`mailinglist`, or hop on +:ref:`ircchannel` and let us know. + +**What is the most common cause of "The following entries are not handled by any tool"?** + +Often it corresponds to entries that aren't bound by the server (for which you'll get error messages on the server). You should try inspecting the logs on the server to see what may be the cause. + +**How can I figure out if error is client or server side?** + +* Cache a copy of the client using ``bcfg2 -c /tmp/config.xml`` +* Search for the entry of interest +* If it looks correct, then there is a client issue + +This file contains all aspects of client configuration. It is structured as a series of bundles and base entries. + +.. note:: + + Most often the entry is not correct and the issue lies in the specification. + +**Where are the server log messages?** + +The bcfg2-server process logs to syslog facility LOG_DAEMON. The server produces a series of messages upon a variety of events and errors. + +**Is there a way to check if all repository XML files conform to schemas?** + +Bcfg2 comes with XML schemas describing all of the XML formats used in +the server repository. A validation command ``bcfg2-repo-validate`` is +included with the source distribution and all packages. Run it with +the ``-v`` flag to see each file and the results if its validation. diff --git a/doc/getting_help/faq/index.txt b/doc/getting_help/faq/index.txt new file mode 100644 index 000000000..27aa5303f --- /dev/null +++ b/doc/getting_help/faq/index.txt @@ -0,0 +1,17 @@ +.. -*- mode: rst -*- + +.. _faq-index: + +=== +FAQ +=== + +The Frequently Asked Questions (FAQ) answers the most common questions +about Bcfg2. At the moment the FAQ is splitted into a general +and a client specfic section. + +.. toctree:: + :maxdepth: 2 + + general + client diff --git a/doc/getting_help/index.txt b/doc/getting_help/index.txt index bc713bcbe..308f31df1 100644 --- a/doc/getting_help/index.txt +++ b/doc/getting_help/index.txt @@ -1,33 +1,40 @@ .. -*- mode: rst -*- -.. _help-index: +.. _gettinghelp-index: -======================= -Getting Help with Bcfg2 -======================= +.. _IRC logs: http://colabti.org/irclogger/irclogger_logs/bcfg2 + + +Getting Help +============ Having trouble? We'd like to help! -* Try the :ref:`FAQ ` -- it's got answers to many common questions. -* Looking for specific information? Try the :ref:`genindex`, :ref:`modindex` or the :ref:`detailed table of contents `. -* Search for information in the :ref:`help-mailinglist`. -* Visit our :ref:`help-irc` channel. +There are several ways to get in touch with the community around Bcfg2. -.. _report-a-bug: +* Try the :ref:`FAQ ` -- it's got answers to many common + questions. -Report A Bug -============ +* Looking for specific information? Try the :ref:`genindex`, + :ref:`modindex`, or the :ref:`detailed table of contents `. + +* Search for information in the :ref:`mailinglist`. -Report bugs with Bcfg2 on the `Trac ticket tracker`_. +* Ask a question in the :ref:`ircchannel`, or search the `IRC logs`_ + to see if its been asked before. -.. _Bcfg2 mailing list archives: http://trac.mcs.anl.gov/projects/bcfg2/wiki/MailingList -.. _Trac ticket tracker: http://trac.mcs.anl.gov/projects/bcfg2/wiki +Note that the IRC channel tends to be much busier than the mailing +list; use whichever seems most appropriate for your query, but don't +let the lack of mailing list activity make you think the project isn't +active. -Other ways to get in touch -========================== .. toctree:: - :maxdepth: 2 + :maxdepth: 1 - irc + reporting mailinglist + ircchannel + faq/index + error-messages + manpages diff --git a/doc/getting_help/irc.txt b/doc/getting_help/irc.txt deleted file mode 100644 index 37d2099d3..000000000 --- a/doc/getting_help/irc.txt +++ /dev/null @@ -1,45 +0,0 @@ -.. -*- mode: rst -*- - -.. _help-irc: - -=== -IRC -=== - -The Bcfg2 IRC channel is `#bcfg2 on chat.freenode.net`_. It is home -to both support and development discussions. If you have a question, -suggestion, or just want to know about Bcfg2, please drop in and say hi. - -.. _#bcfg2 on chat.freenode.net: irc://chat.freenode.net/bcfg2 - -Archives are available at: http://colabti.org/irclogger/irclogger_logs/bcfg2. - -.. raw:: html - -
- - -
- in the timespan - - (yyyymmdd-yyyymmdd) -

Options:
-
-
- - -Administrative Note -=================== - -If the IRC logging stops working for a while, coordinate on #bcfg2 and -then bug **feb** on #irclogger (freenode), and stick around on that -channel until you get an answer (**feb** is great, but busy and in a -non-US time zone). Actually as long as **ilogger2** is logged in you -should be okay (**feb** looks at the logs). - -If you have private logs for the period of time **ilogger2** was off the -channel, you can convert them to the `format shown here`_, and **feb** -will incorporate them into the online logs. Be sure to strip out any -private messages in your logs first :-) - -.. _format shown here: http://colabti.org/irclogger/irclogger_log/bcfg2?date=2008-03-21,Fri;raw=on diff --git a/doc/getting_help/ircchannel.txt b/doc/getting_help/ircchannel.txt new file mode 100644 index 000000000..b97e5f6a6 --- /dev/null +++ b/doc/getting_help/ircchannel.txt @@ -0,0 +1,28 @@ +.. -*- mode: rst -*- + +.. _Freenode: http://chat.freenode.net +.. _#bcfg2: irc://chat.freenode.net/bcfg2 + +.. _ircchannel: + +=========== +IRC Channel +=========== + +The Bcfg2 IRC channel is `#bcfg2`_ on `Freenode`_. It is home to both support and development discussions. If you have a question, suggestion, or just want to know about Bcfg2, please drop in and say hi. + +Archives are available at: http://colabti.org/irclogger/irclogger_logs/bcfg2 + +.. raw:: html + +
+ + +
+ in the timespan + + (yyyymmdd-yyyymmdd) +

Options:
+
+
+ diff --git a/doc/getting_help/manpages.txt b/doc/getting_help/manpages.txt new file mode 100644 index 000000000..14c22a92e --- /dev/null +++ b/doc/getting_help/manpages.txt @@ -0,0 +1,16 @@ +.. -*- mode: rst -*- + +.. _manpages: + +============ +Manual pages +============ + +These are copies of the bcfg2 manual pages created with man2html. +The most recent versions of these man pages are always in the `man/` +directory in the source. + +.. toctree:: + :glob: + + manpages/* diff --git a/doc/getting_help/manpages/bcfg2-admin.txt b/doc/getting_help/manpages/bcfg2-admin.txt new file mode 100644 index 000000000..4440c7134 --- /dev/null +++ b/doc/getting_help/manpages/bcfg2-admin.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _manpages-bcfg2-admin: + +=========== +bcfg2-admin +=========== + +The man page of ``bcfg2-admin``. :: + + man bcfg2-admin diff --git a/doc/getting_help/manpages/bcfg2-build-reports.txt b/doc/getting_help/manpages/bcfg2-build-reports.txt new file mode 100644 index 000000000..217c25627 --- /dev/null +++ b/doc/getting_help/manpages/bcfg2-build-reports.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _manpages-bcfg2-build-reports: + +=================== +bcfg2-build-reports +=================== + +The man page of ``bcfg2-build-reports``. :: + + man bcfg2-build-reports diff --git a/doc/getting_help/manpages/bcfg2-conf.txt b/doc/getting_help/manpages/bcfg2-conf.txt new file mode 100644 index 000000000..623521a67 --- /dev/null +++ b/doc/getting_help/manpages/bcfg2-conf.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _manpages-bcfg2.conf: + +========== +bcfg2.conf +========== + +The man page of ``bcfg2.conf``. :: + + man bcfg2.conf diff --git a/doc/getting_help/manpages/bcfg2-info.txt b/doc/getting_help/manpages/bcfg2-info.txt new file mode 100644 index 000000000..751905e0b --- /dev/null +++ b/doc/getting_help/manpages/bcfg2-info.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _manpages-bcfg2-info: + +========== +bcfg2-info +========== + +The man page of ``bcfg2-info``. :: + + man bcfg2-info diff --git a/doc/getting_help/manpages/bcfg2-repo-validate.txt b/doc/getting_help/manpages/bcfg2-repo-validate.txt new file mode 100644 index 000000000..b13bd928b --- /dev/null +++ b/doc/getting_help/manpages/bcfg2-repo-validate.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _manpages-bcfg2-repo-validate: + +=================== +bcfg2-repo-validate +=================== + +The man page of ``bcfg2-repo-validate``. :: + + man bcfg2-repo-validate diff --git a/doc/getting_help/manpages/bcfg2-server.txt b/doc/getting_help/manpages/bcfg2-server.txt new file mode 100644 index 000000000..27002789e --- /dev/null +++ b/doc/getting_help/manpages/bcfg2-server.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _manpages-bcfg2-server: + +============ +bcfg2-server +============ + +The man page of ``bcfg2-server``. :: + + man bcfg2-server diff --git a/doc/getting_help/manpages/bcfg2.txt b/doc/getting_help/manpages/bcfg2.txt new file mode 100644 index 000000000..4e93ab449 --- /dev/null +++ b/doc/getting_help/manpages/bcfg2.txt @@ -0,0 +1,11 @@ +.. -*- mode: rst -*- + +.. _manpages-bcfg2: + +===== +bcfg2 +===== + +The man page of bcfg2. :: + + man bcfg2 diff --git a/doc/getting_help/reporting.txt b/doc/getting_help/reporting.txt new file mode 100644 index 000000000..cd53b1206 --- /dev/null +++ b/doc/getting_help/reporting.txt @@ -0,0 +1,12 @@ +.. -*- mode: rst -*- + +.. _reporting: + +.. _tracker: http://trac.mcs.anl.gov/projects/bcfg2/wiki + +============== +Reporting bugs +============== + +Report bugs with Bcfg2 in our `tracker`_. + diff --git a/doc/getting_started/index.txt b/doc/getting_started/index.txt index 2c05c5238..786c70290 100644 --- a/doc/getting_started/index.txt +++ b/doc/getting_started/index.txt @@ -2,57 +2,245 @@ .. _getting_started-index: -=========== -Using Bcfg2 -=========== +=============== +Getting started +=============== -These are many of the resources available to help new users get started. +The steps below should get you from just thinking about a +configuration management system to an operational installation of +Bcfg2. If you get stuck, be sure to check the :ref:`mailinglist` +or to drop in on our :ref:`ircchannel`. -* For the impatient there is the :ref:`quickstart-index` page. -* :ref:`help-index` has information when you are troubleshooting or need to ask a question. -* If you find anything wrong or missing please :ref:`report-a-bug` to let us know. +Get and Install Bcfg2 Server +============================ -.. toctree:: - :maxdepth: 2 +We recommend running the server on a Linux machine for ease of +deployment due to the availability of packages for the dependencies. - using-bcfg2-info - using-bcfg2-with-centos +First, you need to download and install Bcfg2. The section +:ref:`installation-index` in this manual describes the steps to take. +To start, you will need to install the server on one machine and the +client on one or more machines. Yes, your server can also be a client +(and should be by the time your environment is fully managed). -Must Reads -========== +.. _Bcfg2 download page: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Download +.. _Install page: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Install + +Set up Repository +================= + +The next step after installing the Bcfg2 packages is to configure the +server. You can easily set up a personalized default configuration by +running, on the server, :: + + bcfg2-admin init -* `Documentation` -* `WritingSpecification` -* `Bcfg2 Architecture ` -* `ServerSideOverview` -* `UpgradeTesting` -* `Troubleshooting` -* `Bcfg2 Server Plugins ` +You will be presented with a series of questions that will build a +Bcfg2 configuration file in ``/etc/bcfg2.conf``, set up a skeleton +repository (in ``/var/lib/bcfg2`` by default), help you create ssl +certificates, and do any other similar tasks needed to get you +started. + +Once this process is done, you can start the Bcfg2 server:: + + /etc/init.d/bcfg2-server start + +You can try it out by running the Bcfg2 client on the same machine, +acting like it is your first client. + +.. note:: + + The following command will tell the client to run in no-op mode, + meaning it will only check the client against the repository and + report any changes it sees. It won't make any changes (partially + because you haven't populated the repository with any + yet). However, nobody is perfect - you can make a typo, our + software can have bugs, monkeys can break in and hit enter before + you are done. Don't run this command on a production system if you + don't know what it does and aren't prepared for the + consequences. We don't know of anybody having problems with it + before, but it is better to be safe than sorry. + +And now for the command:: + + bcfg2 -q -v -n -Misc/Others -=========== +That can be translated as "bcfg2 quick verbose no-op". The output +should be something similar to:: -* `Probes ` -* `AgentMode` -* `DynamicGroups` -* `Client Tool Drivers ` -* `Developing for Bcfg2 ` -* `Howtos` + Loaded tool drivers: + Chkconfig POSIX PostInstall RPM -Reporting -========= + Phase: initial + Correct entries: 0 + Incorrect entries: 0 + Total managed entries: 0 + Unmanaged entries: 242 + + + Phase: final + Correct entries: 0 + Incorrect entries: 0 + Total managed entries: 0 + Unmanaged entries: 242 + +Perfect! We have started out with an empty configuration, and none of +our configuration elements are correct. It doesn't get much cleaner +than that. But what about those unmanaged entries? Those are the extra +configuration elements (probably all packages at the moment) that +still aren't managed. Your goal now is to migrate each of those plus +any it can't see up to the "Correct entries" line. + +Populate Repository +=================== + +Finally, you need to populate your repository. Unfortunately, from +here on out we can't write up a simple recipe for you to follow to get +this done. It is very dependent on your local configuration, your +configuration management goals, the politics surrounding your +particular machines, and many other similar details. We can, however, +give you guidance. + +After the above steps, you should have a toplevel repository structure +that looks like:: + + bcfg-server:~ # ls /var/lib/bcfg2 + Bundler/ Cfg/ Metadata/ Pkgmgr/ Rules/ SSHbase/ etc/ + +The place to start is the Metadata directory, which contains two +files: ``clients.xml`` and ``groups.xml``. Your current +``clients.xml`` will look pretty close to: + +.. code-block:: xml + + + + + +The ``clients.xml`` file is just a series of ```` tags, each +of which describe one host you manage. Right now we only manage one +host, the server machine we just created. This machine is bound to the +``basic`` profile, is pingable, has a pingtime of ``0``, and has the +name ``bcfg-server.example.com``. The two "ping" parameters don't +matter to us at the moment, but the other two do. The name parameter +is the fully qualified domain name of your host, and the profile +parameter maps that host into the ``groups.xml`` file. + +Our simple ``groups.xml`` file looks like: + +.. code-block:: xml + + + + + + + + + + + + + +There are two types of groups in Bcfg: profile groups +(``profile='true'``) and non-profile groups +(``profile='false'``). Profile groups can act as top-level groups to +which clients can bind, while non-profile groups only exist as members +of other groups. In our simple starter case, we have a profile group +named ``basic``, and that is the group that our first client bound +to. Our first client is a SuSE machine, so it contains the ``suse`` +group. Of course, ``bcfg2-admin`` isn't smart enough to fill out the +rest of your config, so the ``suse`` group further down is empty. + +Let's say the first thing we want to set up on our machine is the +message of the day. To do this, we simply need to create a Bundle and +add that Bundle to an appropriate group. In this simple example, we +start out by adding + +.. code-block:: xml + + + +to the ``basic`` group. + +Next, we create a motd.xml file in the Bundler directory: + +.. code-block:: xml + + + + + +Now when we run the client, we get slightly different output:: + + Loaded tool drivers: + Chkconfig POSIX PostInstall RPM + Incomplete information for entry Path:/etc/motd; cannot verify + + Phase: initial + Correct entries: 0 + Incorrect entries: 1 + Total managed entries: 1 + Unmanaged entries: 242 + + In dryrun mode: suppressing entry installation for: + Path:/etc/motd + + Phase: final + Correct entries: 0 + Incorrect entries: 1 + Total managed entries: 1 + Unmanaged entries: 242 + +We now have an extra unmanaged entry, bringing our total number of +managed entries up to one. To manage it we need to copy ``/etc/motd`` +to ``/var/lib/bcfg2/Cfg/etc/motd/``. Note the layout of that path: all +plain-text config files live in the Cfg directory. The directory +structure under that directory directly mimics your real filesystem +layout, making it easy to find and add new files. The last directory +is the name of the file itself, so in this case the full path to the +motd file would be ``/var/lib/bcfg2/Cfg/etc/motd/motd``. Copy your +real ``/etc/motd`` file to that location, run the client again, and +you will find that we now have a correct entry:: + + Loaded tool drivers: + Chkconfig POSIX PostInstall RPM + + Phase: initial + Correct entries: 1 + Incorrect entries: 0 + Total managed entries: 1 + Unmanaged entries: 242 + + + Phase: final + Correct entries: 1 + Incorrect entries: 0 + Total managed entries: 1 + Unmanaged entries: 242 + +Done! Now we just have 242 (or more) entries to take care of! + +:ref:`server-plugins-structures-bundler-index` is a relatively easy +directory to populate. You can find many samples of Bundles in the +`Bundle Repository`_, many of which can be used without editing. + +.. _Bundle Repository: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Bundler/examples + +Next Steps +========== -* :ref:`server-reports-index` +Several other utilities can help from this point on: -Examples -======== +``bcfg2-info`` is a utility that instantiates a copy of the Bcfg2 server +core (minus the networking code) for examination. From this, you can +directly query: -* `Demo Repository ` -* `Plugins/Bundler/examples` -* `Plugins/Probes/examples` -* `Plugins/TGenshi/examples` +* Client Metadata +* Which entries are provided by particular plugins +* Client Configurations -Man Pages -========= +Run ``bcfg2-info``, and type help and the prompt when it comes up. -* `Manual Pages ` +``bcfg2-admin`` can perform a variety of repository maintenance +tasks. Run ``bcfg2-admin`` help for details. diff --git a/doc/getting_started/using-bcfg2-info.txt b/doc/getting_started/using-bcfg2-info.txt deleted file mode 100644 index 1fab0ea07..000000000 --- a/doc/getting_started/using-bcfg2-info.txt +++ /dev/null @@ -1,132 +0,0 @@ -.. -*- mode: rst -*- - -.. _getting_started-using_bcfg2_info: - -================ -Using bcfg2-info -================ - -*bcfg2-info* is a tool for introspecting server functions. It is -useful for understanding how the server is interpreting your -repository. It consists of the same logic executed by the server to -process the repository and produce configuration specifications, just -without all of the network communication code. Think of *bcfg2-info* -as *bcfg2-server* on a stick. It is a useful location to do testing -and staging of new configuration rules, prior to deployment. This is -particularly useful when developing templates, or developing Bcfg2 -plugins. - -Getting Started -=============== - -First, fire up the bcfg2-info interpreter. - -.. code-block:: none - - [0:464] bcfg2-info - Loading experimental plugin(s): Packages - NOTE: Interfaces subject to change - Handled 8 events in 0.006s - Handled 4 events in 0.035s - Welcome to bcfg2-info - Type "help" for more information - > - -At this point, the server core has been loaded up, all plugins have -been loaded, and the *bcfg2-info* has both read the initial state of -the Bcfg2 repository, as well as begun monitoring it for changes. Like -*bcfg2-server*, *bcfg2-info* monitors the repository for changes, -however, unlike *bcfg2-server*, it does not process change events -automatically. File modification events can be processed by explicitly -calling the **update** command. This will process the events, -displaying the number of events processed and the amount of time taken -by this processing. If no events are available, no message will be -displayed. For example, after a change to a file in the repository: - -.. code-block:: none - - >update - Handled 1 events in 0.001s - > update - > - -This explicit update process allows you to control the update process, -as well as see the precise changes caused by repository -modifications. - -*bcfg2-info* has several builtin commands that display the state of -various internal server core state. These are most useful for -examining the state of client metadata, either for a single client, or -for clients overall. - -**clients** - displays a list of clients, along with their profile groups -**groups** - displays a list of groups, the inheritance hierarchy, profile - status, and category name, if there is one. -**showclient** - displays full metadata information for a client, including - profile group, group memberships, bundle list, and any connector - data, like Probe values or Property info. - -Debugging Configuration Rules -============================= - -In addition to the commands listed above for viewing client metadata, -there are also commands which can shed light on the configuration -generation process. Recall that configuration generation occurs in -three major steps: - -1) Resolve client metadata -2) Build list of entries for the configuration -3) Bind host-specific version of each entry - -Step *1* can be viewed with the commands presented in the previous -section. The latter two steps can be examined using the following -commands. - -**showentries** - displays a list of entries (optionally filtered by type) that - appear in a client's configuration specification - -**buildfile** - Perform the entry binding process on a single entry, displaying - its results. This command is very useful when developing - configuration file templates. - -**build** - Build the full configuration specification and write it to a - file. - -**mappings** - displays the entries handled by the plugins loaded by the server - core. This command is useful when the server reports a bind - failure for an entry. - -Debugging and Developing Bcfg2 -============================== - -*bcfg2-info* loads a full Bcfg2 server core, so it provides the ideal -environment for developing and debugging Bcfg2. Because it is hard to -automate this sort of process, we have only implemented two commands -in *bcfg2-info* to aid in the process. - -**profile** - The profile command produces python profiling information for - other *bcfg2-info* commands. This can be used to track - performance problems in configuration generation. - -**debug** - The debug command exits the *bcfg2-info* interpreter loop and drops - to a python interpreter prompt. The Bcfg2 server core is available - in this namespace as "self". Full documentation for the server core - is out of scope for this document. This capability is most useful - to call into plugin methods, often with setup calls or the enabling - of diagnostics. - - It is possible to return to the *bcfg2-info* command loop by - exiting the python interpreter with ^D. - - There is built-in support for IPython in *bcfg2-info*. If IPython - is installed, dropping into debug mode in *bcfg2-info* will use - the IPython interpreter by default. diff --git a/doc/getting_started/using-bcfg2-with-centos.txt b/doc/getting_started/using-bcfg2-with-centos.txt deleted file mode 100644 index 93875d4c5..000000000 --- a/doc/getting_started/using-bcfg2-with-centos.txt +++ /dev/null @@ -1,79 +0,0 @@ -.. -*- mode: rst -*- - -.. _EPEL: http://fedoraproject.org/wiki/EPEL -.. _RPMForge: https://rpmrepo.org/RPMforge - -.. _getting_started-using_bcfg2-with-centos: - -======================= -Using Bcfg2 With CentOS -======================= - -This section covers specific topics for using Bcfg2 with CentOS. Most -likely the tips on this page also apply to other members of the Red Hat -family of Linux operating systems. - -From Source -+++++++++++ - -Install Prerequisities -###################### - -While you can go about building all these things from source, this -how to will try and meet the dependencies using packages from EPEL_ -or RPMforge_. The *el5* package should be compatible with CentOS 5.x. - -EPEL_:: - - [root@centos ~]# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm - -RPMforge_:: - - [root@centos ~]# rpm -Uvh http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm - -.. note:: - - Be careful with `mixing package repositories - `_. - -Now you can install the rest of the prerequisites:: - - [root@centos ~]# yum install python-genshi python-cheetah python-lxml - -Build Packages from source -########################## - -* After installing git, clone the master branch:: - - [root@centos redhat]# git clone git://git.mcs.anl.gov/bcfg2.git - -* Install the ``fedora-packager`` package :: - - [root@centos ~]# yum install fedora-packager - -* A directory structure for the RPM build process has to be established. :: - - [you@centos ~]$ rpmdev-setuptree - -* Change to the *redhat* directory of the checked out Bcfg2 source:: - - [you@centos ~]$ cd bcfg2/redhat/ - -* In the particular directory is a Makefile which will do the job of building the RPM packages. You can do this as root, but it's not recommanded:: - - [you@centos redhat]$ make - -* Now the new RPM package can be installed. Please adjust the path to your RPM package:: - - [root@centos ~]# rpm -ihv /home/YOU/rpmbuild/RPMS/noarch/bcfg2-server-1.0.0-0.2r5835.noarch.rpm - -Install Packages from Package repository -######################################## - -To install the bcfg2-server and bcfg2 from a package repository, just -use Yum to do it:: - - [root@centos ~]# yum install bcfg2-server bcfg2 - -.. toctree:: - :hidden: diff --git a/doc/installation/distributions.txt b/doc/installation/distributions.txt new file mode 100644 index 000000000..5a86e81d5 --- /dev/null +++ b/doc/installation/distributions.txt @@ -0,0 +1,17 @@ +.. -*- mode: rst -*- + +.. _distributions: + +=========================== +Distribution-specific notes +=========================== + +The installation of Bcfg2 on a specific distribution depends on +the used package management tool and the disposability in the +distribution's package :term:`repository` +. + +.. toctree:: + :glob: + + distro/* diff --git a/doc/installation/distro/archlinux.txt b/doc/installation/distro/archlinux.txt new file mode 100644 index 000000000..75ff59c49 --- /dev/null +++ b/doc/installation/distro/archlinux.txt @@ -0,0 +1,17 @@ +.. -*- mode: rst -*- + +.. _installation-archlinux: + +.. _Arch Linux: http://www.archlinux.org/ +.. _AUR: http://aur.archlinux.org/packages.php?ID=20979 + + +ArchLinux +========= + +Packages for `Arch Linux`_ are available in the Arch User Repository (AUR_). +Just use `pacman` to perform the installation :: + + pacman -S bcfg2 bcfg2-server + + diff --git a/doc/installation/distro/debian.txt b/doc/installation/distro/debian.txt new file mode 100644 index 000000000..67a4f1d9d --- /dev/null +++ b/doc/installation/distro/debian.txt @@ -0,0 +1,24 @@ +.. -*- mode: rst -*- + +.. _debian: + +.. _Wiki: http://trac.mcs.anl.gov/projects/bcfg2/wiki/PrecompiledPackages#UnofficialDebianRepository + +Debian +====== + +Packages of Bcfg2 are available for Debian Lenny, Debian Squeeze, and +Debian Sid. The fastest way to get Bcfg2 onto your Debian system +is to use `apt-get` or `aptitude`. :: + + sudo aptitude install bcfg2 bcfg2-server + +If you want to use unofficial packages from Bcfg2. Add the following line +to your `/etc/apt/sources.list` file :: + + deb ftp://ftp.mcs.anl.gov/pub/bcfg/debian sarge/ + +Now just run `aptitute` in the way it is mentioned above. + +For more details about running prerelease version of Bcfg2 on Debian +systems, please refer to the Wiki_. diff --git a/doc/installation/distro/fedora.txt b/doc/installation/distro/fedora.txt new file mode 100644 index 000000000..92771b974 --- /dev/null +++ b/doc/installation/distro/fedora.txt @@ -0,0 +1,23 @@ +.. -*- mode: rst -*- + +.. _Packages: https://admin.fedoraproject.org/pkgdb/acls/name/bcfg2 +.. _Fedora: https://www.fedoraproject.org + +.. _fedora-installation: + +Fedora +====== + +The fastest way to get Bcfg2 Packages_ onto your Fedora_ system is to +use `yum` or PackageKit. Yum will pull in all dependencies of Bcfg2 +automatically. :: + + $ su -c 'yum install bcfg2-server bcfg2' + +Be aware that the latest release of Bcfg2 may only be available for the +Development release of Fedora (Rawhide). With the activation of the +Rawhide repository of Fedora you will be able to install it. :: + + $ su -c 'yum install --enablerepo=rawhide bcfg2-server bcfg2' + +This way is not recommanded on productive systems. Only for testing. diff --git a/doc/installation/distro/gentoo.txt b/doc/installation/distro/gentoo.txt new file mode 100644 index 000000000..5497a01b2 --- /dev/null +++ b/doc/installation/distro/gentoo.txt @@ -0,0 +1,27 @@ +.. -*- mode: rst -*- + +.. _gentoo-installation: + +.. _Freenode: http://chat.freenode.net +.. _#bcfg2: irc://chat.freenode.net/bcfg2 + + +Gentoo +====== + +Early in July 2008, Bcfg2 was added to the Gentoo portage tree. So far +it's only keyworded for ~x86, but we hope to see it soon in the amd64 and +x64-solaris ports. If you're using Gentoo on some other architecture, it +should still work provided that you have a reasonably up to date Python; +try adding `app-admin/bcfg2 ~*` to your `/etc/portage/package.keywords` +file. + +If you don’t use portage to install Bcfg2, you’ll want to make sure you +have all the prerequisites installed first. For a server, you’ll need: + +* ``app-admin/gamin`` or ``app-admin/fam`` +* ``dev-python/lxml`` + +Clients will need at least: + +* ``app-portage/gentoolkit`` diff --git a/doc/installation/distro/osx.txt b/doc/installation/distro/osx.txt new file mode 100644 index 000000000..8b7a5a95d --- /dev/null +++ b/doc/installation/distro/osx.txt @@ -0,0 +1,29 @@ +.. -*- mode: rst -*- + +.. _osx-installation: + +.. _Freenode: http://chat.freenode.net +.. _#bcfg2: irc://chat.freenode.net/bcfg2 + + +OS X +==== + +Once macports is installed:: + + port install bcfg2 + +Using native OS X python +------------------------ + +First, make sure you have Xcode installed as you need `packagemaker` which +comes bundled in the Developer tools. + +Clone the git source:: + + git clone git://git.mcs.anl.gov/bcfg2.git + +Change to the osx directory and type make. Your new package should be located +at bcfg2-'''$VERSION'''.pkg (where '''$VERSION''' is that which is specified +in setup.py). + diff --git a/doc/installation/distro/rhel.txt b/doc/installation/distro/rhel.txt new file mode 100644 index 000000000..49e43179f --- /dev/null +++ b/doc/installation/distro/rhel.txt @@ -0,0 +1,31 @@ +.. -*- mode: rst -*- + +.. _CentOS: http://www.centos.org/ +.. _Red Hat/RHEL: http://www.redhat.com/rhel/ +.. _Scientific Linux: http://www.scientificlinux.org/ +.. _EPEL: http://fedoraproject.org/wiki/EPEL +.. _RPMForge: https://rpmrepo.org/RPMforge + +.. _rhel-installation: + +RHEL / Centos / Scientific Linux +================================ + +While you can go about building all these things from source, this +section will try and meet the dependencies using packages from EPEL_ +[#f1]_. The *el5* and the soon available *el6* package should be compatible +with `CentOS`_ 5.x/6.x and `Scientific Linux`_. + +EPEL_:: + + [root@centos ~]# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm + +Install the bcfg2-server and bcfg2 RPMs:: + + [root@centos ~]# yum install bcfg2-server bcfg2 + +.. note:: + + The latest package for *el5* is only available in the testing repository. + +.. [#f1] For more details check the EPEL_ `instructions `_ diff --git a/doc/installation/distro/ubuntu.txt b/doc/installation/distro/ubuntu.txt new file mode 100644 index 000000000..694cce865 --- /dev/null +++ b/doc/installation/distro/ubuntu.txt @@ -0,0 +1,36 @@ +.. -*- mode: rst -*- + +.. _ubuntu-installation: + +.. _Ubuntu: http://www.ubuntu.com +.. _Wiki: http://trac.mcs.anl.gov/projects/bcfg2/wiki/PrecompiledPackages#UbuntuLaunchpadBcfg2PPA + +Ubuntu +====== + +The steps to bring Bcfg2 onto your Ubuntu_ system depends on your +release. + +* Dapper + Add the following lines to `/etc/apt/sources.list` :: + + deb ftp://ftp.mcs.anl.gov/pub/bcfg/ubuntu dapper/ + deb http://archive.ubuntu.com/ubuntu dapper universe + deb-src http://archive.ubuntu.com/ubuntu dapper universe + +* Edgy + Add the following lines to `/etc/apt/sources.list` :: + + deb ftp://ftp.mcs.anl.gov/pub/bcfg/ubuntu edgy/ + deb http://archive.ubuntu.com/ubuntu edgy universe + deb-src http://archive.ubuntu.com/ubuntu edgy universe + +* Feisty + Those packages are available from the Ubuntu_ repositories. + +To install the packages, just lauch the following command :: + + sudo aptitude install bcfg2 bcfg2-server + +For more details about running prerelease version of Bcfg2 on Ubuntu_ +systems, please refer to the Wiki_. diff --git a/doc/installation/index.txt b/doc/installation/index.txt new file mode 100644 index 000000000..9f04d4b52 --- /dev/null +++ b/doc/installation/index.txt @@ -0,0 +1,23 @@ +.. -*- mode: rst -*- + +.. _installation-index: + +============ +Installation +============ + +Before installing, you will need to choose a machine to be the Bcfg2 +server. We recommend a Linux-based machine for this purpose, but the +server will work on any supported operating system. Note that you may +eventually want to run a web server on this machine for reporting and +serving up package repositories. The server package only needs to be +installed on your designated Bcfg2 server machine. The clients package +needs to be installed on any machine you plan to manage by Bcfg2. + +.. toctree:: + :maxdepth: 2 + + prerequisites + source + packages + distributions diff --git a/doc/installation/packages.txt b/doc/installation/packages.txt new file mode 100644 index 000000000..a15e3e98e --- /dev/null +++ b/doc/installation/packages.txt @@ -0,0 +1,81 @@ +.. -*- mode: rst -*- + +.. _packages: + +.. _CentOS: http://www.centos.org/ +.. _Red Hat/RHEL: http://www.redhat.com/rhel/ +.. _Scientific Linux: http://www.scientificlinux.org/ +.. _EPEL: http://fedoraproject.org/wiki/EPEL +.. _RPMForge: https://rpmrepo.org/RPMforge + + +Building packages from source +============================= + +The Bcfg2 distribution contains two different spec files. + +Building from Tarball +--------------------- + +* Copy the tarball to `/usr/src/packages/SOURCES/` +* Extract another copy of it somewhere else (eg: `/tmp`) and retrieve + the `misc/bcfg2.spec` file +* Run :: + + rpmbuild -ba bcfg2.spec + +* The resulting RPMs will be in `/usr/src/packages/RPMS/` and SRPMs + in `/usr/src/packages/SRPMS` + +Building from an GIT Checkout +----------------------------- + +* Change to the `redhat/` directory in the working copy +* Run :: + + make + +* The resulting RPMs will be in `/usr/src/redhat/RPMS/ `and SRPMs + in `/usr/src/redhat/SRPMS` and will have the SVN revision appended + +Building RPM packages with ``rpmbuild`` +--------------------------------------- + +While you can go about building all these things from source, this +how to will try and meet the dependencies using packages from EPEL_. +The *el5* package should be compatible with CentOS 5.x. + +* Installation of the EPEL_ repository package :: + + [root@centos ~]# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm + +* Now you can install the rest of the prerequisites :: + + [root@centos ~]# yum install python-genshi python-cheetah python-lxml + +* After installing git, check out the master branch :: + + [root@centos redhat]# git clone git://git.mcs.anl.gov/bcfg2.git + +* Install the ``fedora-packager`` package :: + + [root@centos ~]# yum install fedora-packager + +* A directory structure for the RPM build process has to be established. :: + + [you@centos ~]$ rpmdev-setuptree + +* Change to the *redhat* directory of the checked out Bcfg2 source:: + + [you@centos ~]$ cd bcfg2/redhat/ + +* In the particular directory is a ``Makefile`` which will do the job of + building the RPM packages. You can do this as root, but it's not + recommanded :: + + [you@centos redhat]$ make + +* Now the new RPM package can be installed. Please adjust the path to + your RPM package :: + + [root@centos ~]# rpm -ihv /home/YOU/rpmbuild/RPMS/noarch/bcfg2-server-1.0.0-0.2r5835.noarch.rpm diff --git a/doc/installation/prerequisites.txt b/doc/installation/prerequisites.txt new file mode 100644 index 000000000..e4ea715b0 --- /dev/null +++ b/doc/installation/prerequisites.txt @@ -0,0 +1,47 @@ +.. -*- mode: rst -*- + +.. _prerequisites: + +Prerequisites +============= + +Bcfg2 has several server side prerequisites and a minimal set of +client side requirements. This page describes the prerequisite +software situation on all supported platforms. The table describes +what software is needed on the client and server side. + + +Bcfg2 Client +------------ + +===================================== =================== ============================== +Software Version Requires +===================================== =================== ============================== +libxml2 (if lxml is used) Any +libxslt (if lxml is used) Any libxml2 +python 2.3-2.4, 2.5 [#f1]_ +lxml or elementtree [#f2]_ Any lxml: libxml2, libxslt, python +python-apt [#f3]_ Any python +debsums (if APT tool driver is used) Any +===================================== =================== ============================== + + +.. [#f1] python 2.5 works with elementtree. +.. [#f2] elementtree is included in python 2.5 and later. +.. [#f3] python-apt is only required on platforms that use apt, such as Debian and Ubuntu. + +Bcfg2 Server +------------ + +===================================== ============= ============================== +Software Version Requires +===================================== ============= ============================== +libxml2 2.6.24+ +libxslt Any libxml2 +python 2.2-2.5 +lxml 0.9+ lxml: libxml2, libxslt, python +gamin or fam Any +python-gamin or python-fam Any gamin or fam, python +M2crypto Any python, openssl +===================================== ============= ============================== + diff --git a/doc/installation/source.txt b/doc/installation/source.txt new file mode 100644 index 000000000..e21f7150f --- /dev/null +++ b/doc/installation/source.txt @@ -0,0 +1,64 @@ +.. -*- mode: rst -*- + +.. _Download: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Download +.. _GPG: http://pgpkeys.mit.edu:11371/pks/lookup?op=get&search=0x75BF2C177F7D197E +.. _GPGKey: ftp://ftp.mcs.anl.gov/pub/bcfg/bcfg2-1.1.0.tar.gz.gpg +.. _Tarball: ftp://ftp.mcs.anl.gov/pub/bcfg/bcfg2-1.1.0.tar.gz + +.. |md5sum| replace:: 13593938daf7e8b9a81cb4b677dc7f99 +.. |version| replace:: 1.1.0 +.. |rel_date| replace:: 9/27/10 + +.. _source: + +Download +======== + +Tarball +------- + +The Bcfg2 source tarball can be grabbed from the Download_ page. + +========= ======== ======= ============== ===================== +Version URL GPG key Release Date md5sum +========= ======== ======= ============== ===================== +|version| Tarball_ GPGKey_ |rel_date| |md5sum| +========= ======== ======= ============== ===================== + +The full command to use with ``wget`` are listed below. Please +replace ```` with |version|. :: + + wget ftp://ftp.mcs.anl.gov/pub/bcfg/bcfg2-.tar.gz + wget ftp://ftp.mcs.anl.gov/pub/bcfg/bcfg2-.tar.gz.gpg + +All tarballs are signed with GPG key `7F7D197E `_. You can verify +your download by importing the key and running :: + + $ gpg --recv-keys 0x75bf2c177f7d197e + $ gpg --verify bcfg2-.tar.gz.gpg bcfg2-.tar.gz + +For older or prepreleases please visit the Download_ wiki page. + + +Git checkout +------------ + +You can also get the latest (possibly broken) code via git :: + + git clone git://git.mcs.anl.gov/bcfg2.git + +Installation from source +======================== + +If you are working with the release tarball of Bcfg2 you need to +untar it before you can go on with the installation :: + + tar -xzf bcfg2-.tar.gz + +Now you can build Bcfg2 with. If you are working with a SVN checkout +no need to be specified. :: + + cd bcfg2- + python setup.py install --prefix=/install/prefix + +This will install both the client and server on that machine. diff --git a/doc/server/plugins/generators/tcheetah.txt b/doc/server/plugins/generators/tcheetah.txt index 52a0f3264..e1ad600a2 100644 --- a/doc/server/plugins/generators/tcheetah.txt +++ b/doc/server/plugins/generators/tcheetah.txt @@ -27,7 +27,7 @@ located in in a ``TCheetah`` subdirectory of your repository, usually files, ``template`` and ``info``. The template is a standard Cheetah template with two additions: -* `self.metadata` is the client's :ref:`metadata ` +* `self.metadata` is the client's metadata * `self.properties` is an xml document of unstructured data The ``info`` file is formatted like ``:info`` files from Cfg. @@ -44,7 +44,19 @@ Permissions entry and a Path entry to handle the same file. self.metadata variables ======================= -self.metadata is an instance of the class ClientMetadata and documented :ref:`here `. +The following variables are available for self.metadata: + +* hostname +* bundles +* groups +* categories +* probes +* uuid +* password + +self.metadata is an instance of the class +ClientMetadata of file `Bcfg2/Server/Plugins/Metadata.py +`_. self.properties =============== diff --git a/doc/server/plugins/generators/tgenshi/index.txt b/doc/server/plugins/generators/tgenshi/index.txt index 425b3a289..cd9bcf152 100644 --- a/doc/server/plugins/generators/tgenshi/index.txt +++ b/doc/server/plugins/generators/tgenshi/index.txt @@ -48,10 +48,8 @@ supported. Inside of templates =================== -* **metadata** is the client's :ref:`metadata ` -* **properties.properties** is an xml document of unstructured data -* **name** is the path name specified in bcfg -* **path** is the path to the TGenshi template +* metadata is the client's metadata +* properties.properties is an xml document of unstructured data See the genshi `documentation `_ for examples of diff --git a/doc/server/plugins/grouping/metadata.txt b/doc/server/plugins/grouping/metadata.txt index 22c967262..96fc70ff5 100644 --- a/doc/server/plugins/grouping/metadata.txt +++ b/doc/server/plugins/grouping/metadata.txt @@ -225,70 +225,3 @@ Probes The metadata plugin includes client-side probing functionality. This is fully documented :ref:`here `. - -.. _server-plugins-grouping-metadata-clientmetadata: - -ClientMetadata -============== - -A special client metadata class is available to the TGenshi and TCheetah -plugins. - -+----------------------+------------------------------------------------+-------------------+ -| Attribute | Description | Value | -+======================+================================================+===================+ -| hostname | Client hostname | String | -+----------------------+------------------------------------------------+-------------------+ -| profile | Client profile | String | -+----------------------+------------------------------------------------+-------------------+ -| aliases | Client aliases | List | -+----------------------+------------------------------------------------+-------------------+ -| addresses | Adresses this client is known by | List | -+----------------------+------------------------------------------------+-------------------+ -| groups | Groups this client is a member of | List | -+----------------------+------------------------------------------------+-------------------+ -| categories | Categories of this clients groups | List | -+----------------------+------------------------------------------------+-------------------+ -| uuid | uuid identifier for this client | String | -+----------------------+------------------------------------------------+-------------------+ -| password | bcfg password for this client | String | -+----------------------+------------------------------------------------+-------------------+ -| connectors | connector plugins known to this client | List | -+----------------------+------------------------------------------------+-------------------+ -| query | MetadataQuery object | MetadataQuery | -+----------------------+------------------------------------------------+-------------------+ - -| - -+------------------------------+------------------------------------------------+-------------------+ -| Method | Description | Value | -+==============================+================================================+===================+ -| inGroup(group) | True if this client is a memnber of 'group' | Boolean | -+------------------------------+------------------------------------------------+-------------------+ -| group_in_category(category) | Returns the group in 'category' if the client | String | -| | is a member of 'category', otherwise '' | | -+------------------------------+------------------------------------------------+-------------------+ - -MetadataQuery -------------- - -This class provides query routines for the servers Metadata. - -+------------------------------+------------------------------------------------+-------------------+ -| Method | Description | Value | -+==============================+================================================+===================+ -| by_name(client) | Get ClientMetadata object for 'client' | ClientMetadata | -+------------------------------+------------------------------------------------+-------------------+ -| names_by_groups(group) | | | -+------------------------------+------------------------------------------------+-------------------+ -| names_by_profiles(profile) | All clients names in 'profile' | List | -+------------------------------+------------------------------------------------+-------------------+ -| all_clients() | All known client hostnames | List | -+------------------------------+------------------------------------------------+-------------------+ -| all_groups() | All known group names | List | -+------------------------------+------------------------------------------------+-------------------+ -| all_groups_in_category(cat) | All groups in category 'cat' | List | -+------------------------------+------------------------------------------------+-------------------+ -| all() | Get ClientMetadata for all clients | List | -+------------------------------+------------------------------------------------+-------------------+ - diff --git a/doc/server/plugins/index.txt b/doc/server/plugins/index.txt index 61f91da86..126331325 100644 --- a/doc/server/plugins/index.txt +++ b/doc/server/plugins/index.txt @@ -68,15 +68,6 @@ Literal Configuration (Generators) Each of these plugins has a corresponding subdirectory with the same name in the Bcfg2 repository. -Connector Plugins ------------------ - -.. toctree:: - :maxdepth: 2 - :glob: - - connectors/* - Statistics Plugins ------------------ @@ -112,4 +103,5 @@ More details can be found in :ref:`server-plugins-plugin-roles` plugin-roles probes/index + properties trigger diff --git a/doc/server/plugins/properties.txt b/doc/server/plugins/properties.txt new file mode 100644 index 000000000..fa8bfd884 --- /dev/null +++ b/doc/server/plugins/properties.txt @@ -0,0 +1,46 @@ +.. -*- mode: rst -*- + +.. _server-plugins-properties: + +========== +Properties +========== + +The Properties plugin is a connector plugin that adds information from +properties files into client metadata instances. + +Enabling Properties +=================== + +First, ``mkdir /var/lib/bcfg2/Properties``. Each property XML file goes +in this directory. Each will automatically be cached by the server, +and reread/reparsed upon changes. Add **Properties** to your ``plugins`` +line in ``/etc/bcfg2.conf``. + +Data Structures +=============== + +Properties adds a new dictionary to client metadata instances that maps +property file names to PropertyFile instances. PropertyFile instances +contain parsed XML data as the "data" attribute. + +Usage +===== + +Specific property files can be referred to in +templates as metadata.Properties[]. The +data attribute is an LXML element object. (Documented +`here `_) + +Currently, no access methods are defined for this data, but as we +formulate common use cases, we will add them to the !PropertyFile class +as methods. This will simplify templates. + +Accessing Properties contest from TGenshi +========================================= + +Access contents of ``Properties/auth.xml`` + +:: + + ${metadata.Properties['auth.xml'].data.find('file').find('bcfg2.key').text} diff --git a/doc/server/plugins/structures/bundler/index.txt b/doc/server/plugins/structures/bundler/index.txt index da49b299e..7b4cd7b6f 100644 --- a/doc/server/plugins/structures/bundler/index.txt +++ b/doc/server/plugins/structures/bundler/index.txt @@ -29,7 +29,7 @@ The following is an annotated copy of a bundle: .. code-block:: xml - + diff --git a/doc/unsorted/contribute.txt b/doc/unsorted/contribute.txt deleted file mode 100644 index fab9d09a1..000000000 --- a/doc/unsorted/contribute.txt +++ /dev/null @@ -1,81 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-contribute: - -===================== -Contributing to Bcfg2 -===================== - -There are several ways users can contribute to the Bcfg2 project. - -* Developing code -* Testing prereleases -* Adding to the common repository -* Improving the wiki - -Development -=========== - -Send patches to the [wiki:MailingList bcfg mailing list] or create -a trac [https://trac.mcs.anl.gov/projects/bcfg2/newticket ticket] -with the patch included. In order to submit a ticket via the -trac system, you will need to create a session by clicking on the -[https://trac.mcs.anl.gov/projects/bcfg2/prefs Preferences] link and -filling out/saving changes to the form. In order to be considered for -mainline inclusion, patches need to be BSD licensed. The most convenient -way to prepare patches is by using git diff inside of a source tree -checked out of subversion. The source tree can be checked out by running:: - - git clone git://git.mcs.anl.gov/bcfg2.git - -Users wishing to contribute on a regular basis can apply for direct -subversion access. Mail the mailing list for details. - -Several resources for developers exist in the wiki: - -* [wiki:DevelopmentTips] -* [wiki:Development/WritingPlugins Writing Bcfg2 Server Plugins] -* [wiki:Architecture] -* [wiki:WritingClientToolDrivers] -* [wiki:Bcfg2SubversionHowto] -* [wiki:LearningPython] -* [wiki:UsingRcache] - -Bcfg2 is the result of a lot of work by many different people. They are -listed on the [wiki:Contributors contributors page.] - -Feel free to drop in during a [wiki:CodeSprintIdeas code sprint] if you -would like to help out with some easier problems. - -Testing Prereleases -=================== - -Before each release, several prereleases will be tagged. It is helpful -to have users test these releases (when feasible) because it is hard to -replicate the full range of potential reconfiguration situations; between -different operating systems, system management tools, and configuration -specification variation, there can be large differences between sites. - -See the [wiki:TrackingDevelopmentTrunk] page for a better view of changes -in the prereleases. - -Adding to the Common Repository -=============================== - -The Bcfg2 common repository is a set of portable examples that new -repositories can be based on. This repo has several parts. The first -is a series of group definitions that describe a wide range of client -systems. The second is a set of portable bundles that have been ported -to use these groups. This makes these bundles transparently portable -across new client architectures. - -This approach has several benefits to users - -* Configuration specification can be shared across sites where appropriate -* This common configuration specification can be reused, allowing sites to migrate to new systems that other sites have already ported the common repository to -* Setup of new systems becomes a lot easier. - -Improving the wiki -================== - -Mail the [wiki:MailingList mailing list] for an account on the wiki. diff --git a/doc/unsorted/converging_rhel5.txt b/doc/unsorted/converging_rhel5.txt deleted file mode 100644 index 9d508e5e4..000000000 --- a/doc/unsorted/converging_rhel5.txt +++ /dev/null @@ -1,116 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-converging_rhel5: - -====================================== -Converging on Verification with RHEL 5 -====================================== - -Running verification -==================== - -To get complete verification status, run:: - - bcfg2 -vqned - -Unmanaged entries -================= - -* Package (top-level) - - #. Enable the "Packages" plugin in {{{/etc/bcfg2.conf}}}, and configure the Yum repositories in {{{/var/lib/bcfg2/Packages/config.xml}}}. - #. If a package is unwanted, remove it:: - - sudo yum remove PACKAGE - - #. Otherwise, add {{{}}} to the Base or Bundler configuration. - -* Package (dependency) - - #. Ensure the Yum repository sources configured in {{{/var/lib/bcfg2/Packages/config.xml}}} are correct. - #. Ensure the Yum repositories themselves are up-to-date with the main package and dependencies. - #. Rebuild the Packages plugin cache:: - - bcfg2-admin xcmd Packages.Refresh - -* Service - - #. Add {{{}}} to the Base or Bundler configuration. - #. Add {{{}}} to {{{/var/lib/bcfg2/Rules/services.xml}}}. - -Incorrect entries -================= - -For a "Package" ---------------- - -* Failed RPM verification - - #. Run {{{rpm -V PACKAGE}}} - #. Add configuration files (the ones with "c" next to them in the verification output) to {{{/var/lib/bcfg2/Cfg/}}}. - - * For example, {{{/etc/motd}}} to {{{/var/lib/bcfg2/Cfg/etc/motd/motd}}}. Yes, there is an extra directory level named after the file. - - #. Specify configuration files as {{{}}} in the Base or Bundler configuration. - #. Add directories to {{{/var/lib/bcfg2/Rules/directories.xml}}}. For example: - - .. code-block:: xml - - - - - - -* Multiple instances - - * Option A: Explicitly list the instances - - #. Drop the {{{}}} from the Base or Bundler configuration. - #. Add an explicit {{{}}} and {{{}}} configuration to a new Bundle, like the following: - - .. code-block:: xml - - - - - - - - - - #. Add the bundle to the applicable groups in {{{/var/lib/bcfg2/Metadata/groups.xml}}}. - - * Option B: Disable verification of the package - - #. Add {{{pkg_checks="false"}}} to the {{{}}} tag. - -For a "Path" -------------------- - - * Unclear verification problem (no details from BCFG2) - - 1. Run {{{bcfg2 -vqI}}} to see detailed verification issues (but deny any suggested actions). - - * Permissions mismatch - - 1. Create an {{{info.xml}}} file in the same directory as the configuration file. Example: - - .. code-block:: xml - - - - - - - - -Other troubleshooting tools -=========================== - - * Generate the physical configuration from the server side:: - - bcfg2-info buildfile /test test.example.com - - * Generate the physical configuration from the client side:: - - bcfg2 -vqn -c/root/bcfg2-physical.xml diff --git a/doc/unsorted/developing_for_bcfg2.txt b/doc/unsorted/developing_for_bcfg2.txt deleted file mode 100644 index 9d3e77bd7..000000000 --- a/doc/unsorted/developing_for_bcfg2.txt +++ /dev/null @@ -1,111 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-developing_for_bcfg2: - -==================== -Developing For Bcfg2 -==================== - -While the Bcfg2 server provides a good interface for representing -general system configurations, its plugin interface offers the -ability to implement configuration interfaces and representation -tailored to problems encountered by a particular site. This -chapter describes what plugins are good for, what they can do, and -how to implement them. - -Bcfg2 Plugins -============= - -Bcfg2 plugins are loadable python modules that the Bcfg2 server -loads at initialization time. These plugins can contribute to -the functions already offered by the Bcfg2 server or can extend -its functionality. In general, plugins will provide some portion -of the configuration for clients, with a data representation -that is tuned for a set of common tasks. Much of the core -functionality of Bcfg2 is implemented by several plugins, -however, they are not special in any way; new plugins could -easily supplant one or all of them. - -The following table describes the various functions of bcfg2 plugins. - -|| '' '''Name''' '' || '' '''Description''' '' || -|| Probes || Plugins can issue commands to collect client-side state (like hardware inventory) to include in client configurations || -|| !ConfigurationEntry List || Plugins can construct a list of per-client configuration entry lists to include in client configurations. || -|| !ConfigurationEntry contents || Literal values for configuration entries. || -|| XML-RPC functions || Plugins can export function calls that expose internal functions. || - -Writing Bcfg2 Plugins -===================== - -Bcfg2 plugins are python classes that subclass from -Bcfg2.Server.Plugin.Plugin. Several plugin-specific values must -be set in the new plugin. These values dictate how the new -plugin will behave with respect to the above four functions. -The following table describes all important member fields. - -|| '' '''Name''' '' || '' '''Description''' '' || '' '''Format''' '' || -|| __name__ || The name of the plugin || string || -|| __version__ || The plugin version (generally tied to revctl keyword expansion). || string || -|| __author__ || The plugin author. || string || -|| __rmi__ || Set of functions to be exposed as XML-RPC functions || List of function names (strings) || -|| Entries || Multidimentional dictionary of keys that point to the function [[BR]] used to bind literal contents for a given configuration entity. || Dictionary of !ConfigurationEntityType, Name keys and function reference values || -|| !BuildStructures || Function that returns a list of the structures for a given client || Member function || -|| !GetProbes || Function that returns a list of probes that a given client should execute || Member function || -|| !ReceiveData || Function that accepts the probe results for a given client. || Member function || - -Example Plugin -============== - -.. code-block:: python - - import Bcfg2.Server.Plugin - class MyPlugin(Bcfg2.Server.Plugin.Plugin): - '''An example plugin''' - # All plugins need to subclass Bcfg2.Server.Plugin.Plugin - __name__ = 'MyPlugin' - __version__ = '1' - __author__ = 'me@me.com' - __rmi__ = ['myfunction'] - # myfunction is not available remotely as MyPlugin.myfunction - - def __init__(self, core, datastore): - Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) - self.Entries = {'Path':{'/etc/foo.conf': self.buildFoo}} - - def myfunction(self): - '''function for xmlrpc rmi call''' - #do something - return True - - def buildFoo(self, entry, metadata): - '''Bind per-client information into entry based on metadata''' - entry.attrib.update({'type':'file', 'owner':'root', 'group':'root', 'perms':'644'}) - entry.text = '''contents of foo.conf''' - -Example Connector -================= - -.. code-block:: python - - import Bcfg2.Server.Plugin - - class Foo(Bcfg2.Server.Plugin.Plugin, - Bcfg2.Server.Plugin.Connector): - '''The Foo plugin is here to illustrate a barebones connector''' - name = 'Foo' - version = '$Revision: $' - experimental = True - - def __init__(self, core, datastore): - Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) - Bcfg2.Server.Plugin.Connector.__init__(self) - self.store = XMLFileBacked(self.data, core.fam) - - def get_additional_data(self, metadata): - mydata = {} - for data in self.store.entries['foo.xml'].data.get("foo", []): - mydata[data] = "bar" - return dict([('mydata', mydata)]) - - def get_additional_groups(self, meta): - return self.cgroups.get(meta.hostname, list()) diff --git a/doc/unsorted/development_tips.txt b/doc/unsorted/development_tips.txt deleted file mode 100644 index 29924e645..000000000 --- a/doc/unsorted/development_tips.txt +++ /dev/null @@ -1,20 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-development_tips: - -========================== -Tips for Bcfg2 Development -========================== - -#. Focus on either the client or server code. This focuses the development process down the the precise pieces of code that matter for the task at hand. - - * If you are developing a client driver, then write up a small configuration specification that includes the needed characteristics. - * If you are working on the server, run bcfg2-info and use to assess the code - -#. Use the python interpreter. One of python's most appealing features is interactive use of the interpreter. - - * If you are developing for the client-side, run "python -i /usr/sbin/bcfg2" with the appropriate bcfg2 options. This will cause the python interpreter to continue running, leaving all variables intact. This can be used to examine data state in a convenient fashion. - * If you are developing for the server side, use bcfg2-info and the "debug" option. This will leave you at a python interpreter prompt, with the server core loaded in the variable "bcore". - -#. Use pylint obsessively. It raises a lot of style-related warnings which can be ignored, but most all of the errors are legitimate. -#. If you are doing anything with Regular Expressions, [http://kodos.sourceforge.net/ Kodos - The Python Regular Expression Debugger] and [http://re-try.appspot.com/ re-try] are your friends. diff --git a/doc/unsorted/development_writing_plugins.txt b/doc/unsorted/development_writing_plugins.txt deleted file mode 100644 index cc0bd7c00..000000000 --- a/doc/unsorted/development_writing_plugins.txt +++ /dev/null @@ -1,77 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-development_writing_plugins: - -=============== -Writing Plugins -=============== - -Server Plugin Types -=================== - -Generator ---------- - -Generator plugins contribute to literal client configurations - -Structure ---------- - -Structure Plugins contribute to abstract client configurations - -Metadata --------- - -Signal metadata capabilities - -Connector ---------- - -Connector Plugins augment client metadata instances - -Probing -------- - -Signal probe capability - -Statistics ----------- - -Signal statistics handling capability - -Decision --------- - -Signal decision handling capability - -Version -------- - -Interact with various version control systems - -Writing Server Plugins -====================== - -Metadata --------- - -If you would like to define your own Metadata plugin (to extend/change functionality of the existing Metadata plugin), here are the steps to do so. We will call our new plugin `MyMetadata`. - -#. Add MyMetadata.py - - .. code-block:: python - - __revision__ = '$Revision$' - - import Bcfg2.Server.Plugins.Metadata - - class MyMetadata(Bcfg2.Server.Plugins.Metadata.Metadata): - '''This class contains data for Bcfg2 server metadata''' - __version__ = '$Id$' - __author__ = 'bcfg-dev@mcs.anl.gov' - - def __init__(self, core, datastore, watch_clients=True): - Bcfg2.Server.Plugins.Metadata.Metadata.__init__(self, core, datastore, watch_clients) - -#. Add MyMetadata to `src/lib/Server/Plugins/__init__.py` -#. Replace Metadata with MyMetadata in the plugins line of bcfg2.conf diff --git a/doc/unsorted/dynamic_groups.txt b/doc/unsorted/dynamic_groups.txt deleted file mode 100644 index 11535dc8b..000000000 --- a/doc/unsorted/dynamic_groups.txt +++ /dev/null @@ -1,27 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-dynamic_groups: - -============== -Dynamic Groups -============== - -Bcfg2 supports the use of dynamic groups. These groups are not included -in a client's profile group, but instead are derived from the results -of probes executed on the client. These dynamic groups need not already -exist in ``Metadata/groups.xml``. If a dynamic group is defined in -``Metadata/groups.xml``, clients that include this group will also get -all included groups and bundles. - -Setting up dynamic groups -========================= - -In order to define a dynamic group, setup a probe that outputs the text -based on system properties:: - - group:groupname - -This output is processed by the Bcfg2 server, and results in dynamic -group membership in groupname for the client. See the :ref:`Probes -` page for a more thorough description -of probes. diff --git a/doc/unsorted/emacs_snippet.txt b/doc/unsorted/emacs_snippet.txt deleted file mode 100644 index 471a3b244..000000000 --- a/doc/unsorted/emacs_snippet.txt +++ /dev/null @@ -1,53 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-emacs_snippet: - -======================================= -Using Bcfg2 with Emacs + YASnippet mode -======================================= - -This page describes using emacs with YASnippet mode with a set of snippets that allow quick composition of bundles and base files. More snippets are under development. - -#. Download YASnippet from http://code.google.com/p/yasnippet/ -#. Install it into your emacs load path (typically ~/.emacs.d/site-lisp) -#. Add YASnippet initialization to your .emacs (remember to re-byte-compile it if needed) - - .. code-block:: cl - - (require 'yasnippet-bundle) - - ;;; Bcfg2 snippet - - (yas/define-snippets 'sgml-mode - '( - (" - $0 - " nil) - (" - $0 - " nil) - (" - $0" nil) - (" - $0" nil) - (" - $0" nil) - (" - $0" nil) - (" - $0" nil) - (" - $0" nil) - (" - $0" nil) - ) - ) - -#. One quick M-x eval-current-buffer, and this code is enabled - -Each of these snippets activates on the opening element, ie , and the snippet will be expanded. The template will be inserted into the text with a set of input prompts, which default to overwrite mode and can be tabbed through. - -The code above only works for bundles and base, but will be expanded to support other xml files as well. diff --git a/doc/unsorted/gentoo.txt b/doc/unsorted/gentoo.txt deleted file mode 100644 index 4a549210d..000000000 --- a/doc/unsorted/gentoo.txt +++ /dev/null @@ -1,177 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-gentoo: - -====== -Gentoo -====== - -This document tries to lay out anything Gentoo-specific that you need -to know in order to use Bcfg2. Mostly that has to do with getting it -to cooperate with the various pieces of Portage. Services, all things -POSIX, and just about anything else that Bcfg2 does will work the same -on Gentoo as on any other distribution. Bcfg2 is new on Gentoo; please -let the list know if you find errors or omissions. - -Installing Bcfg2 -================ - -Early in July 2008, Bcfg2 was added to the Gentoo portage tree. So far -it's only keyworded for ~x86, but we hope to see it soon in the amd64 and -x64-solaris ports. If you're using Gentoo on some other architecture, it -should still work provided that you have a reasonably up to date Python; -try adding `app-admin/bcfg2 ~*` to your `/etc/portage/package.keywords` -file. - -If you don’t use portage to install Bcfg2, you’ll want to make sure you -have all the prerequisites installed first. For a server, you’ll need: - -* ``app-admin/gamin`` or ``app-admin/fam`` -* ``dev-python/lxml`` - -Clients will need at least: - -* ``app-portage/gentoolkit`` - -Package Repository -================== - -You’ll need (to make) at least one archive of binary packages. The -Portage driver calls ``emerge`` with the ``–getbinpkgonly`` option. See -:manpage:`make.conf(5)` and :manpage:`emerge(1)` manpages, specifically -the *PORTAGE_BINHOST* environment variable. - -Time Saver: quickpkg --------------------- - -If you have a standing Gentoo machine that you want to preserve or -propagate, you can generate a complete package archive based on the -present state of the system by using the quickpkg utility. For example: - -.. code-block:: sh - - for pkg in `equery -q l` ; do quickpkg "=$pkg" ; done - -…will leave you with a complete archive of all the packages on your -system in ``/usr/portage/packages/All``, which you can then move to your -ftp server. - -Cataloging Packages In Your Repository --------------------------------------- - -Once you have a set of packages, you will need to create a catalog for -them in ``/var/lib/bcfg2/Pkgmgr``. Here’s a template: - -.. code-block:: xml - - - - - - - -…and a partially filled-out example, for our local Gentoo/VMware build: - -.. code-block:: xml - - - - - [...] - - - - -The `` name (in our example, “gentoo-200701-vmware”) should -be included by any host which will draw its packages from this list. Our -collection of packages for this class of machines is at the listed URI, -and we only have one collection of packages for this batch of machines so -in our case the `priority` doesn’t really matter, we’ve set it to `0`. - -Notice that package name fields are in `CAT/TITLE` format. - -Here is a hack which will generate a list of Package lines from -a system’s database of installed packages, especially useful in -conjunction with the `quickpkg` example above: - -.. code-block:: sh - - #!/bin/bash - for pkg in `equery -q l` ; do - title=`echo $pkg | sed -e 's/\(.*\)-\([0-9].*\)/\1/'` - version=`echo $pkg | sed -e 's/\(.*\)-\([0-9].*\)/\2/'` - echo " " - done - -Configuring Client Machines -=========================== - -Set up ``/etc/bcfg2.conf`` the way you would for any other Bcfg2 client. - -In ``make.conf``, set *PORTAGE_BINHOST* to point to the URI of -your package repository. You may want to create versions of -``make.conf`` for each package repository you maintain, with -appropriate *PORTAGE_BINHOST* URI's in each, and associated with -that package archive's group under ``Cfg`` -- for example, we have -``Cfg/etc/make.conf/make.conf.G99_gentoo-200701-vmware``. If a client -host switches groups, and the new group needs a different set of packages, -everything should just fall into place. - -Pitfalls -======== - -Package Verification Issues ---------------------------- - -As of this writing (2007/01/31), we’re aware of a number of packages -marked stable in the Gentoo x86 tree which, for one reason or another, -consistently fail to verify cleanly under `equery check`. In some cases -(pam, openldap), files which don’t (ever) exist on the system are -nonetheless recorded in the package database; in some (python, Bcfg2, -ahem), whole classes of files (.pyc and .pyo files) consistently fail -their md5sum checks; and in others, the problem appears to be a -discrepancy in the way that symlinks are created vs. the way they’re -recorded in the database. For example, in the OpenSSH package, -/usr/bin/slogin is a symlink to ./ssh, but equery expects it to point to -an unadorned ssh. An analogous situation exists with their manpages, -leading to noise like this:: - - # equery check openssh - [ Checking net-misc/openssh-4.5_p1 ] - !!! /etc/ssh/sshd_config has incorrect md5sum - !!! /usr/bin/slogin does not point to ssh - !!! /usr/share/man/man1/slogin.1.gz does not point to ssh.1.gz - !!! /etc/ssh/ssh_config has incorrect md5sum - * 62 out of 66 files good - -We can ignore the lines for ``ssh_config`` and ``sshd_config``; those will -be caught by Bcfg2 as registered config files and handled appropriately. - -Because Bcfg2 relies on the client system’s native package reporting -tool to judge the state of installed packages, complaints like these -about trivial or intractable verification failures can trigger unnecessary -bundle reinstalls when the Bcfg2 client runs. Bcfg2 will catch on after a -pass or two that the situation isn’t getting any better with repeated -package installs, stop trying, and list those packages as “bad” in -the client system’s statistics. - -Aside from filing bugs with the Gentoo package maintainers, your narrator -has been unable to come up with a good approach to this. Maybe write a -series of ``Rules`` definitions according to what the package database -thinks it should find, and/or stage copies of affected files under -``Cfg``, and associate those rules and files with the affected package in -a bundle? Annoying but possibly necessary if you want your stats file -to look good. - -/boot ------ - -Gentoo as well as some other distros recommend leaving ``/boot`` unmounted -during normal runtime. This can lead to trouble during verification and -package installation, for example when ``/boot/grub/grub.conf`` turns -up missing. The simplest way around this might just be to ensure that -``/boot`` is mounted whenever you run Bcfg2, possibly wrapping Bcfg2 -in a script for the purpose. I’ve also thought about adding *Action* -clauses to bundles for grub and our kernel packages, which would mount -``/boot`` before the bundle installs and unmount it afterward, but this -doesn’t get around the problem of those packages flunking verification. diff --git a/doc/unsorted/install.txt b/doc/unsorted/install.txt deleted file mode 100644 index 6589261ab..000000000 --- a/doc/unsorted/install.txt +++ /dev/null @@ -1,47 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-install: - -============ -Installation -============ - -Prerequisites -============= - -First, install the prerequisite libraries. See the [wiki:Prereqs] page for more information. - -Bcfg2 -===== - -Before installing, you will need to choose a machine to be the Bcfg2 server. We recommend a Linux-based machine for this purpose, but the server will work on any supported operating system. Note that you may eventually want to run a web server on this machine for reporting and serving up package repositories. - -* '''From packages:''' The easiest way to install Bcfg2 is from packages for your operating system. You can grab packages (and source packages) for various OSes from the [wiki:Download] page. Install them as you would any other packages. The server package only needs to be installed on your designated Bcfg2 server machine; the clients package needs to be installed on any machine you plan to manage by Bcfg2. -* '''From source:''' The Bcfg2 source tarball can also be grabbed from the [wiki:Download] page. After untarring the file, you can build Bcfg2 with {{{python setup.py install --prefix=/install/prefix}}} This will install both the client and server on that machine. - -Configuration -============= - -Once Bcfg2 is installed, head over to the [wiki:QuickStart] to get it configured and up-and-running. - - -OS X -==== - -Using native OS X python ------------------------- - -First, make sure you have Xcode installed as you need `packagemaker` which comes bundled in the Developer tools. - -Clone the git source:: - - git clone git://git.mcs.anl.gov/bcfg2.git - -Change to the osx directory and type make. Your new package should be located at bcfg2-'''$VERSION'''.pkg (where '''$VERSION''' is that which is specified in setup.py). - -Using macports --------------- - -Once macports is installed:: - - port install bcfg2 diff --git a/doc/unsorted/learningpython.txt b/doc/unsorted/learningpython.txt deleted file mode 100644 index 3810d3899..000000000 --- a/doc/unsorted/learningpython.txt +++ /dev/null @@ -1,23 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-learningpython: - -=============== -Learning Python -=============== - -Learning -======== - -* MIT OpenCourseWare [http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-189January--IAP--2008/CourseHome/index.htm A Gentle Introduction to Programming Using Python] which primarily uses [http://www.greenteapress.com/thinkpython/thinkpython.html Think Python: How to Think Like a Computer Scientist]. -* [http://www.diveintopython.org/ Dive into Python], available in (free) online and dead trees formats. Good introduction, but a bit dated at this point (2004). -* djbclark recommends [http://hetland.org/writing/beginning-python/ Beginning Python: From Novice to Professional] -* djbclark recommends [http://www.oreilly.com/catalog/pythoncook2/ Python Cookbook, 2nd Edition] - -References -========== - -* desai recommends "Python: Essential Reference, 3rd Edition", which is available [http://safari.samspublishing.com/0672328623 online], in [http://www.samspublishing.com/bookstore/product.asp?isbn=0768664985&rl=1 pdf], and as a [http://www.samspublishing.com/bookstore/product.asp?isbn=0672328623&rl=1 book]. -* djbclark recommends [http://www.oreilly.com/catalog/pythonpr3/ Python Pocket Reference, 3rd Edition] -* [http://www.oreilly.com/catalog/pythonian2/ Python in a Nutshell, 2nd Edition] -* lueningh recommends the official [http://docs.python.org/lib/lib.html library reference] for, say, when you just need to know what all of a string object's methods are. diff --git a/doc/unsorted/mrepo.txt b/doc/unsorted/mrepo.txt deleted file mode 100644 index 61c3fd8c8..000000000 --- a/doc/unsorted/mrepo.txt +++ /dev/null @@ -1,71 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-mrepo: - -===== -mrepo -===== - -This page describes how to setup an `mrepo`_ mirror. - -.. _mrepo: http://dag.wieers.com/home-made/mrepo/ - -mrepo builds a local APT/Yum RPM repository from local ISO files, -downloaded updates, and extra packages from 3rd party repositories. It -takes care of setting up the ISO files, downloading the RPMs, -configuring HTTP access and providing PXE/TFTP resources for remote -network installations. - -Sample mrepo configuration -========================== - -:: - - ### Configuration file for mrepo - - ### The [main] section allows to override mrepo's default settings - ### The mrepo-example.conf gives an overview of all the possible settings - [main] - srcdir = /var/mrepo/src - wwwdir = /var/www/mrepo - confdir = /etc/mrepo.conf.d - arch = x86_64 - - mailto = - smtp-server = localhost - - hardlink = yes - shareiso = yes - - rsync-timeout = 3600 - - [centos5] - name = CentOS Server $release ($arch) - release = 5 - arch = x86_64 - metadata = yum repomd - - # ISO images - iso = centos-$release-server-$arch-DVD.iso - - #addons = rsync://mirrors.kernel.org/centos/$release/addons/$arch/RPMS - centosplus = rsync://mirrors.kernel.org/centos/$release/centosplus/$arch/RPMS - extras = rsync://mirrors.kernel.org/centos/$release/extras/$arch/RPMS - #fasttrack = rsync://mirrors.kernel.org/centos/$release/fasttrack/$arch/RPMS - os = rsync://mirrors.kernel.org/centos/$release/os/$arch/CentOS - updates = rsync://mirrors.kernel.org/centos/$release/updates/$arch/RPMS - dag = http://apt.sw.be/redhat/el$release/en/$arch/RPMS.dag - dries = http://apt.sw.be/redhat/el$release/en/$arch/RPMS.dries - rpmforge = http://apt.sw.be/redhat/el$release/en/$arch/RPMS.rpmforge - - ### Any other section is considered a definition for a distribution - ### You can put distribution sections in /etc/mrepo.conf.d/ - ### Examples can be found in the documentation at: - ### /usr/share/doc/mrepo-0.8.6/dists/. - -Run mrepo to update the repositories -==================================== - -:: - - mrepo -ug diff --git a/doc/unsorted/nat_howto.txt b/doc/unsorted/nat_howto.txt deleted file mode 100644 index 131c0c533..000000000 --- a/doc/unsorted/nat_howto.txt +++ /dev/null @@ -1,56 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-nat_howto: - -========= -NAT HOWTO -========= - -This page describes how to setup bcfg2 to properly function with a collection of clients behind NAT. It describes the issues, how the underlying portions of the bcfg2 system function, and how to correctly setup client metadata to cope with this environment. - -Issues -====== - -Bcfg2, by default, uses ip address lookup to determine the identity of a client that has connected. This process doesn't work properly in the case of NATted hosts, because all requests from these clients come from the same external address when connecting to the server. - -These client identification issues will manifest themselves in a number of ways: - -* Inability to setup discrete clients with different profiles -* Incorrect sharing of probe results across clients in the same NAT pool -* Inability to bootstrap clients properly when client data is not predefined - -Architectural Issues -==================== - -Client identification is performed as the beginning of each client/server interaction. As of 0.9.3pre3, client identification via IP address can be completely short-circuited through the use of a client uuid. Setup of client uuids requires actions of both the client and server. On the server side, the client uuid must be added to the client record in Metadata/clients.xml. This attribute allows the server to use the user part of the authentication to resolve the client's metadata. Also, either the location attribute should be set to floating, or the IP address of the NAT must be reflected in the address attribute. -Once added, the Client entry in clients.xml will look like: - -.. code-block:: xml - - - -Alternatively, the Client entry can be setup like: - -.. code-block:: xml - - - -The difference between these definitions is explained in detail on the [wiki:Authentication] page, but in short, the second form requires that the client access the server from the NAT address, while the first form allows it to connect from any address provided it uses the proper uuid. (Client identification is orthogonal to the use of per-client passwords; this can be set in addition to the attributes above.) - -Once this setup is done, each client must be configured to use the proper uuid upon any server interaction. This can be done using either the command line argument -u, or the setting "user" in the "communication" section of /etc/bcfg2.conf. - -UUID Choice -=========== - -When determining client UUIDs, one must take care to ensure that UUIDs are unique to the client. Any hardware-specific attribute, like a hash of a mac address would be sufficient. Alternatively, if a local hostname is unique, it may be used as well. - -Automated Client Bootstrapping -============================== - -Automated setup of new clients from behind NAT works by using the common password. For example:: - - /usr/sbin/bcfg2 -u ubik3 -p desktop -x - -It is not possible at this time to do automated setup without setting up a pre-shared per-client key. diff --git a/doc/unsorted/writing_specification.txt b/doc/unsorted/writing_specification.txt index 5a75165bf..eced54841 100644 --- a/doc/unsorted/writing_specification.txt +++ b/doc/unsorted/writing_specification.txt @@ -166,7 +166,8 @@ The following is an annotated copy of a bundle: .. code-block:: xml - + -- cgit v1.2.3-1-g7c22 From 51eed1498b02861b2f93854d021387debf194d82 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 9 Nov 2010 00:23:28 +0100 Subject: troubleshooting moved --- doc/architecture.txt | 354 ----------------------------------- doc/authentication.txt | 143 -------------- doc/bcfg2.conf-options.txt | 19 -- doc/getting_help/index.txt | 1 + doc/getting_help/troubleshooting.txt | 184 ++++++++++++++++++ doc/troubleshooting.txt | 184 ------------------ 6 files changed, 185 insertions(+), 700 deletions(-) delete mode 100644 doc/architecture.txt delete mode 100644 doc/authentication.txt delete mode 100644 doc/bcfg2.conf-options.txt create mode 100644 doc/getting_help/troubleshooting.txt delete mode 100644 doc/troubleshooting.txt diff --git a/doc/architecture.txt b/doc/architecture.txt deleted file mode 100644 index ef2fe3830..000000000 --- a/doc/architecture.txt +++ /dev/null @@ -1,354 +0,0 @@ -.. -*- mode: rst -*- - -.. _architecture: - -=========================== -Detailed Bcfg2 Architecture -=========================== - -Bcfg2 is based on a client-server architecture. The client is responsible -for interpreting (but not processing) the configuration served by the -server. This configuration is literal, so no local process is required. -After completion of the configuration process, the client uploads a set -of statistics to the server. This section will describe the goals and -then the architecture motivated by it. - -Goals -===== - -* **Model configurations using declarative semantics.** - - Declarative semantics maximize the utility of configuration management - tools; they provide the most flexibility for the tool to determine - the right course of action in any given situation. This means that - users can focus on the task of describing the desired configuration, - while leaving the task of transitioning clients states to the tool. - -* **Configuration descriptions should be comprehensive.** - - This means that configurations served to the client should be sufficient - to reproduce all desired functionality. This assumption allows the - use of heuristics to detect extra configuration, aiding in reliable, - comprehensive configuration definitions. - -* **Provide a flexible approach to user interactions.** - - Most configuration management systems take a rigid approach to user - interactions; that is, either the client system is always correct, - or the central system is. This means that users are forced into an - overly proscribed model where the system asserts where correct data - is. Configuration data modification is frequently undertaken on both - the configuration server and clients. Hence, the existence of a single - canonical data location can easily pose a problem during normal tool - use. Bcfg2 takes a different approach. - -The default assumption is that data on the server is correct, however, -the client has the option to run in another mode where local changes are -catalogued for server-side integration. If the Bcfg2 client is run in dry -run mode, it can help to reconcile differences between current client -state and the configuration described on the server. The Bcfg2 client -also searches for extra configuration; that is, configuration that is -not specified by the configuration description. When extra configuration -is found, either configuration has been removed from the configuration -description on the server, or manual configuration has occurred on the -client. Options related to two-way verification and removal are useful -for configuration reconciliation when interactive access is used. - -* Plugins and administrative applications. -* Incremental operations. - -The Bcfg2 Client -================ - -The Bcfg2 client performs all client configuration or reconfiguration -operations. It renders a declarative configuration specification, provided -by the Bcfg2 server, into a set of configuration operations which will, -if executed, attempt to change the client's state into that described by -the configuration specification. Conceptually, the Bcfg2 client serves to -isolate the Bcfg2 server and specification from the imperative operations -required to implement configuration changes. - -This isolation allows declarative specifications to be manipulated -symbolically on the server, without needing to understand the properties -of the underlying system tools. In this way, the Bcfg2 client acts -as a sort of expert system that *knows* how to implement declarative -configuration changes. - -The operation of the Bcfg2 client is intended to be as simple as -possible. The normal configuration process consists of four main steps: - -* **Probe Execution** - - During the probe execution stage, the client connects to the server - and downloads a series of probes to execute. These probes reveal - local facts to the Bcfg2 server. For example, a probe could discover - the type of video card in a system. The Bcfg2 client returns this - data to the server, where it can influence the client configuration - generation process. - -* **Configuration Download and Inventory** - - The Bcfg2 client now downloads a configuration specification from the - Bcfg2 server. The configuration describes the complete target state - of the machine. That is, all aspects of client configuration should - be represented in this specification. For example, all software - packages and services should be represented in the configuration - specification. The client now performs a local system inventory. - This process consists of verifying each entry present in the - configuration specification. After this check is completed, heuristic - checks are executed for configuration not included in the configuration - specification. We refer to this inventory process as 2-way validation, - as first we verify that the client contains all configuration that - is included in the specification, then we check if the client has - any extra configuration that isn't present. This provides a fairly - rigorous notion of client configuration congruence. Once the 2-way - verification process has been performed, the client has built a list of - all configuration entries that are out of spec. This list has two parts: - specified configuration that is incorrect (or missing) and unspecified - configuration that should be removed. - -* **Configuration Update** - - The client now attempts to update its configuration to match the - specification. Depending on options, changes may not (or only partially) - be performed. First, if extra configuration correction is enabled, - extra configuration can be removed. Then the remaining changes - are processed. The Bcfg2 client loops while progress is made in the - correction of these incorrect configuration entries. This loop results - in the client being able to accomplish all it will be able to during - one execution. Once all entries are fixed, or no progress is being - made, the loop terminates. Once all configuration changes that can be - performed have been, bundle dependencies are handled. Bundle groupings - result in two different behaviors. Contained entries are assumed - to be inter-dependent. To address this, the client re-verifies each - entry in any bundle containing an updates configuration entry. Also, - services contained in modified bundles are restarted. - -* **Statistics Upload** - - Once the reconfiguration process has concluded, the client reports - information back to the server about the actions it performed during the - reconfiguration process. Statistics function as a detailed return code - from the client. The server stores statistics information. Information - included in this statistics update includes (but is not limited to): - - * Overall client status (clean/dirty) - * List of modified configuration entries - * List of uncorrectable configuration entries - * List of unmanaged configuration entries - -Architecture Abstraction ------------------------- - -The Bcfg2 client internally supports the administrative tools available -on different architectures. For example, ``rpm`` and ``apt-get`` are -both supported, allowing operation of Debian, Redhat, SUSE, and Mandriva -systems. The client toolset is determined based on the availability of -client tools. The client includes a series of libraries which describe -how to interact with the system tools on a particular platform. - -Three of the libraries exist. There is a base set of functions, which -contain definitions describing how to perform POSIX operations. Support -for configuration files, directories, symlinks, hardlinks, etc., are -included here. Two other libraries subclass this one, providing support -for Debian and rpm-based systems. - -The Debian toolset includes support for apt-get and update-rc.d. These -tools provide the ability to install and remove packages, and to install -and remove services. - -The Redhat toolset includes support for rpm and chkconfig. Any other -platform that uses these tools can also use this toolset. Hence, all -of the other familiar rpm-based distributions can use this toolset -without issue. - -Other platforms can easily use the POSIX toolset, ignoring support for -packages or services. Alternatively, adding support for new toolsets -isn't difficult. Each toolset consists of about 125 lines of python code. - -The Bcfg2 Server -================ - -The Bcfg2 server is responsible for taking a network description and -turning it into a series of configuration specifications for particular -clients. It also manages probed data and tracks statistics for clients. - -The Bcfg2 server takes information from two sources when generating -client configuration specifications. The first is a pool of metadata that -describes clients as members of an aspect-based classing system. That is, -clients are defined in terms of aspects of their behavior. The other is -a file system repository that contains mappings from metadata to literal -configuration. These are combined to form the literal configuration -specifications for clients. - -The Configuration Specification Construction Process ----------------------------------------------------- - -As we described in the previous section, the client connects to the server -to request a configuration specification. The server uses the client's -metadata and the file system repository to build a specification that -is tailored for the client. This process consists of the following steps: - -* **Metadata Lookup** - - The server uses the client's IP address to initiate the metadata - lookup. This initial metadata consists of a (profile, image) tuple. If - the client already has metadata registered, then it is used. If not, - then default values are used and stored for future use. This metadata - tuple is expanded using some profile and class definitions also included - in the metadata. The end result of this process is metadata consisting - of hostname, profile, image, a list of classes, a list of attributes - and a list of bundles. - -* **Abstract Configuration Construction** - - Once the server has the client metadata, it is used to create - an abstract configuration. An abstract configuration contains - all of the configuration elements that will exist in the final - specification **without** any specifics. All entries will be typed - (i.e. the tagname will be one of Package, Path, Action, etc) and will - include a name. These configuration entries are grouped into bundles, - which document installation time interdependencies. - -* **Configuration Binding** - - The abstract configuration determines the structure of the client - configuration, however, it doesn't yet contain literal configuration - information. After the abstract configuration is created, each - configuration entry must be bound to a client-specific value. The Bcfg2 - server uses plugins to provide these client-specific bindings. The Bcfg2 - server core contains a dispatch table that describes which plugins can - handle requests of a particular type. The responsible plugin is located - for each entry. It is called, passing in the configuration entry and - the client's metadata. The behavior of plugins is explicitly undefined, - so as to allow maximum flexibility. The behaviours of the stock plugins - are documented elsewhere in this manual. Once this binding process - is completed, the server has a literal, client-specific configuration - specification. This specification is complete and comprehensive; the - client doesn't need to process it at all in order to use it. It also - represents the totality of the configuration specified for the client. - -The Literal Configuration Specification -======================================= - -Literal configuration specifications are served to clients by the -Bcfg2 server. This is a differentiating factor for Bcfg2; all other -major configuration management systems use a non-literal configuration -specification. That is, the clients receive a symbolic configuration that -they process to implement target states. We took the literal approach -for a few reasons: - -* A small list of configuration element types can be defined, each of - which can have a set of defined semantics. This allows the server to - have a well-formed model of client-side operations. Without a static - lexicon with defined semantics, this isn't possible. This allows the - server, for example, to record the update of a package as a coherent - event. -* Literal configurations do not require client-side processing. Removing - client-side processing reduces the critical footprint of the tool. - That is, the Bcfg2 client (and the tools it calls) need to be - functional, but the rest of the system can be in any state. Yet, - the client will receive a correct configuration. -* Having static, defined element semantics also requires that all - operations be defined and implemented in advance. The implementation - can maximize reliability and robustness. In more ad-hoc setups, these - operations aren't necessarily safely implemented. - -The Structure of Specifications -------------------------------- - -Configuration specifications contain some number of clauses. Two types -of clauses exist. Bundles are groups of inter-dependent configuration -entities. The purpose of bundles is to encode installation-time -dependencies such that all new configuration is properly activated -during reconfiguration operations. That is, if a daemon configuration -file is changed, its daemon should be restarted. Another example of -bundle usage is the reconfiguration of a software package. If a package -contains a default configuration file, but it gets overwritten by an -environment-specific one, then that updated configuration file should -survive package upgrade. The purpose of bundles is to describe services, -or reconfigured software packages. Independent clauses contain groups -of configuration entities that aren't related in any way. This provides a -convenient mechanism that can be used for bulk installations of software. - -Each of these clauses contains some number of configuration entities. A -number of configuration entities exist including Path, Package, Service, -etc. Each of these correspond to the obvious system item. Configuration -specifications can get quite large; many systems have specifications -that top one megabyte in size. An example of one is included in an -appendix. These configurations can be written by hand, or generated by -the server. - -Design Considerations -===================== - -This section will discuss several aspects of the design of Bcfg2, and the -particular use cases that motivated them. Initially, this will consist -of a discussion of the system metadata, and the intended usage model -for package indices as well. - -System Metadata ---------------- - -Bcfg2 system metadata describes the underlying patterns in system -configurations. It describes commonalities and differences between these -specifications in a rigorous way. The groups used by Bcfg2's metadata are -responsible for differentiating clients from one another, and building -collections of allocatable configuration. - -The Bcfg2 metadata system has been designed with several high-level -goals in mind. Flexibility and precision are paramount concerns; no -configuration should be undescribable using the constructs present in -the Bcfg2 repository. We have found (generally the hard way) that any -assumptions about the inherent simplicity of configuration patterns tend -to be wrong, so obscenely complex configurations must be representable, -even if these requirements seem illogical during the implementation. - -In particular, we wanted to streamline several operations that commonly -occurred in our environment. - -* Copying one node's profile to another node. - - In many environments, many nodes are instances of a common configuration - specification. They all have similar roles and software. In our - environment, desktop machines were the best example of this. Other than - strictly per-host configuration like SSH keys, all desktop machines - use a common configuration specification. This trivializes the process - of creating a new desktop machine. - -* Creating a specialized version of an existing profile. - - In environments with highly varied configurations, departmental - infrastructure being a good example, "another machine like X but with - extra software" is a common requirement. For this reason, it must be - trivially possible to inherit most of a configuration specification - from some more generic source, while being able to describe overriding - aspects in a convenient fashion. - -* Compose several pre-existing configuration aspects to create a new profile. - - The ability to compose configuration aspects allows the easy creation - of new profiles based on a series of predefined set of configuration - specification fragments. The end result is more agility in environments - where change is the norm. - - In order for a classing system to be comprehensive, it must be usable in - complex ways. The Bcfg2 metadata system has constructs that map cleanly - to first-order logic. This implies that any complex configuration - pattern can be represented (at all) by the metadata, as first-order - logic is provably comprehensive. (There is a discussion later in the - document describing the metadata system in detail, and showing how it - corresponds to first-order logic) - -These use cases motivate several of the design decisions that we -made. There must be a many to one correspondence between clients and -groups. Membership in a given profile group must imbue a client with -all of its configuration properties. - -Package Management ------------------- - -The interface provided in the Bcfg2 repository for package specification -was designed with automation in mind. The goal was to support an -append only interface to the repository, so that users do not need to -continuously re-write already existing bits of specification. diff --git a/doc/authentication.txt b/doc/authentication.txt deleted file mode 100644 index ff3b1d901..000000000 --- a/doc/authentication.txt +++ /dev/null @@ -1,143 +0,0 @@ -.. -*- mode: rst -*- - -.. _authentication: - -============== -Authentication -============== - -Scenarios -========= - -1. Cluster nodes that are frequently rebuilt - - Default settings work well; machines do not float, and a per-client - password is not required. - -2. :ref:`NAT Howto nat_howto` - - * Build client records in advance with ``bcfg2-admin``, setting a uuid - for each new client. - - * Set the address attribute for each to the address of the NAT. - - * Optionally, set a per-client password for each, and set into secure - mode. - - .. note:: - - This will require the use of the uuid and password from each - client, and will require that they come through the NAT address. - -Building bcfg2.conf automatically -================================= - -This is a TCheetah template that automatically constructs per-client -`bcfg2.conf` from the per-client metadata:: - - [communication] - protocol = xmlrpc/ssl - #if $self.metadata.uuid != None - user = $self.metadata.uuid - #end if - #if $self.metadata.password != None - password = $self.metadata.password - #else - password = my-password-foobar - #end if - - [components] - bcfg2 = https://localhost:6789 - -In this setup, this will cause any clients that have uuids established -to be set to use them in `bcfg2.conf`. It will also cause any clients -with passwords set to use them instead of the global password. - -How Authentication Works -======================== - -#. First, the client is associated with a client record. If the client - specifies a uuid, it uses this instead of the results of a dns or - address lookup. - -#. Next, the ip address is verified against the client record. If the - address doesn't match, then the client must be set to - location=floating - -#. Finally, the password is verified. If the client is set to secure - mode, the only its per-client password is accepted. If it is not set - to secure mode, then either the global password or per-client password - will be accepted - -Failure during any of these stages results in authentication -failure. Note that clients set into secure mode that do not have -per-client passwords set will not be able to connect. - -SSL Cert-based client authentication -==================================== - -SSL-based client authentication is supported. This requires several -things: - -#. Certificate Authority (to sign all keys) - -#. Server key and cert signed by the CA - -#. Client key and cert signed by the CA - -A variety of CAs can be used, but these keys can be simply generated -using the following set of steps: - -#. Setup a CA - - http://www.flatmtn.com/article/setting-openssl-create-certificates - -#. Create keys for each client and server, signing them with the CA - signing cert - - http://www.flatmtn.com/article/setting-ssl-certificates-apache - - .. note:: - The client CN must be the FQDN of the client (as returned by a - reverse DNS lookup of the ip address. Otherwise, you will end up - with an error message on the client that looks like:: - - Server failure: Protocol Error: 401 Unauthorized - Failed to download probes from bcfg2 - Server Failure - - You will also see an error message on the server that looks - something like:: - - cmssrv01 bcfg2-server[9785]: Got request for cmssrv115 from incorrect address 131.225.206.122 - cmssrv01 bcfg2-server[9785]: Resolved to cmssrv115.fnal.gov - -#. Distribute the keys and certs to the appropriate locations - -#. Copy the ca cert to clients, so that the server can be authenticated - -Clients authenticating themselves with a certificate will be -authenticated that way first; clients can be setup to either -authenticate solely with certs, use certs with a fallback to password, -or password only. Also a bootstrap mode will be added shortly; this -will allow a client to authenticate with a password its first time, -requiring a certificate all subsequent times. This behavior can be -controlled through the use of the auth attribute in -`Metadata/clients.xml`:: - - - - - -Allowed values are: - - +---------------+------------------------------------------+ - | **Auth Type** | **Meaning** | - +---------------+------------------------------------------+ - | cert | Certificates must be used | - +---------------+------------------------------------------+ - | cert+password | Certificate or password may be used | - +---------------+------------------------------------------+ - | bootstrap | Password can be used for one client run, | - | | after that certificate is required | - +---------------+------------------------------------------+ diff --git a/doc/bcfg2.conf-options.txt b/doc/bcfg2.conf-options.txt deleted file mode 100644 index 85bc0190f..000000000 --- a/doc/bcfg2.conf-options.txt +++ /dev/null @@ -1,19 +0,0 @@ -.. -*- mode: rst -*- - -.. _bcfg2.conf-options: - -========== -bcfg2.conf -========== - -This page documents the various options available in bcfg2.conf. The -various sections correspond to the sections in the file itself. - -components -========== - -logging -------- - -Specify an alternate path for the lockfile used by the bcfg2 client. -Default value is ``/var/lock/bcfg2.run`` diff --git a/doc/getting_help/index.txt b/doc/getting_help/index.txt index 308f31df1..1060a8f4b 100644 --- a/doc/getting_help/index.txt +++ b/doc/getting_help/index.txt @@ -38,3 +38,4 @@ active. faq/index error-messages manpages + troubleshooting diff --git a/doc/getting_help/troubleshooting.txt b/doc/getting_help/troubleshooting.txt new file mode 100644 index 000000000..cce9c3d78 --- /dev/null +++ b/doc/getting_help/troubleshooting.txt @@ -0,0 +1,184 @@ +.. -*- mode: rst -*- + +.. _troubleshooting: + +=============== +Troubleshooting +=============== + +From time to time, Bcfg2 produces results that the user finds surprising. +This can happen either due to bugs or user error. This page describes +several techniques to gain visibility into the bcfg2 client and server +and understand what is going on. + + +Figure out if error is client or server side +============================================ + +* Cache a copy of the client configuration using ``bcfg2 -qnc /tmp/config.xml`` +* Look in the file and search for the entry of interest +* If it looks correct, then there is a client issue +* If not, it is time to inspect things on the server + +This file contains all aspects of client configuration. It is structured +as a series of bundles and base entries. + +.. note:: + + Most often the entry is not correct and the issue lies in + the specification. + +Review server log messages +========================== + +The bcfg2-server process logs to syslog facility LOG_DAEMON. The server +produces a series of messages upon a variety of events and errors. + +Check if all repository XML files conform to schemas +==================================================== + +Bcfg2 comes with XML schemas describing all of the XML formats used in +the server repository. A validation command ``bcfg2-repo-validate`` is +included with the source distribution and all packages. Run it with the +-v flag to see each file and the results if its validation. + +If the bcfg2 server is not reflecting recent changes, try restarting the bcfg2-server process +============================================================================================= + +If this fixes the problem, it is either a bug in the +underlying file monitoring system (fam or gamin) or a bug in +Bcfg2's file monitoring code. In either case, file a `ticket +`_ in the tracking +system. In the ticket, include: + +* filesystem monitoring system (fam or gamin) +* kernel version (if on linux) +* if any messages of the form "Handled N events in M + seconds" appeared between the modification event and the client + configuration generation request appeared in the server log +* which plugin handled the file in the repostiory (Cfg, Rules, Packages, + TCheetah, TGenshi, Metadata) +* if a touch of the file after the modification causes the problem to + go away + +bcfg2-info +========== + +Bcfg2 server operations can be simulated using the ``bcfg2-info`` command. +The command is interactive, and has commands to allow several useful +operations + +* clients - Current client metadata (profile and group) settings +* groups - Current group metadata values +* mappings - Configuration entries provided by plugins +* buildfile - Build a config file for a client +* showentries - Build the abstract configuration (list + of entries) for a client +* build - Build the complete configuration + for a client + +Type `help` in bcfg2-info for more information. + +Error Messages +============== + +This page describes error messages produced by Bcfg2 and steps that can +be taken to remedy them. + ++------------------------------+----------+---------------------+--------------+ +| Error | Location | Meaning | Repair | ++==============================+==========+=====================+==============+ +| Incomplete information for | Client | The described entry | [1]_ | +| entry : | | is not fully | | +| cannot verify | | specified by the | | +| | | server, so no | | +| | | verification can be | | +| | | performed. | | ++------------------------------+----------+---------------------+--------------+ +| Incomplete information for | Client | The described entry | [1]_ | +| entry : | | is not fully | | +| cannot install | | specified by the | | +| | | server, so no | | +| | | verification can be | | +| | | performed. | | ++------------------------------+----------+---------------------+--------------+ +| The following entries are | Client | The client cannot | [2]_ | +| not handled by any tool: | | figure out how to | | +| : | | handle this entry. | | ++------------------------------+----------+---------------------+--------------+ +| No ca is specified. Cannot | Client | The client is | [3]_ | +| authenticate the server with | | unable to verify | | +| SSL. | | the server | | ++------------------------------+----------+---------------------+--------------+ +| Failed to bind entry: | Server | The server was | [4]_ | +| | | unable to find a | | +| | | suitable version of | | +| | | entry for client. | | ++------------------------------+----------+---------------------+--------------+ +| Failed to bind to socket | Server | The server was | [5]_ | +| | | unable to bind to | | +| | | the tcp server | | +| | | socket. | | ++------------------------------+----------+---------------------+--------------+ +| Failed to load | Server | The server was | [6]_ | +| ssl key | | unable to read and | | +| | | process the ssl key.| | ++------------------------------+----------+---------------------+--------------+ +| Failed to read file | Server | The server failed | [7]_ | +| | | to read the | | +| | | specified file | | ++------------------------------+----------+---------------------+--------------+ +| Failed to parse file | Server | The server failed | [8]_ | +| | | to parse the | | +| | | specified XML file | | ++------------------------------+----------+---------------------+--------------+ +| Client metadata resolution | Server | The server cannot | [9]_ | +| error for | | resolve the client | | +| | | hostname or the | | +| | | client is | | +| | | associated with a | | +| | | non-profile group. | | ++------------------------------+----------+---------------------+--------------+ + + +.. [1] This entry is not being bound. Ensure that a version of this + entry applies to this client. +.. [2] Add a type to the generator definition for this entry +.. [3] Copy the Bcfg2 server's CA certificate to the client and specify it + using the **ca** option in the [communication] section of + ``bcfg2.conf`` +.. [4] This entry is not being bound. Ensure that a version of this + entry applies to this client. +.. [5] Ensure that another instance of the daemon (or any other process) + is not listening on the same port. +.. [6] Ensure that the key is readable by the user running the daemon + and that it is well-formed. +.. [7] Ensure that this file still exists; a frequent cause is the + deletion of a temp file. +.. [8] Ensure that the file is properly formed XML. +.. [9] Fix hostname resolution for the client or ensure that the profile + group is properly setup. + +FAQs +==== + +Why won't bcfg2-server start? +----------------------------- + +If your server doesn't seem to be starting and you see no error +messages in your server logs, try running it in the foreground to see +why. + +Why am I getting a traceback? +----------------------------- + +If you get a traceback, please let us know by :ref:`reporting it +` on Trac, via the mailing list, or on IRC. Your best bet +to get a quick response will be to jump on IRC during the daytime (CST). + +What is the most common cause of "The following entries are not handled by any tool"? +------------------------------------------------------------------------------------- + +Often it corresponds to entries that aren't bound by the server (for which +you'll get error messages on the server). You should try inspecting the +logs on the server to see what may be the cause. diff --git a/doc/troubleshooting.txt b/doc/troubleshooting.txt deleted file mode 100644 index ef96c30bb..000000000 --- a/doc/troubleshooting.txt +++ /dev/null @@ -1,184 +0,0 @@ -.. -*- mode: rst -*- - -.. _unsorted-troubleshooting: - -=============== -Troubleshooting -=============== - -From time to time, Bcfg2 produces results that the user finds surprising. -This can happen either due to bugs or user error. This page describes -several techniques to gain visibility into the bcfg2 client and server -and understand what is going on. - - -Figure out if error is client or server side -============================================ - -* Cache a copy of the client configuration using ``bcfg2 -qnc /tmp/config.xml`` -* Look in the file and search for the entry of interest -* If it looks correct, then there is a client issue -* If not, it is time to inspect things on the server - -This file contains all aspects of client configuration. It is structured -as a series of bundles and base entries. - -.. note:: - - Most often the entry is not correct and the issue lies in - the specification. - -Review server log messages -========================== - -The bcfg2-server process logs to syslog facility LOG_DAEMON. The server -produces a series of messages upon a variety of events and errors. - -Check if all repository XML files conform to schemas -==================================================== - -Bcfg2 comes with XML schemas describing all of the XML formats used in -the server repository. A validation command ``bcfg2-repo-validate`` is -included with the source distribution and all packages. Run it with the --v flag to see each file and the results if its validation. - -If the bcfg2 server is not reflecting recent changes, try restarting the bcfg2-server process -============================================================================================= - -If this fixes the problem, it is either a bug in the -underlying file monitoring system (fam or gamin) or a bug in -Bcfg2's file monitoring code. In either case, file a `ticket -`_ in the tracking -system. In the ticket, include: - -* filesystem monitoring system (fam or gamin) -* kernel version (if on linux) -* if any messages of the form "Handled N events in M - seconds" appeared between the modification event and the client - configuration generation request appeared in the server log -* which plugin handled the file in the repostiory (Cfg, Rules, Packages, - TCheetah, TGenshi, Metadata) -* if a touch of the file after the modification causes the problem to - go away - -bcfg2-info -========== - -Bcfg2 server operations can be simulated using the ``bcfg2-info`` command. -The command is interactive, and has commands to allow several useful -operations - -* clients - Current client metadata (profile and group) settings -* groups - Current group metadata values -* mappings - Configuration entries provided by plugins -* buildfile - Build a config file for a client -* showentries - Build the abstract configuration (list - of entries) for a client -* build - Build the complete configuration - for a client - -Type `help` in bcfg2-info for more information. - -Error Messages -============== - -This page describes error messages produced by Bcfg2 and steps that can -be taken to remedy them. - -+------------------------------+----------+---------------------+--------------+ -| Error | Location | Meaning | Repair | -+==============================+==========+=====================+==============+ -| Incomplete information for | Client | The described entry | [1]_ | -| entry : | | is not fully | | -| cannot verify | | specified by the | | -| | | server, so no | | -| | | verification can be | | -| | | performed. | | -+------------------------------+----------+---------------------+--------------+ -| Incomplete information for | Client | The described entry | [1]_ | -| entry : | | is not fully | | -| cannot install | | specified by the | | -| | | server, so no | | -| | | verification can be | | -| | | performed. | | -+------------------------------+----------+---------------------+--------------+ -| The following entries are | Client | The client cannot | [2]_ | -| not handled by any tool: | | figure out how to | | -| : | | handle this entry. | | -+------------------------------+----------+---------------------+--------------+ -| No ca is specified. Cannot | Client | The client is | [3]_ | -| authenticate the server with | | unable to verify | | -| SSL. | | the server | | -+------------------------------+----------+---------------------+--------------+ -| Failed to bind entry: | Server | The server was | [4]_ | -| | | unable to find a | | -| | | suitable version of | | -| | | entry for client. | | -+------------------------------+----------+---------------------+--------------+ -| Failed to bind to socket | Server | The server was | [5]_ | -| | | unable to bind to | | -| | | the tcp server | | -| | | socket. | | -+------------------------------+----------+---------------------+--------------+ -| Failed to load | Server | The server was | [6]_ | -| ssl key | | unable to read and | | -| | | process the ssl key.| | -+------------------------------+----------+---------------------+--------------+ -| Failed to read file | Server | The server failed | [7]_ | -| | | to read the | | -| | | specified file | | -+------------------------------+----------+---------------------+--------------+ -| Failed to parse file | Server | The server failed | [8]_ | -| | | to parse the | | -| | | specified XML file | | -+------------------------------+----------+---------------------+--------------+ -| Client metadata resolution | Server | The server cannot | [9]_ | -| error for | | resolve the client | | -| | | hostname or the | | -| | | client is | | -| | | associated with a | | -| | | non-profile group. | | -+------------------------------+----------+---------------------+--------------+ - - -.. [1] This entry is not being bound. Ensure that a version of this - entry applies to this client. -.. [2] Add a type to the generator definition for this entry -.. [3] Copy the Bcfg2 server's CA certificate to the client and specify it - using the **ca** option in the [communication] section of - ``bcfg2.conf`` -.. [4] This entry is not being bound. Ensure that a version of this - entry applies to this client. -.. [5] Ensure that another instance of the daemon (or any other process) - is not listening on the same port. -.. [6] Ensure that the key is readable by the user running the daemon - and that it is well-formed. -.. [7] Ensure that this file still exists; a frequent cause is the - deletion of a temp file. -.. [8] Ensure that the file is properly formed XML. -.. [9] Fix hostname resolution for the client or ensure that the profile - group is properly setup. - -FAQs -==== - -Why won't bcfg2-server start? ------------------------------ - -If your server doesn't seem to be starting and you see no error -messages in your server logs, try running it in the foreground to see -why. - -Why am I getting a traceback? ------------------------------ - -If you get a traceback, please let us know by :ref:`reporting it -` on Trac, via the mailing list, or on IRC. Your best bet -to get a quick response will be to jump on IRC during the daytime (CST). - -What is the most common cause of "The following entries are not handled by any tool"? -------------------------------------------------------------------------------------- - -Often it corresponds to entries that aren't bound by the server (for which -you'll get error messages on the server). You should try inspecting the -logs on the server to see what may be the cause. -- cgit v1.2.3-1-g7c22 From 0fba2216c8ebe88bd3b74fd79edf27982d33ae69 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 9 Nov 2010 00:29:52 +0100 Subject: Intro added --- doc/contents.txt | 38 +++++--------- doc/index.txt | 80 +++--------------------------- doc/introduction/architecture-overview.txt | 34 +++++++++++++ doc/introduction/index.txt | 41 +++++++++++++++ doc/introduction/os-support.txt | 46 +++++++++++++++++ 5 files changed, 141 insertions(+), 98 deletions(-) create mode 100644 doc/introduction/architecture-overview.txt create mode 100644 doc/introduction/index.txt create mode 100644 doc/introduction/os-support.txt diff --git a/doc/contents.txt b/doc/contents.txt index 40128175e..df5c5350c 100644 --- a/doc/contents.txt +++ b/doc/contents.txt @@ -2,30 +2,29 @@ .. _contents: -================================= -Welcome to Bcfg2's documentation! -================================= +========================================== +Welcome to Bcfg2's |version| documentation +========================================== .. toctree:: :maxdepth: 2 + :numbered: - index - quickstart/index - help/index - faq/index - authentication + introduction/index + installation/index getting_started/index + architecture/index server/index client/index - troubleshooting - help/index - bcfg2.conf-options - architecture + reports/index development/index - + getting_help/index + glossary + appendix/index + unsorted/index + obsolete/index - glossary Indices, glossary and tables ============================ @@ -34,14 +33,3 @@ Indices, glossary and tables * :ref:`modindex` * :ref:`glossary` * :ref:`search` - -Deprecated/obsolete documentation -================================= - -The following documentation covers features that have been deprecated or that -have been replaced in newer versions of Bcfg2. - -.. toctree:: - :maxdepth: 2 - - obsolete/index diff --git a/doc/index.txt b/doc/index.txt index 0479fea2d..583ea38e3 100644 --- a/doc/index.txt +++ b/doc/index.txt @@ -2,9 +2,9 @@ .. _index: -====================== -Bcfg2 Manual |release| -====================== +========================================== +Welcome to Bcfg2's |version| documentation +========================================== What is Bcfg2? ============== @@ -37,74 +37,8 @@ systems are constantly changing; if required in your environment, Bcfg2 can enable the construction of complex change management and deployment strategies. -Architecture ------------- - -Bcfg2 provides a declarative interface to system configuration. Its -configuration specifications describe a literal configuration goal -state for clients. In this architecture, the Bcfg2 client tool is -responsible for determining what, if any, configuration operations must -occur and then performing those operations. The client also uploads -statistics and client configuration state information. The design -and implementation of the reporting system is described on a separate -:ref:`page `. - -A comprehensive description of the Bcfg2 Architecture (and the choices -behind the design) can be found at :ref:`architecture`. - -Server -^^^^^^ - -The role of the Bcfg2 server is rendering a client-specific target -configuration description from a global specification. The specification -consists of a directory structure containing data for a variety of server -plugins. The Bcfg2 server has a plugin interface that can be used to -interpret the configuration specification. - -Client -^^^^^^ - -The Bcfg2 client is responsible for determining what operations are -necessary in order to reach the desired configuration state. Read on -for more information about :ref:`client-index`. - -What Operating Systems Does Bcfg2 Support? -========================================== - -Bcfg2 is fairly portable. It has been successfully run on: - -* `AIX`_, `FreeBSD`_, `OpenBSD`_, `Mac OS X`_, `OpenSolaris`_, - `Solaris`_. - -.. _AIX: http://www.ibm.com/aix -.. _FreeBSD: http://www.freebsd.org/ -.. _OpenBSD: http://www.openbsd.org/ -.. _Mac OS X: http://www.apple.com/macosx/ -.. _OpenSolaris: http://opensolaris.org/ -.. _Solaris: http://www.sun.com/software/solaris/ - -* Many `GNU/Linux`_ distributions, including `Blag`_, `CentOS`_, - `Debian`_, `Fedora`_, `Gentoo`_, `gNewSense`_, `Mandriva`_, - `OpenSUSE`_, `Redhat/RHEL`_, `SuSE/SLES`_, `Trisquel`_ and - `Ubuntu`_. - -.. _GNU/Linux: http://www.gnu.org/gnu/Linux-and-gnu.html -.. _Blag: http://www.blagblagblag.org/ -.. _CentOS: http://www.centos.org/ -.. _Debian: http://www.debian.org/ -.. _Fedora: http://www.fedoraproject.org/ -.. _Gentoo: http://www.gentoo.org/ -.. _gNewSense: http://www.gnewsense.org/ -.. _Mandriva: http://www.mandriva.com/ -.. _OpenSUSE: http://opensuse.org/ -.. _Redhat/RHEL: http://www.redhat.com/rhel/ -.. _SuSE/SLES: http://www.novell.com/linux/ -.. _Trisquel: http://trisquel.info/ -.. _Ubuntu: http://www.ubuntu.com/ +.. toctree:: + :numbered: + :maxdepth: 2 -Bcfg2 should run on any POSIX compatible operating system, however -direct support for an operating system's package and service formats -are limited by the currently available :ref:`client-tools-index` -(new client tools are pretty easy to add). Check the :ref:`FAQ -` for a more exact list of platforms on which Bcfg2 -works. + contents diff --git a/doc/introduction/architecture-overview.txt b/doc/introduction/architecture-overview.txt new file mode 100644 index 000000000..55bf4e557 --- /dev/null +++ b/doc/introduction/architecture-overview.txt @@ -0,0 +1,34 @@ +.. -*- mode: rst -*- + +.. _architecture-overview: + +Architecture Overview +===================== + +Bcfg2 provides a declarative interface to system configuration. Its +configuration specifications describe a literal configuration goal +state for clients. In this architecture, the Bcfg2 client tool is +responsible for determining what, if any, configuration operations must +occur and then performing those operations. The client also uploads +statistics and client configuration state information. The design +and implementation of the reporting system is described on a separate +:ref:`page `. + +A comprehensive description of the Bcfg2 Architecture (and the choices +behind the design) can be found at :ref:`architecture-index`. + +Server +------ + +The role of the Bcfg2 server is rendering a client-specific target +configuration description from a global specification. The specification +consists of a directory structure containing data for a variety of server +plugins. The Bcfg2 server has a plugin interface that can be used to +interpret the configuration specification. + +Client +------ + +The Bcfg2 client is responsible for determining what operations are +necessary in order to reach the desired configuration state. Read on +for more information about :ref:`client-index`. diff --git a/doc/introduction/index.txt b/doc/introduction/index.txt new file mode 100644 index 000000000..5f4d41ff4 --- /dev/null +++ b/doc/introduction/index.txt @@ -0,0 +1,41 @@ +.. -*- mode: rst -*- + +.. _introduction-index: + +Introduction +============ + +Bcfg2 helps system administrators produce a consistent, reproducible, +and verifiable description of their environment, and offers +visualization and reporting tools to aid in day-to-day administrative +tasks. It is the fifth generation of configuration management tools +developed in the `Mathematics and Computer Science Division`_ of +`Argonne National Laboratory`_. + +.. _Mathematics and Computer Science Division: http://www.mcs.anl.gov/ +.. _Argonne National Laboratory: http://www.anl.gov/ + +It is based on an operational model in which the specification can be +used to validate and optionally change the state of clients, but in a +feature unique to Bcfg2 the client's response to the specification can +also be used to assess the completeness of the specification. Using +this feature, Bcfg2 provides an objective measure of how good a job an +administrator has done in specifying the configuration of client +systems. Bcfg2 is therefore built to help administrators construct an +accurate, comprehensive specification. + +Bcfg2 has been designed from the ground up to support gentle +reconciliation between the specification and current client states. It +is designed to gracefully cope with manual system modifications. + +Finally, due to the rapid pace of updates on modern networks, client +systems are constantly changing; if required in your environment, +Bcfg2 can enable the construction of complex change management and +deployment strategies. + + +.. toctree:: + :maxdepth: 2 + + architecture-overview + os-support diff --git a/doc/introduction/os-support.txt b/doc/introduction/os-support.txt new file mode 100644 index 000000000..efbc307cb --- /dev/null +++ b/doc/introduction/os-support.txt @@ -0,0 +1,46 @@ +.. -*- mode: rst -*- + +.. _os-support: + +What Operating Systems Does Bcfg2 Support? +------------------------------------------ + +Bcfg2 is fairly portable. It has been successfully run on: + +* `AIX`_, `FreeBSD`_, `OpenBSD`_, `Mac OS X`_, `OpenSolaris`_, + `Solaris`_. + +.. _AIX: http://www.ibm.com/aix +.. _FreeBSD: http://www.freebsd.org/ +.. _OpenBSD: http://www.openbsd.org/ +.. _Mac OS X: http://www.apple.com/macosx/ +.. _OpenSolaris: http://opensolaris.org/ +.. _Solaris: http://www.sun.com/software/solaris/ + +* Many `GNU/Linux`_ distributions, including `Archlinux`_, `Blag`_, `CentOS`_, + `Debian`_, `Fedora`_, `Gentoo`_, `gNewSense`_, `Mandriva`_, + `OpenSUSE`_, `Red Hat/RHEL`_, `Scientific Linux`_, `SuSE/SLES`_, `Trisquel`_, + and `Ubuntu`_. + +.. _GNU/Linux: http://www.gnu.org/gnu/Linux-and-gnu.html +.. _Archlinux: http://www.archlinux.org +.. _Blag: http://www.blagblagblag.org/ +.. _CentOS: http://www.centos.org/ +.. _Debian: http://www.debian.org/ +.. _Fedora: http://www.fedoraproject.org/ +.. _Gentoo: http://www.gentoo.org/ +.. _gNewSense: http://www.gnewsense.org/ +.. _Mandriva: http://www.mandriva.com/ +.. _OpenSUSE: http://opensuse.org/ +.. _Red Hat/RHEL: http://www.redhat.com/rhel/ +.. _Scientific Linux: http://www.scientificlinux.org/ +.. _SuSE/SLES: http://www.novell.com/linux/ +.. _Trisquel: http://trisquel.info/ +.. _Ubuntu: http://www.ubuntu.com/ + +Bcfg2 should run on any POSIX compatible operating system, however +direct support for an operating system's package and service formats +are limited by the currently available :ref:`client-tools-index` +(new client tools are pretty easy to add). Check the :ref:`FAQ +` for a more exact list of platforms on which Bcfg2 +works`. -- cgit v1.2.3-1-g7c22 From e73ac8768901cb52b8d1c345772df0ebd5dd86ba Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 9 Nov 2010 00:36:42 +0100 Subject: quickstart removed --- doc/introduction/os-support.txt | 2 +- doc/quickstart/centos.txt | 567 --------------------------- doc/quickstart/index.txt | 260 ------------ doc/quickstart/ubuntu.txt | 479 ---------------------- doc/server/plugins/connectors/properties.txt | 10 +- 5 files changed, 5 insertions(+), 1313 deletions(-) delete mode 100644 doc/quickstart/centos.txt delete mode 100644 doc/quickstart/index.txt delete mode 100644 doc/quickstart/ubuntu.txt diff --git a/doc/introduction/os-support.txt b/doc/introduction/os-support.txt index efbc307cb..3e27019f2 100644 --- a/doc/introduction/os-support.txt +++ b/doc/introduction/os-support.txt @@ -20,7 +20,7 @@ Bcfg2 is fairly portable. It has been successfully run on: * Many `GNU/Linux`_ distributions, including `Archlinux`_, `Blag`_, `CentOS`_, `Debian`_, `Fedora`_, `Gentoo`_, `gNewSense`_, `Mandriva`_, `OpenSUSE`_, `Red Hat/RHEL`_, `Scientific Linux`_, `SuSE/SLES`_, `Trisquel`_, - and `Ubuntu`_. + and `Ubuntu`_. .. _GNU/Linux: http://www.gnu.org/gnu/Linux-and-gnu.html .. _Archlinux: http://www.archlinux.org diff --git a/doc/quickstart/centos.txt b/doc/quickstart/centos.txt deleted file mode 100644 index 4a702683e..000000000 --- a/doc/quickstart/centos.txt +++ /dev/null @@ -1,567 +0,0 @@ -.. -*- mode: rst -*- - -.. _EPEL: http://fedoraproject.org/wiki/EPEL - -.. _quickstart-centos: - -===================== -Quickstart for CentOS -===================== - -This is a complete getting started guide for CentOS. With this document -you should be able to install a Bcfg2 server and a Bcfg2 client. - -Install Bcfg2 -============= - -The fastest way to get Bcfg2 onto your system is to use Yum or -your preferred package management tool. We'll be using the ones -that are distributed through EPEL_, but depending on your aversion -to risk you could download an RPM from other places as well. See -:ref:`getting_started-using_bcfg2-with-centos` for information about -building Bcfg2 from source and making your own packages. - -Using EPEL ----------- - -Make sure EPEL_ is a valid repository on your server. The `instructions -`_ on how to do this -basically say:: - - [root@centos ~]# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm - -.. note:: - - You will have to adjust this command to match your architecture and - the current EPEL release. - -Install the bcfg2-server and bcfg2 RPMs:: - - [root@centos ~]# yum install bcfg2-server bcfg2 - -Your system should now have the necessary software to use Bcfg2. The -next step is to set up your Bcfg2 :term:`repository`. - -Initialize your repository -========================== - -Now that you're done with the install, you need to initialize your -repository and setup your ``/etc/bcfg2.conf``. ``bcfg2-admin init`` -is a tool which allows you to automate this:: - - [root@centos ~]# 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): - What is the server's hostname: [centos] - Input the server location [https://centos: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 - : 1 - Generating a 2048 bit RSA private key - .........................+++ - ..................+++ - writing new private key to '/etc/bcfg2.key' - ----- - Signature ok - subject=/C=US=ST=Illinois/L=Argonne/CN=centos - Getting Private key - Repository created successfuly in /var/lib/bcfg2 - -Change responses as necessary. - -Start the server -================ - -You are now ready to start your bcfg2 server for the first time:: - - [root@centos ~]# /sbin/service bcfg2-server start - -To verify that everything started ok, look for the running daemon and check the logs:: - - [root@centos ~]# /etc/init.d/service bcfg2-server status - [root@centos ~]# tail /var/log/messages - Mar 29 12:42:26 centos bcfg2-server[5093]: service available at https://centos:6789 - Mar 29 12:42:26 centos bcfg2-server[5093]: serving bcfg2-server at https://centos:6789 - Mar 29 12:42:26 centos bcfg2-server[5093]: serve_forever() [start] - Mar 29 12:42:41 centos bcfg2-server[5093]: Handled 16 events in 0.007s - -Run bcfg2 to be sure you are able to communicate with the server:: - - [root@centos ~]# bcfg2 -vqn - No ca is specified. Cannot authenticate the server with SSL. - No ca is specified. Cannot authenticate the server with SSL. - Loaded plugins: fastestmirror - Loading mirror speeds from cached hostfile - Excluding Packages in global exclude list - Finished - Loaded tool drivers: - Action Chkconfig POSIX YUMng - - Phase: initial - Correct entries: 0 - Incorrect entries: 0 - Total managed entries: 0 - Unmanaged entries: 208 - - - Phase: final - Correct entries: 0 - Incorrect entries: 0 - Total managed entries: 0 - Unmanaged entries: 208 - - No ca is specified. Cannot authenticate the server with SSL. - -The ca message is just a warning, meaning that the client does not -have sufficient information to verify that it is talking to the -correct server. This can be fixed by distributing the ca certificate -from the server to all clients. By default, this file is available in -``/etc/bcfg2.crt`` on the server. Copy this file to the client (with a -bundle) and add the ca option to ``bcfg2.conf`` pointing at the file, -and the client will be able to verify it is talking to the correct server -upon connection:: - - [root@centos ~]# cat /etc/bcfg2.conf - - - [communication] - protocol = xmlrpc/ssl - password = N41lMNeW - ca = /etc/bcfg2.crt - - [components] - bcfg2 = https://centos:6789 - -Now if you run the client, no more warning:: - - [root@centos ~]# bcfg2 -vqn - Loaded plugins: fastestmirror - Loading mirror speeds from cached hostfile - Excluding Packages in global exclude list - Finished - Loaded tool drivers: - Action Chkconfig POSIX YUMng - - Phase: initial - Correct entries: 0 - Incorrect entries: 0 - Total managed entries: 0 - Unmanaged entries: 208 - - - Phase: final - Correct entries: 0 - Incorrect entries: 0 - Total managed entries: 0 - Unmanaged entries: 208 - -Bring your first machine under Bcfg2 control -============================================ - -Now it is time to get your first machine's configuration into your -Bcfg2 :term:`repository`. Let's start with the server itself. - - -Setup the `Packages`_ plugin ----------------------------- - -.. _Packages: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Packages - -First, replace **Pkgmgr** with **Packages** in the plugins -line of ``bcfg2.conf``. Then create Packages layout (as per -:ref:`packages-exampleusage`) in ``/var/lib/bcfg2`` - -.. note:: I am using the RawURL syntax here since we are using `mrepo`_ - to manage our yum mirrors. - -.. _mrepo: http://dag.wieers.com/home-made/mrepo/ - -.. code-block:: xml - - - - - centos5.4 - http://mrepo/centos5-x86_64/RPMS.os - x86_64 - - - centos5.4 - http://mrepo/centos5-x86_64/RPMS.updates - x86_64 - - - centos5.4 - http://mrepo/centos5-x86_64/RPMS.extras - x86_64 - - - -Due to the `Magic Groups`_, we need to modify our Metadata. Let's -add a **centos5.4** group which inherits a **centos** group -(this should replace the existing **redhat** group) present in -``/var/lib/bcfg2/Metadata/groups.xml``. The resulting file should look -something like this - -.. _Magic Groups: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Packages#MagicGroups - -.. code-block:: xml - - - - - - - - - - - - - - - - - - -.. note:: - When editing your xml files by hand, it is useful to occasionally run - `bcfg2-repo-validate` to ensure that your xml validates properly. - -The final thing we need is for the client to have the proper -arch group membership. For this, we will make use of the -:ref:`unsorted-dynamic_groups` capabilities of the Probes plugin. Add -Probes to your plugins line in ``bcfg2.conf`` and create the Probe.:: - - [root@centos ~]# grep plugins /etc/bcfg2.conf - plugins = Base,Bundler,Cfg,Metadata,Packages,Probes,Rules,SSHbase - [root@centos ~]# mkdir /var/lib/bcfg2/Probes - [root@centos ~]# cat /var/lib/bcfg2/Probes/groups - #!/bin/sh - - echo "group:`uname -m`" - -Now we restart the bcfg2-server:: - - [root@centos ~]# /etc/init.d/bcfg2-server restart - -If you tail ``/var/log/syslog`` now, you will see the Packages plugin in -action, updating the cache. - -Start managing packages ------------------------ - -Add a base-packages bundle. Let's see what happens when we just populate -it with the *yum* package. - -.. code-block:: xml - - [root@centos ~]# cat /var/lib/bcfg2/Bundler/base-packages.xml - - - - -You need to reference the bundle from your Metadata. The resulting -profile group might look something like this - -.. code-block:: xml - - - - - - -Now if we run the client, we can see what this has done for us.:: - - [root@centos ~]# bcfg2 -vqn - Running probe groups - Probe groups has result: - x86_64 - Loaded plugins: fastestmirror - Loading mirror speeds from cached hostfile - Excluding Packages in global exclude list - Finished - Loaded tool drivers: - Action Chkconfig POSIX YUMng - Package pam failed verification. - - Phase: initial - Correct entries: 94 - Incorrect entries: 1 - Total managed entries: 95 - Unmanaged entries: 113 - - In dryrun mode: suppressing entry installation for: - Package:pam - - Phase: final - Correct entries: 94 - Incorrect entries: 1 - Package:pam - Total managed entries: 95 - Unmanaged entries: 113 - -Interesting, our **pam** package failed verification. What does this -mean? Let's have a look:: - - [root@centos ~]# rpm --verify pam - ....L... c /etc/pam.d/system-auth - -Sigh, it looks like the default RPM install for pam fails to verify -using its own verification process (trust me, it's not the only one). At -any rate, I was able to get rid of this particular issue by removing the -symlink and running ``yum reinstall pam``. - -As you can see, the Packages plugin has generated the dependencies -required for the yum package automatically. The ultimate goal should -be to move all the packages from the **Unmanaged** entries section to -the **Managed** entries section. So, what exactly *are* those Unmanaged -entries?:: - - [root@centos ~]# bcfg2 -veqn - Running probe groups - Probe groups has result: - x86_64 - Loaded plugins: fastestmirror - Loading mirror speeds from cached hostfile - Excluding Packages in global exclude list - Finished - Loaded tool drivers: - Action Chkconfig POSIX YUMng - Extra Package openssh-clients 4.3p2-36.el5_4.4.x86_64. - Extra Package libuser 0.54.7-2.1el5_4.1.x86_64. - ... - - Phase: initial - Correct entries: 95 - Incorrect entries: 0 - Total managed entries: 95 - Unmanaged entries: 113 - - - Phase: final - Correct entries: 95 - Incorrect entries: 0 - Total managed entries: 95 - Unmanaged entries: 113 - Package:at - Package:avahi - Package:avahi-compat-libdns_sd - ... - -Now you can go through these and continue adding the packages you want -to your Bundle. After a while, I ended up with a minimal bundle that -looks like this - -.. code-block:: xml - - - - - - - - - - - - - - - - - - - -Now when I run the client, you can see I have only one unmanaged -package:: - - [root@centos ~]# bcfg2 -veqn - Running probe groups - Probe groups has result: - x86_64 - Loaded plugins: fastestmirror - Loading mirror speeds from cached hostfile - Excluding Packages in global exclude list - Finished - Loaded tool drivers: - Action Chkconfig POSIX YUMng - Extra Package gpg-pubkey e8562897-459f07a4.None. - Extra Package gpg-pubkey 217521f6-45e8a532.None. - - Phase: initial - Correct entries: 187 - Incorrect entries: 0 - Total managed entries: 187 - Unmanaged entries: 16 - - - Phase: final - Correct entries: 187 - Incorrect entries: 0 - Total managed entries: 187 - Unmanaged entries: 16 - Package:gpg-pubkey - Service:atd - Service:avahi-daemon - Service:bcfg2-server - ... - -The gpg-pubkey packages are special in that they are not really -packages. Currently, the way to manage them is using :ref:`BoundEntries -`. So, after adding them, our Bundle now looks like this - -.. note:: This does not actually control the contents of the files, - you will need to do this part separately (see below). - -.. code-block:: xml - - - - - - - - - - - - - - - - - - - - - - - -.. note:: version="foo" is just a dummy attribute for the gpg-pubkey Package - -To actually push the gpg keys out via Bcfg2, you will need to manage the -files as well. This can be done by adding Path entries for each of the -gpg keys you want to manage - -.. code-block:: xml - - - - - - - - - - - - - - - - - - - - - - - - - -Then add the files to Cfg:: - - mkdir -p Cfg/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 - cp /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 !$/RPM-GPG-KEY-CentOS-5 - mkdir -p Cfg/etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL - cp /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL !$/RPM-GPG-KEY-EPEL - -Now, running the client shows only unmanaged Service entries. Woohoo! - -Manage services ---------------- - -Now let's clear up the unmanaged service entries by adding the following -entries to our bundle. - -.. code-block:: xml - - - - - - - - - - - - - - - - - - -...and bind them in Rules - -.. code-block:: xml - - [root@centos ~]# cat /var/lib/bcfg2/Rules/services.xml - - - - - - - - - - - - - - - - - - - -Now we run the client and see there are no more unmanaged entries! :: - - [root@centos ~]# bcfg2 -veqn - Running probe groups - Probe groups has result: - x86_64 - Loaded plugins: fastestmirror - Loading mirror speeds from cached hostfile - Excluding Packages in global exclude list - Finished - Loaded tool drivers: - Action Chkconfig POSIX YUMng - - Phase: initial - Correct entries: 205 - Incorrect entries: 0 - Total managed entries: 205 - Unmanaged entries: 0 - - - Phase: final - Correct entries: 205 - Incorrect entries: 0 - Total managed entries: 205 - Unmanaged entries: 0 - -Dynamic (web) reports -===================== - -See installation instructions at :ref:`server-reports-install` diff --git a/doc/quickstart/index.txt b/doc/quickstart/index.txt deleted file mode 100644 index 37dbaa915..000000000 --- a/doc/quickstart/index.txt +++ /dev/null @@ -1,260 +0,0 @@ -.. -*- mode: rst -*- - -.. _quickstart-index: - -========== -Quickstart -========== - -The steps below should get you from just thinking about a -configuration management system to an operational installation of -Bcfg2. If you get stuck, be sure to check the `mailing list`_ -or to drop in on our `IRC channel`_. - -.. _mailing list: https://trac.mcs.anl.gov/projects/bcfg2/wiki/MailingList -.. _IRC channel: https://trac.mcs.anl.gov/projects/bcfg2/wiki/IRCChannel - -See the `Platform-specific Quickstart Notes`_ at the end of this page in case your operating systems has been favored with its own quickstart document. - -Get and Install Bcfg2 Server -============================ - -We recommend running the server on a Linux machine for ease of -deployment due to the availability of packages for the dependencies. - -First, you need to download and install Bcfg2. The `Bcfg2 download -page`_ has both source and packages for common environments, while our -`Install page`_ describes what to do once you have the packages in hand. -To start, you will need to install the server on one machine and the -client on one or more machines. Yes, your server can also be a client -(and should be by the time your environment is fully managed). - -.. _Bcfg2 download page: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Download -.. _Install page: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Install - -Set up Repository -================= - -The next step after installing the Bcfg2 packages is to configure the -server. You can easily set up a personalized default configuration by -running, on the server, :: - - bcfg2-admin init - -You will be presented with a series of questions that will build a -Bcfg2 configuration file in ``/etc/bcfg2.conf``, set up a skeleton -repository (in ``/var/lib/bcfg2`` by default), help you create ssl -certificates, and do any other similar tasks needed to get you -started. - -Once this process is done, you can start the Bcfg2 server:: - - /etc/init.d/bcfg2-server start - -You can try it out by running the Bcfg2 client on the same machine, -acting like it is your first client. - -.. note:: - - The following command will tell the client to run in no-op mode, - meaning it will only check the client against the repository and - report any differences it sees. It won't make any changes (partially - because you haven't populated the repository with any yet). However, - nobody is perfect - you can make a typo, our software can have bugs, - monkeys can break in and hit enter before you are done. Don't run - this command on a production system if you don't know what it does - and aren't prepared for the consequences. We don't know of anybody - having problems with it before, but it is better to be safe than sorry. - -And now for the command:: - - bcfg2 -q -v -n - -That can be translated as "bcfg2 quick verbose no-op". The output -should be something similar to:: - - Loaded tool drivers: - Chkconfig POSIX YUMng - - Phase: initial - Correct entries: 0 - Incorrect entries: 0 - Total managed entries: 0 - Unmanaged entries: 242 - - - Phase: final - Correct entries: 0 - Incorrect entries: 0 - Total managed entries: 0 - Unmanaged entries: 242 - -Perfect! We have started out with an empty configuration, and none of -our configuration elements are correct. It doesn't get much cleaner -than that. But what about those unmanaged entries? Those are the extra -configuration elements (probably all packages and services at the -moment) that still aren't managed, but have been detected by the client -tools. Your goal now is to migrate each of those plus any it can't see -up to the "Correct entries" line. - -Populate Repository -=================== - -Finally, you need to populate your repository. Unfortunately, from -here on out we can't write up a simple recipe for you to follow to get -this done. It is very dependent on your local configuration, your -configuration management goals, the politics surrounding your -particular machines, and many other similar details. We can, however, -give you guidance. - -After the above steps, you should have a toplevel repository structure -that looks like:: - - bcfg-server:~ # ls /var/lib/bcfg2 - Base/ Bundler/ Cfg/ Metadata/ Pkgmgr/ Rules/ SSHbase/ etc/ - -The place to start is the Metadata directory, which contains two -files: ``clients.xml`` and ``groups.xml``. Your current -``clients.xml`` will look pretty close to: - -.. code-block:: xml - - - - - -The ``clients.xml`` file is just a series of ```` tags, each -of which describe one host you manage. Right now we only manage one -host, the server machine we just created. This machine is bound to the -``basic`` profile, is pingable, has a pingtime of ``0``, and has the -name ``bcfg-server.example.com``. The two "ping" parameters don't -matter to us at the moment, but the other two do. The name parameter -is the fully qualified domain name of your host, and the profile -parameter maps that host into the ``groups.xml`` file. - -Our simple ``groups.xml`` file looks like: - -.. code-block:: xml - - - - - - - - - - - - - -There are two types of groups in Bcfg: profile groups (``profile='true'``) -and non-profile groups (``profile='false'``). Profile groups can act as -top-level groups to which clients can bind, while non-profile groups only -exist as members of other groups. In our simple starter case, we have -a profile group named ``basic``, and that is the group that our first -client bound to. Our first client is a SuSE machine, so it contains the -``suse`` group. Of course, ``bcfg2-admin`` isn't smart enough to fill -out the rest of your config, so the ``suse`` group further down is empty. - -Let's say the first thing we want to set up on our machine is the -message of the day. To do this, we simply need to create a Bundle and -add that Bundle to an appropriate group. In this simple example, we -start out by adding - -.. code-block:: xml - - - -to the ``basic`` group. - -Next, we create a motd.xml file in the Bundler directory: - -.. code-block:: xml - - - - - -Now when we run the client, we get slightly different output:: - - Loaded tool drivers: - Chkconfig POSIX YUMng - Incomplete information for entry Path:/etc/motd; cannot verify - - Phase: initial - Correct entries: 0 - Incorrect entries: 1 - Total managed entries: 1 - Unmanaged entries: 242 - - In dryrun mode: suppressing entry installation for: - Path:/etc/motd - - Phase: final - Correct entries: 0 - Incorrect entries: 1 - Total managed entries: 1 - Unmanaged entries: 242 - -We now have an extra unmanaged entry, bringing our total number of -managed entries up to one. To manage it we need to copy ``/etc/motd`` -to ``/var/lib/bcfg2/Cfg/etc/motd/``. Note the layout of that path: all -plain-text config files live in the Cfg directory. The directory -structure under that directory directly mimics your real filesystem -layout, making it easy to find and add new files. The last directory -is the name of the file itself, so in this case the full path to the -motd file would be ``/var/lib/bcfg2/Cfg/etc/motd/motd``. Copy your -real ``/etc/motd`` file to that location, run the client again, and -you will find that we now have a correct entry:: - - Loaded tool drivers: - Chkconfig POSIX PostInstall RPM - - Phase: initial - Correct entries: 1 - Incorrect entries: 0 - Total managed entries: 1 - Unmanaged entries: 242 - - - Phase: final - Correct entries: 1 - Incorrect entries: 0 - Total managed entries: 1 - Unmanaged entries: 242 - -Done! Now we just have 242 (or more) entries to take care of! - -:ref:`server-plugins-structures-bundler-index` is a relatively easy -directory to populate. You can find many samples of Bundles in the -`Bundle Repository`_, many of which can be used without editing. - -.. _Bundle Repository: http://docs.bcfg2.org/server/plugins/structures/bundler/index.html#other-examples - -Next Steps -========== - -Several other utilities can help from this point on: - -:ref:`bcfg2-info ` is a utility that -instantiates a copy of the bcfg2 server core (minus the networking code) -for examination. From this, you can directly query: - -* Client Metadata -* Which entries are provided by particular plugins -* Client Configurations - -Run ``bcfg2-info``, and type help and the prompt when it comes up. - -``bcfg2-admin`` can perform a variety of repository maintenance -tasks. Run ``bcfg2-admin`` help for details. - -Platform-specific Quickstart Notes -================================== - -.. toctree:: - :maxdepth: 2 - - centos - ubuntu diff --git a/doc/quickstart/ubuntu.txt b/doc/quickstart/ubuntu.txt deleted file mode 100644 index 41d69eb0c..000000000 --- a/doc/quickstart/ubuntu.txt +++ /dev/null @@ -1,479 +0,0 @@ -.. -*- mode: rst -*- - -.. _quickstart-ubuntu: - -===================== -Quickstart for Ubuntu -===================== - -.. note:: - - This particular how to was done on lucid, but should apply to any - other `stable`__ version of Ubuntu. - -__ ubuntu-releases_ -.. _ubuntu-releases: https://wiki.ubuntu.com/Releases - -Install Bcfg2 -============= - -We first need to install the server. For this example, we will use the -bcfg2 server package from the bcfg2 `PPA`_ (note that there is also a -version available in the ubuntu archives, but it is not as up to date). - -.. _PPA: https://launchpad.net/~bcfg2/+archive/ppa - -Add the Ubuntu PPA listing to your APT sources ----------------------------------------------- - -See http://trac.mcs.anl.gov/projects/bcfg2/wiki/PrecompiledPackages#UbuntuLucid - -Install bcfg2-server --------------------- -:: - - aptitude install bcfg2-server - -Remove the default configuration preseeded by the ubuntu package:: - - root@lucid:~# rm -rf /etc/bcfg2* /var/lib/bcfg2 - -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 process.:: - - root@lucid:~# 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): - What is the server's hostname: [lucid] - Input the server location [https://lucid: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 2048 bit RSA private key - ......................................................................................+++ - ...+++ - writing new private key to '/etc/bcfg2.key' - ----- - Signature ok - subject=/C=US/ST=Illinois/L=Argonne/CN=lucid - Getting Private key - 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@lucid:~# /etc/init.d/bcfg2-server start - root@lucid:~# tail /var/log/syslog - Dec 17 22:07:02 lucid bcfg2-server[17523]: serving bcfg2-server at https://lucid:6789 - Dec 17 22:07:02 lucid bcfg2-server[17523]: serve_forever() [start] - Dec 17 22:07:02 lucid bcfg2-server[17523]: Processed 16 fam events in 0.502 seconds. 0 coalesced - -Run bcfg2 to be sure you are able to communicate with the server:: - - root@lucid:~# bcfg2 -vqn - Loaded tool drivers: - APT Action DebInit POSIX - - Phase: initial - Correct entries: 0 - Incorrect entries: 0 - Total managed entries: 0 - Unmanaged entries: 382 - - - Phase: final - Correct entries: 0 - Incorrect entries: 0 - Total managed entries: 0 - Unmanaged entries: 382 - -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. - -Setup the `Packages`_ plugin ----------------------------- - -.. _Packages: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Packages - -Replace Pkgmgr with Packages in the plugins line of ``bcfg2.conf``:: - - root@lucid:~# cat /etc/bcfg2.conf - [server] - repository = /var/lib/bcfg2 - plugins = Base,Bundler,Cfg,Metadata,Packages,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. - #/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 = secret - certificate = /etc/bcfg2.crt - key = /etc/bcfg2.key - ca = /etc/bcfg2.crt - - [components] - bcfg2 = https://lucid:6789 - -Create Packages layout (as per :ref:`packages-exampleusage`) in -``/var/lib/bcfg2`` - -.. code-block:: xml - - root@lucid:~# mkdir /var/lib/bcfg2/Packages - root@lucid:~# cat /var/lib/bcfg2/Packages/config.xml - - - ubuntu-lucid - http://us.archive.ubuntu.com/ubuntu - lucid - main - multiverse - restricted - universe - amd64 - i386 - - - -Due to the `Magic Groups`_, we need to modify our Metadata. Let's add -an **ubuntu-lucid** group which inherits the **ubuntu** group already -present in ``/var/lib/bcfg2/Metadata/groups.xml``. The resulting file -should look something like this - -.. _Magic Groups: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Packages#MagicGroups - -.. code-block:: xml - - - - - - - - - - - - - - - - - - -.. note:: - When editing your xml files by hand, it is useful to occasionally run - `bcfg2-repo-validate` to ensure that your xml validates properly. - -The last thing we need is for the client to have the proper -arch group membership. For this, we will make use of the -:ref:`unsorted-dynamic_groups` capabilities of the Probes plugin. Add -Probes to your plugins line in ``bcfg2.conf`` and create the Probe. - -.. code-block:: sh - - root@lucid:~# grep plugins /etc/bcfg2.conf - plugins = Base,Bundler,Cfg,Metadata,Packages,Probes,Rules,SSHbase - root@lucid:~# mkdir /var/lib/bcfg2/Probes - root@lucid:~# cat /var/lib/bcfg2/Probes/groups - #!/bin/sh - - ARCH=`uname -m` - case "$ARCH" in - "x86_64") - echo "group:amd64" - ;; - "i686") - echo "group:i386" - ;; - esac - -Now we restart the bcfg2-server:: - - root@lucid:~# /etc/init.d/bcfg2-server restart - Stopping Configuration Management Server: * bcfg2-server - Starting Configuration Management Server: * bcfg2-server - root@lucid:~# tail /var/log/syslog - Dec 17 22:36:47 lucid bcfg2-server[17937]: Packages: File read failed; falling back to file download - Dec 17 22:36:47 lucid bcfg2-server[17937]: Packages: Updating http://us.archive.ubuntu.com/ubuntu//dists/lucid/main/binary-amd64/Packages.gz - Dec 17 22:36:54 lucid bcfg2-server[17937]: Packages: Updating http://us.archive.ubuntu.com/ubuntu//dists/lucid/multiverse/binary-amd64/Packages.gz - Dec 17 22:36:55 lucid bcfg2-server[17937]: Packages: Updating http://us.archive.ubuntu.com/ubuntu//dists/lucid/restricted/binary-amd64/Packages.gz - Dec 17 22:36:56 lucid bcfg2-server[17937]: Packages: Updating http://us.archive.ubuntu.com/ubuntu//dists/lucid/universe/binary-amd64/Packages.gz - Dec 17 22:37:27 lucid bcfg2-server[17937]: Failed to read file probed.xml - Dec 17 22:37:27 lucid bcfg2-server[17937]: Loading experimental plugin(s): Packages - Dec 17 22:37:27 lucid bcfg2-server[17937]: NOTE: Interfaces subject to change - Dec 17 22:37:27 lucid bcfg2-server[17937]: service available at https://lucid:6789 - Dec 17 22:37:27 lucid bcfg2-server[17937]: serving bcfg2-server at https://lucid:6789 - Dec 17 22:37:27 lucid bcfg2-server[17937]: serve_forever() [start] - Dec 17 22:37:28 lucid bcfg2-server[17937]: Processed 17 fam events in 0.502 seconds. 0 coalesced - -Start managing packages ------------------------ - -Add a base-packages bundle. Let's see what happens when we just populate -it with the ubuntu-standard package. - -.. code-block:: xml - - root@lucid:~# cat /var/lib/bcfg2/Bundler/base-packages.xml - - - - -You need to reference the bundle from your Metadata. The resulting -profile group might look something like this - -.. code-block:: xml - - - - - - -Now if we run the client in debug mode (-d), we can see what this has -done for us.:: - - root@lucid:~# bcfg2 -vqdn - Running probe groups - Probe groups has result: - amd64 - Loaded tool drivers: - APT Action DebInit POSIX - The following packages are specified in bcfg2: - ubuntu-standard - The following packages are prereqs added by Packages: - adduser debconf hdparm libdevmapper1.02.1 libk5crypto3 libparted1.8-12 libxml2 passwd upstart - apt debianutils info libdns53 libkeyutils1 libpci3 logrotate pciutils usbutils - aptitude dmidecode install-info libelf1 libkrb5-3 libpopt0 lsb-base perl-base wget - at dnsutils iptables libept0 libkrb5support0 libreadline5 lshw popularity-contest zlib1g - base-files dosfstools libacl1 libgcc1 liblwres50 libreadline6 lsof psmisc - base-passwd dpkg libattr1 libgdbm3 libmagic1 libselinux1 ltrace readline-common - bsdmainutils ed libbind9-50 libgeoip1 libmpfr1ldbl libsigc++-2.0-0c2a man-db rsync - bsdutils file libc-bin libgmp3c2 libncurses5 libssl0.9.8 memtest86+ sed - cpio findutils libc6 libgssapi-krb5-2 libncursesw5 libstdc++6 mime-support sensible-utils - cpp ftp libcap2 libisc50 libpam-modules libusb-0.1-4 ncurses-bin strace - cpp-4.4 gcc-4.4-base libcomerr2 libisccc50 libpam-runtime libuuid1 netbase time - cron groff-base libcwidget3 libisccfg50 libpam0g libxapian15 parted tzdata - - Phase: initial - Correct entries: 101 - Incorrect entries: 0 - Total managed entries: 101 - Unmanaged entries: 281 - - - Phase: final - Correct entries: 101 - Incorrect entries: 0 - Total managed entries: 101 - Unmanaged entries: 281 - -As you can see, the Packages plugin has generated the dependencies -required for the ubuntu-standard package for us automatically. The -ultimate goal should be to move all the packages from the **Unmanaged** -entries section to the **Managed** entries section. So, what exactly *are* -those Unmanaged entries?:: - - root@lucid:~# bcfg2 -vqen - Running probe groups - Probe groups has result: - amd64 - Loaded tool drivers: - APT Action DebInit POSIX - - Phase: initial - Correct entries: 101 - Incorrect entries: 0 - Total managed entries: 101 - Unmanaged entries: 281 - - - Phase: final - Correct entries: 101 - Incorrect entries: 0 - Total managed entries: 101 - Unmanaged entries: 281 - Package:apparmor - Package:apparmor-utils - Package:apport - ... - -Now you can go through these and continue adding the packages you want to -your Bundle. Note that ``aptitude why`` is useful when trying to figure -out the reason for a package being installed. Also, deborphan is helpful -for removing leftover dependencies which are no longer needed. After a -while, I ended up with a minimal bundle that looks like this - -.. code-block:: xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -As you can see below, I no longer have any unmanaged packages. :: - - root@lucid:~# bcfg2 -vqen - Running probe groups - Probe groups has result: - amd64 - Loaded tool drivers: - APT Action DebInit POSIX - - Phase: initial - Correct entries: 247 - Incorrect entries: 0 - Total managed entries: 247 - Unmanaged entries: 10 - - - Phase: final - Correct entries: 247 - Incorrect entries: 0 - Total managed entries: 247 - Unmanaged entries: 10 - Service:bcfg2 Service:fam Service:killprocs Service:rc.local Service:single - Service:bcfg2-server Service:grub-common Service:ondemand Service:rsync Service:ssh - -Manage services ---------------- - -Now let's clear up the unmanaged service entries by adding the following -entries to our bundle... - -.. code-block:: xml - - - - - - - - - - - - - - -...and bind them in Rules - -.. code-block:: xml - - root@lucid:~# cat /var/lib/bcfg2/Rules/services.xml - - - - - - - - - - - - - - -Now we run the client and see there are no more unmanaged entries! :: - - root@lucid:~# bcfg2 -vqn - Running probe groups - Probe groups has result: - amd64 - Loaded tool drivers: - APT Action DebInit POSIX - - Phase: initial - Correct entries: 257 - Incorrect entries: 0 - Total managed entries: 257 - Unmanaged entries: 0 - - All entries correct. - - Phase: final - Correct entries: 257 - Incorrect entries: 0 - Total managed entries: 257 - Unmanaged entries: 0 - - All entries correct. - -Dynamic (web) reports -===================== - -See installation instructions at :ref:`server-reports-install` diff --git a/doc/server/plugins/connectors/properties.txt b/doc/server/plugins/connectors/properties.txt index fa8bfd884..4a3830a43 100644 --- a/doc/server/plugins/connectors/properties.txt +++ b/doc/server/plugins/connectors/properties.txt @@ -27,9 +27,9 @@ contain parsed XML data as the "data" attribute. Usage ===== -Specific property files can be referred to in -templates as metadata.Properties[]. The -data attribute is an LXML element object. (Documented +Specific property files can be referred to in templates as +metadata.Properties[]. The data attribute is an LXML element object. +(Documented `here `_) Currently, no access methods are defined for this data, but as we @@ -39,8 +39,6 @@ as methods. This will simplify templates. Accessing Properties contest from TGenshi ========================================= -Access contents of ``Properties/auth.xml`` - -:: +Access contents of ``Properties/auth.xml`` :: ${metadata.Properties['auth.xml'].data.find('file').find('bcfg2.key').text} -- cgit v1.2.3-1-g7c22 From fa3d48565cab5c6fedf0ceaf5c5d7596eeb49ff0 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 9 Nov 2010 00:40:57 +0100 Subject: Small fix --- doc/server/index.txt | 7 +++---- doc/server/plugins/connectors/properties.txt | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/doc/server/index.txt b/doc/server/index.txt index b0c97ccae..0de02c400 100644 --- a/doc/server/index.txt +++ b/doc/server/index.txt @@ -2,16 +2,15 @@ .. _server-index: -============ -Bcfg2 Server -============ +================ +The Bcfg2 Server +================ .. toctree:: :maxdepth: 2 plugins/index admin/index - reports/index configurationentries info snapshots/index diff --git a/doc/server/plugins/connectors/properties.txt b/doc/server/plugins/connectors/properties.txt index 4a3830a43..707de0880 100644 --- a/doc/server/plugins/connectors/properties.txt +++ b/doc/server/plugins/connectors/properties.txt @@ -14,8 +14,8 @@ Enabling Properties First, ``mkdir /var/lib/bcfg2/Properties``. Each property XML file goes in this directory. Each will automatically be cached by the server, -and reread/reparsed upon changes. Add **Properties** to your ``plugins`` -line in ``/etc/bcfg2.conf``. +and reread/reparsed upon changes. Add **Properties** to your `plugins` +line in `/etc/bcfg2.conf`. Data Structures =============== @@ -39,6 +39,6 @@ as methods. This will simplify templates. Accessing Properties contest from TGenshi ========================================= -Access contents of ``Properties/auth.xml`` :: +Access contents of `Properties/auth.xml` :: ${metadata.Properties['auth.xml'].data.find('file').find('bcfg2.key').text} -- cgit v1.2.3-1-g7c22 From 7a884707ec7189f743dbb8de07e957e2f63e02c8 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 9 Nov 2010 00:43:30 +0100 Subject: Removed --- doc/server/plugins/properties.txt | 46 --------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 doc/server/plugins/properties.txt diff --git a/doc/server/plugins/properties.txt b/doc/server/plugins/properties.txt deleted file mode 100644 index fa8bfd884..000000000 --- a/doc/server/plugins/properties.txt +++ /dev/null @@ -1,46 +0,0 @@ -.. -*- mode: rst -*- - -.. _server-plugins-properties: - -========== -Properties -========== - -The Properties plugin is a connector plugin that adds information from -properties files into client metadata instances. - -Enabling Properties -=================== - -First, ``mkdir /var/lib/bcfg2/Properties``. Each property XML file goes -in this directory. Each will automatically be cached by the server, -and reread/reparsed upon changes. Add **Properties** to your ``plugins`` -line in ``/etc/bcfg2.conf``. - -Data Structures -=============== - -Properties adds a new dictionary to client metadata instances that maps -property file names to PropertyFile instances. PropertyFile instances -contain parsed XML data as the "data" attribute. - -Usage -===== - -Specific property files can be referred to in -templates as metadata.Properties[]. The -data attribute is an LXML element object. (Documented -`here `_) - -Currently, no access methods are defined for this data, but as we -formulate common use cases, we will add them to the !PropertyFile class -as methods. This will simplify templates. - -Accessing Properties contest from TGenshi -========================================= - -Access contents of ``Properties/auth.xml`` - -:: - - ${metadata.Properties['auth.xml'].data.find('file').find('bcfg2.key').text} -- cgit v1.2.3-1-g7c22 From 879bcfb87ff4080010a444c6a1ff6e90361648e4 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 9 Nov 2010 00:54:04 +0100 Subject: Guide for web reports moved --- doc/appendix/guides/web-reports.txt | 184 ++++++++++++++++++++++++++++++++++++ doc/reports/index.txt | 1 - doc/reports/install.txt | 183 ----------------------------------- doc/server/plugins/index.txt | 15 ++- 4 files changed, 197 insertions(+), 186 deletions(-) create mode 100644 doc/appendix/guides/web-reports.txt delete mode 100644 doc/reports/install.txt diff --git a/doc/appendix/guides/web-reports.txt b/doc/appendix/guides/web-reports.txt new file mode 100644 index 000000000..9eadfb678 --- /dev/null +++ b/doc/appendix/guides/web-reports.txt @@ -0,0 +1,184 @@ +.. -*- mode: rst -*- + +.. _EPEL: http://fedoraproject.org/wiki/EPEL + +.. This is combination of the Ubuntu guide and the Centos guide for + installing the web reports. + +.. _web-reports: + +================================== +Dynamic (web) Reports installation +================================== + +The first step is to install the needed software components like the +Django framework and the database (SQlite2). All packages for Fedora +are in the Fedora Package Collection or in EPEL_ for CentOS/RHEL:: + + [root@system01 ~]# yum -y install Django python-simplejson python-sqlite2 + +Of course is a web server needed as well:: + + [root@system01 ~]# yum -y install httpd mod_python + +The same packages are needed for Ubuntu systems:: + + [root@system01 ~]# aptitude install python-django apache2 libapache2-mod-python + +Now we need to create the sqlite database. Use the following command on +Fedora, CentOS, or RHEL.:: + + [root@system01 ~]# python /usr/lib/python2.4/site-packages/Bcfg2/Server/Reports/manage.py syncdb + Creating table auth_permission + Creating table auth_group + Creating table auth_user + Creating table auth_message + Creating table django_content_type + Creating table django_session + Creating table django_site + Creating table django_admin_log + Creating table reports_client + Creating table reports_ping + Creating table reports_interaction + Creating table reports_reason + Creating table reports_entries + Creating table reports_entries_interactions + Creating table reports_performance + Creating table reports_internaldatabaseversion + + 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.Permission model + Installing index for auth.Message model + Installing index for admin.LogEntry model + Installing index for reports.Client model + Installing index for reports.Ping model + Installing index for reports.Interaction model + Installing index for reports.Entries model + Installing index for reports.Entries_interactions model + +.. note:: There are different versions of Python available. If you are + unsure about your installed version use the following line instead of + the line above.:: + + [root@system01 ~]# PYVER=`python -c 'import sys;print(sys.version[0:3])'`; python /usr/lib/python$PYVER/site-packages/Bcfg2/site-packages/Bcfg2/Server/Reports/manage.py syncdb + +The path on Ubuntu systems is different. Please use the same path as shown +in the following command to execute the script on an Ubuntu machine in +the next steps:: + + [root@system01 ~]# python /usr/share/pyshared/Bcfg2/Server/Reports/manage.py syncdb + Creating table auth_permission + Creating table auth_group + Creating table auth_user + Creating table auth_message + Creating table django_content_type + Creating table django_session + Creating table django_site + Creating table django_admin_log + Creating table reports_client + Creating table reports_ping + Creating table reports_interaction + Creating table reports_reason + Creating table reports_entries + Creating table reports_entries_interactions + Creating table reports_performance + Creating table reports_internaldatabaseversion + + 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.Permission model + Installing index for auth.Message model + Installing index for admin.LogEntry model + Installing index for reports.Client model + Installing index for reports.Ping model + Installing index for reports.Interaction model + Installing index for reports.Entries model + Installing index for reports.Entries_interactions model + +The server should be tested to make sure that there are no mistakes:: + + [root@system01 ~]# python /usr/lib/python2.6/site-packages/Bcfg2/Server/Reports/manage.py testserver + Creating test database... + Creating table auth_permission + Creating table auth_group + Creating table auth_user + Creating table auth_message + Creating table django_content_type + Creating table django_session + Creating table django_site + Creating table django_admin_log + Creating table reports_client + Creating table reports_ping + Creating table reports_interaction + Creating table reports_reason + Creating table reports_entries + Creating table reports_entries_interactions + Creating table reports_performance + Creating table reports_internaldatabaseversion + Installing index for auth.Permission model + Installing index for auth.Message model + Installing index for admin.LogEntry model + Installing index for reports.Client model + Installing index for reports.Ping model + Installing index for reports.Interaction model + Installing index for reports.Entries model + Installing index for reports.Entries_interactions model + Validating models... + 0 errors found + + Django version 1.1.1, using settings 'Reports.settings' + Development server is running at http://127.0.0.1:8000/ + Quit the server with CONTROL-C. + +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,Packages,Probes,Rules,SSHbase + +Start/restart the Bcfg2 server:: + + [root@system01 ~]# /etc/init.d/bcfg2-server restart + +Run the Bcfg2 client in order to populate the statistics database +(this run should take a bit longer since you are uploading the client +statistics to the database). + +Download the static reports content:: + + [root@system01 ~]# cd /var/www/ + [root@system01 ~]# svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2/reports + +Configure Apache using :ref:`dynamic-http-install` as a guide + +Copy server/statistics sections of ``bcfg2.conf`` to +``/etc/bcfg2-web.conf`` (make sure it is world-readable). You should +then have something like this:: + + [server] + repository = /var/lib/bcfg2 + plugins = Base,Bundler,Cfg,DBStats,Metadata,Packages,Probes,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. + #/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 + +Restart apache and point a browser to your Bcfg2 server. + +If using sqlite be sure the sql database file and directory containing the +database are writable to apache. diff --git a/doc/reports/index.txt b/doc/reports/index.txt index bef686305..1360d5ffd 100644 --- a/doc/reports/index.txt +++ b/doc/reports/index.txt @@ -24,6 +24,5 @@ uses django and a database backend. .. toctree:: :maxdepth: 2 - install static dynamic diff --git a/doc/reports/install.txt b/doc/reports/install.txt deleted file mode 100644 index 80f9342ae..000000000 --- a/doc/reports/install.txt +++ /dev/null @@ -1,183 +0,0 @@ -.. -*- mode: rst -*- - -.. _EPEL: http://fedoraproject.org/wiki/EPEL - -.. This is combination of the Ubuntu guide and the Centos guide for - installing the web reports. - -.. _server-reports-install: - -===================== -Dynamic (web) Reports -===================== - -The first step is to install the needed software components like the -Django framework and the database (SQlite2). All packages for Fedora -are in the Fedora Package Collection or in EPEL_ for CentOS/RHEL:: - - [root@system01 ~]# yum -y install Django python-simplejson python-sqlite2 - -Of course is a web server needed as well:: - - [root@system01 ~]# yum -y install httpd mod_python - -The same packages are needed for Ubuntu systems:: - - [root@system01 ~]# aptitude install python-django apache2 libapache2-mod-python - -Now we need to create the sqlite database. Use the following command on -Fedora, CentOS, or RHEL.:: - - [root@system01 ~]# python /usr/lib/python2.4/site-packages/Bcfg2/Server/Reports/manage.py syncdb - Creating table auth_permission - Creating table auth_group - Creating table auth_user - Creating table auth_message - Creating table django_content_type - Creating table django_session - Creating table django_site - Creating table django_admin_log - Creating table reports_client - Creating table reports_ping - Creating table reports_interaction - Creating table reports_reason - Creating table reports_entries - Creating table reports_entries_interactions - Creating table reports_performance - Creating table reports_internaldatabaseversion - - 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.Permission model - Installing index for auth.Message model - Installing index for admin.LogEntry model - Installing index for reports.Client model - Installing index for reports.Ping model - Installing index for reports.Interaction model - Installing index for reports.Entries model - Installing index for reports.Entries_interactions model - -.. note:: There are different versions of Python available. If you are - unsure about your installed version use the following line instead of - the line above.:: - - [root@system01 ~]# PYVER=`python -c 'import sys;print(sys.version[0:3])'`; python /usr/lib/python$PYVER/site-packages/Bcfg2/site-packages/Bcfg2/Server/Reports/manage.py syncdb - -The path on Ubuntu systems is different. Please use the same path as shown -in the following command to execute the script on an Ubuntu machine in -the next steps:: - - [root@system01 ~]# python /usr/share/pyshared/Bcfg2/Server/Reports/manage.py syncdb - Creating table auth_permission - Creating table auth_group - Creating table auth_user - Creating table auth_message - Creating table django_content_type - Creating table django_session - Creating table django_site - Creating table django_admin_log - Creating table reports_client - Creating table reports_ping - Creating table reports_interaction - Creating table reports_reason - Creating table reports_entries - Creating table reports_entries_interactions - Creating table reports_performance - Creating table reports_internaldatabaseversion - - 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.Permission model - Installing index for auth.Message model - Installing index for admin.LogEntry model - Installing index for reports.Client model - Installing index for reports.Ping model - Installing index for reports.Interaction model - Installing index for reports.Entries model - Installing index for reports.Entries_interactions model - -The server should be tested to make sure that there are no mistakes:: - - [root@system01 ~]# python /usr/lib/python2.6/site-packages/Bcfg2/Server/Reports/manage.py testserver - Creating test database... - Creating table auth_permission - Creating table auth_group - Creating table auth_user - Creating table auth_message - Creating table django_content_type - Creating table django_session - Creating table django_site - Creating table django_admin_log - Creating table reports_client - Creating table reports_ping - Creating table reports_interaction - Creating table reports_reason - Creating table reports_entries - Creating table reports_entries_interactions - Creating table reports_performance - Creating table reports_internaldatabaseversion - Installing index for auth.Permission model - Installing index for auth.Message model - Installing index for admin.LogEntry model - Installing index for reports.Client model - Installing index for reports.Ping model - Installing index for reports.Interaction model - Installing index for reports.Entries model - Installing index for reports.Entries_interactions model - Validating models... - 0 errors found - - Django version 1.1.1, using settings 'Reports.settings' - Development server is running at http://127.0.0.1:8000/ - Quit the server with CONTROL-C. - -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,Packages,Probes,Rules,SSHbase - -Start/restart the Bcfg2 server:: - - [root@system01 ~]# /etc/init.d/bcfg2-server restart - -Run the Bcfg2 client in order to populate the statistics database -(this run should take a bit longer since you are uploading the client -statistics to the database). - -Download the static reports content:: - - [root@system01 ~]# cd /var/www/ - [root@system01 ~]# svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2/reports - -Configure Apache using :ref:`dynamic-http-install` as a guide - -Copy server/statistics sections of ``bcfg2.conf`` to -``/etc/bcfg2-web.conf`` (make sure it is world-readable). You should -then have something like this:: - - [server] - repository = /var/lib/bcfg2 - plugins = Base,Bundler,Cfg,DBStats,Metadata,Packages,Probes,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. - #/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 - -Restart apache and point a browser to your Bcfg2 server. - -If using sqlite be sure the sql database file and directory containing the database are writable to apache. diff --git a/doc/server/plugins/index.txt b/doc/server/plugins/index.txt index 126331325..e561722cf 100644 --- a/doc/server/plugins/index.txt +++ b/doc/server/plugins/index.txt @@ -30,6 +30,18 @@ http://trac.mcs.anl.gov/projects/bcfg2/browser/trunk/bcfg2/src/lib/Server/Plugin .. _Bcfg2 repository: http://trac.mcs.anl.gov/projects/bcfg2/browser/trunk/bcfg2/src/lib/Server/Plugins. +Connectors +---------- + +.. toctree:: + :maxdepth: 2 + :glob: + + connectors/* + +Each of these plugins has a corresponding subdirectory with the same +name in the Bcfg2 repository. + Metadata (Grouping) ------------------- @@ -78,7 +90,7 @@ Statistics Plugins statistics/* DBStats can be enabled by adding it to the plugins line in -``/etc/bcfg2.conf``. +`/etc/bcfg2.conf`. Version Plugins --------------- @@ -103,5 +115,4 @@ More details can be found in :ref:`server-plugins-plugin-roles` plugin-roles probes/index - properties trigger -- cgit v1.2.3-1-g7c22 From 01f6e4c0ddbc2f1fa01ba464a563d17eb4540966 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 9 Nov 2010 01:08:24 +0100 Subject: Attempt to build a rpm pkg list with yum --- tools/create-rpm-pkglist.py | 124 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 tools/create-rpm-pkglist.py diff --git a/tools/create-rpm-pkglist.py b/tools/create-rpm-pkglist.py new file mode 100644 index 000000000..e88de4191 --- /dev/null +++ b/tools/create-rpm-pkglist.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# +# Copyright (c) 2010 Fabian Affolter, Bernewireless.net. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: + +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the Bernewireless nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Author: Fabian Affolter +# + +import yum +import os +import sys +from lxml import etree +from optparse import OptionParser + +__author__ = 'Fabian Affolter ' +__version__ = '0.1' + +def retrievePackages(): + """Getting the installed packages with yum.""" + yb = yum.YumBase() + yb.conf.cache = os.geteuid() != 1 + pl = yb.doPackageLists('installed') + pkglist = [] + for pkg in sorted(pl.installed): + pkgdata = pkg.name, pkg.version + pkglist.append(pkgdata) + + return pkglist + +def parse_command_line_parameters(): + """Parses command line arguments.""" + usage = "usage: %prog [options]" + version = 'Version: %prog ' + __version__ + parser = OptionParser(usage, version=version) + parser.add_option("-s", "--show", action="store_true", + help="Prints the result to STOUT") + parser.add_option("-v", "--pkgversion", action="store_true", + help="Include Package version") + parser.add_option("-f", "--filename", dest="filename", + type="string", + metavar="FILE", default="packages.xml", + help="Write the output to an XML FILE" ) + + (options, args) = parser.parse_args() + num_args = 1 + + return options, args + +def indent(elem, level=0): + """Helps clean up the XML.""" + # Stolen from http://effbot.org/zone/element-lib.htm + i = "\n" + level*" " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + " " + for e in elem: + indent(e, level+1) + if not e.tail or not e.tail.strip(): + e.tail = i + " " + if not e.tail or not e.tail.strip(): + e.tail = i + else: + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i + +def transformXML(): + """Transform the package list to an XML file.""" + packagelist = retrievePackages() + root = etree.Element("PackageList") + for i,j in packagelist: + root.append( etree.Element("Package", name = i, version = j) ) + #Print the content + #print(etree.tostring(root, pretty_print=True)) + tree = etree.ElementTree(root) + return tree + +def main(): + options, args = parse_command_line_parameters() + filename = options.filename + packagelist = transformXML() + + if options.show == True: + tree = etree.parse(filename) + for node in tree.findall("//Package"): + print node.attrib["name"] + indent(packagelist.getroot()) + packagelist.write(filename, encoding="utf-8") + + if options.pkgversion == True: + tree = etree.parse(filename) + for node in tree.findall("//Package"): + print "%s-%s" % (node.attrib["name"], node.attrib["version"]) + +#FIXME : This should be changed to the standard way of optparser +#FIXME : Make an option available to strip the version number of the pkg + if options.pkgversion == None and options.show == None: + indent(packagelist.getroot()) + packagelist.write(filename, encoding="utf-8") + +if __name__ == "__main__": + main() -- cgit v1.2.3-1-g7c22 From 6bbcc73c5b3397ff42d51e8db5e5cba67dc24c35 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 9 Nov 2010 01:14:50 +0100 Subject: Manual added and minor layout changes README --- README | 15 +++++++-------- doc/bcfg2.pdf | Bin 0 -> 1387540 bytes 2 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 doc/bcfg2.pdf diff --git a/README b/README index beb0d3303..7368776a4 100644 --- a/README +++ b/README @@ -24,24 +24,23 @@ For details about the installation of Bcfg2 please refer to the following pages in the Bcfg2 wiki. * Prerequisites: http://bcfg2.org/wiki/Prereqs -* Download: http://bcfg2.org/wiki/Download -* Installation: http://bcfg2.org/wiki/Install +* Download: http://bcfg2.org/wiki/Download +* Installation: http://bcfg2.org/wiki/Install Need help --------- -* FAQ: http://bcfg2.org/wiki/FAQ -* IRC: #bcfg2 on chat.freenode.net +* FAQ: http://bcfg2.org/wiki/FAQ +* IRC: #bcfg2 on chat.freenode.net * Mailing list: https://lists.mcs.anl.gov/mailman/listinfo/bcfg-dev -* Bug tracker: http://bcfg2.org/report +* Bug tracker: http://bcfg2.org/report Documentation ------------- -A lot of documentation is available in the Bcfg2 wiki and the Bcfg2 -manual. +A lot of documentation is available in the Bcfg2 manual and the Bcfg2 wiki. -Wiki: http://bcfg2.org/wiki/ +Wiki: http://bcfg2.org/wiki/ Manual: http://docs.bcfg2.org/ diff --git a/doc/bcfg2.pdf b/doc/bcfg2.pdf new file mode 100644 index 000000000..4a34a5352 Binary files /dev/null and b/doc/bcfg2.pdf differ -- cgit v1.2.3-1-g7c22 From 66a3fe52b72595f50449fd1ccecee7224479c082 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 10 Nov 2010 18:01:58 -0600 Subject: doc: Fix broken troubleshooting link Signed-off-by: Sol Jerome --- doc/troubleshooting.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/troubleshooting.txt b/doc/troubleshooting.txt index ef96c30bb..cce9c3d78 100644 --- a/doc/troubleshooting.txt +++ b/doc/troubleshooting.txt @@ -1,6 +1,6 @@ .. -*- mode: rst -*- -.. _unsorted-troubleshooting: +.. _troubleshooting: =============== Troubleshooting -- cgit v1.2.3-1-g7c22 From 010e4a6c963f5c8983cd1c948cb988d4d2e001fe Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 15 Nov 2010 12:19:37 -0600 Subject: export.py: Update export script for use with git Signed-off-by: Sol Jerome --- tools/export.py | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/tools/export.py b/tools/export.py index fcb9e5a4d..6f46e1011 100755 --- a/tools/export.py +++ b/tools/export.py @@ -10,20 +10,14 @@ from subprocess import Popen, PIPE import sys pkgname = 'bcfg2' -repo = 'https://svn.mcs.anl.gov/repos/bcfg' +ftphost = 'terra.mcs.anl.gov' +ftpdir = '/mcs/ftp/pub/bcfg' version = raw_input("Please enter the version you are tagging (e.g. 1.0.0): ") -tagstr = version.replace('.', '_') - -expath = "/tmp/%s-%s/" % (pkgname, version) -tarname = "/tmp/%s-%s.tar.gz" % (pkgname, version) +tarname = '/tmp/%s-%s.tar.gz' % (pkgname, version) def run(command): return Popen(command, shell=True, stdout=PIPE).communicate() -#FIXME: someone please figure out how to do this using the python svn bindings -cmd = "svn info | grep URL | awk '{print $2}'" -url = run(cmd)[0].strip() - # update the version majorver = version[:5] minorver = version[5:] @@ -65,20 +59,22 @@ for line in fileinput.input('solaris/Makefile', inplace=1): if line.startswith('VERS='): line = line.replace(line, 'VERS=%s-1\n' % version) sys.stdout.write(line) + # tag the release -cmd = "svn ci -m 'Version bump to %s'" % version +#FIXME: do this using python-dulwich +cmd = "git commit -asm 'Version bump to %s'" % version output = run(cmd)[0].strip() -cmd = "svn copy %s %s/tags/%s_%s -m 'tagged %s release'" % \ - (url, repo, pkgname, tagstr, version) +# NOTE: This will use the default email address key. If you want to sign the tag +# using a different key, you will need to set 'signingkey' to the proper +# value in the [user] section of your git configuration. +cmd = "git tag -s v%s -m 'tagged %s release'" % (version, version) output = run(cmd)[0].strip() -cmd = "svn export %s" % expath -output = run(cmd)[0].strip() -cmd = "svn log -v %s/tags/%s_%s > %sChangelog" % \ - (repo, pkgname, tagstr, expath) -output = run(cmd)[0].strip() -cmd = "tar czf %s %s" % (tarname, expath) +cmd = "git archive --format=tar --prefix=%s-%s v%s | gzip > %s" % \ + (pkgname, version, version, tarname) output = run(cmd)[0].strip() cmd = "gpg --armor --output %s.gpg --detach-sig %s" % (tarname, tarname) output = run(cmd)[0].strip() -cmd = "scp %s* terra.mcs.anl.gov:/mcs/ftp/pub/bcfg" % tarname + +# upload release to ftp +cmd = "scp %s* terra.mcs.anl.gov:/mcs/ftp/pub/bcfg/" % tarname output = run(cmd)[0].strip() -- cgit v1.2.3-1-g7c22 From 5abb142f341b51fb03f5c57434b977beecb4b27a Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 15 Nov 2010 13:34:23 -0600 Subject: export.py: Fix archive creation bug in export script Signed-off-by: Sol Jerome --- tools/export.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/export.py b/tools/export.py index 6f46e1011..c64ff90a2 100755 --- a/tools/export.py +++ b/tools/export.py @@ -69,7 +69,7 @@ output = run(cmd)[0].strip() # value in the [user] section of your git configuration. cmd = "git tag -s v%s -m 'tagged %s release'" % (version, version) output = run(cmd)[0].strip() -cmd = "git archive --format=tar --prefix=%s-%s v%s | gzip > %s" % \ +cmd = "git archive --format=tar --prefix=%s-%s/ v%s | gzip > %s" % \ (pkgname, version, version, tarname) output = run(cmd)[0].strip() cmd = "gpg --armor --output %s.gpg --detach-sig %s" % (tarname, tarname) -- cgit v1.2.3-1-g7c22 From b33ebf356cd51456c7a09f341924af5fe10f88b9 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 15 Nov 2010 15:34:33 -0600 Subject: Packages: Pylint/PEP8 fixes Signed-off-by: Sol Jerome --- src/lib/Server/Plugins/Packages.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/lib/Server/Plugins/Packages.py b/src/lib/Server/Plugins/Packages.py index 194330723..ee21fb622 100644 --- a/src/lib/Server/Plugins/Packages.py +++ b/src/lib/Server/Plugins/Packages.py @@ -76,8 +76,8 @@ def _fetch_url(url): class Source(object): basegroups = [] - def __init__(self, basepath, url, version, arches, components, groups, rawurl, - blacklist, whitelist, recommended): + def __init__(self, basepath, url, version, arches, components, groups, + rawurl, blacklist, whitelist, recommended): self.basepath = basepath self.version = version self.components = components @@ -112,7 +112,8 @@ class Source(object): try: self.read_files() except: - logger.error("Packages: File read failed; falling back to file download") + logger.error("Packages: File read failed; " + "falling back to file download") should_download = True if should_download or force_update: @@ -389,7 +390,7 @@ class APTSource(Source): if self.recommended: depfnames = ['Depends', 'Pre-Depends', 'Recommends'] else: - depfnames = ['Depends', 'Pre-Depends'] + depfnames = ['Depends', 'Pre-Depends'] for fname in self.files: if not self.rawurl: barch = [x for x in fname.split('@') if x.startswith('binary-')][0][7:] @@ -504,7 +505,6 @@ class PACSource(Source): raise Exception("PACSource : RAWUrl not supported (yet)") urls = property(get_urls) - def read_files(self): bdeps = dict() bprov = dict() @@ -512,7 +512,7 @@ class PACSource(Source): if self.recommended: depfnames = ['Depends', 'Pre-Depends', 'Recommends'] else: - depfnames = ['Depends', 'Pre-Depends'] + depfnames = ['Depends', 'Pre-Depends'] for fname in self.files: if not self.rawurl: @@ -535,8 +535,8 @@ class PACSource(Source): for tarinfo in tar: if tarinfo.isdir(): - self.pkgnames.add(tarinfo.name.rsplit("-",2)[0]) - print "added : " + tarinfo.name.rsplit("-",2)[0] + self.pkgnames.add(tarinfo.name.rsplit("-", 2)[0]) + print "added : " + tarinfo.name.rsplit("-", 2)[0] tar.close() self.deps['global'] = dict() @@ -676,7 +676,7 @@ class Packages(Bcfg2.Server.Plugin.Plugin, # do while unclassified or vpkgs or both or pkgs while unclassified or pkgs or both or final_pass: #print len(unclassified), len(pkgs), len(both), len(vpkgs), final_pass - if really_done: + if really_done: break if len(unclassified) + len(pkgs) + len(both) == 0: # one more pass then exit @@ -760,7 +760,9 @@ class Packages(Bcfg2.Server.Plugin.Plugin, meta - client metadata instance structures - a list of structure-stage entry combinations ''' - if self.disableResolver: return # Config requests no resolver + if self.disableResolver: + # Config requests no resolver + return initial = set([pkg.get('name') for struct in structures \ for pkg in struct.findall('Package') + @@ -857,7 +859,8 @@ class Packages(Bcfg2.Server.Plugin.Plugin, cachefiles = [] for source in self.sources: cachefiles.append(source.cachefile) - if not self.disableMetaData: source.setup_data(force_update) + if not self.disableMetaData: + source.setup_data(force_update) self.sentinels.update(source.basegroups) for cfile in glob.glob("%s/cache-*" % self.cachepath): if cfile not in cachefiles: -- cgit v1.2.3-1-g7c22 From a58895db0f037bf3a28e33e950a3cfc3d22f45ff Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 15 Nov 2010 17:05:31 -0600 Subject: redhat: Sync some upstream changes for the spec file Signed-off-by: Sol Jerome --- misc/bcfg2.spec | 4 ++-- redhat/bcfg2.spec.in | 32 ++++++++++---------------------- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/misc/bcfg2.spec b/misc/bcfg2.spec index 8e77ad908..30fadf206 100644 --- a/misc/bcfg2.spec +++ b/misc/bcfg2.spec @@ -168,8 +168,8 @@ deployment strategies. %{_sbindir}/bcfg2 %{python_sitelib}/Bcfg2/*.py* %{python_sitelib}/Bcfg2/Client/* -%{_mandir}/man1/* -%{_mandir}/man5/* +{_mandir}/man1/bcfg2.1* +%{_mandir}/man5/bcfg2.conf.5* %{_initrddir}/bcfg2 %config(noreplace) %{_sysconfdir}/default/bcfg2 %{_sysconfdir}/cron.hourly/bcfg2 diff --git a/redhat/bcfg2.spec.in b/redhat/bcfg2.spec.in index 40f2d6df2..9378e9267 100644 --- a/redhat/bcfg2.spec.in +++ b/redhat/bcfg2.spec.in @@ -1,4 +1,6 @@ -# This file is licensed under the GPL +%if ! (0%{?fedora} > 12 || 0%{?rhel} > 5) +%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} +%endif Name: @PACKAGE@ Version: @VERSION@ @@ -7,23 +9,15 @@ Release: @RELEASE@ %define __python python %{!?py_ver: %define py_ver %(%{__python} -c 'import sys;print(sys.version[0:3])')} %define pythonversion %{py_ver} -%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} %{!?_initrddir: %define _initrddir %{_sysconfdir}/rc.d/init.d} -# Most rpm-based distributions include the lxml package a 'python-lxml', -# but some distributions and some people who roll their own lxml packages -# call it just 'lxml'. We'll try to catch both. -%define dfl_lxml python-lxml -%define alt_lxml lxml -%define lxmldep %(rpm -q %{alt_lxml} 2>&1 > /dev/null && echo %{alt_lxml} || echo %{dfl_lxml}) - Summary: Configuration management system + Group: Applications/System License: BSD URL: http://trac.mcs.anl.gov/projects/bcfg2 Source0: %{name}-%{version}-%{release}.tar.gz -BuildRoot: %{_builddir}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildArch: noarch %if 0%{?fedora} >= 8 @@ -35,7 +29,7 @@ BuildRequires: python-setuptools %if "%{py_ver}" == "2.4" Requires: python-elementtree %else if "%{py_ver}" < "2.5" -Requires: %{lxmldep} >= 0.9 +Requires: python-lxml %endif Requires: initscripts Requires(post): /sbin/chkconfig @@ -43,7 +37,6 @@ Requires(preun): /sbin/chkconfig Requires(preun): /sbin/service Requires(postun): /sbin/service - %description Bcfg2 helps system administrators produce a consistent, reproducible, and verifiable description of their environment, and offers @@ -77,7 +70,7 @@ Requires: bcfg2 = %{version}-%{release} %if "%{py_ver}" < "2.6" Requires: python-ssl %endif -Requires: %{lxmldep} >= 0.9 +Requires: python-lxml >= 0.9 Requires: /usr/bin/openssl Requires: gamin-python Requires(post): /sbin/chkconfig @@ -93,6 +86,7 @@ Configuration management server # fixup some paths %{__perl} -pi -e 's@/etc/default@%{_sysconfdir}/sysconfig@g' debian/bcfg2.init +%{__perl} -pi -e 's@/etc/default@%{_sysconfdir}/sysconfig@g' debian/bcfg2-server.init %{__perl} -pi -e 's@/etc/default@%{_sysconfdir}/sysconfig@g' tools/bcfg2-cron %{__perl} -pi -e 's@/usr/lib/bcfg2@%{_libexecdir}@g' debian/bcfg2.cron.daily @@ -111,10 +105,9 @@ done %build %{__python} -c 'import setuptools; execfile("setup.py")' build - %install rm -rf %{buildroot} -%{__python} -c 'import setuptools; execfile("setup.py")' install --skip-build --root %{buildroot} --prefix=/usr +%{__python} -c 'import setuptools; execfile("setup.py")' install --skip-build --root %{buildroot} mkdir -p %{buildroot}%{_sbindir} mkdir -p %{buildroot}%{_initrddir} @@ -200,7 +193,6 @@ fi %dir %{_var}/cache/bcfg2 - %files server %defattr(-,root,root,-) @@ -220,11 +212,7 @@ fi %{_sbindir}/bcfg2-reports %{_sbindir}/bcfg2-server -%{_mandir}/man8/bcfg2-admin.8* -%{_mandir}/man8/bcfg2-build-reports.8* -%{_mandir}/man8/bcfg2-info.8* -%{_mandir}/man8/bcfg2-repo-validate.8* -%{_mandir}/man8/bcfg2-server.8* +%{_mandir}/man8/*.8* %dir %{_var}/lib/bcfg2 -- cgit v1.2.3-1-g7c22 From 3cc5a7e114a5e38b22776993271a8f0a2f54a8e8 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 15 Nov 2010 19:42:04 -0600 Subject: redhat: Fix Makefile so that building from git works Signed-off-by: Sol Jerome --- redhat/Makefile | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/redhat/Makefile b/redhat/Makefile index bf7c69591..7533b98da 100644 --- a/redhat/Makefile +++ b/redhat/Makefile @@ -11,15 +11,15 @@ .PHONY: cvs-export git-export svn-export test-export .PHONY: cvs-clean git-clean svn-clean test-clean -SCM_TYPE := svn +SCM_TYPE := git SCM_PATH := ../ #CVSROOT := $(shell cat 2>/dev/null src/CVS/Root) -SVN_PATH := $(shell svn info ${SCM_PATH} 2>/dev/null | awk '/^URL:/{print $$2}') -SVN_REV := $(shell svn info ${SVN_PATH} 2>/dev/null | awk '/^Last Changed Rev:/{print $$4}') +#SVN_PATH := $(shell svn info ${SCM_PATH} 2>/dev/null | awk '/^URL:/{print $$2}') +#SVN_REV := $(shell svn info ${SVN_PATH} 2>/dev/null | awk '/^Last Changed Rev:/{print $$4}') PACKAGE := $(shell cat PACKAGE) VERSION := $(shell cat VERSION) -RELEASE := $(shell cat RELEASE)r${SVN_REV} +RELEASE := $(shell cat RELEASE) BASE_VER := ${VERSION}-${RELEASE} CURRENT_PACKAGE := $(PACKAGE)-$(BASE_VER) TARBALL := $(CURRENT_PACKAGE).tar @@ -80,8 +80,8 @@ buildtargz: buildtarball # This target copies files that are not in svn into the build tree prepbuildtarball: $(SCM_TYPE)-export - @cp ${PACKAGE}.spec ./build/${CURRENT_PACKAGE}/redhat && \ - cp -R scripts ./build/${CURRENT_PACKAGE}/redhat + @cp ${PACKAGE}.spec ./build/${CURRENT_PACKAGE}/redhat/ && \ + cp -R scripts ./build/${CURRENT_PACKAGE}/redhat/ specfile: $(PACKAGE).spec @@ -113,11 +113,8 @@ test-export: builddir --file - git-export: builddir prepclean - @git-tar-tree HEAD $(PACKAGE)-$(VERSION) \ - | tar \ - --extract \ - --directory ./build/ \ - --file - + @cd ../ && git archive --format=tar --prefix=$(CURRENT_PACKAGE)/ HEAD \ + | (cd redhat/build && tar xf -) git-clean: @: -- cgit v1.2.3-1-g7c22 From 0a7ab577370872ebab45d21bf25d31a1bae9e3b9 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 15 Nov 2010 20:39:44 -0600 Subject: doc: Fix broken plugin links Signed-off-by: Sol Jerome --- doc/server/configurationentries.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/server/configurationentries.txt b/doc/server/configurationentries.txt index 1146a51c6..8741e56f5 100644 --- a/doc/server/configurationentries.txt +++ b/doc/server/configurationentries.txt @@ -5,10 +5,10 @@ .. _Base: plugins/structures/base .. _Bundler: plugins/structures/bundler -.. _Cfg: plugins/generators/cfg +.. _Cfg: plugins/generators/cfg.html .. _TGenshi: plugins/generators/tgenshi -.. _TCheetah: plugins/generators/tcheetah -.. _Rules: plugins/generators/rules +.. _TCheetah: plugins/generators/tcheetah.html +.. _Rules: plugins/generators/rules.html .. _server-configurationentries: -- cgit v1.2.3-1-g7c22 From 26d630dd735d76e947289ca1ff1ed69ca1e465b4 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 16 Nov 2010 11:34:03 -0600 Subject: SSLCA: PEP8 fixes Signed-off-by: Sol Jerome --- src/lib/Server/Plugins/SSLCA.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/lib/Server/Plugins/SSLCA.py b/src/lib/Server/Plugins/SSLCA.py index 0dc448e69..4125cd498 100644 --- a/src/lib/Server/Plugins/SSLCA.py +++ b/src/lib/Server/Plugins/SSLCA.py @@ -7,6 +7,7 @@ import os from subprocess import Popen, PIPE, STDOUT from ConfigParser import ConfigParser + class SSLCA(Bcfg2.Server.Plugin.GroupSpool): """ The SSLCA generator handles the creation and @@ -34,9 +35,9 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): ident = self.handles[event.requestID] + event.filename else: ident = self.handles[event.requestID][:-1] - + fname = "".join([ident, '/', event.filename]) - + if event.filename.endswith('.xml'): if action in ['exists', 'created', 'changed']: if event.filename.endswith('key.xml'): @@ -89,12 +90,12 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): of a new key if one doesn't exist. """ # set path type and permissions, otherwise bcfg2 won't bind the file - permdata = {'owner':'root', - 'group':'root', - 'type':'file', - 'perms':'644'} + permdata = {'owner': 'root', + 'group': 'root', + 'type': 'file', + 'perms': '644'} [entry.attrib.__setitem__(key, permdata[key]) for key in permdata] - + # check if we already have a hostfile, or need to generate a new key # TODO: verify key fits the specs path = entry.get('name') @@ -125,10 +126,10 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): of a new cert if one doesn't exist. """ # set path type and permissions, otherwise bcfg2 won't bind the file - permdata = {'owner':'root', - 'group':'root', - 'type':'file', - 'perms':'644'} + permdata = {'owner': 'root', + 'group': 'root', + 'type': 'file', + 'perms': '644'} [entry.attrib.__setitem__(key, permdata[key]) for key in permdata] path = entry.get('name') @@ -157,7 +158,7 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): """ chaincert = self.CAs[self.cert_specs[entry.get('name')]['ca']].get('chaincert') cert = self.data + filename - cmd = "openssl verify -CAfile %s %s" % (chaincert, cert) + cmd = "openssl verify -CAfile %s %s" % (chaincert, cert) res = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT).stdout.read() if res == cert + ": OK\n": return True @@ -225,7 +226,7 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): cp.write(conffile) conffile.close() return conffile.name - + def build_request(self, key_filename, req_config, entry): """ creates the certificate request @@ -236,4 +237,3 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): cmd = "openssl req -new -config %s -days %s -key %s -text -out %s" % (req_config, days, key, req) res = Popen(cmd, shell=True, stdout=PIPE).stdout.read() return req - -- cgit v1.2.3-1-g7c22 From 117f6d8aef51803a22af3687381d8e94ebb67730 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 16 Nov 2010 13:55:01 -0600 Subject: gentoo: Sync with latest ebuild from upstream Signed-off-by: Sol Jerome --- gentoo/bcfg2-1.0_pre1.ebuild | 71 -------------------------------------------- gentoo/bcfg2-1.0_pre2.ebuild | 56 ---------------------------------- gentoo/bcfg2-1.0_pre3.ebuild | 55 ---------------------------------- gentoo/bcfg2-1.1.0rc1.ebuild | 54 --------------------------------- gentoo/bcfg2-1.1.1.ebuild | 60 +++++++++++++++++++++++++++++++++++++ 5 files changed, 60 insertions(+), 236 deletions(-) delete mode 100644 gentoo/bcfg2-1.0_pre1.ebuild delete mode 100644 gentoo/bcfg2-1.0_pre2.ebuild delete mode 100644 gentoo/bcfg2-1.0_pre3.ebuild delete mode 100644 gentoo/bcfg2-1.1.0rc1.ebuild create mode 100644 gentoo/bcfg2-1.1.1.ebuild diff --git a/gentoo/bcfg2-1.0_pre1.ebuild b/gentoo/bcfg2-1.0_pre1.ebuild deleted file mode 100644 index 494588d0e..000000000 --- a/gentoo/bcfg2-1.0_pre1.ebuild +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 1999-2004 Gentoo Technologies, Inc. -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -DESCRIPTION="Bcfg2 is a configuration management tool. Package includes client -and server." -HOMEPAGE="http://trac.mcs.anl.gov/projects/bcfg2" - -# handle the "pre" case -MY_P="${P/_/}" -SRC_URI="ftp://ftp.mcs.anl.gov/pub/bcfg/${MY_P}.tar.gz" -S="${WORKDIR}/${MY_P}" - -LICENSE="BSD" -RESTRICT="mirror" - -SLOT="0" -KEYWORDS="~x86 ~amd64" -IUSE="server" - -DEPEND=" - app-portage/gentoolkit - - || ( >=dev-lang/python-2.5 - ( - >=dev-lang/python-2.3 - || ( dev-python/elementtree dev-python/lxml ) - ) - ) - " - -RDEPEND=" - server? ( - dev-python/pyopenssl - || ( app-admin/gamin app-admin/fam ) - ) - " - -src_compile() { - python setup.py build -} - -src_install() { - python setup.py install \ - --root=${D} \ - --record=PY_SERVER_LIBS \ - --install-scripts /usr/sbin - - # Remove files only necessary for a server installation - if ! use server; then - rm -rf ${D}/usr/sbin/bcfg2-* - rm -rf ${D}/usr/share/bcfg2 - rm -rf ${D}/usr/share/man/man8 - fi - - # Install a server init.d script - if use server; then - newinitd ${FILESDIR}/bcfg2-server.rc bcfg2-server - fi - - insinto /etc - doins ${S}/examples/bcfg2.conf -} - -pkg_postinst () { - depscan.sh -} - -pkg_postrm () { - depscan.sh -} diff --git a/gentoo/bcfg2-1.0_pre2.ebuild b/gentoo/bcfg2-1.0_pre2.ebuild deleted file mode 100644 index dd4eab709..000000000 --- a/gentoo/bcfg2-1.0_pre2.ebuild +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 1999-2009 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit distutils - -DESCRIPTION="Bcfg2 is a configuration management tool." -HOMEPAGE="http://trac.mcs.anl.gov/projects/bcfg2" - -# handle the "pre" case -MY_P="${P/_/}" -SRC_URI="ftp://ftp.mcs.anl.gov/pub/bcfg/${MY_P}.tar.gz" -S="${WORKDIR}/${MY_P}" - -LICENSE="BSD" -SLOT="0" -KEYWORDS="~amd64 ~x86" -IUSE="server" - -DEPEND=">=dev-lang/python-2.5 - dev-python/m2crypto" - -RDEPEND="app-portage/gentoolkit - server? ( - dev-python/lxml - dev-python/pyopenssl - app-admin/gam-server )" - -src_install() { - distutils_src_install --record=PY_SERVER_LIBS --install-scripts /usr/sbin - - # Remove files only necessary for a server installation - if ! use server; then - rm -rf "${D}"/usr/sbin/bcfg2-* - rm -rf "${D}"/usr/share/bcfg2 - rm -rf "${D}"/usr/share/man/man8 - fi - - # Install a server init.d script - if use server; then - newinitd "${FILESDIR}"/bcfg2-server.rc bcfg2-server - fi - - insinto /etc - doins "${S}"/examples/bcfg2.conf -} - -pkg_postinst () { - depscan.sh - use server && einfo "If this is a new installation, you probably need to run: " - use server && einfo " bcfg2-admin init" -} - -pkg_postrm () { - depscan.sh -} diff --git a/gentoo/bcfg2-1.0_pre3.ebuild b/gentoo/bcfg2-1.0_pre3.ebuild deleted file mode 100644 index 6b366dcb0..000000000 --- a/gentoo/bcfg2-1.0_pre3.ebuild +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 1999-2009 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit distutils - -DESCRIPTION="Bcfg2 is a configuration management tool." -HOMEPAGE="http://trac.mcs.anl.gov/projects/bcfg2" - -# handle the "pre" case -MY_P="${P/_/}" -SRC_URI="ftp://ftp.mcs.anl.gov/pub/bcfg/${MY_P}.tar.gz" -S="${WORKDIR}/${MY_P}" - -LICENSE="BSD" -SLOT="1" -KEYWORDS="~amd64 ~x86" -IUSE="server" - -DEPEND=">=dev-lang/python-2.5" - -RDEPEND="app-portage/gentoolkit - || ( dev-python/ssl-py26 >=dev-lang/python-2.6 ) - server? ( - dev-python/lxml - app-admin/gam-server )" - -src_install() { - distutils_src_install --record=PY_SERVER_LIBS --install-scripts /usr/sbin - - # Remove files only necessary for a server installation - if ! use server; then - rm -rf "${D}"/usr/sbin/bcfg2-* - rm -rf "${D}"/usr/share/bcfg2 - rm -rf "${D}"/usr/share/man/man8 - fi - - # Install a server init.d script - if use server; then - newinitd "${FILESDIR}"/bcfg2-server.rc bcfg2-server - fi - - insinto /etc - doins "${S}"/examples/bcfg2.conf -} - -pkg_postinst () { - depscan.sh - use server && einfo "If this is a new installation, you probably need to run: " - use server && einfo " bcfg2-admin init" -} - -pkg_postrm () { - depscan.sh -} diff --git a/gentoo/bcfg2-1.1.0rc1.ebuild b/gentoo/bcfg2-1.1.0rc1.ebuild deleted file mode 100644 index c482a5d70..000000000 --- a/gentoo/bcfg2-1.1.0rc1.ebuild +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 1999-2009 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: $ - -inherit distutils - -DESCRIPTION="Bcfg2 is a configuration management tool." -HOMEPAGE="http://trac.mcs.anl.gov/projects/bcfg2" - -# handle the "pre" case -MY_P="${P/_/}" -SRC_URI="ftp://ftp.mcs.anl.gov/pub/bcfg/${MY_P}.tar.gz" -S="${WORKDIR}/${MY_P}" - -LICENSE="BSD" -SLOT="1" -KEYWORDS="~amd64 ~x86" -IUSE="server" - -DEPEND=">=dev-lang/python-2.5" - -RDEPEND="app-portage/gentoolkit - >=dev-lang/python-2.6 - server? ( - dev-python/lxml - app-admin/gam-server )" - -src_install() { - distutils_src_install --record=PY_SERVER_LIBS --install-scripts /usr/sbin - - # Remove files only necessary for a server installation - if ! use server; then - rm -rf "${D}"/usr/sbin/bcfg2-* - rm -rf "${D}"/usr/share/bcfg2 - rm -rf "${D}"/usr/share/man/man8 - fi - - # Install a server init.d script - if use server; then - newinitd "${FILESDIR}"/bcfg2-server.rc bcfg2-server - fi - - insinto /etc - doins "${S}"/examples/bcfg2.conf -} - -pkg_postinst () { - use server && einfo "If this is a new installation, you probably need to run: " - use server && einfo " bcfg2-admin init" -} - -pkg_postrm () { - python_mod_cleanup -} diff --git a/gentoo/bcfg2-1.1.1.ebuild b/gentoo/bcfg2-1.1.1.ebuild new file mode 100644 index 000000000..6b41c16ea --- /dev/null +++ b/gentoo/bcfg2-1.1.1.ebuild @@ -0,0 +1,60 @@ +# Copyright 1999-2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="3" +PYTHON_DEPEND="2:2.6" +SUPPORT_PYTHON_ABIS="1" +# ssl module required. +RESTRICT_PYTHON_ABIS="2.4 2.5 3.*" + +inherit distutils + +DESCRIPTION="Bcfg2 is a configuration management tool." +HOMEPAGE="http://trac.mcs.anl.gov/projects/bcfg2" + +# handle the "pre" case +MY_P="${P/_/}" +SRC_URI="ftp://ftp.mcs.anl.gov/pub/bcfg/${MY_P}.tar.gz" +S="${WORKDIR}/${MY_P}" + +LICENSE="BSD" +SLOT="0" +KEYWORDS="~amd64 ~x86 ~amd64-linux ~x86-linux ~x64-solaris" +IUSE="server" + +DEPEND="app-portage/gentoolkit + server? ( + dev-python/lxml + app-admin/gam-server )" +RDEPEND="${DEPEND}" + +PYTHON_MODNAME="Bcfg2" + +src_install() { + distutils_src_install --record=PY_SERVER_LIBS --install-scripts "${EPREFIX}"/usr/sbin + + # Remove files only necessary for a server installation + if ! use server; then + rm -rf "${ED}"usr/sbin/bcfg2-* + rm -rf "${ED}"usr/share/bcfg2 + rm -rf "${ED}"usr/share/man/man8 + fi + + # Install a server init.d script + if use server; then + newinitd "${FILESDIR}"/bcfg2-server.rc bcfg2-server + fi + + insinto /etc + doins examples/bcfg2.conf +} + +pkg_postinst () { + distutils_pkg_postinst + + if use server; then + einfo "If this is a new installation, you probably need to run:" + einfo " bcfg2-admin init" + fi +} -- cgit v1.2.3-1-g7c22 From 7a85e5deaaea9b237be1762f4ba5062632119f92 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 18 Nov 2010 20:00:04 -0600 Subject: macports: Sync with upstream (updated for 1.1.1) Signed-off-by: Sol Jerome --- osx/macports/Portfile | 13 ++++++------ osx/macports/files/patch-setup.py.diff | 37 +++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/osx/macports/Portfile b/osx/macports/Portfile index 91e8e0384..ed9d9b25b 100644 --- a/osx/macports/Portfile +++ b/osx/macports/Portfile @@ -5,10 +5,12 @@ PortSystem 1.0 PortGroup python26 1.0 name bcfg2 -license BSD -version 1.0.1 +version 1.1.1 categories sysutils python -maintainers ices.utexas.edu:solj +maintainers gmail.com:sol.jerome +license BSD +supported_archs noarch + description Bcfg2 configuration management system long_description Bcfg2 helps system administrators deploy complex \ changes across large numbers of systems in a \ @@ -18,9 +20,8 @@ homepage http://www.bcfg2.org/ platforms darwin master_sites ftp://ftp.mcs.anl.gov/pub/bcfg -checksums md5 6fbf36acc5cc58b2504a25c25cad3921 \ - sha1 36cac49009c906d4cb61e36a7a8c7b6859518862 \ - rmd160 fae98b10b721d059a9a483e046b83bd61458179d +checksums sha1 c0214d28796805ff8e3522d348914f366ba860aa \ + rmd160 2b7d8dfc2e14d1a2def743fe525ee91c5a3d3342 patchfiles patch-setup.py.diff diff --git a/osx/macports/files/patch-setup.py.diff b/osx/macports/files/patch-setup.py.diff index cc948face..f78d27e5c 100644 --- a/osx/macports/files/patch-setup.py.diff +++ b/osx/macports/files/patch-setup.py.diff @@ -1,26 +1,26 @@ ---- setup.py.orig 2009-11-20 16:07:52.000000000 -0600 -+++ setup.py 2009-11-20 16:29:56.000000000 -0600 -@@ -5,45 +5,19 @@ - - setup(name="Bcfg2", - version="1.0.1", +--- setup.py 2010-11-15 15:30:28.000000000 -0600 ++++ setup.py.macports 2010-11-18 19:06:49.155292524 -0600 +@@ -11,47 +11,22 @@ + setup(cmdclass=cmdclass, + name="Bcfg2", + version="1.1.1", - description="Bcfg2 Server", + description="Bcfg2 Client", author="Narayan Desai", author_email="desai@mcs.anl.gov", -- packages=["Bcfg2", -- "Bcfg2.Client", -+ packages=["Bcfg2.Client", +- packages=["Bcfg2", +- "Bcfg2.Client", ++ packages=["Bcfg2.Client", "Bcfg2.Client.Tools", -- 'Bcfg2.Server', +- 'Bcfg2.Server', - "Bcfg2.Server.Admin", -- "Bcfg2.Server.Hostbase", -- "Bcfg2.Server.Hostbase.hostbase", -- "Bcfg2.Server.Plugins", -- "Bcfg2.Server.Reports", +- "Bcfg2.Server.Hostbase", +- "Bcfg2.Server.Hostbase.hostbase", +- "Bcfg2.Server.Plugins", +- "Bcfg2.Server.Reports", - "Bcfg2.Server.Reports.reports", - "Bcfg2.Server.Reports.reports.templatetags", -- "Bcfg2.Server.Snapshots", +- "Bcfg2.Server.Snapshots", ], + py_modules = ["Bcfg2.Options", + "Bcfg2.Proxy", @@ -36,6 +36,9 @@ - ('share/bcfg2/xsl-transforms/xsl-transform-includes', - glob('reports/xsl-transforms/xsl-transform-includes/*.xsl')), - ('share/man/man1', glob("man/bcfg2.1")), ++ package_data = {'Bcfg2.Server.Reports.reports':['fixtures/*.xml', ++ 'templates/*.html', 'templates/*/*.html', ++ 'templates/*/*.inc' ] }, + scripts = glob('src/sbin/bcfg2'), + data_files = [('share/man/man1', glob("man/bcfg2.1")), ('share/man/man5', glob("man/*.5")), @@ -49,7 +52,9 @@ - ('share/bcfg2/Reports/templates/config_items', - glob('src/lib/Server/Reports/reports/templates/config_items/*')), - ('share/bcfg2/Hostbase/templates', -- glob('src/lib/Server/Hostbase/hostbase/webtemplates/*')), +- glob('src/lib/Server/Hostbase/hostbase/webtemplates/*.*')), +- ('share/bcfg2/Hostbase/templates/hostbase', +- glob('src/lib/Server/Hostbase/hostbase/webtemplates/hostbase/*')), - ('share/bcfg2/Hostbase/repo', - glob('src/lib/Server/Hostbase/templates/*')), ] -- cgit v1.2.3-1-g7c22 From 0cff753190c235a9ce65a920730d715a5e4a8ed4 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 23 Nov 2010 20:04:39 -0600 Subject: doc: Update group probe with modifications from Jonathan Billings Signed-off-by: Sol Jerome --- doc/server/plugins/probes/group.txt | 58 +++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/doc/server/plugins/probes/group.txt b/doc/server/plugins/probes/group.txt index 13b0d12eb..f529b8b3e 100644 --- a/doc/server/plugins/probes/group.txt +++ b/doc/server/plugins/probes/group.txt @@ -20,57 +20,65 @@ Probe used to dynamically set client groups based on OS/distro. if [ -e /etc/release ]; then # Solaris - OUTPUT=$OUTPUT'\n'`echo group:solaris` + OUTPUT="$OUTPUT\ngroup:solaris" elif [ -e /etc/debian_version ]; then # debian based - OUTPUT=$OUTPUT'\n'`echo group:deb` + OUTPUT="$OUTPUT\ngroup:deb" if [ -e /etc/lsb-release ]; then # variant . /etc/lsb-release OS_GROUP=$DISTRIB_CODENAME - DEBIAN_VERSION=$(echo "$DISTRIB_ID" | tr '[A-Z' '[a-z]') + DEBIAN_VERSION=$(echo "$DISTRIB_ID" | tr '[A-Z]' '[a-z]') case "$OS_GROUP" in "lucid") - OUTPUT=$OUTPUT'\n'`echo group:$DISTRIB_CODENAME` - OUTPUT=$OUTPUT'\n'`echo group:$DEBIAN_VERSION` + OUTPUT="$OUTPUT\ngroup:${DISTRIB_CODENAME}" + OUTPUT="$OUTPUT\ngroup:${DEBIAN_VERSION}" ;; esac else # debian OS_GROUP=`cat /etc/debian_version` - OUTPUT=$OUTPUT'\n'`echo group:debian` + OUTPUT="$OUTPUT\ngroup:debian" case "$OS_GROUP" in 5.*) - OUTPUT=$OUTPUT'\n'`echo group:lenny` + OUTPUT="$OUTPUT\ngroup:lenny" ;; "sid") - OUTPUT=$OUTPUT'\n'`echo group:sid` + OUTPUT="$OUTPUT\ngroup:sid" ;; esac fi elif [ -e /etc/redhat-release ]; then # redhat based - OUTPUT=$OUTPUT'\n'`echo group:rpm` - OS_GROUP=`cat /etc/redhat-release | cut -d' ' -f1 | tr '[A-Z]' '[a-z]'` - REDHAT_VERSION=`cat /etc/redhat-release | cut -d' ' -f3` - case "$OS_GROUP" in - "centos" | "fedora") - OUTPUT=$OUTPUT'\n'`echo group:$OS_GROUP` - OUTPUT=$OUTPUT'\n'`echo group:$OS_GROUP$REDHAT_VERSION` - ;; - esac + if [ -x /bin/rpm ]; then + OUTPUT="${OUTPUT}\ngroup:rpm" + OS_GROUP=`bin/rpm -q --qf "%{NAME}" --whatprovides redhat-release | sed 's/-release.*//' | tr '[A-Z]' '[a-z]'` + REDHAT_VERSION=`bin/rpm -q --qf "%{VERSION}" --whatprovides redhat-release` + case "$OS_GROUP" in + "centos" | "fedora") + OUTPUT="${OUTPUT}\ngroup:${OS_GROUP}" + OUTPUT="${OUTPUT}\ngroup:${OS_GROUP}-${REDHAT_VERSION}" + ;; + "redhat") + REDHAT_RELEASE=`bin/rpm -q --qf "%{RELEASE}" --whatprovides redhat-release| cut -d. -f1` + OUTPUT="${OUTPUT}\ngroup:${OS_GROUP}" + OUTPUT="${OUTPUT}\ngroup:${OS_GROUP}-${REDHAT_VERSION}" + OUTPUT="${OUTPUT}\ngroup:${OS_GROUP}-${REDHAT_RELEASE}" + ;; + esac + fi elif [ -e /etc/gentoo-release ]; then # gentoo - OUTPUT=$OUTPUT'\n'`echo group:gentoo` + OUTPUT="$OUTPUT\ngroup:gentoo" elif [ -x /usr/sbin/system_profiler ]; then # os x ### NOTE: Think about using system_profiler SPSoftwareDataType here - OUTPUT=$OUTPUT'\n'`echo group:osx` + OUTPUT="$OUTPUT\ngroup:osx" OSX_VERSION=`sw_vers | grep 'ProductVersion:' | egrep -o '[0-9]+\.[0-9]+'` if [ "$OSX_VERSION" == "10.6" ]; then - OUTPUT=$OUTPUT'\n'`echo group:osx-snow` + OUTPUT="$OUTPUT\ngroup:osx-snow" elif [ "$OSX_VERSION" == "10.5" ]; then - OUTPUT=$OUTPUT'\n'`echo group:osx-leo` + OUTPUT="$OUTPUT\ngroup:osx-leo" fi echo $OUTPUT else @@ -81,16 +89,16 @@ Probe used to dynamically set client groups based on OS/distro. case "$ARCH" in "x86_64") if [ "$OS_GROUP" == 'centos' ]; then - OUTPUT=$OUTPUT'\n'`echo group:$ARCH` + OUTPUT="$OUTPUT\ngroup:${ARCH}" else - OUTPUT=$OUTPUT'\n'`echo group:amd64` + OUTPUT="$OUTPUT\ngroup:amd64" fi ;; "i386" | "i686") - OUTPUT=$OUTPUT'\n'`echo group:i386` + OUTPUT="$OUTPUT\ngroup:i386" ;; "sparc64") - OUTPUT=$OUTPUT'\n'`echo group:sparc64` + OUTPUT="$OUTPUT\ngroup:sparc64" ;; esac -- cgit v1.2.3-1-g7c22 From 165f426083778303fcd2ee4d3fd697571de2867a Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Sun, 5 Dec 2010 16:55:12 -0600 Subject: doc: Make some minor changes to the new documentation Signed-off-by: Sol Jerome --- AUTHORS | 2 +- doc/appendix/articles.txt | 3 +- doc/appendix/books.txt | 3 +- doc/appendix/contributors.txt | 10 +-- doc/appendix/files.txt | 2 +- doc/appendix/files/mysql.txt | 17 ++--- doc/appendix/files/ntp.txt | 122 +++++++++++++++++---------------- doc/appendix/guides/authentication.txt | 2 +- doc/unsorted/writing_specification.txt | 3 +- 9 files changed, 81 insertions(+), 83 deletions(-) diff --git a/AUTHORS b/AUTHORS index 6c6ba4c51..d90874ad4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,4 +1,4 @@ -In chronological order: +In chronological order: - Narayan Desai has written most of bcfg2, including all parts not explicitly mentioned in this file diff --git a/doc/appendix/articles.txt b/doc/appendix/articles.txt index 4e31dd7ed..4a842a00e 100644 --- a/doc/appendix/articles.txt +++ b/doc/appendix/articles.txt @@ -21,5 +21,4 @@ Articles * `System Management Methodologies with Bcfg2 `_ * Narayan Desai, Rick Bradshaw and Joey Hagedorn - * In ;login: Magazine, Volume 31, #1, pages 11-18, February 2006 - + * In ;login: Magazine, Volume 31, #1, pages 11-18, February 2006 diff --git a/doc/appendix/books.txt b/doc/appendix/books.txt index 7cb864810..43906bca4 100644 --- a/doc/appendix/books.txt +++ b/doc/appendix/books.txt @@ -8,5 +8,4 @@ Books * `Configuration Management with Bcfg2 `_ - * Narayan Desai and Cory Lueninghoener - + * Narayan Desai and Cory Lueninghoener diff --git a/doc/appendix/contributors.txt b/doc/appendix/contributors.txt index 88246b513..9f2c18115 100644 --- a/doc/appendix/contributors.txt +++ b/doc/appendix/contributors.txt @@ -9,7 +9,7 @@ Contributors ============ -.. +.. This is list is no longer in chronological order like the AUTHORS file because it's easier to maintain (for me). Automatically sorted. @@ -22,7 +22,7 @@ In alphabetical order of the given name: - Daniel Clark created encap packages for bcfg2 and deps, wrote fossil-scm dvcs support, and helps with Debian packaging - Danny Clark enabled the Encap packaging - David Dahl worked on Hostbase -- David Strauss worked on CentOS, RHEL, Yum, and Bazaar VCS support +- David Strauss worked on CentOS, RHEL, Yum, and Bazaar VCS support - Ed Smith has done substantial hardening of the bcfg client and server and implemented a common logging infrastructure. - Fabian Affolter made some patches and worked on the manual - Jason Pepas has written a RPM package list creator has contributed patches to the Red Hat toolset @@ -37,7 +37,8 @@ In alphabetical order of the given name: - Sami Haahtinen has written Debian packaging logic. - Scott Behrens and Rick Bradshaw have written the VHost plugin - Scott Matott -- Sol Jerome squashes bugs, helps manage the project roadmap, and implements various interesting features. +- Sol Jerome squashes bugs, helps manage the + project roadmap, and implements various interesting features. - Ti Leggett worked on ebuild packaging and bugfixes, RPM packaging - Zach Lowry Solaris support and general hardening @@ -49,5 +50,4 @@ throughout this project. Philip Steinbachs provided detailed feedback as an early external user. The most updated listing is available in the AUTHORS_ file in the -SVN :term:`repository` of Bcfg2. - +git :term:`repository` for Bcfg2. diff --git a/doc/appendix/files.txt b/doc/appendix/files.txt index e5217b684..c96393065 100644 --- a/doc/appendix/files.txt +++ b/doc/appendix/files.txt @@ -7,7 +7,7 @@ Example files ============= In this section are some examples for getting started with a more -indeep usage of Bcfg2. +in-depth usage of Bcfg2. .. toctree:: :maxdepth: 1 diff --git a/doc/appendix/files/mysql.txt b/doc/appendix/files/mysql.txt index ae4a1450b..81104ec17 100644 --- a/doc/appendix/files/mysql.txt +++ b/doc/appendix/files/mysql.txt @@ -1,10 +1,10 @@ .. -*- mode: rst -*- -.. _getting_started-mysql: +.. _appendix-files-mysql: .. Author: Patrick Ruckstuhl -Mysql example +MySQL example ============= I had some time ago to continue with putting my configuration into @@ -15,8 +15,8 @@ I added a new bundle: .. code-block:: xml - - + + @@ -34,18 +34,14 @@ The ``users.sh`` script looks like this: On debian there is a user account in ``/etc/mysql/debian.cnf`` automatically created, but you could also (manually) create a user in the database that has enough permissions and add the -login information in a file yourself. This file looks like this: - -.. code-block:: sh +login information in a file yourself. This file looks like this:: [client] host = localhost user = debian-sys-maint password = XXXXXXXXXX -The ``users.sql`` looks like this: - -.. code-block:: sh +The ``users.sql`` looks like this:: DELETE FROM db; INSERT INTO db VALUES ('localhost', 'phpmyadmin', 'pma', 'Y', 'Y', @@ -60,4 +56,3 @@ The ``users.sql`` looks like this: 'N', 'N', 'N', '', '', '', '', 0, 0, 0); FLUSH PRIVILEGES; - diff --git a/doc/appendix/files/ntp.txt b/doc/appendix/files/ntp.txt index 33cb3bfbb..ec1fa3094 100644 --- a/doc/appendix/files/ntp.txt +++ b/doc/appendix/files/ntp.txt @@ -21,76 +21,81 @@ Package only Our example starts with the bare minimum configuration setup. We have a client, a profile group, a list of packages, and a base configuration. -.. code-block:: sh +``Metadata/clients.xml``: - # cat Metadata/clients.xml - - - +.. code-block:: xml -.. code-block:: sh + + + - # cat Metadata/groups.xml - - - +``Metadata/groups.xml``: -.. code-block:: sh +.. code-block:: xml - # cat Base/base.xml - - - - - + + + + +``Base/base.xml``: -.. code-block:: sh +.. code-block:: xml - # cat Pkgmgr/packages.xml - - - + + + + + + +``Pkgmgr/packages.xml``: + +.. code-block:: xml + + + + Add service ----------- Configure the service, and add it to the base. -.. code-block:: sh +``Svcmgr/services.xml``: - # cat Svcmgr/services.xml - - - +.. code-block:: xml -.. code-block:: sh + + + - # cat Base/base.xml - - - - - - +``Base/base.xml``: + +.. code-block:: xml + + + + + + + Add config file --------------- -Setup an ``etc/`` directory structure, and add it to the base. - -.. code-block:: sh +Setup an ``etc/`` directory structure, and add it to the base.:: # cat Cfg/etc/ntp.conf/ntp.conf server ntp1.utexas.edu -.. code-block:: sh +``Base/base.xml``: - # cat Base/base.xml - +.. code-block:: xml + + - + @@ -105,7 +110,7 @@ related configuration entries that are used to provide a single service. This is done for several reasons: * Grouping related things in one place makes it easier to add those - entries for a multiple groups of clients + entries for multiple groups of clients * Grouping entries into bundles makes their validation occur collectively. This means that config files can override the contents of packages. Also, config files are rechecked after @@ -119,22 +124,24 @@ The config file, package, and service are really all related components describing the idea of an ntp client, so they should be logically grouped together. We use a bundle to accomplish this. -.. code-block:: sh +``Bundler/ntp.xml``: - # cat Bundler/ntp.xml - - - - - +.. code-block:: xml + + + + + + After this bundle is created, it must be associated with a group (or groups). Add a bundle child element to the group(s) which should install this bundle. -.. code-block:: sh +``Metadata/groups.xml``: + +.. code-block:: xml - # cat Metadata/groups.xml ... @@ -143,9 +150,8 @@ install this bundle. ... -Once this bundle is created, a client reconfigure will install these -entries. If any are modified, then the ``ntpd`` service will be -restarted. If you only want ntp configurations to be updated -(and nothing else), the bcfg2 client can be run with a -``-b `` option that will only update entries in -the specified bundle. +Once this bundle is created, a client reconfigure will install +these entries. If any are modified, then the *ntpd* service will +be restarted. If you only want ntp configurations to be updated (and +nothing else), the bcfg2 client can be run with a ``-b `` +option that will only update entries in the specified bundle. diff --git a/doc/appendix/guides/authentication.txt b/doc/appendix/guides/authentication.txt index b9efbb929..13b797625 100644 --- a/doc/appendix/guides/authentication.txt +++ b/doc/appendix/guides/authentication.txt @@ -123,7 +123,7 @@ or password only. Also a bootstrap mode will be added shortly; this will allow a client to authenticate with a password its first time, requiring a certificate all subsequent times. This behavior can be controlled through the use of the auth attribute in -`Metadata/clients.xml`:: +``Metadata/clients.xml``:: diff --git a/doc/unsorted/writing_specification.txt b/doc/unsorted/writing_specification.txt index eced54841..5a75165bf 100644 --- a/doc/unsorted/writing_specification.txt +++ b/doc/unsorted/writing_specification.txt @@ -166,8 +166,7 @@ The following is an annotated copy of a bundle: .. code-block:: xml - + -- cgit v1.2.3-1-g7c22 From 87e3123d31cebbe451f685526c37d18ce0ad509c Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Tue, 7 Dec 2010 14:23:52 -0500 Subject: Using xpath rather than findall so that we can handle the condition correctly --- src/sbin/bcfg2-info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info index 497c39174..f379a51bb 100755 --- a/src/sbin/bcfg2-info +++ b/src/sbin/bcfg2-info @@ -238,7 +238,7 @@ class infoCore(cmd.Cmd, Bcfg2.Server.Core.Core): return # handle entries - for configfile in [cfile for cfile in client_config.findall(".//Path[@type = 'file']")]: + for configfile in [cfile for cfile in client_config.xpath(".//Path[@type = 'file']")]: try: write_config_file(odir, configfile) except FileNotBuilt, ex: -- cgit v1.2.3-1-g7c22 From 22fedd5bf837233fc59340634f6cd7e81717a2d1 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 3 Dec 2010 01:25:49 +0100 Subject: Initial bcfg2-admin backup part (cherry picked from commit a5f0c8b9936eb55283b3a2bb03e048842c773b45) --- src/lib/Server/Admin/Backup.py | 47 ++++++++++++++++++++++++++++++++++++++++ src/lib/Server/Admin/__init__.py | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/lib/Server/Admin/Backup.py diff --git a/src/lib/Server/Admin/Backup.py b/src/lib/Server/Admin/Backup.py new file mode 100644 index 000000000..583f0329c --- /dev/null +++ b/src/lib/Server/Admin/Backup.py @@ -0,0 +1,47 @@ +import glob +import sys +import time +import tarfile +import Bcfg2.Server.Admin +import Bcfg2.Options + +class Backup(Bcfg2.Server.Admin.MetadataCore): + __shorthelp__ = "Make a backup of the Bcfg2 repository." + __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin backup start" + "\n\nbcfg2-admin backup restore") + __usage__ = ("bcfg2-admin backup [start|restore]") + + def __init__(self, configfile): + Bcfg2.Server.Admin.MetadataCore.__init__(self, configfile, + self.__usage__) + + def __call__(self, args): + Bcfg2.Server.Admin.MetadataCore.__call__(self, args) + # Get Bcfg2 repo directory + opts = {'repo': Bcfg2.Options.SERVER_REPOSITORY} + setup = Bcfg2.Options.OptionParser(opts) + setup.parse(sys.argv[1:]) + repo = setup['repo'] + + if len(args) == 0: + self.errExit("No argument specified.\n" + "Please see bcfg2-admin backup help for usage.") + if args[0] == 'start': + timestamp = time.strftime('%Y%m%d%H%M%S') + format = 'gz' + mode = 'w:' + format + filename = timestamp + '.tar' + '.' + format + out = tarfile.open(filename, mode=mode) + content = os.listdir(os.getcwd()) + for item in content: + out.add(item) + out.close() + print "Archive %s was stored.\nLocation: %s" % (filename, datastore) + + elif args[0] == 'restore': + print 'Not implemented yet' + + else: + print "No command specified" + raise SystemExit(1) + diff --git a/src/lib/Server/Admin/__init__.py b/src/lib/Server/Admin/__init__.py index 3a088b2fb..bb5c41895 100644 --- a/src/lib/Server/Admin/__init__.py +++ b/src/lib/Server/Admin/__init__.py @@ -2,7 +2,7 @@ __revision__ = '$Revision$' __all__ = ['Mode', 'Client', 'Compare', 'Init', 'Minestruct', 'Perf', 'Pull', 'Query', 'Reports', 'Snapshots', 'Tidy', 'Viz', - 'Xcmd', 'Group'] + 'Xcmd', 'Group', 'Backup'] import ConfigParser import logging -- cgit v1.2.3-1-g7c22 From 1d8a9780d38b095ac2e67e3aeb5e436c756b719a Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Fri, 3 Dec 2010 01:52:34 +0100 Subject: Fixed backup location (cherry picked from commit c9eec98340168b1e9e3f4877b15b681855ee696b) --- src/lib/Server/Admin/Backup.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/Server/Admin/Backup.py b/src/lib/Server/Admin/Backup.py index 583f0329c..f150b9cf0 100644 --- a/src/lib/Server/Admin/Backup.py +++ b/src/lib/Server/Admin/Backup.py @@ -1,4 +1,5 @@ import glob +import os import sys import time import tarfile @@ -21,7 +22,7 @@ class Backup(Bcfg2.Server.Admin.MetadataCore): opts = {'repo': Bcfg2.Options.SERVER_REPOSITORY} setup = Bcfg2.Options.OptionParser(opts) setup.parse(sys.argv[1:]) - repo = setup['repo'] + self.datastore = setup['repo'] if len(args) == 0: self.errExit("No argument specified.\n" @@ -31,12 +32,12 @@ class Backup(Bcfg2.Server.Admin.MetadataCore): format = 'gz' mode = 'w:' + format filename = timestamp + '.tar' + '.' + format - out = tarfile.open(filename, mode=mode) - content = os.listdir(os.getcwd()) + out = tarfile.open(self.datastore + '/' + filename, mode=mode) + content = os.listdir(self.datastore) for item in content: out.add(item) out.close() - print "Archive %s was stored.\nLocation: %s" % (filename, datastore) + print "Archive %s was stored.\nLocation: %s" % (filename, self.datastore) elif args[0] == 'restore': print 'Not implemented yet' -- cgit v1.2.3-1-g7c22 From 8f96008ca5d3a567bed009dd0401007aa6cb9223 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 5 Dec 2010 21:50:18 +0100 Subject: Backup part reworked (cherry picked from commit 94e4f622b4dee6b33983a17313c0ef5a71c93f2e) --- src/lib/Server/Admin/Backup.py | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/src/lib/Server/Admin/Backup.py b/src/lib/Server/Admin/Backup.py index f150b9cf0..27a7fd8c8 100644 --- a/src/lib/Server/Admin/Backup.py +++ b/src/lib/Server/Admin/Backup.py @@ -1,4 +1,3 @@ -import glob import os import sys import time @@ -8,9 +7,9 @@ import Bcfg2.Options class Backup(Bcfg2.Server.Admin.MetadataCore): __shorthelp__ = "Make a backup of the Bcfg2 repository." - __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin backup start" - "\n\nbcfg2-admin backup restore") - __usage__ = ("bcfg2-admin backup [start|restore]") + __longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin backup") + #"\n\nbcfg2-admin backup restore") + __usage__ = ("bcfg2-admin backup") def __init__(self, configfile): Bcfg2.Server.Admin.MetadataCore.__init__(self, configfile, @@ -23,26 +22,11 @@ class Backup(Bcfg2.Server.Admin.MetadataCore): setup = Bcfg2.Options.OptionParser(opts) setup.parse(sys.argv[1:]) self.datastore = setup['repo'] - - if len(args) == 0: - self.errExit("No argument specified.\n" - "Please see bcfg2-admin backup help for usage.") - if args[0] == 'start': - timestamp = time.strftime('%Y%m%d%H%M%S') - format = 'gz' - mode = 'w:' + format - filename = timestamp + '.tar' + '.' + format - out = tarfile.open(self.datastore + '/' + filename, mode=mode) - content = os.listdir(self.datastore) - for item in content: - out.add(item) - out.close() - print "Archive %s was stored.\nLocation: %s" % (filename, self.datastore) - - elif args[0] == 'restore': - print 'Not implemented yet' - - else: - print "No command specified" - raise SystemExit(1) - + timestamp = time.strftime('%Y%m%d%H%M%S') + format = 'gz' + mode = 'w:' + format + filename = timestamp + '.tar' + '.' + format + out = tarfile.open(self.datastore + '/' + filename, mode=mode) + out.add(self.datastore, os.path.basename(self.datastore)) + out.close() + print "Archive %s was stored under %s" % (filename, self.datastore) -- cgit v1.2.3-1-g7c22 From 477c0fc85218cba12597cf3daf7728b127b0fd64 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 8 Dec 2010 19:43:54 -0600 Subject: doc: Finish merging remaining documentation updates Signed-off-by: Sol Jerome --- doc/appendix/configuration/mrepo.txt | 3 +- doc/appendix/contributors.txt | 2 +- doc/appendix/guides/authentication.txt | 10 +- doc/appendix/guides/centos.txt | 2 +- doc/appendix/guides/converging_rhel5.txt | 50 +++--- doc/appendix/guides/fedora.txt | 5 - doc/appendix/guides/gentoo.txt | 42 ++--- doc/appendix/guides/nat_howto.txt | 56 +++++-- doc/appendix/guides/ubuntu.txt | 14 +- doc/appendix/guides/using-bcfg2-info.txt | 2 +- doc/appendix/guides/using-bcfg2-with-centos.txt | 4 +- doc/appendix/guides/vcs.txt | 44 +++--- doc/appendix/guides/web-reports-install.txt | 184 ++++++++++++++++++++++ doc/appendix/guides/web-reports.txt | 184 ---------------------- doc/appendix/index.txt | 8 - doc/appendix/tools.txt | 2 +- doc/architecture/index.txt | 18 +-- doc/bcfg2.pdf | Bin 1387540 -> 0 bytes doc/client/tools/blast.txt | 10 -- doc/client/tools/chkconfig.txt | 15 -- doc/client/tools/debinit.txt | 9 -- doc/client/tools/encap.txt | 9 -- doc/client/tools/freebsdinit.txt | 9 -- doc/client/tools/freebsdpackage.txt | 10 -- doc/client/tools/index.txt | 171 +++++++++++++++++--- doc/client/tools/launchd.txt | 13 -- doc/client/tools/portage.txt | 9 -- doc/client/tools/posix.txt | 10 -- doc/client/tools/rcupdate.txt | 10 -- doc/client/tools/rpm.txt | 11 -- doc/client/tools/rpmng.txt | 11 -- doc/client/tools/smf.txt | 15 -- doc/client/tools/sysv.txt | 9 -- doc/client/tools/upstart.txt | 11 -- doc/client/tools/yum.txt | 11 -- doc/conf.py | 3 +- doc/contents.txt | 9 +- doc/development/client-driver.txt | 16 +- doc/development/documentation.txt | 37 ++--- doc/development/emacs_snippet.txt | 60 ------- doc/development/index.txt | 25 +-- doc/development/plugin-types.txt | 46 ------ doc/development/plugins.txt | 172 +++++++++++++++++++- doc/development/server.txt | 83 ---------- doc/development/setup.txt | 2 +- doc/development/vim_snippet.txt | 65 -------- doc/development/writing_plugins.txt | 104 ------------ doc/development/writing_specification.txt | 54 ------- doc/getting_help/error-messages.txt | 45 ------ doc/getting_help/faq/client.txt | 16 -- doc/getting_help/faq/general.txt | 72 --------- doc/getting_help/faq/index.txt | 17 -- doc/getting_help/index.txt | 41 ----- doc/getting_help/ircchannel.txt | 28 ---- doc/getting_help/mailinglist.txt | 24 --- doc/getting_help/manpages.txt | 16 -- doc/getting_help/manpages/bcfg2-admin.txt | 11 -- doc/getting_help/manpages/bcfg2-build-reports.txt | 11 -- doc/getting_help/manpages/bcfg2-conf.txt | 11 -- doc/getting_help/manpages/bcfg2-info.txt | 11 -- doc/getting_help/manpages/bcfg2-repo-validate.txt | 11 -- doc/getting_help/manpages/bcfg2-server.txt | 11 -- doc/getting_help/manpages/bcfg2.txt | 11 -- doc/getting_help/reporting.txt | 12 -- doc/getting_help/troubleshooting.txt | 184 ---------------------- doc/getting_started/index.txt | 116 +++++++------- doc/help/faq/client.txt | 16 ++ doc/help/faq/general.txt | 56 +++++++ doc/help/faq/index.txt | 17 ++ doc/help/index.txt | 42 +++++ doc/help/irc.txt | 45 ++++++ doc/help/mailinglist.txt | 24 +++ doc/help/troubleshooting.txt | 184 ++++++++++++++++++++++ doc/index.txt | 7 +- doc/installation/distributions.txt | 135 +++++++++++++++- doc/installation/distro/archlinux.txt | 17 -- doc/installation/distro/debian.txt | 24 --- doc/installation/distro/fedora.txt | 23 --- doc/installation/distro/gentoo.txt | 27 ---- doc/installation/distro/osx.txt | 29 ---- doc/installation/distro/rhel.txt | 31 ---- doc/installation/distro/ubuntu.txt | 36 ----- doc/installation/packages.txt | 40 ++--- doc/installation/prerequisites.txt | 55 ++++--- doc/installation/source.txt | 58 +++---- doc/reports/dynamic.txt | 3 +- doc/reports/static.txt | 4 +- doc/server/plugins/connectors/properties.txt | 13 +- doc/server/plugins/generators/tcheetah.txt | 17 +- doc/server/plugins/generators/tgenshi/index.txt | 6 +- doc/server/plugins/grouping/metadata.txt | 66 ++++++++ doc/server/plugins/index.txt | 23 ++- doc/server/plugins/structures/bundler/index.txt | 2 +- doc/unsorted/bcfg2.conf-options.txt | 19 +++ doc/unsorted/emacs_snippet.txt | 60 +++++++ doc/unsorted/vim_snippet.txt | 65 ++++++++ doc/unsorted/writing_specification.txt | 4 +- 97 files changed, 1570 insertions(+), 1875 deletions(-) create mode 100644 doc/appendix/guides/web-reports-install.txt delete mode 100644 doc/appendix/guides/web-reports.txt delete mode 100644 doc/bcfg2.pdf delete mode 100644 doc/client/tools/blast.txt delete mode 100644 doc/client/tools/chkconfig.txt delete mode 100644 doc/client/tools/debinit.txt delete mode 100644 doc/client/tools/encap.txt delete mode 100644 doc/client/tools/freebsdinit.txt delete mode 100644 doc/client/tools/freebsdpackage.txt delete mode 100644 doc/client/tools/launchd.txt delete mode 100644 doc/client/tools/portage.txt delete mode 100644 doc/client/tools/posix.txt delete mode 100644 doc/client/tools/rcupdate.txt delete mode 100644 doc/client/tools/rpm.txt delete mode 100644 doc/client/tools/rpmng.txt delete mode 100644 doc/client/tools/smf.txt delete mode 100644 doc/client/tools/sysv.txt delete mode 100644 doc/client/tools/upstart.txt delete mode 100644 doc/client/tools/yum.txt delete mode 100644 doc/development/emacs_snippet.txt delete mode 100644 doc/development/plugin-types.txt delete mode 100644 doc/development/server.txt delete mode 100644 doc/development/vim_snippet.txt delete mode 100644 doc/development/writing_plugins.txt delete mode 100644 doc/development/writing_specification.txt delete mode 100644 doc/getting_help/error-messages.txt delete mode 100644 doc/getting_help/faq/client.txt delete mode 100644 doc/getting_help/faq/general.txt delete mode 100644 doc/getting_help/faq/index.txt delete mode 100644 doc/getting_help/index.txt delete mode 100644 doc/getting_help/ircchannel.txt delete mode 100644 doc/getting_help/mailinglist.txt delete mode 100644 doc/getting_help/manpages.txt delete mode 100644 doc/getting_help/manpages/bcfg2-admin.txt delete mode 100644 doc/getting_help/manpages/bcfg2-build-reports.txt delete mode 100644 doc/getting_help/manpages/bcfg2-conf.txt delete mode 100644 doc/getting_help/manpages/bcfg2-info.txt delete mode 100644 doc/getting_help/manpages/bcfg2-repo-validate.txt delete mode 100644 doc/getting_help/manpages/bcfg2-server.txt delete mode 100644 doc/getting_help/manpages/bcfg2.txt delete mode 100644 doc/getting_help/reporting.txt delete mode 100644 doc/getting_help/troubleshooting.txt create mode 100644 doc/help/faq/client.txt create mode 100644 doc/help/faq/general.txt create mode 100644 doc/help/faq/index.txt create mode 100644 doc/help/index.txt create mode 100644 doc/help/irc.txt create mode 100644 doc/help/mailinglist.txt create mode 100644 doc/help/troubleshooting.txt delete mode 100644 doc/installation/distro/archlinux.txt delete mode 100644 doc/installation/distro/debian.txt delete mode 100644 doc/installation/distro/fedora.txt delete mode 100644 doc/installation/distro/gentoo.txt delete mode 100644 doc/installation/distro/osx.txt delete mode 100644 doc/installation/distro/rhel.txt delete mode 100644 doc/installation/distro/ubuntu.txt create mode 100644 doc/unsorted/bcfg2.conf-options.txt create mode 100644 doc/unsorted/emacs_snippet.txt create mode 100644 doc/unsorted/vim_snippet.txt diff --git a/doc/appendix/configuration/mrepo.txt b/doc/appendix/configuration/mrepo.txt index 0633af98e..309cd6779 100644 --- a/doc/appendix/configuration/mrepo.txt +++ b/doc/appendix/configuration/mrepo.txt @@ -15,7 +15,6 @@ takes care of setting up the ISO files, downloading the RPMs, configuring HTTP access and providing PXE/TFTP resources for remote network installations. - Sample mrepo configuration -------------------------- @@ -66,6 +65,6 @@ Sample mrepo configuration Update the repositories ----------------------- -To update your local repository, just lauch the following command :: +:: mrepo -ug diff --git a/doc/appendix/contributors.txt b/doc/appendix/contributors.txt index 9f2c18115..eaf4aa29a 100644 --- a/doc/appendix/contributors.txt +++ b/doc/appendix/contributors.txt @@ -1,6 +1,6 @@ .. -*- mode: rst -*- -.. _AUTHORS: http://trac.mcs.anl.gov/projects/bcfg2/browser/trunk/bcfg2/AUTHORS +.. _AUTHORS: http://trac.mcs.anl.gov/projects/bcfg2/browser/AUTHORS .. _MCS: http://www.mcs.anl.gov/ .. _appendix-contributors: diff --git a/doc/appendix/guides/authentication.txt b/doc/appendix/guides/authentication.txt index 13b797625..0a324b718 100644 --- a/doc/appendix/guides/authentication.txt +++ b/doc/appendix/guides/authentication.txt @@ -1,6 +1,6 @@ .. -*- mode: rst -*- -.. _guide-authentication: +.. _appendix-guides-authentication: ============== Authentication @@ -14,7 +14,7 @@ Scenarios Default settings work well; machines do not float, and a per-client password is not required. -2. :ref:`NAT Howto nat_howto` +2. :ref:`appendix-guides-nat_howto` * Build client records in advance with ``bcfg2-admin``, setting a uuid for each new client. @@ -33,7 +33,7 @@ Building bcfg2.conf automatically ================================= This is a TCheetah template that automatically constructs per-client -`bcfg2.conf` from the per-client metadata:: +bcfg2.conf from the per-client metadata:: [communication] protocol = xmlrpc/ssl @@ -43,14 +43,14 @@ This is a TCheetah template that automatically constructs per-client #if $self.metadata.password != None password = $self.metadata.password #else - password = my-password-foobar + password = my-password-foobat #end if [components] bcfg2 = https://localhost:6789 In this setup, this will cause any clients that have uuids established -to be set to use them in `bcfg2.conf`. It will also cause any clients +to be set to use them in ``bcfg2.conf``. It will also cause any clients with passwords set to use them instead of the global password. How Authentication Works diff --git a/doc/appendix/guides/centos.txt b/doc/appendix/guides/centos.txt index 91c1f268f..1e3c90156 100644 --- a/doc/appendix/guides/centos.txt +++ b/doc/appendix/guides/centos.txt @@ -2,7 +2,7 @@ .. _EPEL: http://fedoraproject.org/wiki/EPEL -.. _guide-centos: +.. _appendix-guides-centos: ===================== Quickstart for CentOS diff --git a/doc/appendix/guides/converging_rhel5.txt b/doc/appendix/guides/converging_rhel5.txt index 9d508e5e4..7581d307f 100644 --- a/doc/appendix/guides/converging_rhel5.txt +++ b/doc/appendix/guides/converging_rhel5.txt @@ -1,6 +1,6 @@ .. -*- mode: rst -*- -.. _unsorted-converging_rhel5: +.. _appendix-guides-converging_rhel5: ====================================== Converging on Verification with RHEL 5 @@ -18,25 +18,29 @@ Unmanaged entries * Package (top-level) - #. Enable the "Packages" plugin in {{{/etc/bcfg2.conf}}}, and configure the Yum repositories in {{{/var/lib/bcfg2/Packages/config.xml}}}. + #. Enable the "Packages" plugin in ``/etc/bcfg2.conf``, and configure + the Yum repositories in ``/var/lib/bcfg2/Packages/config.xml``. #. If a package is unwanted, remove it:: sudo yum remove PACKAGE - #. Otherwise, add {{{}}} to the Base or Bundler configuration. + #. Otherwise, add ```` to the Base or Bundler configuration. * Package (dependency) - #. Ensure the Yum repository sources configured in {{{/var/lib/bcfg2/Packages/config.xml}}} are correct. - #. Ensure the Yum repositories themselves are up-to-date with the main package and dependencies. + #. Ensure the Yum repository sources configured in + ``/var/lib/bcfg2/Packages/config.xml`` are correct. + #. Ensure the Yum repositories themselves are up-to-date with the main + package and dependencies. #. Rebuild the Packages plugin cache:: bcfg2-admin xcmd Packages.Refresh * Service - #. Add {{{}}} to the Base or Bundler configuration. - #. Add {{{}}} to {{{/var/lib/bcfg2/Rules/services.xml}}}. + #. Add ```` to the Base or Bundler configuration. + #. Add ```` to + ``/var/lib/bcfg2/Rules/services.xml``. Incorrect entries ================= @@ -46,13 +50,17 @@ For a "Package" * Failed RPM verification - #. Run {{{rpm -V PACKAGE}}} - #. Add configuration files (the ones with "c" next to them in the verification output) to {{{/var/lib/bcfg2/Cfg/}}}. + #. Run ``rpm -V PACKAGE`` + #. Add configuration files (the ones with "c" next to them in the + verification output) to ``/var/lib/bcfg2/Cfg/``. - * For example, {{{/etc/motd}}} to {{{/var/lib/bcfg2/Cfg/etc/motd/motd}}}. Yes, there is an extra directory level named after the file. + * For example, ``/etc/motd`` to ``/var/lib/bcfg2/Cfg/etc/motd/motd``. + Yes, there is an extra directory level named after the file. - #. Specify configuration files as {{{}}} in the Base or Bundler configuration. - #. Add directories to {{{/var/lib/bcfg2/Rules/directories.xml}}}. For example: + #. Specify configuration files as ```` in the Base + or Bundler configuration. + #. Add directories to ``/var/lib/bcfg2/Rules/directories.xml``. For + example: .. code-block:: xml @@ -65,8 +73,9 @@ For a "Package" * Option A: Explicitly list the instances - #. Drop the {{{}}} from the Base or Bundler configuration. - #. Add an explicit {{{}}} and {{{}}} configuration to a new Bundle, like the following: + #. Drop the ```` from the Base or Bundler configuration. + #. Add an explicit ```` and ```` configuration + to a new Bundle, like the following: .. code-block:: xml @@ -78,22 +87,25 @@ For a "Package" - #. Add the bundle to the applicable groups in {{{/var/lib/bcfg2/Metadata/groups.xml}}}. + #. Add the bundle to the applicable groups in + ``/var/lib/bcfg2/Metadata/groups.xml``. * Option B: Disable verification of the package - #. Add {{{pkg_checks="false"}}} to the {{{}}} tag. + #. Add ``pkg_checks="false"`` to the ```` tag. For a "Path" ------------------- - * Unclear verification problem (no details from BCFG2) + * Unclear verification problem (no details from Bcfg2) - 1. Run {{{bcfg2 -vqI}}} to see detailed verification issues (but deny any suggested actions). + 1. Run ``bcfg2 -vqI`` to see detailed verification issues (but deny + any suggested actions). * Permissions mismatch - 1. Create an {{{info.xml}}} file in the same directory as the configuration file. Example: + 1. Create an ``info.xml`` file in the same directory as the + configuration file. Example: .. code-block:: xml diff --git a/doc/appendix/guides/fedora.txt b/doc/appendix/guides/fedora.txt index f3a5a3929..d8d3b1b34 100644 --- a/doc/appendix/guides/fedora.txt +++ b/doc/appendix/guides/fedora.txt @@ -470,8 +470,3 @@ The first commit can be the empty or the allready populated directory:: While running ``bcfg2-info`` the following line will show up:: Initialized git plugin with git directory = /var/lib/bcfg2/.git - - - - - diff --git a/doc/appendix/guides/gentoo.txt b/doc/appendix/guides/gentoo.txt index 023e6ac24..e818364ce 100644 --- a/doc/appendix/guides/gentoo.txt +++ b/doc/appendix/guides/gentoo.txt @@ -1,6 +1,6 @@ .. -*- mode: rst -*- -.. _guide-gentoo: +.. _appendix-guides-gentoo: ====== Gentoo @@ -23,8 +23,8 @@ should still work provided that you have a reasonably up to date Python; try adding `app-admin/bcfg2 ~*` to your `/etc/portage/package.keywords` file. -If you don’t use portage to install Bcfg2, you’ll want to make sure you -have all the prerequisites installed first. For a server, you’ll need: +If you don't use portage to install Bcfg2, you'll want to make sure you +have all the prerequisites installed first. For a server, you'll need: * ``app-admin/gamin`` or ``app-admin/fam`` * ``dev-python/lxml`` @@ -37,7 +37,7 @@ Package Repository ================== You’ll need (to make) at least one archive of binary packages. The -Portage driver calls ``emerge`` with the ``–getbinpkgonly`` option. See +Portage driver calls ``emerge`` with the ``-getbinpkgonly`` option. See :manpage:`make.conf(5)` and :manpage:`emerge(1)` manpages, specifically the *PORTAGE_BINHOST* environment variable. @@ -52,7 +52,7 @@ present state of the system by using the quickpkg utility. For example: for pkg in `equery -q l` ; do quickpkg "=$pkg" ; done -…will leave you with a complete archive of all the packages on your +...will leave you with a complete archive of all the packages on your system in ``/usr/portage/packages/All``, which you can then move to your ftp server. @@ -60,7 +60,7 @@ Cataloging Packages In Your Repository -------------------------------------- Once you have a set of packages, you will need to create a catalog for -them in ``/var/lib/bcfg2/Pkgmgr``. Here’s a template: +them in ``/var/lib/bcfg2/Pkgmgr``. Here's a template: .. code-block:: xml @@ -70,7 +70,7 @@ them in ``/var/lib/bcfg2/Pkgmgr``. Here’s a template: -…and a partially filled-out example, for our local Gentoo/VMware build: +...and a partially filled-out example, for our local Gentoo/VMware build: .. code-block:: xml @@ -82,17 +82,17 @@ them in ``/var/lib/bcfg2/Pkgmgr``. Here’s a template: -The `` name (in our example, “gentoo-200701-vmware”) should +The `` name (in our example, "gentoo-200701-vmware") should be included by any host which will draw its packages from this list. Our collection of packages for this class of machines is at the listed URI, and we only have one collection of packages for this batch of machines so -in our case the `priority` doesn’t really matter, we’ve set it to `0`. +in our case the `priority` doesn’t really matter, we've set it to `0`. Notice that package name fields are in `CAT/TITLE` format. Here is a hack which will generate a list of Package lines from -a system’s database of installed packages, especially useful in -conjunction with the `quickpkg` example above: +a system's database of installed packages, especially useful in +conjunction with the ``quickpkg`` example above: .. code-block:: sh @@ -123,14 +123,14 @@ Pitfalls Package Verification Issues --------------------------- -As of this writing (2007/01/31), we’re aware of a number of packages +As of this writing (2007/01/31), we're aware of a number of packages marked stable in the Gentoo x86 tree which, for one reason or another, -consistently fail to verify cleanly under `equery check`. In some cases -(pam, openldap), files which don’t (ever) exist on the system are +consistently fail to verify cleanly under ``equery check``. In some cases +(pam, openldap), files which don't (ever) exist on the system are nonetheless recorded in the package database; in some (python, Bcfg2, ahem), whole classes of files (.pyc and .pyo files) consistently fail their md5sum checks; and in others, the problem appears to be a -discrepancy in the way that symlinks are created vs. the way they’re +discrepancy in the way that symlinks are created vs. the way they're recorded in the database. For example, in the OpenSSH package, /usr/bin/slogin is a symlink to ./ssh, but equery expects it to point to an unadorned ssh. An analogous situation exists with their manpages, @@ -147,13 +147,13 @@ leading to noise like this:: We can ignore the lines for ``ssh_config`` and ``sshd_config``; those will be caught by Bcfg2 as registered config files and handled appropriately. -Because Bcfg2 relies on the client system’s native package reporting +Because Bcfg2 relies on the client system's native package reporting tool to judge the state of installed packages, complaints like these about trivial or intractable verification failures can trigger unnecessary bundle reinstalls when the Bcfg2 client runs. Bcfg2 will catch on after a -pass or two that the situation isn’t getting any better with repeated -package installs, stop trying, and list those packages as “bad” in -the client system’s statistics. +pass or two that the situation isn't getting any better with repeated +package installs, stop trying, and list those packages as "bad" in +the client system's statistics. Aside from filing bugs with the Gentoo package maintainers, your narrator has been unable to come up with a good approach to this. Maybe write a @@ -171,7 +171,7 @@ during normal runtime. This can lead to trouble during verification and package installation, for example when ``/boot/grub/grub.conf`` turns up missing. The simplest way around this might just be to ensure that ``/boot`` is mounted whenever you run Bcfg2, possibly wrapping Bcfg2 -in a script for the purpose. I’ve also thought about adding *Action* +in a script for the purpose. I've also thought about adding *Action* clauses to bundles for grub and our kernel packages, which would mount ``/boot`` before the bundle installs and unmount it afterward, but this -doesn’t get around the problem of those packages flunking verification. +doesn't get around the problem of those packages flunking verification. diff --git a/doc/appendix/guides/nat_howto.txt b/doc/appendix/guides/nat_howto.txt index 131c0c533..818d3e644 100644 --- a/doc/appendix/guides/nat_howto.txt +++ b/doc/appendix/guides/nat_howto.txt @@ -1,56 +1,86 @@ .. -*- mode: rst -*- -.. _unsorted-nat_howto: +.. _appendix-guides-nat_howto: ========= NAT HOWTO ========= -This page describes how to setup bcfg2 to properly function with a collection of clients behind NAT. It describes the issues, how the underlying portions of the bcfg2 system function, and how to correctly setup client metadata to cope with this environment. +This page describes how to setup Bcfg2 to properly function with a +collection of clients behind NAT. It describes the issues, how the +underlying portions of the Bcfg2 system function, and how to correctly +setup client metadata to cope with this environment. Issues ====== -Bcfg2, by default, uses ip address lookup to determine the identity of a client that has connected. This process doesn't work properly in the case of NATted hosts, because all requests from these clients come from the same external address when connecting to the server. +Bcfg2, by default, uses ip address lookup to determine the identity of +a client that has connected. This process doesn't work properly in the +case of NAT'ed hosts, because all requests from these clients come from +the same external address when connecting to the server. -These client identification issues will manifest themselves in a number of ways: +These client identification issues will manifest themselves in a number +of ways: * Inability to setup discrete clients with different profiles * Incorrect sharing of probe results across clients in the same NAT pool -* Inability to bootstrap clients properly when client data is not predefined +* Inability to bootstrap clients properly when client data is not + predefined Architectural Issues ==================== -Client identification is performed as the beginning of each client/server interaction. As of 0.9.3pre3, client identification via IP address can be completely short-circuited through the use of a client uuid. Setup of client uuids requires actions of both the client and server. On the server side, the client uuid must be added to the client record in Metadata/clients.xml. This attribute allows the server to use the user part of the authentication to resolve the client's metadata. Also, either the location attribute should be set to floating, or the IP address of the NAT must be reflected in the address attribute. -Once added, the Client entry in clients.xml will look like: +Client identification is performed at the beginning of each client/server +interaction. As of 0.9.3, client identification via IP address can be +completely short-circuited through the use of a client uuid. Setup of +client uuids requires actions of both the client and server. On the +server side, the client uuid must be added to the client record in +``Metadata/clients.xml``. This attribute allows the server to use the +user part of the authentication to resolve the client's metadata. Also, +either the location attribute should be set to floating, or the IP address +of the NAT must be reflected in the address attribute. Once added, +the Client entry in clients.xml will look something like this: .. code-block:: xml -Alternatively, the Client entry can be setup like: +Alternatively, the Client entry can be setup like this: .. code-block:: xml -The difference between these definitions is explained in detail on the [wiki:Authentication] page, but in short, the second form requires that the client access the server from the NAT address, while the first form allows it to connect from any address provided it uses the proper uuid. (Client identification is orthogonal to the use of per-client passwords; this can be set in addition to the attributes above.) +The difference between these definitions is explained in detail in the +:ref:`appendix-guides-authentication` section, but in short, the second +form requires that the client access the server from the NAT address, +while the first form allows it to connect from any address provided it +uses the proper uuid. (Client identification is orthogonal to the use +of per-client passwords; this can be set in addition to the attributes +above.) -Once this setup is done, each client must be configured to use the proper uuid upon any server interaction. This can be done using either the command line argument -u, or the setting "user" in the "communication" section of /etc/bcfg2.conf. +Once this setup is done, each client must be configured to use the proper +uuid upon any server interaction. This can be done using either the +command line argument -u, or the setting "user" in the "communication" +section of ``/etc/bcfg2.conf``. UUID Choice =========== -When determining client UUIDs, one must take care to ensure that UUIDs are unique to the client. Any hardware-specific attribute, like a hash of a mac address would be sufficient. Alternatively, if a local hostname is unique, it may be used as well. +When determining client UUIDs, one must take care to ensure that UUIDs +are unique to the client. Any hardware-specific attribute, like a hash +of a mac address would be sufficient. Alternatively, if a local hostname +is unique, it may be used as well. Automated Client Bootstrapping ============================== -Automated setup of new clients from behind NAT works by using the common password. For example:: +Automated setup of new clients from behind NAT works by using the common +password. For example:: /usr/sbin/bcfg2 -u ubik3 -p desktop -x -It is not possible at this time to do automated setup without setting up a pre-shared per-client key. +It is not possible at this time to do automated setup without setting +up a pre-shared per-client key. diff --git a/doc/appendix/guides/ubuntu.txt b/doc/appendix/guides/ubuntu.txt index a4790ffed..595005018 100644 --- a/doc/appendix/guides/ubuntu.txt +++ b/doc/appendix/guides/ubuntu.txt @@ -1,6 +1,6 @@ .. -*- mode: rst -*- -.. _guide-ubuntu: +.. _appendix-guides-ubuntu: ====== Ubuntu @@ -8,9 +8,9 @@ Ubuntu .. note:: - This particular how to was done on lucid, but should apply to any - other `stable`__ version of Ubuntu. - + This particular how to was done on lucid, but should apply to any + other `stable`__ version of Ubuntu. + __ ubuntu-releases_ .. _ubuntu-releases: https://wiki.ubuntu.com/Releases @@ -60,9 +60,9 @@ allows you to automate this process.:: 6: Gentoo 7: FreeBSD : 5 - Generating a 1024 bit RSA private key - .......................................................................................+++ - ...++++++ + Generating a 2048 bit RSA private key + ......................................................................................+++ + ...+++ writing new private key to '/etc/bcfg2.key' ----- Signature ok diff --git a/doc/appendix/guides/using-bcfg2-info.txt b/doc/appendix/guides/using-bcfg2-info.txt index 5f77a3c70..b2354652f 100644 --- a/doc/appendix/guides/using-bcfg2-info.txt +++ b/doc/appendix/guides/using-bcfg2-info.txt @@ -1,6 +1,6 @@ .. -*- mode: rst -*- -.. _guide-using_bcfg2_info: +.. _appendix-guides-using_bcfg2_info: ================ Using bcfg2-info diff --git a/doc/appendix/guides/using-bcfg2-with-centos.txt b/doc/appendix/guides/using-bcfg2-with-centos.txt index 7c452f422..93875d4c5 100644 --- a/doc/appendix/guides/using-bcfg2-with-centos.txt +++ b/doc/appendix/guides/using-bcfg2-with-centos.txt @@ -43,9 +43,9 @@ Now you can install the rest of the prerequisites:: Build Packages from source ########################## -* After installing subversion, check out a copy of trunk :: +* After installing git, clone the master branch:: - [root@centos redhat]# svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2 + [root@centos redhat]# git clone git://git.mcs.anl.gov/bcfg2.git * Install the ``fedora-packager`` package :: diff --git a/doc/appendix/guides/vcs.txt b/doc/appendix/guides/vcs.txt index 207337c30..6c2879a65 100644 --- a/doc/appendix/guides/vcs.txt +++ b/doc/appendix/guides/vcs.txt @@ -1,28 +1,23 @@ .. -*- mode: rst -*- -.. _guide-vcs: +.. _appendix-guides-vcs: ======================= Version control systems ======================= -The sections in this guide do only cover the basics steps in the setup -of the different version control system for the usage with the Bcfg2 -plugin support. More more details about +The sections in this guide only cover the basics steps in the setup of +the different version control systems for usage with the Bcfg2. Git === .. _Git tutorial: http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html -Adding the :ref:`server-plugins-version-git` plugins can preserve -versioning information. The first step is to add **Git** to your -plugin line:: - - plugins = Base,Bundler,Cfg,...,Git - -For tracking the configuration files in the ``/var/lib/bcfg2`` -directory a git repository need to be established:: +Adding the :ref:`server-plugins-version-git` plugin will allow you to +store version information in the statistics database. For tracking the +configuration files in the ``/var/lib/bcfg2`` directory a git repository +needs to be established:: git init @@ -38,12 +33,11 @@ While running ``bcfg2-info`` the following line will show up:: Mercurial ========= -For the :ref:`server-plugins-version-hg` plugin are the same changes -needed as for git. :: +The :ref:`server-plugins-version-hg` plugin also allows you to store +version information in the statistics database. - plugins = Base,Bundler,Cfg,...,Mercurial - -The repository must be initialized:: +To use mercurial to track your configuration files, the repository must +be initialized:: hg init @@ -68,12 +62,11 @@ While running ``bcfg2-info`` the following line will show up:: Darcs ===== -If you wish to use the :ref:`server-plugins-version-darcs` plugin an -entry has to be made in the ``bcfg2.conf`` file.:: - - plugins = Base,Bundler,Cfg,...,Darcs +The :ref:`server-plugins-version-darcs` plugin also allows you to store +version information in the statistics database. -The dracs repository must be initialized:: +To use darcs to track your configuration files, the repository must +be initialized:: darcs initialize @@ -87,7 +80,8 @@ darcs will ask you to enter your e-mail address. you@example.com END_ENTRY -All files in the ``/var/lib/bcfg2`` should be added to darcs now:: +All files in the ``/var/lib/bcfg2`` directory should be added to darcs +now:: darcs add * @@ -102,8 +96,8 @@ While running ``bcfg2-info`` the following line will show up:: Cvs === -If you wish to use the :ref:`server-plugins-version-darcs` plugin an -entry has to be made in the ``bcfg2.conf`` file.:: +The :ref:`server-plugins-version-cvs` plugin also allows you to store +version information in the statistics database. plugins = Base,Bundler,Cfg,...,Cvs diff --git a/doc/appendix/guides/web-reports-install.txt b/doc/appendix/guides/web-reports-install.txt new file mode 100644 index 000000000..af2e240fa --- /dev/null +++ b/doc/appendix/guides/web-reports-install.txt @@ -0,0 +1,184 @@ +.. -*- mode: rst -*- + +.. _EPEL: http://fedoraproject.org/wiki/EPEL + +.. This is combination of the Ubuntu guide and the Centos guide for + installing the web reports. + +.. _appendix-guides-web-reports-install: + +================================== +Dynamic (web) Reports installation +================================== + +The first step is to install the needed software components like the +Django framework and the database (SQlite2). All packages for Fedora +are in the Fedora Package Collection or in EPEL_ for CentOS/RHEL:: + + [root@system01 ~]# yum -y install Django python-simplejson python-sqlite2 + +Of course is a web server needed as well:: + + [root@system01 ~]# yum -y install httpd mod_python + +The same packages are needed for Ubuntu systems:: + + [root@system01 ~]# aptitude install python-django apache2 libapache2-mod-python + +Now we need to create the sqlite database. Use the following command on +Fedora, CentOS, or RHEL.:: + + [root@system01 ~]# python /usr/lib/python2.4/site-packages/Bcfg2/Server/Reports/manage.py syncdb + Creating table auth_permission + Creating table auth_group + Creating table auth_user + Creating table auth_message + Creating table django_content_type + Creating table django_session + Creating table django_site + Creating table django_admin_log + Creating table reports_client + Creating table reports_ping + Creating table reports_interaction + Creating table reports_reason + Creating table reports_entries + Creating table reports_entries_interactions + Creating table reports_performance + Creating table reports_internaldatabaseversion + + 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.Permission model + Installing index for auth.Message model + Installing index for admin.LogEntry model + Installing index for reports.Client model + Installing index for reports.Ping model + Installing index for reports.Interaction model + Installing index for reports.Entries model + Installing index for reports.Entries_interactions model + +.. note:: There are different versions of Python available. If you are + unsure about your installed version use the following line instead of + the line above.:: + + [root@system01 ~]# PYVER=`python -c 'import sys;print(sys.version[0:3])'`; python /usr/lib/python$PYVER/site-packages/Bcfg2/site-packages/Bcfg2/Server/Reports/manage.py syncdb + +The path on Ubuntu systems is different. Please use the same path as shown +in the following command to execute the script on an Ubuntu machine in +the next steps:: + + [root@system01 ~]# python /usr/share/pyshared/Bcfg2/Server/Reports/manage.py syncdb + Creating table auth_permission + Creating table auth_group + Creating table auth_user + Creating table auth_message + Creating table django_content_type + Creating table django_session + Creating table django_site + Creating table django_admin_log + Creating table reports_client + Creating table reports_ping + Creating table reports_interaction + Creating table reports_reason + Creating table reports_entries + Creating table reports_entries_interactions + Creating table reports_performance + Creating table reports_internaldatabaseversion + + 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.Permission model + Installing index for auth.Message model + Installing index for admin.LogEntry model + Installing index for reports.Client model + Installing index for reports.Ping model + Installing index for reports.Interaction model + Installing index for reports.Entries model + Installing index for reports.Entries_interactions model + +The server should be tested to make sure that there are no mistakes:: + + [root@system01 ~]# python /usr/lib/python2.6/site-packages/Bcfg2/Server/Reports/manage.py testserver + Creating test database... + Creating table auth_permission + Creating table auth_group + Creating table auth_user + Creating table auth_message + Creating table django_content_type + Creating table django_session + Creating table django_site + Creating table django_admin_log + Creating table reports_client + Creating table reports_ping + Creating table reports_interaction + Creating table reports_reason + Creating table reports_entries + Creating table reports_entries_interactions + Creating table reports_performance + Creating table reports_internaldatabaseversion + Installing index for auth.Permission model + Installing index for auth.Message model + Installing index for admin.LogEntry model + Installing index for reports.Client model + Installing index for reports.Ping model + Installing index for reports.Interaction model + Installing index for reports.Entries model + Installing index for reports.Entries_interactions model + Validating models... + 0 errors found + + Django version 1.1.1, using settings 'Reports.settings' + Development server is running at http://127.0.0.1:8000/ + Quit the server with CONTROL-C. + +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,Packages,Probes,Rules,SSHbase + +Start/restart the Bcfg2 server:: + + [root@system01 ~]# /etc/init.d/bcfg2-server restart + +Run the Bcfg2 client in order to populate the statistics database +(this run should take a bit longer since you are uploading the client +statistics to the database). + +Download the static reports content:: + + [root@system01 ~]# cd /var/www/ + [root@system01 ~]# svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2/reports + +Configure Apache using :ref:`dynamic-http-install` as a guide + +Copy server/statistics sections of ``bcfg2.conf`` to +``/etc/bcfg2-web.conf`` (make sure it is world-readable). You should +then have something like this:: + + [server] + repository = /var/lib/bcfg2 + plugins = Base,Bundler,Cfg,DBStats,Metadata,Packages,Probes,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. + #/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 + +Restart apache and point a browser to your Bcfg2 server. + +If using sqlite be sure the sql database file and directory containing +the database are writable to apache. diff --git a/doc/appendix/guides/web-reports.txt b/doc/appendix/guides/web-reports.txt deleted file mode 100644 index 9eadfb678..000000000 --- a/doc/appendix/guides/web-reports.txt +++ /dev/null @@ -1,184 +0,0 @@ -.. -*- mode: rst -*- - -.. _EPEL: http://fedoraproject.org/wiki/EPEL - -.. This is combination of the Ubuntu guide and the Centos guide for - installing the web reports. - -.. _web-reports: - -================================== -Dynamic (web) Reports installation -================================== - -The first step is to install the needed software components like the -Django framework and the database (SQlite2). All packages for Fedora -are in the Fedora Package Collection or in EPEL_ for CentOS/RHEL:: - - [root@system01 ~]# yum -y install Django python-simplejson python-sqlite2 - -Of course is a web server needed as well:: - - [root@system01 ~]# yum -y install httpd mod_python - -The same packages are needed for Ubuntu systems:: - - [root@system01 ~]# aptitude install python-django apache2 libapache2-mod-python - -Now we need to create the sqlite database. Use the following command on -Fedora, CentOS, or RHEL.:: - - [root@system01 ~]# python /usr/lib/python2.4/site-packages/Bcfg2/Server/Reports/manage.py syncdb - Creating table auth_permission - Creating table auth_group - Creating table auth_user - Creating table auth_message - Creating table django_content_type - Creating table django_session - Creating table django_site - Creating table django_admin_log - Creating table reports_client - Creating table reports_ping - Creating table reports_interaction - Creating table reports_reason - Creating table reports_entries - Creating table reports_entries_interactions - Creating table reports_performance - Creating table reports_internaldatabaseversion - - 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.Permission model - Installing index for auth.Message model - Installing index for admin.LogEntry model - Installing index for reports.Client model - Installing index for reports.Ping model - Installing index for reports.Interaction model - Installing index for reports.Entries model - Installing index for reports.Entries_interactions model - -.. note:: There are different versions of Python available. If you are - unsure about your installed version use the following line instead of - the line above.:: - - [root@system01 ~]# PYVER=`python -c 'import sys;print(sys.version[0:3])'`; python /usr/lib/python$PYVER/site-packages/Bcfg2/site-packages/Bcfg2/Server/Reports/manage.py syncdb - -The path on Ubuntu systems is different. Please use the same path as shown -in the following command to execute the script on an Ubuntu machine in -the next steps:: - - [root@system01 ~]# python /usr/share/pyshared/Bcfg2/Server/Reports/manage.py syncdb - Creating table auth_permission - Creating table auth_group - Creating table auth_user - Creating table auth_message - Creating table django_content_type - Creating table django_session - Creating table django_site - Creating table django_admin_log - Creating table reports_client - Creating table reports_ping - Creating table reports_interaction - Creating table reports_reason - Creating table reports_entries - Creating table reports_entries_interactions - Creating table reports_performance - Creating table reports_internaldatabaseversion - - 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.Permission model - Installing index for auth.Message model - Installing index for admin.LogEntry model - Installing index for reports.Client model - Installing index for reports.Ping model - Installing index for reports.Interaction model - Installing index for reports.Entries model - Installing index for reports.Entries_interactions model - -The server should be tested to make sure that there are no mistakes:: - - [root@system01 ~]# python /usr/lib/python2.6/site-packages/Bcfg2/Server/Reports/manage.py testserver - Creating test database... - Creating table auth_permission - Creating table auth_group - Creating table auth_user - Creating table auth_message - Creating table django_content_type - Creating table django_session - Creating table django_site - Creating table django_admin_log - Creating table reports_client - Creating table reports_ping - Creating table reports_interaction - Creating table reports_reason - Creating table reports_entries - Creating table reports_entries_interactions - Creating table reports_performance - Creating table reports_internaldatabaseversion - Installing index for auth.Permission model - Installing index for auth.Message model - Installing index for admin.LogEntry model - Installing index for reports.Client model - Installing index for reports.Ping model - Installing index for reports.Interaction model - Installing index for reports.Entries model - Installing index for reports.Entries_interactions model - Validating models... - 0 errors found - - Django version 1.1.1, using settings 'Reports.settings' - Development server is running at http://127.0.0.1:8000/ - Quit the server with CONTROL-C. - -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,Packages,Probes,Rules,SSHbase - -Start/restart the Bcfg2 server:: - - [root@system01 ~]# /etc/init.d/bcfg2-server restart - -Run the Bcfg2 client in order to populate the statistics database -(this run should take a bit longer since you are uploading the client -statistics to the database). - -Download the static reports content:: - - [root@system01 ~]# cd /var/www/ - [root@system01 ~]# svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2/reports - -Configure Apache using :ref:`dynamic-http-install` as a guide - -Copy server/statistics sections of ``bcfg2.conf`` to -``/etc/bcfg2-web.conf`` (make sure it is world-readable). You should -then have something like this:: - - [server] - repository = /var/lib/bcfg2 - plugins = Base,Bundler,Cfg,DBStats,Metadata,Packages,Probes,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. - #/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 - -Restart apache and point a browser to your Bcfg2 server. - -If using sqlite be sure the sql database file and directory containing the -database are writable to apache. diff --git a/doc/appendix/index.txt b/doc/appendix/index.txt index 1bac69a3d..407119e24 100644 --- a/doc/appendix/index.txt +++ b/doc/appendix/index.txt @@ -6,14 +6,6 @@ Appendix ======== -Bcfg2 is based on a client-server architecture. The client is -responsible for interpreting (but not processing) the configuration -served by the server. This configuration is literal, so no local -process is required. After completion of the configuration process, -the client uploads a set of statistics to the server. This section -will describe the goals and then the architecture motivated by it. - - .. toctree:: :maxdepth: 2 diff --git a/doc/appendix/tools.txt b/doc/appendix/tools.txt index 040823504..1d7a8dd90 100644 --- a/doc/appendix/tools.txt +++ b/doc/appendix/tools.txt @@ -11,4 +11,4 @@ can help you to maintain your Bcfg2 configuration, to make the initial setup easier, or to do some other tasks. -http://trac.mcs.anl.gov/projects/bcfg2/browser/trunk/bcfg2/tools +http://trac.mcs.anl.gov/projects/bcfg2/browser/tools diff --git a/doc/architecture/index.txt b/doc/architecture/index.txt index d5e034d34..742035f8d 100644 --- a/doc/architecture/index.txt +++ b/doc/architecture/index.txt @@ -2,16 +2,16 @@ .. _architecture-index: -====================== -Architecture in Detail -====================== +=========================== +Detailed Bcfg2 Architecture +=========================== -Bcfg2 is based on a client-server architecture. The client is -responsible for interpreting (but not processing) the configuration -served by the server. This configuration is literal, so no local -process is required. After completion of the configuration process, -the client uploads a set of statistics to the server. This section -will describe the goals and then the architecture motivated by it. +Bcfg2 is based on a client-server architecture. The client is responsible +for interpreting (but not processing) the configuration served by the +server. This configuration is literal, so no local process is required. +After completion of the configuration process, the client uploads a set +of statistics to the server. This section will describe the goals and +then the architecture motivated by it. .. toctree:: diff --git a/doc/bcfg2.pdf b/doc/bcfg2.pdf deleted file mode 100644 index 4a34a5352..000000000 Binary files a/doc/bcfg2.pdf and /dev/null differ diff --git a/doc/client/tools/blast.txt b/doc/client/tools/blast.txt deleted file mode 100644 index 14eb53124..000000000 --- a/doc/client/tools/blast.txt +++ /dev/null @@ -1,10 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-blast: - -===== -Blast -===== - -Blastwave Packages. This tool driver is for blastwave packages on -solaris. diff --git a/doc/client/tools/chkconfig.txt b/doc/client/tools/chkconfig.txt deleted file mode 100644 index 35cc0969e..000000000 --- a/doc/client/tools/chkconfig.txt +++ /dev/null @@ -1,15 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-chkconfig: - -========= -Chkconfig -========= - -Tool to manage services (primarily on Red Hat based distros). - -.. note:: Start and stop are standard arguments, but the one for reload - isn't consistent across services. You can specify which argument - to use with the `restart` property in Service tags. Example: - ```` diff --git a/doc/client/tools/debinit.txt b/doc/client/tools/debinit.txt deleted file mode 100644 index 33d20f89c..000000000 --- a/doc/client/tools/debinit.txt +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-debinit: - -======= -DebInit -======= - -Debian Service Support; exec's update-rc.d to configure services. diff --git a/doc/client/tools/encap.txt b/doc/client/tools/encap.txt deleted file mode 100644 index 40508ac7a..000000000 --- a/doc/client/tools/encap.txt +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-encap: - -===== -Encap -===== - -`Encap `_ Packages. diff --git a/doc/client/tools/freebsdinit.txt b/doc/client/tools/freebsdinit.txt deleted file mode 100644 index 7df2518bc..000000000 --- a/doc/client/tools/freebsdinit.txt +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-freebsdinit: - -=========== -FreeBSDInit -=========== - -FreeBSD Service Support. Only bundle updates will work. diff --git a/doc/client/tools/freebsdpackage.txt b/doc/client/tools/freebsdpackage.txt deleted file mode 100644 index a460fb41c..000000000 --- a/doc/client/tools/freebsdpackage.txt +++ /dev/null @@ -1,10 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-freebsdpackage: - -============== -FreeBSDPackage -============== - -FreeBSD Packages. Verifies packages and their version numbers but can't -install packages. diff --git a/doc/client/tools/index.txt b/doc/client/tools/index.txt index 7f6e6b667..9bec46316 100644 --- a/doc/client/tools/index.txt +++ b/doc/client/tools/index.txt @@ -2,31 +2,154 @@ .. _client-tools-index: -Available client tools -====================== - -Client tool drivers allow Bcfg2 to execute configuration operations -by interfacing with platform and distribution specific tools. - -Tool drivers handle any reconfiguration or verification operation. -So far we have tools that primarily deal with packaging systems -and service management. The POSIX tool also handles file system -and permissions/groups operations. To write your own tool driver, -to handle a new packaging format, or new service architecture see -:ref:`development-client-driver`. - -When the Bcfg2 client is run, it attempts to instantiate each of -these drivers. The succeeding list of drivers are printed as a -debug message after this process has completed. Drivers can -supercede one another, for example, the Yum driver conflicts (and -unloads) the RPM driver. This behavior can be overridden by running -the Bcfg2 client with the ``-D`` flag. This flag takes a colon -delimited list of drivers to use on the system. +Client Tool Drivers +=================== + +Client tool drivers allow Bcfg2 to execute configuration operations by +interfacing with platform and distribution specific tools. + +Tool drivers handle any reconfiguration or verification operation. So +far we have tools that primarily deal with packaging systems and service +management. The POSIX tool also handles file system and permissions/groups +operations. + +To write your own tool driver, to handle a new packaging format, or new +service architecture see :ref:`development-index-writingtooldrivers` + +When the Bcfg2 client is run, it attempts to instantiate each of these +drivers. The succeeding list of drivers are printed as a debug message +after this process has completed. Drivers can supercede one another, +for example, the Yum driver conflicts (and unloads) the RPM driver. This +behavior can be overridden by running the Bcfg2 client with the ``-D`` +flag. This flag takes a colon delimited list of drivers to use on +the system. Currently these are the tool drivers that are distributed with Bcfg2: -.. toctree:: - :maxdepth: 1 - :glob: +Action +------ + +Pre and post-install tests and actions. This driver executes commands +and supplies status information to the Bcfg2 server via the statistics +mechanism. It can also be used to prevent bundle installation when +pre-conditions are not met. See the UsingActions page for more details. + +APT +--- + +Debian Packages. This tool driver is used to handle packages on dpkg +based systems and employs the "apt" executable. Extra information can be +found at :ref:`client-tools-apt`. + +Blast +----- + +Blastwave Packages. This tool driver is for blastwave packages on solaris + +Chkconfig +--------- + +Tool to manage services (primarily on Redhat based distros). + +.. note:: Start and stop are standard arguments, but the one for reload + isn't consistent across services. You can specify which argument + to use with the `restart` property in Service tags. Example: + ```` + +DebInit +------- + +Debian Service Support; exec's update-rc.d to configure services. + +Encap +----- + +`Encap `_ Packages. + +FreeBSDInit +----------- + +FreeBSD Service Support. Only bundle updates will work. + +FreeBSDPackage +-------------- + +FreeBSD Packages. Verifies packages and their version numbers but can't +install packages. + +launchd +------- + +Mac OS X Services. To use this tool, you must maintain a standard launch +daemon .plist file in ``/Library/LaunchDaemons/`` (example ssh.plist) +and setup a ```` entry in your config to load or unload the service. Note the name +is the ''Label'' specified inside of the .plist file + +Portage +------- + +Support for Gentoo Packages. + +POSIX +----- + +Files and Permissions are handled by the POSIX driver. Usage well +documented other places. + +RcUpdate +-------- + +Uses the rc-update executable to manage services on distributions such +as Gentoo. + +RPM +--- + +.. warning:: Deprecated in favor of :ref:`RPMng ` + +Executes rpm to manage packages most often on redhat based systems. + +RPMng +----- + +Next-generation RPM tool. Handles RPM sublties like epoch and +prelinking and 64-bit platforms better than the RPM client +tool. :ref:`client-tools-yumng` + +SMF +--- + +Solaris Service Support. + +Example legacy run service (lrc): + +.. code-block:: xml + + + +SYSV +---- + +Handles System V Packaging format that is available on Solaris. + +Upstart +------- + +Upstart service support. Uses `Upstart`_ to configure services. + +.. _Upstart: http://upstart.ubuntu.com/ + +Yum +--- + +.. warning:: Deprecated in favor of :ref:`YUMng ` + +Handles RPMs using the YUM package manager. + +YUMng +----- - * +Handles RPMs using the YUM package manager. Handles sublties better than +the Yum client tool. :ref:`client-tools-yumng` diff --git a/doc/client/tools/launchd.txt b/doc/client/tools/launchd.txt deleted file mode 100644 index 59a872297..000000000 --- a/doc/client/tools/launchd.txt +++ /dev/null @@ -1,13 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-launchd: - -======= -launchd -======= - -Mac OS X Services. To use this tool, you must maintain a standard launch -daemon .plist file in ``/Library/LaunchDaemons/`` (example ssh.plist) -and setup a ```` entry in your config to load or unload the service. Note the name -is the ''Label'' specified inside of the .plist file diff --git a/doc/client/tools/portage.txt b/doc/client/tools/portage.txt deleted file mode 100644 index 7a91408b1..000000000 --- a/doc/client/tools/portage.txt +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-portage: - -======= -Portage -======= - -Support for Gentoo Packages. diff --git a/doc/client/tools/posix.txt b/doc/client/tools/posix.txt deleted file mode 100644 index c4da38332..000000000 --- a/doc/client/tools/posix.txt +++ /dev/null @@ -1,10 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-posix: - -===== -POSIX -===== - -Files and Permissions are handled by the POSIX driver. Usage well -documented other places. diff --git a/doc/client/tools/rcupdate.txt b/doc/client/tools/rcupdate.txt deleted file mode 100644 index 4547d3b39..000000000 --- a/doc/client/tools/rcupdate.txt +++ /dev/null @@ -1,10 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-rcupdate: - -======== -RcUpdate -======== - -Uses the rc-update executable to manage services on distributions such -as Gentoo. diff --git a/doc/client/tools/rpm.txt b/doc/client/tools/rpm.txt deleted file mode 100644 index 17d367b55..000000000 --- a/doc/client/tools/rpm.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-rpm: - -=== -RPM -=== - -.. warning:: Deprecated in favor of :ref:`RPMng ` - -Executes rpm to manage packages most often on redhat based systems. diff --git a/doc/client/tools/rpmng.txt b/doc/client/tools/rpmng.txt deleted file mode 100644 index c6d6cddf1..000000000 --- a/doc/client/tools/rpmng.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-rpmng: - -===== -RPMng -===== - -Next-generation RPM tool, will be default in upcoming release. Handles -RPM sublties like epoch and prelinking and 64-bit platforms better than -RPM client tool. diff --git a/doc/client/tools/smf.txt b/doc/client/tools/smf.txt deleted file mode 100644 index 4829a14ed..000000000 --- a/doc/client/tools/smf.txt +++ /dev/null @@ -1,15 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-smf: - -=== -SMF -=== - -Solaris Service Support. - -Example legacy run service (lrc): - -.. code-block:: xml - - diff --git a/doc/client/tools/sysv.txt b/doc/client/tools/sysv.txt deleted file mode 100644 index c08614c52..000000000 --- a/doc/client/tools/sysv.txt +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-sysv: - -==== -SYSV -==== - -Handles System V Packaging format that is available on Solaris. diff --git a/doc/client/tools/upstart.txt b/doc/client/tools/upstart.txt deleted file mode 100644 index 60d0cf4ef..000000000 --- a/doc/client/tools/upstart.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-upstart: - -======= -Upstart -======= - -Upstart service support. Uses `Upstart`_ to configure services. - -.. _Upstart: http://upstart.ubuntu.com/ diff --git a/doc/client/tools/yum.txt b/doc/client/tools/yum.txt deleted file mode 100644 index fcb5244df..000000000 --- a/doc/client/tools/yum.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _client-tools-yum: - -=== -Yum -=== - -.. warning:: Deprecated in favor of :ref:`YUMng ` - -Handles RPMs using the YUM package manager. diff --git a/doc/conf.py b/doc/conf.py index e11cc4ca8..77ab6fd94 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -36,7 +36,8 @@ source_suffix = '.txt' #source_encoding = 'utf-8' # The master toctree document. -master_doc = 'contents' +#master_doc = 'contents' +master_doc = 'index' # General information about the project. project = u'Bcfg2' diff --git a/doc/contents.txt b/doc/contents.txt index df5c5350c..ab66e1b55 100644 --- a/doc/contents.txt +++ b/doc/contents.txt @@ -2,13 +2,12 @@ .. _contents: -========================================== -Welcome to Bcfg2's |version| documentation -========================================== +============================= +Bcfg2 documentation |release| +============================= .. toctree:: :maxdepth: 2 - :numbered: introduction/index installation/index @@ -18,7 +17,7 @@ Welcome to Bcfg2's |version| documentation client/index reports/index development/index - getting_help/index + help/index glossary appendix/index diff --git a/doc/development/client-driver.txt b/doc/development/client-driver.txt index 19da9cb67..cc065dd32 100644 --- a/doc/development/client-driver.txt +++ b/doc/development/client-driver.txt @@ -10,20 +10,20 @@ driver for a configuration element type. The included example describes an existing driver, and the process that was used to create it. #. Pick a name for the driver. In this case, we picked the name RPM. -#. Add "RPM" to the ``__all__ list`` in ``src/lib/Client/Tools/__init__.py`` +#. Add "RPM" to the ``__all__`` list in ``src/lib/Client/Tools/__init__.py`` #. Create a file in ``src/lib/Client/Tools`` with the same name (RPM.py) -#. Create a class in this file with the same name (``class RPM``) +#. Create a class in this file with the same name (class RPM) - * If it handles ``Package`` entries, subclass ``Bcfg2.Client.Tools.PkgTool`` + * If it handles **Package** entries, subclass ``Bcfg2.Client.Tools.PkgTool`` (from here referenced as branch [P]) - * If it handles ``Service`` entries, subclass ``Bcfg2.Client.Tools.SvcTool`` + * If it handles **Service** entries, subclass ``Bcfg2.Client.Tools.SvcTool`` (from here referenced as branch [S]) - * Otherwise, ``subclass Bcfg2.Client.Tools.Tool`` (from here referenced + * Otherwise, subclass ``Bcfg2.Client.Tools.Tool`` (from here referenced as branch [T]) #. Set ``__name__`` to "RPM" #. Add any required executable programs to ``__execs__`` -#. Set ``__handles__`` to a list of (``entry.tag``, ``entry.get('type')``) +#. Set ``__handles__`` to a list of (**entry.tag**, **entry.get('type')**) tuples. This determines which entries the Tool module can be used on. In this case, we set ``__handles__ = [('Package', 'rpm')]``. #. Add verification. This method should return True/False depending @@ -46,9 +46,9 @@ an existing driver, and the process that was used to create it. all-at-once installations, followed, in the case of failures, by single installations. To enable this support, set the pkgtype attribute to the package type handled by this driver. Set the - ``pkgtool`` to a tuple ("command string %s", ("per-package string + pkgtool to a tuple ("command string %s", ("per-package string format", [list of package entry fields])). For RPM, we have - ``setup pkgtool = ("rpm --oldpackage --replacepkgs --quiet -U %s", ("%s", ["url"]))`` + setup ``pkgtool = ("rpm --oldpackage --replacepkgs --quiet -U %s", ("%s", ["url"]))`` #. Implement entry removal diff --git a/doc/development/documentation.txt b/doc/development/documentation.txt index 8223670b8..0f75b9bba 100644 --- a/doc/development/documentation.txt +++ b/doc/development/documentation.txt @@ -19,22 +19,23 @@ The wiki .. _MCS: http://www.mcs.anl.gov/ .. _Argonne National Laboratory: http://www.anl.gov/ -A python-based Trac_ instance is used for the Bcfg2 website. The -Wiki_ part of the website can be edited after you have successful -logged in. For the login is a vaild OpenID provider needed and an -interaction from an administrator. Please request your access to -the Wiki_ on the :ref:`mailinglist` or in the :ref:`ircchannel`. +A python-based Trac_ instance is used for the Bcfg2 development +website. The Wiki_ part of the website can be edited after you +have successfully logged in. In order to login, a vaild OpenID +provider is needed. Please request your access to the Wiki_ on the +:ref:`help-mailinglist` or in the :ref:`help-irc`. The manual ---------- .. _rst: http://en.wikipedia.org/wiki/ReStructuredText .. _Sphinx: http://sphinx.pocoo.org -.. _Docutils: +.. _Docutils: -The source for the manual is located in the `doc/` directory in the -SVN repository or in the source tarball. All files are written in -rst_ (ReStructuredText). For the build process we are using Sphinx_. +The source for the manual is located in the ``doc/`` directory in the +git repository or in the source tarball. All files are written in +rst_ (ReStructuredText) format. Sphinx_ is used to build the +documentation from the restructured text sources. Building the Manual ^^^^^^^^^^^^^^^^^^^ @@ -42,7 +43,7 @@ Building the Manual * Install the prerequisites. Docutils_ and Sphinx_ are needed to build. * For Debian (Lenny) the tools are available in the `backports `_ repository; installation can be done with the following:: - + apt-get -t lenny-backports install python-sphinx * The needed tools for Fedora based systems are in the `Fedora Package Collection `_; installation can be done easily with Yum:: @@ -56,20 +57,14 @@ Building the Manual * Download the source. Please refer to :ref:`source` for more details. -* Building the HTML version, run the following command in the `doc/` directory. The output will appear in `../build/sphinx/html`:: +* Build the HTML version by running the following command in the + top level of the source directory. The output will appear in + ``build/sphinx/html``:: python setup.py build_sphinx * Building the PDF version :: - - python setup.py build_sphinx --builder=latex + + python setup.py build_sphinx --builder=latex cd build/sphinx/latex make - -The latest version of the manual -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The latest version of the manual can always be found -`on the Four Kitchens server `_. - -This is an auto-updated from the `Launchpad mirror `_. diff --git a/doc/development/emacs_snippet.txt b/doc/development/emacs_snippet.txt deleted file mode 100644 index 2905a2b45..000000000 --- a/doc/development/emacs_snippet.txt +++ /dev/null @@ -1,60 +0,0 @@ -.. -*- mode: rst -*- - -.. _development-emacs_snippet: - -====================== -Emacs + YASnippet mode -====================== - -This page describes using emacs with YASnippet mode with a set of -snippets that allow quick composition of bundles and base files. -More snippets are under development. - -#. Download YASnippet from http://code.google.com/p/yasnippet/ -#. Install it into your emacs load path (typically ~/.emacs.d/site-lisp) -#. Add YASnippet initialization to your .emacs (remember to re-byte-compile it if needed) - - .. code-block:: cl - - (require 'yasnippet-bundle) - - ;;; Bcfg2 snippet - - (yas/define-snippets 'sgml-mode - '( - (" - $0 - " nil) - (" - $0 - " nil) - (" - $0" nil) - (" - $0" nil) - (" - $0" nil) - (" - $0" nil) - (" - $0" nil) - (" - $0" nil) - (" - $0" nil) - ) - ) - -#. One quick M-x eval-current-buffer, and this code is enabled - -Each of these snippets activates on the opening element, ie , -and the snippet will be expanded. The template will be inserted into -the text with a set of input prompts, which default to overwrite mode -and can be tabbed through. - -The code above only works for bundles and base, but will be expanded -to support other xml files as well. diff --git a/doc/development/index.txt b/doc/development/index.txt index 222978c98..352000dc8 100644 --- a/doc/development/index.txt +++ b/doc/development/index.txt @@ -6,19 +6,12 @@ Bcfg2 Development ================= -There are several ways users can contribute to the Bcfg2 project. +There are many ways to get involved in Bcfg2 development. Here we will +outline some things that can help you get familiar with the various +areas of the Bcfg2 code. -* Developing code -* Testing prereleases -* Reporting bugs -* Adding to the common repository -* Improving the wiki and writing documentation - -This section will outline some things that can help you get familiar -with the various areas of the Bcfg2 code. - -Send patches to the :ref:`mailinglist` or create a trac +Send patches to the :ref:`help-mailinglist` or create a trac `ticket `_ with the patch included. In order to submit a ticket via the trac system, you will need to create a session by clicking on the @@ -33,22 +26,16 @@ The source tree can be checked out by running:: git clone git://git.mcs.anl.gov/bcfg2.git Users wishing to contribute on a regular basis can apply for direct -git access. Mail the :ref:`mailinglist` for details. +git access. Mail the :ref:`help-mailinglist` for details. .. toctree:: :maxdepth: 1 - + tips setup client-driver plugins - writing_plugins - plugin-types - writing_specification - server testing documentation docstyleguide - emacs_snippet - vim_snippet diff --git a/doc/development/plugin-types.txt b/doc/development/plugin-types.txt deleted file mode 100644 index 5f0a4771a..000000000 --- a/doc/development/plugin-types.txt +++ /dev/null @@ -1,46 +0,0 @@ -.. -*- mode: rst -*- - -.. _development-plugin-types: - -Server Plugin Types -------------------- - -Generator -^^^^^^^^^ - -Generator plugins contribute to literal client configurations - -Structure -^^^^^^^^^ - -Structure Plugins contribute to abstract client configurations - -Metadata -^^^^^^^^ - -Signal metadata capabilities - -Connector -^^^^^^^^^ - -Connector Plugins augment client metadata instances - -Probing -^^^^^^^ - -Signal probe capability - -Statistics -^^^^^^^^^^ - -Signal statistics handling capability - -Decision -^^^^^^^^ - -Signal decision handling capability - -Version -^^^^^^^ - -Interact with various version control systems diff --git a/doc/development/plugins.txt b/doc/development/plugins.txt index b6debba24..709b9fcec 100644 --- a/doc/development/plugins.txt +++ b/doc/development/plugins.txt @@ -3,7 +3,7 @@ .. _development-plugins: Bcfg2 Plugin development ------------------------- +======================== While the Bcfg2 server provides a good interface for representing general system configurations, its plugin interface offers the ability @@ -12,7 +12,7 @@ problems encountered by a particular site. This chapter describes what plugins are good for, what they can do, and how to implement them. Bcfg2 Plugins -^^^^^^^^^^^^^ +------------- Bcfg2 plugins are loadable python modules that the Bcfg2 server loads at initialization time. These plugins can contribute to the functions already @@ -43,3 +43,171 @@ The following table describes the various functions of bcfg2 plugins. | | expose internal functions. | +--------------------+---------------------------------------------+ +Server Plugin Types +------------------- + +Generator +^^^^^^^^^ + +Generator plugins contribute to literal client configurations + +Structure +^^^^^^^^^ + +Structure Plugins contribute to abstract client configurations + +Metadata +^^^^^^^^ + +Signal metadata capabilities + +Connector +^^^^^^^^^ + +Connector Plugins augment client metadata instances + +Probing +^^^^^^^ + +Signal probe capability + +Statistics +^^^^^^^^^^ + +Signal statistics handling capability + +Decision +^^^^^^^^ + +Signal decision handling capability + +Version +^^^^^^^ + +Interact with various version control systems + +Writing Bcfg2 Server Plugins +---------------------------- + +Bcfg2 plugins are python classes that subclass from +Bcfg2.Server.Plugin.Plugin. Several plugin-specific values must be set +in the new plugin. These values dictate how the new plugin will behave +with respect to the above four functions. The following table describes +all important member fields. + ++-----------------+-----------------------------------+--------------------------+ +| Name | Description | Format | ++=================+===================================+==========================+ +| __name__ | The name of the plugin | string | ++-----------------+-----------------------------------+--------------------------+ +| __version__ | The plugin version (generally | string | +| | tied to revctl keyword expansion) | | ++-----------------+-----------------------------------+--------------------------+ +| __author__ | The plugin author. | string | ++-----------------+-----------------------------------+--------------------------+ +| __author__ | The plugin author. | string | ++-----------------+-----------------------------------+--------------------------+ +| __rmi__ | Set of functions to be exposed as | List of function names | +| | XML-RPC functions | (strings) | ++-----------------+-----------------------------------+--------------------------+ +| Entries | Multidimentional dictionary of | Dictionary of | +| | keys that point to the function | ConfigurationEntityType, | +| | used to bind literal contents for | Name keys, and function | +| | a given configuration entity. | reference values | ++-----------------+-----------------------------------+--------------------------+ +| BuildStructures | Function that returns a list of | Member function | +| | the structures for a given client | | ++-----------------+-----------------------------------+--------------------------+ +| GetProbes | Function that returns a list of | Member function | +| | probes that a given client should | | +| | execute | | ++-----------------+-----------------------------------+--------------------------+ +| ReceiveData | Function that accepts the probe | Member function | +| | results for a given client. | | ++-----------------+-----------------------------------+--------------------------+ + +Example Plugin +^^^^^^^^^^^^^^ + +.. code-block:: python + + import Bcfg2.Server.Plugin + class MyPlugin(Bcfg2.Server.Plugin.Plugin): + '''An example plugin''' + # All plugins need to subclass Bcfg2.Server.Plugin.Plugin + __name__ = 'MyPlugin' + __version__ = '1' + __author__ = 'me@me.com' + __rmi__ = ['myfunction'] + # myfunction is not available remotely as MyPlugin.myfunction + + def __init__(self, core, datastore): + Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) + self.Entries = {'Path':{'/etc/foo.conf': self.buildFoo}} + + def myfunction(self): + '''function for xmlrpc rmi call''' + #do something + return True + + def buildFoo(self, entry, metadata): + '''Bind per-client information into entry based on metadata''' + entry.attrib.update({'type':'file', 'owner':'root', 'group':'root', 'perms':'644'}) + entry.text = '''contents of foo.conf''' + +Example Connector +^^^^^^^^^^^^^^^^^ + +.. code-block:: python + + import Bcfg2.Server.Plugin + + class Foo(Bcfg2.Server.Plugin.Plugin, + Bcfg2.Server.Plugin.Connector): + '''The Foo plugin is here to illustrate a barebones connector''' + name = 'Foo' + version = '$Revision: $' + experimental = True + + def __init__(self, core, datastore): + Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) + Bcfg2.Server.Plugin.Connector.__init__(self) + self.store = XMLFileBacked(self.data, core.fam) + + def get_additional_data(self, metadata): + + mydata = {} + for data in self.store.entries['foo.xml'].data.get("foo", []): + + mydata[data] = "bar" + + return dict([('mydata', mydata)]) + + def get_additional_groups(self, meta): + return self.cgroups.get(meta.hostname, list()) + +Example Metadata plugin +^^^^^^^^^^^^^^^^^^^^^^^ + +If you would like to define your own Metadata plugin (to extend/change +functionality of the existing Metadata plugin), here are the steps to +do so. We will call our new plugin `MyMetadata`. + +#. Add MyMetadata.py + + .. code-block:: python + + __revision__ = '$Revision$' + + import Bcfg2.Server.Plugins.Metadata + + class MyMetadata(Bcfg2.Server.Plugins.Metadata.Metadata): + '''This class contains data for bcfg2 server metadata''' + __version__ = '$Id$' + __author__ = 'bcfg-dev@mcs.anl.gov' + + def __init__(self, core, datastore, watch_clients=True): + Bcfg2.Server.Plugins.Metadata.Metadata.__init__(self, core, datastore, watch_clients) + +#. Add MyMetadata to ``src/lib/Server/Plugins/__init__.py`` +#. Replace Metadata with MyMetadata in the plugins line of bcfg2.conf diff --git a/doc/development/server.txt b/doc/development/server.txt deleted file mode 100644 index 0f594422e..000000000 --- a/doc/development/server.txt +++ /dev/null @@ -1,83 +0,0 @@ -.. -*- mode: rst -*- - -.. _development-server-plugins: - -Writing Server Plugins ----------------------- - -Metadata -^^^^^^^^ - -If you would like to define your own Metadata plugin (to extend/change -functionality of the existing Metadata plugin), here are the steps to -do so. We will call our new plugin `MyMetadata`. - -#. Add MyMetadata.py - - .. code-block:: python - - __revision__ = '$Revision$' - - import Bcfg2.Server.Plugins.Metadata - - class MyMetadata(Bcfg2.Server.Plugins.Metadata.Metadata): - '''This class contains data for bcfg2 server metadata''' - __version__ = '$Id$' - __author__ = 'bcfg-dev@mcs.anl.gov' - - def __init__(self, core, datastore, watch_clients=True): - Bcfg2.Server.Plugins.Metadata.Metadata.__init__(self, core, datastore, watch_clients) - -#. Add MyMetadata to ``src/lib/Server/Plugins/__init__.py`` -#. Replace Metadata with MyMetadata in the plugins line of bcfg2.conf - -.. _development-server-packages: - -Packages --------- - -In order to support a given client package tool driver, that driver -must support use of the auto value for the version attribute in Package -entries. In this case, the tool driver views the current state of -available packages, and uses the underlying package manager's choice of -correct package version in lieu of an explicit, centrally-specified, -version. This support enables Packages to provide a list of Package -entries with version='auto'. Currently, the APT and YUMng drivers support -this feature. Note that package management systems without any network -support cannot operate in this fashion, so RPMng and SYSV will never be -able to use Packages. Emerge, Zypper, IPS, and Blastwave all have the -needed features to be supported by Packages, but support has not yet -been written. - -Packages fills two major functions in configuration generation. The first -is to provide entry level binding support for Package entries included -in client configurations. This function is quite easy to implement; -Packages determines (based on client group membership) if the package -is available for the client system, and which type it has. Because -version='auto' is used, no version determination needs to be done. - -The second major function is more complex. Packages ensures that client -configurations include all package-level prerequisites for package entries -explicitly included in the configuration. In order to support this, -Packages needs to directly process network data for package management -systems (the network sources for apt or yum, for examples), process -these files, and build data structures describing prerequisites and the -providers of those functions/paths. To simplify implementations of this, -there is a generic base class (Bcfg2.Server.Plugins.Packages.Source) -that provides a framework for fetching network data via HTTP, processing -those sources (with subclass defined methods for processing the specific -format provided by the tool), a generic dependency resolution method, -and a caching mechanism that greatly speeds up server/bcfg2-info startup. - -Each source type must define: - -* a get_urls attribute (and associated urls property) that describes - the URLS where to get data from. -* a read_files method that reads and processes the downloaded files - -Sources may define a get_provides method, if provides are complex. For -example, provides in rpm can be either rpm names or file paths, so -multiple data sources need to be multiplexed. - -The APT source in ``src/lib/Server/Plugins/Packages.py`` provides a -relatively simple implementation of a source. diff --git a/doc/development/setup.txt b/doc/development/setup.txt index 08a85dac1..8729ee76e 100644 --- a/doc/development/setup.txt +++ b/doc/development/setup.txt @@ -8,7 +8,7 @@ Environment setup for development * Check out a copy of the code:: - svn co https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2 + git clone git://git.mcs.anl.gov/bcfg2.git * Create link to ``src/lib``:: diff --git a/doc/development/vim_snippet.txt b/doc/development/vim_snippet.txt deleted file mode 100644 index a01c1cfda..000000000 --- a/doc/development/vim_snippet.txt +++ /dev/null @@ -1,65 +0,0 @@ -.. -*- mode: rst -*- - -.. _development-vim_snippet: - -=================== -Vim Snippet Support -=================== - -This page describes using vim with snipMate and a set of snippets -that allow quick composition of bundles and base files. - -#. Download snipMate from http://www.vim.org/scripts/script.php?script_id=2540 -#. Install it using the install instructions (unzip snipMate.zip -d ~/.vim or equivalent, e.g. $HOME\vimfiles on Windows) -#. Add the following to ``~/.vim/snippets/xml.snippets`` - - .. code-block:: cl - - # Bundle - snippet - ${2} - - # Base - snippet - ${1} - - # Group - snippet - ${2} - - # ConfigFile - snippet - # Service - snippet - # Package - snippet - # Action - snippet - # Directory - snippet - # SymLink - snippet - # Permissions - snippet - - -#. Save and start editing away! - -Each of these snippets activates on the opening element, ie . -After this string is entered, but before entering a space, press , -and the snippet will be expanded. The template will be inserted into -the text with a set of input prompts, which default to overwrite mode -and can be tabbed through. - -The code above only works for bundles and base, but will be expanded -to support other xml files as well. diff --git a/doc/development/writing_plugins.txt b/doc/development/writing_plugins.txt deleted file mode 100644 index 40e077e43..000000000 --- a/doc/development/writing_plugins.txt +++ /dev/null @@ -1,104 +0,0 @@ -.. -*- mode: rst -*- - -.. _development-write-plugins: - -Writing Bcfg2 Plugins -===================== - -Bcfg2 plugins are python classes that subclass from -Bcfg2.Server.Plugin.Plugin. Several plugin-specific values must be set -in the new plugin. These values dictate how the new plugin will behave -with respect to the above four functions. The following table describes -all important member fields. - -+-----------------+-----------------------------------+--------------------------+ -| Name | Description | Format | -+=================+===================================+==========================+ -| __name__ | The name of the plugin | string | -+-----------------+-----------------------------------+--------------------------+ -| __version__ | The plugin version (generally | string | -| | tied to revctl keyword expansion) | | -+-----------------+-----------------------------------+--------------------------+ -| __author__ | The plugin author. | string | -+-----------------+-----------------------------------+--------------------------+ -| __author__ | The plugin author. | string | -+-----------------+-----------------------------------+--------------------------+ -| __rmi__ | Set of functions to be exposed as | List of function names | -| | XML-RPC functions | (strings) | -+-----------------+-----------------------------------+--------------------------+ -| Entries | Multidimentional dictionary of | Dictionary of | -| | keys that point to the function | ConfigurationEntityType, | -| | used to bind literal contents for | Name keys, and function | -| | a given configuration entity. | reference values | -+-----------------+-----------------------------------+--------------------------+ -| BuildStructures | Function that returns a list of | Member function | -| | the structures for a given client | | -+-----------------+-----------------------------------+--------------------------+ -| GetProbes | Function that returns a list of | Member function | -| | probes that a given client should | | -| | execute | | -+-----------------+-----------------------------------+--------------------------+ -| ReceiveData | Function that accepts the probe | Member function | -| | results for a given client. | | -+-----------------+-----------------------------------+--------------------------+ - -Example Plugin --------------- - -.. code-block:: python - - import Bcfg2.Server.Plugin - class MyPlugin(Bcfg2.Server.Plugin.Plugin): - '''An example plugin''' - # All plugins need to subclass Bcfg2.Server.Plugin.Plugin - __name__ = 'MyPlugin' - __version__ = '1' - __author__ = 'me@me.com' - __rmi__ = ['myfunction'] - # myfunction is not available remotely as MyPlugin.myfunction - - def __init__(self, core, datastore): - Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) - self.Entries = {'Path':{'/etc/foo.conf': self.buildFoo}} - - def myfunction(self): - '''function for xmlrpc rmi call''' - #do something - return True - - def buildFoo(self, entry, metadata): - '''Bind per-client information into entry based on metadata''' - entry.attrib.update({'type':'file', 'owner':'root', 'group':'root', 'perms':'644'}) - entry.text = '''contents of foo.conf''' - -Example Connector ------------------ - -.. code-block:: python - - import Bcfg2.Server.Plugin - - class Foo(Bcfg2.Server.Plugin.Plugin, - Bcfg2.Server.Plugin.Connector): - '''The Foo plugin is here to illustrate a barebones connector''' - name = 'Foo' - version = '$Revision: $' - experimental = True - - def __init__(self, core, datastore): - Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) - Bcfg2.Server.Plugin.Connector.__init__(self) - self.store = XMLFileBacked(self.data, core.fam) - - def get_additional_data(self, metadata): - - mydata = {} - for data in self.store.entries['foo.xml'].data.get("foo", []): - - mydata[data] = "bar" - - return dict([('mydata', mydata)]) - - def get_additional_groups(self, meta): - return self.cgroups.get(meta.hostname, list()) - diff --git a/doc/development/writing_specification.txt b/doc/development/writing_specification.txt deleted file mode 100644 index 4e1c03483..000000000 --- a/doc/development/writing_specification.txt +++ /dev/null @@ -1,54 +0,0 @@ -.. -*- mode: rst -*- - -.. _development-writing_specification: - -=========================== -Writing Bcfg2 Specification -=========================== - -Bcfg2 specifications are logically divided in to three areas: - -* Metadata -* Abstract -* Literal - -The metadata portion of the configuration assigns a client to its profile -group and to its non-profile groups. The profile group is assigned -in ``Metadata/clients.xml`` and the non profile group assignments are in -``Metadata/groups.xml``. - -The group memberships contained in the metadata are then used to constuct -an abstract configuration for the client. An abstract configuration for -a client identifies the configuration entities (packages, configuration -files, service, etc) that a client requires, but it does not identify -them explicitly. For instance an abstract configuration may identify -that a client needs the Bcfg2 package with - -.. code-block:: xml - - - -but this does not explicitly identify that an RPM package version -0.9.2 should be loaded from http://rpm.repo.server/bcfg2-1.0.1-0.1.rpm. -The abstract configuration is defined in the xml configuration files -for the Base and Bundles plugins. - -A combination of a clients metadata (group memberships) and abstract -configuration is then used to generate the clients literal configuration. -For instance the above abstract configuration entry may generate a -literal configuration of - - -.. code-block:: xml - - - -A clients literal configuration is generated by a number of plugins that -handle the different configuration entities. - - -.. figure:: specification_overview.png - :width: 60% - :alt: Specification overview - :align: center - diff --git a/doc/getting_help/error-messages.txt b/doc/getting_help/error-messages.txt deleted file mode 100644 index 72d1f1f40..000000000 --- a/doc/getting_help/error-messages.txt +++ /dev/null @@ -1,45 +0,0 @@ -.. -*- mode: rst -*- - -.. _error-messages: - -============== -Error Messages -============== - -This page describes error messages produced by Bcfg2 and steps that -can be taken to remedy them. - -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ -| Error | Location | Meaning | Repair | -+===========================================================================+==========+=====================================================================================================+=========+ -| Incomplete information for entry :; cannot verify | Client | The described entry is not fully specified by the server, so no verification can be performed. | [#f1]_ | -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ -| Incomplete information for entry :; cannot install | Client | The described entry is not fully specified by the server, so no verification can be performed. | [#f2]_ | -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ -| The following entries are not handled by any tool: : | Client | The client cannot figure out how to handle this entry. | [#f3]_ | -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ -| no server x509 fingerprint; no server verification performed! | Client | The client is unable to verify the server | [#f4]_ | -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ -| Failed to bind entry: | Server | The server was unable to find a suitable version of entry for client. | [#f5]_ | -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ -| Failed to bind to socket | Server | The server was unable to bind to the tcp server socket. | [#f6]_ | -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ -| Failed to load ssl key | Server | The server was unable to read and process the ssl key. | [#f7]_ | -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ -| Failed to read file | Server | The server failed to read the specified file | [#f8]_ | -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ -| Failed to parse file | Server | The server failed to parse the specified XML file | [#f9]_ | -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ -| Client metadata resolution error for | Server | The server cannot resolve the client hostname or the client is associated with a non-profile group. | [#f10]_ | -+---------------------------------------------------------------------------+----------+-----------------------------------------------------------------------------------------------------+---------+ - -.. [#f1] This entry is not being bound. Ensure that a version of this entry applies to this client. -.. [#f2] This entry is not being bound. Ensure that a version of this entry applies to this client. -.. [#f3] Add a type to the generator definition for this entry -.. [#f4] Run bcfg2-admin fingerprint on the server and add it to the client bcfg2.conf as mentioned here -.. [#f5] This entry is not being bound. Ensure that a version of this entry applies to this client. -.. [#f6] Ensure that another instance of the daemon (or any other process) is not listening on the same port. -.. [#f7] Ensure that the key is readable by the user running the daemon and that it is well-formed. -.. [#f8] Ensure that this file still exists; a frequent cause is the deletion of a temp file. -.. [#f9] Ensure that the file is properly formed XML. -.. [#f10] Fix hostname resolution for the client or ensure that the profile group is properly setup. diff --git a/doc/getting_help/faq/client.txt b/doc/getting_help/faq/client.txt deleted file mode 100644 index a230a84bb..000000000 --- a/doc/getting_help/faq/client.txt +++ /dev/null @@ -1,16 +0,0 @@ -.. -*- mode: rst -*- - -.. _faq-client: - -FAQ: Client -=========== - -**No ca is specified. Cannot authenticate the server with SSL.** - -This means that the client does not have a copy of the CA for the server, -so it can't verify that it is talking to the right server. To fix this -issue, copy ``/etc/bcfg2.crt`` from the server to ``/etc/bcfg2.ca`` -on the client. Then add the following on the client. :: - - [communication] - ca = /etc/bcfg2.ca diff --git a/doc/getting_help/faq/general.txt b/doc/getting_help/faq/general.txt deleted file mode 100644 index f08bfb7b2..000000000 --- a/doc/getting_help/faq/general.txt +++ /dev/null @@ -1,72 +0,0 @@ -.. -*- mode: rst -*- - -.. _faq-general: - -FAQ: General -============ - -**What does Bcfg2 stand for?** - -Initially, Bcfg stood for the bundle configuration system. Bcfg2 is the -second major revision. At this point, the acronym is meaningless, but -the name has stuck. Luckily, Bcfg2 googles better than Bcfg does. No, -seriously. Try it. All I know is that I have no interest in a billion -cubic feet of gas. - -**What architectures does Bcfg2 support?** - -Bcfg2 should run on any POSIX compatible operating system, however direct -support for an operating system's package and service formats are limited -by the currently available :ref:`client-tools-index` (although new client -tools are pretty easy to add). The following is an incomplete but more -exact list of platforms on which Bcfg2 works. - -* GNU/Linux deb based distros -* GNU/Linux rpm based distros -* Solaris pkg based -* Gentoo portage based -* OSX (POSIX/launchd support) - -**What pre-requisites are needed to run Bcfg2?** - -Please visit the :ref:`prerequisites` section in the manual. - -**Why won't bcfg2-server start?** - -If your server doesn't seem to be starting and you see no error -messages in your server logs, try running it in the foreground to -see why. - -**Why am I getting a traceback?** - -If you get a traceback, please let us know. You can file a -`ticket `_, send -the traceback to the :ref:`mailinglist`, or hop on -:ref:`ircchannel` and let us know. - -**What is the most common cause of "The following entries are not handled by any tool"?** - -Often it corresponds to entries that aren't bound by the server (for which you'll get error messages on the server). You should try inspecting the logs on the server to see what may be the cause. - -**How can I figure out if error is client or server side?** - -* Cache a copy of the client using ``bcfg2 -c /tmp/config.xml`` -* Search for the entry of interest -* If it looks correct, then there is a client issue - -This file contains all aspects of client configuration. It is structured as a series of bundles and base entries. - -.. note:: - - Most often the entry is not correct and the issue lies in the specification. - -**Where are the server log messages?** - -The bcfg2-server process logs to syslog facility LOG_DAEMON. The server produces a series of messages upon a variety of events and errors. - -**Is there a way to check if all repository XML files conform to schemas?** - -Bcfg2 comes with XML schemas describing all of the XML formats used in -the server repository. A validation command ``bcfg2-repo-validate`` is -included with the source distribution and all packages. Run it with -the ``-v`` flag to see each file and the results if its validation. diff --git a/doc/getting_help/faq/index.txt b/doc/getting_help/faq/index.txt deleted file mode 100644 index 27aa5303f..000000000 --- a/doc/getting_help/faq/index.txt +++ /dev/null @@ -1,17 +0,0 @@ -.. -*- mode: rst -*- - -.. _faq-index: - -=== -FAQ -=== - -The Frequently Asked Questions (FAQ) answers the most common questions -about Bcfg2. At the moment the FAQ is splitted into a general -and a client specfic section. - -.. toctree:: - :maxdepth: 2 - - general - client diff --git a/doc/getting_help/index.txt b/doc/getting_help/index.txt deleted file mode 100644 index 1060a8f4b..000000000 --- a/doc/getting_help/index.txt +++ /dev/null @@ -1,41 +0,0 @@ -.. -*- mode: rst -*- - -.. _gettinghelp-index: - -.. _IRC logs: http://colabti.org/irclogger/irclogger_logs/bcfg2 - - -Getting Help -============ - -Having trouble? We'd like to help! - -There are several ways to get in touch with the community around Bcfg2. - -* Try the :ref:`FAQ ` -- it's got answers to many common - questions. - -* Looking for specific information? Try the :ref:`genindex`, - :ref:`modindex`, or the :ref:`detailed table of contents `. - -* Search for information in the :ref:`mailinglist`. - -* Ask a question in the :ref:`ircchannel`, or search the `IRC logs`_ - to see if its been asked before. - -Note that the IRC channel tends to be much busier than the mailing -list; use whichever seems most appropriate for your query, but don't -let the lack of mailing list activity make you think the project isn't -active. - - -.. toctree:: - :maxdepth: 1 - - reporting - mailinglist - ircchannel - faq/index - error-messages - manpages - troubleshooting diff --git a/doc/getting_help/ircchannel.txt b/doc/getting_help/ircchannel.txt deleted file mode 100644 index b97e5f6a6..000000000 --- a/doc/getting_help/ircchannel.txt +++ /dev/null @@ -1,28 +0,0 @@ -.. -*- mode: rst -*- - -.. _Freenode: http://chat.freenode.net -.. _#bcfg2: irc://chat.freenode.net/bcfg2 - -.. _ircchannel: - -=========== -IRC Channel -=========== - -The Bcfg2 IRC channel is `#bcfg2`_ on `Freenode`_. It is home to both support and development discussions. If you have a question, suggestion, or just want to know about Bcfg2, please drop in and say hi. - -Archives are available at: http://colabti.org/irclogger/irclogger_logs/bcfg2 - -.. raw:: html - -
- - -
- in the timespan - - (yyyymmdd-yyyymmdd) -

Options:
-
-
- diff --git a/doc/getting_help/mailinglist.txt b/doc/getting_help/mailinglist.txt deleted file mode 100644 index c77caa0c4..000000000 --- a/doc/getting_help/mailinglist.txt +++ /dev/null @@ -1,24 +0,0 @@ -.. -*- mode: rst -*- - -.. _help-mailinglist: - -============ -Mailing List -============ - -To subscribe to the mailing list for Bcfg2 please visit the `bcfg-dev -mailman page`_ - -`Searchable archives`_ are available from Gmane. You can also read the -mailing list from any NNTP client via Gmane. - -.. _bcfg-dev mailman page: https://lists.mcs.anl.gov/mailman/listinfo/bcfg-dev -.. _Searchable archives: http://dir.gmane.org/gmane.comp.sysutils.bcfg2.devel - -.. raw:: html - -
- - - - diff --git a/doc/getting_help/manpages.txt b/doc/getting_help/manpages.txt deleted file mode 100644 index 14c22a92e..000000000 --- a/doc/getting_help/manpages.txt +++ /dev/null @@ -1,16 +0,0 @@ -.. -*- mode: rst -*- - -.. _manpages: - -============ -Manual pages -============ - -These are copies of the bcfg2 manual pages created with man2html. -The most recent versions of these man pages are always in the `man/` -directory in the source. - -.. toctree:: - :glob: - - manpages/* diff --git a/doc/getting_help/manpages/bcfg2-admin.txt b/doc/getting_help/manpages/bcfg2-admin.txt deleted file mode 100644 index 4440c7134..000000000 --- a/doc/getting_help/manpages/bcfg2-admin.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _manpages-bcfg2-admin: - -=========== -bcfg2-admin -=========== - -The man page of ``bcfg2-admin``. :: - - man bcfg2-admin diff --git a/doc/getting_help/manpages/bcfg2-build-reports.txt b/doc/getting_help/manpages/bcfg2-build-reports.txt deleted file mode 100644 index 217c25627..000000000 --- a/doc/getting_help/manpages/bcfg2-build-reports.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _manpages-bcfg2-build-reports: - -=================== -bcfg2-build-reports -=================== - -The man page of ``bcfg2-build-reports``. :: - - man bcfg2-build-reports diff --git a/doc/getting_help/manpages/bcfg2-conf.txt b/doc/getting_help/manpages/bcfg2-conf.txt deleted file mode 100644 index 623521a67..000000000 --- a/doc/getting_help/manpages/bcfg2-conf.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _manpages-bcfg2.conf: - -========== -bcfg2.conf -========== - -The man page of ``bcfg2.conf``. :: - - man bcfg2.conf diff --git a/doc/getting_help/manpages/bcfg2-info.txt b/doc/getting_help/manpages/bcfg2-info.txt deleted file mode 100644 index 751905e0b..000000000 --- a/doc/getting_help/manpages/bcfg2-info.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _manpages-bcfg2-info: - -========== -bcfg2-info -========== - -The man page of ``bcfg2-info``. :: - - man bcfg2-info diff --git a/doc/getting_help/manpages/bcfg2-repo-validate.txt b/doc/getting_help/manpages/bcfg2-repo-validate.txt deleted file mode 100644 index b13bd928b..000000000 --- a/doc/getting_help/manpages/bcfg2-repo-validate.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _manpages-bcfg2-repo-validate: - -=================== -bcfg2-repo-validate -=================== - -The man page of ``bcfg2-repo-validate``. :: - - man bcfg2-repo-validate diff --git a/doc/getting_help/manpages/bcfg2-server.txt b/doc/getting_help/manpages/bcfg2-server.txt deleted file mode 100644 index 27002789e..000000000 --- a/doc/getting_help/manpages/bcfg2-server.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _manpages-bcfg2-server: - -============ -bcfg2-server -============ - -The man page of ``bcfg2-server``. :: - - man bcfg2-server diff --git a/doc/getting_help/manpages/bcfg2.txt b/doc/getting_help/manpages/bcfg2.txt deleted file mode 100644 index 4e93ab449..000000000 --- a/doc/getting_help/manpages/bcfg2.txt +++ /dev/null @@ -1,11 +0,0 @@ -.. -*- mode: rst -*- - -.. _manpages-bcfg2: - -===== -bcfg2 -===== - -The man page of bcfg2. :: - - man bcfg2 diff --git a/doc/getting_help/reporting.txt b/doc/getting_help/reporting.txt deleted file mode 100644 index cd53b1206..000000000 --- a/doc/getting_help/reporting.txt +++ /dev/null @@ -1,12 +0,0 @@ -.. -*- mode: rst -*- - -.. _reporting: - -.. _tracker: http://trac.mcs.anl.gov/projects/bcfg2/wiki - -============== -Reporting bugs -============== - -Report bugs with Bcfg2 in our `tracker`_. - diff --git a/doc/getting_help/troubleshooting.txt b/doc/getting_help/troubleshooting.txt deleted file mode 100644 index cce9c3d78..000000000 --- a/doc/getting_help/troubleshooting.txt +++ /dev/null @@ -1,184 +0,0 @@ -.. -*- mode: rst -*- - -.. _troubleshooting: - -=============== -Troubleshooting -=============== - -From time to time, Bcfg2 produces results that the user finds surprising. -This can happen either due to bugs or user error. This page describes -several techniques to gain visibility into the bcfg2 client and server -and understand what is going on. - - -Figure out if error is client or server side -============================================ - -* Cache a copy of the client configuration using ``bcfg2 -qnc /tmp/config.xml`` -* Look in the file and search for the entry of interest -* If it looks correct, then there is a client issue -* If not, it is time to inspect things on the server - -This file contains all aspects of client configuration. It is structured -as a series of bundles and base entries. - -.. note:: - - Most often the entry is not correct and the issue lies in - the specification. - -Review server log messages -========================== - -The bcfg2-server process logs to syslog facility LOG_DAEMON. The server -produces a series of messages upon a variety of events and errors. - -Check if all repository XML files conform to schemas -==================================================== - -Bcfg2 comes with XML schemas describing all of the XML formats used in -the server repository. A validation command ``bcfg2-repo-validate`` is -included with the source distribution and all packages. Run it with the --v flag to see each file and the results if its validation. - -If the bcfg2 server is not reflecting recent changes, try restarting the bcfg2-server process -============================================================================================= - -If this fixes the problem, it is either a bug in the -underlying file monitoring system (fam or gamin) or a bug in -Bcfg2's file monitoring code. In either case, file a `ticket -`_ in the tracking -system. In the ticket, include: - -* filesystem monitoring system (fam or gamin) -* kernel version (if on linux) -* if any messages of the form "Handled N events in M - seconds" appeared between the modification event and the client - configuration generation request appeared in the server log -* which plugin handled the file in the repostiory (Cfg, Rules, Packages, - TCheetah, TGenshi, Metadata) -* if a touch of the file after the modification causes the problem to - go away - -bcfg2-info -========== - -Bcfg2 server operations can be simulated using the ``bcfg2-info`` command. -The command is interactive, and has commands to allow several useful -operations - -* clients - Current client metadata (profile and group) settings -* groups - Current group metadata values -* mappings - Configuration entries provided by plugins -* buildfile - Build a config file for a client -* showentries - Build the abstract configuration (list - of entries) for a client -* build - Build the complete configuration - for a client - -Type `help` in bcfg2-info for more information. - -Error Messages -============== - -This page describes error messages produced by Bcfg2 and steps that can -be taken to remedy them. - -+------------------------------+----------+---------------------+--------------+ -| Error | Location | Meaning | Repair | -+==============================+==========+=====================+==============+ -| Incomplete information for | Client | The described entry | [1]_ | -| entry : | | is not fully | | -| cannot verify | | specified by the | | -| | | server, so no | | -| | | verification can be | | -| | | performed. | | -+------------------------------+----------+---------------------+--------------+ -| Incomplete information for | Client | The described entry | [1]_ | -| entry : | | is not fully | | -| cannot install | | specified by the | | -| | | server, so no | | -| | | verification can be | | -| | | performed. | | -+------------------------------+----------+---------------------+--------------+ -| The following entries are | Client | The client cannot | [2]_ | -| not handled by any tool: | | figure out how to | | -| : | | handle this entry. | | -+------------------------------+----------+---------------------+--------------+ -| No ca is specified. Cannot | Client | The client is | [3]_ | -| authenticate the server with | | unable to verify | | -| SSL. | | the server | | -+------------------------------+----------+---------------------+--------------+ -| Failed to bind entry: | Server | The server was | [4]_ | -| | | unable to find a | | -| | | suitable version of | | -| | | entry for client. | | -+------------------------------+----------+---------------------+--------------+ -| Failed to bind to socket | Server | The server was | [5]_ | -| | | unable to bind to | | -| | | the tcp server | | -| | | socket. | | -+------------------------------+----------+---------------------+--------------+ -| Failed to load | Server | The server was | [6]_ | -| ssl key | | unable to read and | | -| | | process the ssl key.| | -+------------------------------+----------+---------------------+--------------+ -| Failed to read file | Server | The server failed | [7]_ | -| | | to read the | | -| | | specified file | | -+------------------------------+----------+---------------------+--------------+ -| Failed to parse file | Server | The server failed | [8]_ | -| | | to parse the | | -| | | specified XML file | | -+------------------------------+----------+---------------------+--------------+ -| Client metadata resolution | Server | The server cannot | [9]_ | -| error for | | resolve the client | | -| | | hostname or the | | -| | | client is | | -| | | associated with a | | -| | | non-profile group. | | -+------------------------------+----------+---------------------+--------------+ - - -.. [1] This entry is not being bound. Ensure that a version of this - entry applies to this client. -.. [2] Add a type to the generator definition for this entry -.. [3] Copy the Bcfg2 server's CA certificate to the client and specify it - using the **ca** option in the [communication] section of - ``bcfg2.conf`` -.. [4] This entry is not being bound. Ensure that a version of this - entry applies to this client. -.. [5] Ensure that another instance of the daemon (or any other process) - is not listening on the same port. -.. [6] Ensure that the key is readable by the user running the daemon - and that it is well-formed. -.. [7] Ensure that this file still exists; a frequent cause is the - deletion of a temp file. -.. [8] Ensure that the file is properly formed XML. -.. [9] Fix hostname resolution for the client or ensure that the profile - group is properly setup. - -FAQs -==== - -Why won't bcfg2-server start? ------------------------------ - -If your server doesn't seem to be starting and you see no error -messages in your server logs, try running it in the foreground to see -why. - -Why am I getting a traceback? ------------------------------ - -If you get a traceback, please let us know by :ref:`reporting it -` on Trac, via the mailing list, or on IRC. Your best bet -to get a quick response will be to jump on IRC during the daytime (CST). - -What is the most common cause of "The following entries are not handled by any tool"? -------------------------------------------------------------------------------------- - -Often it corresponds to entries that aren't bound by the server (for which -you'll get error messages on the server). You should try inspecting the -logs on the server to see what may be the cause. diff --git a/doc/getting_started/index.txt b/doc/getting_started/index.txt index 786c70290..9661fcb89 100644 --- a/doc/getting_started/index.txt +++ b/doc/getting_started/index.txt @@ -6,10 +6,13 @@ Getting started =============== -The steps below should get you from just thinking about a -configuration management system to an operational installation of -Bcfg2. If you get stuck, be sure to check the :ref:`mailinglist` -or to drop in on our :ref:`ircchannel`. +The steps below should get you from just thinking about a configuration +management system to an operational installation of Bcfg2. If you get +stuck, be sure to check the :ref:`help-mailinglist` or to drop in on +our :ref:`help-irc`. + +See the `Platform-specific Quickstart Notes`_ at the end of this page +if you happen to be using one of the more common operating systems. Get and Install Bcfg2 Server ============================ @@ -18,7 +21,7 @@ We recommend running the server on a Linux machine for ease of deployment due to the availability of packages for the dependencies. First, you need to download and install Bcfg2. The section -:ref:`installation-index` in this manual describes the steps to take. +:ref:`installation-index` in this manual describes the steps to take. To start, you will need to install the server on one machine and the client on one or more machines. Yes, your server can also be a client (and should be by the time your environment is fully managed). @@ -50,26 +53,25 @@ acting like it is your first client. .. note:: - The following command will tell the client to run in no-op mode, - meaning it will only check the client against the repository and - report any changes it sees. It won't make any changes (partially - because you haven't populated the repository with any - yet). However, nobody is perfect - you can make a typo, our - software can have bugs, monkeys can break in and hit enter before - you are done. Don't run this command on a production system if you - don't know what it does and aren't prepared for the - consequences. We don't know of anybody having problems with it - before, but it is better to be safe than sorry. + The following command will tell the client to run in no-op mode, + meaning it will only check the client against the repository and + report any differences it sees. It won't make any changes (partially + because you haven't populated the repository with any yet). However, + nobody is perfect. You can make a typo, our software can have bugs, + monkeys can break in and hit enter before you are done. Don't run + this command on a production system if you don't know what it does + and aren't prepared for the consequences. We don't know of anybody + having problems with it before, but it is better to be safe than sorry. And now for the command:: - bcfg2 -q -v -n + bcfg2 -q -v -n That can be translated as "bcfg2 quick verbose no-op". The output should be something similar to:: Loaded tool drivers: - Chkconfig POSIX PostInstall RPM + Chkconfig POSIX YUMng Phase: initial Correct entries: 0 @@ -87,9 +89,10 @@ should be something similar to:: Perfect! We have started out with an empty configuration, and none of our configuration elements are correct. It doesn't get much cleaner than that. But what about those unmanaged entries? Those are the extra -configuration elements (probably all packages at the moment) that -still aren't managed. Your goal now is to migrate each of those plus -any it can't see up to the "Correct entries" line. +configuration elements (probably all packages and services at the +moment) that still aren't managed, but have been detected by the client +tools. Your goal now is to migrate each of those plus any it can't see +up to the "Correct entries" line. Populate Repository =================== @@ -105,7 +108,7 @@ After the above steps, you should have a toplevel repository structure that looks like:: bcfg-server:~ # ls /var/lib/bcfg2 - Bundler/ Cfg/ Metadata/ Pkgmgr/ Rules/ SSHbase/ etc/ + Base/ Bundler/ Cfg/ Metadata/ Pkgmgr/ Rules/ SSHbase/ etc/ The place to start is the Metadata directory, which contains two files: ``clients.xml`` and ``groups.xml``. Your current @@ -113,9 +116,9 @@ files: ``clients.xml`` and ``groups.xml``. Your current .. code-block:: xml - - - + + + The ``clients.xml`` file is just a series of ```` tags, each of which describe one host you manage. Right now we only manage one @@ -130,27 +133,26 @@ Our simple ``groups.xml`` file looks like: .. code-block:: xml - - - - - - - - - - - - -There are two types of groups in Bcfg: profile groups -(``profile='true'``) and non-profile groups -(``profile='false'``). Profile groups can act as top-level groups to -which clients can bind, while non-profile groups only exist as members -of other groups. In our simple starter case, we have a profile group -named ``basic``, and that is the group that our first client bound -to. Our first client is a SuSE machine, so it contains the ``suse`` -group. Of course, ``bcfg2-admin`` isn't smart enough to fill out the -rest of your config, so the ``suse`` group further down is empty. + + + + + + + + + + + + +There are two types of groups in Bcfg: profile groups (``profile='true'``) +and non-profile groups (``profile='false'``). Profile groups can act as +top-level groups to which clients can bind, while non-profile groups only +exist as members of other groups. In our simple starter case, we have +a profile group named ``basic``, and that is the group that our first +client bound to. Our first client is a SuSE machine, so it contains the +``suse`` group. Of course, ``bcfg2-admin`` isn't smart enough to fill +out the rest of your config, so the ``suse`` group further down is empty. Let's say the first thing we want to set up on our machine is the message of the day. To do this, we simply need to create a Bundle and @@ -159,7 +161,7 @@ start out by adding .. code-block:: xml - + to the ``basic`` group. @@ -167,14 +169,14 @@ Next, we create a motd.xml file in the Bundler directory: .. code-block:: xml - - - + + + Now when we run the client, we get slightly different output:: Loaded tool drivers: - Chkconfig POSIX PostInstall RPM + Chkconfig POSIX YUMng Incomplete information for entry Path:/etc/motd; cannot verify Phase: initial @@ -225,16 +227,16 @@ Done! Now we just have 242 (or more) entries to take care of! directory to populate. You can find many samples of Bundles in the `Bundle Repository`_, many of which can be used without editing. -.. _Bundle Repository: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Plugins/Bundler/examples +.. _Bundle Repository: http://docs.bcfg2.org/server/plugins/structures/bundler/index.html#other-examples Next Steps ========== Several other utilities can help from this point on: -``bcfg2-info`` is a utility that instantiates a copy of the Bcfg2 server -core (minus the networking code) for examination. From this, you can -directly query: +:ref:`bcfg2-info ` is a utility that +instantiates a copy of the bcfg2 server core (minus the networking code) +for examination. From this, you can directly query: * Client Metadata * Which entries are provided by particular plugins @@ -244,3 +246,9 @@ Run ``bcfg2-info``, and type help and the prompt when it comes up. ``bcfg2-admin`` can perform a variety of repository maintenance tasks. Run ``bcfg2-admin`` help for details. + +Platform-specific Quickstart Notes +================================== + +* :ref:`appendix-guides-centos` +* :ref:`appendix-guides-ubuntu` diff --git a/doc/help/faq/client.txt b/doc/help/faq/client.txt new file mode 100644 index 000000000..8eb04e620 --- /dev/null +++ b/doc/help/faq/client.txt @@ -0,0 +1,16 @@ +.. -*- mode: rst -*- + +.. _faq-client: + +FAQ: Client +=========== + +**No ca is specified. Cannot authenticate the server with SSL.** + +This means that the client does not have a copy of the CA for the server, +so it can't verify that it is talking to the right server. To fix this +issue, copy ``/etc/bcfg2.crt`` from the server to ``/etc/bcfg2.ca`` +on the client. Then add the following on the client.:: + + [communication] + ca = /etc/bcfg2.ca diff --git a/doc/help/faq/general.txt b/doc/help/faq/general.txt new file mode 100644 index 000000000..0534e72d2 --- /dev/null +++ b/doc/help/faq/general.txt @@ -0,0 +1,56 @@ +.. -*- mode: rst -*- + +.. _faq-general: + +FAQ: General +============ + +**What does Bcfg2 stand for?** + +Initially, Bcfg stood for the bundle configuration system. Bcfg2 is the +second major revision. At this point, the acronym is meaningless, but +the name has stuck. Luckily, Bcfg2 googles better than Bcfg does. No, +seriously. Try it. All I know is that I have no interest in a billion +cubic feet of gas. + +**What architectures does Bcfg2 support?** + +Bcfg2 should run on any POSIX compatible operating system, however direct +support for an operating system's package and service formats are limited +by the currently available :ref:`client-tools-index` (although new client +tools are pretty easy to add). The following is an incomplete but more +exact list of platforms on which Bcfg2 works. + +* GNU/Linux deb based distros +* GNU/Linux rpm based distros +* Solaris pkg based +* Gentoo portage based +* OSX (POSIX/launchd support) + +**What pre-requisites are needed to run Bcfg2?** + +Please visit the :ref:`prerequisites` section in the manual. + +**Why won't bcfg2-server start?** + +If your server doesn't seem to be starting and you see no error +messages in your server logs, try running it in the foreground to +see why. + +**Why am I getting a traceback?** + +If you get a traceback, please let us know. You can file a `ticket +`_, send the traceback +to the :ref:`help-mailinglist`, or hop on the :ref:`help-irc` and let +us know. + +**Where are the server log messages?** + +The bcfg2-server process logs to syslog facility LOG_DAEMON. The server produces a series of messages upon a variety of events and errors. + +**Is there a way to check if all repository XML files conform to schemas?** + +Bcfg2 comes with XML schemas describing all of the XML formats used in +the server repository. A validation command ``bcfg2-repo-validate`` is +included with the source distribution and all packages. Run it with +the ``-v`` flag to see each file and the results if its validation. diff --git a/doc/help/faq/index.txt b/doc/help/faq/index.txt new file mode 100644 index 000000000..ee418d84d --- /dev/null +++ b/doc/help/faq/index.txt @@ -0,0 +1,17 @@ +.. -*- mode: rst -*- + +.. _faq-index: + +=== +FAQ +=== + +The Frequently Asked Questions (FAQ) answers the most common questions +about Bcfg2. At the moment the FAQ is splitted into a general +and a client specfic section. + +.. toctree:: + :maxdepth: 2 + + general + client diff --git a/doc/help/index.txt b/doc/help/index.txt new file mode 100644 index 000000000..63c2ca350 --- /dev/null +++ b/doc/help/index.txt @@ -0,0 +1,42 @@ +.. -*- mode: rst -*- + +.. _help-index: + +======================= +Getting Help with Bcfg2 +======================= + +Having trouble? We'd like to help! + +There are several ways to get in touch with the Bcfg2 community. + +* Try the :ref:`FAQ ` -- it's got answers to many common + questions. +* Check the :ref:`help-troubleshooting` page to see if you can narrow + down the cause of your issue. +* Looking for specific information? Try the :ref:`genindex`, + :ref:`modindex`, or the :ref:`detailed table of contents `. +* Search for information in the :ref:`help-mailinglist`. +* Visit our :ref:`help-irc`, or search the `IRC logs`_. + +Note that the IRC channel tends to be much busier than the mailing +list; use whichever seems most appropriate for your query, but don't +let the lack of mailing list activity make you think the project isn't +active. + +.. _IRC logs: http://colabti.org/irclogger/irclogger_logs/bcfg2 +.. _Bcfg2 mailing list archives: http://trac.mcs.anl.gov/projects/bcfg2/wiki/MailingList +.. _Trac ticket tracker: http://trac.mcs.anl.gov/projects/bcfg2/wiki + +Report A Bug +============ + +Report bugs with Bcfg2 on the `Trac ticket tracker`_. + +.. toctree:: + :hidden: + + mailinglist + irc + faq/index + troubleshooting diff --git a/doc/help/irc.txt b/doc/help/irc.txt new file mode 100644 index 000000000..303c39e68 --- /dev/null +++ b/doc/help/irc.txt @@ -0,0 +1,45 @@ +.. -*- mode: rst -*- + +.. _Freenode: http://chat.freenode.net +.. _#bcfg2: irc://chat.freenode.net/bcfg2 + +.. _help-irc: + +=========== +IRC Channel +=========== + +The Bcfg2 IRC channel is `#bcfg2`_ on `Freenode`_. It is home to both +support and development discussions. If you have a question, suggestion, +or just want to know about Bcfg2, please drop in and say hi. + +Archives are available at: http://colabti.org/irclogger/irclogger_logs/bcfg2 + +.. raw:: html + +
+ + +
+ in the timespan + + (yyyymmdd-yyyymmdd) +

Options:
+
+
+ + +Administrative Note +=================== + +If the IRC logging stops working for a while, coordinate on #bcfg2 and +then bug **feb** on #irclogger (freenode), and stick around on that +channel until you get an answer (**feb** is great, but busy and in a +non-US time zone). Actually as long as **ilogger2** is logged in you +should be okay (**feb** looks at the logs). + +If you have private logs for the period of time **ilogger2** was off the +channel, you can convert them to the will incorporate them into the online +logs. Be sure to strip out any private messages in your logs first :-) + +.. _format shown here: http://colabti.org/irclogger/irclogger_log/bcfg2?date=2008-03-21,Fri;raw=on diff --git a/doc/help/mailinglist.txt b/doc/help/mailinglist.txt new file mode 100644 index 000000000..c77caa0c4 --- /dev/null +++ b/doc/help/mailinglist.txt @@ -0,0 +1,24 @@ +.. -*- mode: rst -*- + +.. _help-mailinglist: + +============ +Mailing List +============ + +To subscribe to the mailing list for Bcfg2 please visit the `bcfg-dev +mailman page`_ + +`Searchable archives`_ are available from Gmane. You can also read the +mailing list from any NNTP client via Gmane. + +.. _bcfg-dev mailman page: https://lists.mcs.anl.gov/mailman/listinfo/bcfg-dev +.. _Searchable archives: http://dir.gmane.org/gmane.comp.sysutils.bcfg2.devel + +.. raw:: html + +
+ + + + diff --git a/doc/help/troubleshooting.txt b/doc/help/troubleshooting.txt new file mode 100644 index 000000000..0892587aa --- /dev/null +++ b/doc/help/troubleshooting.txt @@ -0,0 +1,184 @@ +.. -*- mode: rst -*- + +.. _help-troubleshooting: + +=============== +Troubleshooting +=============== + +From time to time, Bcfg2 produces results that the user finds surprising. +This can happen either due to bugs or user error. This page describes +several techniques to gain visibility into the bcfg2 client and server +and understand what is going on. + + +Figure out if error is client or server side +============================================ + +* Cache a copy of the client configuration using ``bcfg2 -qnc /tmp/config.xml`` +* Look in the file and search for the entry of interest +* If it looks correct, then there is a client issue +* If not, it is time to inspect things on the server + +This file contains all aspects of client configuration. It is structured +as a series of bundles and base entries. + +.. note:: + + Most often the entry is not correct and the issue lies in + the specification. + +Review server log messages +========================== + +The bcfg2-server process logs to syslog facility LOG_DAEMON. The server +produces a series of messages upon a variety of events and errors. + +Check if all repository XML files conform to schemas +==================================================== + +Bcfg2 comes with XML schemas describing all of the XML formats used in +the server repository. A validation command ``bcfg2-repo-validate`` is +included with the source distribution and all packages. Run it with the +-v flag to see each file and the results if its validation. + +If the bcfg2 server is not reflecting recent changes, try restarting the bcfg2-server process +============================================================================================= + +If this fixes the problem, it is either a bug in the +underlying file monitoring system (fam or gamin) or a bug in +Bcfg2's file monitoring code. In either case, file a `ticket +`_ in the tracking +system. In the ticket, include: + +* filesystem monitoring system (fam or gamin) +* kernel version (if on linux) +* if any messages of the form "Handled N events in M + seconds" appeared between the modification event and the client + configuration generation request appeared in the server log +* which plugin handled the file in the repostiory (Cfg, Rules, Packages, + TCheetah, TGenshi, Metadata) +* if a touch of the file after the modification causes the problem to + go away + +bcfg2-info +========== + +Bcfg2 server operations can be simulated using the ``bcfg2-info`` command. +The command is interactive, and has commands to allow several useful +operations + +* clients - Current client metadata (profile and group) settings +* groups - Current group metadata values +* mappings - Configuration entries provided by plugins +* buildfile - Build a config file for a client +* showentries - Build the abstract configuration (list + of entries) for a client +* build - Build the complete configuration + for a client + +Type `help` in bcfg2-info for more information. + +Error Messages +============== + +This page describes error messages produced by Bcfg2 and steps that can +be taken to remedy them. + ++------------------------------+----------+---------------------+--------------+ +| Error | Location | Meaning | Repair | ++==============================+==========+=====================+==============+ +| Incomplete information for | Client | The described entry | [1]_ | +| entry : | | is not fully | | +| cannot verify | | specified by the | | +| | | server, so no | | +| | | verification can be | | +| | | performed. | | ++------------------------------+----------+---------------------+--------------+ +| Incomplete information for | Client | The described entry | [1]_ | +| entry : | | is not fully | | +| cannot install | | specified by the | | +| | | server, so no | | +| | | verification can be | | +| | | performed. | | ++------------------------------+----------+---------------------+--------------+ +| The following entries are | Client | The client cannot | [2]_ | +| not handled by any tool: | | figure out how to | | +| : | | handle this entry. | | ++------------------------------+----------+---------------------+--------------+ +| No ca is specified. Cannot | Client | The client is | [3]_ | +| authenticate the server with | | unable to verify | | +| SSL. | | the server | | ++------------------------------+----------+---------------------+--------------+ +| Failed to bind entry: | Server | The server was | [4]_ | +| | | unable to find a | | +| | | suitable version of | | +| | | entry for client. | | ++------------------------------+----------+---------------------+--------------+ +| Failed to bind to socket | Server | The server was | [5]_ | +| | | unable to bind to | | +| | | the tcp server | | +| | | socket. | | ++------------------------------+----------+---------------------+--------------+ +| Failed to load | Server | The server was | [6]_ | +| ssl key | | unable to read and | | +| | | process the ssl key.| | ++------------------------------+----------+---------------------+--------------+ +| Failed to read file | Server | The server failed | [7]_ | +| | | to read the | | +| | | specified file | | ++------------------------------+----------+---------------------+--------------+ +| Failed to parse file | Server | The server failed | [8]_ | +| | | to parse the | | +| | | specified XML file | | ++------------------------------+----------+---------------------+--------------+ +| Client metadata resolution | Server | The server cannot | [9]_ | +| error for | | resolve the client | | +| | | hostname or the | | +| | | client is | | +| | | associated with a | | +| | | non-profile group. | | ++------------------------------+----------+---------------------+--------------+ + + +.. [1] This entry is not being bound. Ensure that a version of this + entry applies to this client. +.. [2] Add a type to the generator definition for this entry +.. [3] Copy the Bcfg2 server's CA certificate to the client and specify it + using the **ca** option in the [communication] section of + ``bcfg2.conf`` +.. [4] This entry is not being bound. Ensure that a version of this + entry applies to this client. +.. [5] Ensure that another instance of the daemon (or any other process) + is not listening on the same port. +.. [6] Ensure that the key is readable by the user running the daemon + and that it is well-formed. +.. [7] Ensure that this file still exists; a frequent cause is the + deletion of a temp file. +.. [8] Ensure that the file is properly formed XML. +.. [9] Fix hostname resolution for the client or ensure that the profile + group is properly setup. + +FAQs +==== + +Why won't bcfg2-server start? +----------------------------- + +If your server doesn't seem to be starting and you see no error +messages in your server logs, try running it in the foreground to see +why. + +Why am I getting a traceback? +----------------------------- + +If you get a traceback, please let us know by :ref:`reporting it +` on Trac, via the mailing list, or on IRC. Your best bet +to get a quick response will be to jump on IRC during the daytime (CST). + +What is the most common cause of "The following entries are not handled by any tool"? +------------------------------------------------------------------------------------- + +Often it corresponds to entries that aren't bound by the server (for which +you'll get error messages on the server). You should try inspecting the +logs on the server to see what may be the cause. diff --git a/doc/index.txt b/doc/index.txt index 583ea38e3..98616ab72 100644 --- a/doc/index.txt +++ b/doc/index.txt @@ -2,9 +2,9 @@ .. _index: -========================================== -Welcome to Bcfg2's |version| documentation -========================================== +============================= +Bcfg2 documentation |release| +============================= What is Bcfg2? ============== @@ -38,7 +38,6 @@ Bcfg2 can enable the construction of complex change management and deployment strategies. .. toctree:: - :numbered: :maxdepth: 2 contents diff --git a/doc/installation/distributions.txt b/doc/installation/distributions.txt index 5a86e81d5..38b34f14d 100644 --- a/doc/installation/distributions.txt +++ b/doc/installation/distributions.txt @@ -3,15 +3,134 @@ .. _distributions: =========================== -Distribution-specific notes +Distribution-specific notes =========================== -The installation of Bcfg2 on a specific distribution depends on -the used package management tool and the disposability in the -distribution's package :term:`repository` -. +The installation of Bcfg2 on a specific distribution depends on the +package management tool and the availability of the package in the +distribution's repository. -.. toctree:: - :glob: +ArchLinux +========= - distro/* +Packages for `Arch Linux`_ are available in the Arch User Repository (AUR_). +Just use `pacman` to perform the installation :: + + pacman -S bcfg2 bcfg2-server + +.. _Arch Linux: http://www.archlinux.org/ +.. _AUR: http://aur.archlinux.org/packages.php?ID=20979 + +Debian +====== + +Packages of Bcfg2 are available for Debian Lenny, Debian Squeeze, and +Debian Sid. The fastest way to get Bcfg2 onto your Debian system +is to use ``apt-get`` or ``aptitude``. :: + + sudo aptitude install bcfg2 bcfg2-server + +If you want to use unofficial packages from Bcfg2 see the instructions +at `CustomDebianRepository`_. + +.. _CustomDebianRepository: http://trac.mcs.anl.gov/projects/bcfg2/wiki/PrecompiledPackages#UnofficialDebianRepository + +Fedora +====== + +The fastest way to get Bcfg2 Packages_ onto your Fedora_ system is to +use `yum` or PackageKit. Yum will pull in all dependencies of Bcfg2 +automatically. :: + + su -c 'yum install bcfg2-server bcfg2' + +Be aware that the latest release of Bcfg2 may only be available for the +Development release of Fedora (Rawhide). With the activation of the +Rawhide repository of Fedora you will be able to install it. :: + + su -c 'yum install --enablerepo=rawhide bcfg2-server bcfg2' + +This way is not recommended on production systems. Only for testing. + +Gentoo +====== + +Early in July 2008, Bcfg2 was added to the Gentoo portage tree. So far +it's still keyworded for all architectures, but we are actively working +to get it marked as stable. + +If you don't use portage to install Bcfg2, you'll want to make sure you +have all the prerequisites installed first. For a server, you'll need: + +* ``app-admin/gamin`` or ``app-admin/fam`` +* ``dev-python/lxml`` + +Clients will need at least: + +* ``app-portage/gentoolkit`` + +OS X +==== + +Bcfg2 can be installed either via MacPorts or by creating a native OS X +package. + +MacPorts +-------- + +Once macports is installed:: + + port install bcfg2 + +Using native OS X python +------------------------ + +First, make sure you have Xcode installed as you need ``packagemaker`` which +comes bundled in the Developer tools. + +Clone the git source:: + + git clone git://git.mcs.anl.gov/bcfg2.git + +Change to the osx directory and type make. Your new package should be +located at bcfg2-$VERSION.pkg (where $VERSION is that which is specified +in setup.py). + +RHEL / Centos / Scientific Linux +================================ + +While you can go about building all these things from source, this +section will try and meet the dependencies using packages from EPEL_ +[#f1]_. The *el5* and the soon available *el6* package should be compatible +with `CentOS`_ 5.x/6.x and `Scientific Linux`_. + +EPEL_:: + + [root@centos ~]# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm + +Install the bcfg2-server and bcfg2 RPMs:: + + [root@centos ~]# yum install bcfg2-server bcfg2 + +.. note:: + + The latest package for *el5* is only available in the testing repository. + +.. [#f1] For more details check the EPEL_ `instructions `_ + +.. _CentOS: http://www.centos.org/ +.. _Scientific Linux: http://www.scientificlinux.org/ +.. _EPEL: http://fedoraproject.org/wiki/EPEL +.. _RPMForge: https://rpmrepo.org/RPMforge + +Ubuntu +====== + +We highly recommend following the instructions at `ubuntu-installation`_ +in order to install a recent version of Bcfg2 on your system. However, +if you would like to install the older package, you can use the following +command:: + + sudo aptitude install bcfg2 bcfg2-server + +.. _ubuntu-installation: http://trac.mcs.anl.gov/projects/bcfg2/wiki/PrecompiledPackages#UbuntuLaunchpadBcfg2PPA diff --git a/doc/installation/distro/archlinux.txt b/doc/installation/distro/archlinux.txt deleted file mode 100644 index 75ff59c49..000000000 --- a/doc/installation/distro/archlinux.txt +++ /dev/null @@ -1,17 +0,0 @@ -.. -*- mode: rst -*- - -.. _installation-archlinux: - -.. _Arch Linux: http://www.archlinux.org/ -.. _AUR: http://aur.archlinux.org/packages.php?ID=20979 - - -ArchLinux -========= - -Packages for `Arch Linux`_ are available in the Arch User Repository (AUR_). -Just use `pacman` to perform the installation :: - - pacman -S bcfg2 bcfg2-server - - diff --git a/doc/installation/distro/debian.txt b/doc/installation/distro/debian.txt deleted file mode 100644 index 67a4f1d9d..000000000 --- a/doc/installation/distro/debian.txt +++ /dev/null @@ -1,24 +0,0 @@ -.. -*- mode: rst -*- - -.. _debian: - -.. _Wiki: http://trac.mcs.anl.gov/projects/bcfg2/wiki/PrecompiledPackages#UnofficialDebianRepository - -Debian -====== - -Packages of Bcfg2 are available for Debian Lenny, Debian Squeeze, and -Debian Sid. The fastest way to get Bcfg2 onto your Debian system -is to use `apt-get` or `aptitude`. :: - - sudo aptitude install bcfg2 bcfg2-server - -If you want to use unofficial packages from Bcfg2. Add the following line -to your `/etc/apt/sources.list` file :: - - deb ftp://ftp.mcs.anl.gov/pub/bcfg/debian sarge/ - -Now just run `aptitute` in the way it is mentioned above. - -For more details about running prerelease version of Bcfg2 on Debian -systems, please refer to the Wiki_. diff --git a/doc/installation/distro/fedora.txt b/doc/installation/distro/fedora.txt deleted file mode 100644 index 92771b974..000000000 --- a/doc/installation/distro/fedora.txt +++ /dev/null @@ -1,23 +0,0 @@ -.. -*- mode: rst -*- - -.. _Packages: https://admin.fedoraproject.org/pkgdb/acls/name/bcfg2 -.. _Fedora: https://www.fedoraproject.org - -.. _fedora-installation: - -Fedora -====== - -The fastest way to get Bcfg2 Packages_ onto your Fedora_ system is to -use `yum` or PackageKit. Yum will pull in all dependencies of Bcfg2 -automatically. :: - - $ su -c 'yum install bcfg2-server bcfg2' - -Be aware that the latest release of Bcfg2 may only be available for the -Development release of Fedora (Rawhide). With the activation of the -Rawhide repository of Fedora you will be able to install it. :: - - $ su -c 'yum install --enablerepo=rawhide bcfg2-server bcfg2' - -This way is not recommanded on productive systems. Only for testing. diff --git a/doc/installation/distro/gentoo.txt b/doc/installation/distro/gentoo.txt deleted file mode 100644 index 5497a01b2..000000000 --- a/doc/installation/distro/gentoo.txt +++ /dev/null @@ -1,27 +0,0 @@ -.. -*- mode: rst -*- - -.. _gentoo-installation: - -.. _Freenode: http://chat.freenode.net -.. _#bcfg2: irc://chat.freenode.net/bcfg2 - - -Gentoo -====== - -Early in July 2008, Bcfg2 was added to the Gentoo portage tree. So far -it's only keyworded for ~x86, but we hope to see it soon in the amd64 and -x64-solaris ports. If you're using Gentoo on some other architecture, it -should still work provided that you have a reasonably up to date Python; -try adding `app-admin/bcfg2 ~*` to your `/etc/portage/package.keywords` -file. - -If you don’t use portage to install Bcfg2, you’ll want to make sure you -have all the prerequisites installed first. For a server, you’ll need: - -* ``app-admin/gamin`` or ``app-admin/fam`` -* ``dev-python/lxml`` - -Clients will need at least: - -* ``app-portage/gentoolkit`` diff --git a/doc/installation/distro/osx.txt b/doc/installation/distro/osx.txt deleted file mode 100644 index 8b7a5a95d..000000000 --- a/doc/installation/distro/osx.txt +++ /dev/null @@ -1,29 +0,0 @@ -.. -*- mode: rst -*- - -.. _osx-installation: - -.. _Freenode: http://chat.freenode.net -.. _#bcfg2: irc://chat.freenode.net/bcfg2 - - -OS X -==== - -Once macports is installed:: - - port install bcfg2 - -Using native OS X python ------------------------- - -First, make sure you have Xcode installed as you need `packagemaker` which -comes bundled in the Developer tools. - -Clone the git source:: - - git clone git://git.mcs.anl.gov/bcfg2.git - -Change to the osx directory and type make. Your new package should be located -at bcfg2-'''$VERSION'''.pkg (where '''$VERSION''' is that which is specified -in setup.py). - diff --git a/doc/installation/distro/rhel.txt b/doc/installation/distro/rhel.txt deleted file mode 100644 index 49e43179f..000000000 --- a/doc/installation/distro/rhel.txt +++ /dev/null @@ -1,31 +0,0 @@ -.. -*- mode: rst -*- - -.. _CentOS: http://www.centos.org/ -.. _Red Hat/RHEL: http://www.redhat.com/rhel/ -.. _Scientific Linux: http://www.scientificlinux.org/ -.. _EPEL: http://fedoraproject.org/wiki/EPEL -.. _RPMForge: https://rpmrepo.org/RPMforge - -.. _rhel-installation: - -RHEL / Centos / Scientific Linux -================================ - -While you can go about building all these things from source, this -section will try and meet the dependencies using packages from EPEL_ -[#f1]_. The *el5* and the soon available *el6* package should be compatible -with `CentOS`_ 5.x/6.x and `Scientific Linux`_. - -EPEL_:: - - [root@centos ~]# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm - -Install the bcfg2-server and bcfg2 RPMs:: - - [root@centos ~]# yum install bcfg2-server bcfg2 - -.. note:: - - The latest package for *el5* is only available in the testing repository. - -.. [#f1] For more details check the EPEL_ `instructions `_ diff --git a/doc/installation/distro/ubuntu.txt b/doc/installation/distro/ubuntu.txt deleted file mode 100644 index 694cce865..000000000 --- a/doc/installation/distro/ubuntu.txt +++ /dev/null @@ -1,36 +0,0 @@ -.. -*- mode: rst -*- - -.. _ubuntu-installation: - -.. _Ubuntu: http://www.ubuntu.com -.. _Wiki: http://trac.mcs.anl.gov/projects/bcfg2/wiki/PrecompiledPackages#UbuntuLaunchpadBcfg2PPA - -Ubuntu -====== - -The steps to bring Bcfg2 onto your Ubuntu_ system depends on your -release. - -* Dapper - Add the following lines to `/etc/apt/sources.list` :: - - deb ftp://ftp.mcs.anl.gov/pub/bcfg/ubuntu dapper/ - deb http://archive.ubuntu.com/ubuntu dapper universe - deb-src http://archive.ubuntu.com/ubuntu dapper universe - -* Edgy - Add the following lines to `/etc/apt/sources.list` :: - - deb ftp://ftp.mcs.anl.gov/pub/bcfg/ubuntu edgy/ - deb http://archive.ubuntu.com/ubuntu edgy universe - deb-src http://archive.ubuntu.com/ubuntu edgy universe - -* Feisty - Those packages are available from the Ubuntu_ repositories. - -To install the packages, just lauch the following command :: - - sudo aptitude install bcfg2 bcfg2-server - -For more details about running prerelease version of Bcfg2 on Ubuntu_ -systems, please refer to the Wiki_. diff --git a/doc/installation/packages.txt b/doc/installation/packages.txt index a15e3e98e..b175d2625 100644 --- a/doc/installation/packages.txt +++ b/doc/installation/packages.txt @@ -9,34 +9,34 @@ .. _RPMForge: https://rpmrepo.org/RPMforge -Building packages from source -============================= +Building RPM packages from source +================================= The Bcfg2 distribution contains two different spec files. Building from Tarball --------------------- -* Copy the tarball to `/usr/src/packages/SOURCES/` -* Extract another copy of it somewhere else (eg: `/tmp`) and retrieve - the `misc/bcfg2.spec` file +* Copy the tarball to ``/usr/src/packages/SOURCES/`` +* Extract another copy of it somewhere else (eg: ``/tmp``) and retrieve + the ``misc/bcfg2.spec`` file * Run :: - rpmbuild -ba bcfg2.spec + rpmbuild -ba bcfg2.spec -* The resulting RPMs will be in `/usr/src/packages/RPMS/` and SRPMs - in `/usr/src/packages/SRPMS` +* The resulting RPMs will be in ``/usr/src/packages/RPMS/`` and SRPMs + in ``/usr/src/packages/SRPMS`` Building from an GIT Checkout ----------------------------- -* Change to the `redhat/` directory in the working copy +* Change to the ``redhat/`` directory in the working copy * Run :: make -* The resulting RPMs will be in `/usr/src/redhat/RPMS/ `and SRPMs - in `/usr/src/redhat/SRPMS` and will have the SVN revision appended +* The resulting RPMs will be in ``/usr/src/redhat/RPMS/`` and SRPMs + in ``/usr/src/redhat/SRPMS`` and will have the SVN revision appended Building RPM packages with ``rpmbuild`` --------------------------------------- @@ -47,35 +47,35 @@ The *el5* package should be compatible with CentOS 5.x. * Installation of the EPEL_ repository package :: - [root@centos ~]# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm + [root@centos ~]# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm * Now you can install the rest of the prerequisites :: - [root@centos ~]# yum install python-genshi python-cheetah python-lxml + [root@centos ~]# yum install python-genshi python-cheetah python-lxml * After installing git, check out the master branch :: - [root@centos redhat]# git clone git://git.mcs.anl.gov/bcfg2.git + [root@centos redhat]# git clone git://git.mcs.anl.gov/bcfg2.git * Install the ``fedora-packager`` package :: - [root@centos ~]# yum install fedora-packager + [root@centos ~]# yum install fedora-packager * A directory structure for the RPM build process has to be established. :: - [you@centos ~]$ rpmdev-setuptree + [you@centos ~]$ rpmdev-setuptree * Change to the *redhat* directory of the checked out Bcfg2 source:: - [you@centos ~]$ cd bcfg2/redhat/ + [you@centos ~]$ cd bcfg2/redhat/ -* In the particular directory is a ``Makefile`` which will do the job of +* In the particular directory is a ``Makefile`` which will do the job of building the RPM packages. You can do this as root, but it's not recommanded :: - [you@centos redhat]$ make + [you@centos redhat]$ make * Now the new RPM package can be installed. Please adjust the path to your RPM package :: - [root@centos ~]# rpm -ihv /home/YOU/rpmbuild/RPMS/noarch/bcfg2-server-1.0.0-0.2r5835.noarch.rpm + [root@centos ~]# rpm -ihv /home/YOU/rpmbuild/RPMS/noarch/bcfg2-server-1.0.0-0.2r5835.noarch.rpm diff --git a/doc/installation/prerequisites.txt b/doc/installation/prerequisites.txt index e4ea715b0..758ee4a21 100644 --- a/doc/installation/prerequisites.txt +++ b/doc/installation/prerequisites.txt @@ -14,16 +14,22 @@ what software is needed on the client and server side. Bcfg2 Client ------------ -===================================== =================== ============================== -Software Version Requires -===================================== =================== ============================== -libxml2 (if lxml is used) Any -libxslt (if lxml is used) Any libxml2 -python 2.3-2.4, 2.5 [#f1]_ -lxml or elementtree [#f2]_ Any lxml: libxml2, libxslt, python -python-apt [#f3]_ Any python -debsums (if APT tool driver is used) Any -===================================== =================== ============================== ++----------------------------+---------------+--------------------------------+ +| Software | Version | Requires | ++============================+===============+================================+ +| libxml2 (if lxml is used) | Any | | ++----------------------------+---------------+--------------------------------+ +| libxslt (if lxml is used) | Any | libxml2 | ++----------------------------+---------------+--------------------------------+ +| python | >= 2.3 [#f1]_ | | ++----------------------------+---------------+--------------------------------+ +| lxml or elementtree [#f2]_ | Any | lxml: libxml2, libxslt, python | ++----------------------------+---------------+--------------------------------+ +| python-apt [#f3]_ | Any | python | ++----------------------------+---------------+--------------------------------+ +| debsums (if APT tool | Any | | +| driver is used) | | | ++----------------------------+---------------+--------------------------------+ .. [#f1] python 2.5 works with elementtree. @@ -33,15 +39,20 @@ debsums (if APT tool driver is used) Any Bcfg2 Server ------------ -===================================== ============= ============================== -Software Version Requires -===================================== ============= ============================== -libxml2 2.6.24+ -libxslt Any libxml2 -python 2.2-2.5 -lxml 0.9+ lxml: libxml2, libxslt, python -gamin or fam Any -python-gamin or python-fam Any gamin or fam, python -M2crypto Any python, openssl -===================================== ============= ============================== - ++----------------------------+----------+--------------------------------+ +| Software | Version | Requires | ++============================+==========+================================+ +| libxml2 | 2.6.24+ | | ++----------------------------+----------+--------------------------------+ +| libxslt | Any | libxml2 | ++----------------------------+----------+--------------------------------+ +| python | 2.2-2.5 | | ++----------------------------+----------+--------------------------------+ +| lxml | 0.9+ | lxml: libxml2, libxslt, python | ++----------------------------+----------+--------------------------------+ +| gamin or fam | Any | | ++----------------------------+----------+--------------------------------+ +| python-gamin or python-fam | Any | gamin or fam, python | ++----------------------------+----------+--------------------------------+ +| M2crypto | Any | python, openssl | ++----------------------------+----------+--------------------------------+ diff --git a/doc/installation/source.txt b/doc/installation/source.txt index e21f7150f..3ea0404ad 100644 --- a/doc/installation/source.txt +++ b/doc/installation/source.txt @@ -1,64 +1,46 @@ .. -*- mode: rst -*- -.. _Download: http://trac.mcs.anl.gov/projects/bcfg2/wiki/Download -.. _GPG: http://pgpkeys.mit.edu:11371/pks/lookup?op=get&search=0x75BF2C177F7D197E -.. _GPGKey: ftp://ftp.mcs.anl.gov/pub/bcfg/bcfg2-1.1.0.tar.gz.gpg -.. _Tarball: ftp://ftp.mcs.anl.gov/pub/bcfg/bcfg2-1.1.0.tar.gz - -.. |md5sum| replace:: 13593938daf7e8b9a81cb4b677dc7f99 -.. |version| replace:: 1.1.0 -.. |rel_date| replace:: 9/27/10 +.. _GPG1: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x75BF2C177F7D197E +.. _GPG2: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x80B8492FA88FFF4B .. _source: +Installation from source +======================== + Download -======== +-------- Tarball -------- +^^^^^^^ The Bcfg2 source tarball can be grabbed from the Download_ page. -========= ======== ======= ============== ===================== -Version URL GPG key Release Date md5sum -========= ======== ======= ============== ===================== -|version| Tarball_ GPGKey_ |rel_date| |md5sum| -========= ======== ======= ============== ===================== - -The full command to use with ``wget`` are listed below. Please -replace ```` with |version|. :: - - wget ftp://ftp.mcs.anl.gov/pub/bcfg/bcfg2-.tar.gz - wget ftp://ftp.mcs.anl.gov/pub/bcfg/bcfg2-.tar.gz.gpg - -All tarballs are signed with GPG key `7F7D197E `_. You can verify -your download by importing the key and running :: - - $ gpg --recv-keys 0x75bf2c177f7d197e - $ gpg --verify bcfg2-.tar.gz.gpg bcfg2-.tar.gz - -For older or prepreleases please visit the Download_ wiki page. +All tarballs are signed with GPG keys `7F7D197E `_ or `A88FFF4B +`_. You can verify your download by importing the keys and running :: + gpg --recv-keys 0x75bf2c177f7d197e 0x80B8492FA88FFF4B + gpg --verify bcfg2-.tar.gz.gpg bcfg2-.tar.gz Git checkout ------------- +^^^^^^^^^^^^ You can also get the latest (possibly broken) code via git :: - git clone git://git.mcs.anl.gov/bcfg2.git + git clone git://git.mcs.anl.gov/bcfg2.git -Installation from source -======================== +Install +------- If you are working with the release tarball of Bcfg2 you need to untar it before you can go on with the installation :: - tar -xzf bcfg2-.tar.gz + tar -xzf bcfg2-.tar.gz -Now you can build Bcfg2 with. If you are working with a SVN checkout -no need to be specified. :: +Now you can build Bcfg2 with. If you are working from a git clone no + need to be specified. :: - cd bcfg2- - python setup.py install --prefix=/install/prefix + cd bcfg2- + python setup.py install --prefix=/install/prefix This will install both the client and server on that machine. diff --git a/doc/reports/dynamic.txt b/doc/reports/dynamic.txt index 1ec41af64..f798529eb 100644 --- a/doc/reports/dynamic.txt +++ b/doc/reports/dynamic.txt @@ -39,7 +39,8 @@ The recommended statistics plugin is DBStats. To use it, add it to the plugin can be used in conjunction with a crontab entry to run ``/usr/sbin/bcfg2-admin reports load_stats``. -Detailed installation instructions can be found :ref:`here `. +Detailed installation instructions can be found :ref:`here +`. .. _dynamic-http-install: diff --git a/doc/reports/static.txt b/doc/reports/static.txt index d5d96fe12..67ba38a14 100644 --- a/doc/reports/static.txt +++ b/doc/reports/static.txt @@ -30,7 +30,7 @@ Retention Model =============== The current reporting system stores statistics in an XML data store, by -default to {{{/etc/statistics.xml}}}. It retains either one or two +default to ``/etc/statistics.xml``. It retains either one or two statistic sets per host. If the client has a clean configuration state, the most recent (clean) record is retained. If the client has a dirty configuration state, two records are retained. One record is the last @@ -53,7 +53,7 @@ Output ====== Several output reports can be generated from the statistics store with -the command line tool {{{bcfg2-build-reports}}}. +the command line tool ``bcfg2-build-reports``. * Nodes Digest * Nodes Individual diff --git a/doc/server/plugins/connectors/properties.txt b/doc/server/plugins/connectors/properties.txt index 707de0880..afe3cd955 100644 --- a/doc/server/plugins/connectors/properties.txt +++ b/doc/server/plugins/connectors/properties.txt @@ -14,8 +14,8 @@ Enabling Properties First, ``mkdir /var/lib/bcfg2/Properties``. Each property XML file goes in this directory. Each will automatically be cached by the server, -and reread/reparsed upon changes. Add **Properties** to your `plugins` -line in `/etc/bcfg2.conf`. +and reread/reparsed upon changes. Add **Properties** to your ``plugins`` +line in ``/etc/bcfg2.conf``. Data Structures =============== @@ -27,9 +27,9 @@ contain parsed XML data as the "data" attribute. Usage ===== -Specific property files can be referred to in templates as -metadata.Properties[]. The data attribute is an LXML element object. -(Documented +Specific property files can be referred to in +templates as metadata.Properties[]. The +data attribute is an LXML element object. (Documented `here `_) Currently, no access methods are defined for this data, but as we @@ -39,6 +39,7 @@ as methods. This will simplify templates. Accessing Properties contest from TGenshi ========================================= -Access contents of `Properties/auth.xml` :: +Access contents of ``Properties/auth.xml``:: + ${metadata.Properties['auth.xml'].data.find('file').find('bcfg2.key').text} diff --git a/doc/server/plugins/generators/tcheetah.txt b/doc/server/plugins/generators/tcheetah.txt index e1ad600a2..185b25ef5 100644 --- a/doc/server/plugins/generators/tcheetah.txt +++ b/doc/server/plugins/generators/tcheetah.txt @@ -27,7 +27,7 @@ located in in a ``TCheetah`` subdirectory of your repository, usually files, ``template`` and ``info``. The template is a standard Cheetah template with two additions: -* `self.metadata` is the client's metadata +* `self.metadata` is the client's :ref:`metadata ` * `self.properties` is an xml document of unstructured data The ``info`` file is formatted like ``:info`` files from Cfg. @@ -44,19 +44,8 @@ Permissions entry and a Path entry to handle the same file. self.metadata variables ======================= -The following variables are available for self.metadata: - -* hostname -* bundles -* groups -* categories -* probes -* uuid -* password - -self.metadata is an instance of the class -ClientMetadata of file `Bcfg2/Server/Plugins/Metadata.py -`_. +self.metadata is an instance of the class ClientMetadata and documented +:ref:`here `. self.properties =============== diff --git a/doc/server/plugins/generators/tgenshi/index.txt b/doc/server/plugins/generators/tgenshi/index.txt index cd9bcf152..425b3a289 100644 --- a/doc/server/plugins/generators/tgenshi/index.txt +++ b/doc/server/plugins/generators/tgenshi/index.txt @@ -48,8 +48,10 @@ supported. Inside of templates =================== -* metadata is the client's metadata -* properties.properties is an xml document of unstructured data +* **metadata** is the client's :ref:`metadata ` +* **properties.properties** is an xml document of unstructured data +* **name** is the path name specified in bcfg +* **path** is the path to the TGenshi template See the genshi `documentation `_ for examples of diff --git a/doc/server/plugins/grouping/metadata.txt b/doc/server/plugins/grouping/metadata.txt index 96fc70ff5..fc452eb2f 100644 --- a/doc/server/plugins/grouping/metadata.txt +++ b/doc/server/plugins/grouping/metadata.txt @@ -225,3 +225,69 @@ Probes The metadata plugin includes client-side probing functionality. This is fully documented :ref:`here `. + +.. _server-plugins-grouping-metadata-clientmetadata: + +ClientMetadata +============== + +A special client metadata class is available to the TGenshi and TCheetah +plugins. + ++----------------------+------------------------------------------------+-------------------+ +| Attribute | Description | Value | ++======================+================================================+===================+ +| hostname | Client hostname | String | ++----------------------+------------------------------------------------+-------------------+ +| profile | Client profile | String | ++----------------------+------------------------------------------------+-------------------+ +| aliases | Client aliases | List | ++----------------------+------------------------------------------------+-------------------+ +| addresses | Adresses this client is known by | List | ++----------------------+------------------------------------------------+-------------------+ +| groups | Groups this client is a member of | List | ++----------------------+------------------------------------------------+-------------------+ +| categories | Categories of this clients groups | List | ++----------------------+------------------------------------------------+-------------------+ +| uuid | uuid identifier for this client | String | ++----------------------+------------------------------------------------+-------------------+ +| password | bcfg password for this client | String | ++----------------------+------------------------------------------------+-------------------+ +| connectors | connector plugins known to this client | List | ++----------------------+------------------------------------------------+-------------------+ +| query | MetadataQuery object | MetadataQuery | ++----------------------+------------------------------------------------+-------------------+ + +| + ++------------------------------+------------------------------------------------+-------------------+ +| Method | Description | Value | ++==============================+================================================+===================+ +| inGroup(group) | True if this client is a memnber of 'group' | Boolean | ++------------------------------+------------------------------------------------+-------------------+ +| group_in_category(category) | Returns the group in 'category' if the client | String | +| | is a member of 'category', otherwise '' | | ++------------------------------+------------------------------------------------+-------------------+ + +MetadataQuery +------------- + +This class provides query routines for the servers Metadata. + ++------------------------------+------------------------------------------------+-------------------+ +| Method | Description | Value | ++==============================+================================================+===================+ +| by_name(client) | Get ClientMetadata object for 'client' | ClientMetadata | ++------------------------------+------------------------------------------------+-------------------+ +| names_by_groups(group) | | | ++------------------------------+------------------------------------------------+-------------------+ +| names_by_profiles(profile) | All clients names in 'profile' | List | ++------------------------------+------------------------------------------------+-------------------+ +| all_clients() | All known client hostnames | List | ++------------------------------+------------------------------------------------+-------------------+ +| all_groups() | All known group names | List | ++------------------------------+------------------------------------------------+-------------------+ +| all_groups_in_category(cat) | All groups in category 'cat' | List | ++------------------------------+------------------------------------------------+-------------------+ +| all() | Get ClientMetadata for all clients | List | ++------------------------------+------------------------------------------------+-------------------+ diff --git a/doc/server/plugins/index.txt b/doc/server/plugins/index.txt index e561722cf..61f91da86 100644 --- a/doc/server/plugins/index.txt +++ b/doc/server/plugins/index.txt @@ -30,18 +30,6 @@ http://trac.mcs.anl.gov/projects/bcfg2/browser/trunk/bcfg2/src/lib/Server/Plugin .. _Bcfg2 repository: http://trac.mcs.anl.gov/projects/bcfg2/browser/trunk/bcfg2/src/lib/Server/Plugins. -Connectors ----------- - -.. toctree:: - :maxdepth: 2 - :glob: - - connectors/* - -Each of these plugins has a corresponding subdirectory with the same -name in the Bcfg2 repository. - Metadata (Grouping) ------------------- @@ -80,6 +68,15 @@ Literal Configuration (Generators) Each of these plugins has a corresponding subdirectory with the same name in the Bcfg2 repository. +Connector Plugins +----------------- + +.. toctree:: + :maxdepth: 2 + :glob: + + connectors/* + Statistics Plugins ------------------ @@ -90,7 +87,7 @@ Statistics Plugins statistics/* DBStats can be enabled by adding it to the plugins line in -`/etc/bcfg2.conf`. +``/etc/bcfg2.conf``. Version Plugins --------------- diff --git a/doc/server/plugins/structures/bundler/index.txt b/doc/server/plugins/structures/bundler/index.txt index 7b4cd7b6f..da49b299e 100644 --- a/doc/server/plugins/structures/bundler/index.txt +++ b/doc/server/plugins/structures/bundler/index.txt @@ -29,7 +29,7 @@ The following is an annotated copy of a bundle: .. code-block:: xml - + diff --git a/doc/unsorted/bcfg2.conf-options.txt b/doc/unsorted/bcfg2.conf-options.txt new file mode 100644 index 000000000..57e26cbd2 --- /dev/null +++ b/doc/unsorted/bcfg2.conf-options.txt @@ -0,0 +1,19 @@ +.. -*- mode: rst -*- + +.. _unsorted-bcfg2.conf-options: + +========== +bcfg2.conf +========== + +This page documents the various options available in bcfg2.conf. The +various sections correspond to the sections in the file itself. + +components +========== + +logging +------- + +Specify an alternate path for the lockfile used by the bcfg2 client. +Default value is ``/var/lock/bcfg2.run`` diff --git a/doc/unsorted/emacs_snippet.txt b/doc/unsorted/emacs_snippet.txt new file mode 100644 index 000000000..b9f7fd25b --- /dev/null +++ b/doc/unsorted/emacs_snippet.txt @@ -0,0 +1,60 @@ +.. -*- mode: rst -*- + +.. _unsorted-emacs_snippet: + +====================== +Emacs + YASnippet mode +====================== + +This page describes using emacs with YASnippet mode with a set of +snippets that allow quick composition of bundles and base files. +More snippets are under development. + +#. Download YASnippet from http://code.google.com/p/yasnippet/ +#. Install it into your emacs load path (typically ~/.emacs.d/site-lisp) +#. Add YASnippet initialization to your .emacs (remember to re-byte-compile it if needed) + + .. code-block:: cl + + (require 'yasnippet-bundle) + + ;;; Bcfg2 snippet + + (yas/define-snippets 'sgml-mode + '( + (" + $0 + " nil) + (" + $0 + " nil) + (" + $0" nil) + (" + $0" nil) + (" + $0" nil) + (" + $0" nil) + (" + $0" nil) + (" + $0" nil) + (" + $0" nil) + ) + ) + +#. One quick M-x eval-current-buffer, and this code is enabled + +Each of these snippets activates on the opening element, ie , +and the snippet will be expanded. The template will be inserted into +the text with a set of input prompts, which default to overwrite mode +and can be tabbed through. + +The code above only works for bundles and base, but will be expanded +to support other xml files as well. diff --git a/doc/unsorted/vim_snippet.txt b/doc/unsorted/vim_snippet.txt new file mode 100644 index 000000000..e4fda7eca --- /dev/null +++ b/doc/unsorted/vim_snippet.txt @@ -0,0 +1,65 @@ +.. -*- mode: rst -*- + +.. _unsorted-vim_snippet: + +=================== +Vim Snippet Support +=================== + +This page describes using vim with snipMate and a set of snippets +that allow quick composition of bundles and base files. + +#. Download snipMate from http://www.vim.org/scripts/script.php?script_id=2540 +#. Install it using the install instructions (unzip snipMate.zip -d ~/.vim or equivalent, e.g. $HOME\vimfiles on Windows) +#. Add the following to ``~/.vim/snippets/xml.snippets`` + + .. code-block:: cl + + # Bundle + snippet + ${2} + + # Base + snippet + ${1} + + # Group + snippet + ${2} + + # ConfigFile + snippet + # Service + snippet + # Package + snippet + # Action + snippet + # Directory + snippet + # SymLink + snippet + # Permissions + snippet + + +#. Save and start editing away! + +Each of these snippets activates on the opening element, ie . +After this string is entered, but before entering a space, press , +and the snippet will be expanded. The template will be inserted into +the text with a set of input prompts, which default to overwrite mode +and can be tabbed through. + +The code above only works for bundles and base, but will be expanded +to support other xml files as well. diff --git a/doc/unsorted/writing_specification.txt b/doc/unsorted/writing_specification.txt index 5a75165bf..3201067f0 100644 --- a/doc/unsorted/writing_specification.txt +++ b/doc/unsorted/writing_specification.txt @@ -14,8 +14,8 @@ Bcfg2 specifications are logically divided in to three areas: The metadata portion of the configuration assigns a client to its profile group and to its non-profile groups. The profile group is assigned -in Metadata/clients.xml and the non profile group assignments are in -Metadata/groups.xml. +in ``Metadata/clients.xml`` and the non profile group assignments are in +``Metadata/groups.xml``. The group memberships contained in the metadata are then used to constuct an abstract configuration for the client. An abstract configuration for -- cgit v1.2.3-1-g7c22 From d08c7ba3ca269639edd8e7696558c74bc06fb487 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 8 Dec 2010 19:44:59 -0600 Subject: doc: Add back dynamic groups documentation Signed-off-by: Sol Jerome --- doc/unsorted/dynamic_groups.txt | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 doc/unsorted/dynamic_groups.txt diff --git a/doc/unsorted/dynamic_groups.txt b/doc/unsorted/dynamic_groups.txt new file mode 100644 index 000000000..11535dc8b --- /dev/null +++ b/doc/unsorted/dynamic_groups.txt @@ -0,0 +1,27 @@ +.. -*- mode: rst -*- + +.. _unsorted-dynamic_groups: + +============== +Dynamic Groups +============== + +Bcfg2 supports the use of dynamic groups. These groups are not included +in a client's profile group, but instead are derived from the results +of probes executed on the client. These dynamic groups need not already +exist in ``Metadata/groups.xml``. If a dynamic group is defined in +``Metadata/groups.xml``, clients that include this group will also get +all included groups and bundles. + +Setting up dynamic groups +========================= + +In order to define a dynamic group, setup a probe that outputs the text +based on system properties:: + + group:groupname + +This output is processed by the Bcfg2 server, and results in dynamic +group membership in groupname for the client. See the :ref:`Probes +` page for a more thorough description +of probes. -- cgit v1.2.3-1-g7c22