8302a1ccda7be5f83ea5a54580572be564c8abd6
3 ## use func to collect inventory data on anything, yes, anything
5 ## Copyright 2007, Red Hat, Inc
6 ## Michael DeHaan <mdehaan@redhat.com>
9 ## This software may be freely redistributed under the terms of the GNU
10 ## general public license.
12 ## You should have received a copy of the GNU General Public License
13 ## along with this program; if not, write to the Free Software
14 ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 from func
.minion
import sub_process
24 import func
.overlord
.client
as func_client
25 import func
.utils
as utils
27 DEFAULT_TREE
= "/var/lib/func/inventory/"
30 class FuncInventory(object):
37 p
= optparse
.OptionParser()
38 p
.add_option("-v", "--verbose",
41 help="provide extra output")
42 p
.add_option("-s", "--server-spec",
45 help="run against specific servers, default: '*'")
46 p
.add_option("-m", "--methods",
49 help="run inventory only on certain function names, default: 'inventory'")
50 p
.add_option("-M", "--modules",
53 help="run inventory only on certain module names, default: 'all'")
54 p
.add_option("-t", "--tree",
57 help="output results tree here, default: %s" % DEFAULT_TREE
)
58 p
.add_option("-n", "--no-git",
61 help="disable useful change tracking features")
62 p
.add_option("-x", "--xmlrpc", dest
="xmlrpc",
63 help="output data using XMLRPC format",
65 p
.add_option("-j", "--json", dest
="json",
66 help="output data using JSON",
70 (options
, args
) = p
.parse_args(args
)
71 self
.options
= options
73 filtered_module_list
= options
.modules
.split(",")
74 filtered_function_list
= options
.methods
.split(",")
76 self
.git_setup(options
)
78 # see what modules each host provides (as well as what hosts we have)
79 host_methods
= func_client
.Client(options
.server_spec
).system
.list_methods()
81 # call all remote info methods and handle them
83 print "- scanning ..."
84 # for (host, modules) in host_modules.iteritems():
86 for (host
, methods
) in host_methods
.iteritems():
88 if utils
.is_error(methods
):
89 print "-- connection refused: %s" % host
92 for each_method
in methods
:
94 #if type(each_method) == int:
95 # if self.options.verbose:
96 # print "-- connection refused: %s" % host
99 tokens
= each_method
.split(".")
100 module_name
= ".".join(tokens
[:-1])
101 method_name
= tokens
[-1]
103 if not "all" in filtered_module_list
and not module_name
in filtered_module_list
:
106 if not "all" in filtered_function_list
and not method_name
in filtered_function_list
:
109 client
= func_client
.Client(host
,noglobs
=True) # ,noglobs=True)
110 results
= getattr(getattr(client
,module_name
),method_name
)()
111 if self
.options
.verbose
:
112 print "-- %s: running: %s %s" % (host
, module_name
, method_name
)
113 self
.save_results(options
, host
, module_name
, method_name
, results
)
114 self
.git_update(options
)
117 def format_return(self
, data
):
119 The call module supports multiple output return types, the default is pprint.
122 # special case... if the return is a string, just print it straight
123 if type(data
) == str:
126 if self
.options
.xmlrpc
:
127 return xmlrpclib
.dumps((data
,""))
129 if self
.options
.json
:
132 return simplejson
.dumps(data
)
134 print "ERROR: json support not found, install python-simplejson"
137 return pprint
.pformat(data
)
139 # FUTURE: skvidal points out that guest symlinking would be an interesting feature
141 def save_results(self
, options
, host_name
, module_name
, method_name
, results
):
142 dirname
= os
.path
.join(options
.tree
, host_name
, module_name
)
143 if not os
.path
.exists(dirname
):
145 filename
= os
.path
.join(dirname
, method_name
)
146 results_file
= open(filename
,"w+")
147 data
= self
.format_return(results
)
148 results_file
.write(data
)
151 def git_setup(self
,options
):
154 if not os
.path
.exists("/usr/bin/git"):
155 print "git-core is not installed, so no change tracking is available."
156 print "use --no-git or, better, just install it."
159 if not os
.path
.exists(options
.tree
):
160 os
.makedirs(options
.tree
)
161 dirname
= os
.path
.join(options
.tree
, ".git")
162 if not os
.path
.exists(dirname
):
164 print "- initializing git repo: %s" % options
.tree
166 os
.chdir(options
.tree
)
167 rc1
= sub_process
.call(["/usr/bin/git", "init"], shell
=False)
172 print "- git already initialized: %s" % options
.tree
174 def git_update(self
,options
):
179 print "- updating git"
180 mytime
= time
.asctime()
182 os
.chdir(options
.tree
)
183 rc1
= sub_process
.call(["/usr/bin/git", "add", "*" ], shell
=False)
184 rc2
= sub_process
.call(["/usr/bin/git", "commit", "-a", "-m", "Func-inventory update: %s" % mytime
], shell
=False)
189 if __name__
== "__main__":
190 inv
= FuncInventory()