diff --git a/NEWS b/NEWS index 41c081f5..7467262e 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ * #754: Fix error handling to log command output as one record per line instead of truncating too-long output and swallowing the end of some Borg error messages. * #757: Update documentation so "sudo borgmatic" works for pipx borgmatic installations. + * #761: Fix for borgmatic not stopping Borg immediately when the user presses ctrl-C. * Update documentation to recommend installing/upgrading borgmatic with pipx instead of pip. See the documentation for more information: https://torsion.org/borgmatic/docs/how-to/set-up-backups/#installation diff --git a/borgmatic/signals.py b/borgmatic/signals.py index 3811f8c3..7ec31d91 100644 --- a/borgmatic/signals.py +++ b/borgmatic/signals.py @@ -23,12 +23,20 @@ def handle_signal(signal_number, frame): if signal_number == signal.SIGTERM: logger.critical('Exiting due to TERM signal') sys.exit(EXIT_CODE_FROM_SIGNAL + signal.SIGTERM) + elif signal_number == signal.SIGINT: + raise KeyboardInterrupt() def configure_signals(): ''' Configure borgmatic's signal handlers to pass relevant signals through to any child processes - like Borg. Note that SIGINT gets passed through even without these changes. + like Borg. ''' - for signal_number in (signal.SIGHUP, signal.SIGTERM, signal.SIGUSR1, signal.SIGUSR2): + for signal_number in ( + signal.SIGHUP, + signal.SIGINT, + signal.SIGTERM, + signal.SIGUSR1, + signal.SIGUSR2, + ): signal.signal(signal_number, handle_signal) diff --git a/docs/how-to/upgrade.md b/docs/how-to/upgrade.md index fb61f5c4..9708c005 100644 --- a/docs/how-to/upgrade.md +++ b/docs/how-to/upgrade.md @@ -18,7 +18,7 @@ sudo pipx upgrade borgmatic Omit `sudo` if you installed borgmatic as a non-root user. And if you installed borgmatic *both* as root and as a non-root user, you'll need to -upgrade each installation indepedently. +upgrade each installation independently. If you originally installed borgmatic with `sudo pip3 install --user`, you can uninstall it first with `sudo pip3 uninstall borgmatic` and then [install it diff --git a/tests/unit/test_signals.py b/tests/unit/test_signals.py index 83be32cb..86bb759c 100644 --- a/tests/unit/test_signals.py +++ b/tests/unit/test_signals.py @@ -1,3 +1,4 @@ +import pytest from flexmock import flexmock from borgmatic import signals as module @@ -34,6 +35,17 @@ def test_handle_signal_exits_on_sigterm(): module.handle_signal(signal_number, frame) +def test_handle_signal_raises_on_sigint(): + signal_number = module.signal.SIGINT + frame = flexmock(f_back=flexmock(f_code=flexmock(co_name='something'))) + flexmock(module.os).should_receive('getpgrp').and_return(flexmock) + flexmock(module.os).should_receive('killpg') + flexmock(module.sys).should_receive('exit').never() + + with pytest.raises(KeyboardInterrupt): + module.handle_signal(signal_number, frame) + + def test_configure_signals_installs_signal_handlers(): flexmock(module.signal).should_receive('signal').at_least().once()