Skip to content

Commit

Permalink
Rewrite openqa-advanced-retrigger-jobs in python
Browse files Browse the repository at this point in the history
  • Loading branch information
okurz committed Jul 23, 2024
1 parent 4093b20 commit f32c1d5
Showing 1 changed file with 85 additions and 51 deletions.
136 changes: 85 additions & 51 deletions openqa-advanced-retrigger-jobs
Original file line number Diff line number Diff line change
@@ -1,54 +1,88 @@
#!/bin/bash -e
#worker="${worker:-"openqaworker4"}"
host="${host:-"openqa.opensuse.org"}"
failed_since="${failed_since:-"$(date -I)"}"
instance_string="${INSTANCE+" and instance='$INSTANCE'"}"
worker_string="${WORKER+"assigned_worker_id in (select id from workers where (host='$WORKER'$instance_string)) and "}"
result="${result:-"result='incomplete'"}"
additional_filters="${additional_filters+" and $additional_filters"}"
comment="${comment:-""}"
dry_run="${dry_run:-"0"}"

usage() {
cat << EOF
Usage: $0 [OPTIONS]
#!/usr/bin/env python3

"""
Retrigger openQA jobs based on database queries.
By default retriggers openQA jobs with result '$result' since '$failed_since'
on '$host'.
Can be restricted to jobs that ran on worker by setting the variable 'WORKER'
and optionally 'INSTANCE'.
Needs SSH access to the target openQA host '$host'.
Options:
-h, --help display this help
EOF
exit "$1"
}

main() {
opts=$(getopt -o h -l help -n "$0" -- "$@") || usage 1
eval set -- "$opts"
while true; do
case "$1" in
-h | --help) usage 0 ;;
--)
shift
break
;;
*) break ;;
esac
done

[ "$dry_run" = "1" ] && client_prefix="echo"
# shellcheck disable=SC2029
for i in $(ssh "$host" "sudo -u geekotest psql --no-align --tuples-only --command=\"select id from jobs where (${worker_string}${result} and clone_id is null and t_finished >= '$failed_since'$additional_filters);\" openqa"); do
$client_prefix openqa-cli api --host "$host" -X POST jobs/"$i"/restart
[ -n "$comment" ] && $client_prefix openqa-cli api --host "$host" -X POST jobs/"$i"/comments text="$comment"
done
}

caller 0 > /dev/null || main "$@"
Needs SSH access to the specified target openQA host.
"""

import argparse
import logging
import subprocess
import sys
from datetime import datetime

logging.basicConfig()
log = logging.getLogger(sys.argv[0] if __name__ == "__main__" else __name__)


class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
"""Preserve multi-line __doc__ and provide default arguments in help strings."""

pass


def main():
parser = argparse.ArgumentParser(description=__doc__, formatter_class=CustomFormatter)
parser.add_argument(
"-v",
"--verbose",
help="Increase verbosity level, specify multiple times to increase verbosity",
action="count",
default=1,
)
parser.add_argument("-H", "--host", default="openqa.opensuse.org", help="Target openQA host")
parser.add_argument(
"-s",
"--failed-since",
default=datetime.today().isoformat(),
help="Filter jobs failed since this date",
)
parser.add_argument("-w", "--worker", default=None, help="Filter jobs assigned to this worker")
parser.add_argument("-i", "--instance", default=None, help="Instance of the worker")
parser.add_argument("-r", "--result", default="incomplete", help="Filter jobs with this result")
parser.add_argument(
"-a",
"--additional-filters",
default=None,
help="Additional filters for the SQL query",
)
parser.add_argument("-c", "--comment", default=None, help="Comment to add to the retriggered jobs")
parser.add_argument(
"-d",
"--dry-run",
action="store_true",
help="If set, only print the actions without executing",
)
args = parser.parse_args()
verbose_to_log = {
0: logging.CRITICAL,
1: logging.ERROR,
2: logging.WARN,
3: logging.INFO,
4: logging.DEBUG,
}
logging_level = logging.DEBUG if args.verbose > 4 else verbose_to_log[args.verbose]
log.setLevel(logging_level)
instance_string = f" and instance='{args.instance}'" if args.instance else ""
worker_string = f"assigned_worker_id in (select id from workers where (host='{args.worker}'{instance_string})) and " if args.worker else ""
additional_filters = f" and {args.additional_filters}" if args.additional_filters else ""
client_prefix = "echo" if args.dry_run else ""

query = (
f"select id from jobs where ({worker_string}result='{args.result}' "
f"and clone_id is null and t_finished >= '{args.failed_since}'{additional_filters});"
)

log.debug(f"Using SQL query: '{query}' on {args.host}")
ssh_command = f'ssh {args.host} "sudo -u geekotest psql --no-align --tuples-only --command=\\"{query}\\" openqa"'
job_ids = subprocess.check_output(ssh_command).decode().splitlines()

for job_id in job_ids:
subprocess.run(f"{client_prefix} openqa-cli api --host {args.host} -X POST jobs/{job_id}/restart")
if args.comment:
subprocess.run(f'{client_prefix} openqa-cli api --host {args.host} -X POST jobs/{job_id}/comments text="{args.comment}"')


if __name__ == "__main__":
main()

0 comments on commit f32c1d5

Please sign in to comment.