|
29 | 29 |
|
30 | 30 | # Local application imports (anything from EESSI/eessi-bot-software-layer) |
31 | 31 | from connections import github |
32 | | -from tasks.build import check_build_permission, get_node_types, request_bot_build_issue_comments, \ |
33 | | - submit_build_jobs |
| 32 | +from tasks.build import cancel_jobs, check_build_permission, get_job_ids, get_node_types, \ |
| 33 | + get_work_dirs, request_bot_build_issue_comments, submit_build_jobs |
34 | 34 | from tasks.deploy import deploy_built_artefacts, determine_job_dirs |
35 | 35 | from tasks.clean_up import move_to_trash_bin |
36 | 36 | from tools import config |
|
53 | 53 | config.BUILDENV_SETTING_BUILD_JOB_SCRIPT, # required |
54 | 54 | config.BUILDENV_SETTING_BUILD_LOGS_DIR, # optional+recommended |
55 | 55 | config.BUILDENV_SETTING_BUILD_PERMISSION, # optional+recommended |
| 56 | + config.BUILDENV_SETTING_CANCEL_COMMAND, # required |
56 | 57 | config.BUILDENV_SETTING_CONTAINER_CACHEDIR, # optional+recommended |
57 | 58 | # config.BUILDENV_SETTING_CLONE_GIT_REPO_VIA, # optional |
58 | 59 | # config.BUILDENV_SETTING_CVMFS_CUSTOMIZATIONS, # optional |
|
95 | 96 | config.SECTION_EVENT_HANDLER: [ |
96 | 97 | config.EVENT_HANDLER_SETTING_LOG_PATH], # required |
97 | 98 | config.SECTION_GITHUB: [ |
| 99 | + config.GITHUB_SETTING_API_TIMEOUT, # required |
98 | 100 | config.GITHUB_SETTING_APP_ID, # required |
99 | 101 | config.GITHUB_SETTING_APP_NAME, # required |
100 | 102 | config.GITHUB_SETTING_INSTALLATION_ID, # required |
101 | 103 | config.GITHUB_SETTING_PRIVATE_KEY], # required |
102 | 104 | # the poll interval setting is required for the alternative job handover |
103 | 105 | # protocol (delayed_begin) |
104 | 106 | config.SECTION_JOB_MANAGER: [ |
| 107 | + config.JOB_MANAGER_SETTING_POLL_COMMAND, # required |
105 | 108 | config.JOB_MANAGER_SETTING_POLL_INTERVAL], # required |
106 | 109 | config.SECTION_REPO_TARGETS: [ |
107 | 110 | config.REPO_TARGETS_SETTING_REPOS_CFG_DIR], # required |
@@ -507,7 +510,7 @@ def handle_bot_command_help(self, event_info, bot_command): |
507 | 510 | help_msg += "\n - Commands must be sent with a **new** comment (edits of existing comments are ignored)." |
508 | 511 | help_msg += "\n - A comment may contain multiple commands, one per line." |
509 | 512 | help_msg += "\n - Every command begins at the start of a line and has the syntax `bot: COMMAND [ARGUMENTS]*`" |
510 | | - help_msg += "\n - Currently supported COMMANDs are: `help`, `build`, `show_config`, `status`" |
| 513 | + help_msg += "\n - Currently supported COMMANDs are: `help`, `build`, `show_config`, `status`, `cancel`" |
511 | 514 | help_msg += "\n" |
512 | 515 | help_msg += "\n For more information, see https://www.eessi.io/docs/bot" |
513 | 516 | return help_msg |
@@ -679,6 +682,61 @@ def handle_bot_command_status(self, event_info, bot_command): |
679 | 682 | else: |
680 | 683 | return "\n - failed to create status comment" |
681 | 684 |
|
| 685 | + def handle_bot_command_cancel(self, event_info, bot_command): |
| 686 | + """ |
| 687 | + Handles bot command 'cancel' by parsing 'jobid:' arguments and |
| 688 | + cancelling the jobs. |
| 689 | +
|
| 690 | + Args: |
| 691 | + event_info (dict): event received by event_handler |
| 692 | + bot_command (EESSIBotCommand): command to be handled |
| 693 | +
|
| 694 | + Returns: |
| 695 | + comment (string): list of cancelled jobs if any, error message if not |
| 696 | + """ |
| 697 | + self.log("processing bot command 'cancel'") |
| 698 | + |
| 699 | + request_body = event_info["raw_request_body"] |
| 700 | + repo_name = request_body["repository"]["full_name"] |
| 701 | + pr_number = request_body["issue"]["number"] |
| 702 | + user = request_body["comment"]["user"]["login"] |
| 703 | + |
| 704 | + gh = github.get_instance() |
| 705 | + pr = gh.get_repo(repo_name).get_pull(pr_number) |
| 706 | + |
| 707 | + # Jobs can only be cancelled by the user who submitted the job |
| 708 | + # -> No need to proceed if user cannot submit jobs |
| 709 | + if not check_build_permission(pr, event_info): |
| 710 | + self.log(f"User '{user}' does not have build permission - skipping cancellation.") |
| 711 | + return f"\n - User `{user}` cannot submit or cancel build jobs." |
| 712 | + |
| 713 | + # Get valid 'jobid:' arguments |
| 714 | + job_ids = get_job_ids(bot_command.action_filters) |
| 715 | + if len(job_ids) == 0: |
| 716 | + self.log("Got no valid job IDs") |
| 717 | + return "\n - No valid job IDs were given." |
| 718 | + |
| 719 | + # Get working directories of jobs |
| 720 | + work_dirs = get_work_dirs(job_ids, self.cfg) |
| 721 | + if len(work_dirs) == 0: |
| 722 | + self.log("None of the given jobs are cancellable") |
| 723 | + return "\n - No cancellable jobs were given." |
| 724 | + |
| 725 | + # Log skipped jobs |
| 726 | + for job_id in job_ids: |
| 727 | + if job_id not in work_dirs.keys(): |
| 728 | + log(f"Skipping job {job_id} - not found") |
| 729 | + |
| 730 | + # Cancel jobs |
| 731 | + cancelled_jobs = cancel_jobs(work_dirs, user, pr, self.cfg) |
| 732 | + if len(cancelled_jobs) == 0: |
| 733 | + return "\n - No jobs were cancelled." |
| 734 | + else: |
| 735 | + comment = "" |
| 736 | + for job_id in cancelled_jobs: |
| 737 | + comment += f"\n - cancelled job `{job_id}`" |
| 738 | + return comment |
| 739 | + |
682 | 740 | def start(self, app, port=3000): |
683 | 741 | """ |
684 | 742 | Logs startup information to shell and log file and starts the app using |
|
0 commit comments