Fix for borgmatic not stopping Borg immediately when the user presses ctrl-C (#761).

This commit is contained in:
Dan Helfman 2023-09-27 08:52:00 -07:00
parent af422ad705
commit 10933fd55b
4 changed files with 24 additions and 3 deletions

1
NEWS
View file

@ -7,6 +7,7 @@
* #754: Fix error handling to log command output as one record per line instead of truncating * #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. too-long output and swallowing the end of some Borg error messages.
* #757: Update documentation so "sudo borgmatic" works for pipx borgmatic installations. * #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 * Update documentation to recommend installing/upgrading borgmatic with pipx instead of pip. See the
documentation for more information: documentation for more information:
https://torsion.org/borgmatic/docs/how-to/set-up-backups/#installation https://torsion.org/borgmatic/docs/how-to/set-up-backups/#installation

View file

@ -23,12 +23,20 @@ def handle_signal(signal_number, frame):
if signal_number == signal.SIGTERM: if signal_number == signal.SIGTERM:
logger.critical('Exiting due to TERM signal') logger.critical('Exiting due to TERM signal')
sys.exit(EXIT_CODE_FROM_SIGNAL + signal.SIGTERM) sys.exit(EXIT_CODE_FROM_SIGNAL + signal.SIGTERM)
elif signal_number == signal.SIGINT:
raise KeyboardInterrupt()
def configure_signals(): def configure_signals():
''' '''
Configure borgmatic's signal handlers to pass relevant signals through to any child processes 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) signal.signal(signal_number, handle_signal)

View file

@ -18,7 +18,7 @@ sudo pipx upgrade borgmatic
Omit `sudo` if you installed borgmatic as a non-root user. And if you 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 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 If you originally installed borgmatic with `sudo pip3 install --user`, you can
uninstall it first with `sudo pip3 uninstall borgmatic` and then [install it uninstall it first with `sudo pip3 uninstall borgmatic` and then [install it

View file

@ -1,3 +1,4 @@
import pytest
from flexmock import flexmock from flexmock import flexmock
from borgmatic import signals as module from borgmatic import signals as module
@ -34,6 +35,17 @@ def test_handle_signal_exits_on_sigterm():
module.handle_signal(signal_number, frame) 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(): def test_configure_signals_installs_signal_handlers():
flexmock(module.signal).should_receive('signal').at_least().once() flexmock(module.signal).should_receive('signal').at_least().once()