Module: check_mk
Branch: master
Commit: c23f8336c1c620a0a7b9d13c173215317c653b24
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=c23f8336c1c620…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Thu Dec 17 10:09:14 2015 +0100
New automation for installing MKPs
---
modules/automation.py | 18 ++++++++++++++++++
modules/check_mk.py | 19 +++++++++++++++++++
modules/packaging.py | 38 +++++++++++++++++++++++++++++++++-----
3 files changed, 70 insertions(+), 5 deletions(-)
diff --git a/modules/automation.py b/modules/automation.py
index 29036e2..5e588a5 100644
--- a/modules/automation.py
+++ b/modules/automation.py
@@ -48,6 +48,8 @@ def do_automation(cmd, args):
result = automation_get_package_info(args)
elif cmd == "get-package":
result = automation_get_package(args)
+ elif cmd == "install-package":
+ result = automation_install_package(args)
elif cmd == "remove-package":
result = automation_remove_package(args)
elif cmd == "notification-get-bulks":
@@ -1173,14 +1175,17 @@ def automation_notification_replay(args):
nr = args[0]
return notification_replay_backlog(int(nr))
+
def automation_notification_analyse(args):
nr = args[0]
return notification_analyse_backlog(int(nr))
+
def automation_get_bulks(args):
only_ripe = args[0] == "1"
return find_bulks(only_ripe)
+
def automation_active_check(args):
hostname, plugin, item = args
item = item.decode("utf-8")
@@ -1263,6 +1268,7 @@ def execute_check_plugin(commandline):
def automation_update_dns_cache():
return do_update_dns_cache()
+
def automation_bake_agents():
if "do_bake_agents" in globals():
return do_bake_agents()
@@ -1316,6 +1322,18 @@ def automation_get_package(args):
return package, output_file.content()
+def automation_install_package(args):
+ load_module("packaging")
+ file_content = sys.stdin.read()
+ input_file = fake_file(file_content)
+ try:
+ return install_package(file_object=input_file)
+ except Exception, e:
+ if opt_debug:
+ raise
+ raise MKAutomationError("Cannot install package: %s" % e)
+
+
def automation_remove_package(args):
load_module("packaging")
package_name = args[0]
diff --git a/modules/check_mk.py b/modules/check_mk.py
index 821aa99..bc96596 100755
--- a/modules/check_mk.py
+++ b/modules/check_mk.py
@@ -2851,6 +2851,7 @@ class fake_file:
return len(self._content)
def read(self, size):
+ size = min(size, len(self._content) - self._pointer)
new_end = self._pointer + size
data = self._content[self._pointer:new_end]
self._pointer = new_end
@@ -2862,6 +2863,24 @@ class fake_file:
def content(self):
return self._content
+ def tell(self):
+ return self._pointer
+
+ def seek(self, offset, whence=0):
+ if whence == 0:
+ new_pointer = offset
+ elif whence == 1:
+ new_pointer = self._pointer + offset
+ elif whence == 2:
+ new_pointer = self.size() - offset
+ else:
+ raise IOError("Invalid value for whence")
+
+ if new_pointer < 0:
+ raise IOError("Invalid seek")
+
+ self._pointer = new_pointer
+
def do_backup(tarname):
import tarfile
diff --git a/modules/packaging.py b/modules/packaging.py
index 0f262b9..a219bc1 100644
--- a/modules/packaging.py
+++ b/modules/packaging.py
@@ -76,6 +76,7 @@ Available commands are:
Package files are located in %s.
""" % pac_dir)
+
def do_packaging(args):
if len(args) == 0:
packaging_usage()
@@ -108,6 +109,7 @@ def do_packaging(args):
(", ".join(allc[:-1]), allc[-1]))
sys.exit(1)
+
def package_list(args):
if len(args) > 0:
for name in args:
@@ -123,24 +125,28 @@ def package_list(args):
for pacname in all_package_names():
sys.stdout.write("%s\n" % pacname)
+
def package_info(args):
if len(args) == 0:
raise PackageException("Usage: check_mk -P show NAME|PACKAGE.mkp")
for name in args:
show_package_info(name)
+
def show_package_contents(name):
show_package(name, False)
+
def show_package_info(name):
show_package(name, True)
+
def show_package(name, show_info = False):
try:
if name.endswith(pac_ext):
tar = tarfile.open(name, "r:gz")
info = tar.extractfile("info")
- package = eval(info.read())
+ package = parse_package_info(info.read())
else:
package = read_package_info(name)
if not package:
@@ -214,6 +220,7 @@ def package_create(args):
verbose("New package %s created with %d files.\n" % (pacname, num_files))
verbose("Please edit package details in %s%s%s\n" % (tty_bold, pac_dir +
pacname, tty_normal))
+
def package_find(_no_args):
first = True
for part, title, perm, dir in package_parts:
@@ -231,6 +238,7 @@ def package_find(_no_args):
if first:
verbose("No unpackaged files found.\n")
+
def package_release(args):
if len(args) != 1:
raise PackageException("Usage: check_mk -P release NAME")
@@ -250,6 +258,7 @@ def package_release(args):
for f in filenames:
verbose(" %s\n" % f)
+
def package_pack(args):
if len(args) != 1:
raise PackageException("Usage: check_mk -P pack NAME")
@@ -344,8 +353,12 @@ def package_install(args):
if not os.path.exists(path):
raise PackageException("No such file %s." % path)
- tar = tarfile.open(path, "r:gz")
- package = eval(tar.extractfile("info").read())
+ return install_package(file_name = path)
+
+
+def install_package(file_name=None, file_object=None):
+ tar = tarfile.open(name=file_name, fileobj=file_object, mode="r:gz")
+ package = parse_package_info(tar.extractfile("info").read())
pacname = package["name"]
old_package = read_package_info(pacname)
if old_package:
@@ -372,6 +385,7 @@ def package_install(args):
elif os.path.exists(path):
raise PackageException("File conflict: %s already existing." %
path)
+
# Now install files, but only unpack files explicitely listed
for part, title, perm, dir in package_parts:
filenames = package["files"].get(part, [])
@@ -419,6 +433,8 @@ def package_install(args):
# Last but not least install package file
file(pac_dir + pacname, "w").write(pprint.pformat(package))
+ return package
+
def files_in_dir(part, dir, prefix = ""):
if not os.path.exists(dir):
@@ -463,7 +479,7 @@ def package_part_info():
def unpackaged_files_in_dir(part, dir):
- all = files_in_dir(part, dir)
+ all = files_in_dir(part, dir)
packed = packaged_files_in_dir(part)
return [ f for f in all if f not in packed ]
@@ -479,7 +495,7 @@ def packaged_files_in_dir(part):
def read_package_info(pacname):
try:
- package = eval(file(pac_dir + pacname).read())
+ package = parse_package_info(file(pac_dir + pacname).read())
package["name"] = pacname # do not trust package content
num_files = sum([len(fl) for fl in package["files"].values() ])
package["num_files"] = num_files
@@ -499,3 +515,15 @@ def all_package_names():
all = [ p for p in os.listdir(pac_dir) if p not in [ '.', '..' ] ]
all.sort()
return all
+
+
+def parse_package_info(python_string):
+ try:
+ # ast.literal_eval does not execute any code, just reads in passive
+ # data structures, so it is safe. But: not available on all supported
+ # Python versions
+ import ast
+ except:
+ return eval(python_string)
+
+ return ast.literal_eval(python_string)