[enh] Allow to show the diff between conf in service_regen_conf

This commit is contained in:
Jérôme Lebleu 2016-04-11 18:50:45 +02:00
parent 96d4eb3396
commit eecf03ffbc
2 changed files with 39 additions and 29 deletions

View file

@ -969,6 +969,10 @@ service:
help: Services name to regenerate configuration of help: Services name to regenerate configuration of
nargs: "*" nargs: "*"
metavar: NAME metavar: NAME
-d:
full: --with-diff
help: Show differences in case of configuration changes
action: store_true
-f: -f:
full: --force full: --force
help: > help: >

View file

@ -30,8 +30,8 @@ import glob
import subprocess import subprocess
import errno import errno
import shutil import shutil
import difflib
import hashlib import hashlib
from difflib import unified_diff
from moulinette.core import MoulinetteError from moulinette.core import MoulinetteError
from moulinette.utils import log, filesystem from moulinette.utils import log, filesystem
@ -271,12 +271,13 @@ def service_log(name, number=50):
return result return result
def service_regen_conf(names=[], force=False): def service_regen_conf(names=[], with_diff=False, force=False):
""" """
Regenerate the configuration file(s) for a service Regenerate the configuration file(s) for a service
Keyword argument: Keyword argument:
names -- Services name to regenerate configuration of names -- Services name to regenerate configuration of
with_diff -- Show differences in case of configuration changes
force -- Override all manual modifications in configuration files force -- Override all manual modifications in configuration files
""" """
@ -316,6 +317,10 @@ def service_regen_conf(names=[], force=False):
conf_status = None conf_status = None
regenerated = False regenerated = False
# Get the diff between files
conf_diff = _get_files_diff(
system_path, pending_path, True) if with_diff else None
# Check if the conf must be removed # Check if the conf must be removed
to_remove = True if os.path.getsize(pending_path) == 0 else False to_remove = True if os.path.getsize(pending_path) == 0 else False
@ -384,8 +389,9 @@ def service_regen_conf(names=[], force=False):
conf_status = 'modified' conf_status = 'modified'
# Store the result # Store the result
# TODO: Append the diff if --with-diff
conf_result = {'status': conf_status} conf_result = {'status': conf_status}
if conf_diff is not None:
conf_result['diff'] = conf_diff
if regenerated: if regenerated:
succeed_regen[system_path] = conf_result succeed_regen[system_path] = conf_result
conf_hashes[system_path] = new_hash conf_hashes[system_path] = new_hash
@ -396,9 +402,7 @@ def service_regen_conf(names=[], force=False):
if not succeed_regen and not failed_regen: if not succeed_regen and not failed_regen:
logger.info(m18n.n('service_conf_up_to_date', service=service)) logger.info(m18n.n('service_conf_up_to_date', service=service))
continue continue
elif failed_regen: elif not failed_regen:
logger.error(m18n.n('service_regenconf_failed', services=service))
else:
logger.success(m18n.n('service_conf_updated', service=service)) logger.success(m18n.n('service_conf_updated', service=service))
if succeed_regen: if succeed_regen:
_update_conf_hashes(service, conf_hashes) _update_conf_hashes(service, conf_hashes)
@ -500,36 +504,38 @@ def _tail(file, n, offset=None):
except IOError: return [] except IOError: return []
def _get_diff(string, filename): def _get_files_diff(orig_file, new_file, as_string=False, skip_header=True):
""" """Compare two files and return the differences
Show differences between a string and a file's content
Keyword argument: Read and compare two files. The differences are returned either as a delta
string -- The string in unified diff format or a formatted string if as_string is True. The
filename -- The file to compare with header can also be removed if skip_header is True.
""" """
try: contents = [[], []]
with open(filename, 'r') as f: for i, path in enumerate((orig_file, new_file)):
file_lines = f.readlines() try:
with open(path, 'r') as f:
contents[i] = f.readlines()
except IOError:
pass
string = string + '\n' # Compare files and format output
new_lines = string.splitlines(True) diff = unified_diff(contents[0], contents[1])
if file_lines: if skip_header:
while '\n' == file_lines[-1]: for i in range(2):
del file_lines[-1] try:
return difflib.unified_diff(file_lines, new_lines) next(diff)
except IOError: return [] except:
break
if as_string:
result = ''.join(line for line in diff)
return result.rstrip()
return diff
def _calculate_hash(path): def _calculate_hash(path):
""" """Calculate the MD5 hash of a file"""
Calculate the MD5 hash of a file
Keyword argument:
path -- The path to the file
"""
hasher = hashlib.md5() hasher = hashlib.md5()
try: try:
with open(path, 'rb') as f: with open(path, 'rb') as f: