Skip to content

Commit

Permalink
add cancel subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
kkaarreell committed Dec 11, 2024
1 parent 5b4ec84 commit 70b8267
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,15 @@ request:
tmt_path: ''
```
### Subcommand `cancel`
Cancels TF reqests found in `execute-` files within the given state-dir.
Example:
```
$ newa --prev-state-dir cancel
```
### Subcommand `execute`
Processes multiple files having `schedule-` prefix. For each such file it
Expand Down
27 changes: 27 additions & 0 deletions newa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,33 @@ class TFRequest(Cloneable, Serializable):
uuid: str
details: Optional[dict[str, Any]] = None

def cancel(self, ctx: CLIContext) -> None:
env = copy.deepcopy(os.environ)
# disable colors and escape control sequences
env['NO_COLOR'] = "1"
env['NO_TTY'] = "1"
command: list[str] = ['testing-farm', 'cancel', self.uuid]
try:
process = subprocess.run(
command,
env=env,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True)
output = process.stdout
except subprocess.CalledProcessError as e:
output = e.stdout
if 'cancellation requested' in output:
ctx.logger.info(f'Cancellation of TF request {self.uuid} requested.')
elif 'already canceled' in output:
ctx.logger.info(f'TF request {self.uuid} has been already cancelled.')
elif 'already finished' in output:
ctx.logger.info(f'TF request {self.uuid} has been already finished.')
else:
ctx.logger.error(f'Failed cancelling TF request {self.uuid}.')
ctx.logger.debug(output)

def fetch_details(self) -> None:
self.details = get_request(
url=self.api,
Expand Down
32 changes: 30 additions & 2 deletions newa/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,34 @@ def cmd_schedule(ctx: CLIContext, arch: list[str]) -> None:
ctx.save_schedule_job('schedule-', schedule_job)


@main.command(name='cancel')
@click.pass_obj
def cmd_cancel(ctx: CLIContext) -> None:
ctx.enter_command('cancel')
# make TESTING_FARM_API_TOKEN available to workers as envvar if it has been
# defined only though the settings file
tf_token = ctx.settings.tf_token
if not tf_token:
raise ValueError("TESTING_FARM_API_TOKEN not set!")
os.environ["TESTING_FARM_API_TOKEN"] = tf_token

for execute_job in ctx.load_execute_jobs('execute-'):
# if not execute_job.execution.result:
tf_request = TFRequest(
api=execute_job.execution.request_api,
uuid=execute_job.execution.request_uuid)
tf_request.cancel(ctx)
tf_request.fetch_details()
if tf_request.details:
execute_job.execution.state = tf_request.details['state']
if 'cancel' in execute_job.execution.state:
execute_job.execution.state = 'canceled'
execute_job.execution.result = 'error'
if tf_request.details['result']:
execute_job.execution.result = tf_request.details['result']['overall']
ctx.save_execute_job('execute-', execute_job)


@main.command(name='execute')
@click.option(
'--workers',
Expand Down Expand Up @@ -1104,15 +1132,15 @@ def worker(ctx: CLIContext, schedule_file: Path) -> None:
envs = ','.join([f"{e['os']['compose']}/{e['arch']}"
for e in tf_request.details['environments_requested']])
log(f'TF request {tf_request.uuid} envs: {envs} state: {state}')
finished = state in ['complete', 'error']
finished = state in ['complete', 'error', 'canceled']
else:
log(f'Could not read details of TF request {tf_request.uuid}')

# this is to silence the linter, this cannot happen as the former loop cannot
# finish without knowing request details
if not tf_request.details:
raise Exception(f"Failed to read details of TF request {tf_request.uuid}")
result = tf_request.details['result']['overall']
result = tf_request.details['result']['overall'] if tf_request.details['result'] else 'error'
log(f'finished with result: {result}')
# now write execution details once more
execute_job.execution.artifacts_url = tf_request.details['run']['artifacts']
Expand Down

0 comments on commit 70b8267

Please sign in to comment.