summaryrefslogtreecommitdiffstats
path: root/src/sbin/bcfg2-admin
diff options
context:
space:
mode:
authorNarayan Desai <desai@mcs.anl.gov>2006-12-13 17:23:23 +0000
committerNarayan Desai <desai@mcs.anl.gov>2006-12-13 17:23:23 +0000
commit8a2cfbd5f868a221c496908c3bae3beed1451dce (patch)
treea218c829642ebc12c07f95f1892e4ed393374db9 /src/sbin/bcfg2-admin
parent44550e33cca1698d2284be11989dfdd10c7a1777 (diff)
downloadbcfg2-8a2cfbd5f868a221c496908c3bae3beed1451dce.tar.gz
bcfg2-8a2cfbd5f868a221c496908c3bae3beed1451dce.tar.bz2
bcfg2-8a2cfbd5f868a221c496908c3bae3beed1451dce.zip
Add tidy mode to bcfg2-admin (clean up unused/unusable files)
* Implement SSHbase key cleanup * Still more work to do git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@2591 ce84e21b-d406-0410-9b95-82705330c041
Diffstat (limited to 'src/sbin/bcfg2-admin')
-rwxr-xr-xsrc/sbin/bcfg2-admin79
1 files changed, 71 insertions, 8 deletions
diff --git a/src/sbin/bcfg2-admin b/src/sbin/bcfg2-admin
index 60b11c235..56ac43f58 100755
--- a/src/sbin/bcfg2-admin
+++ b/src/sbin/bcfg2-admin
@@ -1,13 +1,16 @@
#!/usr/bin/python
'''bcfg2-admin is a script that helps to administrate a bcfg2 deployment'''
-import difflib, lxml.etree, os, socket, sys, ConfigParser
+import difflib, logging, lxml.etree, os, re, socket, sys, ConfigParser
import Bcfg2.Server.Core, Bcfg2.Logging
+log = logging.getLogger('bcfg-admin')
+
usage = '''
bcfg2-admin [options]
-init initialize the bcfg2 repository( this is interactive; only run once )
-pull <client> <entry type> <entry name>
+init - initialize the bcfg2 repository( this is interactive; only run once )
+mineentry <client> <entry type> <entry name> - mine statistics for entry information
+minestruct <client> - mine statistics for extra entries
'''
config = '''
@@ -132,17 +135,25 @@ def update_file(path, diff):
print "writing file, %s" % path
open(path, 'w').write(newdata)
-def do_pull(client, etype, ename):
- '''Make currently recorded client state correct for entry'''
+def get_repo_path():
+ '''return repository path'''
cfile = '/etc/bcfg2.conf'
cfp = ConfigParser.ConfigParser()
cfp.read(cfile)
- repo = cfp.get('server', 'repository')
+ return cfp.get('server', 'repository')
+
+def load_stats(client):
+ repo = get_repo_path()
stats = lxml.etree.parse("%s/etc/statistics.xml" % (repo))
hostent = stats.xpath('.//Node[@name="%s"]' % client)
if not hostent:
- print "Could not find stats for client %s" % (client)
- sdata = hostent[0]
+ err_exit("Could not find stats for client %s" % (client))
+ return hostent[0]
+
+def do_pull(client, etype, ename):
+ '''Make currently recorded client state correct for entry'''
+ cfile = '/etc/bcfg2.conf'
+ sdata = load_stats(client)
if sdata.xpath('.//Statistics[@state="dirty"]'):
state = 'dirty'
else:
@@ -199,6 +210,54 @@ def do_pull(client, etype, ename):
else:
err_exit("Don't support entry type %s yet" % etype)
# svn commit if running under svn
+
+def do_minestruct(argdata):
+ '''Pull client entries into structure'''
+ if len(argdata) != 1:
+ err_exit("minestruct must be called with a client name")
+ client = argdata[0]
+ stats = load_stats(client)
+ if len(stats.getchildren()) == 2:
+ # client is dirty
+ current = [ent for ent in stats.getchildren() if ent.get('state') == 'dirty'][0]
+ else:
+ current = stats.getchildren()[0]
+ extra = current.find('Extra').getchildren()
+ log.info("Found %d extra entries" % (len(extra)))
+ log.info(["%s: %s" % (entry.tag, entry.get('name')) for entry in extra])
+
+def do_tidy(args):
+ '''Clean up unused or unusable files from the repository'''
+ hostmatcher = re.compile('.*\.H_(\S+)$')
+ repo = get_repo_path()
+ score = ([], [])
+ # clean up unresolvable hosts in SSHbase
+ for name in os.listdir("%s/SSHbase" % (repo)):
+ if not hostmatcher.match(name):
+ print "could not match name %s" % (name)
+ else:
+ hostname = hostmatcher.match(name).group(1)
+ if hostname in score[0] + score[1]:
+ continue
+ try:
+ socket.gethostbyname(hostname)
+ score[0].append(hostname)
+ except:
+ print "could not resolve %s" % (hostname)
+ score[1].append(hostname)
+ for name in os.listdir("%s/SSHbase" % (repo)):
+ if not hostmatcher.match(name):
+ print "could not match name %s" % (name)
+ else:
+ if hostmatcher.match(name).group(1) in score[1]:
+ if '-f' in args:
+ os.unlink("%s/SSHbase/%s" % (repo, name))
+ else:
+ answer = raw_input("Unlink file %s? [yN] " % name)
+ if answer in ['y', 'Y']:
+ os.unlink("%s/SSHbase/%s" % (repo, name))
+ # clean up file~
+ # clean up files without parsable names in Cfg
if __name__ == '__main__':
Bcfg2.Logging.setup_logging('bcfg2-admin', to_console=True)
@@ -209,6 +268,10 @@ if __name__ == '__main__':
print usage
raise SystemExit, 1
do_pull(sys.argv[2], sys.argv[3], sys.argv[4])
+ elif sys.argv[1] == 'minestruct':
+ do_minestruct(sys.argv[2:])
+ elif sys.argv[1] == 'tidy':
+ do_tidy(sys.argv[2:])
else:
print usage