1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
import getopt
import sys
import Bcfg2.Server.Admin
class Pull(Bcfg2.Server.Admin.MetadataCore):
"""Pull mode retrieves entries from clients and
integrates the information into the repository.
"""
__shorthelp__ = ("Integrate configuration information "
"from clients into the server repository")
__longhelp__ = (__shorthelp__ + "\n\nbcfg2-admin pull [-v] [-f][-I] [-s]"
"<client> <entry type> <entry name>")
__usage__ = ("bcfg2-admin pull [options] <client> <entry type> "
"<entry name>\n\n"
" %-25s%s\n"
" %-25s%s\n"
" %-25s%s\n"
" %-25s%s\n" %
("-v",
"be verbose",
"-f",
"force",
"-I",
"interactive",
"-s",
"stdin"))
allowed = ['Metadata', 'BB', "DBStats", "Statistics", "Cfg", "SSHbase"]
def __init__(self, configfile):
Bcfg2.Server.Admin.MetadataCore.__init__(self, configfile,
self.__usage__)
self.log = False
self.mode = 'interactive'
def __call__(self, args):
Bcfg2.Server.Admin.Mode.__call__(self, args)
use_stdin = False
try:
opts, gargs = getopt.getopt(args, 'vfIs')
except:
print self.__shorthelp__
raise SystemExit(1)
for opt in opts:
if opt[0] == '-v':
self.log = True
elif opt[0] == '-f':
self.mode = 'force'
elif opt[0] == '-I':
self.mode == 'interactive'
elif opt[0] == '-s':
use_stdin = True
if use_stdin:
for line in sys.stdin:
try:
self.PullEntry(*line.split(None, 3))
except SystemExit:
print " for %s" % line
except:
print "Bad entry: %s" % line.strip()
elif len(gargs) < 3:
print self.__longhelp__
raise SystemExit(1)
else:
self.PullEntry(gargs[0], gargs[1], gargs[2])
def BuildNewEntry(self, client, etype, ename):
"""Construct a new full entry for given client/entry from statistics."""
new_entry = {'type':etype, 'name':ename}
for plugin in self.bcore.pull_sources:
try:
(owner, group, perms, contents) = \
plugin.GetCurrentEntry(client, etype, ename)
break
except Bcfg2.Server.Plugin.PluginExecutionError:
if plugin == self.bcore.pull_sources[-1]:
print "Pull Source failure; could not fetch current state"
raise SystemExit(1)
try:
data = {'owner':owner, 'group':group, 'perms':perms, 'text':contents}
except UnboundLocalError:
print("Unable to build entry. "
"Do you have a statistics plugin enabled?")
raise SystemExit(1)
for k, v in data.iteritems():
if v:
new_entry[k] = v
#print new_entry
return new_entry
def Choose(self, choices):
"""Determine where to put pull data."""
if self.mode == 'interactive':
for choice in choices:
print "Plugin returned choice:"
if id(choice) == id(choices[0]):
print "(current entry)",
if choice.all:
print " => global entry"
elif choice.group:
print (" => group entry: %s (prio %d)" %
(choice.group, choice.prio))
else:
print " => host entry: %s" % (choice.hostname)
if raw_input("Use this entry? [yN]: ") in ['y', 'Y']:
return choice
return False
else:
# mode == 'force'
if not choices:
return False
return choices[0]
def PullEntry(self, client, etype, ename):
"""Make currently recorded client state correct for entry."""
new_entry = self.BuildNewEntry(client, etype, ename)
meta = self.bcore.build_metadata(client)
# find appropriate plugin in bcore
glist = [gen for gen in self.bcore.generators if
ename in gen.Entries.get(etype, {})]
if len(glist) != 1:
self.errExit("Got wrong numbers of matching generators for entry:" \
+ "%s" % ([g.name for g in glist]))
plugin = glist[0]
if not isinstance(plugin, Bcfg2.Server.Plugin.PullTarget):
self.errExit("Configuration upload not supported by plugin %s" \
% (plugin.name))
try:
choices = plugin.AcceptChoices(new_entry, meta)
specific = self.Choose(choices)
if specific:
plugin.AcceptPullData(specific, new_entry, self.log)
except Bcfg2.Server.Plugin.PluginExecutionError:
self.errExit("Configuration upload not supported by plugin %s" \
% (plugin.name))
# FIXME svn commit if running under svn
|