summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarayan Desai <desai@mcs.anl.gov>2006-03-16 21:55:04 +0000
committerNarayan Desai <desai@mcs.anl.gov>2006-03-16 21:55:04 +0000
commit599f97b63e66985e92e4c410b4252cc7fa03e30c (patch)
tree30a166acc5b45f0784165d98332973f1da248948
parentd59a484e32788b15bc7ee244a7b3e254ba016ab4 (diff)
downloadbcfg2-599f97b63e66985e92e4c410b4252cc7fa03e30c.tar.gz
bcfg2-599f97b63e66985e92e4c410b4252cc7fa03e30c.tar.bz2
bcfg2-599f97b63e66985e92e4c410b4252cc7fa03e30c.zip
Documentation updates
Add bundle and client support to groups-to-dot.py git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@1801 ce84e21b-d406-0410-9b95-82705330c041
-rw-r--r--doc/architecture.xml123
-rwxr-xr-xtools/groups-to-dot.py36
2 files changed, 153 insertions, 6 deletions
diff --git a/doc/architecture.xml b/doc/architecture.xml
index 779b57611..2fb1b3c98 100644
--- a/doc/architecture.xml
+++ b/doc/architecture.xml
@@ -427,4 +427,127 @@
</para>
</section>
</section>
+
+ <section>
+ <title>Design Considerations</title>
+
+ <para>
+ 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.
+ </para>
+
+ <section>
+ <title>System Metadata</title>
+
+ <para>
+ 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.
+ </para>
+
+ <para>
+ 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.
+ </para>
+
+ <para>
+ In particular, we wanted to streamline several operations that
+ commonly occurred in our environment.
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>Copying one node's profile to another
+ node.</para>
+
+ <para>
+ 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.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Creating a specialized version of a
+ currently existing profile.
+ </para>
+
+ <para>
+ 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.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Compose several pre-existing configuration aspects to
+ create a new profile.
+ </para>
+
+ <para>
+ 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.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ 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)
+ </para>
+
+ <para>
+ These use cases motivate several of the design decisions that
+ we made:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ 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.
+ </para>
+ </listitem>
+ </orderedlist>
+ </section>
+
+ <section>
+ <title>Package Management</title>
+
+ <para>
+ The interface provided in the bcfg2 repository for package
+ specification was designed with automation in mind. The goal
+ was to
+ </section>
+ </section>
</chapter> \ No newline at end of file
diff --git a/tools/groups-to-dot.py b/tools/groups-to-dot.py
index 91230c5dd..164d5599d 100755
--- a/tools/groups-to-dot.py
+++ b/tools/groups-to-dot.py
@@ -10,24 +10,48 @@ colors = ['aquamarine', 'chartreuse', 'gold', 'magenta', 'indianred1', 'limegree
if __name__ == '__main__':
if len(sys.argv) < 2:
- print "Usage groups-to-dot.py <groupsfile>"
+ print "Usage groups-to-dot.py [-h] <metadatadir>"
raise SystemExit, 1
- groups = lxml.etree.parse(sys.argv[1]).getroot()
+ groups = lxml.etree.parse(sys.argv[-1] + '/groups.xml').getroot()
+ clients= lxml.etree.parse(sys.argv[-1] + '/clients.xml').getroot()
categories = {'default':'grey83'}
+ instances = {}
for group in groups.findall('Group'):
if group.get('category', False):
if not categories.has_key(group.get('category')):
categories[group.get('category')] = colors.pop()
print "digraph groups {"
+ if '-h' in sys.argv:
+ print '\trankdir="LR";'
+ for client in clients.findall('Client'):
+ if instances.has_key(client.get('profile')):
+ instances[client.get('profile')].append(client.get('name'))
+ else:
+ instances[client.get('profile')] = [client.get('name')]
+ for profile, clist in instances.iteritems():
+ clist.sort()
+ print '''\t"%s-instances" [ label="%s", shape="record" ];''' % (profile, '|'.join(clist))
+ print '''\t"%s-instances" -> "%s";''' % (profile, profile)
+
+ if '-b' in sys.argv:
+ bundles = []
+ [bundles.append(bund.get('name')) for bund in groups.findall('.//Bundle')
+ if bund.get('name') not in bundles]
+ bundles.sort()
+ for bundle in bundles:
+ print '''\t"%s" [ shape="rect"];''' % (bundle)
+
for group in groups.findall('Group'):
color = categories[group.get('category', 'default')]
if group.get('profile', 'false') == 'true':
- print '\tnode [style="filled,bold", fillcolor=%s];' % (color)
+ print '\t"%s" [style="filled,bold", fillcolor=%s];' % (group.get('name'), color)
else:
- print '\tnode [style="filled", fillcolor=%s];' % (color)
- print '\t"%s";' % (group.get('name'))
-
+ print '\t"%s" [style="filled", fillcolor=%s];' % (group.get('name'), color)
+ if '-b' in sys.argv:
+ for bundle in group.findall('Bundle'):
+ print '\t"%s" -> "%s";' % (group.get('name'), bundle.get('name'))
+
for group in groups.findall('Group'):
for parent in group.findall('Group'):
print '\t"%s" -> "%s" ;' % (group.get('name'), parent.get('name'))