The little things give you away... A collection of various small helper stuff
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

168 lignes
4.5 KiB

  1. #!/bin/bash
  2. columns=("JOBID" "URL" "USER" "PIPENICK" "QUEUED" "STARTED" "LAST ACTIVE") # Duplicated in Python code!
  3. function valid_column {
  4. local candidate="$1"
  5. local column
  6. for column in "${columns[@]}"
  7. do
  8. [[ "${candidate}" == "${column}" ]] && return 0
  9. done
  10. return 1
  11. }
  12. sortcolumns=()
  13. filter=
  14. nocolours=
  15. notable=
  16. while [[ $# -gt 0 ]]
  17. do
  18. if [[ "$1" == "--help" || "$1" == "-h" ]]
  19. then
  20. echo "Usage: archivebot-jobs [--help|-h] [(--sort|-s) COLUMN] [(--filter|-f) COLUMN=VALUE] [--no-colours|--no-colors] [--no-table]" >&2
  21. echo "Prints a table of current AB jobs" >&2
  22. echo "Options:" >&2
  23. echo " --help, -h: Show this message and exit." >&2
  24. echo " --sort COLUMN: Sort the table by a column. This can be used multiple times to refine the sorting." >&2
  25. echo " --filter COLUMN=VALUE: Filter the table for rows where a COLUMN has a certain VALUE. If specified multiple times, only the last value is used." >&2
  26. echo " --no-colours: Don't colourise the last activity column if it's been a while." >&2
  27. echo " --no-table: Raw output without feeding through column(1); columns are separated by tabs." >&2
  28. echo "The COLUMNs are the names of each column, printed in capital letters in the first line of the output." >&2
  29. exit 0
  30. elif [[ "$1" == "--sort" || "$1" == "-s" ]]
  31. then
  32. sortcolumns+=("$2")
  33. shift
  34. elif [[ "$1" == "--filter" || "$1" == "-f" ]]
  35. then
  36. filter="$2"
  37. shift
  38. elif [[ "$1" == "--no-colours" || "$1" == "--no-colors" ]]
  39. then
  40. nocolours=1
  41. elif [[ "$1" == "--no-table" ]]
  42. then
  43. notable=1
  44. else
  45. echo "Unknown option: $1" >&2
  46. exit 1
  47. fi
  48. shift
  49. done
  50. # Validate sortcolumns and filter
  51. if [[ "${filter}" ]]
  52. then
  53. if [[ ! "${filter}" == *=* ]]
  54. then
  55. echo "Invalid filter: ${filter}" >&2
  56. exit 1
  57. fi
  58. if [[ "${filter}" == *$'\n'* ]]
  59. then
  60. echo "Invalid filter: newlines not allowed" >&2
  61. exit 1
  62. fi
  63. column="${filter%%=*}"
  64. if ! valid_column "${column}"
  65. then
  66. echo "Invalid filter column: ${column}" >&2
  67. exit 1
  68. fi
  69. fi
  70. if [[ ${#sortcolumns[@]} -gt 0 ]]
  71. then
  72. for column in "${sortcolumns[@]}"
  73. do
  74. if ! valid_column "${column}"
  75. then
  76. echo "Invalid sort column: ${column}" >&2
  77. exit 1
  78. fi
  79. done
  80. else
  81. # Default sort order
  82. sortcolumns+=("JOBID")
  83. fi
  84. if [[ "${notable}" ]]
  85. then
  86. column=("cat")
  87. else
  88. column=("column" "-t" $'-s\t')
  89. fi
  90. jobdata="$(curl -s -H "Accept: application/json" "http://dashboard.at.ninjawedding.org/logs/recent?count=1" 2>/dev/null)"
  91. pipelinedata="$(curl -s -H "Accept: application/json" "http://dashboard.at.ninjawedding.org/pipelines" 2>/dev/null)"
  92. if [[ -z "${jobdata}" || -z "${pipelinedata}" ]]
  93. then
  94. echo "Error retrieving job or pipeline data" >&2
  95. exit 1
  96. fi
  97. { echo "${jobdata}"; echo "${pipelinedata}"; echo "${filter}"; } | python3 -c \
  98. '
  99. if True: # For sensible indentation
  100. import json
  101. import sys
  102. import time
  103. def time_ago(diff):
  104. if diff <= 0:
  105. return "now"
  106. elif diff < 60:
  107. return "<1 min ago"
  108. elif diff < 86400:
  109. return (f"{diff // 3600:.0f}h " if diff >= 3600 else "") + f"{(diff % 3600) // 60:.0f}mn ago"
  110. else:
  111. return f"{diff // 86400:.0f}d {(diff % 86400) // 3600:.0f}h ago"
  112. def coloured_time_ago(diff):
  113. if diff >= 300:
  114. return "\x1b[0;31m" + time_ago(diff) + "\x1b[0m"
  115. else:
  116. return time_ago(diff)
  117. jobdata = json.loads(sys.stdin.readline())
  118. pipelinedata = json.loads(sys.stdin.readline())
  119. filter = sys.stdin.readline().strip()
  120. pipelines = {p["id"]: p["nickname"] for p in pipelinedata["pipelines"]}
  121. columns = ("JOBID", "URL", "USER", "PIPENICK", "QUEUED", "STARTED", "LAST ACTIVE") # Duplicated in Bash code!
  122. jobs = []
  123. currentTime = time.time()
  124. for j in jobdata:
  125. jobs.append([
  126. j["job_data"]["ident"],
  127. j["job_data"]["url"],
  128. j["job_data"]["started_by"],
  129. pipelines[j["job_data"]["pipeline_id"]] if j["job_data"]["pipeline_id"] in pipelines else "unknown",
  130. currentTime - j["job_data"]["queued_at"],
  131. currentTime - j["job_data"]["started_at"],
  132. currentTime - j["ts"],
  133. ])
  134. # Filter
  135. if filter:
  136. column, value = filter.split("=", 1)
  137. assert column in columns
  138. columnIdx = columns.index(column)
  139. jobs = [job for job in jobs if job[columnIdx] == value]
  140. # Sort
  141. sortColumns = ('"$(printf "'%s', " "${sortcolumns[@]}")"')
  142. assert all(column in columns for column in sortColumns)
  143. sortColumnIdxs = tuple(columns.index(column) for column in sortColumns)
  144. jobs = sorted(jobs, key = lambda job: tuple(job[columnIdx] for columnIdx in sortColumnIdxs))
  145. # Print
  146. print("\t".join(columns))
  147. for job in jobs:
  148. job[4] = time_ago(job[4])
  149. job[5] = time_ago(job[5])
  150. job[6] = (coloured_time_ago if not "'${nocolours}'" else time_ago)(job[6])
  151. print("\t".join(job))
  152. ' | "${column[@]}"