diff --git a/data/actionsmap/yunohost.yml b/data/actionsmap/yunohost.yml index 525c0c1da..f51e93bd8 100644 --- a/data/actionsmap/yunohost.yml +++ b/data/actionsmap/yunohost.yml @@ -980,6 +980,10 @@ service: Override all manual modifications in configuration files action: store_true + -n: + full: --dry-run + help: Show what would have been regenerated + action: store_true -p: full: --list-pending help: List pending configuration files and exit diff --git a/data/hooks/conf_regen/01-yunohost b/data/hooks/conf_regen/01-yunohost index 3583084a1..78cb92b1b 100755 --- a/data/hooks/conf_regen/01-yunohost +++ b/data/hooks/conf_regen/01-yunohost @@ -91,10 +91,11 @@ EOF } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) ;; diff --git a/data/hooks/conf_regen/02-ssl b/data/hooks/conf_regen/02-ssl index 74600fc89..758e61b15 100755 --- a/data/hooks/conf_regen/02-ssl +++ b/data/hooks/conf_regen/02-ssl @@ -72,13 +72,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; init) do_init_regen diff --git a/data/hooks/conf_regen/03-ssh b/data/hooks/conf_regen/03-ssh index b00e1ac33..b0cac73f7 100755 --- a/data/hooks/conf_regen/03-ssh +++ b/data/hooks/conf_regen/03-ssh @@ -27,13 +27,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/06-slapd b/data/hooks/conf_regen/06-slapd index 0a8b41a2a..08b3def6e 100755 --- a/data/hooks/conf_regen/06-slapd +++ b/data/hooks/conf_regen/06-slapd @@ -72,13 +72,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/09-nslcd b/data/hooks/conf_regen/09-nslcd index 0cf3d3374..d0338ad6c 100755 --- a/data/hooks/conf_regen/09-nslcd +++ b/data/hooks/conf_regen/09-nslcd @@ -18,13 +18,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/12-metronome b/data/hooks/conf_regen/12-metronome index 767f9db4e..cabbe8912 100755 --- a/data/hooks/conf_regen/12-metronome +++ b/data/hooks/conf_regen/12-metronome @@ -58,13 +58,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/15-nginx b/data/hooks/conf_regen/15-nginx index 29748fa70..8c2fae2db 100755 --- a/data/hooks/conf_regen/15-nginx +++ b/data/hooks/conf_regen/15-nginx @@ -80,13 +80,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; init) do_init_regen diff --git a/data/hooks/conf_regen/19-postfix b/data/hooks/conf_regen/19-postfix index f7b702ae2..66a92f9a9 100755 --- a/data/hooks/conf_regen/19-postfix +++ b/data/hooks/conf_regen/19-postfix @@ -38,13 +38,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/25-dovecot b/data/hooks/conf_regen/25-dovecot index 7dbeb5d68..344f43222 100755 --- a/data/hooks/conf_regen/25-dovecot +++ b/data/hooks/conf_regen/25-dovecot @@ -51,13 +51,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/28-rmilter b/data/hooks/conf_regen/28-rmilter index 0021f2b7e..187d893c9 100755 --- a/data/hooks/conf_regen/28-rmilter +++ b/data/hooks/conf_regen/28-rmilter @@ -46,13 +46,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/31-rspamd b/data/hooks/conf_regen/31-rspamd index ff9786d2e..5e0cb0bd1 100755 --- a/data/hooks/conf_regen/31-rspamd +++ b/data/hooks/conf_regen/31-rspamd @@ -32,13 +32,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/34-mysql b/data/hooks/conf_regen/34-mysql index 6f2f90b43..c247acbf1 100755 --- a/data/hooks/conf_regen/34-mysql +++ b/data/hooks/conf_regen/34-mysql @@ -33,13 +33,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/37-avahi-daemon b/data/hooks/conf_regen/37-avahi-daemon index 71e811e3f..8ce180551 100755 --- a/data/hooks/conf_regen/37-avahi-daemon +++ b/data/hooks/conf_regen/37-avahi-daemon @@ -18,13 +18,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/40-glances b/data/hooks/conf_regen/40-glances index d21405b3d..e610eca2d 100755 --- a/data/hooks/conf_regen/40-glances +++ b/data/hooks/conf_regen/40-glances @@ -18,13 +18,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/43-dnsmasq b/data/hooks/conf_regen/43-dnsmasq index 2d4de7b1c..b773cb20a 100755 --- a/data/hooks/conf_regen/43-dnsmasq +++ b/data/hooks/conf_regen/43-dnsmasq @@ -48,13 +48,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/46-nsswitch b/data/hooks/conf_regen/46-nsswitch index b8a5b56ed..e2865c867 100755 --- a/data/hooks/conf_regen/46-nsswitch +++ b/data/hooks/conf_regen/46-nsswitch @@ -18,13 +18,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/data/hooks/conf_regen/52-fail2ban b/data/hooks/conf_regen/52-fail2ban index 16bedee0a..3b01aead7 100755 --- a/data/hooks/conf_regen/52-fail2ban +++ b/data/hooks/conf_regen/52-fail2ban @@ -22,13 +22,14 @@ do_post_regen() { } FORCE=$2 +DRY_RUN=$3 case "$1" in pre) - do_pre_regen $3 + do_pre_regen $4 ;; post) - do_post_regen $3 + do_post_regen $4 ;; *) echo "hook called with unknown argument \`$1'" >&2 diff --git a/locales/en.json b/locales/en.json index c33c78c73..90f9e46e5 100644 --- a/locales/en.json +++ b/locales/en.json @@ -130,6 +130,7 @@ "service_cmd_exec_failed" : "Unable to execute command '{command:s}'", "service_regenconf_failed" : "Unable to regenerate the configuration for service(s): {services}", "service_regenconf_pending_applying" : "Applying pending configuration for service '{service}'...", + "service_regenconf_dry_pending_applying" : "Checking pending configuration which would have been applied for service '{service}'...", "service_conf_file_manually_removed" : "The configuration file '{conf}' has been manually removed and will not be created", "service_conf_file_manually_modified" : "The configuration file '{conf}' has been manually modified and will not be updated", "service_conf_file_not_managed" : "The configuration file '{conf}' is not managed yet and will not be updated", @@ -140,6 +141,7 @@ "service_conf_file_copy_failed" : "Unable to copy the new configuration file '{new}' to '{conf}'", "service_conf_up_to_date" : "The configuration is already up-to-date for service '{service}'", "service_conf_updated" : "The configuration has been updated for service '{service}'", + "service_conf_would_be_updated" : "The configuration would have been updated for service '{service}'", "network_check_smtp_ok" : "Outbound mail (SMTP port 25) is not blocked", "network_check_smtp_ko" : "Outbound mail (SMTP port 25) seems to be blocked by your network", diff --git a/src/yunohost/service.py b/src/yunohost/service.py index e82acae6c..95874f99a 100644 --- a/src/yunohost/service.py +++ b/src/yunohost/service.py @@ -271,7 +271,7 @@ def service_log(name, number=50): return result -def service_regen_conf(names=[], with_diff=False, force=False, +def service_regen_conf(names=[], with_diff=False, force=False, dry_run=False, list_pending=False): """ Regenerate the configuration file(s) for a service @@ -280,6 +280,7 @@ def service_regen_conf(names=[], with_diff=False, force=False, names -- Services name to regenerate configuration of with_diff -- Show differences in case of configuration changes force -- Override all manual modifications in configuration files + dry_run -- Show what would have been regenerated list_pending -- List pending configuration files and exit """ @@ -303,7 +304,7 @@ def service_regen_conf(names=[], with_diff=False, force=False, filesystem.mkdir(pending_conf_dir, 0755, True) # Format common hooks arguments - common_args = [1 if force else 0,] + common_args = [1 if force else 0, 1 if dry_run else 0] # Execute hooks for pre-regen pre_args = ['pre',] + common_args @@ -322,10 +323,16 @@ def service_regen_conf(names=[], with_diff=False, force=False, m18n.n('service_regenconf_failed', services=', '.join(pre_result['failed']))) + # Set the processing method + _regen = _process_regen_conf if not dry_run else lambda *a, **k: True + # Iterate over services and process pending conf for service, conf_files in _get_pending_conf(names).items(): - logger.info(m18n.n('service_regenconf_pending_applying', - service=service)) + logger.info(m18n.n( + 'service_regenconf_pending_applying' if not dry_run else \ + 'service_regenconf_dry_pending_applying', + service=service)) + conf_hashes = _get_conf_hashes(service) succeed_regen = {} failed_regen = {} @@ -361,7 +368,7 @@ def service_regen_conf(names=[], with_diff=False, force=False, else: logger.debug("> system conf does not exist yet") conf_status = 'created' - regenerated = _process_regen_conf( + regenerated = _regen( system_path, pending_path, save=False) else: logger.warning(m18n.n( @@ -376,10 +383,10 @@ def service_regen_conf(names=[], with_diff=False, force=False, conf_status = 'managed' regenerated = True elif force and to_remove: - regenerated = _process_regen_conf(system_path) + regenerated = _regen(system_path) conf_status = 'force-removed' elif force: - regenerated = _process_regen_conf(system_path, pending_path) + regenerated = _regen(system_path, pending_path) conf_status = 'force-updated' else: logger.warning(m18n.n('service_conf_file_not_managed', @@ -388,10 +395,10 @@ def service_regen_conf(names=[], with_diff=False, force=False, # -> system conf has not been manually modified elif system_hash == current_hash: if to_remove: - regenerated = _process_regen_conf(system_path) + regenerated = _regen(system_path) conf_status = 'removed' elif system_hash != new_hash: - regenerated = _process_regen_conf(system_path, pending_path) + regenerated = _regen(system_path, pending_path) conf_status = 'updated' else: logger.debug("> system conf is already up-to-date") @@ -400,7 +407,7 @@ def service_regen_conf(names=[], with_diff=False, force=False, else: logger.debug("> system conf has been manually modified") if force: - regenerated = _process_regen_conf(system_path, pending_path) + regenerated = _regen(system_path, pending_path) conf_status = 'force-updated' else: logger.warning(m18n.n( @@ -425,8 +432,11 @@ def service_regen_conf(names=[], with_diff=False, force=False, logger.info(m18n.n('service_conf_up_to_date', service=service)) continue elif not failed_regen: - logger.success(m18n.n('service_conf_updated', service=service)) - if succeed_regen: + logger.success(m18n.n( + 'service_conf_updated' if not dry_run else \ + 'service_conf_would_be_updated', + service=service)) + if succeed_regen and not dry_run: _update_conf_hashes(service, conf_hashes) # Append the service results @@ -435,6 +445,10 @@ def service_regen_conf(names=[], with_diff=False, force=False, 'pending': failed_regen } + # Return in case of dry run + if dry_run: + return result + # Execute hooks for post-regen post_args = ['post',] + common_args def _pre_call(name, priority, path, args):