|
|
|
@ -2,7 +2,7 @@
|
|
|
|
|
# |
|
|
|
|
# 2011 Steven Armstrong (steven-cdist at armstrong.cc) |
|
|
|
|
# 2011-2015 Nico Schottelius (nico-cdist at schottelius.org) |
|
|
|
|
# 2016 Darko Poljak (darko.poljak at gmail.com) |
|
|
|
|
# 2016-2017 Darko Poljak (darko.poljak at gmail.com) |
|
|
|
|
# |
|
|
|
|
# This file is part of cdist. |
|
|
|
|
# |
|
|
|
@ -29,6 +29,8 @@ import subprocess
|
|
|
|
|
import shutil |
|
|
|
|
import logging |
|
|
|
|
import tempfile |
|
|
|
|
import time |
|
|
|
|
import datetime |
|
|
|
|
|
|
|
|
|
import cdist |
|
|
|
|
import cdist.message |
|
|
|
@ -51,7 +53,8 @@ class Local(object):
|
|
|
|
|
host_dir_name, |
|
|
|
|
exec_path=sys.argv[0], |
|
|
|
|
initial_manifest=None, |
|
|
|
|
add_conf_dirs=None): |
|
|
|
|
add_conf_dirs=None, |
|
|
|
|
cache_path_pattern=None): |
|
|
|
|
|
|
|
|
|
self.target_host = target_host |
|
|
|
|
self.hostdir = host_dir_name |
|
|
|
@ -60,6 +63,7 @@ class Local(object):
|
|
|
|
|
self.exec_path = exec_path |
|
|
|
|
self.custom_initial_manifest = initial_manifest |
|
|
|
|
self._add_conf_dirs = add_conf_dirs |
|
|
|
|
self.cache_path_pattern = cache_path_pattern |
|
|
|
|
|
|
|
|
|
self._init_log() |
|
|
|
|
self._init_permissions() |
|
|
|
@ -77,10 +81,7 @@ class Local(object):
|
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def home_dir(self): |
|
|
|
|
if 'HOME' in os.environ: |
|
|
|
|
return os.path.join(os.environ['HOME'], ".cdist") |
|
|
|
|
else: |
|
|
|
|
return None |
|
|
|
|
return cdist.home_dir() |
|
|
|
|
|
|
|
|
|
def _init_log(self): |
|
|
|
|
self.log = logging.getLogger(self.target_host[0]) |
|
|
|
@ -239,28 +240,70 @@ class Local(object):
|
|
|
|
|
""" |
|
|
|
|
if os.access(script, os.X_OK): |
|
|
|
|
self.log.debug('%s is executable, running it', script) |
|
|
|
|
command=[script] |
|
|
|
|
command = [script] |
|
|
|
|
else: |
|
|
|
|
command = [os.environ.get('CDIST_LOCAL_SHELL', "/bin/sh"), "-e"] |
|
|
|
|
self.log.debug('%s is NOT executable, running it with %s', |
|
|
|
|
script, " ".join(command)) |
|
|
|
|
script, " ".join(command)) |
|
|
|
|
command.append(script) |
|
|
|
|
|
|
|
|
|
return self.run(command=command, env=env, return_output=return_output, |
|
|
|
|
message_prefix=message_prefix, save_output=save_output) |
|
|
|
|
|
|
|
|
|
def save_cache(self): |
|
|
|
|
destination = os.path.join(self.cache_path, self.hostdir) |
|
|
|
|
def _cache_subpath_repl(self, matchobj): |
|
|
|
|
if matchobj.group(2) == '%P': |
|
|
|
|
repl = str(os.getpid()) |
|
|
|
|
elif matchobj.group(2) == '%h': |
|
|
|
|
repl = self.hostdir |
|
|
|
|
elif matchobj.group(2) == '%N': |
|
|
|
|
repl = self.target_host[0] |
|
|
|
|
|
|
|
|
|
return matchobj.group(1) + repl |
|
|
|
|
|
|
|
|
|
def _cache_subpath(self, start_time=time.time(), path_format=None): |
|
|
|
|
if path_format: |
|
|
|
|
repl_func = self._cache_subpath_repl |
|
|
|
|
cache_subpath = re.sub(r'([^%]|^)(%h|%P|%N)', repl_func, |
|
|
|
|
path_format) |
|
|
|
|
dt = datetime.datetime.fromtimestamp(start_time) |
|
|
|
|
cache_subpath = dt.strftime(cache_subpath) |
|
|
|
|
else: |
|
|
|
|
cache_subpath = self.hostdir |
|
|
|
|
|
|
|
|
|
i = 0 |
|
|
|
|
while i < len(cache_subpath) and cache_subpath[i] == os.sep: |
|
|
|
|
i += 1 |
|
|
|
|
cache_subpath = cache_subpath[i:] |
|
|
|
|
if not cache_subpath: |
|
|
|
|
cache_subpath = self.hostdir |
|
|
|
|
return cache_subpath |
|
|
|
|
|
|
|
|
|
def save_cache(self, start_time=time.time()): |
|
|
|
|
self.log.debug("cache subpath pattern: {}".format( |
|
|
|
|
self.cache_path_pattern)) |
|
|
|
|
cache_subpath = self._cache_subpath(start_time, |
|
|
|
|
self.cache_path_pattern) |
|
|
|
|
self.log.debug("cache subpath: {}".format(cache_subpath)) |
|
|
|
|
destination = os.path.join(self.cache_path, cache_subpath) |
|
|
|
|
self.log.debug("Saving " + self.base_path + " to " + destination) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
if os.path.exists(destination): |
|
|
|
|
shutil.rmtree(destination) |
|
|
|
|
except PermissionError as e: |
|
|
|
|
raise cdist.Error( |
|
|
|
|
"Cannot delete old cache %s: %s" % (destination, e)) |
|
|
|
|
if not os.path.exists(destination): |
|
|
|
|
shutil.move(self.base_path, destination) |
|
|
|
|
else: |
|
|
|
|
for direntry in os.listdir(self.base_path): |
|
|
|
|
srcentry = os.path.join(self.base_path, direntry) |
|
|
|
|
destentry = os.path.join(destination, direntry) |
|
|
|
|
try: |
|
|
|
|
if os.path.isdir(destentry): |
|
|
|
|
shutil.rmtree(destentry) |
|
|
|
|
elif os.path.exists(destentry): |
|
|
|
|
os.remove(destentry) |
|
|
|
|
except (PermissionError, OSError) as e: |
|
|
|
|
raise cdist.Error( |
|
|
|
|
"Cannot delete old cache entry {}: {}".format( |
|
|
|
|
destentry, e)) |
|
|
|
|
shutil.move(srcentry, destentry) |
|
|
|
|
|
|
|
|
|
shutil.move(self.base_path, destination) |
|
|
|
|
# add target_host since cache dir can be hash-ed target_host |
|
|
|
|
host_cache_path = os.path.join(destination, "target_host") |
|
|
|
|
with open(host_cache_path, 'w') as hostf: |
|
|
|
|