summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/Server/Admin/Client.py55
-rw-r--r--src/lib/Server/Admin/Query.py18
-rw-r--r--src/lib/Server/Plugins/Metadata.py19
3 files changed, 72 insertions, 20 deletions
diff --git a/src/lib/Server/Admin/Client.py b/src/lib/Server/Admin/Client.py
index 9d75a6ab3..c4f931350 100644
--- a/src/lib/Server/Admin/Client.py
+++ b/src/lib/Server/Admin/Client.py
@@ -1,50 +1,75 @@
import lxml.etree
-
+import fcntl
import Bcfg2.Server.Admin
class Client(Bcfg2.Server.Admin.Mode):
__shorthelp__ = 'bcfg2-admin client add <client> attr1=val1 attr2=val2\nbcfg2-admin client del <client>'
__longhelp__ = __shorthelp__ + '\n\tCreate or delete client entries'
- def __init__(self):
- Bcfg2.Server.Admin.Mode.__init__(self)
+ def __init__(self, configfile):
+ Bcfg2.Server.Admin.Mode.__init__(self, configfile)
try:
- self.bcore = Bcfg2.Server.Core.Core(self.repo, [], ['Metadata'],
+ self.bcore = Bcfg2.Server.Core.Core(self.get_repo_path(), [], ['Metadata'],
'foo', False)
except Bcfg2.Server.Core.CoreInitError, msg:
self.errExit("Core load failed because %s" % msg)
- [bcore.fam.Service() for _ in range(5)]
- while bcore.fam.Service():
+ [self.bcore.fam.Service() for _ in range(5)]
+ while self.bcore.fam.Service():
pass
+ self.tree = lxml.etree.parse(self.get_repo_path() + "/Metadata/clients.xml")
+ self.root = self.tree.getroot()
def __call__(self, args):
Bcfg2.Server.Admin.Mode.__call__(self, args)
if args[0] == 'add':
attr_d = {}
- for i in args[1:]:
+ for i in args[2:]:
attr, val = i.split('=', 1)
if attr not in ['profile', 'uuid', 'password', 'address',
'secure', 'location']:
print "Attribute %s unknown" % attr
raise SystemExit(1)
attr_d[attr] = val
- self.AddClient(args[1], attr_d)
+ self.add_client(args[1], attr_d)
elif args[0] in ['delete', 'remove', 'del', 'rm']:
- self.DelClient(args[1])
+ self.del_client(args[1])
else:
print "No command specified"
raise SystemExit(1)
- self.tree.write(self.get_repo_path() + '/Metadata/clients.xml')
+ client_tree = open(self.get_repo_path() + "/Metadata/clients.xml","w")
+ fd = client_tree.fileno()
+ while True:
+ try:
+ fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+ except IOError:
+ continue
+ else:
+ break
+ self.tree.write(client_tree)
+ fcntl.lockf(fd, fcntl.LOCK_UN)
+ client_tree.close()
- def AddClient(self, client, attrs):
+ def add_client(self, client, attrs):
'''add a new client'''
- # FIXME add a dup client check
element = lxml.etree.Element("Client", name=client)
for key, val in attrs.iteritems():
element.set(key, val)
+ node = self.search_client(client)
+ if node != None:
+ print "Client \"%s\" already exists" % (client)
+ raise SystemExit(1)
self.root.append(element)
- def DelClient(self, client):
+ def del_client(self, client):
'''delete an existing client'''
- # FIXME DelClient not implemented
- pass
+ node = self.search_client(client)
+ if node == None:
+ print "Client \"%s\" not found" % (client)
+ raise SystemExit(1)
+ self.root.remove(node)
+ def search_client(self, client):
+ '''find a client'''
+ for node in self.root:
+ if node.attrib["name"] == client:
+ return node
+ return None
diff --git a/src/lib/Server/Admin/Query.py b/src/lib/Server/Admin/Query.py
index 0c0659213..a5e2a977e 100644
--- a/src/lib/Server/Admin/Query.py
+++ b/src/lib/Server/Admin/Query.py
@@ -1,7 +1,7 @@
import Bcfg2.Server.Admin, Bcfg2.Logging, logging
class Query(Bcfg2.Server.Admin.Mode):
- __shorthelp__ = 'bcfg2-admin query [-n] [-c] g=group p=profile'
+ __shorthelp__ = 'bcfg2-admin query [-n] [-c] [-f filename] g=group p=profile'
__longhelp__ = __shorthelp__ + '\n\tQuery clients'
def __init__(self, cfile):
logging.root.setLevel(100)
@@ -22,9 +22,18 @@ class Query(Bcfg2.Server.Admin.Mode):
def __call__(self, args):
Bcfg2.Server.Admin.Mode.__call__(self, args)
clients = self.meta.clients.keys()
+ filename_arg = False
+ filename = None
for arg in args:
+ if filename_arg == True:
+ filename = arg
+ filename_arg = False
+ continue
if arg in ['-n', '-c']:
continue
+ if arg in ['-f']:
+ filename_arg = True
+ continue
try:
k, v = arg.split('=')
except:
@@ -37,9 +46,14 @@ class Query(Bcfg2.Server.Admin.Mode):
self.meta.groups[self.meta.clients[c]][1] or
v in self.meta.cgroups.get(c, [])]
clients = [c for c in clients if c in nc]
-
if '-n' in args:
for client in clients:
print client
else:
print ','.join(clients)
+ if '-f' in args:
+ f = open(filename, "w")
+ for client in clients:
+ f.write(client + "\n")
+ f.close()
+ print "Wrote results to %s" % (filename)
diff --git a/src/lib/Server/Plugins/Metadata.py b/src/lib/Server/Plugins/Metadata.py
index f79aa4d03..67959c968 100644
--- a/src/lib/Server/Plugins/Metadata.py
+++ b/src/lib/Server/Plugins/Metadata.py
@@ -1,7 +1,7 @@
'''This file stores persistent metadata for the BCFG Configuration Repository'''
__revision__ = '$Revision$'
-import lxml.etree, re, socket, time
+import lxml.etree, re, socket, time, fcntl, copy
import Bcfg2.Server.Plugin
class MetadataConsistencyError(Exception):
@@ -267,9 +267,20 @@ class Metadata(Bcfg2.Server.Plugin.MetadataPlugin,
except IOError:
self.logger.error("Failed to write clients.xml")
raise MetadataRuntimeError
+ fd = datafile.fileno()
+ while self.locked(fd) == True:
+ pass
datafile.write(lxml.etree.tostring(self.clientdata.getroot()))
+ fcntl.lockf(fd, fcntl.LOCK_UN)
datafile.close()
-
+
+ def locked(self, fd):
+ try:
+ fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+ except IOError:
+ return True
+ return False
+
def write_probedata(self):
'''write probe data out for use with bcfg2-info'''
if self.pdirty:
@@ -362,8 +373,10 @@ class Metadata(Bcfg2.Server.Plugin.MetadataPlugin,
[newbundles.append(b) for b in nbundles if b not in newbundles]
[newgroups.append(g) for g in ngroups if g not in newgroups]
newcategories.update(ncategories)
+ groupscopy = copy.deepcopy(self.groups)
+ profilescopy = copy.deepcopy(self.profiles)
return ClientMetadata(client, newgroups, newbundles, newcategories,
- probed, uuid, password, self)
+ probed, uuid, password, (groupscopy, profilescopy))
def GetProbes(self, meta, force=False):
'''Return a set of probes for execution on client'''