diff --git a/actions/monkeysphere b/actions/monkeysphere index c5e6a87bc..3090cdd6d 100755 --- a/actions/monkeysphere +++ b/actions/monkeysphere @@ -24,7 +24,9 @@ import argparse import augeas import json import os +import psutil import re +import signal import subprocess @@ -50,6 +52,10 @@ def parse_arguments(): host_publish_key.add_argument( 'key_ids', nargs='*', help='Optional list of KEYIDs') + host_cancel_publish = subparsers.add_parser( + 'host-cancel-publish', help='Cancel a running publish operation') + host_cancel_publish.add_argument('pid', help='PID of the publish process') + return parser.parse_args() @@ -237,6 +243,26 @@ def subcommand_host_publish_key(arguments): print(output) +def subcommand_host_cancel_publish(arguments): + """Kill a running publish process.""" + process = psutil.Process(int(arguments.pid)) + + # Perform tight checks on the process before killing for security. + arguments = process.cmdline() + if not arguments: + # Process already completed + return + + # Remove the sudo prefix if present + while arguments[0] == 'sudo' or arguments[0].startswith('-'): + arguments = arguments[1:] + + if len(arguments) >= 2 and \ + arguments[0].split('/')[-1] == 'monkeysphere' and \ + arguments[1] == 'host-publish-key': + process.send_signal(signal.SIGTERM) + + def main(): """Parse arguments and perform all duties.""" arguments = parse_arguments() diff --git a/plinth/modules/monkeysphere/views.py b/plinth/modules/monkeysphere/views.py index 434bd4607..673ab9dc2 100644 --- a/plinth/modules/monkeysphere/views.py +++ b/plinth/modules/monkeysphere/views.py @@ -86,7 +86,8 @@ def cancel(request): """Cancel ongoing process.""" global publish_process if publish_process: - publish_process.terminate() + actions.superuser_run( + 'monkeysphere', ['host-cancel-publish', str(publish_process.pid)]) publish_process = None messages.info(request, _('Cancelled key publishing.'))