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.
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/PKG-INFO +2 -2
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/ci_artifacts.py +88 -43
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/version.py +1 -1
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/pyproject.toml +2 -2
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/README.md +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/__init__.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/activity_from_fs.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/binreplace.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/check_rpath.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/cli.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/cpumon.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/decent_output.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/jenkins_utils/__init__.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/job_resource_usage.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/last_access.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/lockable_resources.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/procmon.py +0 -0
- {checkmk_dev_tools-2.2.0 → checkmk_dev_tools-2.3.0}/cmk_dev/pycinfo.py +0 -0
- {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.
|
|
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.
|
|
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
|
|
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
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
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(
|
|
936
|
+
**extract_credentials(credentials, credentials_file=credentials_file), timeout=timeout
|
|
910
937
|
) as jenkins_client:
|
|
911
|
-
if not (
|
|
912
|
-
raise Fatal(f"{
|
|
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
|
|
942
|
+
if force_new_build
|
|
917
943
|
else await identify_matching_build(
|
|
918
|
-
|
|
944
|
+
job_info,
|
|
919
945
|
jenkins_client=jenkins_client,
|
|
920
|
-
params=
|
|
921
|
-
path_hashes=
|
|
922
|
-
time_constraints=
|
|
923
|
-
next_check_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
|
|
928
|
-
raise Fatal(
|
|
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=
|
|
958
|
+
job=job_info,
|
|
933
959
|
params=compose_build_params(
|
|
934
|
-
params=
|
|
935
|
-
params_no_check=
|
|
936
|
-
path_hashes=
|
|
960
|
+
params=params,
|
|
961
|
+
params_no_check=params_no_check,
|
|
962
|
+
path_hashes=path_hashes,
|
|
937
963
|
),
|
|
938
|
-
next_check_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
|
-
|
|
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=
|
|
951
|
-
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
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
984
|
+
resolved_out_dir,
|
|
985
|
+
total_download_timeout,
|
|
986
|
+
no_remove_others,
|
|
987
|
+
no_raise,
|
|
963
988
|
)
|
|
964
989
|
)
|
|
965
990
|
)
|
|
966
|
-
if
|
|
991
|
+
if download
|
|
967
992
|
else []
|
|
968
993
|
)
|
|
994
|
+
return {"result": completed_build.result, "artifacts": downloaded_artifacts}
|
|
969
995
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
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
|
|
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
|
|
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,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "checkmk-dev-tools"
|
|
3
|
-
version = "2.
|
|
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.
|
|
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'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|