checkmk-dev-tools 2.2.0__tar.gz → 2.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (19) hide show
  1. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/PKG-INFO +2 -2
  2. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/ci_artifacts.py +88 -43
  3. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/version.py +1 -1
  4. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/pyproject.toml +2 -2
  5. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/README.md +0 -0
  6. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/__init__.py +0 -0
  7. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/activity_from_fs.py +0 -0
  8. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/binreplace.py +0 -0
  9. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/check_rpath.py +0 -0
  10. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/cli.py +0 -0
  11. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/cpumon.py +0 -0
  12. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/decent_output.py +0 -0
  13. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/jenkins_utils/__init__.py +0 -0
  14. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/job_resource_usage.py +0 -0
  15. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/last_access.py +0 -0
  16. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/lockable_resources.py +0 -0
  17. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/procmon.py +0 -0
  18. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/pycinfo.py +0 -0
  19. {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: checkmk-dev-tools
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: Checkmk DevOps tools
5
5
  Author: Frans Fürst
6
6
  Author-email: frans.fuerst@checkmk.com
@@ -14,7 +14,7 @@ Requires-Dist: pydantic (>=2,<3)
14
14
  Requires-Dist: python-jenkins (>=1.8.3,<1.9.0)
15
15
  Requires-Dist: rich
16
16
  Requires-Dist: trickkiste (>=0.3.4,<0.4.0)
17
- Project-URL: Changelog, https://github.com/Checkmk/checkmk-dev-tools/blob/release/2.2.0/changelog.md
17
+ Project-URL: Changelog, https://github.com/Checkmk/checkmk-dev-tools/blob/release/2.3.0/changelog.md
18
18
  Project-URL: Repository, https://github.com/Checkmk/checkmk-dev-tools
19
19
  Description-Content-Type: text/markdown
20
20
 
@@ -24,7 +24,7 @@ from datetime import datetime
24
24
  from itertools import chain
25
25
  from pathlib import Path
26
26
  from subprocess import check_output
27
- from typing import Any, List, Literal, cast
27
+ from typing import Any, List, Literal, TypedDict, cast
28
28
 
29
29
  import requests
30
30
  from influxdb_client import InfluxDBClient # type: ignore[attr-defined]
@@ -56,6 +56,12 @@ from .version import __version__
56
56
 
57
57
  PathHashes = Mapping[str, str]
58
58
  shared_build_info: asyncio.Queue[str] = asyncio.Queue(maxsize=1)
59
+
60
+
61
+ class FetchResult(TypedDict):
62
+ result: None | JobResult
63
+ artifacts: list[str]
64
+
59
65
  MAX_RETRY_ATTEMPTS = 3
60
66
 
61
67
 
@@ -311,7 +317,7 @@ def download_artifacts(
311
317
  total_download_timeout: int = 240,
312
318
  no_remove_others: bool = False,
313
319
  no_raise: bool = False,
314
- ) -> tuple[Sequence[str | None], Sequence[str | None]]:
320
+ ) -> tuple[Sequence[str], Sequence[str]]:
315
321
  """Downloads all artifacts listed for given job/build to @out_dir"""
316
322
  # pylint: disable=protected-access
317
323
  # pylint: disable=too-many-locals
@@ -733,6 +739,7 @@ async def _fn_request_build(args: Args) -> None:
733
739
  path_hashes=compose_path_hashes(args.base_dir, args.dependency_paths),
734
740
  time_constraints=args.time_constraints,
735
741
  next_check_sleep=args.poll_queue_sleep,
742
+ ignore_build_queue=args.ignore_build_queue,
736
743
  args=args,
737
744
  )
738
745
  ):
@@ -901,54 +908,72 @@ def query_matching_builds(
901
908
  return []
902
909
 
903
910
 
904
- async def _fn_fetch(args: Args) -> None:
905
- """Entry point for fetching (request and download combined) artifacts"""
906
- out_dir = compose_out_dir(args.base_dir, args.out_dir)
907
- path_hashes = compose_path_hashes(args.base_dir, args.dependency_paths)
911
+ async def fetch_artifacts(
912
+ job: str,
913
+ params: None | JobParams = None,
914
+ *,
915
+ out_dir: Path = Path("out"),
916
+ base_dir: Path = Path("."),
917
+ params_no_check: None | JobParams = None,
918
+ dependency_paths: None | Sequence[str] = None,
919
+ time_constraints: None | str = None,
920
+ force_new_build: bool = False,
921
+ omit_new_build: bool = False,
922
+ download: bool = True,
923
+ no_remove_others: bool = False,
924
+ no_raise: bool = False,
925
+ poll_queue_sleep: int = 30,
926
+ poll_sleep: int = 60,
927
+ timeout: int = 120,
928
+ total_download_timeout: int = 240,
929
+ credentials: None | Mapping[str, str] = None,
930
+ credentials_file: str = "~/.config/jenkins_jobs/jenkins_jobs.ini",
931
+ ) -> FetchResult:
932
+ """Find or trigger a matching build, wait for it, download artifacts, return result dict."""
933
+ resolved_out_dir = compose_out_dir(base_dir, out_dir)
934
+ path_hashes = compose_path_hashes(base_dir, dependency_paths or [])
908
935
  async with AugmentedJenkinsClient(
909
- **extract_credentials(args.credentials), timeout=args.timeout
936
+ **extract_credentials(credentials, credentials_file=credentials_file), timeout=timeout
910
937
  ) as jenkins_client:
911
- if not (job := await jenkins_client.job_info(args.job)).type == "WorkflowJob":
912
- raise Fatal(f"{args.job} is not a WorkflowJob")
913
- # In case we force a new build anyway we don't have to look for an existing one
938
+ if not (job_info := await jenkins_client.job_info(job)).type == "WorkflowJob":
939
+ raise Fatal(f"{job} is not a WorkflowJob")
914
940
  matching_build = (
915
941
  None
916
- if args.force_new_build
942
+ if force_new_build
917
943
  else await identify_matching_build(
918
- job,
944
+ job_info,
919
945
  jenkins_client=jenkins_client,
920
- params=flatten(args.params),
921
- path_hashes=compose_path_hashes(args.base_dir, args.dependency_paths),
922
- time_constraints=args.time_constraints,
923
- next_check_sleep=args.poll_queue_sleep,
924
- args=args,
946
+ params=params,
947
+ path_hashes=path_hashes,
948
+ time_constraints=time_constraints,
949
+ next_check_sleep=poll_queue_sleep,
925
950
  )
926
951
  )
927
- if args.omit_new_build and not matching_build:
928
- raise Fatal(f"No matching build found for job '{job.name}' but new builds are omitted.")
929
-
952
+ if omit_new_build and not matching_build:
953
+ raise Fatal(
954
+ f"No matching build found for job '{job_info.name}' but new builds are omitted."
955
+ )
930
956
  build_candidate = matching_build or await trigger_build(
931
957
  jenkins_client=jenkins_client,
932
- job=job,
958
+ job=job_info,
933
959
  params=compose_build_params(
934
- params=flatten(args.params),
935
- params_no_check=flatten(args.params_no_check),
936
- path_hashes=compose_path_hashes(args.base_dir, args.dependency_paths),
960
+ params=params,
961
+ params_no_check=params_no_check,
962
+ path_hashes=path_hashes,
937
963
  ),
938
- next_check_sleep=args.poll_queue_sleep,
964
+ next_check_sleep=poll_queue_sleep,
939
965
  )
940
-
941
966
  for key, value in build_candidate.__dict__.items():
942
967
  log().debug(" %s: %s", key, value)
943
-
944
968
  completed_build = await await_build(
945
- job.path,
969
+ job_info.path,
946
970
  build_candidate.number,
947
971
  jenkins_client=jenkins_client,
948
972
  check_result=True,
949
973
  path_hashes=path_hashes,
950
- next_check_sleep=args.poll_sleep,
951
- no_raise=args.no_raise,
974
+ next_check_sleep=poll_sleep,
975
+ no_raise=no_raise,
976
+ download=download,
952
977
  )
953
978
  downloaded_artifacts = (
954
979
  list(
@@ -956,25 +981,44 @@ async def _fn_fetch(args: Args) -> None:
956
981
  *download_artifacts(
957
982
  jenkins_client.client,
958
983
  completed_build,
959
- out_dir,
960
- args.total_download_timeout,
961
- args.no_remove_others,
962
- args.no_raise,
984
+ resolved_out_dir,
985
+ total_download_timeout,
986
+ no_remove_others,
987
+ no_raise,
963
988
  )
964
989
  )
965
990
  )
966
- if args.download
991
+ if download
967
992
  else []
968
993
  )
994
+ return {"result": completed_build.result, "artifacts": downloaded_artifacts}
969
995
 
970
- print(
971
- json.dumps(
972
- {
973
- "result": completed_build.result,
974
- "artifacts": downloaded_artifacts,
975
- }
996
+
997
+ async def _fn_fetch(args: Args) -> None:
998
+ """Entry point for fetching (request and download combined) artifacts"""
999
+ print(
1000
+ json.dumps(
1001
+ await fetch_artifacts(
1002
+ job=args.job,
1003
+ params=flatten(args.params),
1004
+ out_dir=args.out_dir,
1005
+ base_dir=args.base_dir,
1006
+ params_no_check=flatten(args.params_no_check),
1007
+ dependency_paths=args.dependency_paths,
1008
+ time_constraints=args.time_constraints,
1009
+ force_new_build=args.force_new_build,
1010
+ omit_new_build=args.omit_new_build,
1011
+ download=args.download,
1012
+ no_remove_others=args.no_remove_others,
1013
+ no_raise=args.no_raise,
1014
+ poll_queue_sleep=args.poll_queue_sleep,
1015
+ poll_sleep=args.poll_sleep,
1016
+ timeout=args.timeout,
1017
+ total_download_timeout=args.total_download_timeout,
1018
+ credentials=args.credentials,
976
1019
  )
977
1020
  )
1021
+ )
978
1022
 
979
1023
 
980
1024
  async def identify_matching_build(
@@ -985,6 +1029,7 @@ async def identify_matching_build(
985
1029
  path_hashes: PathHashes,
986
1030
  time_constraints: None | str,
987
1031
  next_check_sleep: int = 30,
1032
+ ignore_build_queue: bool = False,
988
1033
  args: None | Args = None,
989
1034
  ) -> None | Build:
990
1035
  """Find an existing build (finished, still running or queued) which matches our
@@ -1102,7 +1147,7 @@ async def identify_matching_build(
1102
1147
  log().info("No matching builds found in the InfluxDB")
1103
1148
 
1104
1149
  log().info("Check for matching queue items via Jenkins API")
1105
- if hasattr(args, "ignore_build_queue") and not args.ignore_build_queue:
1150
+ if not ignore_build_queue:
1106
1151
  if matching_item := await find_matching_queue_item(
1107
1152
  jenkins_client=jenkins_client,
1108
1153
  job=job,
@@ -1143,7 +1188,7 @@ async def identify_matching_build(
1143
1188
  log().info("No matching non finished builds found via the Jenkins API")
1144
1189
 
1145
1190
  log().info("Check for matching queue items via Jenkins API")
1146
- if args and not args.ignore_build_queue:
1191
+ if not ignore_build_queue:
1147
1192
  if matching_item := await find_matching_queue_item(
1148
1193
  jenkins_client=jenkins_client,
1149
1194
  job=job,
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: UTF-8 -*-
3
3
 
4
- __version_info__ = ("2", "2", "0")
4
+ __version_info__ = ("2", "3", "0")
5
5
  __version__ = '.'.join(__version_info__)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "checkmk-dev-tools"
3
- version = "2.2.0" # will-be-updated-automatically
3
+ version = "2.3.0" # will-be-updated-automatically
4
4
  description = "Checkmk DevOps tools"
5
5
  authors = [
6
6
  "Frans Fürst <frans.fuerst@checkmk.com>",
@@ -14,7 +14,7 @@ exclude = ["cmk_dev/out"]
14
14
 
15
15
  [tool.poetry.urls]
16
16
  Repository = "https://github.com/Checkmk/checkmk-dev-tools"
17
- Changelog = "https://github.com/Checkmk/checkmk-dev-tools/blob/release/2.2.0/changelog.md"
17
+ Changelog = "https://github.com/Checkmk/checkmk-dev-tools/blob/release/2.3.0/changelog.md"
18
18
 
19
19
  [tool.poetry.scripts]
20
20
  activity-from-fs = 'cmk_dev.activity_from_fs:main'